/// <summary> /// Try to handle the call - set ref/out params and return value. /// </summary> public RouteAction Handle(ICall call) { if (call == null) { throw new ArgumentNullException(nameof(call)); } // Don't care about concurrency. If race condition happens - simply use the latest result. CallResultData result; if (!this.ResultCache.TryGetResult(call, out result)) { result = this.ResultResolver.ResolveResult(call); var callSpec = this.CallSpecificationFactory.CreateFrom(call, MatchArgs.AsSpecifiedInCall); this.ResultCache.AddResult(callSpec, result); } var callArguments = call.GetArguments(); var originalArguments = call.GetOriginalArguments(); foreach (var argumentValue in result.ArgumentValues) { var argIndex = argumentValue.Index; // If ref/out value has been already modified (e.g. by When..Do), don't override that value. if (!ArgValueWasModified(callArguments[argIndex], originalArguments[argIndex])) { callArguments[argIndex] = argumentValue.Value; } } return(result.ReturnValue.Fold(RouteAction.Continue, RouteAction.Return)); }
public IEnumerable<ArgumentMatchInfo> NonMatchingArguments(ICall call) { var arguments = call.GetOriginalArguments(); return arguments .Select((arg, index) => new ArgumentMatchInfo(index, arg, _argumentSpecifications[index])) .Where(x => !x.IsMatch); }
private static bool IsSpecifyingACall(ICall call, IRoute currentRoute) { var args = call.GetOriginalArguments() ?? EmptyArgs; var argSpecs = call.GetArgumentSpecifications() ?? EmptyArgSpecs; return(currentRoute.IsRecordReplayRoute && args.Any() && argSpecs.Any()); }
public IEnumerable <ArgumentMatchInfo> NonMatchingArguments(ICall call) { var arguments = call.GetOriginalArguments(); return(arguments .Select((arg, index) => new ArgumentMatchInfo(index, arg, _argumentSpecifications[index])) .Where(x => !x.IsMatch)); }
public ICallSpecification CreateFrom(ICall call, MatchArgs matchArgs) { var methodInfo = call.GetMethodInfo(); var argumentSpecs = call.GetArgumentSpecifications(); var arguments = call.GetOriginalArguments(); var parameterInfos = call.GetParameterInfos(); var argumentSpecificationsForCall = _argumentSpecificationsFactory.Create(argumentSpecs, arguments, parameterInfos, matchArgs); return new CallSpecification(methodInfo, argumentSpecificationsForCall); }
private string Format(ICall call) { var methodInfo = call.GetMethodInfo(); var args = methodInfo.GetParameters() .Zip(call.GetOriginalArguments(), (p, a) => new ArgAndParamInfo(p, a)) .ToArray(); return(CallFormatter.Default.Format(methodInfo, FormatArgs(args))); }
public ICallSpecification CreateFrom(ICall call, MatchArgs matchArgs) { var methodInfo = call.GetMethodInfo(); var argumentSpecs = call.GetArgumentSpecifications(); var arguments = call.GetOriginalArguments(); var parameterInfos = call.GetParameterInfos(); var argumentSpecificationsForCall = _argumentSpecificationsFactory.Create(argumentSpecs, arguments, parameterInfos, methodInfo, matchArgs); return(new CallSpecification(methodInfo, argumentSpecificationsForCall)); }
private static Argument[] GetArgumentsFromCall(ICall call) { var result = new Argument[call.GetOriginalArguments().Length]; for (var i = 0; i < result.Length; i++) { result[i] = new Argument(call, i); } return(result); }
private static void If(ICall call, Func <ICall, Predicate <EventInfo> > meetsThisSpecification, Action <string, object> takeThisAction) { var matchingEvent = GetEvents(call, meetsThisSpecification).FirstOrDefault(); if (matchingEvent != null) { // It's important to use original arguments, as it provides better performance. // It's safe to use original arguments here, as only by-ref arguments might be modified, // which should never happen for this case. takeThisAction(matchingEvent.Name, call.GetOriginalArguments()[0] !); } }
private bool IsMatchingArgumentSpecifications(ICall call) { object?[] arguments = call.GetOriginalArguments(); for (int i = 0; i < arguments.Length; i++) { if (!_argumentSpecifications[i].IsSatisfiedBy(arguments[i])) { return(false); } } return(true); }
public RouteAction Handle(ICall call) { if (_propertyHelper.IsCallToSetAReadWriteProperty(call)) { var callToPropertyGetter = _propertyHelper.CreateCallToPropertyGetterFromSetterCall(call); // It's important to use original arguments, as it provides better performance. // It's safe to use original arguments here, as only by-ref arguments might be modified, // which should never happen for this case. var valueBeingSetOnProperty = call.GetOriginalArguments().Last(); ConfigureCall.SetResultForCall(callToPropertyGetter, new ReturnValue(valueBeingSetOnProperty), MatchArgs.AsSpecifiedInCall); } return(RouteAction.Continue()); }
public ICall CreateCallToPropertyGetterFromSetterCall(ICall callToSetter) { var propertyInfo = GetPropertyFromSetterCallOrNull(callToSetter); if (!PropertySetterExistsAndHasAGetMethod(propertyInfo)) { throw new InvalidOperationException("Could not find a GetMethod for \"" + callToSetter.GetMethodInfo() + "\""); } var getter = propertyInfo.GetGetMethod(); var getterArgs = SkipLast(callToSetter.GetOriginalArguments()); var getterArgumentSpecifications = GetGetterCallSpecificationsFromSetterCall(callToSetter); return(_callFactory.Create(getter, getterArgs, callToSetter.Target(), getterArgumentSpecifications)); }
public void MoveLogsSuccessfulMove() { // Arrange GroupFile file = new GroupFile(); ILogger <FileModifier> logger = Substitute.For <ILogger <FileModifier> >(); FileModifier uut = this.FileModifierWithDefaultMocks( logger: logger); // Act uut.Move(file, "destination"); // Assert ICall loggerCall = Assert.Single(logger.ReceivedCalls()); Assert.Equal("Log", loggerCall.GetMethodInfo().Name); Assert.Equal(LogLevel.Information, loggerCall.GetOriginalArguments().First()); }
public void MoveLogsFailedMove() { // Arrange GroupFile file = new GroupFile(); ILogger <FileModifier> logger = Substitute.For <ILogger <FileModifier> >(); IFileOperationsAbstraction ops = Substitute.For <IFileOperationsAbstraction>(); ops.When((x) => x.MoveFile(Arg.Any <string>(), Arg.Any <string>())) .Do((callInfo) => throw new Exception()); FileModifier uut = this.FileModifierWithDefaultMocks( logger: logger, fileOps: ops); // Act uut.Move(file, "destination"); // Assert ICall loggerCall = Assert.Single(logger.ReceivedCalls()); Assert.Equal("Log", loggerCall.GetMethodInfo().Name); Assert.Equal(LogLevel.Error, loggerCall.GetOriginalArguments().First()); }
private IList <IArgumentSpecification> GetGetterCallSpecificationsFromSetterCall(ICall callToSetter) { var lastSetterArg = callToSetter.GetOriginalArguments().Last(); var lastSetterArgType = callToSetter.GetParameterInfos().Last().ParameterType; var argumentSpecifications = callToSetter.GetArgumentSpecifications(); if (argumentSpecifications.Count == 0) { return(argumentSpecifications); } // Getter call has one less argument than the setter call (the last arg is trimmed). // Therefore, we need to remove the last argument specification if it's for the trimmed arg. // Otherwise, NSubstitute might find that the redundant argument specification is present and the // validation logic might trigger an exception. if (_argSpecCompatTester.IsSpecificationCompatible(argumentSpecifications.Last(), lastSetterArg, lastSetterArgType)) { argumentSpecifications = SkipLast(argumentSpecifications); } return(argumentSpecifications); }
public string Format(ICall call) { return CallFormatter.Format(call.GetMethodInfo(), FormatArguments(call.GetOriginalArguments())); }
public static string FormatArgs(this ICall call, DiagContextInternal ctx) { var methodInfo = call.GetMethodInfo(); return(CallFormatter.Format(methodInfo, call.GetOriginalArguments().Select(a => a.GetObjectId(ctx)))); }
private bool HasDifferentNumberOfArguments(ICall call) { return(_argumentSpecifications.Length != call.GetOriginalArguments().Length); }
public string Format(ICall call) { return(CallFormatter.Default.Format(call.GetMethodInfo(), FormatArguments(call.GetOriginalArguments()))); }
private bool HasDifferentNumberOfArguments(ICall call) { return _argumentSpecifications.Length != call.GetOriginalArguments().Length; }