private async Task <Mutant> CreateSurvivingMutantFromExpression( string originalExpression, string mutatedExpression) { var originalDocument = SourceToDocument( $@"namespace DummyNamespace {{ public static class DummyClass {{ public static bool IsPositive(int a) {{ return {originalExpression}; }} }} }}"); var originalSyntaxRoot = await originalDocument.GetSyntaxRootAsync(); var originalNode = originalSyntaxRoot.DescendantNodes().OfType <BinaryExpressionSyntax>().First(); var mutatedNode = SyntaxFactory.ParseExpression(mutatedExpression); var mutatedRoot = originalSyntaxRoot.ReplaceNode(originalNode, mutatedNode); return(await Mutant.Create(originalDocument, originalNode, mutatedRoot)); }
public async Task <(MutantStatus, Mutant)> Run(ITestRunner testRunner, string tempDirectory, IEventListener eventListener) { var mutatedNode = mutator.Mutate(OriginalNode); MutatedSyntaxRoot = originalSyntaxRoot.ReplaceNode(OriginalNode, mutatedNode); var mutant = await Mutant.Create(OriginalClass, OriginalNode, MutatedSyntaxRoot); var compilationResult = await CompileContainingProject(tempDirectory); if (!compilationResult.Success) { // Not all mutations are valid in all circumstances, and therefore may not compile. // E.g. "a + b" => "a - b" works when a and b are integers but not when they're strings. eventListener.MutantSkipped(mutant, "mutation resulted in invalid code"); return(MutantStatus.Skipped, mutant); } CopyMutatedAssemblyIntoTempTestAssemblyDirectories(compilationResult.OutputFilePath, tempDirectory, config); var copiedTempTestAssemblyFilePaths = TempTestAssemblyFilePaths(config, tempDirectory).ToArray(); var ranAnyTests = false; for (var testAssemblyIndex = 0; testAssemblyIndex < config.TestAssemblyFilePaths.Length; ++testAssemblyIndex) { var originalTestAssemblyFilePath = config.TestAssemblyFilePaths[testAssemblyIndex]; var tempTestAssemblyFilePath = copiedTempTestAssemblyFilePaths[testAssemblyIndex]; string[] testsToRun = null; if (coverageAnalysisResult != null) { testsToRun = coverageAnalysisResult.TestsThatCoverMember(memberName, originalTestAssemblyFilePath); if (!testsToRun.Any()) { continue; } } var result = testsToRun != null? testRunner.RunTests(new[] { tempTestAssemblyFilePath }, testsToRun) : testRunner.RunAllTests(new[] { tempTestAssemblyFilePath }); ranAnyTests = true; if (result.Status == TestRunStatus.SomeTestsFailed) { eventListener.MutantKilled(mutant, result.Error); return(MutantStatus.Dead, mutant); } } if (!ranAnyTests) { eventListener.MutantSkipped(mutant, "no covering tests"); return(MutantStatus.Skipped, mutant); } eventListener.MutantSurvived(mutant); return(MutantStatus.Alive, mutant); }