Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJon Hanna <jon@hackcraft.net>2017-01-04 04:45:36 +0300
committerStephen Toub <stoub@microsoft.com>2017-01-04 04:45:36 +0300
commit5390a66eb8be20863535c5c3378d880e95ccee34 (patch)
tree0eea0c1337fd3d8e436f6c2a09a5f33533c3c9bf /src
parentc8f66779e3ce3fa632a16d02bee286fa081214d3 (diff)
Fill some gaps in S.L.Expression testing (#14464)
* Fill some testing gaps related to array expressions. * Test TypeAs expressions between nullables. * Test fault and finally after many such blocks (catch regressions in a non-optimised path hit in this case).
Diffstat (limited to 'src')
-rw-r--r--src/System.Linq.Expressions/tests/Array/ArrayAccessTests.cs44
-rw-r--r--src/System.Linq.Expressions/tests/Array/ArrayIndexTests.cs52
-rw-r--r--src/System.Linq.Expressions/tests/Cast/AsNullable.cs72
-rw-r--r--src/System.Linq.Expressions/tests/ExceptionHandling/ExceptionHandlingExpressions.cs28
4 files changed, 196 insertions, 0 deletions
diff --git a/src/System.Linq.Expressions/tests/Array/ArrayAccessTests.cs b/src/System.Linq.Expressions/tests/Array/ArrayAccessTests.cs
index df6dc385d0..8ae11e8660 100644
--- a/src/System.Linq.Expressions/tests/Array/ArrayAccessTests.cs
+++ b/src/System.Linq.Expressions/tests/Array/ArrayAccessTests.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Reflection;
using Xunit;
@@ -9,6 +10,8 @@ namespace System.Linq.Expressions.Tests
{
public static class ArrayAccessTests
{
+ private static IEnumerable<object[]> Ranks() => Enumerable.Range(1, 5).Select(i => new object[] {i});
+
[Theory]
[ClassData(typeof(CompilationTypes))]
public static void ArrayAccess_MultiDimensionalOf1(bool useInterpreter)
@@ -73,5 +76,46 @@ namespace System.Linq.Expressions.Tests
MemberExpression index = Expression.Property(null, typeof(Unreadable<int>).GetProperty(nameof(Unreadable<int>.WriteOnly)));
Assert.Throws<ArgumentException>("indexes", () => Expression.ArrayAccess(instance, index));
}
+
+ [Theory, ClassData(typeof(CompilationTypes))]
+ public static void NonZeroBasedOneDimensionalArrayAccess(bool useInterpreter)
+ {
+ Array arrayObj = Array.CreateInstance(typeof(int), new[] { 3 }, new[] { -1 });
+ arrayObj.SetValue(5, -1);
+ arrayObj.SetValue(6, 0);
+ arrayObj.SetValue(7, 1);
+ ConstantExpression array = Expression.Constant(arrayObj);
+ IndexExpression indexM1 = Expression.ArrayAccess(array, Expression.Constant(-1));
+ IndexExpression index0 = Expression.ArrayAccess(array, Expression.Constant(0));
+ IndexExpression index1 = Expression.ArrayAccess(array, Expression.Constant(1));
+ Action setValues = Expression.Lambda<Action>(
+ Expression.Block(
+ Expression.Assign(indexM1, Expression.Constant(5)),
+ Expression.Assign(index0, Expression.Constant(6)),
+ Expression.Assign(index1, Expression.Constant(7)))).Compile(useInterpreter);
+ setValues();
+ Assert.Equal(5, arrayObj.GetValue(-1));
+ Assert.Equal(6, arrayObj.GetValue(0));
+ Assert.Equal(7, arrayObj.GetValue(1));
+ Func<bool> testValues = Expression.Lambda<Func<bool>>(
+ Expression.And(
+ Expression.Equal(indexM1, Expression.Constant(5)),
+ Expression.And(
+ Expression.Equal(index0, Expression.Constant(6)),
+ Expression.Equal(index1, Expression.Constant(7))))).Compile(useInterpreter);
+ Assert.True(testValues());
+ }
+
+ [Theory, PerCompilationType(nameof(Ranks))]
+ public static void DifferentRanks(int rank, bool useInterpreter)
+ {
+ Array arrayObj = Array.CreateInstance(typeof(string), Enumerable.Repeat(1, rank).ToArray());
+ arrayObj.SetValue("solitary value", Enumerable.Repeat(0, rank).ToArray());
+ ConstantExpression array = Expression.Constant(arrayObj);
+ IEnumerable<DefaultExpression> indices = Enumerable.Repeat(Expression.Default(typeof(int)), rank);
+ Func<string> func = Expression.Lambda<Func<string>>(
+ Expression.ArrayAccess(array, indices)).Compile(useInterpreter);
+ Assert.Equal("solitary value", func());
+ }
}
}
diff --git a/src/System.Linq.Expressions/tests/Array/ArrayIndexTests.cs b/src/System.Linq.Expressions/tests/Array/ArrayIndexTests.cs
index 7c6a3f1e48..feab3582d6 100644
--- a/src/System.Linq.Expressions/tests/Array/ArrayIndexTests.cs
+++ b/src/System.Linq.Expressions/tests/Array/ArrayIndexTests.cs
@@ -2769,5 +2769,57 @@ namespace System.Linq.Expressions.Tests
Expression index = Expression.Property(null, typeof(Unreadable<int>), nameof(Unreadable<int>.WriteOnly));
Assert.Throws<ArgumentException>("index", () => Expression.ArrayIndex(array, index));
}
+
+ [Theory, ClassData(typeof(CompilationTypes))]
+ public static void NonZeroBasedOneDimensionalArrayIndex(bool useInterpreter)
+ {
+ Array arrayObj = Array.CreateInstance(typeof(int), new[] { 3 }, new[] { -1 });
+ arrayObj.SetValue(5, -1);
+ arrayObj.SetValue(6, 0);
+ arrayObj.SetValue(7, 1);
+ ConstantExpression array = Expression.Constant(arrayObj);
+ BinaryExpression indexM1 = Expression.ArrayIndex(array, Expression.Constant(-1));
+ BinaryExpression index0 = Expression.ArrayIndex(array, Expression.Constant(0));
+ BinaryExpression index1 = Expression.ArrayIndex(array, Expression.Constant(1));
+ Func<bool> testValues = Expression.Lambda<Func<bool>>(
+ Expression.And(
+ Expression.Equal(indexM1, Expression.Constant(5)),
+ Expression.And(
+ Expression.Equal(index0, Expression.Constant(6)),
+ Expression.Equal(index1, Expression.Constant(7))))).Compile(useInterpreter);
+ Assert.True(testValues());
+ }
+
+ [Theory, ClassData(typeof(CompilationTypes))]
+ public static void NonZeroBasedOneDimensionalArrayIndexMethod(bool useInterpreter)
+ {
+ Array arrayObj = Array.CreateInstance(typeof(int), new[] { 3 }, new[] { -1 });
+ arrayObj.SetValue(5, -1);
+ arrayObj.SetValue(6, 0);
+ arrayObj.SetValue(7, 1);
+ ConstantExpression array = Expression.Constant(arrayObj);
+ MethodCallExpression indexM1 = Expression.ArrayIndex(array, new [] { Expression.Constant(-1)});
+ MethodCallExpression index0 = Expression.ArrayIndex(array, new[] { Expression.Constant(0)});
+ MethodCallExpression index1 = Expression.ArrayIndex(array, new[] { Expression.Constant(1)});
+ Func<bool> testValues = Expression.Lambda<Func<bool>>(
+ Expression.And(
+ Expression.Equal(indexM1, Expression.Constant(5)),
+ Expression.And(
+ Expression.Equal(index0, Expression.Constant(6)),
+ Expression.Equal(index1, Expression.Constant(7))))).Compile(useInterpreter);
+ Assert.True(testValues());
+ }
+
+ [Theory, ClassData(typeof(CompilationTypes))]
+ public static void HighRankArrayIndex(bool useInterpreter)
+ {
+ string[,,,,,,,,,] arrayObj = {{{{{{{{{{"hugz"}}}}}}}}}};
+ ConstantExpression array = Expression.Constant(arrayObj);
+ Func<string> func = Expression.Lambda<Func<string>>(
+ Expression.ArrayIndex(array, Enumerable.Repeat(Expression.Constant(0), 10))).Compile(useInterpreter);
+ Assert.Equal("hugz", func());
+ }
+
+
}
}
diff --git a/src/System.Linq.Expressions/tests/Cast/AsNullable.cs b/src/System.Linq.Expressions/tests/Cast/AsNullable.cs
index 480b30530a..37c3080235 100644
--- a/src/System.Linq.Expressions/tests/Cast/AsNullable.cs
+++ b/src/System.Linq.Expressions/tests/Cast/AsNullable.cs
@@ -28,6 +28,46 @@ namespace System.Linq.Expressions.Tests
}
[Theory, ClassData(typeof(CompilationTypes))]
+ public static void CheckEnumAsNullableEnumTypeTest(bool useInterpreter)
+ {
+ E[] array = { 0, E.A, E.B, (E)int.MaxValue, (E)int.MinValue };
+ for (int i = 0; i < array.Length; i++)
+ {
+ VerifyEnumAsNullableEnumType(array[i], useInterpreter);
+ }
+ }
+
+ [Theory, ClassData(typeof(CompilationTypes))]
+ public static void CheckNullableEnumAsNullableEnumTypeTest(bool useInterpreter)
+ {
+ E?[] array = { null, 0, E.A, E.B, (E)int.MaxValue, (E)int.MinValue };
+ for (int i = 0; i < array.Length; i++)
+ {
+ VerifyNullableEnumAsNullableEnumType(array[i], useInterpreter);
+ }
+ }
+
+ [Theory, ClassData(typeof(CompilationTypes))]
+ public static void CheckLongAsNullableEnumTypeTest(bool useInterpreter)
+ {
+ long[] array = { 0, 1, long.MinValue, long.MaxValue };
+ foreach (long value in array)
+ {
+ VerifyLongAsNullableEnumType(value, useInterpreter);
+ }
+ }
+
+ [Theory, ClassData(typeof(CompilationTypes))]
+ public static void CheckNullableLongAsNullableEnumTypeTest(bool useInterpreter)
+ {
+ long?[] array = { null, 0, 1, long.MinValue, long.MaxValue };
+ foreach (long? value in array)
+ {
+ VerifyNullableLongAsNullableEnumType(value, useInterpreter);
+ }
+ }
+
+ [Theory, ClassData(typeof(CompilationTypes))]
public static void CheckNullableEnumAsObjectTest(bool useInterpreter)
{
E?[] array = new E?[] { null, (E)0, E.A, E.B, (E)int.MaxValue, (E)int.MinValue };
@@ -160,6 +200,38 @@ namespace System.Linq.Expressions.Tests
Assert.Equal(value as ValueType, f());
}
+ private static void VerifyEnumAsNullableEnumType(E value, bool useInterpreter)
+ {
+ Expression<Func<E?>> e = Expression.Lambda<Func<E?>>(
+ Expression.TypeAs(Expression.Constant(value), typeof(E?)));
+ Func<E?> f = e.Compile(useInterpreter);
+ Assert.Equal(value, f());
+ }
+
+ private static void VerifyNullableEnumAsNullableEnumType(E? value, bool useInterpreter)
+ {
+ Expression<Func<E?>> e = Expression.Lambda<Func<E?>>(
+ Expression.TypeAs(Expression.Constant(value, typeof(E?)), typeof(E?)));
+ Func<E?> f = e.Compile(useInterpreter);
+ Assert.Equal(value, f());
+ }
+
+ private static void VerifyLongAsNullableEnumType(long value, bool useInterpreter)
+ {
+ Expression<Func<E?>> e = Expression.Lambda<Func<E?>>(
+ Expression.TypeAs(Expression.Constant(value), typeof(E?)));
+ Func<E?> f = e.Compile(useInterpreter);
+ Assert.False(f().HasValue);
+ }
+
+ private static void VerifyNullableLongAsNullableEnumType(long? value, bool useInterpreter)
+ {
+ Expression<Func<E?>> e = Expression.Lambda<Func<E?>>(
+ Expression.TypeAs(Expression.Constant(value, typeof(long?)), typeof(E?)));
+ Func<E?> f = e.Compile(useInterpreter);
+ Assert.False(f().HasValue);
+ }
+
private static void VerifyNullableEnumAsObject(E? value, bool useInterpreter)
{
Expression<Func<object>> e =
diff --git a/src/System.Linq.Expressions/tests/ExceptionHandling/ExceptionHandlingExpressions.cs b/src/System.Linq.Expressions/tests/ExceptionHandling/ExceptionHandlingExpressions.cs
index b47d2cdabe..f57cb5a6da 100644
--- a/src/System.Linq.Expressions/tests/ExceptionHandling/ExceptionHandlingExpressions.cs
+++ b/src/System.Linq.Expressions/tests/ExceptionHandling/ExceptionHandlingExpressions.cs
@@ -526,6 +526,34 @@ namespace System.Linq.Expressions.Tests
FaultTriggeredOnThrow(false);
}
+ [Theory, InlineData(true)]
+ public void FinallyAndFaultAfterManyLabels(bool useInterpreter)
+ {
+ // There is a caching optimisation used below a certain number of faults or
+ // finally, so go past that to catch any regressions in the non-optimised
+ // path.
+ ParameterExpression variable = Expression.Parameter(typeof(int));
+ LabelTarget target = Expression.Label(typeof(int));
+ BlockExpression block = Expression.Block(
+ new[] { variable },
+ Expression.Assign(variable, Expression.Constant(1)),
+ Expression.TryCatch(
+ Expression.Block(
+ Enumerable.Repeat(Expression.TryFinally(Expression.Empty(), Expression.Empty()), 40).Append(
+ Expression.TryFault(
+ Expression.Throw(Expression.Constant(new TestException())),
+ Expression.Assign(variable, Expression.Constant(2))
+ )
+ )
+ ),
+ Expression.Catch(typeof(TestException), Expression.Empty())
+ ),
+ Expression.Return(target, variable),
+ Expression.Label(target, Expression.Default(typeof(int)))
+ );
+ Assert.Equal(2, Expression.Lambda<Func<int>>(block).Compile(useInterpreter)());
+ }
+
[Theory]
[ClassData(typeof(CompilationTypes))]
public void FinallyTriggeredOnNoThrow(bool useInterpreter)