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); }); }
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."); }); }
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); }); }
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); }); }