示例#1
0
        public void QueryExpressionEqualityComparer_ScopeTracking()
        {
            var comparer = new QueryExpressionEqualityComparator();
            var p1       = Expression.Parameter(typeof(int));
            var p2       = Expression.Parameter(typeof(int));
            var p3       = Expression.Parameter(typeof(int));

            {
                var fst =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                Expression.Add(p1, p2),
                                p1,
                                p2,
                                p3
                                ),
                            new QueryTree[] { null, null, null }.ToReadOnly()
                            )
                        );

                var snd =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                Expression.Add(p1, p2),
                                p2,
                                p1,
                                p3
                                ),
                            new QueryTree[] { null, null, null }.ToReadOnly()
                            )
                        );

                Assert.IsFalse(comparer.Equals(fst, snd));
            }

            // Test that alpha renaming doesn't affect equality
            {
                var fst =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                Expression.Add(p1, p2),
                                p1,
                                p2,
                                p3
                                ),
                            new QueryTree[] { null, null, null }.ToReadOnly()
                            )
                        );

                var snd =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                Expression.Add(p2, p1),
                                p2,
                                p1,
                                p3
                                ),
                            new QueryTree[] { null, null, null }.ToReadOnly()
                            )
                        );

                Assert.IsTrue(comparer.Equals(fst, snd));
                Assert.AreEqual(comparer.GetHashCode(fst), comparer.GetHashCode(snd));
            }

            // Scope tracking for reference equal parameter expressions when they are "redefined" in inner lambda
            {
                var fst =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                p1,
                                p1
                                ),
                            new QueryTree[]
                {
                    new LambdaAbstraction(
                        Expression.Lambda(
                            p1,
                            p1
                            ),
                        new QueryTree[] { null }.ToReadOnly()
                        )
                }.ToReadOnly()
                            )
                        );

                var snd =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                p1,
                                p1
                                ),
                            new QueryTree[]
                {
                    new LambdaAbstraction(
                        Expression.Lambda(
                            p1,
                            p2
                            ),
                        new QueryTree[] { null }.ToReadOnly()
                        )
                }.ToReadOnly()
                            )
                        );

                Assert.ThrowsException <InvalidOperationException>(() => comparer.Equals(fst, snd));
                Assert.ThrowsException <InvalidOperationException>(() => comparer.GetHashCode(snd));
            }

            {
                var fst =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                p1,
                                p1
                                ),
                            new QueryTree[]
                {
                    new LambdaAbstraction(
                        Expression.Lambda(
                            p1,
                            p1
                            ),
                        new QueryTree[] { null }.ToReadOnly()
                        )
                }.ToReadOnly()
                            )
                        );

                var snd =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                p1,
                                p1
                                ),
                            new QueryTree[]
                {
                    new LambdaAbstraction(
                        Expression.Lambda(
                            p1,
                            p1
                            ),
                        new QueryTree[] { null }.ToReadOnly()
                        )
                }.ToReadOnly()
                            )
                        );

                Assert.IsTrue(comparer.Equals(fst, snd));
                Assert.AreEqual(comparer.GetHashCode(fst), comparer.GetHashCode(snd));
            }

            {
                var fst =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                p1,
                                p1
                                ),
                            new QueryTree[]
                {
                    new LambdaAbstraction(
                        Expression.Lambda(
                            p1,
                            p2
                            ),
                        new QueryTree[] { null }.ToReadOnly()
                        )
                }.ToReadOnly()
                            )
                        );

                var snd =
                    new WhereOperator(
                        typeof(int),
                        null,
                        new LambdaAbstraction(
                            Expression.Lambda(
                                p1,
                                p1
                                ),
                            new QueryTree[]
                {
                    new LambdaAbstraction(
                        Expression.Lambda(
                            p1,
                            p2
                            ),
                        new QueryTree[] { null }.ToReadOnly()
                        )
                }.ToReadOnly()
                            )
                        );

                Assert.ThrowsException <InvalidOperationException>(() => comparer.Equals(fst, snd));
                Assert.ThrowsException <InvalidOperationException>(() => comparer.GetHashCode(snd));
            }
        }
        public void QueryExpressionFactory_ArgumentChecks()
        {
            var factory            = DefaultQueryExpressionFactory.Instance;
            var unsafeFactory      = new UnsafeQueryExpressionFactory();
            var comparer           = new QueryExpressionEqualityComparator();
            var type1              = typeof(Exception);
            var type2              = typeof(ArgumentException);
            var type3              = typeof(ArgumentNullException);
            var lambdaAbstraction1 = factory.LambdaAbstraction(Expression.Lambda(Expression.Default(type1)));
            var lambdaAbstraction2 = factory.LambdaAbstraction(Expression.Lambda(Expression.Default(type2)));
            var monadMember1       = factory.MonadAbstraction(type1, lambdaAbstraction1);
            var monadMember2       = factory.MonadAbstraction(type2, lambdaAbstraction2);

            // First
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.First(default(Type), default), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.First(default(Type), monadMember1), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.First(type1, source: null), AssertParameterName("source"));
            AssertEx.ThrowsException <ArgumentException>(() => factory.First(type2, monadMember1), AssertParameterName("elementType"));
            Assert.IsTrue(comparer.Equals(
                              factory.First(type1, monadMember2),
                              unsafeFactory.First(type1, monadMember2)
                              ));

            // First Predicate
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.First(elementType: null, source: null, predicate: null), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.First(elementType: null, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.First(type1, source: null, lambdaAbstraction1), AssertParameterName("source"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.First(type1, monadMember1, predicate: null), AssertParameterName("predicate"));
            AssertEx.ThrowsException <ArgumentException>(() => factory.First(type2, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            Assert.IsTrue(comparer.Equals(
                              factory.First(type1, monadMember2, lambdaAbstraction1),
                              unsafeFactory.First(type1, monadMember2, lambdaAbstraction1)
                              ));

            // Select
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Take(elementType: null, source: null, count: null), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Take(elementType: null, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Take(type1, source: null, lambdaAbstraction1), AssertParameterName("source"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Take(type1, monadMember1, count: null), AssertParameterName("count"));
            AssertEx.ThrowsException <ArgumentException>(() => factory.Take(type2, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            Assert.IsTrue(comparer.Equals(
                              factory.Take(type1, monadMember2, lambdaAbstraction1),
                              unsafeFactory.Take(type1, monadMember2, lambdaAbstraction1)
                              ));

            // Take
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Select(elementType: null, inputElementType: null, source: null, selector: null), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Select(elementType: null, type3, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Select(type1, inputElementType: null, monadMember1, lambdaAbstraction1), AssertParameterName("inputElementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Select(type1, type3, source: null, lambdaAbstraction1), AssertParameterName("source"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Select(type1, type3, monadMember1, selector: null), AssertParameterName("selector"));
            AssertEx.ThrowsException <ArgumentException>(() => factory.Select(type2, type3, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            Assert.IsTrue(comparer.Equals(
                              factory.Select(type3, type1, monadMember2, lambdaAbstraction1),
                              unsafeFactory.Select(type3, type1, monadMember2, lambdaAbstraction1)
                              ));

            // Where
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Where(elementType: null, source: null, predicate: null), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Where(elementType: null, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Where(type1, source: null, lambdaAbstraction1), AssertParameterName("source"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.Where(type1, monadMember1, predicate: null), AssertParameterName("predicate"));
            AssertEx.ThrowsException <ArgumentException>(() => factory.Where(type2, monadMember1, lambdaAbstraction1), AssertParameterName("elementType"));
            Assert.IsTrue(comparer.Equals(
                              factory.Where(type1, monadMember2, lambdaAbstraction1),
                              unsafeFactory.Where(type1, monadMember2, lambdaAbstraction1)
                              ));

            // Monad Member
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.MonadAbstraction(elementType: null, inner: null), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.MonadAbstraction(elementType: null, lambdaAbstraction1), AssertParameterName("elementType"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.MonadAbstraction(type1, inner: null), AssertParameterName("inner"));
            Assert.IsTrue(comparer.Equals(
                              factory.MonadAbstraction(type1, lambdaAbstraction1),
                              unsafeFactory.MonadAbstraction(type1, lambdaAbstraction1)
                              ));


            // Lambda Abstraction
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.LambdaAbstraction(body: null), AssertParameterName("body"));
            Assert.ThrowsException <ArgumentException>(() => factory.LambdaAbstraction(Expression.Lambda(Expression.Empty(), Expression.Parameter(type1))));
            Assert.IsTrue(comparer.Equals(
                              factory.LambdaAbstraction(Expression.Lambda(Expression.Empty())),
                              unsafeFactory.LambdaAbstraction(Expression.Lambda(Expression.Empty()), Enumerable.Empty <QueryTree>())
                              ));

            AssertEx.ThrowsException <ArgumentNullException>(() => factory.LambdaAbstraction(body: null, parameters: null), AssertParameterName("body"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.LambdaAbstraction(body: null, Array.Empty <QueryTree>().ToReadOnly()), AssertParameterName("body"));
            AssertEx.ThrowsException <ArgumentNullException>(() => factory.LambdaAbstraction(Expression.Lambda(Expression.Empty(), Expression.Parameter(type1)), parameters: null), AssertParameterName("parameters"));

            Assert.ThrowsException <ArgumentException>(() => factory.LambdaAbstraction(Expression.Lambda(Expression.Empty(), Expression.Parameter(type1)), Array.Empty <QueryTree>().ToReadOnly()));
            Assert.IsTrue(comparer.Equals(
                              factory.LambdaAbstraction(Expression.Lambda(Expression.Empty(), Expression.Parameter(type1)), new QueryTree[] { monadMember1 }.ToReadOnly()),
                              unsafeFactory.LambdaAbstraction(Expression.Lambda(Expression.Empty(), Expression.Parameter(type1)), new QueryTree[] { monadMember1 }.ToReadOnly())
                              ));
        }