diff --git a/src/coverlet.core/Reporters/CoberturaReporter.cs b/src/coverlet.core/Reporters/CoberturaReporter.cs index fce899b5a..23da40c77 100644 --- a/src/coverlet.core/Reporters/CoberturaReporter.cs +++ b/src/coverlet.core/Reporters/CoberturaReporter.cs @@ -145,8 +145,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran coverage.Add(packages); xml.Add(coverage); - var stream = new MemoryStream(); - xml.Save(stream); + using var stream = new MemoryStream(); + using var streamWriter = new StreamWriter(stream, new UTF8Encoding(false)); + xml.Save(streamWriter); return Encoding.UTF8.GetString(stream.ToArray()); } diff --git a/src/coverlet.core/Reporters/OpenCoverReporter.cs b/src/coverlet.core/Reporters/OpenCoverReporter.cs index 21dfe94da..2ea068ee0 100644 --- a/src/coverlet.core/Reporters/OpenCoverReporter.cs +++ b/src/coverlet.core/Reporters/OpenCoverReporter.cs @@ -248,8 +248,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran coverage.Add(modules); xml.Add(coverage); - var stream = new MemoryStream(); - xml.Save(stream); + using var stream = new MemoryStream(); + using var streamWriter = new StreamWriter(stream, new UTF8Encoding(false)); + xml.Save(streamWriter); return Encoding.UTF8.GetString(stream.ToArray()); } diff --git a/test/coverlet.core.tests/Reporters/CoberturaReporterTests.cs b/test/coverlet.core.tests/Reporters/CoberturaReporterTests.cs index d17524e91..a4ab765a9 100644 --- a/test/coverlet.core.tests/Reporters/CoberturaReporterTests.cs +++ b/test/coverlet.core.tests/Reporters/CoberturaReporterTests.cs @@ -69,7 +69,7 @@ public void TestReport() Assert.NotEmpty(report); - var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report))); + var doc = XDocument.Load(new StringReader(report)); IEnumerable matchingRateAttributes = doc.Descendants().Attributes().Where(attr => attr.Name.LocalName.EndsWith("-rate")); IEnumerable rateParentNodeNames = matchingRateAttributes.Select(attr => attr.Parent.Name.LocalName); @@ -101,6 +101,24 @@ public void TestReport() } } + [Fact] + public void CoberturaTestReportDoesNotContainBom() + { + var result = new CoverageResult { Parameters = new CoverageParameters(), Identifier = Guid.NewGuid().ToString() }; + var documents = new Documents(); + var classes = new Classes { { "Class", new Methods() } }; + + documents.Add(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\doc.cs" : @"/doc.cs", classes); + + result.Modules = new Modules { { "Module", documents } }; + + var reporter = new CoberturaReporter(); + string report = reporter.Report(result, new Mock().Object); + + byte[] preamble = Encoding.UTF8.GetBytes(report)[..3]; + Assert.NotEqual(Encoding.UTF8.GetPreamble(), preamble); + } + [Theory] [InlineData( "Test.SearchRequest::pb::Google.Protobuf.IMessage.get_Descriptor()", @@ -151,7 +169,8 @@ public void TestEnsureParseMethodStringCorrectly( Assert.NotEmpty(report); - var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report))); + var doc = XDocument.Load(new StringReader(report)); + var methodAttrs = doc.Descendants() .Where(o => o.Name.LocalName == "method") .Attributes() @@ -220,7 +239,7 @@ public void TestReportWithDifferentDirectories() var reporter = new CoberturaReporter(); string report = reporter.Report(result, new Mock().Object); - var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report))); + var doc = XDocument.Load(new StringReader(report)); var basePaths = doc.Element("coverage").Element("sources").Elements().Select(e => e.Value).ToList(); var relativePaths = doc.Element("coverage").Element("packages").Element("package") @@ -262,7 +281,8 @@ public void TestReportWithSourcelinkPaths() var reporter = new CoberturaReporter(); string report = reporter.Report(result, new Mock().Object); - var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report))); + var doc = XDocument.Load(new StringReader(report)); + string fileName = doc.Element("coverage").Element("packages").Element("package").Element("classes").Elements() .Select(e => e.Attribute("filename").Value).Single(); diff --git a/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs b/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs index c5b530d7e..224000666 100644 --- a/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs +++ b/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs @@ -27,7 +27,7 @@ public void TestReport() var reporter = new OpenCoverReporter(); string report = reporter.Report(result, new Mock().Object); Assert.NotEmpty(report); - var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report))); + var doc = XDocument.Load(new StringReader(report)); Assert.Empty(doc.Descendants().Attributes("sequenceCoverage").Where(v => v.Value != "33.33")); Assert.Empty(doc.Descendants().Attributes("branchCoverage").Where(v => v.Value != "25")); Assert.Empty(doc.Descendants().Attributes("nPathComplexity").Where(v => v.Value != "4")); @@ -77,6 +77,22 @@ public void TestLineBranchCoverage() Assert.Contains(@"", xml); } + [Fact] + public void OpenCoverTestReportDoesNotContainBom() + { + var result = new CoverageResult + { + Identifier = Guid.NewGuid().ToString(), + Modules = new Modules { { "Coverlet.Core.Reporters.Tests", CreateBranchCoverageDocuments() } }, + Parameters = new CoverageParameters() + }; + + string report = new OpenCoverReporter().Report(result, new Mock().Object); + + byte[] preamble = Encoding.UTF8.GetBytes(report)[..3]; + Assert.NotEqual(Encoding.UTF8.GetPreamble(), preamble); + } + private static Documents CreateFirstDocuments() { var lines = new Lines();