예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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;
        }
예제 #4
0
        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);
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        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));
        }
예제 #8
0
        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);
                    }
                }
            }
        }