public void PartialApply_SimpleVirtualInstanceVoidMethod()
        {
            MethodClosureExtensionsFixture.Do(fixture =>
            {
                var c                    = new TestClassSimple(15);
                var method               = typeof(TestClassSimple).GetMethod(nameof(TestClassSimple.SimpleVirtualInstanceVoidMethod));
                var fixedArguments       = new object[] { 5 };
                var partialAppliedMethod = method.PartialApply(fixedArguments);
                Assert.IsNull(partialAppliedMethod.FixedThisArgument);
                CollectionAssert.AreEqual(fixedArguments, partialAppliedMethod.FixedArguments);

                var returnValue = partialAppliedMethod.Invoke(c, new object[] { new string[] { "hello", "world" } });
                Assert.IsNull(returnValue);

                partialAppliedMethod.CreateDelegate <SimpleInstanceVoidMethod_PartialApply_Delegate>(c)("hi", "there");

                fixture.ExpectedLogs = new[]
                {
                    "x: 15",
                    "y: 5",
                    "ss: string[] { hello, world }",
                    "x: 15",
                    "y: 5",
                    "ss: string[] { hi, there }",
                };
            });
        }
        public void Control_SimpleVirtualInstanceVoidMethod([Values] bool emptyPartialApply)
        {
            MethodClosureExtensionsFixture.Do(fixture =>
            {
                var c = new TestClassSimple(-15);
                c.SimpleVirtualInstanceVoidMethod(-5, "home", "alone");

                var method = typeof(TestClassSimple).GetMethod(nameof(TestClassSimple.SimpleVirtualInstanceVoidMethod));
                if (emptyPartialApply)
                {
                    var partialAppliedMethod = method.PartialApply();
                    Assert.IsNull(partialAppliedMethod.FixedThisArgument);
                    CollectionAssert.AreEqual(new object[0], partialAppliedMethod.FixedArguments);
                    method = partialAppliedMethod;
                }

                var returnValue = method.Invoke(c, new object[] { -5, new[] { "home", "alone" } });
                Assert.IsNull(returnValue);

                method.CreateDelegate <Action <int, string[]> >(c)(-5, new[] { "home", "alone" });

                fixture.ExpectedLogs = new[]
                {
                    "x: -15",
                    "y: -5",
                    "ss: string[] { home, alone }",
                    "x: -15",
                    "y: -5",
                    "ss: string[] { home, alone }",
                    "x: -15",
                    "y: -5",
                    "ss: string[] { home, alone }",
                };
            });
        }
 public void PartialApply_ClassInstanceMethod_Error(string methodName,
                                                    Type validDelegateType, Type invalidDelegateType, bool nullTargetDelegateIsException)
 {
     MethodClosureExtensionsFixture.Do(fixture =>
     {
         var c      = new TestClassSimple(15);
         var method = typeof(TestClassSimple).GetMethod(methodName);
         var partialAppliedMethod = method.PartialApply(5);
         AssertInstanceMethodErrors(fixture, c, partialAppliedMethod,
                                    validDelegateType,
                                    invalidDelegateType,
                                    validSampleArgs: new object[] { new[] { "hello", "world" } },
                                    invalidSampleArgs: new object[] { "string" },
                                    nullTargetDelegateIsException);
     });
 }
 public void Bind_ClassInstanceMethod_Error(string methodName, bool bindNull,
                                            Type validDelegateType, Type invalidDelegateType, bool invokeIsAlwaysTargetException, bool delegateDynamicInvokeIsAlwaysException)
 {
     MethodClosureExtensionsFixture.Do(fixture =>
     {
         var c      = new TestClassSimple(15);
         var method = typeof(TestClassSimple).GetMethod(methodName);
         // Instance method cannot be bound to invalid target.
         Assert.Throws(typeof(ArgumentException), () => method.Bind(this));
         var boundMethod = bindNull ? method.Bind(null) : method.Bind(c);
         AssertStaticMethodErrors(fixture, boundMethod,
                                  validDelegateType,
                                  invalidDelegateType,
                                  validSampleArgs: new object[] { 5, new[] { "hello", "world" } },
                                  invalidSampleArgs: new object[] { 5, "string" },
                                  invokeIsAlwaysTargetException,
                                  delegateDynamicInvokeIsAlwaysException);
     });
 }
 public void Control_ClassInstanceMethod_Error(string methodName,
                                               Type validDelegateType, Type invalidDelegateType, bool nullTargetDelegateIsException)
 {
     // On Mono runtime, MethodInfo.CreateDelegate(validDelegateType, null).DynamicInvoke(...) always throws TargetException,
     // regardless of whether the this instance is never used or is used in a null-safe way.
     if (DebugExtensions.IsRunningOnMono)
     {
         nullTargetDelegateIsException = true;
     }
     MethodClosureExtensionsFixture.Do(fixture =>
     {
         var c      = new TestClassSimple(15);
         var method = typeof(TestClassSimple).GetMethod(methodName);
         AssertInstanceMethodErrors(fixture, c, method,
                                    validDelegateType,
                                    invalidDelegateType,
                                    validSampleArgs: new object[] { 5, new[] { "hello", "world" } },
                                    invalidSampleArgs: new object[] { 5, "string" },
                                    nullTargetDelegateIsException);
     });
 }