private static bool DispatchInvocation(Invocation invocation) { DebugView.TraceEvent(IndentLevel.Dispatch, () => String.Format("Intercepted profiler call: {0}", invocation.InputToString())); DebugView.PrintStackTrace(); var mockMixin = invocation.MockMixin; var repo = mockMixin != null ? mockMixin.Repository : MockingContext.ResolveRepository(UnresolvedContextBehavior.CreateNewContextual); if (repo == null) { repo = TryFindGlobalInterceptor(invocation.Method); } if (repo == null) { return(false); } lock (repo) { repo.DispatchInvocation(invocation); } if (invocation.CallOriginal) { DebugView.TraceEvent(IndentLevel.DispatchResult, () => "Calling original implementation"); } else if (invocation.IsReturnValueSet) { DebugView.TraceEvent(IndentLevel.DispatchResult, () => String.Format("Returning value '{0}'", invocation.ReturnValue)); } return(true); }
protected void GetMethodMockInternal(CallPattern callPattern, int depth, List <MethodMockMatcherTreeNode> results, MatchingOptions matchingOptions) { if (depth == callPattern.ArgumentMatchers.Count + 1) { var resultNode = this.Children.Select(x => x as MethodMockMatcherTreeNode).ToList(); results.AddRange(resultNode); foreach (var result in resultNode) { DebugView.TraceEvent(IndentLevel.Matcher, () => String.Format("Found candidate arrangement (id={0}) {1} {2}", result.Id, result.MethodMock.ArrangementExpression, result.MethodMock.IsSequential ? String.Format("(in sequence, used: {0})", result.MethodMock.IsUsed ? "yes" : "no") : "")); } return; } var matcher = depth == 0 ? callPattern.InstanceMatcher : callPattern.ArgumentMatchers[depth - 1]; var children = this.GetMatchingChildren(matcher, matchingOptions, depth); foreach (var child in children) { child.GetMethodMockInternal(callPattern, depth + 1, results, matchingOptions); } }
public void SetMethod(MethodBase method, bool checkCompatibility) { if (checkCompatibility) { if (method == typeof(object).GetConstructor(MockingUtil.EmptyTypes)) { DebugView.TraceEvent(Diagnostics.IndentLevel.Warning, () => "System.Object constructor will be intercepted only in 'new' expressions, i.e. 'new object()'."); } CheckMethodCompatibility(method); CheckInstrumentationAvailability(method); } this.method = method; }
private static bool TraceMatch(IMatcher baseMatcher, IMatcher targetMatcher, int depth) { bool isMatch = baseMatcher.Matches(targetMatcher); DebugView.TraceEvent(IndentLevel.Matcher, () => String.Format("{3}: {0} -> \"{1}\" {4} \"{2}\"", isMatch ? "Match" : "No match", targetMatcher.DebugView, baseMatcher.DebugView, depth == 0 ? "this" : "arg " + depth, isMatch ? "is" : "is not")); return(isMatch); }
public void Intercept(IInvocation invocation) { if (ProfilerInterceptor.ReentrancyCounter > 0) { CallOriginal(invocation, false); return; } bool callOriginal = false; ProfilerInterceptor.GuardInternal(() => { var mockInvocation = new Invocation(invocation.Proxy, invocation.GetConcreteMethod(), invocation.Arguments); DebugView.TraceEvent(IndentLevel.Dispatch, () => String.Format("Intercepted DP call: {0}", mockInvocation.InputToString())); DebugView.PrintStackTrace(); var mock = mockInvocation.MockMixin; var repo = mock != null ? mock.Repository : this.constructionRepo; lock (repo) { repo.DispatchInvocation(mockInvocation); } invocation.ReturnValue = mockInvocation.ReturnValue; callOriginal = mockInvocation.CallOriginal; if (callOriginal) { DebugView.TraceEvent(IndentLevel.DispatchResult, () => "Calling original implementation"); } else if (mockInvocation.IsReturnValueSet) { DebugView.TraceEvent(IndentLevel.DispatchResult, () => String.Format("Returning value '{0}'", invocation.ReturnValue)); } }); if (callOriginal) { CallOriginal(invocation, true); } }
private static bool NodeMatchesFilter(CallPattern callPattern, IMatcherTreeNode node) { var filter = callPattern.Filter; if (filter == null) { return(true); } var args = new List <object>(); var nodeIter = node; while (nodeIter != null) { var valueMatcher = nodeIter.Matcher as IValueMatcher; if (valueMatcher != null) { args.Add(valueMatcher.Value); } nodeIter = nodeIter.Parent; } if (!callPattern.Method.IsStatic && filter.Method.GetParameters().Length + 1 == args.Count) { args.RemoveAt(args.Count - 1); } args.Reverse(); var argsArray = args.ToArray(); object state; MockingUtil.BindToMethod(MockingUtil.Default, new[] { filter.Method }, ref argsArray, null, null, null, out state); var filterFunc = MockingUtil.MakeFuncCaller(filter); var isMatch = (bool)ProfilerInterceptor.GuardExternal(() => filterFunc(argsArray, filter)); DebugView.TraceEvent(IndentLevel.Matcher, () => String.Format("Matcher predicate {0} call to {2} with arguments ({1})", isMatch ? "passed" : "rejected", String.Join(", ", args.Select(x => x.ToString()).ToArray()), callPattern.Method)); return(isMatch); }
public static MocksRepository ResolveRepository(UnresolvedContextBehavior unresolvedContextBehavior) { if (unresolvedContextBehavior != UnresolvedContextBehavior.DoNotCreateNew) { DebugView.TraceEvent(IndentLevel.StackTrace, () => String.Format("Resolving repository with unresolved context behavior {0}", unresolvedContextBehavior)); } foreach (var resolver in registeredContextResolvers) { var repo = resolver.ResolveRepository(unresolvedContextBehavior); if (repo != null) { lastFrameworkAwareRepository = repo; return(repo); } } if (lastFrameworkAwareRepository != null && !ProfilerInterceptor.IsProfilerAttached) { return(lastFrameworkAwareRepository); } return(LocalMockingContextResolver.ResolveRepository(unresolvedContextBehavior)); }
public static void EnableInterception(Type type, bool enabled, MocksRepository behalf) { if (IsProfilerAttached) { #if DEBUG lock (typesEnabledByRepo) { HashSet <Type> types; if (!typesEnabledByRepo.TryGetValue(behalf, out types)) { types = new HashSet <Type>(); typesEnabledByRepo.Add(behalf, types); } if (types.Contains(type) == enabled) { throw new InvalidOperationException("Type interception enabled or disabled twice."); } if (enabled) { types.Add(type); } else { types.Remove(type); } if (types.Count == 0) { typesEnabledByRepo.Remove(behalf); } } #endif bool enabledInAnyRepository; DebugView.TraceEvent(IndentLevel.Configuration, () => String.Format("Interception of type {0} is now {1}", type, enabled ? "on" : "off")); lock (enabledInterceptions) { var hasKey = enabledInterceptions.ContainsKey(type); if (!hasKey) { enabledInterceptions.Add(type, enabled ? 1 : 0); enabledInAnyRepository = enabled; } else { var count = enabledInterceptions[type]; if (!enabled && count > 0) { count--; } else if (enabled) { count++; } enabledInAnyRepository = count > 0; enabledInterceptions[type] = count; } } var typeId = GetTypeId(type); var arrayIndex = typeId >> 3; var arrayMask = 1 << (typeId & ((1 << 3) - 1)); lock (arrangedTypesArray) { if (enabledInAnyRepository) { arrangedTypesArray[arrayIndex] = (byte)(arrangedTypesArray[arrayIndex] | arrayMask); } else { arrangedTypesArray[arrayIndex] = (byte)(arrangedTypesArray[arrayIndex] & ~arrayMask); } } } }