public void InvalidFilterExpressionsTest() { IEnumerable <InvalidExpressionTestCase> testCases = new InvalidExpressionTestCase[] { new InvalidExpressionTestCase { Expression = "", ExpectedErrorMessage = "Expression expected at position 0 in '$(Expression)'." }, }; testCases = testCases.Concat(InvalidExpressionTestCase.InvalidPrimitiveLiteralTestCases); testCases = testCases.Concat(InvalidExpressionTestCase.InvalidExpressionTestCases); this.CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { this.Assert.ExpectedException <ODataException>( () => QueryTokenUtils.ParseQuery("Root", filter: testCase.Expression), StringUtils.ResolveVariables(testCase.ExpectedErrorMessage, new Dictionary <string, string>() { { "Expression", testCase.Expression } }), "The filter parsing should have failed."); }); }
public void FormatExpressionTest() { string[] values = new string[] { "json", "xml", "foo", "bar" }; var testCases = values.Select(value => new { Value = value, }); this.CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { SyntacticTree actual = QueryTokenUtils.ParseQuery("Root", format: testCase.Value); SyntacticTree expected = new SyntacticTree( null, new[] { "Root" }, null, null, null, null, null, null, null, testCase.Value, null); QueryTokenUtils.VerifySyntaxTreesAreEqual(expected, actual, this.Assert); }); }
public void CountExpressionTest() { object[] values = new object[] { null, 0, 1, 2, 5, 11111, -2, 12.3, "Foo", -12.4m, 'c', (long)int.MaxValue + 1, (long)int.MinValue - 1, 2.3f, "(1)", "2 + 3", "int.MaxValue", "false", "true", "False", "True", "FaLSE", "trUE" }; string errorMessageTemplate = "Invalid value '{0}' for $count query option found. Valid values are '{1}'."; HashSet <string> correctValues = new HashSet <string>(StringComparer.OrdinalIgnoreCase) { "true", "false" }; string correctValuesStr = string.Join(", ", correctValues.ToArray()); var testCases = values.Select(value => new { Value = value == null ? null : value.ToString(), ExpectedErrorMessage = value == null || correctValues.Contains(value.ToString()) ? null : string.Format(CultureInfo.InvariantCulture, errorMessageTemplate, value, correctValuesStr).Replace('+', ' ') // URI all + will be replace by space }); this.CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { this.Assert.ExpectedException <ODataException>( () => { SyntacticTree actual = QueryTokenUtils.ParseQuery("Root", count: testCase.Value); bool?countQuery = null; if (testCase.Value != null) { bool countValue; bool.TryParse(testCase.Value, out countValue); countQuery = countValue; } SyntacticTree expected = new SyntacticTree( null, new[] { "Root" }, null, null, null, null, null, null, countQuery, null, null); QueryTokenUtils.VerifySyntaxTreesAreEqual(expected, actual, this.Assert); }, testCase.ExpectedErrorMessage, null); }); }
public void SegmentTests() { var testCases = new [] { new{ Uri = "/Customers", ExpectedNodes = new StartPathToken("Customers", null, null) }, new{ Uri = "/Customers()", ExpectedNodes = new StartPathToken("Customers", null, new NamedValue[0]) }, new{ Uri = "/Customers/$count", ExpectedNodes = (StartPathToken) new KeywordSegmentToken(KeywordKind.Count, new StartPathToken("Customers", null, null)) }, new{ Uri = "/$metadata/Foo", ExpectedNodes = new StartPathToken("Foo", new KeywordSegmentToken(KeywordKind.Metadata, null), null) }, new{ Uri = "/Customers()/$count", ExpectedNodes = (StartPathToken) new KeywordSegmentToken(KeywordKind.Count, new StartPathToken("Customers", null, new NamedValue[0])) }, new{ Uri = "/Customers()/$links/Orders()", ExpectedNodes = new StartPathToken( "Orders", new KeywordSegmentToken(KeywordKind.Links, new StartPathToken("Customers", null, new NamedValue[0])), new NamedValue[0]) }, new{ Uri = "/Customers/$batch", ExpectedNodes = (StartPathToken) new KeywordSegmentToken(KeywordKind.Batch, new StartPathToken("Customers", null, null)) }, new{ Uri = "/Orders/$value", ExpectedNodes = (StartPathToken) new KeywordSegmentToken(KeywordKind.Value, new StartPathToken("Orders", null, null)) }, new{ Uri = "/", ExpectedNodes = new StartPathToken("", null, null) }, }; this.CombinatorialEngineProvider.RunCombinations( testCases, testCase => QueryTokenUtils.VerifyQueryTokensAreEqual( testCase.ExpectedNodes, QueryTokenUtils.ParseQuery(testCase.Uri).Path, this.Assert)); }
public void FilterExpressionTest() { CombinatorialEngineProvider.RunCombinations( ExpressionTestCase.PrimitiveLiteralTestCases() .Concat(ExpressionTestCase.BinaryOperatorTestCases()) .Concat(ExpressionTestCase.UnaryOperatorTestCases()) .Concat(ExpressionTestCase.PropertyAccessTestCases(ExpressionTestCase.PropertyAccessNames)) .Concat(ExpressionTestCase.ParenthesisTestCases()) .Concat(ExpressionTestCase.FunctionCallTestCases()), testCase => QueryTokenUtils.VerifyQueryTokensAreEqual( testCase.ExpectedToken, QueryTokenUtils.ParseQuery("Root", filter: testCase.Expression).Filter, this.Assert)); }
public void InvalidSingleKeyValueTest() { this.CombinatorialEngineProvider.RunCombinations( InvalidExpressionTestCase.InvalidPrimitiveLiteralTestCases, (testCase) => { this.Assert.ExpectedException <ODataException>( () => QueryTokenUtils.ParseQuery("/Customers(" + testCase.Expression + ")"), StringUtils.ResolveVariables(testCase.ExpectedErrorMessage, new Dictionary <string, string>() { { "Expression", testCase.Expression } }), "Parser should fail to parse a key value."); }); }
public void ExpandExpressionTest() { IEnumerable <ExpressionTestCase> expressionTestCases = ExpressionTestCase.PrimitiveLiteralTestCases() .Concat(ExpressionTestCase.BinaryOperatorTestCases()) .Concat(ExpressionTestCase.UnaryOperatorTestCases()) .Concat(ExpressionTestCase.PropertyAccessTestCases(ExpressionTestCase.PropertyAccessNames)) .Concat(ExpressionTestCase.ParenthesisTestCases()) .Concat(ExpressionTestCase.FunctionCallTestCases()); var testCases = expressionTestCases.Select(tc => new ExpandTestCase() { Expand = tc.Expression, ExpectedExpandToken = new ExpandToken(new QueryToken[] { tc.ExpectedToken }) }); // All expressions testCases.Concat(new ExpandTestCase[] { new ExpandTestCase() { Expand = string.Join(", ", expressionTestCases.Select(tc => tc.Expression).ToArray()), ExpectedExpandToken = new ExpandToken(expressionTestCases.Select(tc => tc.ExpectedToken)) } }); this.CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { SyntacticTree actual = QueryTokenUtils.ParseQuery("Root", expand: testCase.Expand); SyntacticTree expected = new SyntacticTree( new SegmentToken("Root", null, null), null, null, null, testCase.ExpectedExpandToken, null, null, null, null, null); QueryTokenUtils.VerifySyntaxTreesAreEqual( expected, actual, this.Assert); }); }
public void InvalidOrderByExpressionsTest() { IEnumerable <InvalidExpressionTestCase> testCases = new InvalidExpressionTestCase[] { new InvalidExpressionTestCase { Expression = "", ExpectedErrorMessage = "Expression expected at position 0 in '$(Expression)'." }, new InvalidExpressionTestCase { Expression = "foo,", ExpectedErrorMessage = "Expression expected at position 4 in '$(Expression)'." }, new InvalidExpressionTestCase { Expression = ",foo", ExpectedErrorMessage = "Expression expected at position 0 in '$(Expression)'." }, new InvalidExpressionTestCase { Expression = "foo asc,", ExpectedErrorMessage = "Expression expected at position 8 in '$(Expression)'." }, new InvalidExpressionTestCase { Expression = "foo desc,", ExpectedErrorMessage = "Expression expected at position 9 in '$(Expression)'." }, new InvalidExpressionTestCase { Expression = "foo asc desc", ExpectedErrorMessage = "Syntax error at position 12 in '$(Expression)'." }, new InvalidExpressionTestCase { Expression = "foo ASC", ExpectedErrorMessage = "Syntax error at position 7 in '$(Expression)'." }, }; testCases = testCases.Concat(InvalidExpressionTestCase.InvalidPrimitiveLiteralTestCases); this.CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { this.Assert.ExpectedException <ODataException>( () => QueryTokenUtils.ParseQuery("Root", orderby: testCase.Expression), StringUtils.ResolveVariables(testCase.ExpectedErrorMessage, new Dictionary <string, string>() { { "Expression", testCase.Expression } }), "The orderby parsing should have failed."); }); }
public void SelectExpressionTest() { IEnumerable <SelectExpressionTestCase> expressionTestCases = SelectExpressionTestCase.SelectPropertyAccessTestCases(ExpressionTestCase.PropertyAccessNames); var testCases = expressionTestCases.Select(tc => new SelectTestCase() { Select = tc.Expression, ExpectedSelectToken = new SelectToken(new PathSegmentToken[] { tc.ExpectedToken }) }); // All expressions testCases.Concat(new SelectTestCase[] { new SelectTestCase() { Select = string.Join(", ", expressionTestCases.Select(tc => tc.Expression).ToArray()), ExpectedSelectToken = new SelectToken(expressionTestCases.Select(tc => tc.ExpectedToken)) } }); this.CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { SyntacticTree actual = QueryTokenUtils.ParseQuery("Root", select: testCase.Select); SyntacticTree expected = new SyntacticTree( new StartPathToken("Root", null, null), null, null, testCase.ExpectedSelectToken, null, null, null, null, null, null); QueryTokenUtils.VerifySyntaxTreesAreEqual( expected, actual, this.Assert); }); }
public void UriVariationExpressionsTest() { IEnumerable <ExpressionTestCase> testCases = new ExpressionTestCase[] { // Uri query where + instead of space is in Uri text new ExpressionTestCase { Expression = "1+lt+2+and+true+ne+false", ExpectedToken = new BinaryOperatorToken( BinaryOperatorKind.And, new BinaryOperatorToken(BinaryOperatorKind.LessThan, new LiteralToken(1), new LiteralToken(2)), new BinaryOperatorToken(BinaryOperatorKind.NotEqual, new LiteralToken(true), new LiteralToken(false))) } }; CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { QueryTokenUtils.VerifyQueryTokensAreEqual( testCase.ExpectedToken, QueryTokenUtils.ParseQuery("Root", filter: testCase.Expression).Filter, this.Assert); }); }
public void OrderByExpressionTest() { IEnumerable <ExpressionTestCase> expressionTestCases = ExpressionTestCase.PrimitiveLiteralTestCases() .Concat(ExpressionTestCase.BinaryOperatorTestCases()) .Concat(ExpressionTestCase.UnaryOperatorTestCases()) .Concat(ExpressionTestCase.PropertyAccessTestCases(ExpressionTestCase.PropertyAccessNames)) .Concat(ExpressionTestCase.ParenthesisTestCases()) .Concat(ExpressionTestCase.FunctionCallTestCases()); // Use filter expressions first without anything var filterWithNoDirection = expressionTestCases.Select(tc => new OrderByTestCase() { OrderBy = tc.Expression, ExpectedOrderByTokens = new OrderByToken[] { new OrderByToken(tc.ExpectedToken, OrderByDirection.Ascending) } }); // Use filter expressions with asc var filterWithAscending = expressionTestCases.Select(tc => new OrderByTestCase() { OrderBy = tc.Expression + " asc", ExpectedOrderByTokens = new OrderByToken[] { new OrderByToken(tc.ExpectedToken, OrderByDirection.Ascending) } }); // Use filter expressions with desc var filterWithDescending = expressionTestCases.Select(tc => new OrderByTestCase() { OrderBy = tc.Expression + " desc", ExpectedOrderByTokens = new OrderByToken[] { new OrderByToken(tc.ExpectedToken, OrderByDirection.Descending) } }); // And now some order by specific cases with multiple orderbys var orderByTestCases = ExpressionTestCase.VariousExpressions().ToList().Variations(3).Select(tc => new OrderByTestCase { OrderBy = string.Join(",", tc.Select((t, index) => t.Expression + ((index % 3 == 0) ? "" : ((index % 3 == 1) ? " asc" : " desc"))).ToArray()), ExpectedOrderByTokens = tc.Select((t, index) => new OrderByToken( t.ExpectedToken, (index % 3 == 2) ? OrderByDirection.Descending : OrderByDirection.Ascending)).ToArray() }); CombinatorialEngineProvider.RunCombinations( filterWithNoDirection .Concat(filterWithAscending) .Concat(filterWithDescending) .Concat(orderByTestCases), (testCase) => { SyntacticTree actual = QueryTokenUtils.ParseQuery("Root", orderby: testCase.OrderBy); SyntacticTree expected = new SyntacticTree( null, new[] { "Root" }, null, testCase.ExpectedOrderByTokens, null, null, null, null, null, null, null); QueryTokenUtils.VerifySyntaxTreesAreEqual( expected, actual, this.Assert); }); }
public void InvalidKeyValuesTest() { var testCases = new[] { new { KeyValues = "(", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(42", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(42,", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(Key)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(Key,0)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(Key=Key)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "\t( Key = eq)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(eq)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "\t( gt )", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "\t(()", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(-INFI)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(INFI)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(-NaNn)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, new { KeyValues = "(NaNn)", ExpectedErrorMessage = "Bad Request: there was an error in the query syntax." }, }; var keyValuesContainers = new string[] { "/Customers{0}", "/Customers{0}/Orders", "/Customers(0)/Orders{0}", "/Customers(0)/$links/Orders{0}" }; this.CombinatorialEngineProvider.RunCombinations( testCases, keyValuesContainers, (testCase, keyValuesContainer) => { this.Assert.ExpectedException <ODataException>( () => QueryTokenUtils.ParseQuery(string.Format(keyValuesContainer, testCase.KeyValues)), testCase.ExpectedErrorMessage, "Parser should fail to parse a key value."); }); }
public void KeyValuesTest() { IEnumerable <KeyValuesTestCase> testCases = new[] { new KeyValuesTestCase { KeyValues = "()", ExpectedKeyValues = new NamedValue[0] }, new KeyValuesTestCase { KeyValues = "(0)", ExpectedKeyValues = new [] { new NamedValue(null, new LiteralToken(0)) } }, new KeyValuesTestCase { KeyValues = "(0,1)", ExpectedKeyValues = new [] { new NamedValue(null, new LiteralToken(0)), new NamedValue(null, new LiteralToken(1)) } }, new KeyValuesTestCase { KeyValues = "(Key='some')", ExpectedKeyValues = new [] { new NamedValue("Key", new LiteralToken("some")), } }, new KeyValuesTestCase { KeyValues = "(Key=datetime'2010-12-09T14:10:20')", ExpectedKeyValues = new [] { new NamedValue("Key", new LiteralToken(new DateTime(2010, 12, 9, 14, 10, 20))) } }, new KeyValuesTestCase { KeyValues = "(Key1=42.42, Key2=42f)", ExpectedKeyValues = new [] { new NamedValue("Key1", new LiteralToken((double)42.42)), new NamedValue("Key2", new LiteralToken((Single)42)) } }, new KeyValuesTestCase { KeyValues = "(Key=1,Key=2)", ExpectedKeyValues = new [] { new NamedValue("Key", new LiteralToken(1)), new NamedValue("Key", new LiteralToken(2)) } }, }; testCases.Concat(ExpressionTestCase.PrimitiveLiteralTestCases().Select(tc => new KeyValuesTestCase() { KeyValues = "(" + tc.Expression + ")", ExpectedKeyValues = new[] { new NamedValue(null, (LiteralToken)tc.ExpectedToken) } })); this.CombinatorialEngineProvider.RunCombinations( testCases, testCase => QueryTokenUtils.VerifyQueryTokensAreEqual( new StartPathToken("Customers", null, testCase.ExpectedKeyValues), QueryTokenUtils.ParseQuery("/Customers" + testCase.KeyValues).Path, this.Assert)); }
void RunTest(bool includeSpaceAroundSymbols) { var testCases = new[] { new { QueryOptions = (List <KeyValuePair <string, string> >)null, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("$filter", "3 eq 2") }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("CustomValue", "null") }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("null", "CustomValue") }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("$custom", "2") }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("$a", "1"), new KeyValuePair <string, string>("$b", "2"), }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("a", "1"), new KeyValuePair <string, string>("$filter", "3 eq 2"), new KeyValuePair <string, string>("b", "2"), }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("$a", "1"), new KeyValuePair <string, string>("$filter", "3 eq 2"), new KeyValuePair <string, string>("$b", "2"), }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("a", "1"), new KeyValuePair <string, string>("b", "2"), new KeyValuePair <string, string>("a", "2"), new KeyValuePair <string, string>("b", "4"), }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("$filter", "3 eq 2"), new KeyValuePair <string, string>("$filter", "2 eq 3"), new KeyValuePair <string, string>("$b", "2"), }, ExpectedErrorMessage = "Query option '$filter' was specified more than once, but it must be specified at most once.", }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("$select", "Name") }, ExpectedErrorMessage = (string)null, }, new { QueryOptions = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("$expand", "Products") }, ExpectedErrorMessage = (string)null, }, }; this.CombinatorialEngineProvider.RunCombinations( testCases, (testCase) => { this.Assert.ExpectedException <ODataException>( () => { SyntacticTree actual = QueryTokenUtils.ParseQuery("Root", testCase.QueryOptions, includeSpaceAroundSymbols); List <CustomQueryOptionToken> options = QueryTokenUtils.NormalizeAndRemoveBuiltInQueryOptions(testCase.QueryOptions); options = options != null && options.Count == 0 ? null : options; SyntacticTree expected = new SyntacticTree( null, new[] { "Feed" }, actual.Filter, actual.OrderByTokens, null, null, actual.Skip, null, null, null, options); QueryTokenUtils.VerifySyntaxTreesAreEqual(expected, actual, this.Assert); }, testCase.ExpectedErrorMessage, null); }); }