예제 #1
0
        public void FilterBinderTest()
        {
            IEdmModel model = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory);

            this.CombinatorialEngineProvider.RunCombinations(
                LiteralTestCases()
                .Concat(UnaryOperatorTestCases())
                .Concat(BinaryOperatorTestCases())
                .Concat(PropertyAccessTestCases(model))
                .Concat(TopFilterExpressionTestCases(model))
                .Concat(BuiltInStringFunctionCallTestCases(model))
                .Concat(BuiltInDateTimeOffsetFunctionCallTestCases(model))
                .Concat(BuiltInMathFunctionCallTestCases(model)),
                (testCase) =>
            {
                string query    = "/" + testCase.EntitySetName + "?$filter=" + testCase.Filter;
                ODataUri actual = QueryNodeUtils.BindQuery(query, model);

                // construct the expected filter node
                var entitySet = model.FindDeclaredEntitySet(testCase.EntitySetName);
                CollectionResourceNode entityCollectionNode = new EntitySetNode(entitySet);
                var expectedFilter = new FilterClause(
                    testCase.ExpectedFilterCondition,
                    new ResourceRangeVariable(ExpressionConstants.It, entitySet.EntityType().ToTypeReference(false).AsEntity(), entityCollectionNode)
                    );

                QueryNodeUtils.VerifyFilterClausesAreEqual(
                    expectedFilter,
                    actual.Filter,
                    this.Assert);
            });
        }
예제 #2
0
        public void InvalidFilterBinderTest()
        {
            var metadata = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory);

            this.CombinatorialEngineProvider.RunCombinations(
                InvalidBinaryOperatorTestCases()
                .Concat(InvalidUnaryOperatorTestCases())
                .Concat(InvalidPropertyAccessTestCases()),
                (testCase) =>
            {
                string query = "/Customers?$filter=" + testCase.Filter;
                this.Assert.ExpectedException <ODataException>(
                    () => QueryNodeUtils.BindQuery(query, metadata),
                    testCase.ExpectedExceptionMessage,
                    "Invalid filter binder test.");
            });
        }
예제 #3
0
        private FilterClause BindFilter(IEdmModel model, string filter, string errorMessage)
        {
            FilterClause actualFilter = null;

            TestExceptionUtils.ExpectedException <ODataException>(
                this.Assert,
                () =>
            {
                string query    = "/TypesWithPrimitiveProperties?$filter=" + filter;
                ODataUri actual = QueryNodeUtils.BindQuery(query, model);

                // the filter node should be the top-level node in the query tree
                actualFilter = (FilterClause)actual.Filter;
            },
                errorMessage,
                null);
            return(actualFilter);
        }
        public void OrderByBinderTest()
        {
            IEdmModel model = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory);

            // TODO: add an error test where the input collection to the order-by is a singleton

            ResourceRangeVariable entityRangeVariable = new ResourceRangeVariable("dummy", model.ResolveTypeReference("TestNS.Customer", false).AsEntity(), model.FindEntityContainer("BinderTestMetadata").FindEntitySet("Customers"));

            OrderByTestCase[] testCases = new OrderByTestCase[]
            {
                new OrderByTestCase()
                {
                    OrderBy = new string[] { "true" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new ConstantNode(true)
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new SingleValuePropertyAccessNode(
                            new ResourceRangeVariableReferenceNode(entityRangeVariable.Name, entityRangeVariable),
                            model.ResolveProperty("TestNS.Customer.Name")
                            )
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "3" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new ConstantNode(3)
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "null" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new ConstantNode(null)
                    }
                },


                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Address" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Emails" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "NonExistant" },
                    ExpectedExceptionMessage = "Could not find a property named 'NonExistant' on type 'TestNS.Customer'."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "ID" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new SingleValuePropertyAccessNode(
                            new ResourceRangeVariableReferenceNode(entityRangeVariable.Name, entityRangeVariable),
                            model.ResolveProperty("TestNS.Customer.Name")
                            ),
                        new SingleValuePropertyAccessNode(
                            new ResourceRangeVariableReferenceNode(entityRangeVariable.Name, entityRangeVariable),
                            model.ResolveProperty("TestNS.Customer.ID")
                            ),
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "Address" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "Emails" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "NonExistant" },
                    ExpectedExceptionMessage = "Could not find a property named 'NonExistant' on type 'TestNS.Customer'."
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                new OrderByDirection?[] { null, OrderByDirection.Ascending, OrderByDirection.Descending },
                (testCase, direction) =>
            {
                string orderByDirection = direction == null
                        ? string.Empty
                        : direction == OrderByDirection.Ascending
                            ? " asc"
                            : " desc";

                this.Assert.IsTrue(testCase.OrderBy.Length > 0, "Need at least one order-by expression");

                StringBuilder queryBuilder = new StringBuilder("/Customers?$orderby=");
                for (int i = 0; i < testCase.OrderBy.Length; ++i)
                {
                    if (i > 0)
                    {
                        queryBuilder.Append(", ");
                    }
                    queryBuilder.Append(testCase.OrderBy[i]);
                    queryBuilder.Append(orderByDirection);
                }

                TestExceptionUtils.ExpectedException <ODataException>(
                    this.Assert,
                    () =>
                {
                    ODataUri actual = QueryNodeUtils.BindQuery(queryBuilder.ToString(), model);

                    // construct the expected order-by node
                    OrderByClause orderByNode = null;
                    for (int i = testCase.ExpectedOrderByExpressions.Length - 1; i >= 0; --i)
                    {
                        orderByNode = new OrderByClause(
                            orderByNode,
                            testCase.ExpectedOrderByExpressions[i],
                            direction ?? OrderByDirection.Ascending,
                            new ResourceRangeVariable(ExpressionConstants.It, model.ResolveTypeReference("TestNS.Customer", false).AsEntity(), model.FindEntityContainer("BinderTestMetadata").FindEntitySet("Customers"))
                            );
                    }

                    QueryNodeUtils.VerifyOrderByClauseAreEqual(
                        orderByNode,
                        actual.OrderBy,
                        this.Assert);
                },
                    testCase.ExpectedExceptionMessage,
                    null);
            });
        }
        public void CustomQueryOptionBinderTest()
        {
            var metadata = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory);

            var testCases = new[]
            {
                new QueryOptionTestCase
                {
                    Query = "/Customers?$foo=12",
                    ExpectedExceptionMessage = "The system query option '$foo' is not supported."
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&c=d",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode("c", "d")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&a=c",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode("a", "c")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?foo",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode(null, "foo")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?foo=",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("foo", string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?&&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                (testCase) =>
            {
                TestExceptionUtils.ExpectedException <ODataException>(
                    this.Assert,
                    () =>
                {
                    SemanticTree actual = QueryNodeUtils.BindQuery(testCase.Query, metadata);
                    QueryNodeUtils.VerifyQueryNodesAreEqual(
                        testCase.ExpectedQueryOptions,
                        actual.CustomQueryOptions,
                        this.Assert);
                },
                    testCase.ExpectedExceptionMessage,
                    null);
            });
        }
예제 #6
0
        public void SkipAndTopBinderTest()
        {
            IEdmModel model = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory);

            var testCases = new[]
            {
                new SkipTopTestCase
                {
                    Query = "/Customers?$skip=2",
                    ExpectedSkipClause = 2
                },
                new SkipTopTestCase
                {
                    Query             = "/Customers?$top=2",
                    ExpectedTopClause = 2
                },
                new SkipTopTestCase
                {
                    Query              = "/Customers?$skip=3&$top=2",
                    ExpectedTopClause  = 2,
                    ExpectedSkipClause = 3
                },
                new SkipTopTestCase
                {
                    Query              = "/Customers?$top=2&$skip=3",
                    ExpectedTopClause  = 2,
                    ExpectedSkipClause = 3
                },
                // TODO: enable those?

                /*
                 * new SkipTopTestCase
                 * {
                 *  Query = "/Customers(0)?$top=100",
                 *  ExpectedExceptionMessage = "The $top query option cannot be applied to the query path. Top can only be applied to a collection of entities."
                 * },
                 * new SkipTopTestCase
                 * {
                 *  Query = "/Customers(0)?$skip=100",
                 *  ExpectedExceptionMessage = "The $skip query option cannot be applied to the query path. Skip can only be applied to a collection of entities."
                 * },
                 * new SkipTopTestCase
                 * {
                 *  Query = "/Customers(0)?$skip=100&top=100",
                 *  ExpectedExceptionMessage = "The $skip query option cannot be applied to the query path. Skip can only be applied to a collection of entities."
                 * },
                 * new SkipTopTestCase
                 * {
                 *  Query = "/Customers(0)?top=100&$skip=100",
                 *  ExpectedExceptionMessage = "The $skip query option cannot be applied to the query path. Skip can only be applied to a collection of entities."
                 * },
                 */
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                (testCase) =>
            {
                TestExceptionUtils.ExpectedException <ODataException>(
                    this.Assert,
                    () =>
                {
                    ODataUri actual = QueryNodeUtils.BindQuery(testCase.Query, model);
                    if (testCase.ExpectedSkipClause != null)
                    {
                        Assert.AreEqual(testCase.ExpectedSkipClause, actual.Skip, "Skip amounts are not equal!");
                    }

                    if (testCase.ExpectedTopClause != null)
                    {
                        Assert.AreEqual(testCase.ExpectedTopClause, actual.Top, "Top amounts are not equal!");
                    }
                },
                    testCase.ExpectedExceptionMessage,
                    null);
            });
        }