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)); } }
/// <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); }
private static IEnumerable <Mutant> MutateAndCompileSource(string sourceFile) { var filesystemRoot = Path.GetPathRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); var inputFile = new CsharpFileLeaf() { SourceCode = sourceFile, SyntaxTree = CSharpSyntaxTree.ParseText(sourceFile) }; var folder = new CsharpFolderComposite(); folder.Add(inputFile); foreach (var(name, code) in CodeInjection.MutantHelpers) { folder.AddCompilationSyntaxTree(CSharpSyntaxTree.ParseText(code, path: name, encoding: Encoding.UTF32)); } var fileSystem = new MockFileSystem(new Dictionary <string, MockFileData> { { Path.Combine(filesystemRoot, "ExampleProject", "Calculator.cs"), new MockFileData(sourceFile) }, { Path.Combine(filesystemRoot, "ExampleProject.Test", "bin", "Debug", "netcoreapp2.0", "ExampleProject.dll"), new MockFileData("Bytecode") }, { Path.Combine(filesystemRoot, "ExampleProject.Test", "obj", "Release", "netcoreapp2.0", "ExampleProject.dll"), new MockFileData("Bytecode") } }); var input = new MutationTestInput { ProjectInfo = new ProjectInfo(fileSystem) { ProjectUnderTestAnalyzerResult = TestHelper.SetupProjectAnalyzerResult( properties: new Dictionary <string, string>() { { "TargetDir", "Project" }, { "AssemblyName", "AssemblyName" }, { "TargetFileName", "TargetFileName.dll" }, }).Object, TestProjectAnalyzerResults = new List <IAnalyzerResult> { TestHelper.SetupProjectAnalyzerResult(properties: new Dictionary <string, string>() { { "AssemblyName", "TargetFileName" }, { "TargetDir", "Test" }, { "TargetFileName", "TestTargetFileName.dll" }, }).Object }, ProjectContents = folder }, AssemblyReferences = new List <PortableExecutableReference> { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }, TestRunner = new Mock <ITestRunner>(MockBehavior.Default).Object }; var options = new StrykerOptions { MutationLevel = MutationLevel.Complete, OptimizationMode = OptimizationModes.CoverageBasedTest, }; var process = new CsharpMutationProcess(input, fileSystem, options); process.Mutate(); var projectContentsMutants = input.ProjectInfo.ProjectContents.Mutants; return(projectContentsMutants); }