コード例 #1
0
        public void GetBranchPoints_ExceptionFilter()
        {
            // arrange
            var type   = _module.Types.Single(x => x.FullName == typeof(ExceptionFilter).FullName);
            var method = type.Methods.Single(x => x.FullName.Contains($"::{nameof(ExceptionFilter.Test)}"));
            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            Assert.Empty(points);
        }
コード例 #2
0
        public void GetBranchPoints_GeneratedBranches_DueToCachedAnonymousMethodDelegate_Ignored()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSimpleTaskWithLambda)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            Assert.Empty(points);
        }
コード例 #3
0
        public void GetBranchPoints_Using_Where_GeneratedBranchesIgnored()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSimpleUsingStatement)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            Assert.Equal(2, points.Count());
        }
コード例 #4
0
        public CecilSymbolHelperTests()
        {
            string location = GetType().Assembly.Location;

            _resolver = new DefaultAssemblyResolver();
            _resolver.AddSearchDirectory(Path.GetDirectoryName(location));
            _parameters = new ReaderParameters {
                ReadSymbols = true, AssemblyResolver = _resolver
            };
            _module            = ModuleDefinition.ReadModule(location, _parameters);
            _cecilSymbolHelper = new CecilSymbolHelper();
        }
コード例 #5
0
        public void GetBranchPoints_IgnoresBranchesIn_AsyncAwaitStateMachine()
        {
            // arrange
            var nestedName = typeof(AsyncAwaitStateMachine).GetNestedTypes(BindingFlags.NonPublic).First().Name;
            var type       = _module.Types.FirstOrDefault(x => x.FullName == typeof(AsyncAwaitStateMachine).FullName);
            var nestedType = type.NestedTypes.FirstOrDefault(x => x.FullName.EndsWith(nestedName));
            var method     = nestedType.Methods.First(x => x.FullName.EndsWith("::MoveNext()"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.Empty(points);
        }
コード例 #6
0
        public void GetBranchPoints_CompleteIf()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasCompleteIf)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(2, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(34, points[0].StartLine);
            Assert.Equal(34, points[1].StartLine);
        }
コード例 #7
0
        public void GetBranchPoints_TwoBranch()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains("::HasTwoDecisions"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(4, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(points[2].Offset, points[3].Offset);
            Assert.Equal(27, points[0].StartLine);
            Assert.Equal(28, points[2].StartLine);
        }
コード例 #8
0
        public void Prepare(Project testProject, ConfigurationSelector configuration, DataCollectorSettings coverageSettings)
        {
            var unitTestDll           = testProject.GetOutputFileName(configuration).ToString();
            var sourceRootTranslator  = new SourceRootTranslator(logger, fileSystem);
            var cecilSymbolHelper     = new CecilSymbolHelper();
            var instrumentationHelper = new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), fileSystem, logger, sourceRootTranslator);
            var coverageParameters    = GetCoverageParameters(coverageSettings);

            var coverage = new CoverletCoverage(unitTestDll,
                                                coverageParameters,
                                                logger,
                                                instrumentationHelper,
                                                fileSystem,
                                                sourceRootTranslator,
                                                cecilSymbolHelper);

            coverage.PrepareModules();
            projectCoverageMap[new Tuple <Project, ConfigurationSelector>(testProject, configuration)] = coverage;
        }
コード例 #9
0
        public void GetBranchPoints_OneBranch()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSingleDecision)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(2, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(0, points[0].Path);
            Assert.Equal(1, points[1].Path);
            Assert.Equal(21, points[0].StartLine);
            Assert.Equal(21, points[1].StartLine);
            Assert.NotNull(points[1].Document);
            Assert.Equal(points[0].Document, points[1].Document);
        }
コード例 #10
0
        public void GetBranchPoints_UsingWithException_Issue243_IgnoresBranchInFinallyBlock()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.UsingWithException_Issue243)}"));

            // check that the method is laid out the way we discovered it to be during the defect
            // @see https://github.com/OpenCover/opencover/issues/243
            Assert.Single(method.Body.ExceptionHandlers);
            Assert.NotNull(method.Body.ExceptionHandlers[0].HandlerStart);
            Assert.Null(method.Body.ExceptionHandlers[0].HandlerEnd);
            Assert.Equal(1, method.Body.Instructions.Count(i => i.OpCode.FlowControl == FlowControl.Cond_Branch));
            Assert.True(method.Body.Instructions.First(i => i.OpCode.FlowControl == FlowControl.Cond_Branch).Offset > method.Body.ExceptionHandlers[0].HandlerStart.Offset);

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.Empty(points);
        }
コード例 #11
0
        public void GetBranchPoints_AssignsNegativeLineNumberToBranchesInMethodsThatHaveNoInstrumentablePoints()
        {
            /*
             * Yes these actually exist - the compiler is very inventive
             * in this case for an anonymous class the compiler will dynamically create an Equals 'utility' method.
             */
            // arrange
            var type   = _module.Types.First(x => x.FullName.Contains("f__AnonymousType"));
            var method = type.Methods.First(x => x.FullName.Contains("::Equals"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            foreach (var branchPoint in points)
            {
                Assert.Equal(-1, branchPoint.StartLine);
            }
        }
コード例 #12
0
        public void GetBranchPoints_SwitchWithBreaks()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSwitchWithBreaks)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(4, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(points[0].Offset, points[2].Offset);
            Assert.Equal(3, points[3].Path);

            Assert.Equal(76, points[0].StartLine);
            Assert.Equal(76, points[1].StartLine);
            Assert.Equal(76, points[2].StartLine);
            Assert.Equal(76, points[3].StartLine);
        }
コード例 #13
0
        private void InstrumentIL(MethodDefinition method)
        {
            method.Body.SimplifyMacros();
            ILProcessor processor = method.Body.GetILProcessor();

            var index = 0;
            var count = processor.Body.Instructions.Count;

            var branchPoints = CecilSymbolHelper.GetBranchPoints(method);

            for (int n = 0; n < count; n++)
            {
                var instruction          = processor.Body.Instructions[index];
                var sequencePoint        = method.DebugInformation.GetSequencePoint(instruction);
                var targetedBranchPoints = branchPoints.Where(p => p.EndOffset == instruction.Offset);

                if (sequencePoint != null && !sequencePoint.IsHidden)
                {
                    var target = AddInstrumentationCode(method, processor, instruction, sequencePoint);
                    foreach (var _instruction in processor.Body.Instructions)
                    {
                        ReplaceInstructionTarget(_instruction, instruction, target);
                    }

                    foreach (ExceptionHandler handler in processor.Body.ExceptionHandlers)
                    {
                        ReplaceExceptionHandlerBoundary(handler, instruction, target);
                    }

                    index += 2;
                }

                foreach (var _branchTarget in targetedBranchPoints)
                {
                    /*
                     * Skip branches with no sequence point reference for now.
                     * In this case for an anonymous class the compiler will dynamically create an Equals 'utility' method.
                     * The CecilSymbolHelper will create branch points with a start line of -1 and no document, which
                     * I am currently not sure how to handle.
                     */
                    if (_branchTarget.StartLine == -1 || _branchTarget.Document == null)
                    {
                        continue;
                    }

                    var target = AddInstrumentationCode(method, processor, instruction, _branchTarget);
                    foreach (var _instruction in processor.Body.Instructions)
                    {
                        ReplaceInstructionTarget(_instruction, instruction, target);
                    }

                    foreach (ExceptionHandler handler in processor.Body.ExceptionHandlers)
                    {
                        ReplaceExceptionHandlerBoundary(handler, instruction, target);
                    }

                    index += 2;
                }

                index++;
            }

            method.Body.OptimizeMacros();
        }