Exemple #1
0
        public void Stryker_ShouldInvokeAllProcesses()
        {
            var projectOrchestratorMock = new Mock <IProjectOrchestrator>(MockBehavior.Strict);
            var mutationTestProcessMock = new Mock <IMutationTestProcess>(MockBehavior.Strict);
            var reporterFactoryMock     = new Mock <IReporterFactory>(MockBehavior.Strict);
            var reporterMock            = new Mock <IReporter>(MockBehavior.Strict);
            var fileSystemMock          = new MockFileSystem();

            var folder = new CsharpFolderComposite
            {
                Name = "ProjectRoot"
            };

            folder.Add(new CsharpFileLeaf()
            {
                Name    = "SomeFile.cs",
                Mutants = new List <Mutant> {
                    new Mutant {
                        Id = 1
                    }
                }
            });

            var mutationTestInput = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectContents = folder
                },
            };
            var options = new StrykerOptions(basePath: "c:/test", fileSystem: fileSystemMock);

            projectOrchestratorMock.Setup(x => x.MutateProjects(options, It.IsAny <IReporter>()))
            .Returns(new List <IMutationTestProcess>()
            {
                mutationTestProcessMock.Object
            });

            reporterFactoryMock.Setup(x => x.Create(It.IsAny <StrykerOptions>(), It.IsAny <IGitInfoProvider>())).Returns(reporterMock.Object);

            reporterMock.Setup(x => x.OnMutantsCreated(It.IsAny <IReadOnlyProjectComponent>()));
            reporterMock.Setup(x => x.OnStartMutantTestRun(It.IsAny <IEnumerable <IReadOnlyMutant> >()));
            reporterMock.Setup(x => x.OnAllMutantsTested(It.IsAny <IReadOnlyProjectComponent>()));

            mutationTestProcessMock.SetupGet(x => x.Input).Returns(mutationTestInput);
            mutationTestProcessMock.Setup(x => x.GetCoverage());
            mutationTestProcessMock.Setup(x => x.Test(It.IsAny <IEnumerable <Mutant> >()))
            .Returns(new StrykerRunResult(It.IsAny <StrykerOptions>(), It.IsAny <double>()));

            var target = new StrykerRunner(projectOrchestratorMock.Object, reporterFactory: reporterFactoryMock.Object);

            target.RunMutationTest(options);

            projectOrchestratorMock.Verify(x => x.MutateProjects(options, It.IsAny <IReporter>()), Times.Once);
            mutationTestProcessMock.Verify(x => x.GetCoverage(), Times.Once);
            mutationTestProcessMock.Verify(x => x.Test(It.IsAny <IEnumerable <Mutant> >()), Times.Once);
            reporterMock.Verify(x => x.OnMutantsCreated(It.IsAny <IReadOnlyProjectComponent>()), Times.Once);
            reporterMock.Verify(x => x.OnStartMutantTestRun(It.IsAny <IEnumerable <IReadOnlyMutant> >()), Times.Once);
            reporterMock.Verify(x => x.OnAllMutantsTested(It.IsAny <IReadOnlyProjectComponent>()), Times.Once);
        }
Exemple #2
0
        public void ClearTextTreeReporter_ShouldPrintOnReportDone()
        {
            var textWriter = new StringWriter();
            var target     = new ClearTextTreeReporter(new StrykerOptions(), textWriter);

            var folder = new CsharpFolderComposite()
            {
                RelativePath = "RootFolder",
                FullPath     = "C://RootFolder",
            };

            folder.Add(new CsharpFileLeaf()
            {
                RelativePath = "RootFolder/SomeFile.cs",
                FullPath     = "C://RootFolder/SomeFile.cs",
                Mutants      = new Collection <Mutant>()
                {
                }
            });

            target.OnAllMutantsTested(folder.ToReadOnly());

            textWriter.RemoveAnsi().ShouldBeWithNewlineReplace($@"

All mutants have been tested, and your mutation score has been calculated
All files [0/0 (N/A)]
└── SomeFile.cs [0/0 (N/A)]
");
            textWriter.DarkGraySpanCount().ShouldBe(2);
        }
Exemple #3
0
        public void ReportComponent_ShouldCalculateMutationScore_TwoFolders()
        {
            var target = new CsharpFolderComposite()
            {
                Name = "RootFolder"
            };

            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed
                    }
                }
            });
            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Survived
                    }
                }
            });

            var result = target.GetMutationScore();

            result.ShouldBe(0.5);
        }
        // initialize the test context and mock objects
        public VsTestRunnersTest()
        {
            var currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var filesystemRoot   = Path.GetPathRoot(currentDirectory);

            var          sourceFile                     = File.ReadAllText(currentDirectory + "/TestResources/ExampleSourceFile.cs");
            var          testProjectPath                = FilePathUtils.NormalizePathSeparators(Path.Combine(filesystemRoot !, "TestProject", "TestProject.csproj"));
            var          projectUnderTestPath           = FilePathUtils.NormalizePathSeparators(Path.Combine(filesystemRoot, "ExampleProject", "ExampleProject.csproj"));
            const string defaultTestProjectFileContents = @"<Project Sdk=""Microsoft.NET.Sdk"">
    <PropertyGroup>
        <TargetFramework>netcoreapp2.0</TargetFramework>
        <IsPackable>false</IsPackable>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include=""Microsoft.NET.Test.Sdk"" Version = ""15.5.0"" />
        <PackageReference Include=""xunit"" Version=""2.3.1"" />
        <PackageReference Include=""xunit.runner.visualstudio"" Version=""2.3.1"" />
        <DotNetCliToolReference Include=""dotnet-xunit"" Version=""2.3.1"" />
    </ItemGroup>
    <ItemGroup>
        <ProjectReference Include=""..\ExampleProject\ExampleProject.csproj"" />
    </ItemGroup>
</Project>";

            _testAssemblyPath = FilePathUtils.NormalizePathSeparators(Path.Combine(filesystemRoot, "_firstTest", "bin", "Debug", "TestApp.dll"));
            _executorUri      = new Uri("exec://nunit");
            var firstTest  = BuildCase("T0");
            var secondTest = BuildCase("T1");

            var content = new CsharpFolderComposite();

            _fileSystem = new MockFileSystem(new Dictionary <string, MockFileData>
            {
                { projectUnderTestPath, new MockFileData(defaultTestProjectFileContents) },
Exemple #5
0
        public void ClearTextReporter_ShouldPrintYellowBetweenThresholdLowAndThresholdBreak()
        {
            var tree         = CSharpSyntaxTree.ParseText("void M(){ int i = 0 + 8; }");
            var originalNode = tree.GetRoot().DescendantNodes().OfType <BinaryExpressionSyntax>().First();

            var mutation = new Mutation()
            {
                OriginalNode    = originalNode,
                ReplacementNode = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, originalNode.Left, originalNode.Right),
                DisplayName     = "This name should display",
                Type            = Mutator.Arithmetic
            };

            var textWriter = new StringWriter();
            var options    = new StrykerOptions {
                Thresholds = new Thresholds {
                    High = 90, Low = 70, Break = 0
                }
            };
            var target = new ClearTextReporter(options, textWriter);

            var folder = new CsharpFolderComposite()
            {
                RelativePath = "RootFolder",
                FullPath     = "C://RootFolder",
            };

            folder.Add(new CsharpFileLeaf()
            {
                RelativePath = "RootFolder/SomeFile.cs",
                FullPath     = "C://RootFolder/SomeFile.cs",
                Mutants      = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Survived, Mutation = mutation
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed, Mutation = mutation
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed, Mutation = mutation
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed, Mutation = mutation
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed, Mutation = mutation
                    }
                }
            });

            target.OnAllMutantsTested(folder);

            textWriter.YellowSpanCount().ShouldBe(2);
        }
Exemple #6
0
 private static void InjectMutantHelpers(CsharpFolderComposite rootFolderComposite, CSharpParseOptions cSharpParseOptions)
 {
     foreach (var(name, code) in CodeInjection.MutantHelpers)
     {
         rootFolderComposite.AddCompilationSyntaxTree(CSharpSyntaxTree.ParseText(code, path: name, encoding: Encoding.UTF32, options: cSharpParseOptions));
     }
 }
Exemple #7
0
        public void InitialisationProcess_ShouldCallNeededResolvers()
        {
            var testRunnerMock                = new Mock <ITestRunner>(MockBehavior.Strict);
            var inputFileResolverMock         = new Mock <IInputFileResolver>(MockBehavior.Strict);
            var initialBuildProcessMock       = new Mock <IInitialBuildProcess>(MockBehavior.Strict);
            var initialTestProcessMock        = new Mock <IInitialTestProcess>(MockBehavior.Strict);
            var assemblyReferenceResolverMock = new Mock <IAssemblyReferenceResolver>(MockBehavior.Strict);

            testRunnerMock.Setup(x => x.RunAll(It.IsAny <int>(), null, null))
            .Returns(new TestRunResult(true));     // testrun is successful
            testRunnerMock.Setup(x => x.DiscoverNumberOfTests()).Returns(999);
            testRunnerMock.Setup(x => x.Dispose());
            var projectContents = new CsharpFolderComposite();

            projectContents.Add(new CsharpFileLeaf
            {
                Name = "SomeFile.cs"
            });
            var folder = new CsharpFolderComposite
            {
                Name = "ProjectRoot"
            };

            folder.AddRange(new Collection <IProjectComponent>
            {
                new CsharpFileLeaf
                {
                    Name = "SomeFile.cs"
                }
            });
            inputFileResolverMock.Setup(x => x.ResolveInput(It.IsAny <IStrykerOptions>()))
            .Returns(new ProjectInfo
            {
                ProjectUnderTestAnalyzerResult = TestHelper.SetupProjectAnalyzerResult(
                    references: new string[0]).Object,
                TestProjectAnalyzerResults = new List <IAnalyzerResult> {
                    TestHelper.SetupProjectAnalyzerResult(
                        projectFilePath: "C://Example/Dir/ProjectFolder").Object
                },
                ProjectContents = folder
            });
            initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny <ITestRunner>())).Returns(999);
            initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <string>()));
            assemblyReferenceResolverMock.Setup(x => x.LoadProjectReferences(It.IsAny <string[]>()))
            .Returns(Enumerable.Empty <PortableExecutableReference>());

            var target = new InitialisationProcess(
                inputFileResolverMock.Object,
                initialBuildProcessMock.Object,
                initialTestProcessMock.Object,
                testRunnerMock.Object,
                assemblyReferenceResolverMock.Object);

            var options = new StrykerOptions();

            var result = target.Initialize(options);

            inputFileResolverMock.Verify(x => x.ResolveInput(It.IsAny <IStrykerOptions>()), Times.Once);
        }
        public void ShouldNotTest_WhenThereAreNoTestableMutations()
        {
            string basePath = Path.Combine(FilesystemRoot, "ExampleProject.Test");

            var folder = new CsharpFolderComposite()
            {
                Name = "ProjectRoot"
            };

            folder.Add(new CsharpFileLeaf()
            {
                Name    = "SomeFile.cs",
                Mutants = new Collection <Mutant>()
                {
                }
            });

            var projectUnderTest = TestHelper.SetupProjectAnalyzerResult(
                properties: new Dictionary <string, string>()
            {
                { "Language", "F#" }
            }).Object;
            var input = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectContents = folder,
                    ProjectUnderTestAnalyzerResult = projectUnderTest
                },
                AssemblyReferences = _assemblies
            };
            var reporterMock = new Mock <IReporter>(MockBehavior.Strict);

            reporterMock.Setup(x => x.OnMutantTested(It.IsAny <Mutant>()));

            var runnerMock = new Mock <ITestRunner>();

            runnerMock.Setup(x => x.DiscoverNumberOfTests()).Returns(1);
            var executorMock = new Mock <IMutationTestExecutor>(MockBehavior.Strict);

            executorMock.SetupGet(x => x.TestRunner).Returns(runnerMock.Object);
            executorMock.Setup(x => x.Test(It.IsAny <IList <Mutant> >(), It.IsAny <int>(), It.IsAny <TestUpdateHandler>()));

            var mutantFilterMock = new Mock <IMutantFilter>(MockBehavior.Loose);

            var options = new StrykerOptions(fileSystem: new MockFileSystem(), basePath: basePath);

            var target = new MutationTestProcess(input,
                                                 reporterMock.Object,
                                                 executorMock.Object,
                                                 mutantFilter: mutantFilterMock.Object,
                                                 options: options);

            var testResult = target.Test(folder.Mutants);

            executorMock.Verify(x => x.Test(It.IsAny <IList <Mutant> >(), It.IsAny <int>(), It.IsAny <TestUpdateHandler>()), Times.Never);
            reporterMock.Verify(x => x.OnMutantTested(It.IsAny <Mutant>()), Times.Never);
            testResult.MutationScore.ShouldBe(double.NaN);
        }
        private CsharpFolderComposite FindProjectFilesUsingBuildalyzer(IAnalyzerResult analyzerResult, StrykerOptions options)
        {
            var projectUnderTestDir             = Path.GetDirectoryName(analyzerResult.ProjectFilePath);
            var generatedAssemblyInfo           = analyzerResult.AssemblyAttributeFileName();
            var projectUnderTestFolderComposite = new CsharpFolderComposite()
            {
                FullPath     = projectUnderTestDir,
                RelativePath = null,
            };
            var cache = new Dictionary <string, CsharpFolderComposite> {
                [string.Empty] = projectUnderTestFolderComposite
            };

            // Save cache in a singleton so we can use it in other parts of the project
            FolderCompositeCache <CsharpFolderComposite> .Instance.Cache = cache;

            CSharpParseOptions cSharpParseOptions = BuildCsharpParseOptions(analyzerResult, options);

            InjectMutantHelpers(projectUnderTestFolderComposite, cSharpParseOptions);

            foreach (var sourceFile in analyzerResult.SourceFiles)
            {
                var relativePath    = Path.GetRelativePath(projectUnderTestDir, sourceFile);
                var folderComposite = GetOrBuildFolderComposite(cache, Path.GetDirectoryName(relativePath), projectUnderTestDir, projectUnderTestFolderComposite);

                var file = new CsharpFileLeaf()
                {
                    SourceCode   = FileSystem.File.ReadAllText(sourceFile),
                    FullPath     = sourceFile,
                    RelativePath = Path.GetRelativePath(projectUnderTestDir, sourceFile)
                };

                // Get the syntax tree for the source file
                var syntaxTree = CSharpSyntaxTree.ParseText(file.SourceCode,
                                                            path: file.FullPath,
                                                            encoding: Encoding.UTF32,
                                                            options: cSharpParseOptions);

                // don't mutate auto generated code
                if (syntaxTree.IsGenerated())
                {
                    // we found the generated assemblyinfo file
                    if (FileSystem.Path.GetFileName(sourceFile).ToLowerInvariant() == generatedAssemblyInfo)
                    {
                        // add the mutated text
                        syntaxTree = InjectMutationLabel(syntaxTree);
                    }
                    _logger.LogDebug("Skipping auto-generated code file: {fileName}", file.FullPath);
                    folderComposite.AddCompilationSyntaxTree(syntaxTree); // Add the syntaxTree to the list of compilationSyntaxTrees
                    continue;                                             // Don't add the file to the folderComposite as we're not reporting on the file
                }

                file.SyntaxTree = syntaxTree;
                folderComposite.Add(file);
            }

            return(projectUnderTestFolderComposite);
        }
Exemple #10
0
        public void ShouldStop_WhenAllMutationsWereIgnored()
        {
            var projectOrchestratorMock = new Mock <IProjectOrchestrator>(MockBehavior.Strict);
            var mutationTestProcessMock = new Mock <IMutationTestProcess>(MockBehavior.Strict);
            var reporterFactoryMock     = new Mock <IReporterFactory>(MockBehavior.Strict);
            var reporterMock            = new Mock <IReporter>(MockBehavior.Strict);
            var fileSystemMock          = new MockFileSystem();

            var folder = new CsharpFolderComposite()
            {
                Name = "ProjectRoot"
            };

            folder.Add(new CsharpFileLeaf
            {
                Name    = "SomeFile.cs",
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        Id = 1, ResultStatus = MutantStatus.Ignored
                    }
                }
            });
            var mutationTestInput = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectContents = folder
                }
            };
            var options = new StrykerOptions(basePath: "c:/test", fileSystem: fileSystemMock, coverageAnalysis: "off");

            projectOrchestratorMock.Setup(x => x.MutateProjects(options, It.IsAny <IReporter>()))
            .Returns(new List <IMutationTestProcess>()
            {
                mutationTestProcessMock.Object
            });

            mutationTestProcessMock.SetupGet(x => x.Input).Returns(mutationTestInput);

            reporterFactoryMock.Setup(x => x.Create(It.IsAny <StrykerOptions>(), It.IsAny <IGitInfoProvider>())).Returns(reporterMock.Object);

            reporterMock.Setup(x => x.OnMutantsCreated(It.IsAny <IReadOnlyProjectComponent>()));
            reporterMock.Setup(x => x.OnStartMutantTestRun(It.IsAny <IEnumerable <IReadOnlyMutant> >()));

            var target = new StrykerRunner(projectOrchestratorMock.Object, reporterFactory: reporterFactoryMock.Object);

            var result = target.RunMutationTest(options);

            result.MutationScore.ShouldBe(double.NaN);

            reporterMock.Verify(x => x.OnStartMutantTestRun(It.IsAny <IList <Mutant> >()), Times.Never);
            reporterMock.Verify(x => x.OnMutantTested(It.IsAny <Mutant>()), Times.Never);
            reporterMock.Verify(x => x.OnAllMutantsTested(It.IsAny <IReadOnlyProjectComponent>()), Times.Never);
        }
Exemple #11
0
        public void InitialisationProcess_ShouldCallNeededResolvers()
        {
            var testRunnerMock                = new Mock <ITestRunner>(MockBehavior.Strict);
            var inputFileResolverMock         = new Mock <IInputFileResolver>(MockBehavior.Strict);
            var initialBuildProcessMock       = new Mock <IInitialBuildProcess>(MockBehavior.Strict);
            var initialTestProcessMock        = new Mock <IInitialTestProcess>(MockBehavior.Strict);
            var assemblyReferenceResolverMock = new Mock <IAssemblyReferenceResolver>(MockBehavior.Strict);

            testRunnerMock.Setup(x => x.RunAll(It.IsAny <ITimeoutValueCalculator>(), null, null))
            .Returns(new TestRunResult(true));     // testrun is successful
            testRunnerMock.Setup(x => x.DiscoverTests()).Returns(new TestSet());
            testRunnerMock.Setup(x => x.Dispose());
            var projectContents = new CsharpFolderComposite();

            projectContents.Add(new CsharpFileLeaf());
            var folder = new CsharpFolderComposite();

            folder.AddRange(new Collection <IProjectComponent>
            {
                new CsharpFileLeaf()
            });
            inputFileResolverMock.Setup(x => x.ResolveInput(It.IsAny <StrykerOptions>()))
            .Returns(new ProjectInfo(new MockFileSystem())
            {
                ProjectUnderTestAnalyzerResult = TestHelper.SetupProjectAnalyzerResult(
                    references: new string[0]).Object,
                TestProjectAnalyzerResults = new List <IAnalyzerResult> {
                    TestHelper.SetupProjectAnalyzerResult(
                        projectFilePath: "C://Example/Dir/ProjectFolder",
                        targetFramework: "netcoreapp2.1").Object
                },
                ProjectContents = folder
            });
            initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny <StrykerOptions>(), It.IsAny <ITestRunner>())).Returns(new InitialTestRun(new TestRunResult(true), new TimeoutValueCalculator(1)));
            initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <string>(), null));
            assemblyReferenceResolverMock.Setup(x => x.LoadProjectReferences(It.IsAny <string[]>()))
            .Returns(Enumerable.Empty <PortableExecutableReference>());

            var target = new InitialisationProcess(
                inputFileResolverMock.Object,
                initialBuildProcessMock.Object,
                initialTestProcessMock.Object,
                testRunnerMock.Object,
                assemblyReferenceResolverMock.Object);

            var options = new StrykerOptions
            {
                ProjectName    = "TheProjectName",
                ProjectVersion = "TheProjectVersion"
            };

            var result = target.Initialize(options);

            inputFileResolverMock.Verify(x => x.ResolveInput(It.IsAny <StrykerOptions>()), Times.Once);
        }
        public void ShouldPrintEachReasonWithCount()
        {
            var target = new FilteredMutantsLogger(_loggerMock.Object);

            var folder = new CsharpFolderComposite();

            folder.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Ignored, ResultStatusReason = "In excluded file"
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Ignored, ResultStatusReason = "In excluded file"
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Ignored, ResultStatusReason = "Mutator excluded"
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Ignored, ResultStatusReason = "Mutator excluded"
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Ignored, ResultStatusReason = "Mutator excluded"
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.CompileError, ResultStatusReason = "CompileError"
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Ignored, ResultStatusReason = "In excluded file"
                    },
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.NotRun
                    },
                }
            });

            target.OnMutantsCreated(folder.ToReadOnlyInputComponent());

            _loggerMock.Verify(LogLevel.Information, "1     mutants got status CompileError. Reason: CompileError", Times.Once);
            _loggerMock.Verify(LogLevel.Information, "3     mutants got status Ignored.      Reason: In excluded file", Times.Once);
            _loggerMock.Verify(LogLevel.Information, "3     mutants got status Ignored.      Reason: Mutator excluded", Times.Once);
            _loggerMock.Verify(LogLevel.Information, "7     total mutants are skipped for the above mentioned reasons", Times.Once);
            _loggerMock.Verify(LogLevel.Information, "1     total mutants will be tested", Times.Once);
            _loggerMock.VerifyNoOtherCalls();
        }
Exemple #13
0
        public void ClearTextReporter_ShouldPrintKilledMutation()
        {
            var tree         = CSharpSyntaxTree.ParseText("void M(){ int i = 0 + 8; }");
            var originalNode = tree.GetRoot().DescendantNodes().OfType <BinaryExpressionSyntax>().First();

            var mutation = new Mutation()
            {
                OriginalNode    = originalNode,
                ReplacementNode = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, originalNode.Left, originalNode.Right),
                DisplayName     = "This name should display",
                Type            = Mutator.Arithmetic
            };

            var textWriter = new StringWriter();
            var target     = new ClearTextReporter(new StrykerOptions(), textWriter);

            var rootFolder = new CsharpFolderComposite();

            var folder = new CsharpFolderComposite()
            {
                RelativePath = "FolderA",
                FullPath     = "C://Project/FolderA",
            };

            folder.Add(new CsharpFileLeaf()
            {
                RelativePath = "FolderA/SomeFile.cs",
                FullPath     = "C://Project/FolderA/SomeFile.cs",
                Mutants      = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed,
                        Mutation     = mutation
                    }
                }
            });

            rootFolder.Add(folder);

            target.OnAllMutantsTested(rootFolder);

            textWriter.RemoveAnsi().ShouldBeWithNewlineReplace($@"

All mutants have been tested, and your mutation score has been calculated
┌─────────────────────┬──────────┬──────────┬───────────┬────────────┬──────────┬─────────┐
│ File                │  % score │ # killed │ # timeout │ # survived │ # no cov │ # error │
├─────────────────────┼──────────┼──────────┼───────────┼────────────┼──────────┼─────────┤
│ All files           │   {100:N2} │        1 │         0 │          0 │        0 │       0 │
│ FolderA/SomeFile.cs │   {100:N2} │        1 │         0 │          0 │        0 │       0 │
└─────────────────────┴──────────┴──────────┴───────────┴────────────┴──────────┴─────────┘
");
            textWriter.GreenSpanCount().ShouldBe(2);
        }
Exemple #14
0
        public void ShouldNotTest_WhenThereAreNoMutationsAtAll()
        {
            string basePath = Path.Combine(FilesystemRoot, "ExampleProject.Test");
            var    scenario = new FullRunScenario();
            var    folder   = new CsharpFolderComposite();

            folder.Add(new CsharpFileLeaf()
            {
                Mutants = scenario.GetMutants()
            });

            var projectUnderTest = TestHelper.SetupProjectAnalyzerResult(
                properties: new Dictionary <string, string>()
            {
                { "Language", "C#" }
            }).Object;
            var input = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo(new MockFileSystem())
                {
                    ProjectContents = folder,
                    ProjectUnderTestAnalyzerResult = projectUnderTest
                },
                AssemblyReferences = _assemblies
            };

            var executorMock = new Mock <IMutationTestExecutor>(MockBehavior.Strict);

            executorMock.SetupGet(x => x.TestRunner).Returns(scenario.GetTestRunnerMock().Object);
            executorMock.Setup(x => x.Test(It.IsAny <IList <Mutant> >(), It.IsAny <ITimeoutValueCalculator>(), It.IsAny <TestUpdateHandler>()));

            var mutantFilterMock = new Mock <IMutantFilter>(MockBehavior.Loose);

            var options = new StrykerOptions()
            {
                BasePath = basePath
            };

            var reporterMock = new Mock <IReporter>(MockBehavior.Strict);

            reporterMock.Setup(x => x.OnMutantTested(It.IsAny <Mutant>()));
            var target = new MutationTestProcess(input,
                                                 reporterMock.Object,
                                                 executorMock.Object,
                                                 mutantFilter: mutantFilterMock.Object,
                                                 options: options);

            var testResult = target.Test(input.ProjectInfo.ProjectContents.Mutants);

            executorMock.Verify(x => x.Test(It.IsAny <IList <Mutant> >(), It.IsAny <ITimeoutValueCalculator>(), It.IsAny <TestUpdateHandler>()), Times.Never);
            reporterMock.Verify(x => x.OnStartMutantTestRun(It.IsAny <IList <Mutant> >()), Times.Never);
            reporterMock.Verify(x => x.OnMutantTested(It.IsAny <Mutant>()), Times.Never);
            testResult.MutationScore.ShouldBe(double.NaN);
        }
        public static IProjectComponent CreateProjectWith(bool duplicateMutant = false, int mutationScore = 60)
        {
            var tree         = CSharpSyntaxTree.ParseText("void M(){ int i = 0 + 8; }");
            var originalNode = tree.GetRoot().DescendantNodes().OfType <BinaryExpressionSyntax>().First();

            var mutation = new Mutation()
            {
                OriginalNode    = originalNode,
                ReplacementNode = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, originalNode.Left, originalNode.Right),
                DisplayName     = "This name should display",
                Type            = Mutator.Arithmetic
            };

            var folder = new CsharpFolderComposite {
                FullPath = "/home/user/src/project/", RelativePath = ""
            };
            int mutantCount = 0;

            for (var i = 1; i <= 2; i++)
            {
                var addedFolder = new CsharpFolderComposite
                {
                    RelativePath = $"{i}",
                    FullPath     = $"/home/user/src/project/{i}",
                };
                folder.Add(addedFolder);

                for (var y = 0; y <= 4; y++)
                {
                    var m = new Collection <Mutant>();
                    addedFolder.Add(new CsharpFileLeaf()
                    {
                        RelativePath = $"{i}/SomeFile{y}.cs",
                        FullPath     = $"/home/user/src/project/{i}/SomeFile{y}.cs",
                        Mutants      = m,
                        SourceCode   = "void M(){ int i = 0 + 8; }"
                    });

                    for (var z = 0; z <= 5; z++)
                    {
                        m.Add(new Mutant()
                        {
                            Id            = duplicateMutant ? 2 : ++mutantCount,
                            ResultStatus  = 100 / 6 * z < mutationScore ? MutantStatus.Killed : MutantStatus.Survived,
                            Mutation      = mutation,
                            CoveringTests = TestsGuidList.EveryTest()
                        });
                    }
                }
            }

            return(folder);
        }
Exemple #16
0
        public void InitialisationProcess_ShouldThrowOnFailedInitialTestRun()
        {
            var testRunnerMock                = new Mock <ITestRunner>(MockBehavior.Strict);
            var inputFileResolverMock         = new Mock <IInputFileResolver>(MockBehavior.Strict);
            var initialBuildProcessMock       = new Mock <IInitialBuildProcess>(MockBehavior.Strict);
            var initialTestProcessMock        = new Mock <IInitialTestProcess>(MockBehavior.Strict);
            var assemblyReferenceResolverMock = new Mock <IAssemblyReferenceResolver>(MockBehavior.Strict);

            testRunnerMock.Setup(x => x.RunAll(It.IsAny <ITimeoutValueCalculator>(), null, null));
            var folder = new CsharpFolderComposite();

            folder.Add(new CsharpFileLeaf());

            inputFileResolverMock.Setup(x => x.ResolveInput(It.IsAny <StrykerOptions>())).Returns(
                new ProjectInfo(new MockFileSystem())
            {
                ProjectUnderTestAnalyzerResult = TestHelper.SetupProjectAnalyzerResult(
                    references: new string[0]).Object,
                TestProjectAnalyzerResults = new List <IAnalyzerResult> {
                    TestHelper.SetupProjectAnalyzerResult(
                        projectFilePath: "C://Example/Dir/ProjectFolder").Object
                },
                ProjectContents = folder
            });

            initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <string>(), null));
            testRunnerMock.Setup(x => x.DiscoverTests()).Returns(new TestSet());
            testRunnerMock.Setup(x => x.Dispose());
            initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny <StrykerOptions>(), It.IsAny <ITestRunner>())).Throws(new InputException("")); // failing test
            assemblyReferenceResolverMock.Setup(x => x.LoadProjectReferences(It.IsAny <string[]>()))
            .Returns(Enumerable.Empty <PortableExecutableReference>())
            .Verifiable();

            var target = new InitialisationProcess(
                inputFileResolverMock.Object,
                initialBuildProcessMock.Object,
                initialTestProcessMock.Object,
                testRunnerMock.Object,
                assemblyReferenceResolverMock.Object);
            var options = new StrykerOptions
            {
                ProjectName    = "TheProjectName",
                ProjectVersion = "TheProjectVersion"
            };

            target.Initialize(options);
            Assert.Throws <InputException>(() => target.InitialTest(options));

            inputFileResolverMock.Verify(x => x.ResolveInput(It.IsAny <StrykerOptions>()), Times.Once);
            assemblyReferenceResolverMock.Verify();
            initialTestProcessMock.Verify(x => x.InitialTest(It.IsAny <StrykerOptions>(), testRunnerMock.Object), Times.Once);
        }
Exemple #17
0
        public void ClearTextTreeReporter_ShouldPrintSurvivedMutation()
        {
            var tree         = CSharpSyntaxTree.ParseText("void M(){ int i = 0 + 8; }");
            var originalNode = tree.GetRoot().DescendantNodes().OfType <BinaryExpressionSyntax>().First();

            var mutation = new Mutation()
            {
                OriginalNode    = originalNode,
                ReplacementNode = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, originalNode.Left, originalNode.Right),
                DisplayName     = "This name should display",
                Type            = Mutator.Arithmetic
            };

            var textWriter = new StringWriter();
            var target     = new ClearTextTreeReporter(new StrykerOptions(), textWriter);

            var folder = new CsharpFolderComposite()
            {
                Name         = "RootFolder",
                RelativePath = "RootFolder",
                FullPath     = "C://RootFolder",
            };

            folder.Add(new CsharpFileLeaf()
            {
                Name         = "SomeFile.cs",
                RelativePath = "RootFolder/SomeFile.cs",
                FullPath     = "C://RootFolder/SomeFile.cs",
                Mutants      = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Survived, Mutation = mutation
                    }
                }
            });

            target.OnAllMutantsTested(folder.ToReadOnly());

            textWriter.RemoveAnsi().ShouldBeWithNewlineReplace($@"

All mutants have been tested, and your mutation score has been calculated
RootFolder [0/1 ({0:P2})]
└── SomeFile.cs [0/1 ({0:P2})]
    └── [Survived] This name should display on line 1
        ├── [-] 0 + 8
        └── [+] 0 -8
");

            // All percentages should be red and the [Survived] too
            textWriter.RedSpanCount().ShouldBe(3);
        }
Exemple #18
0
        /// <summary>
        /// Recursively scans the given directory for files to mutate
        /// </summary>
        private CsharpFolderComposite FindInputFiles(string path, string projectUnderTestDir, string parentFolder, CSharpParseOptions cSharpParseOptions)
        {
            var lastPathComponent = Path.GetFileName(path);

            var folderComposite = new CsharpFolderComposite
            {
                Name         = lastPathComponent,
                FullPath     = Path.GetFullPath(path),
                RelativePath = Path.Combine(parentFolder, lastPathComponent),
                RelativePathToProjectFile = Path.GetRelativePath(projectUnderTestDir, Path.GetFullPath(path))
            };

            foreach (var folder in _fileSystem.Directory.EnumerateDirectories(folderComposite.FullPath).Where(x => !_foldersToExclude.Contains(Path.GetFileName(x))))
            {
                folderComposite.Add(FindInputFiles(folder, projectUnderTestDir, folderComposite.RelativePath, cSharpParseOptions));
            }
            foreach (var file in _fileSystem.Directory.GetFiles(folderComposite.FullPath, "*.cs", SearchOption.TopDirectoryOnly).Where(f => !f.EndsWith(".xaml.cs")))
            {
                // Roslyn cannot compile xaml.cs files generated by xamarin.
                // Since the files are generated they should not be mutated anyway, so skip these files.
                var fileName = Path.GetFileName(file);

                var fileLeaf = new CsharpFileLeaf()
                {
                    SourceCode   = _fileSystem.File.ReadAllText(file),
                    Name         = _fileSystem.Path.GetFileName(file),
                    RelativePath = Path.Combine(folderComposite.RelativePath, fileName),
                    FullPath     = file,
                    RelativePathToProjectFile = Path.GetRelativePath(projectUnderTestDir, file)
                };

                // Get the syntax tree for the source file
                var syntaxTree = CSharpSyntaxTree.ParseText(fileLeaf.SourceCode, path: fileLeaf.FullPath, options: cSharpParseOptions);

                // don't mutate auto generated code
                if (syntaxTree.IsGenerated())
                {
                    _logger.LogDebug("Skipping auto-generated code file: {fileName}", fileLeaf.Name);
                    folderComposite.AddCompilationSyntaxTree(syntaxTree); // Add the syntaxTree to the list of compilationSyntaxTrees
                    continue;                                             // Don't add the file to the folderComposite as we're not reporting on the file
                }

                fileLeaf.SyntaxTree = syntaxTree;

                folderComposite.Add(fileLeaf);
            }

            return(folderComposite);
        }
Exemple #19
0
        // get the FolderComposite object representing the the project's folder 'targetFolder'. Build the needed FolderComposite(s) for a complete path
        private CsharpFolderComposite GetOrBuildFolderComposite(IDictionary <string, CsharpFolderComposite> cache, string targetFolder, string projectUnderTestDir,
                                                                string projectRoot, ProjectComponent <SyntaxTree> inputFiles)
        {
            if (cache.ContainsKey(targetFolder))
            {
                return(cache[targetFolder]);
            }

            var folder = targetFolder;
            CsharpFolderComposite subDir = null;

            while (!string.IsNullOrEmpty(folder))
            {
                if (!cache.ContainsKey(folder))
                {
                    // we have not scanned this folder yet
                    var sub          = Path.GetFileName(folder);
                    var fullPath     = _fileSystem.Path.Combine(projectUnderTestDir, sub);
                    var newComposite = new CsharpFolderComposite
                    {
                        Name         = sub,
                        FullPath     = fullPath,
                        RelativePath = Path.GetRelativePath(projectRoot, fullPath),
                        RelativePathToProjectFile = Path.GetRelativePath(projectUnderTestDir, fullPath)
                    };
                    if (subDir != null)
                    {
                        newComposite.Add(subDir);
                    }

                    cache.Add(folder, newComposite);
                    subDir = newComposite;
                    folder = Path.GetDirectoryName(folder);
                    if (string.IsNullOrEmpty(folder))
                    {
                        // we are at root
                        var root = inputFiles as IFolderComposite;
                        root.Add(subDir);
                    }
                }
                else
                {
                    cache[folder].Add(subDir);
                    break;
                }
            }

            return(cache[targetFolder]);
        }
Exemple #20
0
        public void ReportComponent_ShouldCalculateMutationScore_NoMutations()
        {
            var target = new CsharpFolderComposite();

            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                }
            });

            var result = target.GetMutationScore();

            result.ShouldBe(double.NaN);
        }
        public void ClearTextTreeReporter_ShouldPrintKilledMutation()
        {
            var tree         = CSharpSyntaxTree.ParseText("void M(){ int i = 0 + 8; }");
            var originalNode = tree.GetRoot().DescendantNodes().OfType <BinaryExpressionSyntax>().First();

            var mutation = new Mutation()
            {
                OriginalNode    = originalNode,
                ReplacementNode = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, originalNode.Left, originalNode.Right),
                DisplayName     = "This name should display",
                Type            = Mutator.Arithmetic
            };

            var console = new TestConsole().EmitAnsiSequences();
            var target  = new ClearTextTreeReporter(new StrykerOptions(), console);

            var folder = new CsharpFolderComposite()
            {
                RelativePath = "RootFolder",
                FullPath     = "C://RootFolder",
            };

            folder.Add(new CsharpFileLeaf()
            {
                RelativePath = "RootFolder/SomeFile.cs",
                FullPath     = "C://RootFolder/SomeFile.cs",
                Mutants      = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed, Mutation = mutation
                    }
                }
            });

            target.OnAllMutantsTested(folder);

            console.Output.RemoveAnsi().ShouldBeWithNewlineReplace($@"

All mutants have been tested, and your mutation score has been calculated
All files [1/1 ({1:P2})]
└── SomeFile.cs [1/1 ({1:P2})]
    └── [Killed] This name should display on line 1
        ├── [-] 0 + 8
        └── [+] 0 -8
");
            console.Output.GreenSpanCount().ShouldBe(3);
        }
        /// <summary>
        /// Recursively scans the given directory for files to mutate
        /// Deprecated method, should not be maintained
        /// </summary>
        private CsharpFolderComposite FindInputFiles(string path, string projectUnderTestDir, IAnalyzerResult analyzerResult, StrykerOptions options)
        {
            var rootFolderComposite = new CsharpFolderComposite
            {
                FullPath     = Path.GetFullPath(path),
                RelativePath = Path.GetRelativePath(projectUnderTestDir, Path.GetFullPath(path))
            };

            CSharpParseOptions cSharpParseOptions = BuildCsharpParseOptions(analyzerResult, options);

            InjectMutantHelpers(rootFolderComposite, cSharpParseOptions);

            rootFolderComposite.Add(
                FindInputFiles(path, Path.GetDirectoryName(analyzerResult.ProjectFilePath), cSharpParseOptions)
                );
            return(rootFolderComposite);
        }
        public void ShouldPrintNoMutations()
        {
            var target = new FilteredMutantsLogger(_loggerMock.Object);

            var folder = new CsharpFolderComposite();

            folder.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                }
            });

            target.OnMutantsCreated(folder.ToReadOnlyInputComponent());

            _loggerMock.Verify(LogLevel.Information, "0     total mutants will be tested", Times.Once);
            _loggerMock.VerifyNoOtherCalls();
        }
Exemple #24
0
        public void ReportComponent_ShouldCalculateMutationScore_Recursive()
        {
            var target    = new CsharpFolderComposite();
            var subFolder = new CsharpFolderComposite();

            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed
                    }
                }
            });
            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Survived
                    }
                }
            });
            target.Add(subFolder);
            subFolder.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Survived
                    }, new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed
                    }
                }
            });

            var result = target.GetMutationScore();

            result.ShouldBe(0.5);
        }
Exemple #25
0
        public void ReportComponent_ShouldCalculateMutationScore_BuildErrorIsNull()
        {
            var target = new CsharpFolderComposite();

            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.CompileError
                    }
                }
            });

            var result = target.GetMutationScore();

            result.ShouldBe(double.NaN);
        }
Exemple #26
0
        public void ReportComponent_ShouldCalculateMutationScore_OneMutation()
        {
            var target = new CsharpFolderComposite();

            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed
                    }
                }
            });

            var result = target.GetMutationScore();

            result.ShouldBe(1);
        }
Exemple #27
0
        public void ReportComponent_ShouldCalculateMutationScore_OnlyKilledIsSuccessful(MutantStatus status, double expectedScore)
        {
            var target = new CsharpFolderComposite();

            target.Add(new CsharpFileLeaf()
            {
                Mutants = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = status
                    }
                }
            });

            var result = target.GetMutationScore();

            result.ShouldBe(expectedScore);
        }
        public void ClearTextReporter_ShouldPrintGreenAboveThresholdHigh()
        {
            var tree         = CSharpSyntaxTree.ParseText("void M(){ int i = 0 + 8; }");
            var originalNode = tree.GetRoot().DescendantNodes().OfType <BinaryExpressionSyntax>().First();

            var mutation = new Mutation()
            {
                OriginalNode    = originalNode,
                ReplacementNode = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, originalNode.Left, originalNode.Right),
                DisplayName     = "This name should display",
                Type            = Mutator.Arithmetic
            };

            var textWriter = new StringWriter();
            var target     = new ClearTextReporter(new StrykerOptions(), textWriter);

            var folder = new CsharpFolderComposite()
            {
                Name         = "RootFolder",
                RelativePath = "RootFolder",
                FullPath     = "C://RootFolder",
            };

            folder.Add(new CsharpFileLeaf()
            {
                Name         = "SomeFile.cs",
                RelativePath = "RootFolder/SomeFile.cs",
                RelativePathToProjectFile = "SomeFile.cs",
                FullPath = "C://RootFolder/SomeFile.cs",
                Mutants  = new Collection <Mutant>()
                {
                    new Mutant()
                    {
                        ResultStatus = MutantStatus.Killed, Mutation = mutation
                    },
                }
            });

            target.OnAllMutantsTested(folder.ToReadOnly());

            textWriter.GreenSpanCount().ShouldBe(2);
        }
Exemple #29
0
        private CsharpFolderComposite FindProjectFilesScanningProjectFolders(IAnalyzerResult analyzerResult, IStrykerOptions options)
        {
            var inputFiles          = new CsharpFolderComposite();
            var projectUnderTestDir = Path.GetDirectoryName(analyzerResult.ProjectFilePath);

            foreach (var dir in ExtractProjectFolders(analyzerResult))
            {
                var folder = _fileSystem.Path.Combine(Path.GetDirectoryName(projectUnderTestDir), dir);

                _logger.LogDebug($"Scanning {folder}");
                if (!_fileSystem.Directory.Exists(folder))
                {
                    throw new DirectoryNotFoundException($"Can't find {folder}");
                }

                inputFiles.Add(FindInputFiles(folder, projectUnderTestDir, analyzerResult, options));
            }

            return(inputFiles);
        }
Exemple #30
0
        public void ClearTextReporter_ShouldPrintOnReportDone()
        {
            var textWriter = new StringWriter();
            var target     = new ClearTextReporter(new StrykerOptions(), textWriter);

            var rootFolder = new CsharpFolderComposite();

            var folder = new CsharpFolderComposite()
            {
                RelativePath = "FolderA",
                FullPath     = "C://Project/FolderA",
            };

            folder.Add(new CsharpFileLeaf()
            {
                RelativePath = "FolderA/SomeFile.cs",
                FullPath     = "C://Project/FolderA/SomeFile.cs",
                Mutants      = new Collection <Mutant>()
                {
                }
            });

            rootFolder.Add(folder);

            target.OnAllMutantsTested(rootFolder);

            textWriter.RemoveAnsi().ShouldBeWithNewlineReplace($@"

All mutants have been tested, and your mutation score has been calculated
┌─────────────────────┬──────────┬──────────┬───────────┬────────────┬──────────┬─────────┐
│ File                │  % score │ # killed │ # timeout │ # survived │ # no cov │ # error │
├─────────────────────┼──────────┼──────────┼───────────┼────────────┼──────────┼─────────┤
│ All files           │      N/A │        0 │         0 │          0 │        0 │       0 │
│ FolderA/SomeFile.cs │      N/A │        0 │         0 │          0 │        0 │       0 │
└─────────────────────┴──────────┴──────────┴───────────┴────────────┴──────────┴─────────┘
");
            textWriter.DarkGraySpanCount().ShouldBe(2);
        }