public void ConditionalIndex_Factory_Expression()
        {
            var obj = Expression.Constant(new S("foo"));
            var substring = PropertyInfoOf((S s) => s[default(int), default(int)]);
            var substringGet = substring.GetGetMethod(true);

            var args = new[] { Expression.Constant(1) };

            foreach (var e in new[]
            {
                CSharpExpression.ConditionalIndex(obj, substring, args),
                CSharpExpression.ConditionalIndex(obj, substring, args.AsEnumerable()),
            })
            {
                Assert.AreSame(obj, e.Object);

                Assert.AreEqual(1, e.Arguments.Count);

                Assert.AreEqual(substring.GetIndexParameters()[0], e.Arguments[0].Parameter);

                Assert.AreSame(args[0], e.Arguments[0].Expression);
            }

            foreach (var e in new[]
            {
                CSharpExpression.ConditionalIndex(obj, substringGet, args),
                CSharpExpression.ConditionalIndex(obj, substringGet, args.AsEnumerable()),
            })
            {
                Assert.AreSame(obj, e.Object);

                Assert.AreEqual(1, e.Arguments.Count);

                Assert.AreEqual(substringGet.GetParameters()[0], e.Arguments[0].Parameter);

                Assert.AreSame(args[0], e.Arguments[0].Expression);
            }

            var tooLittle = new Expression[0];

            foreach (var f in new Func<ConditionalIndexCSharpExpression>[]
            {
                () => CSharpExpression.ConditionalIndex(obj, substring, tooLittle),
                () => CSharpExpression.ConditionalIndex(obj, substring, tooLittle.AsEnumerable()),
            })
            {
                AssertEx.Throws<ArgumentException>(() => f());
            }

            var tooMany = new[] { Expression.Constant(1), Expression.Constant(2), Expression.Constant(3) };

            foreach (var f in new Func<ConditionalIndexCSharpExpression>[]
            {
                () => CSharpExpression.ConditionalIndex(obj, substring, tooMany),
                () => CSharpExpression.ConditionalIndex(obj, substring, tooMany.AsEnumerable()),
            })
            {
                AssertEx.Throws<ArgumentException>(() => f());
            }
        }
        public void IndexInit_Factory_ArgumentChecking()
        {
            var index = PropertyInfoOf((Dictionary<string, int> d) => d[default(string)]);
            var setter = index.GetSetMethod(true);
            var args = new[] { Expression.Constant("bar") };
            var value = Expression.Constant(42);

            var xIndex = typeof(X).GetProperty("Item");

            // null
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(default(PropertyInfo), args, value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(default(PropertyInfo), args.AsEnumerable(), value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(index, default(Expression[]), value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(index, default(IEnumerable<Expression>), value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(index, args, default(Expression)));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(index, args.AsEnumerable(), default(Expression)));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(default(MethodInfo), args, value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(default(MethodInfo), args.AsEnumerable(), value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(setter, default(Expression[]), value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(setter, default(IEnumerable<Expression>), value));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(setter, args, default(Expression)));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.IndexInit(setter, args.AsEnumerable(), default(Expression)));

            // only getter
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.IndexInit(xIndex, new[] { value }, value));

            // argument types
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.IndexInit(index, new[] { value }, value));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.IndexInit(setter, new[] { value }, value));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.IndexInit(index, args, args[0]));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.IndexInit(setter, args, args[0]));
        }
        public void ConditionalCall_Factory_Expression()
        {
            var method = MethodInfoOf((C c) => c.F(default(int), default(int), default(int)));

            var obj = Expression.Constant(new C());
            var args = new[] { Expression.Constant(1), Expression.Constant(2) };

            foreach (var e in new[]
            {
                CSharpExpression.ConditionalCall(obj, method, args),
                CSharpExpression.ConditionalCall(obj, method, args.AsEnumerable()),
            })
            {
                Assert.AreSame(obj, e.Object);

                Assert.AreEqual(method, e.Method);

                Assert.AreEqual(2, e.Arguments.Count);

                Assert.AreEqual(method.GetParameters()[0], e.Arguments[0].Parameter);
                Assert.AreEqual(method.GetParameters()[1], e.Arguments[1].Parameter);

                Assert.AreSame(args[0], e.Arguments[0].Expression);
                Assert.AreSame(args[1], e.Arguments[1].Expression);
            }

            var tooLittle = args.Take(1);

            foreach (var f in new Func<ConditionalMethodCallCSharpExpression>[]
            {
                () => CSharpExpression.ConditionalCall(obj, method, tooLittle),
                () => CSharpExpression.ConditionalCall(obj, method, tooLittle.AsEnumerable()),
            })
            {
                AssertEx.Throws<ArgumentException>(() => f());
            }

            var tooMany = args.Concat(args).ToArray();

            foreach (var f in new Func<ConditionalMethodCallCSharpExpression>[]
            {
                () => CSharpExpression.ConditionalCall(obj, method, tooMany),
                () => CSharpExpression.ConditionalCall(obj, method, tooMany.AsEnumerable()),
            })
            {
                AssertEx.Throws<ArgumentException>(() => f());
            }
        }
        public void ConditionalArrayIndex_Properties()
        {
            var array = Expression.Default(typeof(string[]));
            var indexes = new[] { Expression.Constant(0) };

            foreach (var e in new[]
            {
                CSharpExpression.ConditionalArrayIndex(array, indexes),
                CSharpExpression.ConditionalArrayIndex(array, indexes.AsEnumerable()),
            })
            {
                Assert.AreEqual(CSharpExpressionType.ConditionalAccess, e.CSharpNodeType);
                Assert.AreSame(array, e.Array);
                Assert.AreEqual(typeof(string), e.Type);
                Assert.IsTrue(e.Indexes.SequenceEqual(indexes));
            }
        }
        public void ConditionalInvoke_Factory_Expression()
        {
            var function = Expression.Constant(new D((x, y) => x + y));
            var method = typeof(D).GetMethod("Invoke");

            var args = new[] { Expression.Constant(1) };

            foreach (var e in new[]
            {
                CSharpExpression.ConditionalInvoke(function, args),
                CSharpExpression.ConditionalInvoke(function, args.AsEnumerable()),
            })
            {
                Assert.AreSame(function, e.Expression);

                Assert.AreEqual(1, e.Arguments.Count);

                Assert.AreEqual(method.GetParameters()[0], e.Arguments[0].Parameter);

                Assert.AreSame(args[0], e.Arguments[0].Expression);
            }

            var tooLittle = new Expression[0];

            foreach (var f in new Func<ConditionalInvocationCSharpExpression>[]
            {
                () => CSharpExpression.ConditionalInvoke(function, tooLittle),
                () => CSharpExpression.ConditionalInvoke(function, tooLittle.AsEnumerable()),
            })
            {
                AssertEx.Throws<ArgumentException>(() => f());
            }

            var tooMany = new[] { Expression.Constant(1), Expression.Constant(2), Expression.Constant(3) };

            foreach (var f in new Func<ConditionalInvocationCSharpExpression>[]
            {
                () => CSharpExpression.ConditionalInvoke(function, tooMany),
                () => CSharpExpression.ConditionalInvoke(function, tooMany.AsEnumerable()),
            })
            {
                AssertEx.Throws<ArgumentException>(() => f());
            }
        }
Example #6
0
        public void For_Factory_ArgumentChecking()
        {
            var i = Expression.Parameter(typeof(int));
            var initializers = new[] { Expression.Assign(i, Expression.Constant(0)) };
            var iterators = new[] { Expression.PostIncrementAssign(i) };
            var test = Expression.Constant(true);
            var body = Expression.Empty();
            var breakLabel = Expression.Label();
            var continueLabel = Expression.Label();

            // null
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.For(initializers, test, iterators, default(Expression)));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.For(initializers, test, iterators, default(Expression), breakLabel));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.For(initializers, test, iterators, default(Expression), breakLabel, continueLabel));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.For(new[] { i }, initializers, test, iterators, default(Expression)));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.For(new[] { i }, initializers, test, iterators, default(Expression), breakLabel));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.For(new[] { i }, initializers, test, iterators, default(Expression), breakLabel, continueLabel));

            // non-bool
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(initializers, Expression.Default(typeof(int)), iterators, body));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(initializers, Expression.Default(typeof(int)), iterators, body, breakLabel));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(initializers, Expression.Default(typeof(int)), iterators, body, breakLabel, continueLabel));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { i }, initializers, Expression.Default(typeof(int)), iterators, body));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { i }, initializers, Expression.Default(typeof(int)), iterators, body, breakLabel));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { i }, initializers, Expression.Default(typeof(int)), iterators, body, breakLabel, continueLabel));

            // labels must be void
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(initializers, test, iterators, body, Expression.Label(typeof(int))));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(initializers, test, iterators, body, breakLabel, Expression.Label(typeof(int))));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { i }, initializers, test, iterators, body, Expression.Label(typeof(int))));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { i }, initializers, test, iterators, body, breakLabel, Expression.Label(typeof(int))));

            // duplicate variable
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(initializers.Concat(initializers), test, iterators, body));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { i, i }, initializers, test, iterators, body, breakLabel, continueLabel));

            // invalid initializer
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { Expression.Add(i, i) }, test, iterators, body));

            // duplicate labels
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(initializers, test, iterators, body, breakLabel, breakLabel));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.For(new[] { i }, initializers, test, iterators, body, breakLabel, breakLabel));
        }
        public void ConditionalArrayIndex_Update()
        {
            var array = Expression.Default(typeof(string[]));
            var indexes = new[] { Expression.Constant(0) };

            var res = CSharpExpression.ConditionalArrayIndex(array, indexes);

            Assert.AreSame(res, res.Update(res.Array, res.Indexes));

            var obj1 = Expression.Default(typeof(string[]));
            var upd1 = res.Update(obj1, res.Indexes);
            Assert.AreNotSame(upd1, res);
            Assert.AreSame(res.Indexes, upd1.Indexes);
            Assert.AreSame(obj1, upd1.Array);

            var upd2 = res.Update(array, new[] { indexes[0] });
            Assert.AreNotSame(upd2, res);
            Assert.AreSame(res.Array, upd2.Array);
            Assert.IsTrue(upd2.Indexes.SequenceEqual(new[] { indexes[0] }));
        }
        public void ConditionalArrayIndex_Factory_ArgumentChecking()
        {
            var array = Expression.Default(typeof(string[]));
            var indexes = new[] { Expression.Constant(1) };

            // null
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.ConditionalArrayIndex(default(Expression), indexes));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.ConditionalArrayIndex(array, default(Expression[])));
            AssertEx.Throws<ArgumentNullException>(() => CSharpExpression.ConditionalArrayIndex(array, default(IEnumerable<Expression>)));

            // not an array
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.ConditionalArrayIndex(Expression.Default(typeof(long))));

            // wrong amount of indexes
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.ConditionalArrayIndex(Expression.Default(typeof(string[]))));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.ConditionalArrayIndex(Expression.Default(typeof(string[])), Expression.Constant(1), Expression.Constant(2)));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.ConditionalArrayIndex(Expression.Default(typeof(string[,]))));
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.ConditionalArrayIndex(Expression.Default(typeof(string[,])), Expression.Constant(1)));

            // indexes not of type int
            AssertEx.Throws<ArgumentException>(() => CSharpExpression.ConditionalArrayIndex(Expression.Default(typeof(string[,])), Expression.Constant(1), Expression.Constant("bar")));
        }
 public void ConditionalArrayIndex_Compile_Ref_Multidimensional()
 {
     var px = Expression.Parameter(typeof(string[,]));
     var ax = new[] { Expression.Constant(0), Expression.Constant(0) };
     var mx = CSharpExpression.ConditionalArrayIndex(px, ax);
     var fx = Expression.Lambda<Func<string[,], string>>(mx, px);
     var dx = fx.Compile();
     Assert.AreEqual("bar", dx(new string[1, 1] { { "bar" } }));
     Assert.IsNull(dx(null));
 }
 public void ConditionalArrayIndex_Compile_Val_Multidimensional()
 {
     var px = Expression.Parameter(typeof(int[,]));
     var ax = new[] { Expression.Constant(0), Expression.Constant(0) };
     var mx = CSharpExpression.ConditionalArrayIndex(px, ax);
     var fx = Expression.Lambda<Func<int[,], int?>>(mx, px);
     var dx = fx.Compile();
     Assert.AreEqual(42, dx(new int[1, 1] { { 42 } }));
     Assert.IsNull(dx(null));
 }
Example #11
0
        public void For_Properties()
        {
            var i = Expression.Parameter(typeof(int));
            var initializers = new[] { Expression.Assign(i, Expression.Constant(0)) };
            var iterators = new[] { Expression.PostIncrementAssign(i) };
            var test = Expression.Constant(true);
            var body = Expression.Empty();
            var breakLabel = Expression.Label();
            var continueLabel = Expression.Label();

            {
                var res = CSharpExpression.For(initializers, test, iterators, body);

                Assert.AreEqual(CSharpExpressionType.For, res.CSharpNodeType);
                Assert.AreEqual(typeof(void), res.Type);
                Assert.IsTrue(new[] { i }.SequenceEqual(res.Variables));
                Assert.IsTrue(initializers.SequenceEqual(res.Initializers));
                Assert.AreSame(test, res.Test);
                Assert.IsTrue(iterators.SequenceEqual(res.Iterators));
                Assert.AreSame(body, res.Body);
                Assert.IsNull(res.BreakLabel);
                Assert.IsNull(res.ContinueLabel);
            }

            {
                var res = CSharpExpression.For(initializers, test, iterators, body, breakLabel);

                Assert.AreEqual(CSharpExpressionType.For, res.CSharpNodeType);
                Assert.AreEqual(typeof(void), res.Type);
                Assert.IsTrue(new[] { i }.SequenceEqual(res.Variables));
                Assert.IsTrue(initializers.SequenceEqual(res.Initializers));
                Assert.AreSame(test, res.Test);
                Assert.IsTrue(iterators.SequenceEqual(res.Iterators));
                Assert.AreSame(body, res.Body);
                Assert.AreSame(breakLabel, res.BreakLabel);
                Assert.IsNull(res.ContinueLabel);
            }

            {
                var res = CSharpExpression.For(initializers, test, iterators, body, breakLabel, continueLabel);

                Assert.AreEqual(CSharpExpressionType.For, res.CSharpNodeType);
                Assert.AreEqual(typeof(void), res.Type);
                Assert.IsTrue(new[] { i }.SequenceEqual(res.Variables));
                Assert.IsTrue(initializers.SequenceEqual(res.Initializers));
                Assert.AreSame(test, res.Test);
                Assert.IsTrue(iterators.SequenceEqual(res.Iterators));
                Assert.AreSame(body, res.Body);
                Assert.AreSame(breakLabel, res.BreakLabel);
                Assert.AreSame(continueLabel, res.ContinueLabel);
            }

            {
                var res = CSharpExpression.For(new[] { i }, initializers, test, iterators, body);

                Assert.AreEqual(CSharpExpressionType.For, res.CSharpNodeType);
                Assert.AreEqual(typeof(void), res.Type);
                Assert.IsTrue(new[] { i }.SequenceEqual(res.Variables));
                Assert.IsTrue(initializers.SequenceEqual(res.Initializers));
                Assert.AreSame(test, res.Test);
                Assert.IsTrue(iterators.SequenceEqual(res.Iterators));
                Assert.AreSame(body, res.Body);
                Assert.IsNull(res.BreakLabel);
                Assert.IsNull(res.ContinueLabel);
            }

            {
                var res = CSharpExpression.For(new[] { i }, initializers, test, iterators, body, breakLabel);

                Assert.AreEqual(CSharpExpressionType.For, res.CSharpNodeType);
                Assert.AreEqual(typeof(void), res.Type);
                Assert.IsTrue(new[] { i }.SequenceEqual(res.Variables));
                Assert.IsTrue(initializers.SequenceEqual(res.Initializers));
                Assert.AreSame(test, res.Test);
                Assert.IsTrue(iterators.SequenceEqual(res.Iterators));
                Assert.AreSame(body, res.Body);
                Assert.AreSame(breakLabel, res.BreakLabel);
                Assert.IsNull(res.ContinueLabel);
            }

            {
                var res = CSharpExpression.For(new[] { i }, initializers, test, iterators, body, breakLabel, continueLabel);

                Assert.AreEqual(CSharpExpressionType.For, res.CSharpNodeType);
                Assert.AreEqual(typeof(void), res.Type);
                Assert.IsTrue(new[] { i }.SequenceEqual(res.Variables));
                Assert.IsTrue(initializers.SequenceEqual(res.Initializers));
                Assert.AreSame(test, res.Test);
                Assert.IsTrue(iterators.SequenceEqual(res.Iterators));
                Assert.AreSame(body, res.Body);
                Assert.AreSame(breakLabel, res.BreakLabel);
                Assert.AreSame(continueLabel, res.ContinueLabel);
            }
        }
Example #12
0
        public void For_Update()
        {
            var i = Expression.Parameter(typeof(int));
            var variables = new[] { i };
            var initializers = new[] { Expression.Assign(i, Expression.Constant(0)) };
            var iterators = new[] { Expression.PostIncrementAssign(i) };
            var test = Expression.Constant(true);
            var body = Expression.Empty();
            var breakLabel = Expression.Label();
            var continueLabel = Expression.Label();
            var res = CSharpExpression.For(variables, initializers, test, iterators, body, breakLabel, continueLabel);

            Assert.AreSame(res, res.Update(res.BreakLabel, res.ContinueLabel, res.Variables, res.Initializers, res.Test, res.Iterators, res.Body));

            var newVariables = new[] { i };
            var newInitializers = new[] { Expression.Assign(i, Expression.Constant(0)) };
            var newIterators = new[] { Expression.PostIncrementAssign(i) };
            var newTest = Expression.Constant(true);
            var newBody = Expression.Empty();
            var newBreakLabel = Expression.Label();
            var newContinueLabel = Expression.Label();

            var upd1 = res.Update(newBreakLabel, res.ContinueLabel, res.Variables, res.Initializers, res.Test, res.Iterators, res.Body);
            var upd2 = res.Update(res.BreakLabel, newContinueLabel, res.Variables, res.Initializers, res.Test, res.Iterators, res.Body);
            var upd3 = res.Update(res.BreakLabel, res.ContinueLabel, newVariables, res.Initializers, res.Test, res.Iterators, res.Body);
            var upd4 = res.Update(res.BreakLabel, res.ContinueLabel, res.Variables, newInitializers, res.Test, res.Iterators, res.Body);
            var upd5 = res.Update(res.BreakLabel, res.ContinueLabel, res.Variables, res.Initializers, newTest, res.Iterators, res.Body);
            var upd6 = res.Update(res.BreakLabel, res.ContinueLabel, res.Variables, res.Initializers, res.Test, newIterators, res.Body);
            var upd7 = res.Update(res.BreakLabel, res.ContinueLabel, res.Variables, res.Initializers, res.Test, res.Iterators, newBody);

            Assert.AreSame(newBreakLabel, upd1.BreakLabel);
            Assert.AreSame(res.ContinueLabel, upd1.ContinueLabel);
            Assert.AreSame(res.Variables, upd1.Variables);
            Assert.AreSame(res.Initializers, upd1.Initializers);
            Assert.AreSame(res.Test, upd1.Test);
            Assert.AreSame(res.Iterators, upd1.Iterators);
            Assert.AreSame(res.Body, upd1.Body);

            Assert.AreSame(res.BreakLabel, upd2.BreakLabel);
            Assert.AreSame(newContinueLabel, upd2.ContinueLabel);
            Assert.AreSame(res.Variables, upd2.Variables);
            Assert.AreSame(res.Initializers, upd2.Initializers);
            Assert.AreSame(res.Test, upd2.Test);
            Assert.AreSame(res.Iterators, upd2.Iterators);
            Assert.AreSame(res.Body, upd2.Body);

            Assert.AreSame(res.BreakLabel, upd3.BreakLabel);
            Assert.AreSame(res.ContinueLabel, upd3.ContinueLabel);
            Assert.IsTrue(newVariables.SequenceEqual(upd3.Variables));
            Assert.AreSame(res.Initializers, upd3.Initializers);
            Assert.AreSame(res.Test, upd3.Test);
            Assert.AreSame(res.Iterators, upd3.Iterators);
            Assert.AreSame(res.Body, upd3.Body);

            Assert.AreSame(res.BreakLabel, upd4.BreakLabel);
            Assert.AreSame(res.ContinueLabel, upd4.ContinueLabel);
            Assert.AreSame(res.Variables, upd4.Variables);
            Assert.IsTrue(newInitializers.SequenceEqual(upd4.Initializers));
            Assert.AreSame(res.Test, upd4.Test);
            Assert.AreSame(res.Iterators, upd4.Iterators);
            Assert.AreSame(res.Body, upd4.Body);

            Assert.AreSame(res.BreakLabel, upd5.BreakLabel);
            Assert.AreSame(res.ContinueLabel, upd5.ContinueLabel);
            Assert.AreSame(res.Variables, upd5.Variables);
            Assert.AreSame(res.Initializers, upd5.Initializers);
            Assert.AreSame(newTest, upd5.Test);
            Assert.AreSame(res.Iterators, upd5.Iterators);
            Assert.AreSame(res.Body, upd5.Body);

            Assert.AreSame(res.BreakLabel, upd6.BreakLabel);
            Assert.AreSame(res.ContinueLabel, upd6.ContinueLabel);
            Assert.AreSame(res.Variables, upd6.Variables);
            Assert.AreSame(res.Initializers, upd6.Initializers);
            Assert.AreSame(res.Test, upd6.Test);
            Assert.IsTrue(newIterators.SequenceEqual(upd6.Iterators));
            Assert.AreSame(res.Body, upd6.Body);

            Assert.AreSame(res.BreakLabel, upd7.BreakLabel);
            Assert.AreSame(res.ContinueLabel, upd7.ContinueLabel);
            Assert.AreSame(res.Variables, upd7.Variables);
            Assert.AreSame(res.Initializers, upd7.Initializers);
            Assert.AreSame(res.Test, upd7.Test);
            Assert.AreSame(res.Iterators, upd7.Iterators);
            Assert.AreSame(newBody, upd7.Body);
        }
        public void SwitchCase_Properties()
        {
            var b = new[] { Expression.Empty() };
            var t = new int[] { 1, 2 };

            var s1 = CSharpStatement.SwitchCase(t, b);
            var s2 = CSharpStatement.SwitchCase(t.AsEnumerable(), b);
            var s3 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b);
            var s4 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b);
            var s5 = CSharpStatement.SwitchCase(t, b.AsEnumerable());
            var s6 = CSharpStatement.SwitchCase(t.AsEnumerable(), b.AsEnumerable());
            var s7 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b.AsEnumerable());
            var s8 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b.AsEnumerable());

            foreach (var s in new[] { s1, s2, s3, s4, s5, s6, s7, s8 })
            {
                Assert.IsTrue(b.SequenceEqual(s.Statements));
                Assert.IsTrue(t.SequenceEqual(s.TestValues.Cast<int>()));
            }
        }
        public void SwitchCase_Factory_ArgumentChecking()
        {
            var body = new[] { Expression.Empty() };
            var vals = new[] { 1, 2 };
            var objs = new object[] { 1, 2 };

            // null
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(default(int[]), body));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(default(IEnumerable<int>), body));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(default(object[]), body));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(default(IEnumerable<object>), body));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(vals, default(Expression[])));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(vals, default(IEnumerable<Expression>)));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(objs, default(Expression[])));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCase(objs, default(IEnumerable<Expression>)));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCaseDefault(default(Expression[])));
            AssertEx.Throws<ArgumentNullException>(() => CSharpStatement.SwitchCaseDefault(default(IEnumerable<Expression>)));

            // empty
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(Array.Empty<int>(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(Enumerable.Empty<int>(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(Array.Empty<object>(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(Enumerable.Empty<object>(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(vals, Array.Empty<Expression>()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(vals, Enumerable.Empty<Expression>()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(objs, Array.Empty<Expression>()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(objs, Enumerable.Empty<Expression>()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCaseDefault(Array.Empty<Expression>()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCaseDefault(Enumerable.Empty<Expression>()));

            // switch type
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }, body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }, body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }.AsEnumerable(), body.AsEnumerable()));

            // duplicate value
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 1, 2 }, body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }, body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }, body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 1, 2 }, body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }, body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }.AsEnumerable(), body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }, body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }.AsEnumerable(), body.AsEnumerable()));

            // inconsistent typing
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, "foo", 1 }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { "foo", null, 1 }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2L }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, 1, 2L }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, null, 2L }.AsEnumerable(), body));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, "foo", 1 }.AsEnumerable(), body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { "foo", null, 1 }.AsEnumerable(), body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2L }.AsEnumerable(), body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, 1, 2L }.AsEnumerable(), body.AsEnumerable()));
            AssertEx.Throws<ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, null, 2L }.AsEnumerable(), body.AsEnumerable()));

            // those are ok
            CSharpStatement.SwitchCase(new int?[] { null, 1 }, body);
            CSharpStatement.SwitchCase(new string[] { null, "bar" }, body);
            CSharpStatement.SwitchCase(new int?[] { 1, null }, body);
            CSharpStatement.SwitchCase(new string[] { "bar", null }, body);
            CSharpStatement.SwitchCase(new object[] { null }, body);
            CSharpStatement.SwitchCase(new object[] { null }.AsEnumerable(), body);
        }
        public void SwitchCase_Update()
        {
            var b = new[] { Expression.Empty() };
            var c = new[] { Expression.Empty() };
            var t = new int[] { 1, 2 };

            var s1 = CSharpStatement.SwitchCase(t, b);
            var s2 = CSharpStatement.SwitchCase(t.AsEnumerable(), b);
            var s3 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b);
            var s4 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b);
            var s5 = CSharpStatement.SwitchCase(t, b.AsEnumerable());
            var s6 = CSharpStatement.SwitchCase(t.AsEnumerable(), b.AsEnumerable());
            var s7 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b.AsEnumerable());
            var s8 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b.AsEnumerable());

            foreach (var s in new[] { s1, s2, s3, s4, s5, s6, s7, s8 })
            {
                Assert.AreSame(s, s.Update(s.Statements));

                var u = s.Update(c);
                Assert.IsTrue(c.SequenceEqual(u.Statements));
            }
        }
        public void SwitchCaseDefault_Properties()
        {
            var b = new[] { Expression.Empty() };

            var s1 = CSharpStatement.SwitchCaseDefault(b);
            var s2 = CSharpStatement.SwitchCaseDefault(b.AsEnumerable());

            foreach (var s in new[] { s1, s2 })
            {
                Assert.IsTrue(b.SequenceEqual(s.Statements));
                Assert.AreSame(CSharpStatement.SwitchCaseDefaultValue, s.TestValues.Single());
                Assert.AreEqual("default", s.TestValues.Single().ToString());
            }
        }