Making ArgumentSpecification able to create a copy of itself that matches
any args. This moves the logic from CallSpecification and ArgumentSpecificationsFactory.
This commit is contained in:
Родитель
f1f137c7df
Коммит
fd2679d932
|
@ -63,40 +63,34 @@ namespace NSubstitute.Specs.Arguments
|
|||
|
||||
public class When_creating_arg_specs_that_match_any_arguments : When_creating_argument_specifications
|
||||
{
|
||||
private IArgumentSpecification _anyArgsVersionOfIntSpec;
|
||||
private IArgumentSpecification _anyArgsVersionOfStringSpec;
|
||||
|
||||
public override void Context()
|
||||
{
|
||||
base.Context();
|
||||
_matchArgs = MatchArgs.Any;
|
||||
|
||||
_mixedArgumentSpecifications.Add(CreateSpecWith(typeof(int), x => { }));
|
||||
_mixedArgumentSpecifications.Add(CreateSpecWith(typeof(string), x => { }));
|
||||
_anyArgsVersionOfIntSpec = mock<IArgumentSpecification>();
|
||||
_anyArgsVersionOfStringSpec = mock<IArgumentSpecification>();
|
||||
|
||||
_mixedArgumentSpecifications.Add(CreateSpecWith(typeof(int), _anyArgsVersionOfIntSpec));
|
||||
_mixedArgumentSpecifications.Add(CreateSpecWith(typeof(string), _anyArgsVersionOfStringSpec));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_return_arg_specs_based_on_those_worked_out_by_mixed_arg_spec_factory()
|
||||
{
|
||||
for (int i = 0; i < _mixedArgumentSpecifications.Count(); i++)
|
||||
{
|
||||
var argSpec = _result.ElementAt(i);
|
||||
Assert.That(argSpec.IsSatisfiedBy(GetAnyValueFor(argSpec.ForType)), "Result should match any argument of compatible type");
|
||||
Assert.That(argSpec.ForType, Is.EqualTo(_mixedArgumentSpecifications[i].ForType), "Result should be for same arg type");
|
||||
Assert.That(argSpec.Action, Is.EqualTo(_mixedArgumentSpecifications[i].Action), "Result should have same specified action");
|
||||
}
|
||||
var resultArray = _result.ToArray();
|
||||
Assert.That(resultArray[0], Is.EqualTo(_anyArgsVersionOfIntSpec), "Result should be a copy of original spec that matches any args");
|
||||
Assert.That(resultArray[1], Is.SameAs(_anyArgsVersionOfStringSpec), "Result should be a copy of original spec that matches any args");
|
||||
}
|
||||
|
||||
private object GetAnyValueFor(Type t)
|
||||
{
|
||||
if (t == typeof(string)) return "sample value";
|
||||
if (t == typeof(int)) return 123423;
|
||||
throw new ArgumentOutOfRangeException("Was not expecting type " + t.Name + ". If you added another argument specification " +
|
||||
"for this type to the fixture context you'll also need to provide a sample value for it.");
|
||||
}
|
||||
|
||||
private IArgumentSpecification CreateSpecWith(Type type, Action<object> action)
|
||||
private IArgumentSpecification CreateSpecWith(Type type, IArgumentSpecification anyArgsVersionOfSpec)
|
||||
{
|
||||
var spec = mock<IArgumentSpecification>();
|
||||
spec.stub(x => x.ForType).Return(type);
|
||||
spec.Action = action;
|
||||
spec.stub(x => x.CreateCopyMatchingAnyArgOfType(type)).Return(anyArgsVersionOfSpec);
|
||||
return spec;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,5 +26,16 @@ namespace NSubstitute.Core.Arguments
|
|||
public Type ForType { get { return _forType; } }
|
||||
public Action<object> Action { get; set; }
|
||||
public override string ToString() { return _matcher.ToString(); }
|
||||
|
||||
public IArgumentSpecification CreateCopyMatchingAnyArgOfType(Type requiredType)
|
||||
{
|
||||
return new ArgumentSpecification(requiredType, new AnyArgumentMatcher(requiredType)) { Action = RunActionIfTypeIsCompatible };
|
||||
}
|
||||
|
||||
private void RunActionIfTypeIsCompatible(object argument)
|
||||
{
|
||||
if (!argument.IsCompatibleWith(ForType)) return;
|
||||
Action(argument);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,13 +17,8 @@ namespace NSubstitute.Core.Arguments
|
|||
var argumentSpecifications = _mixedArgumentSpecificationsFactory.Create(argumentSpecs, arguments, parameterInfos);
|
||||
|
||||
return (matchArgs == MatchArgs.Any)
|
||||
? argumentSpecifications.Select(x => CreateVariantOfArgSpecThatMatchesAnyCompatibleArg(x))
|
||||
? argumentSpecifications.Select(x => x.CreateCopyMatchingAnyArgOfType(x.ForType))
|
||||
: argumentSpecifications;
|
||||
}
|
||||
|
||||
private IArgumentSpecification CreateVariantOfArgSpecThatMatchesAnyCompatibleArg(IArgumentSpecification x)
|
||||
{
|
||||
return new ArgumentSpecification(x.ForType, new AnyArgumentMatcher(x.ForType)) { Action = x.Action};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,5 +7,6 @@ namespace NSubstitute.Core.Arguments
|
|||
bool IsSatisfiedBy(object argument);
|
||||
Type ForType { get; }
|
||||
Action<object> Action { get; set; }
|
||||
IArgumentSpecification CreateCopyMatchingAnyArgOfType(Type requiredType);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
@ -46,7 +45,7 @@ namespace NSubstitute.Core
|
|||
.GetParameters()
|
||||
.Zip(
|
||||
_argumentSpecifications,
|
||||
(p, spec) => ConvertArgSpecToMatchAnyInstanceOfParameterType(p, spec)
|
||||
(p, spec) => spec.CreateCopyMatchingAnyArgOfType(p.ParameterType)
|
||||
)
|
||||
.ToArray();
|
||||
return new CallSpecification(_methodInfo, anyArgs);
|
||||
|
@ -63,21 +62,6 @@ namespace NSubstitute.Core
|
|||
}
|
||||
}
|
||||
|
||||
private IArgumentSpecification ConvertArgSpecToMatchAnyInstanceOfParameterType(ParameterInfo parameter, IArgumentSpecification spec)
|
||||
{
|
||||
var requiredType = parameter.ParameterType;
|
||||
return new ArgumentSpecification(requiredType, new AnyArgumentMatcher(requiredType))
|
||||
{
|
||||
Action = x => RunActionIfTypeIsCompatible(x, spec.Action, spec.ForType)
|
||||
};
|
||||
}
|
||||
|
||||
private void RunActionIfTypeIsCompatible(object argument, Action<object> action, Type requiredType)
|
||||
{
|
||||
if (!argument.IsCompatibleWith(requiredType)) return;
|
||||
action(argument);
|
||||
}
|
||||
|
||||
private bool HasDifferentNumberOfArguments(ICall call)
|
||||
{
|
||||
return _argumentSpecifications.Length != call.GetArguments().Length;
|
||||
|
|
Загрузка…
Ссылка в новой задаче