Add delegate and MethodInfo invoke special case tests for optional parameters and...
authorvitek-karas <vitek.karas@microsoft.com>
Thu, 14 Jul 2016 15:31:50 +0000 (08:31 -0700)
committervitek-karas <vitek.karas@microsoft.com>
Thu, 14 Jul 2016 15:31:50 +0000 (08:31 -0700)
Adds the same set of tests for both MethodInfo.Invoke and
Delegate.DynamicInvoke.
- Tests around optional parameters and the behavior when passing Missing
as a value for it.
- Tests around handling of the arguments to the invoke method, it should
be able to consume arrays convertible to object[].

Commit migrated from https://github.com/dotnet/corefx/commit/6681e3cf43437a90d5fad72db11daf536675bc6d

src/libraries/System.Reflection/tests/MethodInfo/MethodInfo_InvokeTests.cs
src/libraries/System.Runtime/tests/System/DelegateTests.cs

index 146eff6..b824965 100644 (file)
@@ -7,6 +7,7 @@ using System;
 using System.Collections.Generic;
 using System.Reflection;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using System.Text;
 
 #pragma warning disable 0414
@@ -378,6 +379,44 @@ namespace MethodInfoTests
                     new object[] { 101, "value", 103.14m }));
         }
 
+        [Fact]
+        public static void TestInvokeMethod_OptionalParameter_WithExplicitValue()
+        {
+            Assert.Equal(
+                "value",
+                getMethod(typeof(DefaultParameters), "OptionalObjectParameter").Invoke(new DefaultParameters(), new object[] { "value" }));
+        }
+
+        [Fact]
+        public static void TestInvokeMethod_OptionalParameter_WithMissingValue()
+        {
+            Assert.Equal(
+                Type.Missing,
+                getMethod(typeof(DefaultParameters), "OptionalObjectParameter").Invoke(new DefaultParameters(), new object[] { Type.Missing }));
+        }
+
+        [Fact]
+        public static void TestInvokeMethod_OptionalParameterUnassingableFromMissing_WithMissingValue()
+        {
+            Assert.Throws<ArgumentException>(() => getMethod(typeof(DefaultParameters), "OptionalStringParameter").Invoke(new DefaultParameters(), new object[] { Type.Missing }));
+        }
+
+        [Fact]
+        public static void TestInvokeMethod_ParameterSpecification_ArrayOfStrings()
+        {
+            Assert.Equal(
+                "value",
+                (string)getMethod(typeof(ParameterTypes), "String").Invoke(new ParameterTypes(), new string[] { "value" }));
+        }
+
+        [Fact]
+        public static void TestInvokeMethod_ParameterSpecification_ArrayOfMissing()
+        {
+            Assert.Same(
+                Missing.Value,
+                (object)getMethod(typeof(DefaultParameters), "OptionalObjectParameter").Invoke(new DefaultParameters(), new Missing[] { Missing.Value }));
+        }
+
         // Gets MethodInfo object from a Type
         private static MethodInfo getMethod(Type t, string method)
         {
@@ -508,6 +547,24 @@ namespace MethodInfoTests
                 builder.Append(p3.ToString());
                 return builder.ToString();
             }
+
+            public object OptionalObjectParameter([Optional]object parameter)
+            {
+                return parameter;
+            }
+
+            public string OptionalStringParameter([Optional]string parameter)
+            {
+                return parameter;
+            }
+        }
+
+        private class ParameterTypes
+        {
+            public string String(string parameter)
+            {
+                return parameter;
+            }
         }
     }
 
index 439e52b..7b22fe4 100644 (file)
@@ -2,7 +2,9 @@
 // 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.Reflection;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using System.Text;
 using Xunit;
 
@@ -359,6 +361,44 @@ namespace System.Tests
                 (IntEnum)(new EnumWithDefaultValue(EnumMethod)).DynamicInvoke(new object[] { Type.Missing }));
         }
 
+        [Fact]
+        public static void DynamicInvoke_OptionalParameter_WithExplicitValue()
+        {
+            Assert.Equal(
+                "value",
+                (new OptionalObjectParameter(ObjectMethod)).DynamicInvoke(new object[] { "value" }));
+        }
+
+        [Fact]
+        public static void DynamicInvoke_OptionalParameter_WithMissingValue()
+        {
+            Assert.Equal(
+                Type.Missing,
+                (new OptionalObjectParameter(ObjectMethod)).DynamicInvoke(new object[] { Type.Missing }));
+        }
+
+        [Fact]
+        public static void DynamicInvoke_OptionalParameterUnassingableFromMissing_WithMissingValue()
+        {
+            Assert.Throws<ArgumentException>(() => (new OptionalStringParameter(StringMethod)).DynamicInvoke(new object[] { Type.Missing }));
+        }
+
+        [Fact]
+        public static void DynamicInvoke_ParameterSpecification_ArrayOfStrings()
+        {
+            Assert.Equal(
+                "value",
+               (new StringParameter(StringMethod)).DynamicInvoke(new string[] { "value" }));
+        }
+
+        [Fact]
+        public static void DynamicInvoke_ParameterSpecification_ArrayOfMissing()
+        {
+            Assert.Same(
+                Missing.Value,
+                (new OptionalObjectParameter(ObjectMethod)).DynamicInvoke(new Missing[] { Missing.Value }));
+        }
+
         private static void IntIntMethod(int expected, int actual)
         {
             Assert.Equal(expected, actual);
@@ -473,6 +513,7 @@ namespace System.Tests
             return builder.ToString();
         }
 
+        private delegate string StringParameter(string parameter);
         private delegate string StringWithDefaultValue(string parameter = "test");
         private static string StringMethod(string parameter)
         {
@@ -519,5 +560,13 @@ namespace System.Tests
         {
             return parameter;
         }
+
+        private delegate object OptionalObjectParameter([Optional] object parameter);
+        private static object ObjectMethod(object parameter)
+        {
+            return parameter;
+        }
+
+        private delegate string OptionalStringParameter([Optional] string parameter);
     }
 }