diff --git a/Source/NSubstitute.Acceptance.Specs/ArgumentInvocationFromMatchers.cs b/Source/NSubstitute.Acceptance.Specs/ArgumentInvocationFromMatchers.cs index 59e53f1bb..b8b99a14f 100644 --- a/Source/NSubstitute.Acceptance.Specs/ArgumentInvocationFromMatchers.cs +++ b/Source/NSubstitute.Acceptance.Specs/ArgumentInvocationFromMatchers.cs @@ -1,200 +1,220 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; - -namespace NSubstitute.Acceptance.Specs -{ - public class ArgumentInvocationFromMatchers - { - public delegate void ActionCompatibleDelegate(int i); - public interface IFoo - { - void MethodWithCallback(string something, Action callback); - void MethodWithCallbackWithArguments(string something, Action callback); - void MethodWithDelegateCallback(string something, ActionCompatibleDelegate callback); - int MethodWithCallbackWithArgumentsAndReturnValue(string something, Action callback); - } - - [Test] - public void Invoke_callback_from_matcher() - { - var action = Substitute.For(); - var sub = Substitute.For(); - sub.MethodWithCallback("test", Arg.Invoke()); - - sub.MethodWithCallback("test", action); - - action.Received().Invoke(); - sub.Received().MethodWithCallback("test", action); - } - - [Test] - public void Invoke_callback_with_arguments() - { - var action = Substitute.For>(); - var sub = Substitute.For(); - sub.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello")); - - sub.MethodWithCallbackWithArguments("test", action); - - action.Received().Invoke(1, "hello"); - sub.Received().MethodWithCallbackWithArguments("test", action); - } - - [Test] - public void Invoke_callback_with_argument_using_specific_delegate_type() - { - var action = Substitute.For>(); - var sub = Substitute.For(); - sub.MethodWithCallbackWithArguments("test", Arg.InvokeDelegate>(1, "hello")); - - sub.MethodWithCallbackWithArguments("test", action); - - action.Received().Invoke(1, "hello"); - sub.Received().MethodWithCallbackWithArguments("test", action); - } - - [Test] - public void Invoke_delegate_callback() - { - var action = Substitute.For>(); - ActionCompatibleDelegate @delegate = x => action(x); - var sub = Substitute.For(); - sub.MethodWithDelegateCallback("test", Arg.InvokeDelegate(1)); - - sub.MethodWithDelegateCallback("test", @delegate); - - action.Received().Invoke(1); - sub.Received().MethodWithDelegateCallback("test", @delegate); - } - - [Test] - public void Call_with_invoke_matcher_should_not_count_as_a_received_call() - { - var sub = Substitute.For(); - - sub.MethodWithCallback("test", Arg.Invoke()); - - sub.DidNotReceiveWithAnyArgs().MethodWithCallback(null, null); - } - - [Test] - public void Invoke_callback_as_well_as_return_a_value_for_call() - { - const int expectedReturnValue = 42; - var sub = Substitute.For(); - var action = Substitute.For>(); - sub.MethodWithCallbackWithArgumentsAndReturnValue("test", Arg.Invoke(1, "hello")).Returns(expectedReturnValue); - - var result = sub.MethodWithCallbackWithArgumentsAndReturnValue("test", action); - - action.Received().Invoke(1, "hello"); - Assert.That(result, Is.EqualTo(expectedReturnValue)); - } - - [Test] - public void Set_return_for_any_args_should_invoke_callback_when_args_do_not_match() - { - const int expectedReturnValue = 42; - var sub = Substitute.For(); - var action = Substitute.For>(); - sub - .MethodWithCallbackWithArgumentsAndReturnValue("test", Arg.Invoke(1, "hello")) - .ReturnsForAnyArgs(expectedReturnValue); - - var result = sub.MethodWithCallbackWithArgumentsAndReturnValue("different arg", action); - - action.Received().Invoke(1, "hello"); - Assert.That(result, Is.EqualTo(expectedReturnValue)); - } - - [Test] - public void Invoke_callback_and_set_return_for_any_arguments() - { - const int expectedReturnValue = 42; - var sub = Substitute.For(); - var action = Substitute.For>(); - sub - .MethodWithCallbackWithArgumentsAndReturnValue("test", Arg.Invoke(1, "hello")) - .ReturnsForAnyArgs(expectedReturnValue); - - var result = sub.MethodWithCallbackWithArgumentsAndReturnValue("test", action); - - action.Received().Invoke(1, "hello"); - Assert.That(result, Is.EqualTo(expectedReturnValue)); - } - - [Test] - public void Invoke_callback_using_when_do() - { - var sub = Substitute.For(); - var action = Substitute.For>(); - sub.When(x => x.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello"))).Do(x => { }); - - sub.MethodWithCallbackWithArguments("test", action); - - action.Received().Invoke(1, "hello"); - } - - [Test] - public void Invoke_callback_using_when_for_any_args_do() - { - var sub = Substitute.For(); - var action = Substitute.For>(); - sub.WhenForAnyArgs(x => x.MethodWithCallbackWithArguments(null, Arg.Invoke(1, "hello"))).Do(x => { }); - - sub.MethodWithCallbackWithArguments("something else", action); - action.Received().Invoke(1, "hello"); - } - - [Test] - public void Invoke_multiple_callbacks() - { - var action = Substitute.For>(); - var sub = Substitute.For(); - sub.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello")); - sub.MethodWithCallbackWithArguments("test", Arg.Invoke(2, "bye")); - - sub.MethodWithCallbackWithArguments("test", action); - - action.Received().Invoke(1, "hello"); - action.Received().Invoke(2, "bye"); - Assert.That(action.ReceivedCalls().Count(), Is.EqualTo(2)); - sub.Received().MethodWithCallbackWithArguments("test", action); - Assert.That(sub.ReceivedCalls().Count(), Is.EqualTo(1)); - } - - [Test] - public void Insanity_test() - { - var result = -1; - var sub = Substitute.For(); - var actions = new[] { Substitute.For>(), Substitute.For>(), Substitute.For>() }; - - sub.WhenForAnyArgs(x => x.MethodWithCallbackWithArgumentsAndReturnValue(null, Arg.Invoke(1, "que?"))).Do(x => { }); - sub.MethodWithCallbackWithArgumentsAndReturnValue("hello", Arg.Invoke(2, "hello")).ReturnsForAnyArgs(2); - sub.MethodWithCallbackWithArgumentsAndReturnValue("bye", Arg.Invoke(3, "bye")).Returns(3); - sub.MethodWithCallbackWithArgumentsAndReturnValue("hmm", Arg.Any>()).Returns(4); - - result = sub.MethodWithCallbackWithArgumentsAndReturnValue("something else", actions[0]); - Assert.That(result, Is.EqualTo(2)); - actions[0].Received().Invoke(1, "que?"); - actions[0].Received().Invoke(2, "hello"); - Assert.That(actions[0].ReceivedCalls().Count(), Is.EqualTo(2)); - ClearAllCalls(actions); - - result = sub.MethodWithCallbackWithArgumentsAndReturnValue("bye", actions[0]); - Assert.That(result, Is.EqualTo(3)); - actions[0].Received().Invoke(1, "que?"); - actions[0].Received().Invoke(2, "hello"); - actions[0].Received().Invoke(3, "bye"); - ClearAllCalls(actions); - } - - private void ClearAllCalls(IEnumerable subs) - { - foreach (var sub in subs) { sub.ClearReceivedCalls(); } - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace NSubstitute.Acceptance.Specs +{ + public class ArgumentInvocationFromMatchers + { + public delegate void ActionCompatibleDelegate(int i); + public interface IFoo + { + void MethodWithCallback(string something, Action callback); + void MethodWithCallbackWithArguments(string something, Action callback); + void MethodWithCallbackWithArguments(string something, Action callback); + void MethodWithCallbackWithArguments(string something, Action callback); + void MethodWithCallbackWithArguments(string something, Action callback); + void MethodWithDelegateCallback(string something, ActionCompatibleDelegate callback); + int MethodWithCallbackWithArgumentsAndReturnValue(string something, Action callback); + } + + [Test] + public void Invoke_callback_from_matcher() + { + var action = Substitute.For(); + var sub = Substitute.For(); + sub.MethodWithCallback("test", Arg.Invoke()); + + sub.MethodWithCallback("test", action); + + action.Received().Invoke(); + sub.Received().MethodWithCallback("test", action); + } + + [Test] + public void Invoke_callback_with_arguments() + { + var sub = Substitute.For(); + + var action1 = Substitute.For>(); + sub.MethodWithCallbackWithArguments("test", Arg.Invoke(1)); + sub.MethodWithCallbackWithArguments("test", action1); + action1.Received().Invoke(1); + sub.Received().MethodWithCallbackWithArguments("test", action1); + + var action2 = Substitute.For>(); + sub.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello")); + sub.MethodWithCallbackWithArguments("test", action2); + action2.Received().Invoke(1, "hello"); + sub.Received().MethodWithCallbackWithArguments("test", action2); + + var action3 = Substitute.For>(); + sub.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello", 3.14)); + sub.MethodWithCallbackWithArguments("test", action3); + action3.Received().Invoke(1, "hello", 3.14); + sub.Received().MethodWithCallbackWithArguments("test", action3); + + var action4 = Substitute.For>(); + sub.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello", 3.14, '!')); + sub.MethodWithCallbackWithArguments("test", action4); + action4.Received().Invoke(1, "hello", 3.14, '!'); + sub.Received().MethodWithCallbackWithArguments("test", action4); + } + + [Test] + public void Invoke_callback_with_argument_using_specific_delegate_type() + { + var action = Substitute.For>(); + var sub = Substitute.For(); + sub.MethodWithCallbackWithArguments("test", Arg.InvokeDelegate>(1, "hello")); + + sub.MethodWithCallbackWithArguments("test", action); + + action.Received().Invoke(1, "hello"); + sub.Received().MethodWithCallbackWithArguments("test", action); + } + + [Test] + public void Invoke_delegate_callback() + { + var action = Substitute.For>(); + ActionCompatibleDelegate @delegate = x => action(x); + var sub = Substitute.For(); + sub.MethodWithDelegateCallback("test", Arg.InvokeDelegate(1)); + + sub.MethodWithDelegateCallback("test", @delegate); + + action.Received().Invoke(1); + sub.Received().MethodWithDelegateCallback("test", @delegate); + } + + [Test] + public void Call_with_invoke_matcher_should_not_count_as_a_received_call() + { + var sub = Substitute.For(); + + sub.MethodWithCallback("test", Arg.Invoke()); + + sub.DidNotReceiveWithAnyArgs().MethodWithCallback(null, null); + } + + [Test] + public void Invoke_callback_as_well_as_return_a_value_for_call() + { + const int expectedReturnValue = 42; + var sub = Substitute.For(); + var action = Substitute.For>(); + sub.MethodWithCallbackWithArgumentsAndReturnValue("test", Arg.Invoke(1, "hello")).Returns(expectedReturnValue); + + var result = sub.MethodWithCallbackWithArgumentsAndReturnValue("test", action); + + action.Received().Invoke(1, "hello"); + Assert.That(result, Is.EqualTo(expectedReturnValue)); + } + + [Test] + public void Set_return_for_any_args_should_invoke_callback_when_args_do_not_match() + { + const int expectedReturnValue = 42; + var sub = Substitute.For(); + var action = Substitute.For>(); + sub + .MethodWithCallbackWithArgumentsAndReturnValue("test", Arg.Invoke(1, "hello")) + .ReturnsForAnyArgs(expectedReturnValue); + + var result = sub.MethodWithCallbackWithArgumentsAndReturnValue("different arg", action); + + action.Received().Invoke(1, "hello"); + Assert.That(result, Is.EqualTo(expectedReturnValue)); + } + + [Test] + public void Invoke_callback_and_set_return_for_any_arguments() + { + const int expectedReturnValue = 42; + var sub = Substitute.For(); + var action = Substitute.For>(); + sub + .MethodWithCallbackWithArgumentsAndReturnValue("test", Arg.Invoke(1, "hello")) + .ReturnsForAnyArgs(expectedReturnValue); + + var result = sub.MethodWithCallbackWithArgumentsAndReturnValue("test", action); + + action.Received().Invoke(1, "hello"); + Assert.That(result, Is.EqualTo(expectedReturnValue)); + } + + [Test] + public void Invoke_callback_using_when_do() + { + var sub = Substitute.For(); + var action = Substitute.For>(); + sub.When(x => x.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello"))).Do(x => { }); + + sub.MethodWithCallbackWithArguments("test", action); + + action.Received().Invoke(1, "hello"); + } + + [Test] + public void Invoke_callback_using_when_for_any_args_do() + { + var sub = Substitute.For(); + var action = Substitute.For>(); + sub.WhenForAnyArgs(x => x.MethodWithCallbackWithArguments(null, Arg.Invoke(1, "hello"))).Do(x => { }); + + sub.MethodWithCallbackWithArguments("something else", action); + action.Received().Invoke(1, "hello"); + } + + [Test] + public void Invoke_multiple_callbacks() + { + var action = Substitute.For>(); + var sub = Substitute.For(); + sub.MethodWithCallbackWithArguments("test", Arg.Invoke(1, "hello")); + sub.MethodWithCallbackWithArguments("test", Arg.Invoke(2, "bye")); + + sub.MethodWithCallbackWithArguments("test", action); + + action.Received().Invoke(1, "hello"); + action.Received().Invoke(2, "bye"); + Assert.That(action.ReceivedCalls().Count(), Is.EqualTo(2)); + sub.Received().MethodWithCallbackWithArguments("test", action); + Assert.That(sub.ReceivedCalls().Count(), Is.EqualTo(1)); + } + + [Test] + public void Insanity_test() + { + var result = -1; + var sub = Substitute.For(); + var actions = new[] { Substitute.For>(), Substitute.For>(), Substitute.For>() }; + + sub.WhenForAnyArgs(x => x.MethodWithCallbackWithArgumentsAndReturnValue(null, Arg.Invoke(1, "que?"))).Do(x => { }); + sub.MethodWithCallbackWithArgumentsAndReturnValue("hello", Arg.Invoke(2, "hello")).ReturnsForAnyArgs(2); + sub.MethodWithCallbackWithArgumentsAndReturnValue("bye", Arg.Invoke(3, "bye")).Returns(3); + sub.MethodWithCallbackWithArgumentsAndReturnValue("hmm", Arg.Any>()).Returns(4); + + result = sub.MethodWithCallbackWithArgumentsAndReturnValue("something else", actions[0]); + Assert.That(result, Is.EqualTo(2)); + actions[0].Received().Invoke(1, "que?"); + actions[0].Received().Invoke(2, "hello"); + Assert.That(actions[0].ReceivedCalls().Count(), Is.EqualTo(2)); + ClearAllCalls(actions); + + result = sub.MethodWithCallbackWithArgumentsAndReturnValue("bye", actions[0]); + Assert.That(result, Is.EqualTo(3)); + actions[0].Received().Invoke(1, "que?"); + actions[0].Received().Invoke(2, "hello"); + actions[0].Received().Invoke(3, "bye"); + ClearAllCalls(actions); + } + + private void ClearAllCalls(IEnumerable subs) + { + foreach (var sub in subs) { sub.ClearReceivedCalls(); } + } + } } \ No newline at end of file diff --git a/Source/NSubstitute/Arg.cs b/Source/NSubstitute/Arg.cs index 518f5096a..a55a855c8 100644 --- a/Source/NSubstitute/Arg.cs +++ b/Source/NSubstitute/Arg.cs @@ -1,141 +1,141 @@ -using System; -using System.Linq.Expressions; -using NSubstitute.Core; -using NSubstitute.Core.Arguments; - -namespace NSubstitute -{ - /// - /// Argument matchers used for specifying calls to substitutes. - /// - public static class Arg - { - private readonly static ArgumentSpecificationQueue ArgSpecQueue = new ArgumentSpecificationQueue(SubstitutionContext.Current); - - /// - /// Match any argument value compatible with type . - /// - /// - /// - public static T Any() - { - return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(T))); - } - - /// - /// Match argument that is equal to . - /// - /// - /// - /// - public static T Is(T value) - { - return ArgSpecQueue.EnqueueSpecFor(new EqualsArgumentMatcher(value)); - } - - /// - /// Match argument that satisfies . - /// If the throws an exception for an argument it will be treated as non-matching. - /// - /// - /// - /// - public static T Is(Expression> predicate) - { - return ArgSpecQueue.EnqueueSpecFor(new ExpressionArgumentMatcher(predicate)); - } - - /// - /// Invoke any argument as soon as a matching call is made to the substitute. - /// - /// - public static Action Invoke() - { - return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction()); - } - - /// - /// Invoke any argument with specified argument as soon as a matching call is made to the substitute. - /// - /// - /// - /// - public static Action Invoke(T arg) - { - return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg)); - } - - /// - /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. - /// - /// - /// - /// - /// - /// - public static Action Invoke(T1 arg1, T2 arg2) - { - return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg1, arg2)); - } - - /// - /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. - /// - /// - /// - /// - /// - /// - /// - /// - public static Action Invoke(T1 arg1, T2 arg2, T3 arg3) - { - return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg1, arg2, arg3)); - } - - /// - /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static Action Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg1, arg2, arg3, arg3)); - } - - /// - /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. - /// - /// - /// Arguments to pass to delegate. - /// - public static TDelegate InvokeDelegate(params object[] arguments) - { - return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(TDelegate)), InvokeDelegateAction(arguments)); - } - - /// - /// Capture any argument compatible with type and use it to call the function - /// as soon as a matching call is made to the substitute. - /// - /// - /// - /// - public static T Do(Action useArgument) - { - return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(T)), x => useArgument((T)x)); - } - - private static Action InvokeDelegateAction(params object[] arguments) - { - return x => ((Delegate)x).DynamicInvoke(arguments); - } - } -} +using System; +using System.Linq.Expressions; +using NSubstitute.Core; +using NSubstitute.Core.Arguments; + +namespace NSubstitute +{ + /// + /// Argument matchers used for specifying calls to substitutes. + /// + public static class Arg + { + private readonly static ArgumentSpecificationQueue ArgSpecQueue = new ArgumentSpecificationQueue(SubstitutionContext.Current); + + /// + /// Match any argument value compatible with type . + /// + /// + /// + public static T Any() + { + return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(T))); + } + + /// + /// Match argument that is equal to . + /// + /// + /// + /// + public static T Is(T value) + { + return ArgSpecQueue.EnqueueSpecFor(new EqualsArgumentMatcher(value)); + } + + /// + /// Match argument that satisfies . + /// If the throws an exception for an argument it will be treated as non-matching. + /// + /// + /// + /// + public static T Is(Expression> predicate) + { + return ArgSpecQueue.EnqueueSpecFor(new ExpressionArgumentMatcher(predicate)); + } + + /// + /// Invoke any argument as soon as a matching call is made to the substitute. + /// + /// + public static Action Invoke() + { + return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction()); + } + + /// + /// Invoke any argument with specified argument as soon as a matching call is made to the substitute. + /// + /// + /// + /// + public static Action Invoke(T arg) + { + return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg)); + } + + /// + /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. + /// + /// + /// + /// + /// + /// + public static Action Invoke(T1 arg1, T2 arg2) + { + return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg1, arg2)); + } + + /// + /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. + /// + /// + /// + /// + /// + /// + /// + /// + public static Action Invoke(T1 arg1, T2 arg2, T3 arg3) + { + return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg1, arg2, arg3)); + } + + /// + /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Action Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + return ArgSpecQueue.EnqueueSpecFor>(new AnyArgumentMatcher(typeof(Action)), InvokeDelegateAction(arg1, arg2, arg3, arg4)); + } + + /// + /// Invoke any argument with specified arguments as soon as a matching call is made to the substitute. + /// + /// + /// Arguments to pass to delegate. + /// + public static TDelegate InvokeDelegate(params object[] arguments) + { + return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(TDelegate)), InvokeDelegateAction(arguments)); + } + + /// + /// Capture any argument compatible with type and use it to call the function + /// as soon as a matching call is made to the substitute. + /// + /// + /// + /// + public static T Do(Action useArgument) + { + return ArgSpecQueue.EnqueueSpecFor(new AnyArgumentMatcher(typeof(T)), x => useArgument((T)x)); + } + + private static Action InvokeDelegateAction(params object[] arguments) + { + return x => ((Delegate)x).DynamicInvoke(arguments); + } + } +}