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);
                });
        }
예제 #2
0
        /// <summary>
        /// Parses the full Uri.
        /// </summary>
        /// <returns>An ODataUri representing the full uri</returns>
        private ODataUri ParseUriImplementation()
        {
            ExceptionUtils.CheckArgumentNotNull(this.configuration.Model, "model");
            ExceptionUtils.CheckArgumentNotNull(this.ServiceRoot, "serviceRoot");
            ExceptionUtils.CheckArgumentNotNull(this.fullUri, "fullUri");

            SyntacticTree syntax = SyntacticTree.ParseUri(this.fullUri, this.ServiceRoot, this.Settings.FilterLimit);

            ExceptionUtils.CheckArgumentNotNull(syntax, "syntax");
            BindingState           state     = new BindingState(this.configuration);
            MetadataBinder         binder    = new MetadataBinder(state);
            ODataUriSemanticBinder uriBinder = new ODataUriSemanticBinder(state, binder.Bind);

            return(uriBinder.BindTree(syntax));
        }
예제 #3
0
 private static void VerifySyntaxTreesAreEqualImpl(SyntacticTree expected, SyntacticTree actual, AssertionHandler assert)
 {
     VerifyStringsAreEqual(expected.Path, actual.Path, assert);
     VerifyQueryTokensAreEqual(expected.Filter, actual.Filter, assert);
     if (expected.OrderByTokens != null && actual.OrderByTokens != null)
         VerifyQueryTokensAreEqual(expected.OrderByTokens.Cast<QueryToken>(), actual.OrderByTokens.Cast<QueryToken>(), assert);
     else if ((expected.OrderByTokens != null && actual.OrderByTokens == null) || (expected.OrderByTokens == null && actual.OrderByTokens != null))
         assert.Fail("Query tokens are different");
     assert.AreEqual(expected.Skip, actual.Skip, "Skip values are different.");
     VerificationUtils.VerifyEnumerationsAreEqual(
         expected.QueryOptions,
         actual.QueryOptions,
         VerifyCustomQueryOptionQueryTokensAreEqual,
         (item) => item.ToDebugString(),
         assert);
 }
예제 #4
0
 /// <summary>
 /// Verifies that two queries are equal.
 /// </summary>
 /// <param name="expected">The expected query.</param>
 /// <param name="actual">The actual query.</param>
 /// <param name="assert">Assertion handler to use.</param>
 internal static void VerifySyntaxTreesAreEqual(SyntacticTree expected, SyntacticTree actual, AssertionHandler assert)
 {
     try
     {
         if (!VerifyNullnessMatches(expected, actual, assert, "query")) return;
         VerifySyntaxTreesAreEqualImpl(expected, actual, assert);
     }
     catch (Exception)
     {
         assert.Warn("Expected query: " + expected.ToDebugString());
         assert.Warn("Actual query: " + actual.ToDebugString());
         throw;
     }
 }
        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);
                });
        }
예제 #6
0
        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);
                });
        }
        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);
                });
        }