public void OnAllMutantsTested(IReadOnlyInputComponent reportComponent) { var jsonReport = JsonReportComponent.FromProjectComponent(reportComponent, _options); jsonReport.ThresholdHigh = _options.ThresholdOptions.ThresholdHigh; jsonReport.ThresholdLow = _options.ThresholdOptions.ThresholdLow; jsonReport.ThresholdBreak = _options.ThresholdOptions.ThresholdBreak; WriteReportToJsonFile(jsonReport, Path.Combine(_options.BasePath, "StrykerOutput", "reports", "mutation-report.json")); }
private static string SerializeJsonReport(JsonReportComponent jsonReport) { return(JsonConvert.SerializeObject(jsonReport, new JsonSerializerSettings { ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }, Formatting = Formatting.Indented })); }
public void OnAllMutantsTested(IReadOnlyInputComponent reportComponent) { var jsonReport = JsonReportComponent.FromProjectComponent(reportComponent, _options.ThresholdOptions); jsonReport.Name = _options.ProjectUnderTestNameFilter; using (var file = File.CreateText(_options.BasePath + "/StrykerLogs/mutation-report.json")) { file.WriteLine(SerializeJsonReport(jsonReport)); } }
private void WriteReportToJsonFile(JsonReportComponent jsonReport, string filePath) { var json = JsonConvert.SerializeObject(jsonReport, new JsonSerializerSettings { ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }, Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore }); filePath = GenerateUniqueReportFilePath(filePath); using (var file = _fileSystem.File.CreateText(filePath)) { file.WriteLine(json); } }
private void ValidateJsonReportComponent(JsonReportComponent jsonComponent, IReadOnlyInputComponent inputComponent, string health, int mutants = 0) { jsonComponent.Name.ShouldBe(inputComponent.Name); jsonComponent.Health.ShouldBe(health); jsonComponent.PossibleMutants.ShouldBe(inputComponent.ReadOnlyMutants.Where(m => m.ResultStatus != MutantStatus.BuildError).Count()); jsonComponent.MutationScore.ShouldBe(inputComponent.GetMutationScore()); jsonComponent.CompileErrors.ShouldBe(inputComponent.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.BuildError).Count()); jsonComponent.SurvivedMutants.ShouldBe(inputComponent.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Survived).Count()); jsonComponent.SkippedMutants.ShouldBe(inputComponent.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Skipped).Count()); jsonComponent.TimeoutMutants.ShouldBe(inputComponent.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Timeout).Count()); jsonComponent.KilledMutants.ShouldBe(inputComponent.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Killed).Count()); jsonComponent.TotalMutants.ShouldBe(inputComponent.TotalMutants.Count()); jsonComponent.ThresholdHigh.ShouldBe(80); jsonComponent.ThresholdLow.ShouldBe(60); jsonComponent.ThresholdBreak.ShouldBe(0); if (inputComponent is FolderComposite folderComponent) { jsonComponent.Source.ShouldBe(null); jsonComponent.Mutants.ShouldBeEmpty(); jsonComponent.ChildResults.Count.ShouldBe(folderComponent.Children.Count()); } if (inputComponent is FileLeaf fileComponent) { jsonComponent.Source.ShouldBe(fileComponent.SourceCode); jsonComponent.Mutants.Count.ShouldBe(mutants); for (int i = 0; i < mutants; i++) { jsonComponent.Mutants[i].Id.ShouldBe(fileComponent.Mutants.ToArray()[i].Id); jsonComponent.Mutants[i].MutatorName.ShouldBe(fileComponent.Mutants.ToArray()[i].Mutation.DisplayName); jsonComponent.Mutants[i].Replacement.ShouldBe(fileComponent.Mutants.ToArray()[i].Mutation.ReplacementNode.ToString()); jsonComponent.Mutants[i].Span.ShouldBe( new[] { fileComponent.Mutants.ToArray()[i].Mutation.OriginalNode.SpanStart, fileComponent.Mutants.ToArray()[i].Mutation.OriginalNode.Span.End }); jsonComponent.Mutants[i].Status.ShouldBe(fileComponent.Mutants.ToArray()[i].ResultStatus.ToString()); } } }
public void JsonReportComponent_ShouldGenerateFileTreeForJsonSerialization() { 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 = MutatorType.Arithmetic }; var folder = new FolderComposite() { Name = "RootFolder" }; folder.Add(new FileLeaf() { Name = "SomeFile.cs", Mutants = new Collection <Mutant>() { new Mutant() { Id = 55, ResultStatus = MutantStatus.Killed, Mutation = mutation } }, SourceCode = "void M(){ int i = 0 + 8; }" }); folder.Add(new FileLeaf() { Name = "SomeOtherFile.cs", Mutants = new Collection <Mutant>() { new Mutant() { Id = 56, ResultStatus = MutantStatus.Survived, Mutation = mutation } }, SourceCode = "void M(){ int i = 0 + 8; }" }); folder.Add(new FileLeaf() { Name = "SomeOtherFile.cs", Mutants = new Collection <Mutant>() { new Mutant() { Id = 56, ResultStatus = MutantStatus.Skipped, Mutation = mutation } }, SourceCode = "void M(){ int i = 0 + 8; }" }); var result = JsonReportComponent.FromProjectComponent(folder, new ThresholdOptions(80, 60, 0)); ValidateJsonReportComponent(result, folder, "warning"); ValidateJsonReportComponent(result.ChildResults.ElementAt(0), folder.Children.ElementAt(0), "ok", 1); ValidateJsonReportComponent(result.ChildResults.ElementAt(1), folder.Children.ElementAt(1), "danger", 1); }
public static JsonReportComponent FromProjectComponent(IReadOnlyInputComponent component, StrykerOptions options) { int Where(MutantStatus MutantStatus) => component.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus).Count(); var report = new JsonReportComponent { DetectedMutations = component.DetectedMutants.Count(), TotalMutants = component.TotalMutants.Count(), KilledMutants = Where(MutantStatus.Killed), SurvivedMutants = Where(MutantStatus.Survived), SkippedMutants = Where(MutantStatus.Skipped), TimeoutMutants = Where(MutantStatus.Timeout), CompileErrors = Where(MutantStatus.CompileError), MutationScore = component.GetMutationScore() ?? 0, }; report.ValidMutations = report.TotalMutants + report.SkippedMutants; if (report.MutationScore >= options.ThresholdOptions.ThresholdHigh) { report.Health = "Good"; } else if (report.MutationScore <= options.ThresholdOptions.ThresholdBreak) { report.Health = "Danger"; } else { report.Health = "Warning"; } if (component is FolderComposite folderComponent) { report.Name = component.Name is null ? options.ProjectUnderTestNameFilter : folderComponent.RelativePath; report.ChildResults = new List <JsonReportComponent>(); foreach (var child in folderComponent.Children) { report.ChildResults.Add(FromProjectComponent(child, options)); } } else if (component is FileLeaf fileComponent) { report.Name = fileComponent.Name; report.Source = fileComponent.SourceCode; report.Language = "cs"; report.Mutants = new List <JsonMutant>(); foreach (var mutant in fileComponent.Mutants) { var jsonMutant = new JsonMutant { Id = mutant.Id, MutatorName = mutant.Mutation.DisplayName, Replacement = mutant.Mutation.ReplacementNode.ToFullString(), Location = new JsonMutant.JsonMutantLocation(mutant.Mutation.OriginalNode.SyntaxTree.GetLineSpan(mutant.Mutation.OriginalNode.FullSpan)), Status = mutant.ResultStatus.ToString() }; report.Mutants.Add(jsonMutant); } } else { throw new System.Exception("Unknown IReadOnlyInputComponent implementation"); } return(report); }
public static JsonReportComponent FromProjectComponent(IReadOnlyInputComponent component, ThresholdOptions thresholdOptions) { var report = new JsonReportComponent { Name = component.Name, DetectedMutants = component.DetectedMutants.Count(), TotalMutants = component.TotalMutants.Count(), KilledMutants = component.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Killed).Count(), SurvivedMutants = component.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Survived).Count(), SkippedMutants = component.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Skipped).Count(), TimeoutMutants = component.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.Timeout).Count(), CompileErrors = component.ReadOnlyMutants.Where(m => m.ResultStatus == MutantStatus.BuildError).Count(), MutationScore = component.GetMutationScore(), ThresholdHigh = thresholdOptions.ThresholdHigh, ThresholdLow = thresholdOptions.ThresholdLow, ThresholdBreak = thresholdOptions.ThresholdBreak, }; report.PossibleMutants = report.TotalMutants + report.SkippedMutants; if (report.MutationScore >= report.ThresholdHigh) { report.Health = "ok"; } else if (report.MutationScore <= report.ThresholdBreak) { report.Health = "danger"; } else { report.Health = "warning"; } if (component is FolderComposite folderComponent) { foreach (var child in folderComponent.Children) { report.ChildResults.Add(FromProjectComponent(child, thresholdOptions)); } } else if (component is FileLeaf fileComponent) { report.Source = fileComponent.SourceCode; foreach (var mutant in fileComponent.Mutants) { var jsonMutant = new JsonMutant { Id = mutant.Id, MutatorName = mutant.Mutation.DisplayName, Replacement = mutant.Mutation.ReplacementNode.ToFullString(), Span = new[] { mutant.Mutation.OriginalNode.SpanStart, mutant.Mutation.OriginalNode.Span.End }, Status = StrykerStatusToMutationStatus(mutant.ResultStatus) }; report.Mutants.Add(jsonMutant); } } else { throw new System.Exception("Unknown IReadOnlyInputComponent implementation"); } return(report); }