diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index bd262ad73..490aff5fb 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -27,7 +27,7 @@ ] }, "dotnet-fsharplint": { - "version": "0.20.1", + "version": "0.20.2", "commands": [ "dotnet-fsharplint" ] diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0656b06e3..2fd9f0cdc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,7 +19,7 @@ jobs: fetch-depth: 2 - uses: actions/setup-dotnet@v1 with: - dotnet-version: '5.0.402' + dotnet-version: '6.0.100' - name: Tools run: dotnet tool restore - name: Setup @@ -36,14 +36,18 @@ jobs: if: failure() with: name: reports.windows - path: _Reports + path: | + _Reports + _Packaging/*.xml + ./**/AltCover*.log + ./**/dotnettest.*.txt linux: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 with: - dotnet-version: '5.0.402' + dotnet-version: '6.0.100' - name: Tools run: dotnet tool restore - name: Setup @@ -56,5 +60,6 @@ jobs: name: reports.linux path: | _Reports + _Packaging/*.xml ./**/AltCover*.log ./**/dotnettest.*.txt \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7d9b620aa..6ea996039 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,5 @@ coverage.xml **/Backup/ LastCoverageResults.log CoverageReport-* +Samples/Sample29/Debug/ +Samples/Sample29/SimpleMix/Debug/ diff --git a/AltCover.Api.Tests/AltCover.Api.Tests.fsproj b/AltCover.Api.Tests/AltCover.Api.Tests.fsproj index e94cfef9c..b1561e51e 100644 --- a/AltCover.Api.Tests/AltCover.Api.Tests.fsproj +++ b/AltCover.Api.Tests/AltCover.Api.Tests.fsproj @@ -1,7 +1,7 @@  - net5.0;net472 + net6.0;net472 false AltCover.Api.Tests false @@ -26,7 +26,16 @@ + + + + + + + + + MSDataSetGenerator @@ -36,6 +45,8 @@ + + @@ -59,9 +70,9 @@ all runtime; build; native; contentfiles; analyzers - + - + @@ -80,7 +91,8 @@ - + + contentfiles diff --git a/AltCover.Api.Tests/FSApiTests.fs b/AltCover.Api.Tests/FSApiTests.fs index 704e6ffce..177b616c6 100644 --- a/AltCover.Api.Tests/FSApiTests.fs +++ b/AltCover.Api.Tests/FSApiTests.fs @@ -161,7 +161,7 @@ module FSApiTests = let doc = XDocument.Load(stream) use stream2 = new MemoryStream() CoverageFormats.ConvertToLcov doc stream2 - use stream2a = new MemoryStream(stream2.GetBuffer()) + use stream2a = new MemoryStream(stream2.GetBuffer(), 0, int stream2.Length) use rdr = new StreamReader(stream2a) let result = @@ -176,10 +176,39 @@ module FSApiTests = let expected = rdr2.ReadToEnd().Replace("\r", String.Empty) - // printfn "%s" result + //printfn "%s" result //Assert.That(result, Is.EqualTo expected) test <@ result = expected @> + [] + let OpenCoverWithPartialsToLcov () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.OpenCoverWithPartials.xml") + + let doc = XDocument.Load(stream) + use stream2 = new MemoryStream() + CoverageFormats.ConvertToLcov doc stream2 + use stream2a = new MemoryStream(stream2.GetBuffer(), 0, int stream2.Length) + use rdr = new StreamReader(stream2a) + + let result = + rdr.ReadToEnd().Replace("\r", String.Empty) + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.OpenCoverWithPartials.lcov") + + use rdr2 = new StreamReader(stream3) + + let expected = + rdr2.ReadToEnd().Replace("\r", String.Empty) + //printfn "%s" result + Assert.That(result, Is.EqualTo expected) + test <@ result = expected @> + [] let JsonToOpenCover () = use stream = @@ -202,19 +231,120 @@ module FSApiTests = let expected = rdr2.ReadToEnd() //printfn "%s" result - Assert.That( - result + //Assert.That( + // result + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Replace("8.12", "8.13") // CRAP score rounding + // .Replace("4.12", "4.13") // CRAP score rounding + // .Trim([| '\u00FF' |]), + // Is.EqualTo + // <| expected + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Trim([| '\u00FF' |]) + //) + + test + <@ result + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Replace("8.12", "8.13") // CRAP score rounding + .Replace("4.12", "4.13") // CRAP score rounding + .Trim([| '\u00FF' |]) = expected + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) @> + + [] + let JsonWithPartialsToOpenCover () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.JsonWithPartials.json") + + let doc = + use reader = new StreamReader(stream) + reader.ReadToEnd() + + let result = (OpenCover.JsonToXml doc).ToString() + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.JsonWithPartialsToXml.xml") + + use rdr2 = new StreamReader(stream3) + let expected = rdr2.ReadToEnd() + + //printfn "%s" result + + //Assert.That( + // result + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Trim([| '\u00FF' |]), + // Is.EqualTo + // <| expected + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Trim([| '\u00FF' |]) + //) + + test + <@ result .Replace('\r', '\u00FF') .Replace('\n', '\u00FF') .Replace("\u00FF\u00FF", "\u00FF") - .Trim([| '\u00FF' |]), - Is.EqualTo - <| expected + .Trim([| '\u00FF' |]) = expected .Replace('\r', '\u00FF') .Replace('\n', '\u00FF') .Replace("\u00FF\u00FF", "\u00FF") - .Trim([| '\u00FF' |]) - ) + .Trim([| '\u00FF' |]) @> + + [] + let JsonFromCoverletShouldHaveBranchExitValuesOK() = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.Sample4.coverlet.json") + + let doc = + use reader = new StreamReader(stream) + reader.ReadToEnd() + + let result = "\u00FF" + + (OpenCover.JsonToXml doc).ToString() + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.Sample4.fromcoverletjson.xml") + + use rdr2 = new StreamReader(stream3) + let expected = rdr2.ReadToEnd() + + //printfn "%s" result + + //Assert.That( + // result + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Trim([| '\u00FF' |]), + // Is.EqualTo + // <| expected + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Trim([| '\u00FF' |]) + //) test <@ result @@ -263,6 +393,44 @@ module FSApiTests = .Replace("\u00FF\u00FF", "\u00FF") .Trim([| '\u00FF' |]) @> + [] + let OpenCoverWithPartialsToJson () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.OpenCoverWithPartials.xml") + + let doc = XDocument.Load(stream) + + let result = CoverageFormats.ConvertToJson doc + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.JsonWithPartials.json") + + use rdr2 = new StreamReader(stream3) + let expected = rdr2.ReadToEnd() + + //printfn "%s" result + //Assert.That(result + // .Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |]), + // Is.EqualTo <| expected.Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |]), + // result) + + test + <@ result + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) = expected + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) @> + [] let NCoverToJson () = use stream = @@ -306,6 +474,127 @@ module FSApiTests = .Replace("\u00FF\u00FF", "\u00FF") .Trim([| '\u00FF' |]) @> + [] + let NCoverWithPartialsToJson () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.NCoverWithPartials.xml") + + let doc = XDocument.Load(stream) + // fix up file path + let exe = + Path.Combine(SolutionRoot.location, "AltCover.Tests/SimpleMix.exe") + + doc.Root.Descendants(XName.Get "module") + |> Seq.iter (fun e -> e.Attribute(XName.Get "name").Value <- exe) + + let result = CoverageFormats.ConvertToJson doc + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.JsonFromNCoverWithPartials.json") + + use rdr2 = new StreamReader(stream3) + let expected = rdr2.ReadToEnd() + + //printfn "%s" result + //Assert.That(result + // .Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |]), + // Is.EqualTo <| expected.Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |])) + + test + <@ result + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) = expected + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) @> + + [] + let NCoverToJsonWithEmbeds () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.HandRolledToNCover.xml") + + let doc = XDocument.Load(stream) + + let result = CoverageFormats.ConvertToJson doc + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.HandRolledToNCover.json") + + use rdr2 = new StreamReader(stream3) + let expected = rdr2.ReadToEnd() + + //printfn "%s" result + //Assert.That(result + // .Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |]), + // Is.EqualTo <| expected.Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |])) + + test + <@ result + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) = expected + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) @> + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.GenuineNCover158.Xml") + + let doc = XDocument.Load(stream) + // fix up file path + let exe = + Path.Combine(SolutionRoot.location, "Samples/Sample19", "ConsoleApplication1.exe") + + doc.Root.Descendants(XName.Get "module") + |> Seq.iter (fun e -> e.Attribute(XName.Get "name").Value <- exe) + + let result = CoverageFormats.ConvertToJson doc + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.GenuineNCover158.json") + + use rdr2 = new StreamReader(stream3) + let expected = rdr2.ReadToEnd() + + //printfn "%s" result + //Assert.That(result + // .Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |]), + // Is.EqualTo <| expected.Replace('\r','\u00FF').Replace('\n','\u00FF') + // .Replace("\u00FF\u00FF","\u00FF").Trim([| '\u00FF' |])) + + test + <@ result + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) = expected + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) @> + [] let OpenCoverToBarChart () = use stream = @@ -325,6 +614,7 @@ module FSApiTests = let result = rdr.ReadToEnd().Replace("\r", String.Empty) + .Replace("ID0ES", "ID0ET") // flakiness in label autogenerator use stream2 = Assembly @@ -386,6 +676,56 @@ module FSApiTests = NUnit.Framework.Assert.That(result, NUnit.Framework.Is.EqualTo expected) + [] + let OpenCoverWithPartialsToNCover () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.OpenCoverWithPartials.xml") + + let doc = XDocument.Load stream + // fix up file path + let exe = + Path.Combine(SolutionRoot.location, "AltCover.Tests/SimpleMix.exe") + doc.Descendants("ModulePath".X) + |> Seq.iter (fun x -> x.Value <- exe |> Canonical.canonicalPath) + + use mstream = new MemoryStream() + let rewrite = CoverageFormats.ConvertToNCover doc + rewrite.Save mstream + + use mstream2 = + new MemoryStream(mstream.GetBuffer(), 0, mstream.Position |> int) + + use rdr = new StreamReader(mstream2) + + let result = + rdr.ReadToEnd().Replace("\r", String.Empty) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.NCoverWithPartials.xml") + + use rdr2 = new StreamReader(stream2) + + let time = + (rewrite.Descendants(XName.Get "coverage") + |> Seq.head) + .Attribute( + XName.Get "startTime" + ) + .Value + + let expected = + rdr2 + .ReadToEnd() + .Replace("{0}", time) + .Replace("utf-16", "utf-8") + .Replace("\r", String.Empty) + + NUnit.Framework.Assert.That(result, NUnit.Framework.Is.EqualTo expected) + [] let OpenCoverFromNCover () = let sample = typeof.Assembly.Location @@ -408,6 +748,61 @@ module FSApiTests = test <@ rewrite |> isNull |> not @> + [] + let OpenCoverFromNCoverWithPartials () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.NCoverWithPartials.xml") + + let exe = + Path.Combine(SolutionRoot.location, "AltCover.Tests/SimpleMix.exe") + + let document = + XDocument.Load stream + let now = DateTime.UtcNow.ToLongDateString() + + let rewrite = + CoverageFormats.ConvertFromNCover document [ exe ] + rewrite.Descendants("ModuleTime".X) + |> Seq.iter (fun x -> x.Value <- now) + + use mstream = new MemoryStream() + rewrite.Save mstream + + use mstream2 = + new MemoryStream(mstream.GetBuffer(), 0, mstream.Position |> int) + + use rdr = new StreamReader(mstream2) + + let result = + rdr.ReadToEnd().Replace("\r", String.Empty) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.OpenCoverFromNCoverWithPartials.xml") + + use rdr2 = new StreamReader(stream2) + let doc2 = XDocument.Load rdr2 + doc2.Descendants("ModulePath".X) + |> Seq.iter (fun x -> x.Value <- exe |> Canonical.canonicalPath) + doc2.Descendants("ModuleTime".X) + |> Seq.iter (fun x -> x.Value <- now) + + // OpenCover.PostProcess doc2 BranchOrdinal.Offset + use stream3 = new MemoryStream() + doc2.Save(stream3) + stream3.Position <- 0L + use rdr3 = new StreamReader(stream3) + + let expected = + rdr3 + .ReadToEnd() + .Replace("\r", String.Empty) + //printfn "%A" result + NUnit.Framework.Assert.That(result, NUnit.Framework.Is.EqualTo expected) + [] let FormatsConvertToXmlDocument () = use stream = @@ -508,12 +903,12 @@ module FSApiTests = let cob = CoverageFormats.ConvertToCobertura doc use stream2 = new MemoryStream() cob.Save stream2 - use stream2a = new MemoryStream(stream2.GetBuffer()) + use stream2a = new MemoryStream(stream2.GetBuffer(), 0, int stream2.Length) use rdr = new StreamReader(stream2a) let result = rdr.ReadToEnd().Replace("\r", String.Empty) - // printfn "FSApi.NCoverToCobertura\r\n%s" result + //printfn "FSApi.NCoverToCobertura\r\n%s" result use stream3 = Assembly @@ -541,6 +936,60 @@ module FSApiTests = //NUnit.Framework.Assert.That(result, NUnit.Framework.Is.EqualTo expected) test <@ result = expected @> + [] + let NCoverWithPartialsToCobertura () = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.NCoverWithPartials.xml") + + let doc = XDocument.Load(stream) + + doc.Descendants() + |> Seq.map (fun n -> n.Attribute(XName.Get "excluded")) + |> Seq.filter (isNull >> not) + |> Seq.iter (fun a -> a.Value <- "false") + + let cob = CoverageFormats.ConvertToCobertura doc + use stream2 = new MemoryStream() + cob.Save stream2 + use stream2a = new MemoryStream(stream2.GetBuffer(), 0, int stream2.Length) + use rdr = new StreamReader(stream2a) + + let result = + rdr.ReadToEnd() + .Replace("\r", String.Empty) + .Replace("\\", "/") + + //printfn "FSApi.NCoverToCobertura\r\n%s" result + + use stream3 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Api.Tests.NCoverWithPartials.cob.xml") + + use rdr2 = new StreamReader(stream3) + + let coverage = + cob.Descendants(XName.Get "coverage") |> Seq.head + + let v = + coverage.Attribute(XName.Get "version").Value + + let t = + coverage.Attribute(XName.Get "timestamp").Value + + let expected = + rdr2 + .ReadToEnd() + .Replace("version=\"8.2.0.0\"", "version=\"" + v + "\"") + .Replace("timestamp=\"xx\"", "timestamp=\"" + t + "\"") + .Replace("\r", String.Empty) + + //printfn "%A" result + //NUnit.Framework.Assert.That(result, NUnit.Framework.Is.EqualTo expected) + test <@ result = expected @> + [] let NCoverToBarChart () = use stream = @@ -873,7 +1322,7 @@ module FSApiTests = let summary = merge.Root.Element(XName.Get "Summary") - // printfn "%A" merge + //printfn "%A" merge test <@ summary.ToString() = "" @> @@ -900,7 +1349,7 @@ module FSApiTests = let merge = AltCover.OpenCover.Merge [ doc1; doc2; doc1; doc2 ] let summary = merge.Root.Element(XName.Get "Summary") - // printfn "%A" merge + //printfn "%A" merge test <@ summary diff --git a/AltCover.Api.Tests/OpenCover.xml b/AltCover.Api.Tests/OpenCover.xml index 575e5502c..fe58a8b56 100644 --- a/AltCover.Api.Tests/OpenCover.xml +++ b/AltCover.Api.Tests/OpenCover.xml @@ -1,19 +1,20 @@ - + - + Sample4.dll Sample4 - + + Tests.Program - - + + 0 System.Int32 Tests.Program::main(System.String[]) @@ -21,15 +22,16 @@ - + + Tests.DU - - + + 0 Tests.DU/MyUnion Tests.DU::returnFoo(System.Int32) @@ -37,10 +39,10 @@ - + - - + + 0 Tests.DU/MyUnion Tests.DU::returnBar(System.String) @@ -48,10 +50,10 @@ - + - - + + 0 System.Void Tests.DU::testMakeUnion() @@ -69,10 +71,10 @@ - + - - + + 0 Tests.DU/MyUnion Tests.DU/MyUnion::as_bar() @@ -93,10 +95,10 @@ - + - - + + 0 Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Tests.DU/MyUnion> Tests.DU/MyUnion::get_MyBar() @@ -104,10 +106,10 @@ - + - - + + 0 Tests.DU/MyUnion Tests.DU/get_MyBar@44::Invoke(Microsoft.FSharp.Core.Unit) @@ -115,10 +117,10 @@ - + - - + + 0 System.Void Tests.DU/MyClass::.ctor() @@ -127,15 +129,16 @@ - + + Tests.M - - + + 0 Tests.M/Thing Tests.M::makeThing(System.String) @@ -143,10 +146,10 @@ - + - - + + 0 System.Void Tests.M::testMakeThing() @@ -160,10 +163,10 @@ - + - - + + 0 System.Byte[] Tests.M/Thing::bytes() @@ -171,7 +174,7 @@ - + diff --git a/AltCover.Api.Tests/Program.fs b/AltCover.Api.Tests/Program.fs index bb670b0dc..d29c4a97c 100644 --- a/AltCover.Api.Tests/Program.fs +++ b/AltCover.Api.Tests/Program.fs @@ -13,17 +13,26 @@ module ExpectoMain = Tests.FSApiTests.PostprocessShouldRestoreBranchOnlyOpenCoverState, "FSApiTests.PostprocessShouldRestoreBranchOnlyOpenCoverState" Tests.FSApiTests.JsonToOpenCover, "FSApiTests.JsonToOpenCover" + Tests.FSApiTests.JsonWithPartialsToOpenCover, "FSApiTests.JsonWithPartialsToOpenCover" + Tests.FSApiTests.JsonFromCoverletShouldHaveBranchExitValuesOK, "FSApiTests.JsonFromCoverletShouldHaveBranchExitValuesOK" Tests.FSApiTests.OpenCoverToJson, "FSApiTests.OpenCoverToJson" + Tests.FSApiTests.OpenCoverWithPartialsToJson, "FSApiTests.OpenCoverWithPartialsToJson" Tests.FSApiTests.OpenCoverToLcov, "FSApiTests.OpenCoverToLcov" + Tests.FSApiTests.OpenCoverWithPartialsToLcov, "FSApiTests.OpenCoverWithPartialsToLcov" Tests.FSApiTests.OpenCoverToBarChart, "FSApiTests.OpenCoverToBarChart" Tests.FSApiTests.OpenCoverToNCover, "FSApiTests.OpenCoverToNCover" + Tests.FSApiTests.OpenCoverWithPartialsToNCover, "FSApiTests.OpenCoverWithPartialsToNCover" Tests.FSApiTests.OpenCoverFromNCover, "FSApiTests.OpenCoverFromNCover" + Tests.FSApiTests.OpenCoverFromNCoverWithPartials, "FSApiTests.OpenCoverFromNCoverWithPartials" Tests.FSApiTests.FormatsConvertToXmlDocument, "FSApiTests.FormatsConvertToXmlDocument" Tests.FSApiTests.FormatsConvertToXDocument, "FSApiTests.FormatsConvertToXDocument" Tests.FSApiTests.FormatsRoundTripSimply, "FSApiTests.FormatsRoundTripSimply" Tests.FSApiTests.NCoverToCobertura, "FSApiTests.NCoverToCobertura" + Tests.FSApiTests.NCoverWithPartialsToCobertura, "FSApiTests.NCoverWithPartialsToCobertura" Tests.FSApiTests.NCoverToJson, "FSApiTests.NCoverToJson" + Tests.FSApiTests.NCoverWithPartialsToJson, "FSApiTests.NCoverWithPartialsToJson" + Tests.FSApiTests.NCoverToJsonWithEmbeds, "FSApiTests.NCoverToJsonWithEmbeds" Tests.FSApiTests.NCoverToBarChart, "FSApiTests.NCoverToBarChart" Tests.FSApiTests.OpenCoverBranchCompression, "FSApiTests.OpenCoverBranchCompression" Tests.FSApiTests.ArgumentsBuilt, "FSApiTests.ArgumentsBuilt" diff --git a/AltCover.Avalonia.FuncUI/AltCover.Avalonia.FuncUI.fsproj b/AltCover.Avalonia.FuncUI/AltCover.Avalonia.FuncUI.fsproj index 36f564a2b..c1eeeb210 100644 --- a/AltCover.Avalonia.FuncUI/AltCover.Avalonia.FuncUI.fsproj +++ b/AltCover.Avalonia.FuncUI/AltCover.Avalonia.FuncUI.fsproj @@ -2,15 +2,13 @@ Exe - net5.0 + net6.0 AltCover.Visualizer AltCover.Visualizer false True altcover.visualizer true - true - true AVALONIA $(ProjectDir)..\_Binaries/$(AssemblyName).FuncUI/$(Configuration)+$(Platform)/ $(ProjectDir)..\_Intermediate/$(AssemblyName).FuncUI/$(Configuration)+$(Platform)/ @@ -19,6 +17,15 @@ false + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) true @@ -44,12 +51,12 @@ - + all runtime; build; native; contentfiles; analyzers - + @@ -64,7 +71,8 @@ - + + contentfiles diff --git a/AltCover.Avalonia/AltCover.Avalonia.fsproj b/AltCover.Avalonia/AltCover.Avalonia.fsproj index e328ffa1e..41da1f31c 100644 --- a/AltCover.Avalonia/AltCover.Avalonia.fsproj +++ b/AltCover.Avalonia/AltCover.Avalonia.fsproj @@ -9,8 +9,6 @@ True altcover.visualizer true - true - true AVALONIA $(ProjectDir)..\_Binaries/$(AssemblyName).Avalonia/$(Configuration)+$(Platform)/ $(ProjectDir)..\_Intermediate/$(AssemblyName).Avalonia/$(Configuration)+$(Platform)/ @@ -21,6 +19,15 @@ false + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) true @@ -56,9 +63,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers @@ -72,7 +79,8 @@ - + + contentfiles diff --git a/AltCover.Avalonia/MainWindow.fs b/AltCover.Avalonia/MainWindow.fs index 58e3cc71f..1542db99b 100644 --- a/AltCover.Avalonia/MainWindow.fs +++ b/AltCover.Avalonia/MainWindow.fs @@ -194,9 +194,9 @@ type MainWindow() as this = (root: XPathNavigator) (stack: StackPanel) (lines: FormattedTextLine list) - (filename: string) + (file: Source) = - let branches = HandlerCommon.TagBranches root filename + let branches = HandlerCommon.TagBranches root file let h = (lines |> Seq.head).Height let pad = (h - 16.0) / 2.0 @@ -225,10 +225,10 @@ type MainWindow() as this = (textBox: TextPresenter) (text2: TextPresenter) (lines: FormattedTextLine list) - filename + info = let tags = - HandlerCommon.TagCoverage root filename lines.Length + HandlerCommon.TagCoverage root info lines.Length let formats = tags |> List.map (tagByCoverage textBox lines) @@ -267,7 +267,7 @@ type MainWindow() as this = let showSource (info: Source) (line: int) = try this.UpdateTextFonts text text2 - text.Text <- (File.ReadAllText info.FullName).Replace('\t', '\u2192') + text.Text <- info.ReadAllText().Replace('\t', '\u2192') let textLines = text.FormattedText.GetLines() |> Seq.toList @@ -287,11 +287,11 @@ type MainWindow() as this = root.MoveToRoot() let (formats, linemark) = - markCoverage root text text2 textLines info.FullName + markCoverage root text text2 textLines info let stack = this.FindControl("Branches") root.MoveToRoot() - markBranches root stack textLines info.FullName + markBranches root stack textLines info async { Threading.Thread.Sleep(300) diff --git a/AltCover.Cake/AltCover.Cake.csproj b/AltCover.Cake/AltCover.Cake.csproj index 8f3c581d4..f19907017 100644 --- a/AltCover.Cake/AltCover.Cake.csproj +++ b/AltCover.Cake/AltCover.Cake.csproj @@ -7,8 +7,6 @@ AltCover.Cake AltCover.Cake true - true - true $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ $(SolutionDir)_Intermediate/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -17,6 +15,15 @@ true + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS true @@ -39,9 +46,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers @@ -55,4 +62,7 @@ + + + \ No newline at end of file diff --git a/AltCover.DataCollector/AltCover.DataCollector.csproj b/AltCover.DataCollector/AltCover.DataCollector.csproj index 1fbc9ca5a..17777ff52 100644 --- a/AltCover.DataCollector/AltCover.DataCollector.csproj +++ b/AltCover.DataCollector/AltCover.DataCollector.csproj @@ -7,8 +7,6 @@ AltCover.DataCollector false true - true - true $(ProjectDir)../ true $(SolutionDir)\Build\Infrastructure.snk @@ -19,6 +17,15 @@ true + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS @@ -41,7 +48,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -79,5 +86,7 @@ Resources.Designer.cs - + + + \ No newline at end of file diff --git a/AltCover.DotNet/AltCover.DotNet.fsproj b/AltCover.DotNet/AltCover.DotNet.fsproj index ae039324d..4620d3c94 100644 --- a/AltCover.DotNet/AltCover.DotNet.fsproj +++ b/AltCover.DotNet/AltCover.DotNet.fsproj @@ -7,8 +7,6 @@ AltCover.DotNet false true - true - true RUNNER $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -17,6 +15,15 @@ --keyfile:$(ProjectDir)..\Build\Infrastructure.snk + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) 4 @@ -38,7 +45,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -57,6 +64,7 @@ + contentfiles diff --git a/AltCover.Engine/AltCover.Engine.fsproj b/AltCover.Engine/AltCover.Engine.fsproj index 1135cdb58..9dc5e3c57 100644 --- a/AltCover.Engine/AltCover.Engine.fsproj +++ b/AltCover.Engine/AltCover.Engine.fsproj @@ -8,8 +8,6 @@ false RUNNER true - true - true $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ $(SolutionDir)_Intermediate/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -21,6 +19,8 @@ + false + false TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) 4 true @@ -29,6 +29,7 @@ true + true true TRACE;$(GlobalDefineConstants) @@ -38,6 +39,7 @@ + @@ -45,6 +47,7 @@ + @@ -82,14 +85,17 @@ Recorder.snk + + AltCover.Recorder.net20.dll + - AltCover.Recorder.dll + AltCover.Recorder.net46.dll - + all runtime; build; native; contentfiles; analyzers @@ -121,15 +127,13 @@ - - $(SolutionDir)_Binaries\AltCover.Recorder\$(Configuration)+$(Platform)\net20\AltCover.Recorder.dll - ..\ThirdParty\BlackFox.CommandLine.dll + contentfiles diff --git a/AltCover.Engine/Augment.fs b/AltCover.Engine/Augment.fs index 936c54424..6a90428e5 100644 --- a/AltCover.Engine/Augment.fs +++ b/AltCover.Engine/Augment.fs @@ -24,16 +24,18 @@ module internal Augment = with get() = self |> isNull |> not -#if !(GUI || ValidateGendarmeEmulation) +#if !ValidateGendarmeEmulation type System.String with member self.X with get() = System.Xml.Linq.XName.Get self +#if !GUI member self.InvariantParseDouble() = System.Double.TryParse(self, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture) +#endif #endif type internal Either<'a, 'b> = Choice<'b, 'a> @@ -63,17 +65,18 @@ module internal Augment = action stream #endif -#if !GUI type System.Boolean with member self.ToInt32 with get() = if self then 1 else 0 + #if !ValidateGendarmeEmulation type System.Int32 with member self.Increment (b : bool) = self + b.ToInt32 #endif +#if !GUI type Microsoft.FSharp.Collections.List<'T> with member self.Split with get () = @@ -111,6 +114,16 @@ module internal Augment = [] +[] +[] +[] #if GUI [ Seq.iter (fun s -> s.Add(XElement("source".X, XText(f))))) let internal nCover (report: XDocument) (packages: XElement) = - let processSeqPnts (method: XElement) (lines: XElement) = + let processSeqPnts document (method: XElement) (lines: XElement) = method.Descendants("seqpnt".X) - |> Seq.filter (fun s -> s.Attribute("excluded".X).Value <> "true") + |> Seq.filter (fun s -> s.Attribute("excluded".X).Value <> "true" + && s.Attribute("document".X).Value = document) |> Seq.fold (fun (h, t) s -> let vc = s.Attribute("visitcount".X) @@ -70,7 +71,7 @@ module internal Cobertura = (h + (if vx = "0" then 0 else 1), t + 1)) (0, 0) - let processMethod (methods: XElement) (hits, total) (key, (signature, method)) = + let processMethod document (methods: XElement) (hits, total) (key, (signature, method)) = let mtx = XElement( "method".X, @@ -81,13 +82,13 @@ module internal Cobertura = methods.Add(mtx) let lines = XElement("lines".X) mtx.Add(lines) - let (mHits, mTotal) = processSeqPnts method lines + let (mHits, mTotal) = processSeqPnts document method lines setRate mHits mTotal "line-rate" mtx setRate 1 1 "branch-rate" mtx setRate 1 1 "complexity" mtx (hits + mHits, total + mTotal) - let sortMethod (n: String) (methods: XElement) (method: XElement seq) = + let sortMethod (document: String) (methods: XElement) (method: XElement seq) = method |> Seq.map (fun m -> @@ -116,20 +117,20 @@ module internal Cobertura = (key, (signature, m))) |> LCov.sortByFirst - |> Seq.fold (processMethod methods) (0, 0) + |> Seq.fold (processMethod document methods) (0, 0) - let processClass (classes: XElement) (hits, total) ((name, signature), method) = + let processClass (classes: XElement) (hits, total) ((name, document), method) = let ``class`` = XElement( "class".X, XAttribute("name".X, name), - XAttribute("filename".X, signature) + XAttribute("filename".X, document) ) classes.Add(``class``) let methods = XElement("methods".X) ``class``.Add(methods) - let (mHits, mTotal) = sortMethod name methods method + let (mHits, mTotal) = sortMethod document methods method setRate mHits mTotal "line-rate" ``class`` setRate 1 1 "branch-rate" ``class`` setRate 1 1 "complexity" ``class`` @@ -137,14 +138,19 @@ module internal Cobertura = let extractClasses (``module``: XElement) classes = ``module``.Descendants("method".X) - |> Seq.filter (fun m -> m.Attribute("excluded".X).Value <> "true") - |> Seq.groupBy - (fun method -> - (method.Attribute("class".X).Value, - method.Descendants("seqpnt".X) - |> Seq.map (fun s -> s.Attribute("document".X).Value) - |> Seq.head)) - |> LCov.sortByFirst + |> Seq.filter (fun m -> m.Attribute("excluded".X).Value <> "true" + && m.Descendants("seqpnt".X) |> Seq.isEmpty |> not) + + |> Seq.collect (fun method -> + let cname = method.Attribute("class".X).Value + method.Descendants("seqpnt".X) + |> Seq.map (fun s -> s.Attribute("document".X).Value) + |> Seq.distinct + |> Seq.sort + |> Seq.map (fun d -> (cname, d), method)) + |> Seq.groupBy fst + |> Seq.map (fun (k,s) -> k, s |> Seq.map (fun (k,m) -> m)) + |> Seq.sortBy (fun ((c,d), _) -> c + "\u0000" + d) // short classes sort first |> Seq.fold (processClass classes) (0, 0) let processModule (hits, total) (``module``: XElement) = @@ -184,8 +190,10 @@ module internal Cobertura = |> Int32.TryParse |> snd - let b = valueOf "numBranchPoints" - let bv = valueOf "visitedBranchPoints" + let branches = owner.Descendants("BranchPoint".X) + let b = branches |> Seq.length + let bv = branches |> Seq.filter (fun x -> x.Attribute("vc".X).Value <> "0") + |> Seq.length let s = valueOf "numSequencePoints" let sv = valueOf "visitedSequencePoints" @@ -283,6 +291,7 @@ module internal Cobertura = |> snd) let processMethod + fileid (methods: XElement) (b, bv, s, sv, c, cv) (key, (signature, method)) @@ -298,6 +307,7 @@ module internal Cobertura = mtx.Add(XAttribute("complexity".X, ccplex)) method.Descendants("SequencePoint".X) + |> Seq.filter (fun s -> s.Attribute("fileid".X).Value = fileid) |> Seq.groupBy (fun b -> b.Attribute("sl".X).Value |> Int32.TryParse |> snd) |> Seq.sortBy fst |> Seq.iter (copySeqPnt lines) @@ -315,7 +325,7 @@ module internal Cobertura = c + 1, cv + ccplex) - let arrangeMethods (name: String) (methods: XElement) (methodSet: XElement seq) = + let arrangeMethods (name: String) fileid (methods: XElement) (methodSet: XElement seq) = methodSet |> Seq.map (fun method -> @@ -340,20 +350,21 @@ module internal Cobertura = mt.Descendants("SequencePoint".X) |> Seq.isEmpty |> not) - |> Seq.fold (processMethod methods) (0, 0, 0, 0, 0, 0) + |> Seq.fold (processMethod fileid methods) (0, 0, 0, 0, 0, 0) - let processClass (classes: XElement) (cvcum, ccum) ((name, source), methodSet) = + let processClass files (classes: XElement) (cvcum, ccum) ((name, fileid), methodSet) = + let document = files |> Map.find fileid let ``class`` = XElement( "class".X, XAttribute("name".X, name), - XAttribute("filename".X, source) + XAttribute("filename".X, document) ) classes.Add(``class``) let methods = XElement("methods".X) ``class``.Add(methods) - let (b, bv, s, sv, c, cv) = arrangeMethods name methods methodSet + let (b, bv, s, sv, c, cv) = arrangeMethods name fileid methods methodSet setRate sv s "line-rate" ``class`` setRate bv b "branch-rate" ``class`` setRate cv c "complexity" ``class`` @@ -361,17 +372,25 @@ module internal Cobertura = let processModule files classes (``module``: XElement) = ``module``.Descendants("Method".X) - |> Seq.filter (fun m -> m.Descendants("FileRef".X) |> Seq.isEmpty |> not) - |> Seq.groupBy - (fun method -> - ((method.Parent.Parent.Descendants("FullName".X) - |> Seq.head) - .Value, - method.Descendants("FileRef".X) - |> Seq.map (fun s -> files |> Map.find (s.Attribute("uid".X).Value)) - |> Seq.head)) - |> LCov.sortByFirst - |> Seq.fold (processClass classes) (0, 0) + |> Seq.filter (fun m -> m.Descendants("SequencePoint".X) |> Seq.isEmpty |> not || + m.Descendants("BranchPoint".X) |> Seq.isEmpty |> not) + |> Seq.collect (fun method -> + let cname = (method.Parent.Parent.Descendants("FullName".X) + |> Seq.head) + .Value + [ + method.Descendants("SequencePoint".X) + method.Descendants("BranchPoint".X) + ] + |> Seq.concat + |> Seq.map (fun s -> s.Attribute("fileid".X).Value) + |> Seq.distinct + |> Seq.sort + |> Seq.map (fun d -> (cname, d), method)) + |> Seq.groupBy fst + |> Seq.map (fun (k,s) -> k, s |> Seq.map (fun (k,m) -> m)) + |> Seq.sortBy (fun ((c,d), _) -> c + "\u0000" + (files |> Map.find d)) // short classes sort first + |> Seq.fold (processClass files classes) (0, 0) let lookUpFiles (``module``: XElement) = ``module``.Descendants("File".X) diff --git a/AltCover.Engine/CommandLine.fs b/AltCover.Engine/CommandLine.fs index cf7143df6..cd0440795 100644 --- a/AltCover.Engine/CommandLine.fs +++ b/AltCover.Engine/CommandLine.fs @@ -316,7 +316,7 @@ module internal CommandLine = let internal transformCryptographicException f = try f () - with :? CryptographicException as c -> (c.Message, c) |> SecurityException |> raise + with :? CryptographicException as c -> raise ((c.Message, c) |> SecurityException) [ Seq.last)) :: error else - flag := true)) + flag.Value <- true)) [] +module Compatibility = + [] + let internal sha1Hash () : SHA1 = + new SHA1CryptoServiceProvider() :> SHA1 + + [] + let internal createHttp (path:Uri) = + WebRequest.CreateHttp(path) :> WebRequest \ No newline at end of file diff --git a/AltCover.Engine/Instrument.fs b/AltCover.Engine/Instrument.fs index d3248101d..072b40f39 100644 --- a/AltCover.Engine/Instrument.fs +++ b/AltCover.Engine/Instrument.fs @@ -111,6 +111,7 @@ type internal InstrumentContext = { InstrumentedAssemblies: string list ModuleId: String RecordingAssembly: AssemblyDefinition + RecorderSource : Stream RecordingMethod: MethodDefinition list // initialised once RecordingMethodRef: RecorderRefs // updated each module MethodBody: MethodBody @@ -120,6 +121,7 @@ type internal InstrumentContext = { InstrumentedAssemblies = assemblies ModuleId = String.Empty RecordingAssembly = null + RecorderSource = null RecordingMethod = [] RecordingMethodRef = RecorderRefs.Build() MethodBody = null @@ -128,10 +130,14 @@ type internal InstrumentContext = // Module to handle instrumentation visitor module internal Instrument = - let version = - typeof - .Assembly.GetName() - .Version.ToString() + let recorderVersion() = + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.AltCover.Recorder.net20.dll") + use def = AssemblyDefinition.ReadAssembly stream + def.Name.Version.ToString() + let version = recorderVersion() let internal resolutionTable = Dictionary() @@ -288,9 +294,9 @@ module internal Instrument = [] - let internal prepareAssembly (location: string) = + let internal prepareAssembly (assembly: Stream) = let definition = - AssemblyDefinition.ReadAssembly(location) + AssemblyDefinition.ReadAssembly(assembly) prepareAssemblyDefinition definition @@ -303,6 +309,11 @@ module internal Instrument = "packages" ) + [] + [] let internal resolveFromNugetCache _ (y: AssemblyNameReference) = let name = y.ToString() @@ -979,13 +990,16 @@ module internal Instrument = "EnsureLocalDisposalRule", Justification = "Record return confusing Gendarme -- TODO")>] let private visitStart state = - let recorder = typeof - + let stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.AltCover.Recorder.net20.dll") let recordingAssembly = - prepareAssembly (recorder.Assembly.Location) + prepareAssembly (stream) { state with - RecordingAssembly = recordingAssembly } + RecordingAssembly = recordingAssembly + RecorderSource = stream } [ File.ReadAllText |> injectJSON)))) finally (state.RecordingAssembly :> IDisposable).Dispose() - + state.RecorderSource + |> Option.ofObj + |> Option.iter (fun a -> a.Close()) state.AsyncSupport |> Option.iter (fun a -> a.Close()) { state with RecordingAssembly = null + RecorderSource = null AsyncSupport = None } // Perform visitor operations @@ -1079,11 +1096,13 @@ module internal Instrument = match node with | Finish -> () | _ -> - if state.RecordingAssembly |> isNull |> not then + if state.RecordingAssembly.IsNotNull then (state.RecordingAssembly :> IDisposable).Dispose() - - state.AsyncSupport - |> Option.iter (fun a -> a.Close()) + state.RecorderSource + |> Option.ofObj + |> Option.iter (fun a -> a.Close()) + state.AsyncSupport + |> Option.iter (fun a -> a.Close()) reraise () diff --git a/AltCover.Engine/Json.fs b/AltCover.Engine/Json.fs index 588b33b79..508ccb7d7 100644 --- a/AltCover.Engine/Json.fs +++ b/AltCover.Engine/Json.fs @@ -23,16 +23,17 @@ module internal Json = Justification = "AvoidSpeculativeGenerality too")>] let internal getMethodRecords (modul: NativeJson.Documents) - (doc: string) + (doc: string * string) (cname: string) (mname: string) = let classes = - match modul.TryGetValue doc with + match modul.TryGetValue (fst doc) with | true, c -> c | _ -> let c = NativeJson.Classes() - modul.Add(doc, c) + modul.Add(fst doc, c) + NativeJson.injectEmbed c (snd doc) c let methods = @@ -55,7 +56,7 @@ module internal Json = Justification = "AvoidSpeculativeGenerality too")>] let internal getMethodRecord (modul: NativeJson.Documents) - (doc: string) + (doc: string * string) (cname: string) (mname: string) = @@ -69,7 +70,7 @@ module internal Json = Justification = "Long enough but no longer")>] let internal updateMethodRecord (modul: NativeJson.Documents) - (doc: string) + (doc: string * string) (cname: string) (mname: string) (update: (Nullable * NativeJson.Times * NativeJson.Times)) @@ -170,6 +171,8 @@ module internal Json = let counts = System.Collections.Generic.Dictionary() + let embeds = + System.Collections.Generic.Dictionary() let def = maybeAssembly path @@ -190,65 +193,85 @@ module internal Json = m.Attribute(XName.Get "excluded").Value |> Boolean.TryParse - let mutable docname = String.Empty + let jmethods = System.Collections.Generic.Dictionary() if not excluded then - let sp = NativeJson.SeqPnts() + let basename = sprintf "%s::%s" cname mname + let _, count = counts.TryGetValue basename + let index = count + 1 + counts.[basename] <- index + + let synth = + sprintf "ReturnType%d %s(Argument List%d)" index basename index + + let spoints = m.Descendants(XName.Get "seqpnt") + + let makeSeqPnt (x:XElement) = + let parse n = + x.Attribute(XName.Get n) + |> Option.ofObj + |> Option.map (fun a -> a.Value |> Int32.TryParse |> snd) + |> Option.defaultValue 0 + + { NativeJson.SeqPnt.VC = parse "visitcount" + NativeJson.SeqPnt.SL = parse "line" + NativeJson.SeqPnt.SC = parse "column" + NativeJson.SeqPnt.EL = parse "endline" + NativeJson.SeqPnt.EC = parse "endcolumn" + NativeJson.SeqPnt.Offset = parse "offset" + NativeJson.SeqPnt.Id = 0 + NativeJson.SeqPnt.Times = null + NativeJson.SeqPnt.Tracks = null } + + let sp = spoints + |> Seq.tryHead + |> Option.map makeSeqPnt - m.Descendants(XName.Get "seqpnt") + let (className, methodName) = + maybeNames + def + synth + outerclass + sp + cname + mname + + spoints |> Seq.iter (fun s -> let _, excluded = s.Attribute(XName.Get "excluded").Value |> Boolean.TryParse - let parse n = - s.Attribute(XName.Get n) - |> Option.ofObj - |> Option.map (fun a -> a.Value |> Int32.TryParse |> snd) - |> Option.defaultValue 0 - if not excluded then - if String.IsNullOrWhiteSpace docname then - docname <- s.Attribute(XName.Get "document").Value - - { NativeJson.SeqPnt.VC = parse "visitcount" - NativeJson.SeqPnt.SL = parse "line" - NativeJson.SeqPnt.SC = parse "column" - NativeJson.SeqPnt.EL = parse "endline" - NativeJson.SeqPnt.EC = parse "endcolumn" - NativeJson.SeqPnt.Offset = 0 - NativeJson.SeqPnt.Id = 0 - NativeJson.SeqPnt.Times = null - NativeJson.SeqPnt.Tracks = null } - |> sp.Add) - - if sp.Count > 0 then - let basename = sprintf "%s::%s" cname mname - let _, count = counts.TryGetValue basename - let index = count + 1 - counts.[basename] <- index - - let synth = - sprintf "ReturnType%d %s(Argument List%d)" index basename index - - let (className, methodName) = - maybeNames - def - synth - outerclass - (sp |> Seq.head |> Some) - cname - mname - - let m = - getMethodRecord modul docname className methodName - - m.SeqPnts.AddRange sp - - m.SeqPnts - |> Seq.groupBy (fun s -> s.SL) - |> Seq.iter (fun (l, ss) -> m.Lines.[l] <- lineVisits ss)) + let doc = s.Attribute(XName.Get "document").Value + let embed = + let (ok, result) = embeds.TryGetValue(doc) + if ok then result + else + let found = s.Ancestors("module".X) + |> Seq.collect (fun m -> m.Descendants("altcover.file".X)) + |> Seq.filter (fun f -> f.Attribute(XName.Get "document").Value = doc) + |> Seq.tryHead + |> Option.map (fun f -> f.Attribute(XName.Get "embed").Value) + |> Option.filter (String.IsNullOrWhiteSpace >> not) + |> Option.defaultValue String.Empty + embeds.Add(doc, found) + found + + let docname = (doc, embed) + let jmethod = + getMethodRecord modul docname className methodName + jmethods.[doc] <- jmethod + + s + |> makeSeqPnt + |> jmethod.SeqPnts.Add) + + jmethods.Values + |> Seq.iter (fun jm -> jm.SeqPnts + |> Seq.groupBy (fun s -> s.SL) + |> Seq.iter (fun (l, ss) -> jm.Lines.[l] <- lineVisits ss))) finally maybeDispose def @@ -273,14 +296,22 @@ module internal Json = let modul = NativeJson.Documents() let files = - System.Collections.Generic.Dictionary() + System.Collections.Generic.Dictionary() x.Descendants(XName.Get "File") |> Seq.iter (fun x -> + let document = x.Attribute(XName.Get "fullPath").Value + + let embed = x.Attribute(XName.Get "altcover.embed") + |> Option.ofObj + |> Option.map (fun e -> e.Value) + |> Option.defaultValue String.Empty + files.Add( x.Attribute(XName.Get "uid").Value, - x.Attribute(XName.Get "fullPath").Value + (document, embed) + )) let tracked = @@ -326,14 +357,7 @@ module internal Json = .Value.Replace('+', '/') let outerclass = cname.Split('/') |> Seq.head - - let mutable docname = String.Empty - - let updateDocname (s: XElement) = - if String.IsNullOrWhiteSpace docname then - docname <- files.[s.Attribute(XName.Get "fileid").Value] - - let sp = NativeJson.SeqPnts() + let jmethods = System.Collections.Generic.Dictionary() m.Descendants(XName.Get "SequencePoint") |> Seq.iter @@ -344,55 +368,72 @@ module internal Json = |> Option.map (fun a -> a.Value |> Int32.TryParse |> snd) |> Option.defaultValue 0 - updateDocname s - - { NativeJson.SeqPnt.VC = parse "vc" - NativeJson.SeqPnt.SL = parse "sl" - NativeJson.SeqPnt.SC = parse "sc" - NativeJson.SeqPnt.EL = parse "el" - NativeJson.SeqPnt.EC = parse "ec" - NativeJson.SeqPnt.Offset = parse "offset" - NativeJson.SeqPnt.Id = parse "uspid" - NativeJson.SeqPnt.Times = - let t = s.Descendants(XName.Get "Time") - - if t |> isNull || t |> Seq.isEmpty then - null - else - let t2 = NativeJson.Times() - - t - |> Seq.map - (fun x -> - x.Attribute(XName.Get "time").Value - |> Int64.TryParse - |> snd - |> NativeJson.fromTracking) - |> t2.AddRange - - t2 - - NativeJson.SeqPnt.Tracks = - let t = - s.Descendants(XName.Get "TrackedMethodRef") - - if t |> isNull || t |> Seq.isEmpty then - null - else - let t2 = NativeJson.Tracks() - - t - |> Seq.map - (fun x -> - x.Attribute(XName.Get "uid").Value - |> Int32.TryParse - |> snd) - |> t2.AddRange - - t2 - - } - |> sp.Add) + let docname = files.[s.Attribute(XName.Get "fileid").Value] + let sp = + { NativeJson.SeqPnt.VC = parse "vc" + NativeJson.SeqPnt.SL = parse "sl" + NativeJson.SeqPnt.SC = parse "sc" + NativeJson.SeqPnt.EL = parse "el" + NativeJson.SeqPnt.EC = parse "ec" + NativeJson.SeqPnt.Offset = parse "offset" + NativeJson.SeqPnt.Id = parse "uspid" + NativeJson.SeqPnt.Times = + let t = s.Descendants(XName.Get "Time") + + if t |> isNull || t |> Seq.isEmpty then + null + else + let t2 = NativeJson.Times() + + t + |> Seq.map + (fun x -> + x.Attribute(XName.Get "time").Value + |> Int64.TryParse + |> snd + |> NativeJson.fromTracking) + |> t2.AddRange + + t2 + + NativeJson.SeqPnt.Tracks = + let t = + s.Descendants(XName.Get "TrackedMethodRef") + + if t |> isNull || t |> Seq.isEmpty then + null + else + let t2 = NativeJson.Tracks() + + t + |> Seq.map + (fun x -> + x.Attribute(XName.Get "uid").Value + |> Int32.TryParse + |> snd) + |> t2.AddRange + + t2 + + } + let (className, methodName) = + maybeNames def mname outerclass None cname mname + + let (tid, entry, exit) = + if tracked.ContainsKey mname then + let (tid0, entry, exit) = tracked.[mname] + (Nullable(tid0), entry, exit) + else + (System.Nullable(), null, null) + + updateMethodRecord modul docname className mname (tid, entry, exit) + |> ignore + + let jmethod = + getMethodRecord modul docname className methodName + jmethods.[fst docname] <- jmethod + jmethod.SeqPnts.Add sp + ) let bp = NativeJson.Branches() @@ -405,86 +446,82 @@ module internal Json = |> Option.map (fun a -> a.Value |> Int32.TryParse |> snd) |> Option.defaultValue 0 - updateDocname s + let docname = files.[s.Attribute(XName.Get "fileid").Value] let offset = parse "offset" - { NativeJson.BranchInfo.Hits = parse "vc" - NativeJson.BranchInfo.Line = parse "sl" - NativeJson.BranchInfo.EndOffset = parse "offsetend" - NativeJson.BranchInfo.Path = - bp - |> Seq.filter (fun k -> k.Offset = offset) - |> Seq.length - NativeJson.BranchInfo.Ordinal = uint bp.Count - NativeJson.BranchInfo.Offset = offset - NativeJson.BranchInfo.Id = parse "uspid" - NativeJson.BranchInfo.Times = - let t = s.Descendants(XName.Get "Time") - - if t |> isNull || t |> Seq.isEmpty then - null - else - let t2 = NativeJson.Times() - - t - |> Seq.map - (fun x -> - x.Attribute(XName.Get "time").Value - |> Int64.TryParse - |> snd - |> NativeJson.fromTracking) - |> t2.AddRange - - t2 - - NativeJson.BranchInfo.Tracks = - let t = - s.Descendants(XName.Get "TrackedMethodRef") - - if t |> isNull || t |> Seq.isEmpty then - null - else - let t2 = NativeJson.Tracks() - - t - |> Seq.map - (fun x -> - x.Attribute(XName.Get "uid").Value - |> Int32.TryParse - |> snd) - |> t2.AddRange - - t2 - - } - |> bp.Add) - - if sp.Count > 0 || bp.Count > 0 then - let (className, methodName) = - maybeNames def mname outerclass None cname mname - - let (tid, entry, exit) = - if tracked.ContainsKey mname then - let (tid0, entry, exit) = tracked.[mname] - (Nullable(tid0), entry, exit) - else - (System.Nullable(), null, null) - - updateMethodRecord modul docname className mname (tid, entry, exit) - |> ignore - - let m = - getMethodRecord modul docname className methodName - - if sp.Count > 0 then - m.SeqPnts.AddRange sp - - m.SeqPnts - |> Seq.groupBy (fun s -> s.SL) - |> Seq.iter (fun (l, ss) -> m.Lines.[l] <- lineVisits ss) - - if bp.Count > 0 then - m.Branches.AddRange bp) + let jbp = + { NativeJson.BranchInfo.Hits = parse "vc" + NativeJson.BranchInfo.Line = parse "sl" + NativeJson.BranchInfo.EndOffset = parse "offsetend" + NativeJson.BranchInfo.Path = + bp + |> Seq.filter (fun k -> k.Offset = offset) + |> Seq.length + NativeJson.BranchInfo.Ordinal = uint bp.Count + NativeJson.BranchInfo.Offset = offset + NativeJson.BranchInfo.Id = parse "uspid" + NativeJson.BranchInfo.Times = + let t = s.Descendants(XName.Get "Time") + + if t |> isNull || t |> Seq.isEmpty then + null + else + let t2 = NativeJson.Times() + + t + |> Seq.map + (fun x -> + x.Attribute(XName.Get "time").Value + |> Int64.TryParse + |> snd + |> NativeJson.fromTracking) + |> t2.AddRange + + t2 + + NativeJson.BranchInfo.Tracks = + let t = + s.Descendants(XName.Get "TrackedMethodRef") + + if t |> isNull || t |> Seq.isEmpty then + null + else + let t2 = NativeJson.Tracks() + + t + |> Seq.map + (fun x -> + x.Attribute(XName.Get "uid").Value + |> Int32.TryParse + |> snd) + |> t2.AddRange + + t2 + + } + let (className, methodName) = + maybeNames def mname outerclass None cname mname + + let (tid, entry, exit) = + if tracked.ContainsKey mname then + let (tid0, entry, exit) = tracked.[mname] + (Nullable(tid0), entry, exit) + else + (System.Nullable(), null, null) + + updateMethodRecord modul docname className mname (tid, entry, exit) + |> ignore + + let jmethod = + getMethodRecord modul docname className methodName + jmethods.[fst docname] <- jmethod + jmethod.Branches.Add jbp + bp.Add jbp // for counting paths + ) + jmethods.Values + |> Seq.iter (fun jm -> jm.SeqPnts + |> Seq.groupBy (fun s -> s.SL) + |> Seq.iter (fun (l, ss) -> jm.Lines.[l] <- lineVisits ss))) finally maybeDispose def diff --git a/AltCover.Engine/LCov.fs b/AltCover.Engine/LCov.fs index e8f4b2882..f8d4126e0 100644 --- a/AltCover.Engine/LCov.fs +++ b/AltCover.Engine/LCov.fs @@ -1,6 +1,7 @@ namespace AltCover open System +open System.Diagnostics.CodeAnalysis open System.Globalization open System.IO open System.Xml.Linq @@ -17,24 +18,46 @@ module internal LCov = module internal I = - [] - let internal lineOfMethod (m: XElement) = - (m.Descendants("seqpnt".X) |> Seq.head).Attribute( - "line".X - ) - .Value - |> Int32.TryParse - |> snd + [] + [] + [] + let internal lineOfPartialMethod (m: XElement * XElement seq) = + let (_, s) = m + s + |> Seq.map (fun x -> x.Attribute("line".X).Value + |> Int32.TryParse + |> snd) + |> Seq.min let internal multiSort (by: 'a -> int) (l: (string * 'a seq) seq) = l |> Seq.map (fun (f, ms) -> (f, ms |> Seq.sortBy by |> Seq.toList)) |> sortByFirst - let internal multiSortByNameAndStartLine (l: (string * XElement seq) seq) = - multiSort lineOfMethod l + let internal multiSortByNameAndPartialStartLine (l: (string * (XElement * XElement seq) seq) seq) = + multiSort lineOfPartialMethod l + + [] + [] + [] + let internal computeVisitCount (lines : XElement seq) (attr : string) = + let vx = lines + |> Seq.map (fun l -> let v = l.Attribute(attr.X) + if v |> isNull then 0 + else v.Value |> Int32.TryParse |> snd) + if vx |> Seq.exists(fun v -> v > 0) + then vx |> Seq.max + else vx |> Seq.min // from a real sample e.g. https://pastebin.com/588FggQg (* @@ -63,30 +86,32 @@ FN:4,(anonymous_0) let internal convertReport (report: XDocument) (format: ReportFormat) (stream: Stream) = doWithStream - (fun () -> new StreamWriter(stream)) + (fun () -> new StreamWriter(stream, Text.Encoding.UTF8, 4096, true)) (fun writer -> match format with | ReportFormat.NCover -> - report.Descendants("method".X) + report.Descendants("module".X) + |> Seq.iter (fun assembly -> + assembly.Descendants("method".X) |> Seq.filter (fun m -> m.Attribute("excluded".X).Value <> "true" && m.Descendants("seqpnt".X) |> Seq.exists (fun s -> s.Attribute("excluded".X).Value <> "true")) - |> Seq.groupBy - (fun m -> - (m.Descendants("seqpnt".X) |> Seq.head).Attribute( - "document".X - ) - .Value) - |> I.multiSortByNameAndStartLine + |> Seq.collect( fun m -> m.Descendants("seqpnt".X) + |> Seq.groupBy (fun s -> s.Attribute("document".X) + .Value) + |> Seq.map (fun (d, l) -> (d, (m, l)))) + |> Seq.groupBy fst + |> Seq.map (fun (d, dmlist) -> d, dmlist |> Seq.map snd) + |> I.multiSortByNameAndPartialStartLine |> Seq.iter (fun (f, methods) -> //If available, a tracefile begins with the testname which // is stored in the following format: // // TN: - writer.WriteLine "TN:" + writer.WriteLine ("TN: " + assembly.Attribute("assemblyIdentity".X).Value) // For each source file referenced in the .da file, there is a section // containing filename and coverage data: // @@ -110,10 +135,11 @@ FN:4,(anonymous_0) |> Seq.iter (fun m -> let l = - (I.lineOfMethod m) + (I.lineOfPartialMethod m) .ToString(CultureInfo.InvariantCulture) - let name = fullname m + let (mx, pts) = m + let name = fullname mx writer.WriteLine("FN:" + l + "," + name)) // Next, there is a list of execution counts for each instrumented function: // @@ -121,10 +147,10 @@ FN:4,(anonymous_0) let hit = methods |> Seq.fold - (fun (n: int) m -> + (fun (n: int) (m,_) -> let v = (m.Descendants("seqpnt".X) |> Seq.head).Attribute( - "visitcount".X + "visitcount".X ) .Value @@ -169,20 +195,19 @@ FN:4,(anonymous_0) // checksumming algorithm. let (lf, lh) = methods - |> Seq.collect (fun m -> m.Descendants("seqpnt".X)) + |> Seq.collect snd |> Seq.filter (fun b -> b.Attribute("line".X).Value |> String.IsNullOrWhiteSpace |> not) + |> Seq.groupBy (fun b -> b.Attribute("line".X).Value) + |> Seq.sortBy (fst >> Int32.TryParse >> snd) |> Seq.fold - (fun (f, h) b -> - let sl = b.Attribute("line".X).Value - let v = b.Attribute("visitcount".X) - - let vc = if v |> isNull then "0" else v.Value - writer.WriteLine("DA:" + sl + "," + vc) - (f + 1, h + if vc = "0" then 0 else 1)) + (fun (f, (h:int)) (sl,bs) -> + let vc = I.computeVisitCount bs "visitcount" + writer.WriteLine("DA:" + sl + "," + vc.ToString(CultureInfo.InvariantCulture)) + (f + 1, h.Increment (vc <> 0))) (0, 0) // At the end of a section, there is a summary about how many lines were // found and how many were actually instrumented: @@ -194,16 +219,22 @@ FN:4,(anonymous_0) // Each sections ends with: // // end_of_record - writer.WriteLine "end_of_record") + writer.WriteLine "end_of_record")) | _ -> - report.Descendants("File".X) + report.Descendants("Module".X) + |> Seq.iter (fun assembly -> + assembly.Descendants("File".X) + |> Seq.sortBy(fun f -> f.Attribute("fullPath".X).Value) |> Seq.iter (fun f -> //If available, a tracefile begins with the testname which // is stored in the following format: // // TN: - writer.WriteLine "TN:" + writer.WriteLine ("TN: " + (assembly.Descendants("ModuleName".X) + |> Seq.tryHead + |> Option.map (fun n -> n.Value) + |> Option.defaultValue String.Empty)) // For each source file referenced in the .da file, there is a section // containing filename and coverage data: // @@ -221,8 +252,10 @@ FN:4,(anonymous_0) p.Descendants("Method".X) |> Seq.filter (fun m -> - m.Descendants("FileRef".X) - |> Seq.exists (fun r -> r.Attribute("uid".X).Value = uid)) + m.Descendants() + |> Seq.exists (fun r -> + let f = r.Attribute("fileid".X) + f.IsNotNull && f.Value = uid)) |> Seq.toList let FN (ms: XElement list) = // fsharplint:disable-line NonPublicValuesNames @@ -230,6 +263,7 @@ FN:4,(anonymous_0) |> Seq.iter (fun m -> m.Descendants("SequencePoint".X) + |> Seq.filter (fun s -> s.Attribute("fileid".X).Value = uid) |> Seq.tryHead |> Option.iter (fun s -> @@ -252,6 +286,7 @@ FN:4,(anonymous_0) |> Seq.iter (fun m -> m.Descendants("SequencePoint".X) + |> Seq.filter (fun s -> s.Attribute("fileid".X).Value = uid) |> Seq.tryHead |> Option.iter (fun s -> @@ -281,8 +316,15 @@ FN:4,(anonymous_0) let hit = methods - |> List.filter (fun m -> m.Attribute("visited".X).Value = "true") - + |> List.filter (fun m -> m.Attribute("visited".X).Value = "true" + || [ + m.Descendants("SequencePoint".X) + m.Descendants("BranchPoint".X) + m.Descendants("MethodPoint".X) + ] + |> Seq.concat + |> Seq.exists(fun s -> let v = s.Attribute("vc".X).Value + v.IsNotNull && v <> "0")) writer.WriteLine( "FNH:" + hit.Length.ToString(CultureInfo.InvariantCulture) @@ -298,6 +340,7 @@ FN:4,(anonymous_0) let (brf, brh, _) = ms |> Seq.collect (fun m -> m.Descendants("BranchPoint".X)) + |> Seq.filter (fun s -> s.Attribute("fileid".X).Value = uid) |> Seq.filter (fun b -> b.Attribute("sl".X).Value @@ -352,6 +395,7 @@ FN:4,(anonymous_0) let (lf, lh) = methods |> Seq.collect (fun m -> m.Descendants("SequencePoint".X)) + |> Seq.filter (fun s -> s.Attribute("fileid".X).Value = uid) |> Seq.filter (fun b -> b.Attribute("sl".X).Value @@ -365,16 +409,7 @@ FN:4,(anonymous_0) let sl = line.ToString(CultureInfo.InvariantCulture) - let vc = - points - |> Seq.fold - (fun total point -> - total - + (point.Attribute("vc".X).Value - |> Int32.TryParse - |> snd)) - 0 - + let vc = I.computeVisitCount points "vc" let vcs = vc.ToString(CultureInfo.InvariantCulture) @@ -391,7 +426,7 @@ FN:4,(anonymous_0) // Each sections ends with: // // end_of_record - writer.WriteLine "end_of_record")) + writer.WriteLine "end_of_record"))) let convertJson document s = let x = diff --git a/AltCover.Engine/Main.fs b/AltCover.Engine/Main.fs index 5212712f7..12b63c96b 100644 --- a/AltCover.Engine/Main.fs +++ b/AltCover.Engine/Main.fs @@ -34,8 +34,8 @@ module internal Main = let internal init () = CommandLine.verbosity <- 0 CommandLine.error <- [] - CommandLine.dropReturnCode := false // ddFlag - CoverageParameters.defer := false // ddflag + CommandLine.dropReturnCode.Value <- false // ddFlag + CoverageParameters.defer.Value <- false // ddflag CoverageParameters.theInputDirectories.Clear() CoverageParameters.theOutputDirectories.Clear() ProgramDatabase.symbolFolders.Clear() @@ -56,22 +56,22 @@ module internal Main = CoverageParameters.recorderStrongNameKey <- Some(snk) CoverageParameters.theReportPath <- None - CoverageParameters.zipReport := false - CoverageParameters.methodPoint := false + CoverageParameters.zipReport.Value <- false + CoverageParameters.methodPoint.Value <- false CoverageParameters.nameFilters.Clear() CoverageParameters.theInterval <- None CoverageParameters.trackingNames.Clear() CoverageParameters.topLevel.Clear() CoverageParameters.theReportFormat <- None - CoverageParameters.inplace := false // ddFlag - CoverageParameters.collect := false // ddFlag - CoverageParameters.local := false // ddFlag + CoverageParameters.inplace.Value <- false // ddFlag + CoverageParameters.collect.Value <- false // ddFlag + CoverageParameters.local.Value <- false // ddFlag CoverageParameters.single <- false // more complicated CoverageParameters.coverstyle <- CoverStyle.All - CoverageParameters.sourcelink := false // ddFlag - CoverageParameters.coalesceBranches := false // ddFlag + CoverageParameters.sourcelink.Value <- false // ddFlag + CoverageParameters.coalesceBranches.Value <- false // ddFlag CoverageParameters.staticFilter <- None - CoverageParameters.showGenerated := false + CoverageParameters.showGenerated.Value <- false let internal validateCallContext predicate x = if not (String.IsNullOrWhiteSpace x) then diff --git a/AltCover.Engine/Metadata.fs b/AltCover.Engine/Metadata.fs new file mode 100644 index 000000000..92aeb60b4 --- /dev/null +++ b/AltCover.Engine/Metadata.fs @@ -0,0 +1,35 @@ +namespace AltCover + +open System +open System.Diagnostics.CodeAnalysis +open System.IO +open System.IO.Compression + +open Mono.Cecil.Cil + +module internal Metadata = + let private squash (source:byte[]) = + use squashed = new MemoryStream() + // Get deflation working with this one weird trick + // Dispose the deflate stream w/o closing the one it points at! + do + use compress = new DeflateStream(squashed, CompressionMode.Compress, true) + compress.Write(source, 0, source.Length) + let crushed = Array.create (int squashed.Length) 0uy + squashed.Seek (0L, SeekOrigin.Begin) |> ignore + squashed.Read (crushed, 0, crushed.Length) |> ignore + crushed + + let internal getCompressedSource (embed:EmbeddedSourceDebugInformation) = + let datamake = Maybe embed.Compress squash id + let data = datamake embed.Content + Convert.ToBase64String data + + [] + let internal getSource (record:Document) = + record.CustomDebugInformations + |> Seq.tryFind (fun c -> c.Kind = CustomDebugInformationKind.EmbeddedSource) + |> Option.map (fun c -> getCompressedSource (c :?> EmbeddedSourceDebugInformation)) + |> Option.filter (String.IsNullOrEmpty >> not) \ No newline at end of file diff --git a/AltCover.Engine/NativeJson.fs b/AltCover.Engine/NativeJson.fs index 5016f78c9..17cb9902c 100644 --- a/AltCover.Engine/NativeJson.fs +++ b/AltCover.Engine/NativeJson.fs @@ -673,7 +673,7 @@ module w |> append (slugs.[9]) - |> appendLine ("\"Lines\": {") + |> (if method.Lines |> Seq.isEmpty then append else appendLine) ("\"Lines\": {") |> ifNotEmpty method.Lines lineToBuilder id post |> appendLine ("},") @@ -692,9 +692,12 @@ module >> append (slugs.[9]) >> appendLine ("\"SeqPnts\": [")) id - |> newLine - |> append (slugs.[10]) - |> append ("]") + |> if Seq.isEmpty method.SeqPnts + then id + else + newLine + >> append (slugs.[10]) + >> append ("]") // After SeqPnts, now Tracking |> methodTrackingToBuilder method @@ -745,49 +748,72 @@ module #if GUI || RUNNER // Conversion to XML --------------------------------------------------------- - let internal buildSummary (m: XContainer) = + let internal summaryElement () = let zero name = XAttribute(XName.Get name, 0) + XElement( + XName.Get "Summary", + zero "numBranchPoints", + zero "visitedBranchPoints", + zero "numSequencePoints", + zero "visitedSequencePoints") - let sd = - XElement( - XName.Get "Summary", - zero "numBranchPoints", - zero "visitedBranchPoints", - zero "numSequencePoints", - zero "visitedSequencePoints" - ) - + let internal buildSummary (m: XContainer) = + let sd = summaryElement () m.Add sd sd - let internal buildMethodElement name fileId = - let m = - XElement( - XName.Get "Method", - XAttribute(XName.Get "visited", false), - XAttribute(XName.Get "cyclomaticComplexity", 1), - XAttribute(XName.Get "sequenceCoverage", 0), - XAttribute(XName.Get "branchCoverage", 0), - XAttribute(XName.Get "isConstructor", false), - XAttribute(XName.Get "isStatic", false), - XAttribute(XName.Get "isGetter", false), - XAttribute(XName.Get "isSetter", false) - ) - - let sd = buildSummary m - - [ "MetadataToken", "0"; "Name", name ] - |> Seq.iter - (fun (name, value) -> - let x = XElement(XName.Get name) - x.Value <- value - m.Add x) + [] + let internal tryGetValueOrDefault + (table: Dictionary) + (key: string) + (f: unit -> 'a) + = + let ok, index = table.TryGetValue key - let f = - XElement(XName.Get "FileRef", XAttribute(XName.Get "uid", fileId)) + if ok then + index + else + let value = f () + table.Add(key, value) + value - m.Add f - (m, sd) + let internal buildMethodElement + (table:Dictionary) (item:XElement) + name fileId = + tryGetValueOrDefault + table + name + (fun () -> + let m2 = + XElement( + XName.Get "Method", + XAttribute(XName.Get "visited", false), + XAttribute(XName.Get "cyclomaticComplexity", 1), + XAttribute(XName.Get "sequenceCoverage", 0), + XAttribute(XName.Get "branchCoverage", 0), + XAttribute(XName.Get "isConstructor", false), + XAttribute(XName.Get "isStatic", false), + XAttribute(XName.Get "isGetter", false), + XAttribute(XName.Get "isSetter", false) + ) + + let sd = buildSummary m2 + + [ "MetadataToken", "0"; "Name", name ] + |> Seq.iter + (fun (name, value) -> + let x = XElement(XName.Get name) + x.Value <- value + m2.Add x) + + let f = + XElement(XName.Get "FileRef", XAttribute(XName.Get "uid", fileId)) + + m2.Add f + item.Add m2 + m2) let internal makeSummary (nb: int) (vb: int) (ns: int) (vs: int) (sd: XElement) = sd.Attribute(XName.Get "numBranchPoints").Value <- nb.ToString( @@ -806,24 +832,33 @@ module [] + [] let internal methodToXml + (table:Dictionary) (fileId: int) (item: XElement) (method: KeyValuePair) = - let m, sd = buildMethodElement method.Key fileId - item.Add m + let m = buildMethodElement table item method.Key fileId - let sp = XElement(XName.Get "SequencePoints") - m.Add sp - let bp = XElement(XName.Get "BranchPoints") - m.Add bp - let value = method.Value + // conditional + let sp = m.Descendants("SequencePoints".X) + |> Seq.tryHead + |> Option.defaultWith (fun () -> let tmp = XElement(XName.Get "SequencePoints") + m.Add tmp + tmp) + let bp = m.Descendants("BranchPoints".X) + |> Seq.tryHead + |> Option.defaultWith (fun () -> let tmp = XElement(XName.Get "BranchPoints") + m.Add tmp + tmp) + + let value = method.Value let bec = Dictionary() let bev = Dictionary() - let mutable nb = 0 - let mutable vb = 0 if value.Branches.IsNotNull then value.Branches @@ -831,10 +866,8 @@ module (fun b -> let _, old = bec.TryGetValue b.Line bec.[b.Line] <- old + 1 - nb <- nb + 1 if b.Hits > 0 then - vb <- vb + 1 let _, old = bev.TryGetValue b.Line bev.[b.Line] <- old + 1 @@ -863,10 +896,6 @@ module m.Attribute(XName.Get "cyclomaticComplexity").Value <- (1 + targets) .ToString(CultureInfo.InvariantCulture) - let mutable mvc = 0 - let mutable ns = 0 - let mutable vs = 0 - if value.SeqPnts.IsNotNull then value.SeqPnts |> Seq.iter @@ -875,8 +904,6 @@ module bec.[s.SL] <- 0 let _, bev2 = bev.TryGetValue s.SL bev.[s.SL] <- 0 - ns <- ns + 1 - if s.VC > 0 then vs <- vs + 1 let sx = XElement( @@ -893,8 +920,7 @@ module XAttribute(XName.Get "fileid", fileId) ) - sp.Add sx - mvc <- Math.Max(mvc, s.VC)) + sp.Add sx) else value.Lines |> Seq.iteri @@ -904,8 +930,6 @@ module bec.[k] <- 0 let _, bev2 = bev.TryGetValue k bev.[k] <- 0 - ns <- ns + 1 - if l.Value > 0 then vs <- vs + 1 let sx = XElement( @@ -922,37 +946,61 @@ module XAttribute(XName.Get "fileid", fileId) ) - sp.Add sx - mvc <- Math.Max(mvc, l.Value)) - - let mp = - XElement(XName.Get "MethodPoint", XAttribute(XName.Get "vc", mvc)) - - m.Add mp - makeSummary nb vb ns vs sd + sp.Add sx) + + // recompute points + let sd = m.Descendants("Summary".X) |> Seq.head + let branches = bp.Descendants("BranchPoint".X) + let nb = branches |> Seq.length + let vb = branches |> Seq.filter (fun x -> x.Attribute("vc".X).Value <> "0") + |> Seq.length + let points = sp.Descendants("SequencePoint".X) + let ns = points |> Seq.length + let vs = points |> Seq.filter (fun x -> x.Attribute("vc".X).Value <> "0") + |> Seq.length + + if ns > 0 then + let mp = m.Descendants("MethodPoint".X) |> Seq.tryHead + |> Option.defaultWith (fun () -> let tmp = XElement(XName.Get "MethodPoint", XAttribute(XName.Get "vc", "0")) + m.Add tmp + tmp) + let mvc = points // not Seq.max as that exposes repeated calls to enumerator.Current when bootstrapping + |> Seq.fold (fun max x -> let tmp = x.Attribute("vc".X).Value |> Int32.TryParse |> snd + if tmp > max then tmp else max) 0 // know this is a hard floor + mp.Attribute("vc".X).Value <- mvc.ToString(CultureInfo.InvariantCulture) + + // adjust to match OpenCover values for branches + makeSummary (nb.Increment (nb > 0 || ns > 0)) + (vb.Increment (vb > 0 || vs > 0)) ns vs sd [] - let internal methodsToXml (fileId: int) (item: XElement) (methods: Methods) = - methods |> Seq.iter (methodToXml fileId item) + let internal methodsToXml (fileId: int) (item: XElement) (table:Dictionary) (methods: Methods) = + methods |> Seq.iter (methodToXml table fileId item) + + let private valueOf (x: XElement) (name: string) = + x.Attribute(XName.Get name).Value + |> Int32.TryParse + |> snd [] - let internal tryGetValueOrDefault - (table: Dictionary) - (key: string) - (f: unit -> 'a) - = - let ok, index = table.TryGetValue key + let internal summarize sd (m: XElement) name = + let (nb, vb, ns, vs) = + m.Descendants(XName.Get name) + |> Seq.collect (fun m2 -> m2.Elements(XName.Get "Summary")) + |> Seq.fold + (fun (bn, bv, sn, sv) ms -> + (bn + valueOf ms "numBranchPoints", + bv + valueOf ms "visitedBranchPoints", + sn + valueOf ms "numSequencePoints", + sv + valueOf ms "visitedSequencePoints")) + (0, 0, 0, 0) + + makeSummary nb vb ns vs sd - if ok then - index - else - let value = f () - table.Add(key, value) - value [) + (methodtable: Dictionary) (classes: Classes) = classes @@ -974,6 +1023,7 @@ module (fun () -> XElement( XName.Get "Class", + summaryElement (), XElement(XName.Get "FullName", name), XElement(XName.Get "Methods") )) @@ -981,29 +1031,9 @@ module let next = item.Elements(XName.Get "Methods") |> Seq.head - methodsToXml fileId next kvp.Value) - - let private valueOf (x: XElement) (name: string) = - x.Attribute(XName.Get name).Value - |> Int32.TryParse - |> snd - - [] - let internal summarize sd (m: XElement) name = - let (nb, vb, ns, vs) = - m.Descendants(XName.Get name) - |> Seq.collect (fun m2 -> m2.Elements(XName.Get "Summary")) - |> Seq.fold - (fun (bn, bv, sn, sv) ms -> - (bn + valueOf ms "numBranchPoints", - bv + valueOf ms "visitedBranchPoints", - sn + valueOf ms "numSequencePoints", - sv + valueOf ms "visitedSequencePoints")) - (0, 0, 0, 0) - - makeSummary nb vb ns vs sd + methodsToXml fileId next methodtable kvp.Value + let sd = item.Descendants("Summary".X) |> Seq.head + summarize sd item "Method") [() + let methodTable = Dictionary() documents |> Seq.iter @@ -1047,10 +1078,17 @@ module XAttribute(XName.Get "fullPath", name) ) + kvp.Value + |> Seq.tryFind(fun kvp -> kvp.Key = "\u00ABAltCover.embed\u00BB") + |> Option.map (fun kvp -> kvp.Value.Keys |> Seq.tryHead) + |> Option.flatten + |> Option.iter (fun embed -> item.Add(XAttribute(XName.Get "altcover.embed", embed))) + files.Add item - classesToXml i classTable kvp.Value) + classesToXml i classTable methodTable kvp.Value) classTable + |> Seq.filter (fun kvp -> kvp.Key |> Seq.head <> '\u00AB') |> Seq.iter (fun kvp -> classes.Add kvp.Value) summarize sd m "Method" @@ -1113,6 +1151,12 @@ module original |> Seq.sortBy (fun sp -> + let offset = sp.Attribute(XName.Get "fileid") + let topword = offset + |> Option.ofObj + |> Option.map(fun x -> x.Value |> Int64.TryParse |> snd) + |> Option.defaultValue 0L + let sl = sp.Attribute(XName.Get "sl").Value |> Int32.TryParse @@ -1123,7 +1167,7 @@ module |> Int32.TryParse |> snd - (sl <<< 16) + sc) + (topword <<< 32) + int64 ((sl <<< 16) + sc)) |> sps.Add) x.Descendants(XName.Get "BranchPoints") @@ -1159,6 +1203,16 @@ module #if RUNNER // Instrumentation --------------------------------------------------------- + [] + let injectEmbed (c:Classes) (embed:string) = + if embed |> String.IsNullOrWhiteSpace |> not then + let dummy = Method.Create(None) + let m = Methods() + m.Add (embed, dummy) + c.Add ("\u00ABAltCover.embed\u00BB", m) + [] type internal JsonContext = { Documents: Documents @@ -1196,7 +1250,7 @@ module VisibleMethod = m.VisibleMethod Track = m.Track } - let getMethodRecord (s: JsonContext) (doc: string) = + let getMethodRecord (s: JsonContext) (doc: string) (record:Cil.Document) = let visibleMethodName = s.VisibleMethod.FullName let visibleTypeName = s.VisibleMethod.DeclaringType.FullName @@ -1206,6 +1260,9 @@ module | _ -> let c = Classes() s.Documents.Add(doc, c) + record + |> Metadata.getSource + |> Option.iter (injectEmbed c) c let methods = @@ -1229,9 +1286,9 @@ module |> Option.iter (fun codeSegment -> let doc = - codeSegment.Document |> Visitor.sourceLinkMapping + codeSegment.Document.Url |> Visitor.sourceLinkMapping - let mplus = getMethodRecord s doc + let mplus = getMethodRecord s doc codeSegment.Document mplus.Lines.[codeSegment.StartLine] <- int e.DefaultVisitCount mplus.SeqPnts.Add @@ -1253,7 +1310,7 @@ module b.SequencePoint.Document.Url |> Visitor.sourceLinkMapping - let mplus = getMethodRecord s doc + let mplus = getMethodRecord s doc b.SequencePoint.Document mplus.Branches.Add { Line = b.SequencePoint.StartLine @@ -1284,7 +1341,6 @@ module VisibleType = null } let visitAfterModule s = { s with Documents = null } - // let afterAll = id let reportVisitor (s: JsonContext) (node: Node) = match node with @@ -1297,7 +1353,6 @@ module | AfterMethod m -> visitAfterMethod s m | AfterType _ -> visitAfterType s | AfterModule _ -> visitAfterModule s - // | Finish -> afterAll s | _ -> s let result = diff --git a/AltCover.Engine/OpenCover.fs b/AltCover.Engine/OpenCover.fs index 19a4243f7..c38a9180d 100644 --- a/AltCover.Engine/OpenCover.fs +++ b/AltCover.Engine/OpenCover.fs @@ -4,6 +4,7 @@ open System open System.Diagnostics.CodeAnalysis open System.Globalization open System.IO +open System.IO.Compression open System.Linq open System.Xml.Linq @@ -23,6 +24,7 @@ type internal OpenCoverContext = { Stack: XElement list Excluded: Exclusion Files: Map + Embeds: Map Index: int MethodSeq: int MethodBr: int @@ -43,6 +45,7 @@ type internal OpenCoverContext = { Stack = List.empty Excluded = Nothing Files = Map.empty + Embeds = Map.empty Index = 0 MethodSeq = 0 MethodBr = 0 @@ -125,6 +128,13 @@ module internal OpenCover = element.Add(modules) { s with Stack = modules :: s.Stack } + let recordFile (files: Map) file = + if files.ContainsKey file then + files, files.Item file + else + let index = files.Count + 1 + files.Add(file, index), index + let visitModule (s: OpenCoverContext) (moduleDef: ModuleEntry) = let def = moduleDef.Module let instrumented = moduleDef.Inspection.IsInstrumented @@ -142,8 +152,25 @@ module internal OpenCover = element.Add(XElement("ModuleTime".X, File.GetLastWriteTimeUtc def.FileName)) element.Add(XElement("ModuleName".X, def.Assembly.Name.Name)) - if instrumented then - element.Add(XElement("Files".X)) + let (files, embeds) = + if instrumented then + element.Add(XElement("Files".X)) + def + |> ProgramDatabase.getModuleDocuments + |> Seq.fold (fun f d -> let key = d.Url + |> Visitor.sourceLinkMapping + let map = snd f + + let embed = d + |> Metadata.getSource + |> Option.map (fun s -> Map.add key s map) + |> Option.defaultValue map + + (key + |> recordFile (fst f) + |> fst, + embed)) (s.Files, s.Embeds) + else (s.Files, s.Embeds) let classes = XElement("Classes".X) element.Add(classes) @@ -156,6 +183,8 @@ module internal OpenCover = { s with Stack = classes :: s.Stack Excluded = Nothing + Files = files + Embeds = embeds ModuleSeq = 0 ModuleBr = 0 ModuleMethods = 0 @@ -277,16 +306,9 @@ module internal OpenCover = XAttribute("fileid".X, ref) ) - let recordFile (s: OpenCoverContext) file = - if s.Files.ContainsKey file then - s.Files, s.Files.Item file - else - let index = s.Files.Count + 1 - s.Files.Add(file, index), index - let visitCodeSegment (s: OpenCoverContext) (codeSegment: SeqPnt) i vc = let fileset, ref = - recordFile s (codeSegment.Document |> Visitor.sourceLinkMapping) + recordFile s.Files (codeSegment.Document.Url |> Visitor.sourceLinkMapping) let element = methodPointElement codeSegment ref i vc let head = s.Stack |> Seq.head @@ -319,7 +341,7 @@ module internal OpenCover = let visitGoTo s branch = let doc = branch.SequencePoint.Document.Url - let fileset, ref = recordFile s doc + let fileset, ref = recordFile s.Files doc let fileid = fileset.Item doc (XElement( @@ -623,13 +645,15 @@ module internal OpenCover = files |> Seq.iter (fun f -> - f.Add( + let file = XElement( "File".X, XAttribute("uid".X, v), XAttribute("fullPath".X, k) ) - ))) + f.Add(file) + if s.Embeds.ContainsKey k + then file.Add(XAttribute("altcover.embed".X, s.Embeds.Item k)))) { s with Stack = tail diff --git a/AltCover.Engine/Primitive.fsi b/AltCover.Engine/Primitive.fsi index 188054b10..bcdb23a46 100644 --- a/AltCover.Engine/Primitive.fsi +++ b/AltCover.Engine/Primitive.fsi @@ -246,14 +246,14 @@ namespace AltCoverFake.DotNet.Testing /// Corresponds to command line option ` -q` /// Verbosity : System.Diagnostics.TraceLevel -} - with + } + with /// /// Returns an instance with all fields empty that has all empty or `false` fields except `ExposeReturnCode`, `OpenCover`, `InPlace` and `Save` are `true`, and `ShowStatic` is `-` /// ///a default instance static member Create : unit -> PrepareOptions - end + end // ``` // `Create()` returns an instance that has all empty or `false` fields except `ExposeReturnCode`, `OpenCover`, `InPlace` and `Save` are `true`, and `ShowStatic` is `-` // @@ -271,7 +271,7 @@ namespace AltCoverFake.DotNet.Testing /// [] type LoggingOptions = - { + { /// /// Sink for informational messages /// @@ -288,13 +288,13 @@ namespace AltCoverFake.DotNet.Testing /// Sink for command line/usage messages /// Echo : System.String -> unit } - with + with /// /// Returns an instance that just discards all strings input. /// ///a default instance static member Create : unit -> LoggingOptions - end + end // ``` // `Create()` returns an instance that just discards all strings input. For your particular use, direct message severities appropriately. `Echo` is used to echo the synthetic command line in case of inconsistent inputs. #endif diff --git a/AltCover.Engine/ProgramDatabase.fs b/AltCover.Engine/ProgramDatabase.fs index 5f376c0b0..cedb1222d 100644 --- a/AltCover.Engine/ProgramDatabase.fs +++ b/AltCover.Engine/ProgramDatabase.fs @@ -9,6 +9,7 @@ open Mono.Cecil open Mono.Cecil.Cil open Mono.Cecil.Mdb open Mono.Cecil.Pdb +open Mono.Cecil.Rocks [] module internal ProgramDatabase = @@ -26,22 +27,6 @@ module internal ProgramDatabase = |> Seq.head) .GetMethod("GetEmbeddedPortablePdbEntry") - // and for direct access to the Documents data - let internal getMetadataReader = - typeof.GetField("reader", BindingFlags.Instance ||| BindingFlags.NonPublic) - - let internal metadataSystem = - (typeof.Assembly.GetTypes () - |> Seq.filter (fun m -> m.FullName = "Mono.Cecil.MetadataReader") - |> Seq.head) - .GetField("metadata", BindingFlags.Instance ||| BindingFlags.NonPublic) - - let internal getDocuments = - (typeof.Assembly.GetTypes () - |> Seq.filter (fun m -> m.FullName = "Mono.Cecil.MetadataSystem") - |> Seq.head) - .GetField("Documents", BindingFlags.Instance ||| BindingFlags.NonPublic) - let internal getEmbeddedPortablePdbEntry (assembly: AssemblyDefinition) = getEmbed.Invoke(null, [| assembly.MainModule.GetDebugHeader() :> obj |]) :?> ImageDebugHeaderEntry @@ -116,20 +101,12 @@ module internal ProgramDatabase = assembly.MainModule.ReadSymbols(reader)) - let internal getAssemblyDocuments (assembly: AssemblyDefinition) = - let reader = I.getMetadataReader.GetValue(assembly.MainModule) - let system = I.metadataSystem.GetValue(reader) - I.getDocuments.GetValue(system) // set if sequence points have been loaded - |> Option.ofObj - |> Option.defaultValue - (assembly.MainModule.GetTypes() - |> Seq.collect(fun t -> t.Methods) - |> Seq.collect(fun m -> m.DebugInformation.SequencePoints) - |> Seq.tryHead // assuming lazy & that no SP = no user code - // Have to evaluate if any exist to perform this operation - |> Option.map (fun _ -> I.getDocuments.GetValue(system) - |> Option.ofObj) - |> Option.flatten - |> Option.defaultValue ([] :> obj)) :?> System.Collections.IEnumerable - |> Seq.cast + // reflective short-cuts don't work. + // maybe move this somewhere else, now? + let internal getModuleDocuments (``module``: ModuleDefinition) = + ``module``.GetAllTypes() + |> Seq.collect (fun t -> t.GetMethods()) + |> Seq.collect (fun m -> m.DebugInformation.SequencePoints) + |> Seq.map (fun s -> s.Document) + |> Seq.distinctBy (fun d -> d.Url) |> Seq.toList \ No newline at end of file diff --git a/AltCover.Engine/Report.fs b/AltCover.Engine/Report.fs index c7f3c734d..0b9bf9b20 100644 --- a/AltCover.Engine/Report.fs +++ b/AltCover.Engine/Report.fs @@ -67,6 +67,19 @@ module internal Report = ) head.Add(element) + + // embed support + moduleDef.Module + |> ProgramDatabase.getModuleDocuments + |> Seq.iter (fun d -> let key = d.Url + |> Visitor.sourceLinkMapping + d + |> Metadata.getSource + |> Option.iter (fun s -> let x = XElement("altcover.file".X, + XAttribute("document".X, key), + XAttribute("embed".X, s)) + element.Add x)) + element :: s let visitMethod @@ -87,7 +100,9 @@ module internal Report = XAttribute("fullname".X, Naming.fullMethodName methodDef) ) - head.Add(element) + (head.Elements("altcover.file".X) |> Seq.tryHead + |> Option.map (fun x -> x.AddBeforeSelf) + |> Option.defaultValue head.Add) [| element |] element :: s let visitMethodPoint (s: list) (head: XElement) (e: StatementEntry) = @@ -102,7 +117,7 @@ module internal Report = XAttribute("endline".X, codeSegment.EndLine), XAttribute("endcolumn".X, codeSegment.EndColumn), XAttribute("excluded".X, toExcluded e.Interesting), - XAttribute("document".X, codeSegment.Document |> Visitor.sourceLinkMapping) + XAttribute("document".X, codeSegment.Document.Url |> Visitor.sourceLinkMapping) ) if head.IsEmpty then diff --git a/AltCover.Engine/Runner.fs b/AltCover.Engine/Runner.fs index 5e4140510..8267dac07 100644 --- a/AltCover.Engine/Runner.fs +++ b/AltCover.Engine/Runner.fs @@ -56,7 +56,7 @@ type internal SummaryFormat = | ('R', _) -> Many(R :: (SummaryFormat.ToList state)) | ('O', _) -> Many(O :: (SummaryFormat.ToList state)) | ('C', _) -> Many(C :: (SummaryFormat.ToList state)) - | _ -> s |> FormatException |> raise) + | _ -> raise (s |> FormatException)) (Many []) with :? FormatException -> Default @@ -160,19 +160,22 @@ module internal Runner = let internal init () = CommandLine.verbosity <- 0 CommandLine.error <- [] - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false recordingDirectory <- None workingDirectory <- None - executable := None - LCov.path := None - Cobertura.path := None - Json.path := None - collect := false + executable.Value <- None + LCov.path.Value <- None + Cobertura.path.Value <- None + Json.path.Value <- None + collect.Value <- false threshold <- None output <- None summaryFormat <- Default summary.Clear() |> ignore + [] module internal I = let internal write line = @@ -372,53 +375,91 @@ module internal Runner = (amv, acv) + type Category = + { + Number : string; + Visited : string; + Coverage : string; + } + + [] + let private summariseBase (summary: XElement) go (visit: string) (number: string) (precalc: string option) key = + let vc = summary.Attribute(visit.X).Value + let nc = summary.Attribute(number.X).Value + + let pc = + match precalc with + | None -> + if nc = "0" then + "n/a" + else + let vc1 = vc |> Int32.TryParse |> snd |> float + + let nc1 = nc |> Int32.TryParse |> snd |> float + + Math + .Round(vc1 * 100.0 / nc1, 2) + .ToString(CultureInfo.InvariantCulture) + | Some x -> summary.Attribute(x.X).Value + + if go then writeSummary key vc nc pc + + { + Number = nc + Visited = vc + Coverage = pc + } + + let private allTC l classes methods statements branches = + writeTC totalTC "C" classes.Number + writeTC coverTC "C" classes.Visited + writeTC totalTC "M" methods.Number + writeTC coverTC "M" methods.Visited + writeTC totalTC "S" statements.Number + writeTC coverTC "S" statements.Visited + + l + |> Seq.iter + (fun f -> + let tag = + match f with + | R -> "R" + | B -> "B" + | _ -> String.Empty + + if tag |> String.IsNullOrEmpty |> not then + writeTC totalTC tag branches.Number + writeTC coverTC tag branches.Visited) + [] [] + Justification = "Library method inlined 4 times")>] [] let private makeOpenCoverSummary (report: XDocument) (summary: XElement) = - let summarise go (visit: string) (number: string) (precalc: string option) key = - let vc = summary.Attribute(visit.X).Value - let nc = summary.Attribute(number.X).Value - - let pc = - match precalc with - | None -> - if nc = "0" then - "n/a" - else - let vc1 = vc |> Int32.TryParse |> snd |> float - - let nc1 = nc |> Int32.TryParse |> snd |> float - - Math - .Round(vc1 * 100.0 / nc1, 2) - .ToString(CultureInfo.InvariantCulture) - | Some x -> summary.Attribute(x.X).Value - - if go then writeSummary key vc nc pc - (vc, nc, pc) - let l = (SummaryFormat.ToList summaryFormat) |> Seq.distinct + let summarise = summariseBase summary + let go = summaryFormat = Default || l |> Seq.contains O - let (vc, nc, _) = + let classes = summarise go "visitedClasses" "numClasses" None "VisitedClasses" - let (vm, nm, mcovered) = + let methods = summarise go "visitedMethods" "numMethods" None "VisitedMethods" - let (vs, ns, covered) = + let statements = summarise go "visitedSequencePoints" @@ -426,7 +467,7 @@ module internal Runner = (Some "sequenceCoverage") "VisitedPoints" - let (vb, nb, bcovered) = + let branches = summarise go "visitedBranchPoints" @@ -455,29 +496,11 @@ module internal Runner = let (altmcovered, altcrapvalue) = altSummary go extra report if l |> Seq.contains B || l |> Seq.contains R then - writeTC totalTC "C" nc - writeTC coverTC "C" vc - writeTC totalTC "M" nm - writeTC coverTC "M" vm - writeTC totalTC "S" ns - writeTC coverTC "S" vs + allTC l classes methods statements branches - l - |> Seq.iter - (fun f -> - let tag = - match f with - | R -> "R" - | B -> "B" - | _ -> String.Empty - - if tag |> String.IsNullOrEmpty |> not then - writeTC totalTC tag nb - writeTC coverTC tag vb) - - [ covered - bcovered - mcovered + [ statements.Coverage + branches.Coverage + methods.Coverage altmcovered crapvalue altcrapvalue ] @@ -736,7 +759,7 @@ module internal Runner = CommandLine.Format.Local("MultiplesNotAllowed", "--executable") :: CommandLine.error else - executable := Some x)) + executable.Value <- Some x)) (CommandLine.ddFlag "collect" collect) ("l|lcovReport=", (fun x -> @@ -746,7 +769,7 @@ module internal Runner = CommandLine.Format.Local("MultiplesNotAllowed", "--lcovReport") :: CommandLine.error else - LCov.path := x |> canonicalPath |> Some + LCov.path.Value <- x |> canonicalPath |> Some I.addLCovSummary ())) ("t|threshold=", (fun x -> @@ -767,7 +790,7 @@ module internal Runner = CommandLine.Format.Local("MultiplesNotAllowed", "--cobertura") :: CommandLine.error else - Cobertura.path := x |> canonicalPath |> Some + Cobertura.path.Value <- x |> canonicalPath |> Some I.addCoberturaSummary ())) ("o|outputFile=", (fun x -> @@ -1244,6 +1267,11 @@ module internal Runner = [] + [] + [] let writeNativeJsonReport (hits: Dictionary>) _ diff --git a/AltCover.Engine/Visitor.fs b/AltCover.Engine/Visitor.fs index 3c729ca61..b5e1888b6 100644 --- a/AltCover.Engine/Visitor.fs +++ b/AltCover.Engine/Visitor.fs @@ -44,7 +44,8 @@ type internal SeqPnt = StartColumn: int EndLine: int EndColumn: int - Document: string + [] + Document: Cil.Document Offset: int } static member Build(codeSegment: Cil.SequencePoint) = { StartLine = codeSegment.StartLine @@ -59,7 +60,7 @@ type internal SeqPnt = codeSegment.StartColumn + 1 else codeSegment.EndColumn - Document = codeSegment.Document.Url + Document = codeSegment.Document Offset = codeSegment.Offset } [] @@ -212,7 +213,7 @@ type internal SequenceType = [] module internal KeyStore = let private hash = - new System.Security.Cryptography.SHA1CryptoServiceProvider() + sha1Hash() let private publicKeyOfKey (key: StrongNameKeyData) = key.PublicKey @@ -311,6 +312,11 @@ module internal CoverageParameters = let internal theOutputDirectories = List() + [] + [] let private defaultOutputDirectory _ = inplaceSelection "__Saved" "__Instrumented" @@ -406,8 +412,8 @@ module internal Inspector = match nameProvider with | :? AssemblyDefinition as a -> (CoverageParameters.local.Value) - && a - |> ProgramDatabase.getAssemblyDocuments + && a.MainModule + |> ProgramDatabase.getModuleDocuments |> Seq.map (fun d -> d.Url) |> Seq.exists File.Exists |> not @@ -454,7 +460,7 @@ module internal Visitor = .Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar) // overkill let internal exists (url: Uri) = - let request = System.Net.WebRequest.CreateHttp(url) + let request = createHttp(url) request.Method <- "HEAD" try @@ -622,7 +628,7 @@ module internal Visitor = (fun x -> x.CustomDebugInformations |> Seq.tryFind (fun i -> i.Kind = CustomDebugInformationKind.SourceLink)) - |> Option.bind id + |> Option.flatten |> Option.map (fun i -> let c = diff --git a/AltCover.Expecto.Tests/AltCover.Expecto.Tests.fsproj b/AltCover.Expecto.Tests/AltCover.Expecto.Tests.fsproj index 5d66e020e..3d700f066 100644 --- a/AltCover.Expecto.Tests/AltCover.Expecto.Tests.fsproj +++ b/AltCover.Expecto.Tests/AltCover.Expecto.Tests.fsproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ $(SolutionDir)_Intermediate/$(AssemblyName)/$(Configuration)+$(Platform)/ DEBUG;TRACE;EXPECTO_MAIN @@ -24,8 +24,8 @@ - - + + @@ -33,7 +33,8 @@ - + + contentfiles diff --git a/AltCover.Fake.DotNet.Testing.AltCover/AltCover.Fake.DotNet.Testing.AltCover.fsproj b/AltCover.Fake.DotNet.Testing.AltCover/AltCover.Fake.DotNet.Testing.AltCover.fsproj index 4d547e5dd..80da7f9f6 100644 --- a/AltCover.Fake.DotNet.Testing.AltCover/AltCover.Fake.DotNet.Testing.AltCover.fsproj +++ b/AltCover.Fake.DotNet.Testing.AltCover/AltCover.Fake.DotNet.Testing.AltCover.fsproj @@ -7,8 +7,6 @@ AltCover.Fake.DotNet.Testing.AltCover false true - true - true NoCanonicalDirectories $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -19,6 +17,15 @@ MSB3277;MSB3245 + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) 4 @@ -54,29 +61,24 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers - - - - all runtime; build; native; contentfiles; analyzers; buildtransitive - + contentfiles - \ No newline at end of file diff --git a/AltCover.Fake/AltCover.Fake.fsproj b/AltCover.Fake/AltCover.Fake.fsproj index ba9c9ec87..06fbb4d82 100644 --- a/AltCover.Fake/AltCover.Fake.fsproj +++ b/AltCover.Fake/AltCover.Fake.fsproj @@ -7,8 +7,6 @@ AltCover.Fake false true - true - true RUNNER $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -17,6 +15,15 @@ --keyfile:$(SolutionDir)Build\Infrastructure.snk + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) 4 @@ -36,9 +43,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers @@ -58,6 +65,7 @@ + contentfiles diff --git a/AltCover.FontSupport/AltCover.FontSupport.csproj b/AltCover.FontSupport/AltCover.FontSupport.csproj index ca1d16575..701bfa110 100644 --- a/AltCover.FontSupport/AltCover.FontSupport.csproj +++ b/AltCover.FontSupport/AltCover.FontSupport.csproj @@ -6,8 +6,6 @@ AltCover.FontSupport false true - true - true $(ProjectDir)../ true $(SolutionDir)\Build\Infrastructure.snk @@ -19,6 +17,15 @@ true + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS @@ -40,9 +47,13 @@ - + all runtime; build; native; contentfiles; analyzers + + + + \ No newline at end of file diff --git a/AltCover.Monitor.Tests/AltCover.Monitor.Tests.fsproj b/AltCover.Monitor.Tests/AltCover.Monitor.Tests.fsproj index 383f037d7..54932035c 100644 --- a/AltCover.Monitor.Tests/AltCover.Monitor.Tests.fsproj +++ b/AltCover.Monitor.Tests/AltCover.Monitor.Tests.fsproj @@ -1,7 +1,7 @@  - net5.0;net472 + net6.0;net472 false AltCover.Monitor.Tests false @@ -22,13 +22,13 @@ - - + + ..\ThirdParty\Unquote.dll - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -50,7 +50,8 @@ - + + contentfiles diff --git a/AltCover.Monitor.Tests/MonitorTest.fs b/AltCover.Monitor.Tests/MonitorTest.fs index 83b3fd187..021351229 100644 --- a/AltCover.Monitor.Tests/MonitorTest.fs +++ b/AltCover.Monitor.Tests/MonitorTest.fs @@ -19,7 +19,7 @@ module MonitorTests = let xml = Path.Combine( SolutionRoot.location, - "_Reports/MonitorTestWithAltCoverCoreRunner.net5.0.xml" + "_Reports/MonitorTestWithAltCoverCoreRunner.net6.0.xml" ) let doc = XDocument.Load(xml) @@ -51,4 +51,10 @@ module MonitorTests = maybeIgnore (fun () -> not (a && a0)) let code = b.Code let branch = b.Branch - test <@ (code, branch) = (85, 11) @> + let text = + Path.Combine( + SolutionRoot.location, + "_Reports/MonitorTestWithAltCoverCoreRunner.net6.0.xml" + ) + |> File.ReadAllText + test' <@ (code, branch) = (109, 14) @> text diff --git a/AltCover.Monitor/AltCover.Monitor.csproj b/AltCover.Monitor/AltCover.Monitor.csproj index 9fff747c3..da74cd463 100644 --- a/AltCover.Monitor/AltCover.Monitor.csproj +++ b/AltCover.Monitor/AltCover.Monitor.csproj @@ -6,8 +6,6 @@ AltCover.Monitor false true - true - true $(ProjectDir)../ true $(SolutionDir)\Build\Infrastructure.snk @@ -19,6 +17,15 @@ true + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS true @@ -41,7 +48,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -50,4 +57,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + + + \ No newline at end of file diff --git a/AltCover.PowerShell/AltCover.PowerShell.fsproj b/AltCover.PowerShell/AltCover.PowerShell.fsproj index aff918aa5..a54f6704a 100644 --- a/AltCover.PowerShell/AltCover.PowerShell.fsproj +++ b/AltCover.PowerShell/AltCover.PowerShell.fsproj @@ -7,14 +7,21 @@ AltCover.PowerShell false true - true - true $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ $(SolutionDir)_Intermediate/$(AssemblyName)/$(Configuration)+$(Platform)/ $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) --tailcalls+ --keyfile:$(ProjectDir)..\Build\Infrastructure.snk @@ -41,7 +48,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -63,6 +70,7 @@ + contentfiles diff --git a/AltCover.Recorder.Tests/Adapter.fs b/AltCover.Recorder.Tests/Adapter.fs index c00d761f8..c5f52d005 100644 --- a/AltCover.Recorder.Tests/Adapter.fs +++ b/AltCover.Recorder.Tests/Adapter.fs @@ -166,6 +166,18 @@ module Adapter = | _ -> x.Message = unique Instance.I.issue71Wrapper () () () () catcher pitcher + + let internal invokeCurriedIssue71Wrapper<'T when 'T :> System.Exception> + (unique: string) = + let constructor = + typeof<'T>.GetConstructor ([| typeof |]) + + let pitcher = + fun _ _ _ _ -> + constructor.Invoke([| unique |]) :?> System.Exception + |> raise + + Instance.I.curriedIssue71Wrapper "a" "b" "c" "d" pitcher let internal tracePush (a, b, c) = Instance.I.trace.Push a b c //let LogException (a, b, c, d) = Instance.I.logException a b c d diff --git a/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj b/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj index acebd3059..95563157c 100644 --- a/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj +++ b/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj @@ -1,7 +1,7 @@  - net5.0;net472;net20 + net6.0;net472;net20 false AltCover.Recorder.Tests false @@ -12,6 +12,8 @@ NU1702 NU1702 Major + false + false @@ -31,7 +33,7 @@ - + @@ -47,11 +49,11 @@ all runtime; build; native; contentfiles; analyzers - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -73,7 +75,8 @@ - + + contentfiles diff --git a/AltCover.Recorder.Tests/Recorder.Tests.fs b/AltCover.Recorder.Tests/Recorder.Tests.fs index b6f7a3fa8..e85e57678 100644 --- a/AltCover.Recorder.Tests/Recorder.Tests.fs +++ b/AltCover.Recorder.Tests/Recorder.Tests.fs @@ -378,6 +378,34 @@ module AltCoverTests = let third = Directory.GetFiles(where, "*.exn") Assert.That(third.Length, Is.EqualTo before.Length) + + [] + let WrappedExceptionLoggedToFile () = + let path = Instance.ReportFile |> Path.GetFullPath + let where = path |> Path.GetDirectoryName + let before = Directory.GetFiles(where, "*.exn") + let unique = System.Guid.NewGuid().ToString() + Adapter.invokeCurriedIssue71Wrapper unique + let after = Directory.GetFiles(where, "*.exn") + Assert.That(after.Length, Is.GreaterThan before.Length) + let all = HashSet(after) + strip before all + Assert.That(all.Count, Is.EqualTo 1) + let file = all |> Seq.head + let lines = file |> File.ReadAllLines + File.Delete file + Assert.That(lines.Length, Is.GreaterThan 4) + + lines + |> Seq.take 4 + |> Seq.zip [ "ModuleId = \"b\"" + "hitPointId = \"c\"" + "context = \"d\"" + "exception = System.NullReferenceException: " + unique ] + |> Seq.iter (fun (a, b) -> Assert.That(b, Is.EqualTo a)) + + let third = Directory.GetFiles(where, "*.exn") + Assert.That(third.Length, Is.EqualTo before.Length) [] let Issue71WrapperHandlesKeyNotFoundException () = diff --git a/AltCover.Recorder.Tests/SimpleCoverage.xml b/AltCover.Recorder.Tests/SimpleCoverage.xml index eaa60aa66..2faac0e78 100644 --- a/AltCover.Recorder.Tests/SimpleCoverage.xml +++ b/AltCover.Recorder.Tests/SimpleCoverage.xml @@ -14,5 +14,6 @@ + \ No newline at end of file diff --git a/AltCover.Recorder.sln b/AltCover.Recorder.sln index cc902f5ff..b0dae13ae 100644 --- a/AltCover.Recorder.sln +++ b/AltCover.Recorder.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29318.209 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.Recorder", "AltCover.Recorder\AltCover.Recorder.fsproj", "{85B49E3C-F5B0-40F5-8DB5-1464BEC10E3A}" EndProject diff --git a/AltCover.Recorder/AltCover.Recorder.fsproj b/AltCover.Recorder/AltCover.Recorder.fsproj index 983ae226e..8675ef4ec 100644 --- a/AltCover.Recorder/AltCover.Recorder.fsproj +++ b/AltCover.Recorder/AltCover.Recorder.fsproj @@ -6,15 +6,14 @@ AltCover.Recorder false true - true - true + false + false $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ $(SolutionDir)_Intermediate/$(AssemblyName)/$(Configuration)+$(Platform)/ false - true TRACE --keyfile:$(ProjectDir)..\Build\Infrastructure.snk --standalone --staticlink:ICSharpCode.SharpZipLib @@ -44,7 +43,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -56,6 +55,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -65,6 +65,7 @@ + diff --git a/AltCover.Recorder/Base.fs b/AltCover.Recorder/Base.fs index 66731bbd3..325c551e6 100644 --- a/AltCover.Recorder/Base.fs +++ b/AltCover.Recorder/Base.fs @@ -169,10 +169,10 @@ module internal Counter = | ReportFormat.OpenCover -> openCoverXml | ReportFormat.NCover -> nCoverXml | _ -> - format - |> (sprintf "%A") - |> NotSupportedException - |> raise + raise ( + format + |> (sprintf "%A") + |> NotSupportedException) let internal minTime (t1: DateTime) (t2: DateTime) = if t1 < t2 then t1 else t2 diff --git a/AltCover.Recorder/Recorder.fs b/AltCover.Recorder/Recorder.fs index 0b0bd4f72..4278dbb6b 100644 --- a/AltCover.Recorder/Recorder.fs +++ b/AltCover.Recorder/Recorder.fs @@ -324,13 +324,19 @@ module Instance = | :? ArgumentNullException -> handler moduleId hitPointId context x | _ -> reraise () + let +#if !DEBUG + inline +#endif + internal curriedIssue71Wrapper visits moduleId hitPointId context add = + issue71Wrapper visits moduleId hitPointId context logException add + let internal addVisit moduleId hitPointId context = - issue71Wrapper + curriedIssue71Wrapper visits moduleId hitPointId context - logException Counter.addSingleVisit let internal takeSample strategy moduleId hitPointId (context: Track) = diff --git a/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj b/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj index 5a016f0cf..2ac7b8133 100644 --- a/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj +++ b/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 false AltCover.Recorder2.Tests false @@ -12,6 +12,8 @@ NU1702 NU1702 Major + false + false @@ -41,17 +43,18 @@ all runtime; build; native; contentfiles; analyzers - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + contentfiles diff --git a/AltCover.Tests/AltCover.Tests.fsproj b/AltCover.Tests/AltCover.Tests.fsproj index f63ec256f..56d74603c 100644 --- a/AltCover.Tests/AltCover.Tests.fsproj +++ b/AltCover.Tests/AltCover.Tests.fsproj @@ -1,7 +1,7 @@  - net5.0;net472 + net6.0;net472 false AltCover.Tests MONO @@ -13,7 +13,7 @@ --keyfile:$(ProjectDir)..\Build\Infrastructure.snk - + 3239;0058 @@ -48,6 +48,7 @@ + @@ -55,7 +56,16 @@ + + + + + + + + + @@ -82,6 +92,9 @@ + + AltCover.Recorder.net20.dll + @@ -104,12 +117,9 @@ - - $(ProjectDir)..\_Binaries\AltCover.Recorder\$(Configuration)+$(Platform)\net20\AltCover.Recorder.dll - - + ..\ThirdParty\Unquote.dll @@ -126,11 +136,12 @@ - + - + + contentfiles diff --git a/AltCover.Tests/AltCoverFSharpTypes.n3.xml b/AltCover.Tests/AltCoverFSharpTypes.n3.xml index bf954caf6..1797ef0ec 100644 --- a/AltCover.Tests/AltCoverFSharpTypes.n3.xml +++ b/AltCover.Tests/AltCoverFSharpTypes.n3.xml @@ -1,9 +1,9 @@  - + - + ./_Binaries/Sample4/Debug+AnyCPU/netcoreapp2.1/Sample4.dll 2018-06-13T15:08:24.8840000Z Sample4 @@ -21,10 +21,10 @@ System.Int32 Tests.Program::main(System.String[]) - + - + @@ -61,11 +61,11 @@ - - - - - + + + + + @@ -73,27 +73,26 @@ - + Tests.DU/MyUnion - - + + 100663319 Tests.DU/MyUnion Tests.DU/MyUnion::as_bar() - - - - - - - - - + + + + + + + + - + @@ -101,10 +100,10 @@ Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Tests.DU/MyUnion> Tests.DU/MyUnion::get_MyBar() - + - + @@ -118,10 +117,10 @@ Tests.DU/MyUnion Tests.DU/get_MyBar@44::Invoke(Microsoft.FSharp.Core.Unit) - + - + @@ -135,11 +134,11 @@ System.Void Tests.DU/MyClass::.ctor() - - + + - + @@ -153,10 +152,10 @@ Tests.M/Thing Tests.M::makeThing(System.String) - + - + @@ -164,13 +163,13 @@ System.Void Tests.M::testMakeThing() - - - - + + + + - + @@ -184,10 +183,10 @@ System.Byte[] Tests.M/Thing::bytes() - + - + diff --git a/AltCover.Tests/CppInlineWithOpenCover.xml b/AltCover.Tests/CppInlineWithOpenCover.xml new file mode 100644 index 000000000..aa0a1c7f2 --- /dev/null +++ b/AltCover.Tests/CppInlineWithOpenCover.xml @@ -0,0 +1,1757 @@ + + + + + + C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll + 2021-08-04T01:00:24Z + mscorlib + + + + + C:\Users\steve\Documents\GitHub\altcover\Samples\Sample29\Debug\SimpleMix.exe + 2021-10-30T13:04:37.9842657Z + SimpleMix + + + + + + + + + + + + + + + + <Module> + + + + 100663297 + System.Int32 <Module>::main(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + + 100663298 + System.Void <Module>::<CrtImplementationDetails>.ThrowNestedModuleLoadException(System.Exception,System.Exception) + + + + + + + + + + + 100663299 + System.Void <Module>::<CrtImplementationDetails>.ThrowModuleLoadException(System.String) + + + + + + + + + + + 100663300 + System.Void <Module>::<CrtImplementationDetails>.ThrowModuleLoadException(System.String,System.Exception) + + + + + + + + + + + 100663301 + System.Void <Module>::<CrtImplementationDetails>.RegisterModuleUninitializer(System.EventHandler) + + + + + + + + + + + 100663302 + System.Guid <Module>::<CrtImplementationDetails>.FromGUID(_GUID modopt(System.Runtime.CompilerServices.IsConst)* modopt(System.Runtime.CompilerServices.IsImplicitlyDereferenced)) + + + + + + + + + + + 100663303 + System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__get_default_appdomain(IUnknown**) + + + + + + + + + + + + + + + + + + + + + + + + + 100663304 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__release_appdomain(IUnknown*) + + + + + + + + + + + 100663305 + System.AppDomain <Module>::<CrtImplementationDetails>.GetDefaultDomain() + + + + + + + + + + + + + + + + + + + + + + + + + + 100663306 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DoCallBackInDefaultDomain(method System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall) *(System.Void*),System.Void*) + + + + + + + + + + + + + + + + + + + + + + + + 100663307 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__scrt_is_safe_for_managed_code() + + + + + + + + + + + + + + + + + + 100663308 + System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall) <Module>::<CrtImplementationDetails>.DefaultDomain.DoNothing(System.Void*) + + + + + + + + + + + + 100663309 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.HasPerProcess() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663310 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.HasNative() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663311 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.NeedsInitialization() + + + + + + + + + + + + + + + + + + + + + + 100663312 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.NeedsUninitialization() + + + + + + + + + + + 100663313 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.Initialize() + + + + + + + + + + + 100663314 + System.Void <Module>::?A0x5ea2bff1.??__E?Initialized@CurrentDomain@<CrtImplementationDetails>@@$$Q2HA@@YMXXZ() + + + + + + + + + + 100663315 + System.Void <Module>::?A0x5ea2bff1.??__E?Uninitialized@CurrentDomain@<CrtImplementationDetails>@@$$Q2HA@@YMXXZ() + + + + + + + + + + 100663316 + System.Void <Module>::?A0x5ea2bff1.??__E?IsDefaultDomain@CurrentDomain@<CrtImplementationDetails>@@$$Q2_NA@@YMXXZ() + + + + + + + + + + 100663317 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedVtables@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663318 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedNative@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663319 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedPerProcess@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663320 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedPerAppDomain@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663321 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeVtables(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + 100663322 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeDefaultAppDomain(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + 100663323 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeNative(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663324 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializePerProcess(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + 100663325 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializePerAppDomain(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + 100663326 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeUninitializer(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + 100663327 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport._Initialize(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663328 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.LanguageSupport.UninitializeAppDomain() + + + + + + + + + + + 100663329 + System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall) <Module>::<CrtImplementationDetails>.LanguageSupport._UninitializeDefaultDomain(System.Void*) + + + + + + + + + + + + + + + + + + + + + + 100663330 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.LanguageSupport.UninitializeDefaultDomain() + + + + + + + + + + + + + + + + + + + + 100663331 + System.Void <Module>::<CrtImplementationDetails>.LanguageSupport.DomainUnload(System.Object,System.EventArgs) + + + + + + + + + + + + + + + + + + + + + + + + 100663332 + System.Void <Module>::<CrtImplementationDetails>.LanguageSupport.Cleanup(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst),System.Exception) + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663333 + <CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.{ctor}(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + 100663334 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.{dtor}(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + 100663335 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.Initialize(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663336 + System.Void <Module>::.cctor() + + + + + + + + + + + + 100663337 + System.String <Module>::gcroot<System::String ^>..P$AAVString@System@@(gcroot<System::String ^> modopt(System.Runtime.CompilerServices.IsConst)* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + 100663338 + gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsImplicitlyDereferenced) <Module>::gcroot<System::String ^>.=(gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst),System.String) + + + + + + + + + + + + 100663339 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::gcroot<System::String ^>.{dtor}(gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + 100663340 + gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::gcroot<System::String ^>.{ctor}(gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + 100663341 + System.Int32 <Module>::mainCRTStartupStrArray(System.String[]) + + + + + + + + + + + + + + + + + + 100663342 + System.Void <Module>::?A0x61adbb31.__set_managed_app_type() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663343 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::?A0x61adbb31._common_init() + + + + + + + + + + + + + + 100663344 + System.ValueType modopt(System.Runtime.InteropServices.GCHandle) modopt(System.Runtime.CompilerServices.IsBoxed) <Module>::<CrtImplementationDetails>.AtExitLock._handle() + + + + + + + + + + + + + + + + 100663345 + System.Void <Module>::<CrtImplementationDetails>.AtExitLock._lock_Construct(System.Object) + + + + + + + + + + + + 100663346 + System.Void <Module>::<CrtImplementationDetails>.AtExitLock._lock_Set(System.Object) + + + + + + + + + + + + + + + + + + + + 100663347 + System.Object <Module>::<CrtImplementationDetails>.AtExitLock._lock_Get() + + + + + + + + + + + + + + + + + + 100663348 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock._lock_Destruct() + + + + + + + + + + + + + + + + + + 100663349 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock.IsInitialized() + + + + + + + + + + + + + + 100663350 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock.AddRef() + + + + + + + + + + + + + + + + + 100663351 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock.RemoveRef() + + + + + + + + + + + + + + + + + + + 100663352 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::?A0x6adf33d6.__alloc_global_lock() + + + + + + + + + + + + 100663353 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::?A0x6adf33d6.__dealloc_global_lock() + + + + + + + + + + + 100663354 + System.Void <Module>::_exit_callback() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663355 + System.Int32 <Module>::_initatexit_m() + + + + + + + + + + + + + + + + + + + + + 100663356 + System.Int32 <Module>::_initatexit_app_domain() + + + + + + + + + + + + + + + + + + 100663357 + System.Void <Module>::_app_exit_callback() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663358 + System.Void* <Module>::DecodePointer(System.Void*) + + + + + 100663359 + System.Void* <Module>::EncodePointer(System.Void*) + + + + + + 100663360 + System.Int32 <Module>::_initterm_e(method System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*,method System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*) + + + + + + + + + + + + + + + + + + + + + + + + 100663361 + System.Void <Module>::_initterm(method System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*,method System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*) + + + + + + + + + + + + + + + + + + + + 100663362 + System.ModuleHandle <Module>::<CrtImplementationDetails>.ThisModule.Handle() + + + + + + + + + + + 100663363 + System.Void <Module>::_initterm_m(method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *() modopt(System.Runtime.CompilerServices.IsConst)*,method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *() modopt(System.Runtime.CompilerServices.IsConst)*) + + + + + + + + + + + + + + + + + + + + + 100663364 + method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *() <Module>::<CrtImplementationDetails>.ThisModule.ResolveMethod<void const * __clrcall(void)>(method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *()) + + + + + + + + + + + 100663365 + System.Void <Module>::___CxxCallUnwindDtor(method System.Void *(System.Void*),System.Void*) + + + + + + + + + + + + 100663366 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::NativeCountVowels(System.Char*) + + + + + 100663367 + System.Void* modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_getFiberPtrId() + + + + + 100663368 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_cexit() + + + + + 100663369 + System.Void modopt(System.Runtime.CompilerServices.CallConvStdcall) <Module>::Sleep(System.UInt32 modopt(System.Runtime.CompilerServices.IsLong)) + + + + + 100663370 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::abort() + + + + + 100663371 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__security_init_cookie() + + + + + 100663372 + _crt_argv_mode modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_get_startup_argv_mode() + + + + + 100663373 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_set_fmode(System.Int32) + + + + + 100663374 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_get_startup_file_mode() + + + + + 100663375 + System.Char** modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_get_initial_wide_environment() + + + + + 100663376 + HINSTANCE__* modopt(System.Runtime.CompilerServices.CallConvStdcall) <Module>::GetModuleHandleW(System.Char modopt(System.Runtime.CompilerServices.IsConst)*) + + + + + 100663377 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_configure_wide_argv(_crt_argv_mode) + + + + + 100663378 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_get_startup_thread_locale_mode() + + + + + 100663379 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_configthreadlocale(System.Int32) + + + + + 100663380 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_get_startup_new_mode() + + + + + 100663381 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_set_app_type(_crt_app_type) + + + + + 100663382 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_get_startup_commit_mode() + + + + + 100663383 + System.Int32* modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__p__commode() + + + + + 100663384 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_seh_filter_exe(System.UInt32 modopt(System.Runtime.CompilerServices.IsLong),_EXCEPTION_POINTERS*) + + + + + 100663385 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::_set_new_mode(System.Int32) + + + + + 100663386 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__FrameUnwindFilter(_EXCEPTION_POINTERS*) + + + + + + + + Example + + + + 100663387 + System.Int32 Example::main(System.String[]) + + + + + + + + + + + + + + + + + + + + 100663388 + System.Void Example::.ctor() + + + + + + + + + <CrtImplementationDetails>.ModuleLoadException + + + + 100663389 + System.Void <CrtImplementationDetails>.ModuleLoadException::.ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext) + + + + + + + + + + + 100663390 + System.Void <CrtImplementationDetails>.ModuleLoadException::.ctor(System.String,System.Exception) + + + + + + + + + + + 100663391 + System.Void <CrtImplementationDetails>.ModuleLoadException::.ctor(System.String) + + + + + + + + + + + + + <CrtImplementationDetails>.ModuleLoadExceptionHandlerException + + + + 100663394 + System.Exception <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::get_NestedException() + + + + + + + + + + 100663395 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::set_NestedException(System.Exception) + + + + + + + + + + 100663392 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::.ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext) + + + + + + + + + + + + 100663393 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::.ctor(System.String,System.Exception,System.Exception) + + + + + + + + + + + + 100663396 + System.String <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::ToString() + + + + + + + + + + + + + + + + + + + + + + + + + + 100663397 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext) + + + + + + + + + + + + + + <CrtImplementationDetails>.ModuleUninitializer + + + + 100663398 + System.Void <CrtImplementationDetails>.ModuleUninitializer::AddHandler(System.EventHandler) + + + + + + + + + + + + + + + + + + + + + + + 100663399 + System.Void <CrtImplementationDetails>.ModuleUninitializer::.cctor() + + + + + + + + + + + + 100663400 + System.Void <CrtImplementationDetails>.ModuleUninitializer::.ctor() + + + + + + + + + + + + + + 100663401 + System.Void <CrtImplementationDetails>.ModuleUninitializer::SingletonDomainUnload(System.Object,System.EventArgs) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll + 2021-04-08T04:26:00.6371167Z + System + + + + \ No newline at end of file diff --git a/AltCover.Tests/Expecto.fs b/AltCover.Tests/Expecto.fs index bcd82b831..9771f632c 100644 --- a/AltCover.Tests/Expecto.fs +++ b/AltCover.Tests/Expecto.fs @@ -230,10 +230,16 @@ module ExpectoTestManifest = "Runner.DegenerateCasesShouldNotGenerateLcov" Tests.AltCoverRunnerTests.OpenCoverShouldGeneratePlausibleLcov, "Runner.OpenCoverShouldGeneratePlausibleLcov" + Tests.AltCoverRunnerTests.OpenCoverWithPartialsShouldGeneratePlausibleLcov, + "Runner.OpenCoverWithPartialsShouldGeneratePlausibleLcov" Tests.AltCoverRunnerTests.JsonShouldGeneratePlausibleLcov, "Runner.JsonShouldGeneratePlausibleLcov" + Tests.AltCoverRunnerTests.JsonWithPartialsShouldGeneratePlausibleLcov, + "Runner.JsonWithPartialsShouldGeneratePlausibleLcov" Tests.AltCoverRunnerTests.NCoverShouldGeneratePlausibleLcov, "Runner.NCoverShouldGeneratePlausibleLcov" + Tests.AltCoverRunnerTests.NCoverWithPartialsShouldGeneratePlausibleLcov, + "Runner.NCoverWithPartialsShouldGeneratePlausibleLcov" Tests.AltCoverRunnerTests.NCoverShouldGenerateMorePlausibleLcov, "Runner.NCoverShouldGenerateMorePlausibleLcov" Tests.AltCoverRunnerTests.NCoverShouldGeneratePlausibleLcovWithMissingFullName, @@ -241,12 +247,18 @@ module ExpectoTestManifest = Tests.AltCoverRunnerTests.MultiSortDoesItsThing, "Runner.MultiSortDoesItsThing" Tests.AltCoverRunnerTests.JsonShouldGeneratePlausibleXml, "Runner.JsonShouldGeneratePlausibleXml" + Tests.AltCoverRunnerTests.JsonWithPartialsShouldGeneratePlausibleXml, + "Runner.JsonWithPartialsShouldGeneratePlausibleXml" Tests.AltCoverRunnerTests.JsonShouldGeneratePlausibleCobertura, "Runner.JsonShouldGeneratePlausibleCobertura" + Tests.AltCoverRunnerTests.JsonWithPartialsShouldGeneratePlausibleCobertura, + "Runner.JsonWithPartialsShouldGeneratePlausibleCobertura" Tests.AltCoverRunnerTests.JsonFromComplexNestingShouldGeneratePlausibleCobertura, "Runner.JsonFromComplexNestingShouldGeneratePlausibleCobertura" Tests.AltCoverRunnerTests.NCoverShouldGeneratePlausibleCobertura, "Runner.NCoverShouldGeneratePlausibleCobertura" + Tests.AltCoverRunnerTests.NCoverWithPartialsShouldGeneratePlausibleCobertura, + "Runner.NCoverWithPartialsShouldGeneratePlausibleCobertura" Tests.AltCoverRunnerTests.NCoverShouldGenerateMorePlausibleCobertura, "Runner.NCoverShouldGenerateMorePlausibleCobertura" Tests.AltCoverRunnerTests.DegenerateCasesShouldNotGenerateCobertura, @@ -255,6 +267,8 @@ module ExpectoTestManifest = "Runner.NCoverShouldGeneratePlausibleCoberturaWithMissingFullName" Tests.AltCoverRunnerTests.OpenCoverShouldGeneratePlausibleCobertura, "Runner.OpenCoverShouldGeneratePlausibleCobertura" + Tests.AltCoverRunnerTests.OpenCoverWithPartialsShouldGeneratePlausibleCobertura, + "Runner.OpenCoverWithPartialsShouldGeneratePlausibleCobertura" Tests.AltCoverRunnerTests.ThresholdViolationShouldBeReported, "Runner.ThresholdViolationShouldBeReported" Tests.AltCoverRunnerTests.TryGetValueHandlesNull, "Runner.TryGetValueHandlesNull" @@ -395,8 +409,16 @@ module ExpectoTestManifest = Tests.AltCoverTests.FullMethodNamesAreExtracted, "Tests.FullMethodNamesAreExtracted" Tests.AltCoverTests.ShouldGenerateExpectedXmlReportFromDotNet, "Tests.ShouldGenerateExpectedXmlReportFromDotNet" + Tests.AltCoverTests.ShouldGenerateExpectedXmlReportWithEmbeds, + "Tests.ShouldGenerateExpectedXmlReportFromWithEmbeds" + Tests.AltCoverTests.ShouldGenerateExpectedXmlReportWithPartials, + "Tests.ShouldGenerateExpectedXmlReportFromWithPartials" Tests.AltCoverTests.ShouldGenerateExpectedJsonReportFromDotNet, "Tests.ShouldGenerateExpectedJsonReportFromDotNet" + Tests.AltCoverTests.ShouldGenerateExpectedJsonReportWithEmbeds, + "Tests.ShouldGenerateExpectedJsonReportWithEmbeds" + Tests.AltCoverTests.ShouldGenerateExpectedJsonReportWithPartials, + "Tests.ShouldGenerateExpectedJsonReportWithPartials" Tests.AltCoverTests.ShouldGenerateExpectedXmlReportForNCoverWithMethodPointOnly, "Tests.ShouldGenerateExpectedXmlReportForNCoverWithMethodPointOnly" Tests.AltCoverTests.ShouldGenerateExpectedXmlReportForNCoverWithTopLevel, @@ -421,6 +443,10 @@ module ExpectoTestManifest = "Tests.ShouldGenerateExpectedXmlReportWithSourceLinkOpenCoverStyle" Tests.AltCoverTests.ShouldGenerateExpectedXmlReportFromDotNetOpenCoverStyle, "Tests.ShouldGenerateExpectedXmlReportFromDotNetOpenCoverStyle" + Tests.AltCoverTests.ShouldGenerateExpectedXmlReportWithEmbedsOpenCoverStyle, + "Tests.ShouldGenerateExpectedXmlReportWithEmbedsOpenCoverStyle" + Tests.AltCoverTests.ShouldGenerateExpectedXmlReportWithPartialsOpenCoverStyle, + "Tests.ShouldGenerateExpectedXmlReportWithPartialsOpenCoverStyle" Tests.AltCoverTests.ShouldGenerateExpectedXmlReportFromDotNetLineCoverStyle, "Tests.ShouldGenerateExpectedXmlReportFromDotNetLineCoverStyle" Tests.AltCoverTests.ShouldGenerateExpectedXmlReportFromDotNetBranchCoverStyle, diff --git a/AltCover.Tests/HandRolledMonoCoverage.lcov b/AltCover.Tests/HandRolledMonoCoverage.lcov index e98570753..dc32af3c9 100644 --- a/AltCover.Tests/HandRolledMonoCoverage.lcov +++ b/AltCover.Tests/HandRolledMonoCoverage.lcov @@ -1,4 +1,4 @@ -TN: +TN: Sample1 SF:altcover/Sample1/Program.cs FN:11,System.Void TouchTest.Program::Main(System.String[]) FNDA:1,System.Void TouchTest.Program::Main(System.String[]) @@ -10,9 +10,9 @@ BRF:2 BRH:1 DA:11,1 DA:12,1 -DA:13,2 +DA:13,1 DA:14,1 -DA:15,3 +DA:15,1 DA:16,1 DA:18,0 DA:19,0 diff --git a/AltCover.Tests/HandRolledMonoCoverage.xml b/AltCover.Tests/HandRolledMonoCoverage.xml index d91fee450..21182ecf8 100644 --- a/AltCover.Tests/HandRolledMonoCoverage.xml +++ b/AltCover.Tests/HandRolledMonoCoverage.xml @@ -8,7 +8,7 @@ 2018-02-23T19:05:36.7253612Z Sample1 - + diff --git a/AltCover.Tests/HandRolledToNCover.json b/AltCover.Tests/HandRolledToNCover.json new file mode 100644 index 000000000..519a1def8 --- /dev/null +++ b/AltCover.Tests/HandRolledToNCover.json @@ -0,0 +1,157 @@ +{ + "Sample1.exe": { + "altcover/Sample1/Program.cs": { + "\u00ABAltCover.embed\u00BB": { + "hU9NS8NAED0nkP/wzKnVkgavRT3Uk6gIDRQRD2ucJkuTnTC7SQjS/\u002B5mq\u002BDNwwzDvI9501ttKuwm66jdJHESr9dwZB064UpUGxYHFgh1LA4VGRLlNJuZbFRLtlMloeC\u002BrAsvTOKvJI60cSRGNSgbZS1efs2iGYw60YNyBOu8U4mB9SeelDYL68THeXuHksouZ2rgR4MSGB5xg3uvK3RL2TOPm4DpAxYey17Jk25xned5UP5Ioy0byw1le9GOHrWhRbqvSQjaop0gXB7Jv6vK4x1SXGEXMmQP7POkl\u002BnqnGV5PnYKnRpL/5woRjJOk6ux9UMv0wofPF2kf33m5uv0DQ==": { + "Lines": {}, + "Branches": [] + } + }, + "TouchTest.Program": { + "ReturnType1 TouchTest.Program::Main(Argument List1)": { + "Lines": { + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "18": 0, + "19": 0, + "20": 0, + "21": 1 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 11, + "SC": 3, + "EL": 11, + "EC": 4, + "Offset": 0, + "Id": 0 + }, + { + "VC": 1, + "SL": 12, + "SC": 23, + "EL": 12, + "EC": 24, + "Offset": 1, + "Id": 0 + }, + { + "VC": 1, + "SL": 13, + "SC": 4, + "EL": 13, + "EC": 5, + "Offset": 7, + "Id": 0 + }, + { + "VC": 1, + "SL": 13, + "SC": 12, + "EL": 13, + "EC": 13, + "Offset": 9, + "Id": 0 + }, + { + "VC": 1, + "SL": 14, + "SC": 4, + "EL": 14, + "EC": 5, + "Offset": 24, + "Id": 0 + }, + { + "VC": 1, + "SL": 15, + "SC": 5, + "EL": 15, + "EC": 6, + "Offset": 25, + "Id": 0 + }, + { + "VC": 1, + "SL": 15, + "SC": 60, + "EL": 15, + "EC": 61, + "Offset": 36, + "Id": 0 + }, + { + "VC": 1, + "SL": 15, + "SC": 13, + "EL": 15, + "EC": 14, + "Offset": 46, + "Id": 0 + }, + { + "VC": 1, + "SL": 16, + "SC": 4, + "EL": 16, + "EC": 5, + "Offset": 51, + "Id": 0 + }, + { + "VC": 0, + "SL": 18, + "SC": 4, + "EL": 18, + "EC": 5, + "Offset": 57, + "Id": 0 + }, + { + "VC": 0, + "SL": 19, + "SC": 5, + "EL": 19, + "EC": 6, + "Offset": 58, + "Id": 0 + }, + { + "VC": 0, + "SL": 19, + "SC": 13, + "EL": 19, + "EC": 14, + "Offset": 63, + "Id": 0 + }, + { + "VC": 0, + "SL": 20, + "SC": 4, + "EL": 20, + "EC": 5, + "Offset": 68, + "Id": 0 + }, + { + "VC": 1, + "SL": 21, + "SC": 3, + "EL": 21, + "EC": 4, + "Offset": 69, + "Id": 0 + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/AltCover.Tests/HandRolledToNCover.xml b/AltCover.Tests/HandRolledToNCover.xml index c0809b927..d0294c03a 100644 Binary files a/AltCover.Tests/HandRolledToNCover.xml and b/AltCover.Tests/HandRolledToNCover.xml differ diff --git a/AltCover.Tests/JsonFromNCoverWithPartials.json b/AltCover.Tests/JsonFromNCoverWithPartials.json new file mode 100644 index 000000000..df1f7b1ca --- /dev/null +++ b/AltCover.Tests/JsonFromNCoverWithPartials.json @@ -0,0 +1,331 @@ +{ + "SimpleMix.exe": { + "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/include/vcclr.h": { + "\u003CModule\u003E": { + "System.Int32 \u003CModule\u003E::main(System.String[])": { + "Lines": { + "41": 1, + "42": 1, + "43": 1 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 41, + "SC": 0, + "EL": 41, + "EC": 0, + "Offset": 20, + "Id": 0 + }, + { + "VC": 1, + "SL": 42, + "SC": 0, + "EL": 42, + "EC": 0, + "Offset": 22, + "Id": 0 + }, + { + "VC": 1, + "SL": 43, + "SC": 0, + "EL": 43, + "EC": 0, + "Offset": 25, + "Id": 0 + } + ] + } + }, + "Example": { + "System.Int32 Example::main(System.String[])": { + "Lines": { + "41": 1, + "42": 1, + "43": 1 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 41, + "SC": 0, + "EL": 41, + "EC": 0, + "Offset": 12, + "Id": 0 + }, + { + "VC": 1, + "SL": 42, + "SC": 0, + "EL": 42, + "EC": 0, + "Offset": 14, + "Id": 0 + }, + { + "VC": 1, + "SL": 43, + "SC": 0, + "EL": 43, + "EC": 0, + "Offset": 17, + "Id": 0 + } + ] + } + } + }, + "C:/Users/steve/Documents/GitHub/altcover/Samples/Sample29/SimpleMix/SimpleMix.cpp": { + "\u00ABAltCover.embed\u00BB": { + "1ZJBb9swDIXvBvwfOO9iN0Xas5sGGIweCgTb0HbbrQGrMLEGWxIouUlR5L\u002BPlpKmwDCg11104Ht8Ij/p4gKaxV2DXUc8Vc5BDT1qA47tb1IB1rqjaZ7l2WdtVDesCAofVrjeTdsilh3jpkcYTI8GN7TKM20CfMWgn6mxgwk/7ZY6X25Vi7wMZ\u002BDuA2uzqfLsNc8ARrcafXANl1djRVnjA7z5n2O/qIsCSdvhy83ttx9FdG5bmQ7Ks1MkQAyV2DXIlV61XKaAczjaJpOqSiZIN08mMW0/HkxhYJPqUt2fNnzbL88GLzFgsCfvUBHcv/hA/dUoMa1Bdeg93OywdzKeDOSGp06resz3QciouPXIuURmfJmlgLpOAz7OHwF549/vc1CknwVF8UC7AMHCE0GLvqVVAgLQCDzbUV3/Yh1ooQ2V0lIdVKfN0gWeNcJ2Dg6uTxyE\u002BVKhDzMZjVhbPhnnUB59AN8DP9g0zSj6GF/9\u002B/a/f4KL9tRwwH15fIB9VD5KJ30geelPR9p1fegT/T2\u002BD/P77wH\u002BAQ==": { + "Lines": {}, + "Branches": [] + } + }, + "\u003CModule\u003E": { + "System.Int32 \u003CModule\u003E::main(System.String[])": { + "Lines": { + "38": 1, + "40": 1, + "41": 1, + "42": 1, + "45": 1, + "47": 1, + "49": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 38, + "SC": 0, + "EL": 38, + "EC": 0, + "Offset": 0, + "Id": 0 + }, + { + "VC": 1, + "SL": 40, + "SC": 0, + "EL": 40, + "EC": 0, + "Offset": 8, + "Id": 0 + }, + { + "VC": 1, + "SL": 41, + "SC": 0, + "EL": 41, + "EC": 0, + "Offset": 14, + "Id": 0 + }, + { + "VC": 1, + "SL": 42, + "SC": 0, + "EL": 42, + "EC": 0, + "Offset": 33, + "Id": 0 + }, + { + "VC": 1, + "SL": 45, + "SC": 0, + "EL": 45, + "EC": 0, + "Offset": 35, + "Id": 0 + }, + { + "VC": 1, + "SL": 47, + "SC": 0, + "EL": 47, + "EC": 0, + "Offset": 46, + "Id": 0 + }, + { + "VC": 0, + "SL": 49, + "SC": 0, + "EL": 49, + "EC": 0, + "Offset": 48, + "Id": 0 + } + ] + } + }, + "Example": { + "System.Int32 Example::main(System.String[])": { + "Lines": { + "25": 1, + "26": 1, + "27": 1, + "30": 1, + "32": 1 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 25, + "SC": 0, + "EL": 25, + "EC": 0, + "Offset": 0, + "Id": 0 + }, + { + "VC": 1, + "SL": 26, + "SC": 0, + "EL": 26, + "EC": 0, + "Offset": 6, + "Id": 0 + }, + { + "VC": 1, + "SL": 27, + "SC": 0, + "EL": 27, + "EC": 0, + "Offset": 25, + "Id": 0 + }, + { + "VC": 1, + "SL": 30, + "SC": 0, + "EL": 30, + "EC": 0, + "Offset": 27, + "Id": 0 + }, + { + "VC": 1, + "SL": 32, + "SC": 0, + "EL": 32, + "EC": 0, + "Offset": 38, + "Id": 0 + } + ] + } + } + }, + "d:/a01/_work/5/s/src/vctools/crt/crtw32/msilcrt/mcrtexe.cpp": { + "\u003CModule\u003E": { + "System.Int32 \u003CModule\u003E::mainCRTStartupStrArray(System.String[])": { + "Lines": { + "223": 1, + "228": 1, + "241": 1, + "247": 1, + "278": 1, + "279": 0, + "284": 0, + "287": 1, + "288": 1 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 223, + "SC": 0, + "EL": 223, + "EC": 0, + "Offset": 0, + "Id": 0 + }, + { + "VC": 1, + "SL": 228, + "SC": 0, + "EL": 228, + "EC": 0, + "Offset": 11, + "Id": 0 + }, + { + "VC": 1, + "SL": 241, + "SC": 0, + "EL": 241, + "EC": 0, + "Offset": 22, + "Id": 0 + }, + { + "VC": 1, + "SL": 247, + "SC": 0, + "EL": 247, + "EC": 0, + "Offset": 28, + "Id": 0 + }, + { + "VC": 1, + "SL": 278, + "SC": 0, + "EL": 278, + "EC": 0, + "Offset": 35, + "Id": 0 + }, + { + "VC": 0, + "SL": 279, + "SC": 0, + "EL": 279, + "EC": 0, + "Offset": 37, + "Id": 0 + }, + { + "VC": 0, + "SL": 284, + "SC": 0, + "EL": 284, + "EC": 0, + "Offset": 56, + "Id": 0 + }, + { + "VC": 1, + "SL": 287, + "SC": 0, + "EL": 287, + "EC": 0, + "Offset": 64, + "Id": 0 + }, + { + "VC": 1, + "SL": 288, + "SC": 0, + "EL": 288, + "EC": 0, + "Offset": 66, + "Id": 0 + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/AltCover.Tests/JsonWithPartials.json b/AltCover.Tests/JsonWithPartials.json new file mode 100644 index 000000000..d995a407a --- /dev/null +++ b/AltCover.Tests/JsonWithPartials.json @@ -0,0 +1,388 @@ +{ + "SimpleMix.exe": { + "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/include/vcclr.h": { + "\u003CModule\u003E": { + "System.Int32 \u003CModule\u003E::main(System.String[])": { + "Lines": { + "41": 1, + "42": 1, + "43": 1 + }, + "Branches": [ + { + "Line": 42, + "Offset": 23, + "EndOffset": 25, + "Path": 0, + "Ordinal": 2, + "Hits": 1, + "Id": 13 + }, + { + "Line": 42, + "Offset": 23, + "EndOffset": 33, + "Path": 1, + "Ordinal": 3, + "Hits": 0, + "Id": 14 + } + ], + "SeqPnts": [ + { + "VC": 1, + "SL": 41, + "SC": 0, + "EL": 41, + "EC": 0, + "Offset": 20, + "Id": 4 + }, + { + "VC": 1, + "SL": 42, + "SC": 0, + "EL": 42, + "EC": 0, + "Offset": 22, + "Id": 5 + }, + { + "VC": 1, + "SL": 43, + "SC": 0, + "EL": 43, + "EC": 0, + "Offset": 25, + "Id": 6 + } + ] + } + }, + "Example": { + "System.Int32 Example::main(System.String[])": { + "Lines": { + "41": 1, + "42": 1, + "43": 1 + }, + "Branches": [ + { + "Line": 42, + "Offset": 15, + "EndOffset": 17, + "Path": 0, + "Ordinal": 0, + "Hits": 1, + "Id": 625 + }, + { + "Line": 42, + "Offset": 15, + "EndOffset": 25, + "Path": 1, + "Ordinal": 1, + "Hits": 0, + "Id": 626 + } + ], + "SeqPnts": [ + { + "VC": 1, + "SL": 41, + "SC": 0, + "EL": 41, + "EC": 0, + "Offset": 12, + "Id": 619 + }, + { + "VC": 1, + "SL": 42, + "SC": 0, + "EL": 42, + "EC": 0, + "Offset": 14, + "Id": 620 + }, + { + "VC": 1, + "SL": 43, + "SC": 0, + "EL": 43, + "EC": 0, + "Offset": 17, + "Id": 621 + } + ] + } + } + }, + "C:/Users/steve/Documents/GitHub/altcover/Samples/Sample29/SimpleMix/SimpleMix.cpp": { + "\u00ABAltCover.embed\u00BB": { + "1ZJBb9swDIXvBvwfOO9iN0Xas5sGGIweCgTb0HbbrQGrMLEGWxIouUlR5L\u002BPlpKmwDCg11104Ht8Ij/p4gKaxV2DXUc8Vc5BDT1qA47tb1IB1rqjaZ7l2WdtVDesCAofVrjeTdsilh3jpkcYTI8GN7TKM20CfMWgn6mxgwk/7ZY6X25Vi7wMZ\u002BDuA2uzqfLsNc8ARrcafXANl1djRVnjA7z5n2O/qIsCSdvhy83ttx9FdG5bmQ7Ks1MkQAyV2DXIlV61XKaAczjaJpOqSiZIN08mMW0/HkxhYJPqUt2fNnzbL88GLzFgsCfvUBHcv/hA/dUoMa1Bdeg93OywdzKeDOSGp06resz3QciouPXIuURmfJmlgLpOAz7OHwF549/vc1CknwVF8UC7AMHCE0GLvqVVAgLQCDzbUV3/Yh1ooQ2V0lIdVKfN0gWeNcJ2Dg6uTxyE\u002BVKhDzMZjVhbPhnnUB59AN8DP9g0zSj6GF/9\u002B/a/f4KL9tRwwH15fIB9VD5KJ30geelPR9p1fegT/T2\u002BD/P77wH\u002BAQ==": { + "Lines": {}, + "Branches": [] + } + }, + "\u003CModule\u003E": { + "System.Int32 \u003CModule\u003E::main(System.String[])": { + "Lines": { + "38": 1, + "40": 1, + "41": 1, + "42": 1, + "45": 1, + "47": 1, + "49": 0 + }, + "Branches": [ + { + "Line": 38, + "Offset": 6, + "EndOffset": 8, + "Path": 0, + "Ordinal": 0, + "Hits": 1, + "Id": 11 + }, + { + "Line": 38, + "Offset": 6, + "EndOffset": 48, + "Path": 1, + "Ordinal": 1, + "Hits": 0, + "Id": 12 + } + ], + "SeqPnts": [ + { + "VC": 1, + "SL": 38, + "SC": 0, + "EL": 38, + "EC": 0, + "Offset": 0, + "Id": 1 + }, + { + "VC": 1, + "SL": 40, + "SC": 0, + "EL": 40, + "EC": 0, + "Offset": 8, + "Id": 2 + }, + { + "VC": 1, + "SL": 41, + "SC": 0, + "EL": 41, + "EC": 0, + "Offset": 14, + "Id": 3 + }, + { + "VC": 1, + "SL": 42, + "SC": 0, + "EL": 42, + "EC": 0, + "Offset": 33, + "Id": 7 + }, + { + "VC": 1, + "SL": 45, + "SC": 0, + "EL": 45, + "EC": 0, + "Offset": 35, + "Id": 8 + }, + { + "VC": 1, + "SL": 47, + "SC": 0, + "EL": 47, + "EC": 0, + "Offset": 46, + "Id": 9 + }, + { + "VC": 0, + "SL": 49, + "SC": 0, + "EL": 49, + "EC": 0, + "Offset": 48, + "Id": 10 + } + ] + } + }, + "Example": { + "System.Int32 Example::main(System.String[])": { + "Lines": { + "25": 1, + "26": 1, + "27": 1, + "30": 1, + "32": 1 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 25, + "SC": 0, + "EL": 25, + "EC": 0, + "Offset": 0, + "Id": 617 + }, + { + "VC": 1, + "SL": 26, + "SC": 0, + "EL": 26, + "EC": 0, + "Offset": 6, + "Id": 618 + }, + { + "VC": 1, + "SL": 27, + "SC": 0, + "EL": 27, + "EC": 0, + "Offset": 25, + "Id": 622 + }, + { + "VC": 1, + "SL": 30, + "SC": 0, + "EL": 30, + "EC": 0, + "Offset": 27, + "Id": 623 + }, + { + "VC": 1, + "SL": 32, + "SC": 0, + "EL": 32, + "EC": 0, + "Offset": 38, + "Id": 624 + } + ] + } + } + }, + "d:/a01/_work/5/s/src/vctools/crt/crtw32/msilcrt/mcrtexe.cpp": { + "\u003CModule\u003E": { + "System.Int32 \u003CModule\u003E::mainCRTStartupStrArray(System.String[])": { + "Lines": { + "223": 1, + "228": 1, + "241": 1, + "247": 1, + "278": 1, + "279": 0, + "284": 0, + "287": 1, + "288": 1 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 1, + "SL": 223, + "SC": 0, + "EL": 223, + "EC": 0, + "Offset": 0, + "Id": 368 + }, + { + "VC": 1, + "SL": 228, + "SC": 0, + "EL": 228, + "EC": 0, + "Offset": 11, + "Id": 369 + }, + { + "VC": 1, + "SL": 241, + "SC": 0, + "EL": 241, + "EC": 0, + "Offset": 22, + "Id": 370 + }, + { + "VC": 1, + "SL": 247, + "SC": 0, + "EL": 247, + "EC": 0, + "Offset": 28, + "Id": 371 + }, + { + "VC": 1, + "SL": 278, + "SC": 0, + "EL": 278, + "EC": 0, + "Offset": 35, + "Id": 372 + }, + { + "VC": 0, + "SL": 279, + "SC": 0, + "EL": 279, + "EC": 0, + "Offset": 37, + "Id": 373 + }, + { + "VC": 0, + "SL": 284, + "SC": 0, + "EL": 284, + "EC": 0, + "Offset": 56, + "Id": 374 + }, + { + "VC": 1, + "SL": 287, + "SC": 0, + "EL": 287, + "EC": 0, + "Offset": 64, + "Id": 375 + }, + { + "VC": 1, + "SL": 288, + "SC": 0, + "EL": 288, + "EC": 0, + "Offset": 66, + "Id": 376 + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/AltCover.Tests/JsonWithPartialsToRawXml.xml b/AltCover.Tests/JsonWithPartialsToRawXml.xml new file mode 100644 index 000000000..ef4704615 --- /dev/null +++ b/AltCover.Tests/JsonWithPartialsToRawXml.xml @@ -0,0 +1,95 @@ + + + + + + + SimpleMix.exe + SimpleMix + + + + + + + + + <Module> + + + + 0 + System.Int32 <Module>::main(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + + 0 + System.Int32 <Module>::mainCRTStartupStrArray(System.String[]) + + + + + + + + + + + + + + + + + + + + Example + + + + 0 + System.Int32 Example::main(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/JsonWithPartialsToXml.xml b/AltCover.Tests/JsonWithPartialsToXml.xml new file mode 100644 index 000000000..ef5b95c0c --- /dev/null +++ b/AltCover.Tests/JsonWithPartialsToXml.xml @@ -0,0 +1,94 @@ + + + + + + SimpleMix.exe + SimpleMix + + + + + + + + + <Module> + + + + 0 + System.Int32 <Module>::main(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + + 0 + System.Int32 <Module>::mainCRTStartupStrArray(System.String[]) + + + + + + + + + + + + + + + + + + + + Example + + + + 0 + System.Int32 Example::main(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/NCover.lcov b/AltCover.Tests/NCover.lcov index e51078417..c81ba2493 100644 --- a/AltCover.Tests/NCover.lcov +++ b/AltCover.Tests/NCover.lcov @@ -1,4 +1,4 @@ -TN: +TN: Sample1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null SF:altcover\Sample1\Program.cs FN:11,System.Void TouchTest.Program.Main(System.String[]) FNDA:1,System.Void TouchTest.Program.Main(System.String[]) @@ -14,8 +14,8 @@ DA:15,1 DA:16,1 DA:18,0 DA:19,0 -DA:20,X +DA:20,0 DA:21,-1 -LH:8 +LH:7 LF:10 end_of_record diff --git a/AltCover.Tests/NCover122.xml b/AltCover.Tests/NCover122.xml index 7504adc2b..6e5a9df35 100644 --- a/AltCover.Tests/NCover122.xml +++ b/AltCover.Tests/NCover122.xml @@ -17,5 +17,6 @@ + \ No newline at end of file diff --git a/AltCover.Tests/NCoverBugFix.lcov b/AltCover.Tests/NCoverBugFix.lcov index add941c8f..a70d3437e 100644 --- a/AltCover.Tests/NCoverBugFix.lcov +++ b/AltCover.Tests/NCoverBugFix.lcov @@ -1,4 +1,4 @@ -TN: +TN: Sample1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null SF:Sample1/Program.cs FN:11,TouchTest.Program.Main FNDA:1,TouchTest.Program.Main diff --git a/AltCover.Tests/NCoverWithEmbeds.xml b/AltCover.Tests/NCoverWithEmbeds.xml new file mode 100644 index 000000000..367cccdc9 --- /dev/null +++ b/AltCover.Tests/NCoverWithEmbeds.xml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AltCover.Tests/NCoverWithPartials.cob.xml b/AltCover.Tests/NCoverWithPartials.cob.xml new file mode 100644 index 000000000..b26e853bd --- /dev/null +++ b/AltCover.Tests/NCoverWithPartials.cob.xml @@ -0,0 +1,119 @@ + + + + + C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/include + C:/Users/steve/Documents/GitHub/altcover/Samples/Sample29/SimpleMix + d:/a01/_work/5/s/src/vctools/crt/crtw32/msilcrt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/NCoverWithPartials.lcov b/AltCover.Tests/NCoverWithPartials.lcov new file mode 100644 index 000000000..1e2194115 --- /dev/null +++ b/AltCover.Tests/NCoverWithPartials.lcov @@ -0,0 +1,61 @@ +TN: SimpleMix, Version=1.0.7973.23538, Culture=neutral, PublicKeyToken=null +SF:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vcclr.h +FN:41,System.Int32 ::main(System.String[]) +FN:41,System.Int32 Example::main(System.String[]) +FNDA:1,System.Int32 ::main(System.String[]) +FNDA:1,System.Int32 Example::main(System.String[]) +FNF:2 +FNH:2 +BRF:0 +BRH:0 +DA:41,1 +DA:42,1 +DA:43,1 +LH:3 +LF:3 +end_of_record +TN: SimpleMix, Version=1.0.7973.23538, Culture=neutral, PublicKeyToken=null +SF:C:\Users\steve\Documents\GitHub\altcover\Samples\Sample29\SimpleMix\SimpleMix.cpp +FN:25,System.Int32 Example::main(System.String[]) +FN:38,System.Int32 ::main(System.String[]) +FNDA:1,System.Int32 Example::main(System.String[]) +FNDA:1,System.Int32 ::main(System.String[]) +FNF:2 +FNH:2 +BRF:0 +BRH:0 +DA:25,1 +DA:26,1 +DA:27,1 +DA:30,1 +DA:32,1 +DA:38,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:45,1 +DA:47,1 +DA:49,0 +LH:11 +LF:12 +end_of_record +TN: SimpleMix, Version=1.0.7973.23538, Culture=neutral, PublicKeyToken=null +SF:d:\a01\_work\5\s\src\vctools\crt\crtw32\msilcrt\mcrtexe.cpp +FN:223,System.Int32 ::mainCRTStartupStrArray(System.String[]) +FNDA:1,System.Int32 ::mainCRTStartupStrArray(System.String[]) +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:223,1 +DA:228,1 +DA:241,1 +DA:247,1 +DA:278,1 +DA:279,0 +DA:284,0 +DA:287,1 +DA:288,1 +LH:7 +LF:9 +end_of_record diff --git a/AltCover.Tests/NCoverWithPartials.xml b/AltCover.Tests/NCoverWithPartials.xml new file mode 100644 index 000000000..d2cfb9d30 --- /dev/null +++ b/AltCover.Tests/NCoverWithPartials.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/NativeJsonWithEmbeds.json b/AltCover.Tests/NativeJsonWithEmbeds.json new file mode 100644 index 000000000..b1f17c4e1 --- /dev/null +++ b/AltCover.Tests/NativeJsonWithEmbeds.json @@ -0,0 +1,2081 @@ +{ + "CSharpGeneratedDemo.dll": { + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\Analyzer1.SettingsXmlGenerator\\Settings_Main.cs": { + "\u00ABAltCover.embed\u00BB": { + "rVPLTsMwELxHyj\u002BsekokFMG5KhIqDyGVHmgPSIiDSbetJceu7E1pqfJlHPgkfoHNq41bhDiwl9jr2Z3ZsfP18RkGWmToViJFuMrJTJBI6oULg10YAEfueAuTrSPM\u002Bqep5ClTnK4PVvmrkimshCUpFKRKOAcMODQtUU3jMg6rptSRIP48CKnbomoDO1gg9aGAAWh88wBRr7tLNplyzboX76V1OGpZHsUB0xHnCyyDR7k2aZ6hJthU60ZO5yDyOSteK9eCkIezpXFzqXDMpp/iWg8q2B3SyKRsh9FRDIPLbh0chZ\u002BRmtBqvgDPpSP22K/ZnTalpXRJC\u002BdBf\u002BGvzUhGRsyiPcERrijHDYNmyFdjFNxK6\u002Bgx1/vHxnd88kYsUm41RGVFDEOj12gpGS6FXuB0u8Ioitj\u002BG4Wl\u002B3GjpL2NJs1wqWZjM0P3fP4SJ/dao53ihs6AuIWZ191bySzVV8uOwlCkS5zId/yTWq74D7EXP4otm/taC/4zim8=": { + "Lines": { +}, + "Branches": [] + } + }, + "AutoSettings.XmlSettings": { + "System.Void AutoSettings.XmlSettings::.cctor()": { + "Lines": { + "10": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 10, + "SC": 52, + "EL": 10, + "EC": 96, + "Offset": 0, + "Id": 80 + } + ] + } + }, + "AutoSettings.XmlSettings/MainSettings": { + "System.String AutoSettings.XmlSettings/MainSettings::GetLocation()": { + "Lines": { + "19": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 19, + "SC": 44, + "EL": 19, + "EC": 52, + "Offset": 0, + "Id": 81 + } + ] + }, + "System.Void AutoSettings.XmlSettings/MainSettings::.ctor(System.String)": { + "Lines": { + "15": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 25, + "SC": 13, + "EL": 25, + "EC": 14, + "Offset": 39, + "Id": 82 + }, + { + "VC": 0, + "SL": 24, + "SC": 17, + "EL": 24, + "EC": 39, + "Offset": 26, + "Id": 83 + }, + { + "VC": 0, + "SL": 23, + "SC": 17, + "EL": 23, + "EC": 42, + "Offset": 19, + "Id": 84 + }, + { + "VC": 0, + "SL": 22, + "SC": 13, + "EL": 22, + "EC": 14, + "Offset": 18, + "Id": 85 + }, + { + "VC": 0, + "SL": 21, + "SC": 13, + "EL": 21, + "EC": 51, + "Offset": 11, + "Id": 86 + }, + { + "VC": 0, + "SL": 15, + "SC": 13, + "EL": 15, + "EC": 52, + "Offset": 0, + "Id": 87 + } + ] + }, + "System.Boolean AutoSettings.XmlSettings/MainSettings::get_FirstRun()": { + "Lines": { + "31": 0, + "32": 0, + "33": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 33, + "SC": 5, + "EL": 33, + "EC": 6, + "Offset": 56, + "Id": 88 + }, + { + "VC": 0, + "SL": 32, + "SC": 9, + "EL": 32, + "EC": 118, + "Offset": 1, + "Id": 89 + }, + { + "VC": 0, + "SL": 31, + "SC": 5, + "EL": 31, + "EC": 6, + "Offset": 0, + "Id": 90 + } + ] + }, + "System.Int32 AutoSettings.XmlSettings/MainSettings::get_CacheSize()": { + "Lines": { + "40": 0, + "41": 0, + "42": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 42, + "SC": 5, + "EL": 42, + "EC": 6, + "Offset": 56, + "Id": 91 + }, + { + "VC": 0, + "SL": 41, + "SC": 9, + "EL": 41, + "EC": 116, + "Offset": 1, + "Id": 92 + }, + { + "VC": 0, + "SL": 40, + "SC": 5, + "EL": 40, + "EC": 6, + "Offset": 0, + "Id": 93 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\CsvGenerator.CSVGenerator\\Csv_Cars.cs": { + "\u00ABAltCover.embed\u00BB": { + "lZLPSgMxEMbvgX2HsV7qZWkrirJWqYuKoFAoKJ4kTcYSSJOSP4gs\u002B2QefCRfwWRbaktjbeeQXWa\u002B32a\u002Bmf3\u002B/MrIofJS0rFEQBUfGVF0inZGGUI5eoIqIxDCW6EmMPqwDqd5qaVE5oRWNr9DhUawIiNz4cyPpWDAJLUWSmosVE1\u002BpWadiR\u002B7NlRxqGCCrgAbjhr6wPGNeukOiuwP6lFzlLtTQjl4QWp2J7j2cRol24IsGeuoC8z9jfJTNHF\u002BF9Hz5RW8UikDFKe7nM2amzQIg4BVv/IYoYuYWk/GeBDWLbDmLnxfSbWPik2iWQhLFNiCj4IkyfL5vvrQuhXUtZKS\u002BXKCZOiV02lNs40\u002BQK/TOUsKytgLdHv5caIs8wHnbZbscB8L2vB/LDzTiVbbLXTPT063WOh19rWw\u002BGlkomTQeaM2SjVZf6tJTX4A": { + "Lines": { +}, + "Branches": [] + } + }, + "CSV.Cars": { + "System.Collections.Generic.IEnumerable\u00601\u003CCSV.Cars\u003E CSV.Cars::get_All()": { + "Lines": { + "15": 0, + "17": 0, + "19": 0, + "20": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0, + "26": 0, + "27": 0, + "28": 0, + "29": 0, + "30": 0, + "31": 0, + "32": 0, + "33": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 33, + "SC": 13, + "EL": 33, + "EC": 14, + "Offset": 149, + "Id": 59 + }, + { + "VC": 0, + "SL": 32, + "SC": 17, + "EL": 32, + "EC": 26, + "Offset": 145, + "Id": 60 + }, + { + "VC": 0, + "SL": 31, + "SC": 17, + "EL": 31, + "EC": 26, + "Offset": 139, + "Id": 61 + }, + { + "VC": 0, + "SL": 30, + "SC": 17, + "EL": 30, + "EC": 26, + "Offset": 131, + "Id": 62 + }, + { + "VC": 0, + "SL": 29, + "SC": 17, + "EL": 29, + "EC": 30, + "Offset": 115, + "Id": 63 + }, + { + "VC": 0, + "SL": 28, + "SC": 17, + "EL": 28, + "EC": 32, + "Offset": 103, + "Id": 64 + }, + { + "VC": 0, + "SL": 27, + "SC": 17, + "EL": 27, + "EC": 35, + "Offset": 91, + "Id": 65 + }, + { + "VC": 0, + "SL": 26, + "SC": 17, + "EL": 26, + "EC": 34, + "Offset": 79, + "Id": 66 + }, + { + "VC": 0, + "SL": 25, + "SC": 17, + "EL": 25, + "EC": 32, + "Offset": 73, + "Id": 67 + }, + { + "VC": 0, + "SL": 24, + "SC": 17, + "EL": 24, + "EC": 26, + "Offset": 65, + "Id": 68 + }, + { + "VC": 0, + "SL": 23, + "SC": 17, + "EL": 23, + "EC": 30, + "Offset": 49, + "Id": 69 + }, + { + "VC": 0, + "SL": 22, + "SC": 17, + "EL": 22, + "EC": 32, + "Offset": 37, + "Id": 70 + }, + { + "VC": 0, + "SL": 21, + "SC": 17, + "EL": 21, + "EC": 35, + "Offset": 25, + "Id": 71 + }, + { + "VC": 0, + "SL": 20, + "SC": 17, + "EL": 20, + "EC": 34, + "Offset": 13, + "Id": 72 + }, + { + "VC": 0, + "SL": 19, + "SC": 17, + "EL": 19, + "EC": 32, + "Offset": 7, + "Id": 73 + }, + { + "VC": 0, + "SL": 17, + "SC": 17, + "EL": 17, + "EC": 49, + "Offset": 1, + "Id": 74 + }, + { + "VC": 0, + "SL": 15, + "SC": 17, + "EL": 15, + "EC": 18, + "Offset": 0, + "Id": 75 + } + ] + }, + "System.Void CSV.Cars::.ctor()": { + "Lines": { + "7": 0, + "8": 0, + "9": 0, + "10": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 10, + "SC": 41, + "EL": 10, + "EC": 49, + "Offset": 21, + "Id": 76 + }, + { + "VC": 0, + "SL": 9, + "SC": 40, + "EL": 9, + "EC": 48, + "Offset": 14, + "Id": 77 + }, + { + "VC": 0, + "SL": 8, + "SC": 44, + "EL": 8, + "EC": 52, + "Offset": 7, + "Id": 78 + }, + { + "VC": 0, + "SL": 7, + "SC": 44, + "EL": 7, + "EC": 52, + "Offset": 0, + "Id": 79 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\CsvGenerator.CSVGenerator\\Csv_People.cs": { + "\u00ABAltCover.embed\u00BB": { + "lVJNT8JAEL1v0v8w4gUuREAPpqIBYowJMSYkXsmyHbFm2JL98COkv8yDP8m/4C5tMZVFYQ7tZua9mTdv9\u002BvjM2LH0hLxGSGg9L\u002BISb5AveQCYTR5gFXEwIXVqZzD5F0bXLRHGREKk2ZSt29QokpFHLECuLQzSgUI4lrDPWZL13lV1nxow42rF5VmC1bwwhW8QR8GRDHkP8iykzbKj75zqhx4jiYG7T65YyT4yC2Zo3gXaZAkCp2OvXmpNDDtdAbzv2b93uX2WtoFKu/eRbHX5RVMOZGjeXc33tQE7qJ6HyrXq3BKfKqe9DFOtdkQ1/PwtZZstuJtVnktIlASZY/qfkKQ9vou\u002BtAYW8FhmFEjiKrMd8BuD4bo1poYhWjC8NL2PsD5SQBAvl9TBAUdovk5e5KQZPiv5l4XRlyRf0p7aD49O0xz\u002BTwoUFJorJJbpZzVTznL2Tc=": { + "Lines": { +}, + "Branches": [] + } + }, + "CSV.People": { + "System.Void CSV.People::.cctor()": { + "Lines": { + "8": 0, + "13": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 8, + "SC": 40, + "EL": 8, + "EC": 41, + "Offset": 13, + "Id": 37 + }, + { + "VC": 0, + "SL": 8, + "SC": 27, + "EL": 8, + "EC": 39, + "Offset": 7, + "Id": 38 + }, + { + "VC": 0, + "SL": 8, + "SC": 25, + "EL": 8, + "EC": 26, + "Offset": 6, + "Id": 39 + }, + { + "VC": 0, + "SL": 13, + "SC": 9, + "EL": 13, + "EC": 49, + "Offset": 0, + "Id": 40 + } + ] + }, + "System.Collections.Generic.IEnumerable\u00601\u003CCSV.People\u003E CSV.People::get_All()": { + "Lines": { + "16": 0, + "18": 0, + "20": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0, + "26": 0, + "27": 0, + "28": 0, + "29": 0, + "30": 0, + "31": 0, + "32": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 32, + "SC": 13, + "EL": 32, + "EC": 14, + "Offset": 111, + "Id": 41 + }, + { + "VC": 0, + "SL": 31, + "SC": 17, + "EL": 31, + "EC": 26, + "Offset": 107, + "Id": 42 + }, + { + "VC": 0, + "SL": 30, + "SC": 17, + "EL": 30, + "EC": 26, + "Offset": 101, + "Id": 43 + }, + { + "VC": 0, + "SL": 29, + "SC": 17, + "EL": 29, + "EC": 26, + "Offset": 93, + "Id": 44 + }, + { + "VC": 0, + "SL": 28, + "SC": 17, + "EL": 28, + "EC": 32, + "Offset": 84, + "Id": 45 + }, + { + "VC": 0, + "SL": 27, + "SC": 17, + "EL": 27, + "EC": 46, + "Offset": 72, + "Id": 46 + }, + { + "VC": 0, + "SL": 26, + "SC": 17, + "EL": 26, + "EC": 37, + "Offset": 60, + "Id": 47 + }, + { + "VC": 0, + "SL": 25, + "SC": 17, + "EL": 25, + "EC": 34, + "Offset": 54, + "Id": 48 + }, + { + "VC": 0, + "SL": 24, + "SC": 17, + "EL": 24, + "EC": 26, + "Offset": 46, + "Id": 49 + }, + { + "VC": 0, + "SL": 23, + "SC": 17, + "EL": 23, + "EC": 32, + "Offset": 37, + "Id": 50 + }, + { + "VC": 0, + "SL": 22, + "SC": 17, + "EL": 22, + "EC": 46, + "Offset": 25, + "Id": 51 + }, + { + "VC": 0, + "SL": 21, + "SC": 17, + "EL": 21, + "EC": 37, + "Offset": 13, + "Id": 52 + }, + { + "VC": 0, + "SL": 20, + "SC": 17, + "EL": 20, + "EC": 34, + "Offset": 7, + "Id": 53 + }, + { + "VC": 0, + "SL": 18, + "SC": 17, + "EL": 18, + "EC": 53, + "Offset": 1, + "Id": 54 + }, + { + "VC": 0, + "SL": 16, + "SC": 17, + "EL": 16, + "EC": 18, + "Offset": 0, + "Id": 55 + } + ] + }, + "System.Void CSV.People::.ctor()": { + "Lines": { + "9": 0, + "10": 0, + "11": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 11, + "SC": 42, + "EL": 11, + "EC": 50, + "Offset": 14, + "Id": 56 + }, + { + "VC": 0, + "SL": 10, + "SC": 46, + "EL": 10, + "EC": 54, + "Offset": 7, + "Id": 57 + }, + { + "VC": 0, + "SL": 9, + "SC": 43, + "EL": 9, + "EC": 51, + "Offset": 0, + "Id": 58 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\MathsGenerator.MathsGenerator\\__MathLibrary__.cs": { + "\u00ABAltCover.embed\u00BB": { + "dZBNasMwEIX3Bt9hlhK4vkBab9KmLTSbphdQ5EkikEaufgIm9GRd9Ei9QuXYxrGhg0Cj0ce8N/P7/ZNn0Ss6wq71AU35puhzNa8tnuXaao0yKEu\u002BfEZCp2RC8oyEQd8IibAV4eThkmfQxL1WEnwQIV1SC\u002B9hY52JWrygbtBdsQQOMedfnygadGKv8b626QsrWFs6owsf9vFaYLeMolCBtJpPDS9T2sXBOhTyBOwsHHhQtMDHaBXqGhyG6AhYr83Bryby63/bPQ7bdhcNS566ugsFdClSXcAmkhwGKmAc7MDhoZo7mUYrU6txBWy5ghvsXdAR2aCXtOCuF\u002Be8SAKD/WQ9nT8=": { + "Lines": { +}, + "Branches": [] + } + }, + "Maths.FormulaHelpers": { + "System.Double Maths.FormulaHelpers::MySum(System.Int32,System.Int32,System.Func\u00602\u003CSystem.Double,System.Double\u003E)": { + "Lines": { + "16": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 16, + "SC": 13, + "EL": 16, + "EC": 93, + "Offset": 0, + "Id": 21 + } + ] + }, + "System.Collections.Generic.IEnumerable\u00601\u003CSystem.Double\u003E Maths.FormulaHelpers::ConvertToDouble(System.Collections.Generic.IEnumerable\u00601\u003CSystem.Int32\u003E)": { + "Lines": { + "10": 0, + "11": 0, + "12": 0, + "13": 0 + }, + "Branches": [ + { + "Line": 11, + "Offset": 122, + "EndOffset": 124, + "Path": 0, + "Ordinal": 0, + "Hits": 0, + "Id": 2 + }, + { + "Line": 11, + "Offset": 122, + "EndOffset": 62, + "Path": 1, + "Ordinal": 1, + "Hits": 0, + "Id": 3 + } + ], + "SeqPnts": [ + { + "VC": 0, + "SL": 13, + "SC": 9, + "EL": 13, + "EC": 10, + "Offset": 138, + "Id": 22 + }, + { + "VC": 0, + "SL": 11, + "SC": 28, + "EL": 11, + "EC": 30, + "Offset": 111, + "Id": 23 + }, + { + "VC": 0, + "SL": 12, + "SC": 17, + "EL": 12, + "EC": 41, + "Offset": 79, + "Id": 24 + }, + { + "VC": 0, + "SL": 11, + "SC": 22, + "EL": 11, + "EC": 27, + "Offset": 62, + "Id": 25 + }, + { + "VC": 0, + "SL": 11, + "SC": 31, + "EL": 11, + "EC": 34, + "Offset": 35, + "Id": 26 + }, + { + "VC": 0, + "SL": 11, + "SC": 13, + "EL": 11, + "EC": 20, + "Offset": 34, + "Id": 27 + }, + { + "VC": 0, + "SL": 10, + "SC": 9, + "EL": 10, + "EC": 10, + "Offset": 33, + "Id": 28 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\MathsGenerator.MathsGenerator\\Geometry.cs": { + "\u00ABAltCover.embed\u00BB": { + "hVLbasJAEH1uIP8wj0mNWm0pBWmhtLT2QbDmC8bNogubTdzdoKH4ZX3oJ/UXOrmroA0szJw958zZIb/fP66TGaFWYCxawSDMjeXxYIZ2PTm5KjAzeEt0nEmccplybYjjOgpjblJkvKLAVwECfWm2lCSs9SlqK1ACk2gM1D7EBte5OmZGCbUc4FlzDDcZag5eg0nw4fEJ5skWPGoCGBMwgUsWC84sqpU8cNlC0JTrynAL11ReNnoRmh266DrLB2l1ec7rPzOMdIm0cuxCLLuSVaYe9AntQbjRlprqvcv6vX24o3FIp2D7MKS7cYmUuzgb4j2REVcLwpJixmhwP3q4ub2QuhBMUcddaFXFO3TqwYhmz/IwI54nlPUJCKpCQSAKPiFDEP/Ee\u002B3G7OZaxLzbyi7kLFFRB\u002BQnhLwmlOmOluY1Zv3Wxa/32GspeUPJTyhl4up33rvO/g8=": { + "Lines": { +}, + "Branches": [] + } + }, + "Maths.Formulas": { + "System.Double Maths.Formulas::AreaSquare(System.Double)": { + "Lines": { + "8": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 8, + "SC": 51, + "EL": 8, + "EC": 64, + "Offset": 0, + "Id": 29 + } + ] + }, + "System.Double Maths.Formulas::AreaRectangle(System.Double,System.Double)": { + "Lines": { + "9": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 9, + "SC": 65, + "EL": 9, + "EC": 70, + "Offset": 0, + "Id": 30 + } + ] + }, + "System.Double Maths.Formulas::AreaCircle(System.Double)": { + "Lines": { + "10": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 10, + "SC": 51, + "EL": 10, + "EC": 61, + "Offset": 0, + "Id": 31 + } + ] + }, + "System.Double Maths.Formulas::Quadratic(System.Double,System.Double,System.Double)": { + "Lines": { + "11": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 11, + "SC": 72, + "EL": 11, + "EC": 128, + "Offset": 0, + "Id": 32 + } + ] + }, + "System.Double Maths.Formulas::get_GoldenRatio()": { + "Lines": { + "13": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 13, + "SC": 39, + "EL": 13, + "EC": 46, + "Offset": 0, + "Id": 33 + } + ] + }, + "System.Double Maths.Formulas::GoldHarm(System.Double)": { + "Lines": { + "14": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 14, + "SC": 49, + "EL": 14, + "EC": 105, + "Offset": 0, + "Id": 34 + }, + { + "VC": 0, + "SL": 14, + "SC": 98, + "EL": 14, + "EC": 103, + "Offset": 0, + "Id": 36 + } + ] + }, + "System.Double Maths.Formulas::D(System.Double,System.Double,System.Double,System.Double)": { + "Lines": { + "16": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 16, + "SC": 97, + "EL": 16, + "EC": 173, + "Offset": 0, + "Id": 35 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\Mustache.MustacheGenerator\\Mustache_MainAttributes__.cs": { + "\u00ABAltCover.embed\u00BB": { + "hY7BCoJQEEX3Qf8wS4XoAxIDd21qk62ixWiDCqOJM4\u002BQ6Mta9En9Qs\u002BeGRTS3TyYd\u002B\u002B593G7Tydgtd\u002B2olTOI9WmSIzSTjAj7/saY5ORyjwSoTLhdgYR8\u002Bm8NqxFzRRqY8g/OGRRKTUVMggh0xFSRhFYG1FMcxqQC/gucfGLezrVJuEiBbH/VQYbLAkuYHcEcB0zxVTWjPrfuELJx00/a70\u002BVtkRszdD\u002B7LhkFuo/4F1CpfgbV6heHB33T6E4DnaB/PKBw5gRz0B": { + "Lines": { +}, + "Branches": [] + } + }, + "MustacheAttribute": { + "System.Void MustacheAttribute::.ctor(System.String,System.String,System.String)": { + "Lines": { + "8": 0, + "9": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 9, + "SC": 16, + "EL": 9, + "EC": 63, + "Offset": 7, + "Id": 0 + }, + { + "VC": 0, + "SL": 8, + "SC": 9, + "EL": 8, + "EC": 76, + "Offset": 0, + "Id": 1 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\SourceGeneratorSamples.AutoNotifyGenerator\\AutoNotifyAttribute.cs": { + "\u00ABAltCover.embed\u00BB": { + "bZDBSgNBDIbvC/sOoactlH0Ai4fVavFgEbQnEUl30zUwnVkmGWQpPpkHH8lXMNLttqAhzGSG\u002BZJ//u/PrzxLwr6Fx16UdvM887gj6bAmqJKGVVDe9nm2zzOweK5UI2\u002BS0lqwpWI8PmFsSaW8ZXLNDO78G0VWauAStuiEZlA5F97vk1PuHB2vpy9D38P4csHY\u002BiDKtZTXwTesHDy6YnLSsiRPETXE18XN1Xo5ObYQQmfzaociZ9JHhXABY30ghj/9Rpc2juv/sGJ6enUGfPxhxQDz8SGGjqL2K7MR9mCmzE2aLQNhm\u002BUP": { + "Lines": { +}, + "Branches": [] + } + }, + "AutoNotify.AutoNotifyAttribute": { + "System.Void AutoNotify.AutoNotifyAttribute::.ctor()": { + "Lines": { + "9": 0, + "10": 0, + "11": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 11, + "SC": 9, + "EL": 11, + "EC": 10, + "Offset": 8, + "Id": 18 + }, + { + "VC": 0, + "SL": 10, + "SC": 9, + "EL": 10, + "EC": 10, + "Offset": 7, + "Id": 19 + }, + { + "VC": 0, + "SL": 9, + "SC": 9, + "EL": 9, + "EC": 37, + "Offset": 0, + "Id": 20 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\SourceGeneratorSamples.AutoNotifyGenerator\\ExampleViewModel_autoNotify.cs": { + "\u00ABAltCover.embed\u00BB": { + "vZHPSsQwEMbvhb7DHFuQPoBFROqie1AExavEdrYbzD\u002BSaXeL9Mk8\u002BEi\u002BgklbutBF2L2YU5L5vm/ml/x8fceRYhKdYSXCHSq0jLC6Ranj6DOOwC/TvAtegmGWOBNQCuYcrPZMGoGvHHcPukIBl/DcOUKZFVoarVDRcJ\u002BtHzXxTfdktUFLXbFlqsZqTPYNpnBsveGPhIV1FaT3TFUCLSxq\u002BRzoyHJVwwvuCWaSGsNh6gzTskiNVUBb7rI38vp8rPVxNG4c0pHpoIYraJloMF8UF5NdZ2vV6g9MQvECFO7OoL2xtUvCN\u002BlNEojSND0MOcw5c3P/jIVu1FnUTAbH6dyj/r/JB6xj9B76Xw==": { + "Lines": { +}, + "Branches": [] + } + }, + "GeneratedDemo.ExampleViewModel": { + "System.String GeneratedDemo.ExampleViewModel::get_Text()": { + "Lines": { + "10": 0, + "11": 0, + "12": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 12, + "SC": 5, + "EL": 12, + "EC": 6, + "Offset": 10, + "Id": 108 + }, + { + "VC": 0, + "SL": 11, + "SC": 9, + "EL": 11, + "EC": 27, + "Offset": 1, + "Id": 109 + }, + { + "VC": 0, + "SL": 10, + "SC": 5, + "EL": 10, + "EC": 6, + "Offset": 0, + "Id": 110 + } + ] + }, + "System.Void GeneratedDemo.ExampleViewModel::set_Text(System.String)": { + "Lines": { + "15": 0, + "16": 0, + "17": 0, + "18": 0 + }, + "Branches": [ + { + "Line": 17, + "Offset": 15, + "EndOffset": 37, + "Path": 0, + "Ordinal": 0, + "Hits": 0, + "Id": 2 + }, + { + "Line": 17, + "Offset": 15, + "EndOffset": 20, + "Path": 1, + "Ordinal": 1, + "Hits": 0, + "Id": 3 + } + ], + "SeqPnts": [ + { + "VC": 0, + "SL": 18, + "SC": 5, + "EL": 18, + "EC": 6, + "Offset": 37, + "Id": 111 + }, + { + "VC": 0, + "SL": 17, + "SC": 9, + "EL": 17, + "EC": 110, + "Offset": 8, + "Id": 112 + }, + { + "VC": 0, + "SL": 16, + "SC": 9, + "EL": 16, + "EC": 28, + "Offset": 1, + "Id": 113 + }, + { + "VC": 0, + "SL": 15, + "SC": 5, + "EL": 15, + "EC": 6, + "Offset": 0, + "Id": 114 + } + ] + }, + "System.Int32 GeneratedDemo.ExampleViewModel::get_Count()": { + "Lines": { + "25": 0, + "26": 0, + "27": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 27, + "SC": 5, + "EL": 27, + "EC": 6, + "Offset": 10, + "Id": 115 + }, + { + "VC": 0, + "SL": 26, + "SC": 9, + "EL": 26, + "EC": 29, + "Offset": 1, + "Id": 116 + }, + { + "VC": 0, + "SL": 25, + "SC": 5, + "EL": 25, + "EC": 6, + "Offset": 0, + "Id": 117 + } + ] + }, + "System.Void GeneratedDemo.ExampleViewModel::set_Count(System.Int32)": { + "Lines": { + "30": 0, + "31": 0, + "32": 0, + "33": 0 + }, + "Branches": [ + { + "Line": 32, + "Offset": 15, + "EndOffset": 37, + "Path": 0, + "Ordinal": 0, + "Hits": 0, + "Id": 4 + }, + { + "Line": 32, + "Offset": 15, + "EndOffset": 20, + "Path": 1, + "Ordinal": 1, + "Hits": 0, + "Id": 5 + } + ], + "SeqPnts": [ + { + "VC": 0, + "SL": 33, + "SC": 5, + "EL": 33, + "EC": 6, + "Offset": 37, + "Id": 118 + }, + { + "VC": 0, + "SL": 32, + "SC": 9, + "EL": 32, + "EC": 111, + "Offset": 8, + "Id": 119 + }, + { + "VC": 0, + "SL": 31, + "SC": 9, + "EL": 31, + "EC": 30, + "Offset": 1, + "Id": 120 + }, + { + "VC": 0, + "SL": 30, + "SC": 5, + "EL": 30, + "EC": 6, + "Offset": 0, + "Id": 121 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\CSharpSourceGeneratorSamples\\SourceGeneratorSamples.HelloWorldGenerator\\helloWorldGenerated.cs": { + "\u00ABAltCover.embed\u00BB": { + "xZXNatwwEMfvC/sO6p4SSA1tLyUh0MVbkkIaCk6bHgSLrJ1dq0gaoRm7MSVP1kMfqa9QrffDSTeQQ2BXl7Gk/8xvJM/Yf3//GQ5qMn4hipYY3Nlw4JUDCkqDuARr8RajnV2Ah6gYZsPBr\u002BFApBHq0hotiBUno60ieqBfadbSXXmDZiYK1XYOR8ei1z1wWY4cPaGF7DYahivj4WjU\u002BYh5RCcWm6yExhm8Gh2fPet9U4GYY4rwc3lmaj2rO8ERgATcGVrGMl5wUml0wdiULi7nioWO0LG4MiRCxEVU7rRj7nI\u002BjMRrkZ/KrwSRZArbgJygrh14Jnlh\u002BLIupbKssYEoC\u002BWCBVrbt\u002B/l9ron4FB\u002BWbEyTfugpSDjmvEa2czb9RbG/cFzag5A3Sn1fcI/K67oENw69aOu4ADo784WwJyacO8Hx/KHnEBZL6SH5JG6OoR32RuZXX\u002B8ydN0HMLJt8RJjX/epI1sTASutO2YOZqyZqADZ5oXlYrhkXab5Cc/x\u002BfS69wLrKPuX/0mlf9q8fFUTqfLhStTRhXb6fRFoHXxZTtVuN1KMOP7W38Z7\u002Bnl7IlvnezXtvANuf/B3K8ek7n/Bw==": { + "Lines": { +}, + "Branches": [] + } + }, + "HelloWorldGenerated.HelloWorld": { + "System.Void HelloWorldGenerated.HelloWorld::SayHello()": { + "Lines": { + "8": 0, + "9": 0, + "10": 0, + "11": 0, + "12": 0, + "13": 0, + "14": 0, + "15": 0, + "16": 0, + "17": 0, + "18": 0, + "19": 0, + "20": 0, + "21": 0, + "22": 0, + "24": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 24, + "SC": 9, + "EL": 24, + "EC": 10, + "Offset": 155, + "Id": 2 + }, + { + "VC": 0, + "SL": 22, + "SC": 1, + "EL": 22, + "EC": 121, + "Offset": 144, + "Id": 3 + }, + { + "VC": 0, + "SL": 21, + "SC": 1, + "EL": 21, + "EC": 111, + "Offset": 133, + "Id": 4 + }, + { + "VC": 0, + "SL": 20, + "SC": 1, + "EL": 20, + "EC": 104, + "Offset": 122, + "Id": 5 + }, + { + "VC": 0, + "SL": 19, + "SC": 1, + "EL": 19, + "EC": 158, + "Offset": 111, + "Id": 6 + }, + { + "VC": 0, + "SL": 18, + "SC": 1, + "EL": 18, + "EC": 169, + "Offset": 100, + "Id": 7 + }, + { + "VC": 0, + "SL": 17, + "SC": 1, + "EL": 17, + "EC": 125, + "Offset": 89, + "Id": 8 + }, + { + "VC": 0, + "SL": 16, + "SC": 1, + "EL": 16, + "EC": 122, + "Offset": 78, + "Id": 9 + }, + { + "VC": 0, + "SL": 15, + "SC": 1, + "EL": 15, + "EC": 119, + "Offset": 67, + "Id": 10 + }, + { + "VC": 0, + "SL": 14, + "SC": 1, + "EL": 14, + "EC": 124, + "Offset": 56, + "Id": 11 + }, + { + "VC": 0, + "SL": 13, + "SC": 1, + "EL": 13, + "EC": 117, + "Offset": 45, + "Id": 12 + }, + { + "VC": 0, + "SL": 12, + "SC": 1, + "EL": 12, + "EC": 124, + "Offset": 34, + "Id": 13 + }, + { + "VC": 0, + "SL": 11, + "SC": 1, + "EL": 11, + "EC": 109, + "Offset": 23, + "Id": 14 + }, + { + "VC": 0, + "SL": 10, + "SC": 13, + "EL": 10, + "EC": 115, + "Offset": 12, + "Id": 15 + }, + { + "VC": 0, + "SL": 9, + "SC": 13, + "EL": 9, + "EC": 61, + "Offset": 1, + "Id": 16 + }, + { + "VC": 0, + "SL": 8, + "SC": 9, + "EL": 8, + "EC": 10, + "Offset": 0, + "Id": 17 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\Program.cs": { + "GeneratedDemo.Program": { + "System.Void GeneratedDemo.Program::Main(System.String[])": { + "Lines": { + "8": 0, + "10": 0, + "11": 0, + "13": 0, + "14": 0, + "16": 0, + "17": 0, + "19": 0, + "20": 0, + "22": 0, + "23": 0, + "25": 0, + "26": 0, + "27": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 27, + "SC": 9, + "EL": 27, + "EC": 10, + "Offset": 103, + "Id": 94 + }, + { + "VC": 0, + "SL": 26, + "SC": 13, + "EL": 26, + "EC": 37, + "Offset": 97, + "Id": 95 + }, + { + "VC": 0, + "SL": 25, + "SC": 13, + "EL": 25, + "EC": 64, + "Offset": 86, + "Id": 96 + }, + { + "VC": 0, + "SL": 23, + "SC": 13, + "EL": 23, + "EC": 40, + "Offset": 80, + "Id": 97 + }, + { + "VC": 0, + "SL": 22, + "SC": 13, + "EL": 22, + "EC": 67, + "Offset": 69, + "Id": 98 + }, + { + "VC": 0, + "SL": 20, + "SC": 13, + "EL": 20, + "EC": 35, + "Offset": 63, + "Id": 99 + }, + { + "VC": 0, + "SL": 19, + "SC": 13, + "EL": 19, + "EC": 62, + "Offset": 52, + "Id": 100 + }, + { + "VC": 0, + "SL": 17, + "SC": 13, + "EL": 17, + "EC": 43, + "Offset": 46, + "Id": 101 + }, + { + "VC": 0, + "SL": 16, + "SC": 13, + "EL": 16, + "EC": 61, + "Offset": 35, + "Id": 102 + }, + { + "VC": 0, + "SL": 14, + "SC": 13, + "EL": 14, + "EC": 42, + "Offset": 29, + "Id": 103 + }, + { + "VC": 0, + "SL": 13, + "SC": 13, + "EL": 13, + "EC": 60, + "Offset": 18, + "Id": 104 + }, + { + "VC": 0, + "SL": 11, + "SC": 13, + "EL": 11, + "EC": 42, + "Offset": 12, + "Id": 105 + }, + { + "VC": 0, + "SL": 10, + "SC": 13, + "EL": 10, + "EC": 56, + "Offset": 1, + "Id": 106 + }, + { + "VC": 0, + "SL": 8, + "SC": 9, + "EL": 8, + "EC": 10, + "Offset": 0, + "Id": 107 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\UseAutoNotifyGenerator.cs": { + "GeneratedDemo.ExampleViewModel": { + "System.Void GeneratedDemo.ExampleViewModel::.ctor()": { + "Lines": { + "10": 0, + "13": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 13, + "SC": 9, + "EL": 13, + "EC": 33, + "Offset": 11, + "Id": 122 + }, + { + "VC": 0, + "SL": 10, + "SC": 9, + "EL": 10, + "EC": 53, + "Offset": 0, + "Id": 123 + } + ] + } + }, + "GeneratedDemo.UseAutoNotifyGenerator": { + "System.Void GeneratedDemo.UseAutoNotifyGenerator::Run()": { + "Lines": { + "19": 0, + "20": 0, + "23": 0, + "24": 0, + "27": 0, + "28": 0, + "31": 0, + "32": 0, + "33": 0, + "37": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 37, + "SC": 9, + "EL": 37, + "EC": 10, + "Offset": 119, + "Id": 124 + }, + { + "VC": 0, + "SL": 33, + "SC": 13, + "EL": 33, + "EC": 28, + "Offset": 110, + "Id": 125 + }, + { + "VC": 0, + "SL": 32, + "SC": 13, + "EL": 32, + "EC": 29, + "Offset": 98, + "Id": 126 + }, + { + "VC": 0, + "SL": 31, + "SC": 13, + "EL": 31, + "EC": 105, + "Offset": 60, + "Id": 127 + }, + { + "VC": 0, + "SL": 28, + "SC": 13, + "EL": 28, + "EC": 51, + "Offset": 38, + "Id": 128 + }, + { + "VC": 0, + "SL": 27, + "SC": 13, + "EL": 27, + "EC": 34, + "Offset": 31, + "Id": 129 + }, + { + "VC": 0, + "SL": 24, + "SC": 13, + "EL": 24, + "EC": 49, + "Offset": 14, + "Id": 130 + }, + { + "VC": 0, + "SL": 23, + "SC": 13, + "EL": 23, + "EC": 35, + "Offset": 7, + "Id": 131 + }, + { + "VC": 0, + "SL": 20, + "SC": 13, + "EL": 20, + "EC": 58, + "Offset": 1, + "Id": 132 + }, + { + "VC": 0, + "SL": 19, + "SC": 9, + "EL": 19, + "EC": 10, + "Offset": 0, + "Id": 133 + }, + { + "VC": 0, + "SL": 31, + "SC": 45, + "EL": 31, + "EC": 104, + "Offset": 0, + "Id": 134 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\UseCsvGenerator.cs": { + "GeneratedDemo.UseCsvGenerator": { + "System.Void GeneratedDemo.UseCsvGenerator::Run()": { + "Lines": { + "13": 0, + "14": 0, + "15": 0, + "16": 0, + "17": 0, + "18": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 18, + "SC": 9, + "EL": 18, + "EC": 10, + "Offset": 117, + "Id": 135 + }, + { + "VC": 0, + "SL": 17, + "SC": 12, + "EL": 17, + "EC": 94, + "Offset": 70, + "Id": 136 + }, + { + "VC": 0, + "SL": 16, + "SC": 12, + "EL": 16, + "EC": 37, + "Offset": 59, + "Id": 137 + }, + { + "VC": 0, + "SL": 15, + "SC": 12, + "EL": 15, + "EC": 97, + "Offset": 12, + "Id": 138 + }, + { + "VC": 0, + "SL": 14, + "SC": 12, + "EL": 14, + "EC": 33, + "Offset": 1, + "Id": 139 + }, + { + "VC": 0, + "SL": 13, + "SC": 9, + "EL": 13, + "EC": 10, + "Offset": 0, + "Id": 140 + }, + { + "VC": 0, + "SL": 15, + "SC": 43, + "EL": 15, + "EC": 95, + "Offset": 0, + "Id": 141 + }, + { + "VC": 0, + "SL": 17, + "SC": 45, + "EL": 17, + "EC": 92, + "Offset": 0, + "Id": 142 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\UseHelloWorldGenerator.cs": { + "GeneratedDemo.UseHelloWorldGenerator": { + "System.Void GeneratedDemo.UseHelloWorldGenerator::Run()": { + "Lines": { + "6": 0, + "8": 0, + "9": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 9, + "SC": 9, + "EL": 9, + "EC": 10, + "Offset": 7, + "Id": 143 + }, + { + "VC": 0, + "SL": 8, + "SC": 13, + "EL": 8, + "EC": 55, + "Offset": 1, + "Id": 144 + }, + { + "VC": 0, + "SL": 6, + "SC": 9, + "EL": 6, + "EC": 10, + "Offset": 0, + "Id": 145 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\UseMathsGenerator.cs": { + "GeneratedDemo.UseMathsGenerator": { + "System.Void GeneratedDemo.UseMathsGenerator::Run()": { + "Lines": { + "9": 0, + "10": 0, + "11": 0, + "12": 0, + "13": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 13, + "SC": 9, + "EL": 13, + "EC": 10, + "Offset": 115, + "Id": 146 + }, + { + "VC": 0, + "SL": 12, + "SC": 13, + "EL": 12, + "EC": 74, + "Offset": 80, + "Id": 147 + }, + { + "VC": 0, + "SL": 11, + "SC": 13, + "EL": 11, + "EC": 83, + "Offset": 45, + "Id": 148 + }, + { + "VC": 0, + "SL": 10, + "SC": 13, + "EL": 10, + "EC": 95, + "Offset": 1, + "Id": 149 + }, + { + "VC": 0, + "SL": 9, + "SC": 9, + "EL": 9, + "EC": 10, + "Offset": 0, + "Id": 150 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\UseMustacheGenerator.cs": { + "GeneratedDemo.UseMustacheGenerator": { + "System.Void GeneratedDemo.UseMustacheGenerator::Run()": { + "Lines": { + "20": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0, + "26": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 26, + "SC": 9, + "EL": 26, + "EC": 10, + "Offset": 56, + "Id": 151 + }, + { + "VC": 0, + "SL": 25, + "SC": 13, + "EL": 25, + "EC": 57, + "Offset": 45, + "Id": 152 + }, + { + "VC": 0, + "SL": 24, + "SC": 13, + "EL": 24, + "EC": 51, + "Offset": 34, + "Id": 153 + }, + { + "VC": 0, + "SL": 23, + "SC": 13, + "EL": 23, + "EC": 48, + "Offset": 23, + "Id": 154 + }, + { + "VC": 0, + "SL": 22, + "SC": 13, + "EL": 22, + "EC": 46, + "Offset": 12, + "Id": 155 + }, + { + "VC": 0, + "SL": 21, + "SC": 13, + "EL": 21, + "EC": 51, + "Offset": 1, + "Id": 156 + }, + { + "VC": 0, + "SL": 20, + "SC": 9, + "EL": 20, + "EC": 10, + "Offset": 0, + "Id": 157 + } + ] + } + } + }, + "C:\\Users\\steve\\Documents\\GitHub\\altcover\\Samples\\Sample28\\GeneratedDemo\\UseXmlSettingsGenerator.cs": { + "GeneratedDemo.UseXmlSettingsGenerator": { + "System.Void GeneratedDemo.UseXmlSettingsGenerator::Run()": { + "Lines": { + "9": 0, + "14": 0, + "15": 0, + "18": 0, + "19": 0, + "21": 0, + "22": 0, + "25": 0 + }, + "Branches": [], + "SeqPnts": [ + { + "VC": 0, + "SL": 25, + "SC": 9, + "EL": 25, + "EC": 10, + "Offset": 95, + "Id": 158 + }, + { + "VC": 0, + "SL": 22, + "SC": 13, + "EL": 22, + "EC": 67, + "Offset": 73, + "Id": 159 + }, + { + "VC": 0, + "SL": 21, + "SC": 13, + "EL": 21, + "EC": 56, + "Offset": 62, + "Id": 160 + }, + { + "VC": 0, + "SL": 19, + "SC": 13, + "EL": 19, + "EC": 65, + "Offset": 40, + "Id": 161 + }, + { + "VC": 0, + "SL": 18, + "SC": 13, + "EL": 18, + "EC": 55, + "Offset": 29, + "Id": 162 + }, + { + "VC": 0, + "SL": 15, + "SC": 13, + "EL": 15, + "EC": 78, + "Offset": 7, + "Id": 163 + }, + { + "VC": 0, + "SL": 14, + "SC": 13, + "EL": 14, + "EC": 62, + "Offset": 1, + "Id": 164 + }, + { + "VC": 0, + "SL": 9, + "SC": 9, + "EL": 9, + "EC": 10, + "Offset": 0, + "Id": 165 + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/AltCover.Tests/OpenCover.ConvertTo.cobertura b/AltCover.Tests/OpenCover.ConvertTo.cobertura index ca62c1194..17160f2ec 100644 --- a/AltCover.Tests/OpenCover.ConvertTo.cobertura +++ b/AltCover.Tests/OpenCover.ConvertTo.cobertura @@ -1,15 +1,15 @@ - + - + altcover\Sample1 - + - + diff --git a/AltCover.Tests/OpenCover.json b/AltCover.Tests/OpenCover.json index 2b54d00e8..3cd74aba7 100644 --- a/AltCover.Tests/OpenCover.json +++ b/AltCover.Tests/OpenCover.json @@ -1,6 +1,12 @@ { "Sample4.dll": { "altcover/Sample4/Tests.fs": { + "\u00ABAltCover.embed\u00BB": { + "hVTvb9MwEP1eqf/DEb600sg6BAKNdtrP7gO0mrZ2QprQ5CbXxiKxi31ZyWD/O\u002Bc4adIxhPoh9vnd3fPzuyqRoV2LCGGGlmy3s78PS5sIs06losNYWrFIEWCC2QLN1KFhqtVVvkhldCvSHK0PXmOcq1gomuLmMxYbbeJuR69RwU1hCbOdTXiNyxQjklpV8a\u002B5ktTt1KgNKosqnKsfuSZ08buhsJZJpMXhSbW4RWO5wgmRkYucsBcchAP3C/pH317MGMsU/5MVa\u002Bj1fcOpPtPZWhhptXJHmY5z1mICo24H4G54kpO\u002BQSNFKh\u002BdSr2lSC2WVQCoWLOmiVQrDwf4VW0PwXJrXjz5eFZKC5RIGy4KQtvrw6gWaoY/KbxQkY45I5zPxh/DS6TTElZmlDVLwgApEmTiO/o\u002BlqvUPUe8e/Kgu\u002BFYRORJugSuRJM6ybX2rFwYhsfQawoGNuiHdT3ewPHRv7ECpc4ZX90o/IJqRQknvi/Ttmqez33HUq9JMVf8NjWH3zDWGvQS2Ip15FQYF/ESNsFHF4w12xK3Qb12wXNBOJMZ\u002Btvvyi3s/UKY5tJMwxT1kqGCoqREwkZS0hx4YgreHDk\u002Bveo9Vb\u002BNcJziZ4h4F8EE6RmCWggeRR4miITl\u002BVppVgESNNguce/SHcE66Hj6qBMqUFph8NLNJ4U7H7Vl8LDqHc5SHp5GmCr1QaRwZXhEDRWcPPDtVkh7YJEaExqk3Cin0QPDyu/ukWvujspv25efauOf6RjPtftma55aw7ZXaPgtY3fSmt6pdkVFmhbBHgTbOd41d2mrv83d8DwYVER58dzWDWVnek/6Rfv7/H7LVh57MAgq07\u002BWS3g1vZi9\u002B/B2OwEs6MqIrP5XuVDswSvNlm\u002BukQl\u002B\u002B3unOJdAFcvlHw==": { + "Lines": {}, + "Branches": [] + } + }, "Tests.Program": { "System.Int32 Tests.Program::main(System.String[])": { "Lines": { diff --git a/AltCover.Tests/OpenCover.lcov b/AltCover.Tests/OpenCover.lcov index 95bba366f..eccc6cf6e 100644 --- a/AltCover.Tests/OpenCover.lcov +++ b/AltCover.Tests/OpenCover.lcov @@ -1,4 +1,4 @@ -TN: +TN: Sample1 SF:altcover\Sample1\Program.cs FN:11,System.Void TouchTest.Program::Main(System.String[]) FNDA:1,System.Void TouchTest.Program::Main(System.String[]) diff --git a/AltCover.Tests/OpenCoverForPester.coverlet.xml b/AltCover.Tests/OpenCoverForPester.coverlet.xml index 87d01d55e..b4bc2ed90 100644 --- a/AltCover.Tests/OpenCoverForPester.coverlet.xml +++ b/AltCover.Tests/OpenCoverForPester.coverlet.xml @@ -1,9 +1,9 @@  - + - + Sample18.dll 2020-03-28T12:20:44 Sample18 @@ -21,10 +21,10 @@ System.Int32 Tests.Program::main(System.String[]) - + - + @@ -61,22 +61,22 @@ - - + + - - - - - - - - - - - - + + + + + + + + + + + + @@ -87,12 +87,12 @@ - - + + - - + + @@ -102,18 +102,18 @@ System.Int32 Tests.DU::LineSpanning2(System.Collections.Generic.IEnumerable`1<System.Int32>) - - - - - - + + + + + + - - + + - + @@ -134,55 +134,78 @@ System.Tuple`2<System.Double,System.Double> Tests.DU::Multiples(System.Double,System.Double,System.Double) - - - - + + + + - - + + - + - + Tests.DU/MyUnion - - - 100663318 - System.Int32 Tests.DU/MyUnion::CompareTo(System.Object) + + + 100663317 + System.Int32 Tests.DU/MyUnion::CompareTo(Tests.DU/MyUnion) - + - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + 100663323 Tests.DU/MyUnion Tests.DU/MyUnion::AsBar() - - - - - - + + + + + + + - - - - - + + + + + - + @@ -264,36 +287,43 @@ - + - - - - - - - - + + + + + + + + - + Tests.M/Thing - - - 100663367 - System.Int32 Tests.M/Thing::CompareTo(System.Object) + + + 100663366 + System.Int32 Tests.M/Thing::CompareTo(Tests.M/Thing) - + - - + + + + + + + + + @@ -310,7 +340,7 @@ - Tests.DU/LineSpanning2@63-1 + Tests.DU/Pipe #1 stage #1 at line 63@63 diff --git a/AltCover.Tests/OpenCoverFromNCoverWithPartials.xml b/AltCover.Tests/OpenCoverFromNCoverWithPartials.xml new file mode 100644 index 000000000..2f72bc503 --- /dev/null +++ b/AltCover.Tests/OpenCoverFromNCoverWithPartials.xml @@ -0,0 +1,1383 @@ + + + + + + + C:\Users\steve\Documents\GitHub\altcover\AltCover.Tests\SimpleMix.exe + 2021-10-31T14:12:26.1800009Z + SimpleMix + + + + + + + + + + + + + + + + <Module> + + + + 100663297 + System.Int32 <Module>::main(System.String[]) + + + + + + + + + + + + + + + + + + + 100663298 + System.Void <Module>::<CrtImplementationDetails>.ThrowNestedModuleLoadException(System.Exception,System.Exception) + + + + + + + + + + + 100663299 + System.Void <Module>::<CrtImplementationDetails>.ThrowModuleLoadException(System.String) + + + + + + + + + + + 100663300 + System.Void <Module>::<CrtImplementationDetails>.ThrowModuleLoadException(System.String,System.Exception) + + + + + + + + + + + 100663301 + System.Void <Module>::<CrtImplementationDetails>.RegisterModuleUninitializer(System.EventHandler) + + + + + + + + + + + 100663302 + System.Guid <Module>::<CrtImplementationDetails>.FromGUID(_GUID modopt(System.Runtime.CompilerServices.IsConst)* modopt(System.Runtime.CompilerServices.IsImplicitlyDereferenced)) + + + + + + + + + + + 100663303 + System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__get_default_appdomain(IUnknown**) + + + + + + + + + + + + + + + + + + + + + + 100663304 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__release_appdomain(IUnknown*) + + + + + + + + + + + 100663305 + System.AppDomain <Module>::<CrtImplementationDetails>.GetDefaultDomain() + + + + + + + + + + + + + + + + + + + + + + + 100663306 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DoCallBackInDefaultDomain(method System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall) *(System.Void*),System.Void*) + + + + + + + + + + + + + + + + + + + + + 100663307 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__scrt_is_safe_for_managed_code() + + + + + + + + + + + + + 100663308 + System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall) <Module>::<CrtImplementationDetails>.DefaultDomain.DoNothing(System.Void*) + + + + + + + + + + + + 100663309 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.HasPerProcess() + + + + + + + + + + + + + + + + + + + + + + 100663310 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.HasNative() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663311 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.NeedsInitialization() + + + + + + + + + + + 100663312 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.NeedsUninitialization() + + + + + + + + + + + 100663313 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.DefaultDomain.Initialize() + + + + + + + + + + + 100663314 + System.Void <Module>::?A0x5ea2bff1.??__E?Initialized@CurrentDomain@<CrtImplementationDetails>@@$$Q2HA@@YMXXZ() + + + + + + + + + + 100663315 + System.Void <Module>::?A0x5ea2bff1.??__E?Uninitialized@CurrentDomain@<CrtImplementationDetails>@@$$Q2HA@@YMXXZ() + + + + + + + + + + 100663316 + System.Void <Module>::?A0x5ea2bff1.??__E?IsDefaultDomain@CurrentDomain@<CrtImplementationDetails>@@$$Q2_NA@@YMXXZ() + + + + + + + + + + 100663317 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedVtables@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663318 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedNative@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663319 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedPerProcess@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663320 + System.Void <Module>::?A0x5ea2bff1.??__E?InitializedPerAppDomain@CurrentDomain@<CrtImplementationDetails>@@$$Q2W4Progress@2@A@@YMXXZ() + + + + + + + + + + 100663321 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeVtables(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + 100663322 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeDefaultAppDomain(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + 100663323 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeNative(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663324 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializePerProcess(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + 100663325 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializePerAppDomain(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + 100663326 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.InitializeUninitializer(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + 100663327 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport._Initialize(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663328 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.LanguageSupport.UninitializeAppDomain() + + + + + + + + + + + 100663329 + System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall) <Module>::<CrtImplementationDetails>.LanguageSupport._UninitializeDefaultDomain(System.Void*) + + + + + + + + + + + + + + + + + + + 100663330 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.LanguageSupport.UninitializeDefaultDomain() + + + + + + + + + + + + + + + 100663331 + System.Void <Module>::<CrtImplementationDetails>.LanguageSupport.DomainUnload(System.Object,System.EventArgs) + + + + + + + + + + + + + + + 100663332 + System.Void <Module>::<CrtImplementationDetails>.LanguageSupport.Cleanup(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst),System.Exception) + + + + + + + + + + + + + + + + + + + + + + 100663333 + <CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.{ctor}(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + 100663334 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.{dtor}(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + 100663335 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::<CrtImplementationDetails>.LanguageSupport.Initialize(<CrtImplementationDetails>.LanguageSupport* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663336 + System.Void <Module>::.cctor() + + + + + + + + + + + + 100663337 + System.String <Module>::gcroot<System::String ^>..P$AAVString@System@@(gcroot<System::String ^> modopt(System.Runtime.CompilerServices.IsConst)* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + 100663338 + gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsImplicitlyDereferenced) <Module>::gcroot<System::String ^>.=(gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst),System.String) + + + + + + + + + + + + 100663339 + System.Void modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::gcroot<System::String ^>.{dtor}(gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + + + 100663340 + gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.CallConvThiscall) <Module>::gcroot<System::String ^>.{ctor}(gcroot<System::String ^>* modopt(System.Runtime.CompilerServices.IsConst) modopt(System.Runtime.CompilerServices.IsConst)) + + + + + + + + + + + 100663341 + System.Int32 <Module>::mainCRTStartupStrArray(System.String[]) + + + + + + + + + + + + + + + + + + 100663342 + System.Void <Module>::?A0x61adbb31.__set_managed_app_type() + + + + + + + + + + + + + + + + + + + + + + + 100663343 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::?A0x61adbb31._common_init() + + + + + + + + + + + + + + 100663344 + System.ValueType modopt(System.Runtime.InteropServices.GCHandle) modopt(System.Runtime.CompilerServices.IsBoxed) <Module>::<CrtImplementationDetails>.AtExitLock._handle() + + + + + + + + + + + + + 100663345 + System.Void <Module>::<CrtImplementationDetails>.AtExitLock._lock_Construct(System.Object) + + + + + + + + + + + + 100663346 + System.Void <Module>::<CrtImplementationDetails>.AtExitLock._lock_Set(System.Object) + + + + + + + + + + + + + + + + + 100663347 + System.Object <Module>::<CrtImplementationDetails>.AtExitLock._lock_Get() + + + + + + + + + + + + + + + 100663348 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock._lock_Destruct() + + + + + + + + + + + + + + + 100663349 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock.IsInitialized() + + + + + + + + + + + 100663350 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock.AddRef() + + + + + + + + + + + + + + 100663351 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::<CrtImplementationDetails>.AtExitLock.RemoveRef() + + + + + + + + + + + + + + 100663352 + System.Boolean modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::?A0x6adf33d6.__alloc_global_lock() + + + + + + + + + + + + 100663353 + System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::?A0x6adf33d6.__dealloc_global_lock() + + + + + + + + + + + 100663354 + System.Void <Module>::_exit_callback() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663355 + System.Int32 <Module>::_initatexit_m() + + + + + + + + + + + + + + + + + + 100663356 + System.Int32 <Module>::_initatexit_app_domain() + + + + + + + + + + + + + + + 100663357 + System.Void <Module>::_app_exit_callback() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100663360 + System.Int32 <Module>::_initterm_e(method System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*,method System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*) + + + + + + + + + + + + + + + + + 100663361 + System.Void <Module>::_initterm(method System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*,method System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) *()*) + + + + + + + + + + + + + + + 100663362 + System.ModuleHandle <Module>::<CrtImplementationDetails>.ThisModule.Handle() + + + + + + + + + + + 100663363 + System.Void <Module>::_initterm_m(method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *() modopt(System.Runtime.CompilerServices.IsConst)*,method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *() modopt(System.Runtime.CompilerServices.IsConst)*) + + + + + + + + + + + + + + + + 100663364 + method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *() <Module>::<CrtImplementationDetails>.ThisModule.ResolveMethod<void const * __clrcall(void)>(method System.Void modopt(System.Runtime.CompilerServices.IsConst)* *()) + + + + + + + + + + + 100663365 + System.Void <Module>::___CxxCallUnwindDtor(method System.Void *(System.Void*),System.Void*) + + + + + + + + + + + + + + + Example + + + + 100663387 + System.Int32 Example::main(System.String[]) + + + + + + + + + + + + + + + + + 100663388 + System.Void Example::.ctor() + + + + + + + + + <CrtImplementationDetails>.ModuleLoadException + + + + 100663389 + System.Void <CrtImplementationDetails>.ModuleLoadException::.ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext) + + + + + + + + + + + 100663390 + System.Void <CrtImplementationDetails>.ModuleLoadException::.ctor(System.String,System.Exception) + + + + + + + + + + + 100663391 + System.Void <CrtImplementationDetails>.ModuleLoadException::.ctor(System.String) + + + + + + + + + + + + + <CrtImplementationDetails>.ModuleLoadExceptionHandlerException + + + + 100663392 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::.ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext) + + + + + + + + + + + + 100663393 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::.ctor(System.String,System.Exception,System.Exception) + + + + + + + + + + + + 100663394 + System.Exception <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::get_NestedException() + + + + + + + + + + 100663395 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::set_NestedException(System.Exception) + + + + + + + + + + 100663396 + System.String <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::ToString() + + + + + + + + + + + + + + + 100663397 + System.Void <CrtImplementationDetails>.ModuleLoadExceptionHandlerException::GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext) + + + + + + + + + + + + + + <CrtImplementationDetails>.ModuleUninitializer + + + + 100663398 + System.Void <CrtImplementationDetails>.ModuleUninitializer::AddHandler(System.EventHandler) + + + + + + + + + + + + + + + + + + + + 100663399 + System.Void <CrtImplementationDetails>.ModuleUninitializer::.cctor() + + + + + + + + + + + + 100663400 + System.Void <CrtImplementationDetails>.ModuleUninitializer::.ctor() + + + + + + + + + + + + + + 100663401 + System.Void <CrtImplementationDetails>.ModuleUninitializer::SingletonDomainUnload(System.Object,System.EventArgs) + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/OpenCoverWithEmbeds.xml b/AltCover.Tests/OpenCoverWithEmbeds.xml new file mode 100644 index 000000000..37a3ea79a --- /dev/null +++ b/AltCover.Tests/OpenCoverWithEmbeds.xml @@ -0,0 +1,883 @@ + + + + + + C:\Users\steve\Documents\GitHub\altcover\Samples\Sample28\GeneratedDemo\bin\Debug\netcoreapp3.1\CSharpGeneratedDemo.dll + 2021-10-25T17:23:59.746698Z + CSharpGeneratedDemo + + + + + + + + + + + + + + + + + + + + + + Microsoft.CodeAnalysis.EmbeddedAttribute + + + + 100663297 + System.Void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() + + + + + + + + + System.Runtime.CompilerServices.NullableAttribute + + + + 100663298 + System.Void System.Runtime.CompilerServices.NullableAttribute::.ctor(System.Byte) + + + + + + + 100663299 + System.Void System.Runtime.CompilerServices.NullableAttribute::.ctor(System.Byte[]) + + + + + + + + + System.Runtime.CompilerServices.NullableContextAttribute + + + + 100663300 + System.Void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(System.Byte) + + + + + + + + + MustacheAttribute + + + + 100663304 + System.Void MustacheAttribute::.ctor(System.String,System.String,System.String) + + + + + + + + + + + + + HelloWorldGenerated.HelloWorld + + + + 100663305 + System.Void HelloWorldGenerated.HelloWorld::SayHello() + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoNotify.AutoNotifyAttribute + + + + 100663306 + System.Void AutoNotify.AutoNotifyAttribute::.ctor() + + + + + + + + + + + + + + Maths.FormulaHelpers + + + + 100663309 + System.Collections.Generic.IEnumerable`1<System.Double> Maths.FormulaHelpers::ConvertToDouble(System.Collections.Generic.IEnumerable`1<System.Int32>) + + + + + + + 100663310 + System.Double Maths.FormulaHelpers::MySum(System.Int32,System.Int32,System.Func`2<System.Double,System.Double>) + + + + + + + + + + + + Maths.FormulaHelpers/<ConvertToDouble>d__0 + + + + 100663358 + System.Void Maths.FormulaHelpers/<ConvertToDouble>d__0::System.IDisposable.Dispose() + + + + + + + 100663359 + System.Boolean Maths.FormulaHelpers/<ConvertToDouble>d__0::MoveNext() + + + + + + + + + + + + + + + + + + + 100663360 + System.Void Maths.FormulaHelpers/<ConvertToDouble>d__0::<>m__Finally1() + + + + + + + 100663361 + System.Double Maths.FormulaHelpers/<ConvertToDouble>d__0::System.Collections.Generic.IEnumerator<System.Double>.get_Current() + + + + + + + 100663362 + System.Void Maths.FormulaHelpers/<ConvertToDouble>d__0::System.Collections.IEnumerator.Reset() + + + + + + + 100663363 + System.Object Maths.FormulaHelpers/<ConvertToDouble>d__0::System.Collections.IEnumerator.get_Current() + + + + + + + 100663364 + System.Collections.Generic.IEnumerator`1<System.Double> Maths.FormulaHelpers/<ConvertToDouble>d__0::System.Collections.Generic.IEnumerable<System.Double>.GetEnumerator() + + + + + + + 100663365 + System.Collections.IEnumerator Maths.FormulaHelpers/<ConvertToDouble>d__0::System.Collections.IEnumerable.GetEnumerator() + + + + + + + + + Maths.Formulas + + + + 100663311 + System.Double Maths.Formulas::AreaSquare(System.Double) + + + + + + + + + + 100663312 + System.Double Maths.Formulas::AreaRectangle(System.Double,System.Double) + + + + + + + + + + 100663313 + System.Double Maths.Formulas::AreaCircle(System.Double) + + + + + + + + + + 100663314 + System.Double Maths.Formulas::Quadratic(System.Double,System.Double,System.Double) + + + + + + + + + + 100663315 + System.Double Maths.Formulas::get_GoldenRatio() + + + + + + + + + + 100663316 + System.Double Maths.Formulas::GoldHarm(System.Double) + + + + + + + + + + 100663317 + System.Double Maths.Formulas::D(System.Double,System.Double,System.Double,System.Double) + + + + + + + + + + + + Maths.Formulas/<>c + + + + 100663368 + System.Double Maths.Formulas/<>c::<GoldHarm>b__6_0(System.Double) + + + + + + + + + + + + CSV.People + + + + 100663318 + System.Void CSV.People::.cctor() + + + + + + + + + + + + + 100663325 + System.Collections.Generic.IEnumerable`1<CSV.People> CSV.People::get_All() + + + + + + + + + + + + + + + + + + + + + + + + 100663326 + System.Void CSV.People::.ctor() + + + + + + + + + + + + + + CSV.Cars + + + + 100663335 + System.Collections.Generic.IEnumerable`1<CSV.Cars> CSV.Cars::get_All() + + + + + + + + + + + + + + + + + + + + + + + + + + 100663336 + System.Void CSV.Cars::.ctor() + + + + + + + + + + + + + + + AutoSettings.XmlSettings + + + + 100663338 + System.Void AutoSettings.XmlSettings::.ctor() + + + + + + + 100663339 + System.Void AutoSettings.XmlSettings::.cctor() + + + + + + + + + + + + AutoSettings.XmlSettings/MainSettings + + + + 100663369 + System.String AutoSettings.XmlSettings/MainSettings::GetLocation() + + + + + + + + + + 100663370 + System.Void AutoSettings.XmlSettings/MainSettings::.ctor(System.String) + + + + + + + + + + + + + + + 100663371 + System.Boolean AutoSettings.XmlSettings/MainSettings::get_FirstRun() + + + + + + + + + + + + 100663372 + System.Int32 AutoSettings.XmlSettings/MainSettings::get_CacheSize() + + + + + + + + + + + + + + GeneratedDemo.Program + + + + 100663340 + System.Void GeneratedDemo.Program::Main(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + 100663341 + System.Void GeneratedDemo.Program::.ctor() + + + + + + + + + GeneratedDemo.ExampleViewModel + + + + 100663342 + System.Void GeneratedDemo.ExampleViewModel::add_PropertyChanged(System.ComponentModel.PropertyChangedEventHandler) + + + + + + + 100663343 + System.Void GeneratedDemo.ExampleViewModel::remove_PropertyChanged(System.ComponentModel.PropertyChangedEventHandler) + + + + + + + 100663344 + System.String GeneratedDemo.ExampleViewModel::get_Text() + + + + + + + + + + + + 100663345 + System.Void GeneratedDemo.ExampleViewModel::set_Text(System.String) + + + + + + + + + + + + + + + + 100663346 + System.Int32 GeneratedDemo.ExampleViewModel::get_Count() + + + + + + + + + + + + 100663347 + System.Void GeneratedDemo.ExampleViewModel::set_Count(System.Int32) + + + + + + + + + + + + + + + + 100663348 + System.Void GeneratedDemo.ExampleViewModel::.ctor() + + + + + + + + + + + + + GeneratedDemo.UseAutoNotifyGenerator + + + + 100663349 + System.Void GeneratedDemo.UseAutoNotifyGenerator::Run() + + + + + + + + + + + + + + + + + + + + + GeneratedDemo.UseAutoNotifyGenerator/<>c + + + + 100663375 + System.Void GeneratedDemo.UseAutoNotifyGenerator/<>c::<Run>b__0_0(System.Object,System.ComponentModel.PropertyChangedEventArgs) + + + + + + + + + + + + GeneratedDemo.UseCsvGenerator + + + + 100663350 + System.Void GeneratedDemo.UseCsvGenerator::Run() + + + + + + + + + + + + + + + 100663351 + System.Void GeneratedDemo.UseCsvGenerator::.ctor() + + + + + + + + + GeneratedDemo.UseCsvGenerator/<>c + + + + 100663378 + System.Void GeneratedDemo.UseCsvGenerator/<>c::<Run>b__0_0(CSV.Cars) + + + + + + + + + + 100663379 + System.Void GeneratedDemo.UseCsvGenerator/<>c::<Run>b__0_1(CSV.People) + + + + + + + + + + + + GeneratedDemo.UseHelloWorldGenerator + + + + 100663352 + System.Void GeneratedDemo.UseHelloWorldGenerator::Run() + + + + + + + + + + + + + + GeneratedDemo.UseMathsGenerator + + + + 100663353 + System.Void GeneratedDemo.UseMathsGenerator::Run() + + + + + + + + + + + + + + + + GeneratedDemo.UseMustacheGenerator + + + + 100663354 + System.Void GeneratedDemo.UseMustacheGenerator::Run() + + + + + + + + + + + + + + + + 100663355 + System.Void GeneratedDemo.UseMustacheGenerator::.ctor() + + + + + + + + + GeneratedDemo.UseXmlSettingsGenerator + + + + 100663356 + System.Void GeneratedDemo.UseXmlSettingsGenerator::Run() + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/OpenCoverWithPartials.cob.xml b/AltCover.Tests/OpenCoverWithPartials.cob.xml new file mode 100644 index 000000000..4a58f2d8f --- /dev/null +++ b/AltCover.Tests/OpenCoverWithPartials.cob.xml @@ -0,0 +1,143 @@ + + + + + C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include + C:\Users\steve\Documents\GitHub\altcover\Samples\Sample29\SimpleMix + d:\a01\_work\5\s\src\vctools\crt\crtw32\msilcrt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/OpenCoverWithPartials.lcov b/AltCover.Tests/OpenCoverWithPartials.lcov new file mode 100644 index 000000000..9a775e48a --- /dev/null +++ b/AltCover.Tests/OpenCoverWithPartials.lcov @@ -0,0 +1,67 @@ +TN: SimpleMix +SF:C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/include/vcclr.h +FN:41,System.Int32 ::main(System.String[]) +FN:41,System.Int32 Example::main(System.String[]) +FNDA:1,System.Int32 ::main(System.String[]) +FNDA:1,System.Int32 Example::main(System.String[]) +FNF:2 +FNH:2 +BRDA:42,13,0,1 +BRDA:42,13,1,- +BRDA:42,625,0,1 +BRDA:42,625,1,- +BRF:4 +BRH:2 +DA:41,1 +DA:42,1 +DA:43,1 +LH:3 +LF:3 +end_of_record +TN: SimpleMix +SF:C:/Users/steve/Documents/GitHub/altcover/Samples/Sample29/SimpleMix/SimpleMix.cpp +FN:38,System.Int32 ::main(System.String[]) +FN:25,System.Int32 Example::main(System.String[]) +FNDA:1,System.Int32 ::main(System.String[]) +FNDA:1,System.Int32 Example::main(System.String[]) +FNF:2 +FNH:2 +BRDA:38,11,0,1 +BRDA:38,11,1,- +BRF:2 +BRH:1 +DA:25,1 +DA:26,1 +DA:27,1 +DA:30,1 +DA:32,1 +DA:38,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:45,1 +DA:47,1 +DA:49,0 +LH:11 +LF:12 +end_of_record +TN: SimpleMix +SF:d:/a01/_work/5/s/src/vctools/crt/crtw32/msilcrt/mcrtexe.cpp +FN:223,System.Int32 ::mainCRTStartupStrArray(System.String[]) +FNDA:1,System.Int32 ::mainCRTStartupStrArray(System.String[]) +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:223,1 +DA:228,1 +DA:241,1 +DA:247,1 +DA:278,1 +DA:279,0 +DA:284,0 +DA:287,1 +DA:288,1 +LH:7 +LF:9 +end_of_record diff --git a/AltCover.Tests/OpenCoverWithPartials.xml b/AltCover.Tests/OpenCoverWithPartials.xml new file mode 100644 index 000000000..a45b8d5c7 --- /dev/null +++ b/AltCover.Tests/OpenCoverWithPartials.xml @@ -0,0 +1,116 @@ + + + + + + C:/Users/steve/Documents/GitHub/altcover/Samples/Sample29/Debug/SimpleMix.exe + 2021-10-30T13:04:37.9842657Z + SimpleMix + + + + + + + + + <Module> + + + + 100663297 + System.Int32 <Module>::main(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + + 100663341 + System.Int32 <Module>::mainCRTStartupStrArray(System.String[]) + + + + + + + + + + + + + + + + + 100663386 + System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::__FrameUnwindFilter(_EXCEPTION_POINTERS*) + + + + + + + + Example + + + + 100663387 + System.Int32 Example::main(System.String[]) + + + + + + + + + + + + + + + + + + + + 100663388 + System.Void Example::.ctor() + + + + + + + + + + C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll + 2021-04-08T04:26:00.6371167Z + System + + + + \ No newline at end of file diff --git a/AltCover.Tests/Runner.Tests.fs b/AltCover.Tests/Runner.Tests.fs index a06ce0983..df7ecb83a 100644 --- a/AltCover.Tests/Runner.Tests.fs +++ b/AltCover.Tests/Runner.Tests.fs @@ -60,9 +60,8 @@ module AltCoverRunnerTests = let ShouldFailXmlDataForNativeJson () = Assert.Throws (fun () -> - ReportFormat.NativeJson - |> Counter.I.xmlByFormat - |> ignore) + ignore (ReportFormat.NativeJson + |> Counter.I.xmlByFormat)) |> ignore [] @@ -510,7 +509,7 @@ module AltCoverRunnerTests = + "/GenuineNCover158.json" ) - Json.path := Some unique + Json.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -548,7 +547,7 @@ module AltCoverRunnerTests = .Replace("\r", String.Empty) .Replace("\n", String.Empty) @> finally - Json.path := None + Json.path.Value <- None [] let OpenCoverShouldGeneratePlausibleJson () = @@ -583,7 +582,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/OpenCover.json" ) - Json.path := Some unique + Json.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -624,7 +623,7 @@ module AltCoverRunnerTests = .Replace("\u00FF\u00FF", "\u00FF") .Trim([| '\u00FF' |]) @> finally - Json.path := None + Json.path.Value <- None // Runner.fs and CommandLine.fs [] @@ -969,7 +968,7 @@ module AltCoverRunnerTests = lock Runner.executable (fun () -> - Runner.executable := None + Runner.executable.Value <- None match CommandLine.parseCommandLine [| "/x"; "x" |] options |> CommandLine.processHelpOption with @@ -1002,7 +1001,7 @@ module AltCoverRunnerTests = lock Runner.executable (fun () -> - Runner.executable := None + Runner.executable.Value <- None match CommandLine.parseCommandLine [| "/x"; "x" |] options |> CommandLine.processHelpOption with @@ -1018,7 +1017,7 @@ module AltCoverRunnerTests = Runner.executable (fun () -> try - Runner.executable := None + Runner.executable.Value <- None let options = Runner.declareOptions () let unique = "some exe" let input = [| "-x"; unique |] @@ -1034,7 +1033,7 @@ module AltCoverRunnerTests = match Runner.executable.Value with | Some x -> Assert.That(Path.GetFileName x, Is.EqualTo unique) finally - Runner.executable := None) + Runner.executable.Value <- None) [] let ParsingMultipleExeGivesFailure () = @@ -1044,7 +1043,7 @@ module AltCoverRunnerTests = Runner.executable (fun () -> try - Runner.executable := None + Runner.executable.Value <- None let options = Runner.declareOptions () let unique = Guid.NewGuid().ToString() @@ -1067,7 +1066,7 @@ module AltCoverRunnerTests = Is.EqualTo "--executable : specify this only once" ) finally - Runner.executable := None) + Runner.executable.Value <- None) [] let ParsingNoExeGivesFailure () = @@ -1077,7 +1076,7 @@ module AltCoverRunnerTests = Runner.executable (fun () -> try - Runner.executable := None + Runner.executable.Value <- None let options = Runner.declareOptions () let blank = " " let input = [| "-x"; blank |] @@ -1090,7 +1089,7 @@ module AltCoverRunnerTests = Assert.That(y, Is.SameAs options) Assert.That(x, Is.EqualTo "UsageError") finally - Runner.executable := None) + Runner.executable.Value <- None) [] let ParsingWorkerGivesWorker () = @@ -1285,7 +1284,7 @@ module AltCoverRunnerTests = Runner.init () try - Runner.collect := false + Runner.collect.Value <- false let options = Runner.declareOptions () let input = [| "--collect" |] @@ -1299,14 +1298,14 @@ module AltCoverRunnerTests = Assert.That(Runner.collect.Value, Is.True) finally - Runner.collect := false + Runner.collect.Value <- false [] let ParsingMultipleCollectGivesFailure () = Runner.init () try - Runner.collect := false + Runner.collect.Value <- false let options = Runner.declareOptions () let input = [| "--collect"; "--collect" |] @@ -1323,7 +1322,7 @@ module AltCoverRunnerTests = Is.EqualTo "--collect : specify this only once" ) finally - Runner.collect := false + Runner.collect.Value <- false [] let ParsingLcovGivesLcov () = @@ -1333,7 +1332,7 @@ module AltCoverRunnerTests = LCov.path (fun () -> try - LCov.path := None + LCov.path.Value <- None Runner.I.initSummary () let options = Runner.declareOptions () @@ -1354,7 +1353,7 @@ module AltCoverRunnerTests = Assert.That(Runner.I.summaries.Length, Is.EqualTo 2) finally Runner.I.initSummary () - LCov.path := None) + LCov.path.Value <- None) [] let ParsingMultipleLcovGivesFailure () = @@ -1364,7 +1363,7 @@ module AltCoverRunnerTests = LCov.path (fun () -> try - LCov.path := None + LCov.path.Value <- None Runner.I.initSummary () let options = Runner.declareOptions () @@ -1390,7 +1389,7 @@ module AltCoverRunnerTests = ) finally Runner.I.initSummary () - LCov.path := None) + LCov.path.Value <- None) [] let ParsingNoLcovGivesFailure () = @@ -1400,7 +1399,7 @@ module AltCoverRunnerTests = LCov.path (fun () -> try - LCov.path := None + LCov.path.Value <- None Runner.I.initSummary () let options = Runner.declareOptions () @@ -1416,7 +1415,7 @@ module AltCoverRunnerTests = Assert.That(x, Is.EqualTo "UsageError") finally Runner.I.initSummary () - LCov.path := None) + LCov.path.Value <- None) [] let ParsingThresholdGivesThreshold () = @@ -1749,7 +1748,7 @@ module AltCoverRunnerTests = Cobertura.path (fun () -> try - Cobertura.path := None + Cobertura.path.Value <- None Runner.I.initSummary () let options = Runner.declareOptions () @@ -1770,7 +1769,7 @@ module AltCoverRunnerTests = Assert.That(Runner.I.summaries.Length, Is.EqualTo 2) finally Runner.I.initSummary () - Cobertura.path := None) + Cobertura.path.Value <- None) [] let ParsingMultipleCoberturaGivesFailure () = @@ -1780,7 +1779,7 @@ module AltCoverRunnerTests = Cobertura.path (fun () -> try - Cobertura.path := None + Cobertura.path.Value <- None Runner.I.initSummary () let options = Runner.declareOptions () @@ -1806,7 +1805,7 @@ module AltCoverRunnerTests = ) finally Runner.I.initSummary () - Cobertura.path := None) + Cobertura.path.Value <- None) [] let ParsingNoCoberturaGivesFailure () = @@ -1816,7 +1815,7 @@ module AltCoverRunnerTests = Cobertura.path (fun () -> try - Cobertura.path := None + Cobertura.path.Value <- None Runner.I.initSummary () let options = Runner.declareOptions () @@ -1832,7 +1831,7 @@ module AltCoverRunnerTests = Assert.That(x, Is.EqualTo "UsageError") finally Runner.I.initSummary () - Cobertura.path := None) + Cobertura.path.Value <- None) [] let ParsingOutputGivesOutput () = @@ -1863,7 +1862,7 @@ module AltCoverRunnerTests = try Runner.output <- None - Runner.collect := false + Runner.collect.Value <- false let options = Runner.declareOptions () let unique = Guid.NewGuid().ToString() @@ -1914,7 +1913,7 @@ module AltCoverRunnerTests = Runner.init () try - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false let options = Runner.declareOptions () let input = [| "--dropReturnCode" |] @@ -1928,14 +1927,14 @@ module AltCoverRunnerTests = Assert.That(CommandLine.dropReturnCode.Value, Is.True) finally - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false [] let ParsingMultipleDropGivesFailure () = Runner.init () try - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false let options = Runner.declareOptions () let input = @@ -1955,7 +1954,7 @@ module AltCoverRunnerTests = Is.EqualTo "--dropReturnCode : specify this only once" ) finally - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false [] let ParsingTCString () = @@ -2134,7 +2133,7 @@ module AltCoverRunnerTests = Runner.executable (fun () -> try - Runner.executable := None + Runner.executable.Value <- None let options = Runner.declareOptions () let parse = Runner.J.requireExe (Right([], options)) @@ -2143,7 +2142,7 @@ module AltCoverRunnerTests = Assert.That(y, Is.SameAs options) Assert.That(x, Is.EqualTo "UsageError") finally - Runner.executable := None) + Runner.executable.Value <- None) [] let ShouldAcceptExe () = @@ -2153,7 +2152,7 @@ module AltCoverRunnerTests = Runner.executable (fun () -> try - Runner.executable := Some "xxx" + Runner.executable.Value <- Some "xxx" let options = Runner.declareOptions () let parse = @@ -2165,7 +2164,7 @@ module AltCoverRunnerTests = Assert.That(x, Is.EqualTo "xxx") Assert.That(y, Is.EquivalentTo [ "b" ]) finally - Runner.executable := None) + Runner.executable.Value <- None) [] let ShouldRequireCollectIfNotExe () = @@ -2175,8 +2174,8 @@ module AltCoverRunnerTests = Runner.executable (fun () -> try - Runner.executable := None - Runner.collect := true + Runner.executable.Value <- None + Runner.collect.Value <- true let options = Runner.declareOptions () @@ -2186,8 +2185,8 @@ module AltCoverRunnerTests = match parse with | Right ([], z) -> Assert.That(z, Is.SameAs options) finally - Runner.collect := false - Runner.executable := None) + Runner.collect.Value <- false + Runner.executable.Value <- None) [] let ShouldRejectExeIfCollect () = @@ -2197,8 +2196,8 @@ module AltCoverRunnerTests = Runner.executable (fun () -> try - Runner.executable := Some "xxx" - Runner.collect := true + Runner.executable.Value <- Some "xxx" + Runner.collect.Value <- true let options = Runner.declareOptions () @@ -2210,8 +2209,8 @@ module AltCoverRunnerTests = Assert.That(y, Is.SameAs options) Assert.That(x, Is.EqualTo "UsageError") finally - Runner.collect := false - Runner.executable := None) + Runner.collect.Value <- false + Runner.executable.Value <- None) [] let ShouldRequireWorker () = @@ -2304,11 +2303,15 @@ module AltCoverRunnerTests = if create |> File.Exists |> not then do - let from = - Path.Combine(here, "AltCover.Recorder.dll") - + let recorder = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("AltCover.Recorder.net20.dll", StringComparison.Ordinal)) use frombytes = - new FileStream(from, FileMode.Open, FileAccess.Read) + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(recorder) use libstream = new FileStream(create, FileMode.Create) frombytes.CopyTo libstream @@ -2362,7 +2365,7 @@ module AltCoverRunnerTests = Assert.That(r2, Is.EqualTo 2) try - CommandLine.dropReturnCode := true + CommandLine.dropReturnCode.Value <- true let r0 = CommandLine.processTrailingArguments (args @ [ "1"; "2" ]) @@ -2370,7 +2373,7 @@ module AltCoverRunnerTests = Assert.That(r0, Is.EqualTo 0) finally - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false [] let ShouldProcessTrailingArguments () = @@ -2523,7 +2526,7 @@ module AltCoverRunnerTests = let ShouldGetStringConstants () = Runner.init () - let where = + let here = Assembly.GetExecutingAssembly().Location |> Path.GetDirectoryName @@ -2533,6 +2536,30 @@ module AltCoverRunnerTests = synchronized (fun () -> try + let where = + Path.Combine(here, Guid.NewGuid().ToString()) + + Directory.CreateDirectory(where) |> ignore + Runner.recordingDirectory <- Some where + + let create = + Path.Combine(where, "AltCover.Recorder.dll") + + if create |> File.Exists |> not then + do + let recorder = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("AltCover.Recorder.net20.dll", StringComparison.Ordinal)) + use frombytes = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(recorder) + + use libstream = new FileStream(create, FileMode.Create) + frombytes.CopyTo libstream + Runner.recordingDirectory <- Some where Runner.J.recorderName <- "AltCover.Recorder.dll" @@ -3259,7 +3286,7 @@ module AltCoverRunnerTests = Runner.init () try - Runner.collect := true + Runner.collect.Value <- true let counts = Dictionary>() @@ -3311,7 +3338,7 @@ module AltCoverRunnerTests = Assert.That(doc, Is.EqualTo DocumentType.Unknown) Assert.That(counts, Is.Empty) finally - Runner.collect := false + Runner.collect.Value <- false [] let JunkPayloadShouldReportAsExpected () = @@ -4580,7 +4607,7 @@ module AltCoverRunnerTests = let expected = "Visited Classes 0 of 0 (n/a)|Visited Methods 0 of 0 (n/a)|Visited Points 0 of 0 (n/a)|Visited Branches 0 of 0 (n/a)||" - // printfn "%s" <| builder.ToString() + //printfn "%s" <| builder.ToString() Assert.That(builder.ToString(), Is.EqualTo expected) let collected = @@ -4624,7 +4651,7 @@ module AltCoverRunnerTests = "##teamcity[buildStatisticValue key='CodeCoverageAbsCTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsCCovered' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsSTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsSCovered' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsBTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsBCovered' value='0']|" let result = builder.ToString() - // printfn "%s" result + //printfn "%s" result Assert.That(result, Is.EqualTo expected, result) let collected = @@ -4668,7 +4695,7 @@ module AltCoverRunnerTests = "Visited Classes 0 of 0 (n/a)|Visited Methods 0 of 0 (n/a)|Visited Points 0 of 0 (n/a)|Visited Branches 0 of 0 (n/a)||##teamcity[buildStatisticValue key='CodeCoverageAbsCTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsCCovered' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsSTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsSCovered' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsBTotal' value='0']|##teamcity[buildStatisticValue key='CodeCoverageAbsBCovered' value='0']|" let result = builder.ToString() - // printfn "%s" result + //printfn "%s" result Assert.That(result, Is.EqualTo expected, result) let collected = @@ -4798,8 +4825,8 @@ module AltCoverRunnerTests = Assert.That( builder.ToString(), Is.EqualTo( - "Visited Classes 4 of 6 (66.67)|Visited Methods 5 of 10 (50)|Visited Points 5 of 19 (26.32)|Visited Branches 5 of 10 (50)|" - + "|##teamcity[buildStatisticValue key='CodeCoverageAbsCTotal' value='6']|##teamcity[buildStatisticValue key='CodeCoverageAbsCCovered' value='4']|##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='10']|##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='5']|##teamcity[buildStatisticValue key='CodeCoverageAbsSTotal' value='19']|##teamcity[buildStatisticValue key='CodeCoverageAbsSCovered' value='5']|##teamcity[buildStatisticValue key='CodeCoverageAbsRTotal' value='10']|##teamcity[buildStatisticValue key='CodeCoverageAbsRCovered' value='5']|" + "Visited Classes 4 of 6 (66.67)|Visited Methods 5 of 10 (50)|Visited Points 5 of 20 (25)|Visited Branches 5 of 10 (50)|" + + "|##teamcity[buildStatisticValue key='CodeCoverageAbsCTotal' value='6']|##teamcity[buildStatisticValue key='CodeCoverageAbsCCovered' value='4']|##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='10']|##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='5']|##teamcity[buildStatisticValue key='CodeCoverageAbsSTotal' value='20']|##teamcity[buildStatisticValue key='CodeCoverageAbsSCovered' value='5']|##teamcity[buildStatisticValue key='CodeCoverageAbsRTotal' value='10']|##teamcity[buildStatisticValue key='CodeCoverageAbsRCovered' value='5']|" ) )) finally @@ -4816,7 +4843,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/None.lcov" ) - LCov.path := Some unique + LCov.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -4830,7 +4857,7 @@ module AltCoverRunnerTests = Assert.That(r, Is.EqualTo(0, 0, String.Empty)) Assert.That(unique |> File.Exists |> not) finally - LCov.path := None + LCov.path.Value <- None [] let OpenCoverShouldGeneratePlausibleLcov () = @@ -4857,7 +4884,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/OpenCover.lcov" ) - LCov.path := Some unique + LCov.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -4900,7 +4927,77 @@ module AltCoverRunnerTests = Is.EqualTo expected ) finally - LCov.path := None + LCov.path.Value <- None + + [] + let OpenCoverWithPartialsShouldGeneratePlausibleLcov () = + Runner.init () + + let resource = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find + (fun n -> n.EndsWith("OpenCoverWithPartials.xml", StringComparison.Ordinal)) + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource) + + let baseline = XDocument.Load(stream) + + let unique = + Path.Combine( + Assembly.GetExecutingAssembly().Location + |> Path.GetDirectoryName, + Guid.NewGuid().ToString() + "/OpenCoverWithPartials.lcov" + ) + + LCov.path.Value <- Some unique + + unique + |> Path.GetDirectoryName + |> Directory.CreateDirectory + |> ignore + + try + Runner.I.addLCovSummary () + let summarize = Runner.I.summaries |> Seq.head + + let r = + summarize (XML baseline) ReportFormat.OpenCover 0 + + Assert.That(r, Is.EqualTo(0, 0, String.Empty)) + let result = File.ReadAllText unique + + let resource2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("OpenCoverWithPartials.lcov", StringComparison.Ordinal)) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource2) + + use reader = new StreamReader(stream2) + //printfn "%A" result + let expected = + reader + .ReadToEnd() + .Replace("\r", String.Empty) + .Replace("\\", "/") + + Assert.That( + result + .Replace("\r", String.Empty) + .Replace("\\", "/"), + Is.EqualTo expected + ) + finally + LCov.path.Value <- None [] let NCoverShouldGeneratePlausibleLcov () = @@ -4926,7 +5023,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/NCover.lcov" ) - LCov.path := Some unique + LCov.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -4966,7 +5063,74 @@ module AltCoverRunnerTests = Is.EqualTo expected ) finally - LCov.path := None + LCov.path.Value <- None + + [] + let NCoverWithPartialsShouldGeneratePlausibleLcov () = + Runner.init () + + let resource = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("NCoverWithPartials.xml", StringComparison.Ordinal)) + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource) + + let baseline = XDocument.Load(stream) + + let unique = + Path.Combine( + Assembly.GetExecutingAssembly().Location + |> Path.GetDirectoryName, + Guid.NewGuid().ToString() + "/NCover.lcov" + ) + + LCov.path.Value <- Some unique + + unique + |> Path.GetDirectoryName + |> Directory.CreateDirectory + |> ignore + + try + let r = + LCov.summary (XML baseline) ReportFormat.NCover 0 + + Assert.That(r, Is.EqualTo(0, 0, String.Empty)) + let result = File.ReadAllText unique + //printfn "%s" result + + let resource2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("NCoverWithPartials.lcov", StringComparison.Ordinal)) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource2) + + use reader = new StreamReader(stream2) + + let expected = + reader + .ReadToEnd() + .Replace("\r", String.Empty) + .Replace("\\", "/") + + Assert.That( + result + .Replace("\r", String.Empty) + .Replace("\\", "/"), + Is.EqualTo expected + ) + finally + LCov.path.Value <- None [] let NCoverShouldGenerateMorePlausibleLcov () = @@ -4992,7 +5156,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/Sample5.ncover.lcov" ) - LCov.path := Some unique + LCov.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5005,7 +5169,7 @@ module AltCoverRunnerTests = Assert.That(r, Is.EqualTo(0, 0, String.Empty)) let result = File.ReadAllText unique - // printfn "%s" result + //printfn "%s" result let resource2 = Assembly .GetExecutingAssembly() @@ -5032,7 +5196,7 @@ module AltCoverRunnerTests = Is.EqualTo expected ) finally - LCov.path := None + LCov.path.Value <- None [] let JsonShouldGeneratePlausibleLcov () = @@ -5061,7 +5225,7 @@ module AltCoverRunnerTests = + "/Sample4.coverlet.lcov" ) - LCov.path := Some unique + LCov.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5102,7 +5266,77 @@ module AltCoverRunnerTests = Is.EqualTo expected ) finally - LCov.path := None + LCov.path.Value <- None + + [] + let JsonWithPartialsShouldGeneratePlausibleLcov () = + Runner.init () + + let resource = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("JsonWithPartials.json", StringComparison.Ordinal)) + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource) + + let baseline = + use r = new StreamReader(stream) + r.ReadToEnd() |> NativeJson.fromJsonText + + let unique = + Path.Combine( + Assembly.GetExecutingAssembly().Location + |> Path.GetDirectoryName, + Guid.NewGuid().ToString() + + "/JsonWithPartials.lcov" + ) + + LCov.path.Value <- Some unique + + unique + |> Path.GetDirectoryName + |> Directory.CreateDirectory + |> ignore + + try + let r = + LCov.summary (JSON baseline) ReportFormat.NativeJson 0 + + Assert.That(r, Is.EqualTo(0, 0, String.Empty)) + let result = File.ReadAllText unique + + let resource2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find + (fun n -> n.EndsWith("OpenCoverWithPartials.lcov", StringComparison.Ordinal)) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource2) + + use reader = new StreamReader(stream2) + + let expected = + reader + .ReadToEnd() + .Replace("\r", String.Empty) + .Replace("\\", "/") + //printfn "%s" result + Assert.That( + result + .Replace("\r", String.Empty) + .Replace("\\", "/"), + Is.EqualTo expected + ) + finally + LCov.path.Value <- None [] let NCoverShouldGeneratePlausibleLcovWithMissingFullName () = @@ -5135,7 +5369,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/NCoverBugFix.lcov" ) - LCov.path := Some unique + LCov.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5175,7 +5409,7 @@ module AltCoverRunnerTests = Is.EqualTo expected ) finally - LCov.path := None + LCov.path.Value <- None [] let MultiSortDoesItsThing () = @@ -5197,40 +5431,43 @@ module AltCoverRunnerTests = sprintf "" >> load >> (fun x -> x.Descendants(XName.Get "x") |> Seq.head) + >> (fun m -> (m, m.Descendants(XName.Get "seqpnt"))) ) |> List.toSeq)) |> List.toSeq let result = - LCov.I.multiSortByNameAndStartLine input + LCov.I.multiSortByNameAndPartialStartLine input |> Seq.map (fun (f, ms) -> (f, ms |> Seq.map - (fun m -> + (fun (m,l) -> m .ToString() .Replace("\r", String.Empty) .Replace("\n", String.Empty) - .Replace(" <", "<")) + .Replace(" <", "<") + + "|" + String.Join("|", l |> Seq.map string) + ) |> Seq.toList)) |> Seq.toList Assert.That( result, Is.EquivalentTo [ ("a", - [ """""" - """""" - """""" ]) + [ """|""" + """|""" + """|""" ]) ("m", - [ """""" - """""" - """""" ]) + [ """|""" + """|""" + """|""" ]) ("z", - [ """""" - """""" ]) ] + [ """|""" + """|""" ]) ] ) // Approved way is ugly -- https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2202?view=vs-2019 @@ -5266,7 +5503,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/None.cobertura" ) - Cobertura.path := Some unique + Cobertura.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5280,7 +5517,7 @@ module AltCoverRunnerTests = Assert.That(r, Is.EqualTo(0, 0, String.Empty)) Assert.That(unique |> File.Exists |> not) finally - Cobertura.path := None + Cobertura.path.Value <- None [] let NCoverShouldGeneratePlausibleCobertura () = @@ -5306,7 +5543,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/NCover122.cobertura" ) - Cobertura.path := Some unique + Cobertura.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5358,7 +5595,85 @@ module AltCoverRunnerTests = Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) validate result finally - Cobertura.path := None + Cobertura.path.Value <- None + + [] + let NCoverWithPartialsShouldGeneratePlausibleCobertura () = + Runner.init () + + let resource = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("NCoverWithPartials.xml", StringComparison.Ordinal)) + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource) + + let baseline = XDocument.Load(stream) + + let unique = + Path.Combine( + Assembly.GetExecutingAssembly().Location + |> Path.GetDirectoryName, + Guid.NewGuid().ToString() + "/NCoverWithPartials.cobertura" + ) + + Cobertura.path.Value <- Some unique + + unique + |> Path.GetDirectoryName + |> Directory.CreateDirectory + |> ignore + + try + Runner.I.addCoberturaSummary () + let summarize = Runner.I.summaries |> Seq.head + + let r = + summarize (XML baseline) ReportFormat.NCover 0 + + Assert.That(r, Is.EqualTo(0, 0, String.Empty)) + + let result = + Regex + .Replace(File.ReadAllText unique, + """timestamp=\"\d*\">""", + """timestamp="xx">""") + .Replace("\\", "/") + //printfn "%s" result + let resource2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("NCoverWithPartials.cob.xml", StringComparison.Ordinal)) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource2) + + use reader = new StreamReader(stream2) + + let expected = + reader + .ReadToEnd() + .Replace("\r", String.Empty) + .Replace("\\", "/") + .Replace( + """version="3.0.0.0""", + "version=\"" + + typeof + .Assembly.GetName() + .Version.ToString() + ) + + Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) + validate result + finally + Cobertura.path.Value <- None [] let NCoverShouldGenerateMorePlausibleCobertura () = @@ -5385,7 +5700,7 @@ module AltCoverRunnerTests = + "/Sample5.ncover.cobertura" ) - Cobertura.path := Some unique + Cobertura.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5407,7 +5722,7 @@ module AltCoverRunnerTests = """timestamp=\"\d*\">""", """timestamp="xx">""") .Replace("\\", "/") - // printfn "%s" result + //printfn "%s" result let resource2 = Assembly .GetExecutingAssembly() @@ -5438,7 +5753,7 @@ module AltCoverRunnerTests = Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) validate result finally - Cobertura.path := None + Cobertura.path.Value <- None [] let JsonShouldGeneratePlausibleCobertura () = @@ -5468,7 +5783,7 @@ module AltCoverRunnerTests = + "/Sample4FullTracking.cobertura" ) - Cobertura.path := Some unique + Cobertura.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5522,7 +5837,100 @@ module AltCoverRunnerTests = Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) validate result finally - Cobertura.path := None + Cobertura.path.Value <- None + + [] + let JsonWithPartialsShouldGeneratePlausibleCobertura () = + Runner.init () + + let resource = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find + (fun n -> n.EndsWith("JsonWithPartials.json", StringComparison.Ordinal)) + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource) + + let baseline = + use r = new StreamReader(stream) + r.ReadToEnd() |> NativeJson.fromJsonText + + let unique = + Path.Combine( + Assembly.GetExecutingAssembly().Location + |> Path.GetDirectoryName, + Guid.NewGuid().ToString() + + "/JsonWithPartials.cobertura" + ) + + Cobertura.path.Value <- Some unique + + unique + |> Path.GetDirectoryName + |> Directory.CreateDirectory + |> ignore + + try + Runner.I.addCoberturaSummary () + let summarize = Runner.I.summaries |> Seq.head + + let r = + summarize (JSON baseline) ReportFormat.NativeJson 0 + + Assert.That(r, Is.EqualTo(0, 0, String.Empty)) + + let result = + Regex + .Replace(File.ReadAllText unique, + """timestamp=\"\d*\">""", + """timestamp="xx">""") + .Replace("\\", "/") + //printfn "%s" result + let resource2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find + (fun n -> + n.EndsWith("OpenCoverWithPartials.cob.xml", StringComparison.Ordinal)) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource2) + + use reader = new StreamReader(stream2) + + let expected = + reader + .ReadToEnd() + .Replace("\r", String.Empty) + .Replace("\\", "/") + .Replace( + """version="3.0.0.0""", + "version=\"" + + typeof + .Assembly.GetName() + .Version.ToString() + ) + .Replace( // different computations TODO!! + """complexity="2.2""", + """complexity="1.8""") + .Replace( // different computations TODO!! + """complexity="2""", + """complexity="1""") + .Replace( // different computations TODO!! + """.cpp" line-rate="0.78" branch-rate="0""", + """.cpp" line-rate="0.78" branch-rate="1""") + + Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) + validate result + finally + Cobertura.path.Value <- None [] let JsonFromComplexNestingShouldGeneratePlausibleCobertura () = @@ -5551,7 +5959,7 @@ module AltCoverRunnerTests = + "/Sample5.native.cobertura" ) - Cobertura.path := Some unique + Cobertura.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5573,7 +5981,7 @@ module AltCoverRunnerTests = """timestamp=\"\d*\">""", """timestamp="xx">""") .Replace("\\", "/") - // printfn "%s" result + //printfn "%s" result let resource2 = Assembly .GetExecutingAssembly() @@ -5604,7 +6012,7 @@ module AltCoverRunnerTests = Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) validate result finally - Cobertura.path := None + Cobertura.path.Value <- None [] let JsonShouldGeneratePlausibleXml () = @@ -5649,7 +6057,7 @@ module AltCoverRunnerTests = Assembly .GetExecutingAssembly() .GetManifestResourceNames() - |> Seq.find (fun n -> n.EndsWith("Sample5.native.xml", StringComparison.Ordinal)) + |> Seq.find (fun n -> n.EndsWith("Sample5.raw-native.xml", StringComparison.Ordinal)) use stream2 = Assembly @@ -5684,6 +6092,85 @@ module AltCoverRunnerTests = .Replace("\u00FF\u00FF", "\u00FF") .Trim([| '\u00FF' |]) @> + [] + let JsonWithPartialsShouldGeneratePlausibleXml () = + Runner.init () + + let resource = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("JsonWithPartials.json", StringComparison.Ordinal)) + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource) + + let baseline = + use r = new StreamReader(stream) + r.ReadToEnd() |> NativeJson.fromJsonText + + let xml = + baseline + |> NativeJson.jsonToXml + |> NativeJson.orderXml + + let unique = + Path.Combine( + Assembly.GetExecutingAssembly().Location + |> Path.GetDirectoryName, + Guid.NewGuid().ToString() + "/JsonWithPartialsToRawXml.xml" + ) + + unique + |> Path.GetDirectoryName + |> Directory.CreateDirectory + |> ignore + + xml.Save(unique) + let result = File.ReadAllText unique + + let resource2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("JsonWithPartialsToRawXml.xml", StringComparison.Ordinal)) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource2) + + use reader = new StreamReader(stream2) + let expected = reader.ReadToEnd() + //printfn "%s" result + //Assert.That( + // result + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Trim([| '\u00FF' |]), + // Is.EqualTo + // <| expected + // .Replace('\r', '\u00FF') + // .Replace('\n', '\u00FF') + // .Replace("\u00FF\u00FF", "\u00FF") + // .Trim([| '\u00FF' |]), + // result + //) + + test + <@ result + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) = expected + .Replace('\r', '\u00FF') + .Replace('\n', '\u00FF') + .Replace("\u00FF\u00FF", "\u00FF") + .Trim([| '\u00FF' |]) @> + [] let NCoverShouldGeneratePlausibleCoberturaWithMissingFullName () = Runner.init () @@ -5715,7 +6202,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/NCover.cobertura" ) - Cobertura.path := Some unique + Cobertura.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5765,7 +6252,7 @@ module AltCoverRunnerTests = Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) validate result finally - Cobertura.path := None + Cobertura.path.Value <- None [] let OpenCoverShouldGeneratePlausibleCobertura () = @@ -5791,7 +6278,7 @@ module AltCoverRunnerTests = Guid.NewGuid().ToString() + "/issue122.cobertura" ) - Cobertura.path := Some unique + Cobertura.path.Value <- Some unique unique |> Path.GetDirectoryName @@ -5847,7 +6334,89 @@ module AltCoverRunnerTests = validate result finally - Cobertura.path := None + Cobertura.path.Value <- None + + [] + let OpenCoverWithPartialsShouldGeneratePlausibleCobertura () = + Runner.init () + + let resource = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("OpenCoverWithPartials.xml", StringComparison.Ordinal)) + + use stream = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource) + + let baseline = XDocument.Load(stream) + + let unique = + Path.Combine( + Assembly.GetExecutingAssembly().Location + |> Path.GetDirectoryName, + Guid.NewGuid().ToString() + "/OpenCoverWithPartials.cobertura" + ) + + Cobertura.path.Value <- Some unique + + unique + |> Path.GetDirectoryName + |> Directory.CreateDirectory + |> ignore + + try + let r = + Cobertura.summary (XML baseline) ReportFormat.OpenCover 0 + + Assert.That(r, Is.EqualTo(0, 0, String.Empty)) + + let result = + Regex.Replace( + File.ReadAllText unique, + """timestamp=\"\d*\">""", + """timestamp="xx">""" + ) + //printfn "%s" result + let resource2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("OpenCoverWithPartials.cob.xml", StringComparison.Ordinal)) + + use stream2 = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(resource2) + + use reader = new StreamReader(stream2) + + let expected = + reader + .ReadToEnd() + .Replace("\r", String.Empty) + .Replace("\\", "/") + .Replace( + """version="3.0.0.0""", + "version=\"" + + typeof + .Assembly.GetName() + .Version.ToString() + ) + + Assert.That( + result + .Replace("\r", String.Empty) + .Replace("\\", "/"), + Is.EqualTo expected, + result + ) + + validate result + finally + Cobertura.path.Value <- None [] let ThresholdViolationShouldBeReported () = diff --git a/AltCover.Tests/Sample1WithOpenCover.xml b/AltCover.Tests/Sample1WithOpenCover.xml index d30ae619f..7d26274be 100644 --- a/AltCover.Tests/Sample1WithOpenCover.xml +++ b/AltCover.Tests/Sample1WithOpenCover.xml @@ -20,7 +20,7 @@ 2018-02-22T08:50:13.1034471Z Sample1 - + diff --git a/AltCover.Tests/Sample4.coverlet.lcov b/AltCover.Tests/Sample4.coverlet.lcov index 0cb5a65b9..4521ed2ea 100644 --- a/AltCover.Tests/Sample4.coverlet.lcov +++ b/AltCover.Tests/Sample4.coverlet.lcov @@ -1,4 +1,4 @@ -TN: +TN: Sample4 SF:C:\Users\steve\source\repos\ClassLibrary1\Sample4\Program.fs FN:1,System.Int32 Program/Program::main(System.String[]) FNDA:0,System.Int32 Program/Program::main(System.String[]) @@ -10,7 +10,7 @@ DA:1,0 LH:0 LF:1 end_of_record -TN: +TN: Sample4 SF:C:\Users\steve\source\repos\ClassLibrary1\Sample4\Tests.fs FN:49,Tests.DU/MyUnion Tests.DU::returnFoo(System.Int32) FN:50,Tests.DU/MyUnion Tests.DU::returnBar(System.String) @@ -33,7 +33,7 @@ FNDA:2,Tests.M/Thing Tests.M::makeThing(System.String) FNDA:1,System.Void Tests.M::testMakeThing() FNDA:1,System.Byte[] Tests.M/Thing::bytes() FNF:10 -FNH:0 +FNH:7 BRDA:54,0,0,1 BRDA:54,0,1,- BRDA:54,0,0,1 diff --git a/AltCover.Tests/Sample4.fromcoverletjson.xml b/AltCover.Tests/Sample4.fromcoverletjson.xml index 906004ffc..6bde1b0bc 100644 --- a/AltCover.Tests/Sample4.fromcoverletjson.xml +++ b/AltCover.Tests/Sample4.fromcoverletjson.xml @@ -1,9 +1,9 @@  - + - + Sample4.dll Sample4 @@ -12,10 +12,11 @@ + Program/Program - - + + 0 System.Int32 Program/Program::main(System.String[]) @@ -23,15 +24,16 @@ - + + Tests.DU - - + + 0 Tests.DU/MyUnion Tests.DU::returnFoo(System.Int32) @@ -39,10 +41,10 @@ - + - - + + 0 Tests.DU/MyUnion Tests.DU::returnBar(System.String) @@ -50,10 +52,10 @@ - + - - + + 0 System.Void Tests.DU::testMakeUnion() @@ -76,15 +78,16 @@ - + + Tests.DU/MyUnion - - + + 0 Tests.DU/MyUnion Tests.DU/MyUnion::as_bar() @@ -103,10 +106,10 @@ - + - - + + 0 Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Tests.DU/MyUnion> Tests.DU/MyUnion::get_MyBar() @@ -114,15 +117,16 @@ - + + Tests.DU/MyClass - - + + 0 System.Int32 Tests.DU/MyClass::get_Property() @@ -130,10 +134,10 @@ - + - - + + 0 System.Void Tests.DU/MyClass::.ctor() @@ -141,15 +145,16 @@ - + + Tests.M - - + + 0 Tests.M/Thing Tests.M::makeThing(System.String) @@ -157,10 +162,10 @@ - + - - + + 0 System.Void Tests.M::testMakeThing() @@ -178,15 +183,16 @@ - + + Tests.M/Thing - - + + 0 System.Byte[] Tests.M/Thing::bytes() @@ -194,7 +200,7 @@ - + diff --git a/AltCover.Tests/Sample4.native.json b/AltCover.Tests/Sample4.native.json index 25ccfa04a..dce24ee64 100644 --- a/AltCover.Tests/Sample4.native.json +++ b/AltCover.Tests/Sample4.native.json @@ -1,6 +1,6 @@ { "Sample4.dll": { - "Tests.fs": { + "/_//Samples/Sample4/Tests.fs": { "Tests.Program": { "System.Int32 Tests.Program::main(System.String[])": { "Lines": { @@ -14,7 +14,7 @@ "SC": 16, "EL": 61, "EC": 17, - "Offset": 2, + "Offset": 0, "Id": 0 } ] @@ -64,16 +64,16 @@ "Branches": [ { "Line": 54, - "Offset": 209, - "EndOffset": 257, + "Offset": 207, + "EndOffset": 247, "Path": 0, "Ordinal": 0, "Hits": 0 }, { "Line": 54, - "Offset": 209, - "EndOffset": 218, + "Offset": 207, + "EndOffset": 212, "Path": 1, "Ordinal": 1, "Hits": 0, @@ -81,8 +81,8 @@ }, { "Line": 55, - "Offset": 475, - "EndOffset": 524, + "Offset": 463, + "EndOffset": 504, "Path": 0, "Ordinal": 2, "Hits": 0, @@ -90,8 +90,8 @@ }, { "Line": 55, - "Offset": 475, - "EndOffset": 484, + "Offset": 463, + "EndOffset": 468, "Path": 1, "Ordinal": 3, "Hits": 0, @@ -104,8 +104,8 @@ "SL": 56, "SC": 5, "EL": 56, - "EC": 9, - "Offset": 765, + "EC": 44, + "Offset": 738, "Id": 3 }, { @@ -114,7 +114,7 @@ "SC": 5, "EL": 56, "EC": 44, - "Offset": 524, + "Offset": 504, "Id": 4 }, { @@ -122,8 +122,8 @@ "SL": 55, "SC": 5, "EL": 55, - "EC": 9, - "Offset": 517, + "EC": 39, + "Offset": 500, "Id": 5 }, { @@ -132,7 +132,7 @@ "SC": 5, "EL": 55, "EC": 39, - "Offset": 257, + "Offset": 247, "Id": 6 }, { @@ -140,8 +140,8 @@ "SL": 54, "SC": 5, "EL": 54, - "EC": 9, - "Offset": 250, + "EC": 37, + "Offset": 243, "Id": 7 }, { @@ -162,6 +162,7 @@ "Tests.DU/MyUnion": { "Tests.DU/MyUnion Tests.DU/MyUnion::as_bar()": { "Lines": { + "35": 0, "36": 0, "37": 0, "38": 0, @@ -172,8 +173,8 @@ "Branches": [ { "Line": 36, - "Offset": 8, - "EndOffset": 183, + "Offset": 9, + "EndOffset": 178, "Path": 0, "Ordinal": 0, "Hits": 0, @@ -181,8 +182,8 @@ }, { "Line": 36, - "Offset": 8, - "EndOffset": 40, + "Offset": 9, + "EndOffset": 35, "Path": 1, "Ordinal": 1, "Hits": 0, @@ -190,8 +191,8 @@ }, { "Line": 36, - "Offset": 8, - "EndOffset": 91, + "Offset": 9, + "EndOffset": 86, "Path": 2, "Ordinal": 2, "Hits": 0, @@ -199,8 +200,8 @@ }, { "Line": 36, - "Offset": 8, - "EndOffset": 137, + "Offset": 9, + "EndOffset": 132, "Path": 3, "Ordinal": 3, "Hits": 0, @@ -214,7 +215,7 @@ "SC": 17, "EL": 42, "EC": 27, - "Offset": 194, + "Offset": 189, "Id": 9 }, { @@ -223,7 +224,7 @@ "SC": 7, "EL": 42, "EC": 11, - "Offset": 187, + "Offset": 182, "Id": 10 }, { @@ -232,7 +233,7 @@ "SC": 16, "EL": 41, "EC": 20, - "Offset": 183, + "Offset": 178, "Id": 11 }, { @@ -241,35 +242,17 @@ "SC": 20, "EL": 39, "EC": 33, - "Offset": 154, + "Offset": 149, "Id": 12 }, - { - "VC": 0, - "SL": 36, - "SC": 9, - "EL": 36, - "EC": 24, - "Offset": 137, - "Id": 13 - }, { "VC": 0, "SL": 38, "SC": 20, "EL": 38, "EC": 33, - "Offset": 108, - "Id": 14 - }, - { - "VC": 0, - "SL": 36, - "SC": 9, - "EL": 36, - "EC": 24, - "Offset": 91, - "Id": 15 + "Offset": 103, + "Id": 13 }, { "VC": 0, @@ -277,8 +260,8 @@ "SC": 20, "EL": 37, "EC": 33, - "Offset": 54, - "Id": 16 + "Offset": 49, + "Id": 14 }, { "VC": 0, @@ -286,8 +269,17 @@ "SC": 9, "EL": 36, "EC": 24, + "Offset": 1, + "Id": 15 + }, + { + "VC": 0, + "SL": 35, + "SC": 7, + "EL": 35, + "EC": 10, "Offset": 0, - "Id": 17 + "Id": 16 } ] }, @@ -304,7 +296,7 @@ "EL": 44, "EC": 36, "Offset": 0, - "Id": 18 + "Id": 17 }, { "VC": 0, @@ -313,7 +305,7 @@ "EL": 44, "EC": 36, "Offset": 0, - "Id": 19 + "Id": 18 } ] } @@ -333,7 +325,7 @@ "EL": 46, "EC": 15, "Offset": 15, - "Id": 20 + "Id": 19 }, { "VC": 0, @@ -342,7 +334,7 @@ "EL": 47, "EC": 28, "Offset": 8, - "Id": 21 + "Id": 20 } ] } @@ -361,7 +353,7 @@ "EL": 20, "EC": 34, "Offset": 0, - "Id": 22 + "Id": 21 } ] }, @@ -373,8 +365,8 @@ "Branches": [ { "Line": 24, - "Offset": 209, - "EndOffset": 257, + "Offset": 207, + "EndOffset": 247, "Path": 0, "Ordinal": 0, "Hits": 0, @@ -382,8 +374,8 @@ }, { "Line": 24, - "Offset": 209, - "EndOffset": 218, + "Offset": 207, + "EndOffset": 212, "Path": 1, "Ordinal": 1, "Hits": 0, @@ -396,9 +388,9 @@ "SL": 25, "SC": 5, "EL": 25, - "EC": 9, - "Offset": 568, - "Id": 23 + "EC": 54, + "Offset": 551, + "Id": 22 }, { "VC": 0, @@ -406,17 +398,17 @@ "SC": 5, "EL": 25, "EC": 54, - "Offset": 257, - "Id": 24 + "Offset": 247, + "Id": 23 }, { "VC": 0, "SL": 24, "SC": 5, "EL": 24, - "EC": 9, - "Offset": 250, - "Id": 25 + "EC": 43, + "Offset": 243, + "Id": 24 }, { "VC": 0, @@ -425,7 +417,7 @@ "EL": 24, "EC": 43, "Offset": 0, - "Id": 26 + "Id": 25 } ] } @@ -444,7 +436,7 @@ "EL": 18, "EC": 73, "Offset": 0, - "Id": 27 + "Id": 26 } ] } diff --git a/AltCover.Tests/Sample4.syntheticvisits.native.json b/AltCover.Tests/Sample4.syntheticvisits.native.json index ce444f9e1..89dc891dc 100644 --- a/AltCover.Tests/Sample4.syntheticvisits.native.json +++ b/AltCover.Tests/Sample4.syntheticvisits.native.json @@ -1,6 +1,6 @@ { "Sample4.dll": { - "Tests.fs": { + "/_//Samples/Sample4/Tests.fs": { "Tests.Program": { "System.Int32 Tests.Program::main(System.String[])": { "Lines": { @@ -14,7 +14,7 @@ "SC": 16, "EL": 61, "EC": 17, - "Offset": 2, + "Offset": 0, "Id": 0 } ] @@ -69,16 +69,16 @@ "Branches": [ { "Line": 54, - "Offset": 209, - "EndOffset": 257, + "Offset": 207, + "EndOffset": 247, "Path": 0, "Ordinal": 0, "Hits": 0 }, { "Line": 54, - "Offset": 209, - "EndOffset": 218, + "Offset": 207, + "EndOffset": 212, "Path": 1, "Ordinal": 1, "Hits": 2, @@ -90,8 +90,8 @@ }, { "Line": 55, - "Offset": 475, - "EndOffset": 524, + "Offset": 463, + "EndOffset": 504, "Path": 0, "Ordinal": 2, "Hits": 0, @@ -99,8 +99,8 @@ }, { "Line": 55, - "Offset": 475, - "EndOffset": 484, + "Offset": 463, + "EndOffset": 468, "Path": 1, "Ordinal": 3, "Hits": 4, @@ -125,8 +125,8 @@ "SL": 56, "SC": 5, "EL": 56, - "EC": 9, - "Offset": 765, + "EC": 44, + "Offset": 738, "Id": 3 }, { @@ -135,7 +135,7 @@ "SC": 5, "EL": 56, "EC": 44, - "Offset": 524, + "Offset": 504, "Id": 4 }, { @@ -143,8 +143,8 @@ "SL": 55, "SC": 5, "EL": 55, - "EC": 9, - "Offset": 517, + "EC": 39, + "Offset": 500, "Id": 5 }, { @@ -153,7 +153,7 @@ "SC": 5, "EL": 55, "EC": 39, - "Offset": 257, + "Offset": 247, "Id": 6, "Times": [ "AAAAAAAAAAA=", @@ -170,8 +170,8 @@ "SL": 54, "SC": 5, "EL": 54, - "EC": 9, - "Offset": 250, + "EC": 37, + "Offset": 243, "Id": 7 }, { @@ -198,6 +198,7 @@ "Tests.DU/MyUnion": { "Tests.DU/MyUnion Tests.DU/MyUnion::as_bar()": { "Lines": { + "35": 0, "36": 0, "37": 0, "38": 0, @@ -208,8 +209,8 @@ "Branches": [ { "Line": 36, - "Offset": 8, - "EndOffset": 183, + "Offset": 9, + "EndOffset": 178, "Path": 0, "Ordinal": 0, "Hits": 0, @@ -217,8 +218,8 @@ }, { "Line": 36, - "Offset": 8, - "EndOffset": 40, + "Offset": 9, + "EndOffset": 35, "Path": 1, "Ordinal": 1, "Hits": 6, @@ -234,8 +235,8 @@ }, { "Line": 36, - "Offset": 8, - "EndOffset": 91, + "Offset": 9, + "EndOffset": 86, "Path": 2, "Ordinal": 2, "Hits": 0, @@ -243,8 +244,8 @@ }, { "Line": 36, - "Offset": 8, - "EndOffset": 137, + "Offset": 9, + "EndOffset": 132, "Path": 3, "Ordinal": 3, "Hits": 8, @@ -278,7 +279,7 @@ "SC": 17, "EL": 42, "EC": 27, - "Offset": 194, + "Offset": 189, "Id": 9 }, { @@ -287,7 +288,7 @@ "SC": 7, "EL": 42, "EC": 11, - "Offset": 187, + "Offset": 182, "Id": 10 }, { @@ -296,7 +297,7 @@ "SC": 16, "EL": 41, "EC": 20, - "Offset": 183, + "Offset": 178, "Id": 11 }, { @@ -305,35 +306,17 @@ "SC": 20, "EL": 39, "EC": 33, - "Offset": 154, + "Offset": 149, "Id": 12 }, - { - "VC": 0, - "SL": 36, - "SC": 9, - "EL": 36, - "EC": 24, - "Offset": 137, - "Id": 13 - }, { "VC": 0, "SL": 38, "SC": 20, "EL": 38, "EC": 33, - "Offset": 108, - "Id": 14 - }, - { - "VC": 0, - "SL": 36, - "SC": 9, - "EL": 36, - "EC": 24, - "Offset": 91, - "Id": 15 + "Offset": 103, + "Id": 13 }, { "VC": 0, @@ -341,8 +324,8 @@ "SC": 20, "EL": 37, "EC": 33, - "Offset": 54, - "Id": 16 + "Offset": 49, + "Id": 14 }, { "VC": 0, @@ -350,8 +333,17 @@ "SC": 9, "EL": 36, "EC": 24, + "Offset": 1, + "Id": 15 + }, + { + "VC": 0, + "SL": 35, + "SC": 7, + "EL": 35, + "EC": 10, "Offset": 0, - "Id": 17 + "Id": 16 } ] }, @@ -368,7 +360,7 @@ "EL": 44, "EC": 36, "Offset": 0, - "Id": 18 + "Id": 17 }, { "VC": 0, @@ -377,7 +369,7 @@ "EL": 44, "EC": 36, "Offset": 0, - "Id": 19 + "Id": 18 } ] } @@ -397,7 +389,7 @@ "EL": 46, "EC": 15, "Offset": 15, - "Id": 20 + "Id": 19 }, { "VC": 0, @@ -406,7 +398,7 @@ "EL": 47, "EC": 28, "Offset": 8, - "Id": 21 + "Id": 20 } ] } @@ -425,7 +417,7 @@ "EL": 20, "EC": 34, "Offset": 0, - "Id": 22 + "Id": 21 } ] }, @@ -437,8 +429,8 @@ "Branches": [ { "Line": 24, - "Offset": 209, - "EndOffset": 257, + "Offset": 207, + "EndOffset": 247, "Path": 0, "Ordinal": 0, "Hits": 0, @@ -446,8 +438,8 @@ }, { "Line": 24, - "Offset": 209, - "EndOffset": 218, + "Offset": 207, + "EndOffset": 212, "Path": 1, "Ordinal": 1, "Hits": 10, @@ -472,9 +464,9 @@ "SL": 25, "SC": 5, "EL": 25, - "EC": 9, - "Offset": 568, - "Id": 23 + "EC": 54, + "Offset": 551, + "Id": 22 }, { "VC": 0, @@ -482,17 +474,17 @@ "SC": 5, "EL": 25, "EC": 54, - "Offset": 257, - "Id": 24 + "Offset": 247, + "Id": 23 }, { "VC": 0, "SL": 24, "SC": 5, "EL": 24, - "EC": 9, - "Offset": 250, - "Id": 25 + "EC": 43, + "Offset": 243, + "Id": 24 }, { "VC": 0, @@ -501,7 +493,7 @@ "EL": 24, "EC": 43, "Offset": 0, - "Id": 26 + "Id": 25 } ] } @@ -520,7 +512,7 @@ "EL": 18, "EC": 73, "Offset": 0, - "Id": 27 + "Id": 26 } ] } diff --git a/AltCover.Tests/Sample4FullTracking.cobertura b/AltCover.Tests/Sample4FullTracking.cobertura index 22e3123ec..892ed0ed3 100644 --- a/AltCover.Tests/Sample4FullTracking.cobertura +++ b/AltCover.Tests/Sample4FullTracking.cobertura @@ -7,7 +7,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -129,7 +129,7 @@ - + diff --git a/AltCover.Tests/Sample4FullTracking.xml b/AltCover.Tests/Sample4FullTracking.xml index f273d8271..f062fd250 100644 --- a/AltCover.Tests/Sample4FullTracking.xml +++ b/AltCover.Tests/Sample4FullTracking.xml @@ -8,7 +8,7 @@ 2021-01-23T09:14:51.5044232Z Sample4 - + diff --git a/AltCover.Tests/Sample5.native.xml b/AltCover.Tests/Sample5.native.xml index d3e6afc35..43b813676 100644 --- a/AltCover.Tests/Sample5.native.xml +++ b/AltCover.Tests/Sample5.native.xml @@ -1,9 +1,9 @@ - + - + - + Sample5.dll Sample5 @@ -12,10 +12,11 @@ + Sample5.Class1 - - + + 0 System.Int32 Sample5.Class1::F1(System.String) @@ -39,10 +40,10 @@ - + - - + + 0 System.Collections.Generic.IEnumerable`1<System.Int32> Sample5.Class1::F2(System.String) @@ -61,10 +62,10 @@ - + - - + + 0 System.Threading.Tasks.Task`1<System.String> Sample5.Class1::F3(System.String) @@ -76,15 +77,16 @@ - + + Sample5.Class1/Inner - - + + 0 System.Int32 Sample5.Class1/Inner::G1(System.String) @@ -111,10 +113,10 @@ - + - - + + 0 System.Void Sample5.Class1/Inner::G1(System.Int32) @@ -124,10 +126,10 @@ - + - - + + 0 System.Void Sample5.Class1/Inner::G2(System.Int32) @@ -137,10 +139,10 @@ - + - - + + 0 System.Void Sample5.Class1/Inner::G3(System.Int32) @@ -150,10 +152,10 @@ - + - - + + 0 System.Collections.Generic.IEnumerable`1<T> Sample5.Class1/Inner::G2(T) @@ -173,10 +175,10 @@ - + - - + + 0 System.Threading.Tasks.Task`1<System.String> Sample5.Class1/Inner::G3(System.String) @@ -188,15 +190,16 @@ - + + Sample5.RecursiveSyntheticInvocation`2 - - + + 0 System.Collections.Generic.IEnumerable`1<T> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.get_Keys() @@ -206,10 +209,10 @@ - + - - + + 0 K Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.get_Item(T) @@ -217,10 +220,10 @@ - + - - + + 0 System.Int32 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<T,K>>.get_Count() @@ -228,10 +231,10 @@ - + - - + + 0 System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.ContainsKey(T) @@ -239,10 +242,10 @@ - + - - + + 0 System.Collections.Generic.IEnumerator`1<System.Collections.Generic.KeyValuePair`2<T,K>> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<T,K>>.GetEnumerator() @@ -250,10 +253,10 @@ - + - - + + 0 System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2::System.Collections.IEnumerable.GetEnumerator() @@ -261,10 +264,10 @@ - + - - + + 0 System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.TryGetValue(T,K&) @@ -272,10 +275,10 @@ - + - - + + 0 System.Collections.Generic.IEnumerable`1<K> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.get_Values() @@ -284,10 +287,10 @@ - + - - + + 0 System.Collections.Generic.IEnumerable`1<K> Sample5.RecursiveSyntheticInvocation`2::get_ValuesWorks() @@ -297,7 +300,7 @@ - + diff --git a/AltCover.Tests/Sample5.ncover.lcov b/AltCover.Tests/Sample5.ncover.lcov index cbef259aa..92915210f 100644 --- a/AltCover.Tests/Sample5.ncover.lcov +++ b/AltCover.Tests/Sample5.ncover.lcov @@ -1,4 +1,4 @@ -TN: +TN: Sample5, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null SF:altcover/Sample5/Class1.cs FN:12,System.Int32 Sample5.Class1.F1(System.String) FN:14,System.Int32 Sample5.Class1+<>c.b__0_0(System.Char) @@ -16,25 +16,22 @@ BRF:0 BRH:0 DA:12,0 DA:14,0 -DA:30,0 -DA:35,0 -DA:14,0 -DA:14,0 -DA:14,0 DA:18,0 -DA:25,0 -DA:26,0 DA:21,0 DA:22,0 DA:23,0 +DA:25,0 +DA:26,0 +DA:30,0 DA:31,0 DA:32,0 DA:33,0 DA:34,0 +DA:35,0 LH:0 -LF:17 +LF:14 end_of_record -TN: +TN: Sample5, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null SF:altcover/Sample5/Class1a.cs FN:15,System.Boolean Sample5.Class1+d__1.MoveNext() FN:25,System.Void Sample5.Class1+d__2.MoveNext() @@ -86,12 +83,9 @@ BRF:0 BRH:0 DA:15,0 DA:17,0 -DA:17,0 -DA:17,0 DA:18,0 DA:19,0 DA:20,0 -DA:17,0 DA:21,0 DA:25,0 DA:27,0 @@ -100,36 +94,30 @@ DA:29,0 DA:30,0 DA:37,0 DA:39,0 -DA:60,0 -DA:65,0 -DA:39,0 -DA:39,0 -DA:39,0 DA:42,0 DA:43,0 DA:44,0 DA:48,0 -DA:55,0 -DA:56,0 DA:51,0 DA:52,0 DA:53,0 +DA:55,0 +DA:56,0 +DA:60,0 DA:61,0 DA:62,0 DA:63,0 DA:64,0 +DA:65,0 DA:68,0 DA:69,0 DA:70,0 DA:74,0 DA:76,0 DA:77,0 -DA:77,0 -DA:77,0 DA:78,0 DA:79,0 DA:80,0 -DA:77,0 DA:81,0 DA:84,0 DA:85,0 @@ -143,13 +131,10 @@ DA:98,0 DA:99,0 DA:100,0 DA:117,0 -DA:117,0 DA:126,0 DA:127,0 DA:128,0 DA:137,0 -DA:137,0 -DA:137,0 DA:143,0 DA:144,0 DA:146,0 @@ -157,5 +142,5 @@ DA:148,0 DA:150,0 DA:152,0 LH:0 -LF:72 +LF:60 end_of_record diff --git a/AltCover.Tests/Sample5.raw-native.xml b/AltCover.Tests/Sample5.raw-native.xml new file mode 100644 index 000000000..cf8d70fb0 --- /dev/null +++ b/AltCover.Tests/Sample5.raw-native.xml @@ -0,0 +1,310 @@ + + + + + + + Sample5.dll + Sample5 + + + + + + + + Sample5.Class1 + + + + 0 + System.Int32 Sample5.Class1::F1(System.String) + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + System.Collections.Generic.IEnumerable`1<System.Int32> Sample5.Class1::F2(System.String) + + + + + + + + + + + + + + + + + + + + + 0 + System.Threading.Tasks.Task`1<System.String> Sample5.Class1::F3(System.String) + + + + + + + + + + + + + + + + Sample5.Class1/Inner + + + + 0 + System.Int32 Sample5.Class1/Inner::G1(System.String) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + System.Void Sample5.Class1/Inner::G1(System.Int32) + + + + + + + + + + + + 0 + System.Void Sample5.Class1/Inner::G2(System.Int32) + + + + + + + + + + + + 0 + System.Void Sample5.Class1/Inner::G3(System.Int32) + + + + + + + + + + + + 0 + System.Collections.Generic.IEnumerable`1<T> Sample5.Class1/Inner::G2(T) + + + + + + + + + + + + + + + + + + + + + + 0 + System.Threading.Tasks.Task`1<System.String> Sample5.Class1/Inner::G3(System.String) + + + + + + + + + + + + + + + + Sample5.RecursiveSyntheticInvocation`2 + + + + 0 + System.Collections.Generic.IEnumerable`1<T> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.get_Keys() + + + + + + + + + + + + 0 + K Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.get_Item(T) + + + + + + + + + + 0 + System.Int32 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<T,K>>.get_Count() + + + + + + + + + + 0 + System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.ContainsKey(T) + + + + + + + + + + 0 + System.Collections.Generic.IEnumerator`1<System.Collections.Generic.KeyValuePair`2<T,K>> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<T,K>>.GetEnumerator() + + + + + + + + + + 0 + System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2::System.Collections.IEnumerable.GetEnumerator() + + + + + + + + + + 0 + System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.TryGetValue(T,K&) + + + + + + + + + + 0 + System.Collections.Generic.IEnumerable`1<K> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary<T,K>.get_Values() + + + + + + + + + + + 0 + System.Collections.Generic.IEnumerable`1<K> Sample5.RecursiveSyntheticInvocation`2::get_ValuesWorks() + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Tests/SimpleMix.exe b/AltCover.Tests/SimpleMix.exe new file mode 100644 index 000000000..d6905b631 Binary files /dev/null and b/AltCover.Tests/SimpleMix.exe differ diff --git a/AltCover.Tests/SimpleMix.exe.metagen b/AltCover.Tests/SimpleMix.exe.metagen new file mode 100644 index 000000000..dc26631eb --- /dev/null +++ b/AltCover.Tests/SimpleMix.exe.metagen @@ -0,0 +1,7 @@ +ImageRuntimeVersion: v4.0.30319 +Assembly SimpleMix, Version=1.0.*, Culture=Invariant Language (Invariant Country): + hash=SHA1, flags=PublicKey +Assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: + hash=None, flags=None +Assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: + hash=None, flags=None diff --git a/AltCover.Tests/SimpleMix.pdb b/AltCover.Tests/SimpleMix.pdb new file mode 100644 index 000000000..16b866cac Binary files /dev/null and b/AltCover.Tests/SimpleMix.pdb differ diff --git a/AltCover.Tests/Tests.fs b/AltCover.Tests/Tests.fs index dd02b130b..9436f1abd 100644 --- a/AltCover.Tests/Tests.fs +++ b/AltCover.Tests/Tests.fs @@ -64,7 +64,7 @@ module AltCoverTests = #if !NET472 let dir = - Path.Combine(SolutionDir(), "_Binaries/AltCover.Tests/Debug+AnyCPU/net5.0") + Path.Combine(SolutionDir(), "_Binaries/AltCover.Tests/Debug+AnyCPU/net6.0") #else let dir = Path.Combine(SolutionDir(), "_Binaries/AltCover.Tests/Debug+AnyCPU/net472") @@ -140,139 +140,36 @@ module AltCoverTests = [] let ShouldGetPdbFromImage () = let files = - Directory.GetFiles(dir) + [ + Directory.GetFiles(dir, "AltCover*") + Directory.GetFiles(dir, "Sample*") + ] + |> Seq.concat |> Seq.filter (fun x -> x.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || x.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun f -> - f |> Path.GetFileNameWithoutExtension - <> "testhost") |> Seq.filter (fun f -> f |> Path.GetFileName <> "AltCover.Tests.exe") - |> Seq.filter (fun f -> f |> Path.GetFileName <> "CompilerAttributes.dll") + |> Seq.filter (fun f -> f |> Path.GetFileName <> "AltCover.Recorder.g.dll") |> Seq.map (fun x -> (x, Mono.Cecil.AssemblyDefinition.ReadAssembly x)) |> Seq.filter (fun x -> (fst x) + ".mdb" |> File.Exists |> not) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("altcode.", StringComparison.OrdinalIgnoreCase)) -#if !NET472 - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("Expecto", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("ICSharp", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("Mono.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("BlackFox.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("Microsoft.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("Manatee.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("Newtonsoft.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("NuGet.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("nunit", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("FSharp.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("testcentric.", StringComparison.OrdinalIgnoreCase)) - // for coverlet - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("coverlet", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("AltCover,", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("System.", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("Unquote", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName.StartsWith("xunit", StringComparison.OrdinalIgnoreCase)) - |> Seq.filter - (fun x -> - not - <| (snd x) - .FullName - .StartsWith( - "AltCover.Recorder", - StringComparison.OrdinalIgnoreCase - )) -#else - |> Seq.filter - (fun x -> - (snd x) - .FullName - .EndsWith( - "PublicKeyToken=c02b1a9f5b7cade8", - StringComparison.OrdinalIgnoreCase - )) -#endif |> Seq.toList test <@ files <> [] @> - files + let pdbs = + files + |> List.map (fun (f, s) -> f, AltCover.ProgramDatabase.getPdbFromImage s) + + pdbs |> Seq.iter (fun x -> - let pdb = - AltCover.ProgramDatabase.getPdbFromImage (snd x) - - match pdb with - //| None -> Assert.Fail(sprintf "%A" x) + let f = fst x + match snd x with + // Case of true + | None -> Assert.That(f |> Path.GetFileName, Is.EqualTo "Sample2.dll", f) | Some name -> - let probe = Path.ChangeExtension((fst x), ".pdb") + let probe = Path.ChangeExtension(f, ".pdb") let file = FileInfo(probe) let filename = file.Name.Replace("\\", "/") @@ -1112,7 +1009,7 @@ module AltCoverTests = [] let ValidateAutomaticExemption () = try - CoverageParameters.showGenerated := true + CoverageParameters.showGenerated.Value <- true let path = Path.Combine(dir, "Sample4.dll") use def = @@ -1135,7 +1032,7 @@ module AltCoverTests = Exemption.Automatic Exemption.Automatic ] @> finally - CoverageParameters.showGenerated := false + CoverageParameters.showGenerated.Value <- false [] let DetectLocalSource () = @@ -1147,6 +1044,7 @@ module AltCoverTests = |> XDocument.Load xml.Descendants(XName.Get("PackageReference")) + |> Seq.filter (fun x -> x.Attribute("Include".X).IsNotNull) |> Seq.map (fun x -> (x @@ -1155,7 +1053,7 @@ module AltCoverTests = x.Attribute(XName.Get("version")).Value)) |> Map.ofSeq - CoverageParameters.local := false + CoverageParameters.local.Value <- false CoverageParameters.nameFilters.Clear() let fscore = @@ -1235,7 +1133,7 @@ module AltCoverTests = Assert.That(f.MainModule.LocalFilter, Is.False, "f# MainModule non-local") try - CoverageParameters.local := true + CoverageParameters.local.Value <- true Assert.That(localAssembly.LocalFilter, Is.False, "local engine Assembly local") Assert.That(localAssembly.MainModule.LocalFilter, Is.False, "local engine MainModule local") Assert.That(a.LocalFilter, Is.True, "Assembly local") @@ -1246,7 +1144,7 @@ module AltCoverTests = Assert.That(f.MainModule.LocalFilter, Is.False, "f# MainModule local") finally - CoverageParameters.local := false + CoverageParameters.local.Value <- false [] let LocateMatchShouldChooseLongerWildCardPath () = @@ -1631,7 +1529,7 @@ module AltCoverTests = Visitor.visit [] [] // cheat reset try - CoverageParameters.coalesceBranches := true + CoverageParameters.coalesceBranches.Value <- true CoverageParameters.theReportFormat <- Some ReportFormat.OpenCover CoverageParameters.nameFilters.Clear() @@ -1666,7 +1564,7 @@ module AltCoverTests = Interesting = true } -> Assert.That(uid, Is.EqualTo i, "point number")) finally - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false CoverageParameters.nameFilters.Clear() CoverageParameters.theReportFormat <- None @@ -1680,6 +1578,7 @@ module AltCoverTests = let methods = def.MainModule.GetAllTypes() |> Seq.collect (fun t -> t.Methods) + |> Seq.sortBy (fun m -> m.FullName) |> Seq.toList let containing = @@ -1690,80 +1589,80 @@ module AltCoverTests = |> Seq.map (fun (mo: MethodDefinition option) -> mo |> Option.map id) let expected = - [ None // System.Int32 Sample5.Class1::F1(System.String) + [Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // K Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.Generic.IEnumerator.get_Current() + Some "get_ValuesWorks" // K Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.Generic.IEnumerator.get_Current() + None // K Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.get_Item(T) + Some "F2" // System.Boolean Sample5.Class1/d__1::MoveNext() + Some "G2" // System.Boolean Sample5.Class1/Inner/d__2`1::MoveNext() + Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // System.Boolean Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::MoveNext() + Some "get_ValuesWorks" // System.Boolean Sample5.RecursiveSyntheticInvocation`2/d__4::MoveNext() + None // System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.ContainsKey(T) + None // System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.TryGetValue(T,K&) + None // System.Collections.Generic.IEnumerable`1 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.get_Values() + None // System.Collections.Generic.IEnumerable`1 Sample5.RecursiveSyntheticInvocation`2::get_ValuesWorks() None // System.Collections.Generic.IEnumerable`1 Sample5.Class1::F2(System.String) - None // System.Threading.Tasks.Task`1 Sample5.Class1::F3(System.String) - None // System.Void Sample5.Class1::.ctor() - Some "F1" // "System.Int32 Sample5.Class1::g__Interior|0_1(System.Int32,System.Int32)" - Some "F1" // "System.Int32 Sample5.Class1::g__Recursive|0_3(System.Int32)" - None // System.Int32 Sample5.Class1/Inner::G1(System.String) - None // System.Void Sample5.Class1/Inner::G1(System.Int32) - None // System.Collections.Generic.IEnumerable`1 Sample5.Class1/Inner::G2(System.String) - None // System.Void Sample5.Class1/Inner::G2(System.Int32) - None // System.Threading.Tasks.Task`1 Sample5.Class1/Inner::G3(System.String) - None // System.Void Sample5.Class1/Inner::G3(System.Int32) - None // System.Void Sample5.Class1/Inner::.ctor() - Some "g__Recursive|0_4" // T[] Sample5.Class1/Inner::g__InteriorToArray|0_1(T) - Some "b__3" // "System.Int32 Sample5.Class1/Inner::g__Interior|0_1(System.Int32,System.Int32)" - Some "g__Interior|0_2" // "System.Int32 Sample5.Class1/Inner::g__Recursive|0_3(System.Int32)" - None // System.Void Sample5.Class1/Inner/<>c__DisplayClass0_0::.ctor() - Some "G1" // System.Int32 Sample5.Class1/Inner/<>c__DisplayClass0_0::b__2(System.Char) - None // System.Void Sample5.Class1/Inner/<>c::.cctor() - None // System.Void Sample5.Class1/Inner/<>c::.ctor() - Some "G1" // System.Int32 Sample5.Class1/Inner/<>c::b__0_0(System.Char) - Some "G2" // System.Void Sample5.Class1/Inner/d__1::.ctor(System.Int32) - Some "G2" // System.Void Sample5.Class1/Inner/d__1::System.IDisposable.Dispose() - Some "G2" // System.Boolean Sample5.Class1/Inner/d__1::MoveNext() - Some "G2" // System.Int32 Sample5.Class1/Inner/d__1::System.Collections.Generic.IEnumerator.get_Current() - Some "G2" // System.Void Sample5.Class1/Inner/d__1::System.Collections.IEnumerator.Reset() - Some "G2" // System.Object Sample5.Class1/Inner/d__1::System.Collections.IEnumerator.get_Current() - Some "G2" // System.Collections.Generic.IEnumerator`1 Sample5.Class1/Inner/d__1::System.Collections.Generic.IEnumerable.GetEnumerator() - Some "G2" // System.Collections.IEnumerator Sample5.Class1/Inner/d__1::System.Collections.IEnumerable.GetEnumerator() - Some "G3" // System.Void Sample5.Class1/Inner/d__2::.ctor() - Some "G3" // System.Void Sample5.Class1/Inner/d__2::MoveNext() - Some "G3" // System.Void Sample5.Class1/Inner/d__2::SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine) - None // System.Void Sample5.Class1/<>c__DisplayClass0_0::.ctor() + None // System.Collections.Generic.IEnumerable`1 Sample5.Class1/Inner::G2(T) + None // System.Collections.Generic.IEnumerable`1 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.get_Keys() + Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // System.Collections.Generic.IEnumerator`1 Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.Generic.IEnumerable.GetEnumerator() + Some "get_ValuesWorks" // System.Collections.Generic.IEnumerator`1 Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.Generic.IEnumerable.GetEnumerator() + None // System.Collections.Generic.IEnumerator`1> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IEnumerable>.GetEnumerator() + Some "F2" // System.Collections.Generic.IEnumerator`1 Sample5.Class1/d__1::System.Collections.Generic.IEnumerable.GetEnumerator() + Some "G2" // System.Collections.Generic.IEnumerator`1 Sample5.Class1/Inner/d__2`1::System.Collections.Generic.IEnumerable.GetEnumerator() + Some "F2" // System.Collections.IEnumerator Sample5.Class1/d__1::System.Collections.IEnumerable.GetEnumerator() + Some "G2" // System.Collections.IEnumerator Sample5.Class1/Inner/d__2`1::System.Collections.IEnumerable.GetEnumerator() + Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.IEnumerable.GetEnumerator() + Some "get_ValuesWorks" // System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.IEnumerable.GetEnumerator() + None // System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2::System.Collections.IEnumerable.GetEnumerator() + Some "F1" // System.Int32 Sample5.Class1/<>c::b__0_0(System.Char) Some "F1" // System.Int32 Sample5.Class1/<>c__DisplayClass0_0::b__2(System.Char) + Some "F2" // System.Int32 Sample5.Class1/d__1::System.Collections.Generic.IEnumerator.get_Current() + Some "G1" // System.Int32 Sample5.Class1/Inner/<>c::b__0_0(System.Char) + Some "G1" // System.Int32 Sample5.Class1/Inner/<>c__DisplayClass0_0::b__3(System.Char) + Some "b__3" // System.Int32 Sample5.Class1/Inner::g__Interior|0_2(System.Int32,System.Int32) + Some "g__Interior|0_2" // System.Int32 Sample5.Class1/Inner::g__Recursive|0_4(System.Int32) + None // System.Int32 Sample5.Class1/Inner::G1(System.String) // g1 + Some "F1" // System.Int32 Sample5.Class1::g__Interior|0_1(System.Int32,System.Int32) + Some "F1" // System.Int32 Sample5.Class1::g__Recursive|0_3(System.Int32) + None // System.Int32 Sample5.Class1::F1(System.String) + None // System.Int32 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyCollection>.get_Count() + Some "F2" // System.Object Sample5.Class1/d__1::System.Collections.IEnumerator.get_Current() + Some "G2" // System.Object Sample5.Class1/Inner/d__2`1::System.Collections.IEnumerator.get_Current() + Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // System.Object Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.IEnumerator.get_Current() + Some "get_ValuesWorks" // System.Object Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.IEnumerator.get_Current() + None // System.Threading.Tasks.Task`1 Sample5.Class1/Inner::G3(System.String) // g3 + None // System.Threading.Tasks.Task`1 Sample5.Class1::F3(System.String) None // System.Void Sample5.Class1/<>c::.cctor() None // System.Void Sample5.Class1/<>c::.ctor() - Some "F1" // System.Int32 Sample5.Class1/<>c::b__0_0(System.Char) + None // System.Void Sample5.Class1/<>c__DisplayClass0_0::.ctor() Some "F2" // System.Void Sample5.Class1/d__1::.ctor(System.Int32) - Some "F2" // System.Void Sample5.Class1/d__1::System.IDisposable.Dispose() - Some "F2" // System.Boolean Sample5.Class1/d__1::MoveNext() - Some "F2" // System.Int32 Sample5.Class1/d__1::System.Collections.Generic.IEnumerator.get_Current() Some "F2" // System.Void Sample5.Class1/d__1::System.Collections.IEnumerator.Reset() - Some "F2" // System.Object Sample5.Class1/d__1::System.Collections.IEnumerator.get_Current() - Some "F2" // System.Collections.Generic.IEnumerator`1 Sample5.Class1/d__1::System.Collections.Generic.IEnumerable.GetEnumerator() - Some "F2" // System.Collections.IEnumerator Sample5.Class1/d__1::System.Collections.IEnumerable.GetEnumerator() + Some "F2" // System.Void Sample5.Class1/d__1::System.IDisposable.Dispose() Some "F3" // System.Void Sample5.Class1/d__2::.ctor() Some "F3" // System.Void Sample5.Class1/d__2::MoveNext() Some "F3" // System.Void Sample5.Class1/d__2::SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine) - None // "System.Collections.Generic.IEnumerable`1 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.get_Values()" - None // "System.Collections.Generic.IEnumerable`1 Sample5.RecursiveSyntheticInvocation`2::get_ValuesWorks()" - None // "System.Collections.Generic.IEnumerable`1 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.get_Keys()" - None // "K Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.get_Item(T)" - None // "System.Int32 Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyCollection>.get_Count()" - None // "System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.ContainsKey(T)" - None // "System.Collections.Generic.IEnumerator`1> Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IEnumerable>.GetEnumerator()" - None // "System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2::System.Collections.IEnumerable.GetEnumerator()" - None // "System.Boolean Sample5.RecursiveSyntheticInvocation`2::System.Collections.Generic.IReadOnlyDictionary.TryGetValue(T,K&)" - None // "System.Void Sample5.RecursiveSyntheticInvocation`2::.ctor()" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "System.Void Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::.ctor(System.Int32)" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "System.Void Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.IDisposable.Dispose()" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "System.Boolean Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::MoveNext()" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "K Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.Generic.IEnumerator.get_Current()" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "System.Void Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.IEnumerator.Reset()" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "System.Object Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.IEnumerator.get_Current()" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "System.Collections.Generic.IEnumerator`1 Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.Generic.IEnumerable.GetEnumerator()" - Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // "System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.IEnumerable.GetEnumerator()" - Some "get_ValuesWorks" // "System.Void Sample5.RecursiveSyntheticInvocation`2/d__4::.ctor(System.Int32)" - Some "get_ValuesWorks" // "System.Void Sample5.RecursiveSyntheticInvocation`2/d__4::System.IDisposable.Dispose()" - Some "get_ValuesWorks" // "System.Boolean Sample5.RecursiveSyntheticInvocation`2/d__4::MoveNext()" - Some "get_ValuesWorks" // "K Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.Generic.IEnumerator.get_Current()" - Some "get_ValuesWorks" // "System.Void Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.IEnumerator.Reset()" - Some "get_ValuesWorks" // "System.Object Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.IEnumerator.get_Current()" - Some "get_ValuesWorks" // "System.Collections.Generic.IEnumerator`1 Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.Generic.IEnumerable.GetEnumerator()" - Some "get_ValuesWorks" ] // "System.Collections.IEnumerator Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.IEnumerable.GetEnumerator()" + None // System.Void Sample5.Class1/Inner/<>c::.cctor() + None // System.Void Sample5.Class1/Inner/<>c::.ctor() + None // System.Void Sample5.Class1/Inner/<>c__DisplayClass0_0::.ctor() + Some "G2" // System.Void Sample5.Class1/Inner/d__2`1::.ctor(System.Int32) + Some "G2" // System.Void Sample5.Class1/Inner/d__2`1::System.Collections.IEnumerator.Reset() + Some "G2" // System.Void Sample5.Class1/Inner/d__2`1::System.IDisposable.Dispose() + Some "G3" // System.Void Sample5.Class1/Inner/d__4::.ctor() + Some "G3" // System.Void Sample5.Class1/Inner/d__4::MoveNext() + Some "G3" // System.Void Sample5.Class1/Inner/d__4::SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine) + None // System.Void Sample5.Class1/Inner::.ctor() + None // System.Void Sample5.Class1/Inner::G1(System.Int32) + None // System.Void Sample5.Class1/Inner::G2(System.Int32) + None // System.Void Sample5.Class1/Inner::G3(System.Int32) + None // System.Void Sample5.Class1::.ctor() + Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // System.Void Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::.ctor(System.Int32) + Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // System.Void Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.Collections.IEnumerator.Reset() + Some "System.Collections.Generic.IReadOnlyDictionary.get_Values" // System.Void Sample5.RecursiveSyntheticInvocation`2/-get_Values>d__2::System.IDisposable.Dispose() + Some "get_ValuesWorks" // System.Void Sample5.RecursiveSyntheticInvocation`2/d__4::.ctor(System.Int32) + Some "get_ValuesWorks" // System.Void Sample5.RecursiveSyntheticInvocation`2/d__4::System.Collections.IEnumerator.Reset() + Some "get_ValuesWorks" // System.Void Sample5.RecursiveSyntheticInvocation`2/d__4::System.IDisposable.Dispose() + None // System.Void Sample5.RecursiveSyntheticInvocation`2::.ctor() + Some "G2" // T Sample5.Class1/Inner/d__2`1::System.Collections.Generic.IEnumerator.get_Current() + Some "g__Recursive|0_4"] // T[] Sample5.Class1/Inner::g__InteriorToArray|0_1(T) // methods |> Seq.iter (fun x -> printfn "%A" x.FullName) // Assert.That (result, Is.EquivalentTo expected) @@ -1797,7 +1696,7 @@ module AltCoverTests = sprintf "%A %A %d" x (y |> Option.map toFullName) i )) // Disambiguation checks - let g3 = methods.[10] + let g3 = methods.[40] Assert.That( methods @@ -1807,7 +1706,7 @@ module AltCoverTests = Is.EquivalentTo [ g3; g3; g3 ] ) - let g1 = methods.[6] + let g1 = methods.[31] Assert.That( methods @@ -2368,7 +2267,7 @@ module AltCoverTests = Visitor.visit [] [] // cheat reset try - CoverageParameters.coalesceBranches := true + CoverageParameters.coalesceBranches.Value <- true CoverageParameters.theReportFormat <- Some ReportFormat.OpenCover CoverageParameters.nameFilters.Clear() @@ -2430,7 +2329,7 @@ module AltCoverTests = 1 ] ) finally - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false CoverageParameters.nameFilters.Clear() CoverageParameters.theReportFormat <- None @@ -2456,7 +2355,7 @@ module AltCoverTests = try CoverageParameters.theReportFormat <- Some ReportFormat.OpenCover CoverageParameters.nameFilters.Clear() - CoverageParameters.coalesceBranches := true + CoverageParameters.coalesceBranches.Value <- true let deeper = Visitor.I.deeper @@ -2476,17 +2375,17 @@ module AltCoverTests = | BranchPoint b -> b.Representative = Reporting.Representative | _ -> true) - Assert.That(reported.Length, Is.EqualTo 14) + Assert.That(reported.Length, Is.EqualTo 11) reported - |> List.skip 9 + |> List.skip 6 |> List.iteri (fun i node -> match node with | (BranchPoint b) -> Assert.That(b.Uid, Is.EqualTo i, "branch point number")) deeper - |> List.take 9 + |> List.take 6 |> List.iteri (fun i node -> match node with @@ -2498,7 +2397,7 @@ module AltCoverTests = Assert.That(uid, Is.EqualTo i, "point number")) finally - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false CoverageParameters.nameFilters.Clear() CoverageParameters.theReportFormat <- None @@ -2805,7 +2704,7 @@ module AltCoverTests = [] let PathsAreDeeperThanAVisit () = try - CoverageParameters.showGenerated := true + CoverageParameters.showGenerated.Value <- true let where = Assembly.GetExecutingAssembly().Location let path = sample1path let accumulator = System.Collections.Generic.List() @@ -2854,7 +2753,7 @@ module AltCoverTests = Is.EquivalentTo(expected |> Seq.map string) ) finally - CoverageParameters.showGenerated := false + CoverageParameters.showGenerated.Value <- false [] let TrackingDetectsTests () = @@ -3311,8 +3210,6 @@ module AltCoverTests = [] let ShouldGenerateExpectedXmlReportFromDotNet () = let visitor, document = Report.reportGenerator () - // Hack for running while instrumented - let where = Assembly.GetExecutingAssembly().Location let path = sample1path try @@ -3348,6 +3245,98 @@ module AltCoverTests = finally CoverageParameters.nameFilters.Clear() + [] + let ShouldGenerateExpectedXmlReportWithEmbeds () = + let visitor, document = Report.reportGenerator () + let path = Path.Combine(SolutionDir(), "Samples/Sample28/GeneratedDemo/bin/Debug/netcoreapp3.1/CSharpGeneratedDemo.dll") + + try + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- Some ReportFormat.OpenCover + + Visitor.visit + [ visitor ] + (Visitor.I.toSeq + { AssemblyPath = path + Destinations = [] }) + + //printfn "%A" (makeDocument document) + let results = (makeDocument document).Descendants("altcover.file".X) + |> Seq.toList + Assert.That (results |> List.length, Is.EqualTo 9) + results + |> Seq.iter (fun x -> let doc = x.Attribute("document".X) + Assert.That (doc, Is.Not.Null, x.ToString()) + let path = doc.Value + Assert.That(path |> File.Exists, Is.False, path)) + + let lead = results |> Seq.head + let prev = lead.PreviousNode :?> XElement + Assert.That(prev, Is.Not.Null) + Assert.That(prev.Name, Is.EqualTo ("method".X)) + + finally + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- None + + [] + let ShouldGenerateExpectedXmlReportWithPartials () = + let visitor, document = Report.reportGenerator () + let path = Path.Combine(SolutionDir(), "AltCover.Tests/SimpleMix.exe") + + try + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- Some ReportFormat.OpenCover + + Visitor.visit + [ visitor ] + (Visitor.I.toSeq + { AssemblyPath = path + Destinations = [] }) + + //printfn "%A" (makeDocument document) + let results = (makeDocument document) + let methods = results.Descendants("method".X) + |> Seq.toList + let classes = methods + |> List.groupBy (fun x -> x.Attribute("class".X).Value) + let documents = classes + |> List.map (fun (n,ml) -> n, ml + |> Seq.map (fun m -> m.Descendants("seqpnt".X) + |> Seq.map (fun s -> s.Attribute("document".X).Value) + |> Seq.distinct + |> Seq.toList)) + let classdocs = documents + |> List.map (fun (n,dl) -> (n, dl + |> Seq.concat + |> Seq.distinct + |> Seq.toList)) + let classcount = classdocs + |> List.map (fun (n,dl) -> (n, dl |> List.length)) + |> List.sortBy fst + + // printfn "%A" classcount + + // snd > 1 => partial class at least + test <@ classcount = [(".ModuleLoadException", 1); + (".ModuleLoadExceptionHandlerException", 1); + (".ModuleUninitializer", 1); ("", 10); + ("Example", 2)] @> + + let mcount = documents + |> List.map (fun (n,ml) -> (n, ml |> Seq.maxBy List.length |> List.length)) + |> List.sortBy fst + + // snd > 1 => inlined method at least + test <@ mcount = [(".ModuleLoadException", 1); + (".ModuleLoadExceptionHandlerException", 1); + (".ModuleUninitializer", 1); ("", 2); + ("Example", 2)] @> + + finally + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- None + let internal makeJson (f: Stream -> unit) = use stash = new MemoryStream() stash |> f @@ -3405,19 +3394,15 @@ module AltCoverTests = let expected = reader .ReadToEnd() - .Replace( - "Tests.fs", - Path - .GetFullPath(Path.Combine(SolutionRoot.location, - "Samples/Sample4", - "Tests.fs")) - .Replace("\\", "\\\\") - ) + .Replace("/_//Samples/Sample4/Tests.fs", // Not compiled deterministic + (Path.Combine(SolutionDir(), "Samples/Sample4/Tests.fs") + |> canonicalPath).Replace("\\","\\\\")) .Replace('\r', '\u00FF') .Replace('\n', '\u00FF') .Replace("\u00FF\u00FF", "\u00FF") .Trim([| '\u00FF' |]) - //printfn "%s" result + //printfn "expected %A" expected + //printfn "result %s" result Assert.That( result .Replace('\r', '\u00FF') @@ -3431,13 +3416,115 @@ module AltCoverTests = CoverageParameters.nameFilters.Clear() CoverageParameters.theReportFormat <- None + [] + let ShouldGenerateExpectedJsonReportWithPartials () = + let visitor, document = OpenCover.reportGenerator () + let path = Path.Combine(SolutionDir(), "AltCover.Tests/SimpleMix.exe") + try + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- Some ReportFormat.NativeJson + let visitor, document = Main.I.selectReportGenerator () + + Visitor.visit + [ visitor ] + (Visitor.I.toSeq + { AssemblyPath = path + Destinations = [] }) + + let result = makeJson document + //printfn "%A" result + let json = NativeJson.fromJsonText result + Assert.That (json.Count, Is.EqualTo 1) + let documents = json.Values |> Seq.head + + Assert.That(documents.Count, Is.EqualTo 10) + let classdocs = documents + |> Seq.collect (fun kvp -> kvp.Value.Keys + |> Seq.map (fun k -> (k, kvp.Key))) + |> Seq.groupBy fst + |> Seq.toList + + let classcount = classdocs + |> List.map (fun (n,dl) -> (n, dl |> Seq.length)) + |> List.sortBy fst + + // printfn "%A" classcount + + // snd > 1 => partial class at least + test <@ classcount = [(".ModuleLoadException", 1); + (".ModuleLoadExceptionHandlerException", 1); + (".ModuleUninitializer", 1); ("", 10); + ("Example", 2)] @> + + let mcount = documents + |> Seq.collect (fun kvp -> kvp.Value + |> Seq.collect (fun kv -> kv.Value.Keys + |> Seq.map (fun k -> kv.Key, (k, kvp.Key)))) + + |> Seq.groupBy fst + |> Seq.map (fun (n,l) -> n,(l |> Seq.map snd + |> Seq.groupBy fst + |> Seq.map (fun (_, dl) -> dl |> Seq.map snd + |> Seq.distinct + |> Seq.length)) + |> Seq.max) + |> Seq.toList + |> List.sortBy fst + + //mcount + //|> Seq.iter (printfn "%A") + + // snd > 1 => inlined method at least + test <@ mcount = [(".ModuleLoadException", 1); + (".ModuleLoadExceptionHandlerException", 1); + (".ModuleUninitializer", 1); ("", 2); + ("Example", 2)] @> + finally + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- None + + [] + let ShouldGenerateExpectedJsonReportWithEmbeds () = + let visitor, document = OpenCover.reportGenerator () + let path = Path.Combine(SolutionDir(), "Samples/Sample28/GeneratedDemo/bin/Debug/netcoreapp3.1/CSharpGeneratedDemo.dll") + + try + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- Some ReportFormat.NativeJson + let visitor, document = Main.I.selectReportGenerator () + + Visitor.visit + [ visitor ] + (Visitor.I.toSeq + { AssemblyPath = path + Destinations = [] }) + + let result = makeJson document + //printfn "%A" result + let json = NativeJson.fromJsonText result + Assert.That (json.Count, Is.EqualTo 1) + Assert.That (json.["CSharpGeneratedDemo.dll"].Count, Is.EqualTo 16) + let dict = json.["CSharpGeneratedDemo.dll"] + let embeds = dict.Keys + |> Seq.map (fun k -> let file = k |> File.Exists |> not + let embed = dict.[k].ContainsKey "\u00ABAltCover.embed\u00BB" + Assert.That (file, Is.EqualTo embed, k) + if file then 1 else 0) + |> Seq.toList + + test <@ embeds = [1; 1; 1; 1; 1; 1; 1; 1; 1; 0; 0; 0; 0; 0; 0; 0] @> + + finally + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- None + [] let ShouldGenerateExpectedXmlReportForNCoverWithMethodPointOnly () = let visitor, document = Report.reportGenerator () let path = sample4path try - CoverageParameters.methodPoint := true + CoverageParameters.methodPoint.Value <- true Visitor.visit [ visitor ] @@ -3452,7 +3539,7 @@ module AltCoverTests = let sx = mx.Descendants(XName.Get "seqpnt") test <@ sx |> Seq.length = 1 @>) finally - CoverageParameters.methodPoint := false + CoverageParameters.methodPoint.Value <- false [] let ShouldGenerateExpectedXmlReportForNCoverWithTopLevel () = @@ -3791,7 +3878,7 @@ module AltCoverTests = let path = sample4path try - CoverageParameters.methodPoint := true + CoverageParameters.methodPoint.Value <- true CoverageParameters.theReportFormat <- None let visitor, document = Main.I.selectReportGenerator () //OpenCover.reportGenerator() @@ -3811,7 +3898,7 @@ module AltCoverTests = test <@ sx |> Seq.length = 1 @>) finally - CoverageParameters.methodPoint := false + CoverageParameters.methodPoint.Value <- false [] let LocateMatchFallsBackOK () = @@ -3830,7 +3917,7 @@ module AltCoverTests = Path.Combine(here, "_SourceLink/Sample14.dll") try - CoverageParameters.sourcelink := true + CoverageParameters.sourcelink.Value <- true CoverageParameters.staticFilter <- Some StaticFilter.NoFilter Visitor.visit @@ -3887,7 +3974,7 @@ module AltCoverTests = finally CoverageParameters.nameFilters.Clear() - CoverageParameters.sourcelink := false + CoverageParameters.sourcelink.Value <- false CoverageParameters.staticFilter <- None [] @@ -4160,7 +4247,7 @@ module AltCoverTests = Assert.That(branch.Target.Length, Is.EqualTo 2) let xbranch = XElement(XName.Get "test") OpenCover.I.setChain xbranch branch - Assert.That(xbranch.ToString(), Is.EqualTo """""") + Assert.That(xbranch.ToString(), Is.EqualTo """""") finally CoverageParameters.nameFilters.Clear() CoverageParameters.theReportFormat <- None @@ -4293,7 +4380,7 @@ module AltCoverTests = try CoverageParameters.theReportFormat <- Some ReportFormat.NCover - CoverageParameters.sourcelink := true + CoverageParameters.sourcelink.Value <- true Visitor.visit [ visitor ] @@ -4346,14 +4433,12 @@ module AltCoverTests = Assert.That(untracked, Is.EquivalentTo expected2) finally CoverageParameters.nameFilters.Clear() - CoverageParameters.sourcelink := false + CoverageParameters.sourcelink.Value <- false CoverageParameters.theReportFormat <- None [] let ShouldGenerateExpectedXmlReportFromDotNetOpenCoverStyle () = let visitor, document = OpenCover.reportGenerator () - // Hack for running while instrumented - let where = Assembly.GetExecutingAssembly().Location let path = sample1path try @@ -4386,6 +4471,101 @@ module AltCoverTests = CoverageParameters.nameFilters.Clear() CoverageParameters.theReportFormat <- None + [] + let ShouldGenerateExpectedXmlReportWithEmbedsOpenCoverStyle () = + let visitor, document = OpenCover.reportGenerator () + let path = Path.Combine(SolutionDir(), "Samples/Sample28/GeneratedDemo/bin/Debug/netcoreapp3.1/CSharpGeneratedDemo.dll") + + try + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- Some ReportFormat.OpenCover + + Visitor.visit + [ visitor ] + (Visitor.I.toSeq + { AssemblyPath = path + Destinations = [] }) + + let expected = [1; 1; 1; 1; 1; 1; 1; 1; 0; 1; 0; 0; 0; 0; 0; 0] + //printfn "%A" (makeDocument document) + let result = (makeDocument document).Descendants("File".X) + |> Seq.map(fun f -> if f.Attribute("fullPath".X).Value |> File.Exists |> not + then 1 else 0) + |> Seq.toList + // Generated source does not exist at the specified path -- a check on the MSFT inputs + test <@ result = expected @> + + // but we should have picked up the embedded source + let embeds = (makeDocument document).Descendants("File".X) + |> Seq.map (fun f -> if f.Attribute("altcover.embed".X).IsNotNull + then 1 else 0) + |> Seq.toList + test <@ embeds = expected @> + + finally + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- None + + [] + let ShouldGenerateExpectedXmlReportWithPartialsOpenCoverStyle () = + let visitor, document = OpenCover.reportGenerator () + let path = Path.Combine(SolutionDir(), "AltCover.Tests/SimpleMix.exe") + + try + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- Some ReportFormat.OpenCover + + Visitor.visit + [ visitor ] + (Visitor.I.toSeq + { AssemblyPath = path + Destinations = [] }) + + // printfn "%A" (makeDocument document) + let results = (makeDocument document) + let classes = results.Descendants("Class".X) + |> Seq.map (fun c -> (c.Element("FullName".X).Value, + c.Descendants("Method".X) |> Seq.toList)) + |> Seq.toList + + let documents = classes + |> List.map (fun (n,ml) -> (n, ml |> Seq.map (fun m -> [ m.Descendants("SequencePoint".X); + m.Descendants("Branch".X)] + |> Seq.concat + |> Seq.map (fun x -> x.Attribute("fileid".X).Value) + |> Seq.distinct + |> Seq.toList))) + let classdocs = documents + |> List.map (fun (n,dl) -> (n, dl + |> Seq.concat + |> Seq.distinct + |> Seq.toList)) + let classcount = classdocs + |> List.map (fun (n,dl) -> (n, dl |> List.length)) + |> List.sortBy fst + + // printfn "%A" classcount + + // snd > 1 => partial class at least + test <@ classcount = [(".ModuleLoadException", 1); + (".ModuleLoadExceptionHandlerException", 1); + (".ModuleUninitializer", 1); ("", 10); + ("Example", 2)] @> + + let mcount = documents + |> List.map (fun (n,ml) -> (n, ml |> Seq.maxBy List.length |> List.length)) + |> List.sortBy fst + + // snd > 1 => inlined method at least + test <@ mcount = [(".ModuleLoadException", 1); + (".ModuleLoadExceptionHandlerException", 1); + (".ModuleUninitializer", 1); ("", 2); + ("Example", 2)] @> + + finally + CoverageParameters.nameFilters.Clear() + CoverageParameters.theReportFormat <- None + [] let ShouldGenerateExpectedXmlReportFromDotNetLineCoverStyle () = let visitor, document = OpenCover.reportGenerator () @@ -4918,9 +5098,9 @@ module AltCoverTests = let visitor, document = OpenCover.reportGenerator () let sample21 = - Path.Combine(SolutionDir(), "./Samples/Sample21/bin/Debug/net5.0/Sample21.dll") + Path.Combine(SolutionDir(), "./Samples/Sample21/bin/Debug/net6.0/Sample21.dll") - Assert.That(File.Exists sample21, "Test file Sample21 for net5.0 not built") + Assert.That(File.Exists sample21, "Test file Sample21 for net6.0 not built") try "Program" diff --git a/AltCover.Tests/Tests2.fs b/AltCover.Tests/Tests2.fs index 35bcdc27d..b49043b18 100644 --- a/AltCover.Tests/Tests2.fs +++ b/AltCover.Tests/Tests2.fs @@ -36,14 +36,23 @@ module AltCoverTests2 = stream.CopyTo(buffer) StrongNameKeyData.Make(buffer.ToArray()) + let recorderStream () = + let recorder = + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("AltCover.Recorder.net20.dll", StringComparison.Ordinal)) + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(recorder) + // Instrument.I.fs [] let ShouldBeAbleToGetTheVisitReportMethod () = - let path = - Path.Combine(AltCoverTests.dir, "AltCover.Recorder.dll") + use recstream = recorderStream () use def = - Mono.Cecil.AssemblyDefinition.ReadAssembly path + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod def @@ -468,7 +477,7 @@ module AltCoverTests2 = let path = Path.Combine(AltCoverTests.dir, "Sample3.dll") - let prepared = Instrument.I.prepareAssembly path + let prepared = Instrument.I.prepareAssembly (File.OpenRead path) use raw = Mono.Cecil.AssemblyDefinition.ReadAssembly path @@ -657,7 +666,7 @@ module AltCoverTests2 = "Unexpected sampling" ) - let prepared = Instrument.I.prepareAssembly path + let prepared = Instrument.I.prepareAssembly (File.OpenRead path) let traces = System.Collections.Generic.List() @@ -815,7 +824,7 @@ module AltCoverTests2 = try CoverageParameters.theReportPath <- Some unique - let prepared = Instrument.I.prepareAssembly path + let prepared = Instrument.I.prepareAssembly (File.OpenRead path) Instrument.I.writeAssembly prepared outputdll // TODO -- see Instrument.I.WriteAssembly Assert.That (File.Exists (outputdll + ".mdb")) use raw = @@ -1290,13 +1299,10 @@ module AltCoverTests2 = [] let ShouldBeAbleToTrackAMethod () = - let shift = "/../net5.0" - - let path = - Path.Combine(AltCoverTests.dir + shift, "AltCover.Recorder.dll") + use recstream = recorderStream () use def = - Mono.Cecil.AssemblyDefinition.ReadAssembly path + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod def @@ -1352,10 +1358,7 @@ module AltCoverTests2 = [] let ShouldBeAbleToTrackAMethodWithTailCalls () = - let shift = "/../net5.0" - - let rpath = - Path.Combine(AltCoverTests.dir + shift, "AltCover.Recorder.dll") + use recstream = recorderStream () let res = Assembly @@ -1371,8 +1374,8 @@ module AltCoverTests2 = use def = Mono.Cecil.AssemblyDefinition.ReadAssembly stream - let rdef = - Mono.Cecil.AssemblyDefinition.ReadAssembly rpath + use rdef = + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod rdef @@ -1432,10 +1435,7 @@ module AltCoverTests2 = [] let ShouldBeAbleToTrackAMethodWithNonVoidReturn () = - let shift = "/../net5.0" - - let rpath = - Path.Combine(AltCoverTests.dir + shift, "AltCover.Recorder.dll") + use recstream = recorderStream () let sample24 = Path.Combine( @@ -1448,7 +1448,7 @@ module AltCoverTests2 = Mono.Cecil.AssemblyDefinition.ReadAssembly sample24 use rdef = - Mono.Cecil.AssemblyDefinition.ReadAssembly rpath + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod rdef @@ -1513,10 +1513,7 @@ module AltCoverTests2 = [] let ShouldBeAbleToTrackAnAsyncMethod () = - let shift = "/../net5.0" - - let rpath = - Path.Combine(AltCoverTests.dir + shift, "AltCover.Recorder.dll") + use recstream = recorderStream () let sample24 = Path.Combine( @@ -1528,8 +1525,8 @@ module AltCoverTests2 = use def = Mono.Cecil.AssemblyDefinition.ReadAssembly sample24 - let rdef = - Mono.Cecil.AssemblyDefinition.ReadAssembly rpath + use rdef = + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod rdef @@ -1594,10 +1591,7 @@ module AltCoverTests2 = [] let ShouldBeAbleToTrackAnFSAsyncMethod () = - let shift = "/../net5.0" - - let rpath = - Path.Combine(AltCoverTests.dir + shift, "AltCover.Recorder.dll") + use recstream = recorderStream () let sample27 = Path.Combine( @@ -1609,8 +1603,8 @@ module AltCoverTests2 = use def = Mono.Cecil.AssemblyDefinition.ReadAssembly sample27 - let rdef = - Mono.Cecil.AssemblyDefinition.ReadAssembly rpath + use rdef = + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod rdef @@ -1675,10 +1669,7 @@ module AltCoverTests2 = [] let ShouldBeAbleToInstrumentASwitchForNCover () = - let shift = "/../net5.0" - - let rpath = - Path.Combine(AltCoverTests.dir + shift, "AltCover.Recorder.dll") + use recstream = recorderStream () let res = Assembly @@ -1713,7 +1704,7 @@ module AltCoverTests2 = def.MainModule.ReadSymbols(rr) use rdef = - Mono.Cecil.AssemblyDefinition.ReadAssembly rpath + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod rdef @@ -1810,11 +1801,10 @@ module AltCoverTests2 = [] let ShouldNotChangeAnUntrackedMethod () = - let path = - Path.Combine(AltCoverTests.dir, "AltCover.Recorder.dll") + use recstream = recorderStream () use def = - Mono.Cecil.AssemblyDefinition.ReadAssembly path + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let recorder = AltCover.Instrument.I.recordingMethod def @@ -1946,7 +1936,7 @@ module AltCoverTests2 = Mono.Cecil.AssemblyDefinition.ReadAssembly path ProgramDatabase.readSymbols def - CoverageParameters.coalesceBranches := true + CoverageParameters.coalesceBranches.Value <- true let method = def.MainModule.GetAllTypes() @@ -2026,7 +2016,7 @@ module AltCoverTests2 = finally CoverageParameters.nameFilters.Clear() CoverageParameters.theReportFormat <- None - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false [] let SimpleBranchShouldInstrumentByPushingDown () = @@ -2729,11 +2719,10 @@ module AltCoverTests2 = InstrumentContext.Build [ "nunit.framework" "nonesuch" ] - let path' = - Path.Combine(AltCoverTests.dir, "AltCover.Recorder.dll") + use recstream = recorderStream () use def' = - Mono.Cecil.AssemblyDefinition.ReadAssembly path' + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let visit = def'.MainModule.GetAllTypes() @@ -2884,11 +2873,10 @@ module AltCoverTests2 = InstrumentContext.Build [ "nunit.framework" "nonesuch" ] - let path' = - Path.Combine(AltCoverTests.dir, "AltCover.Recorder.dll") + use recstream = recorderStream () use def' = - Mono.Cecil.AssemblyDefinition.ReadAssembly path' + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream let visit = def'.MainModule.GetAllTypes() @@ -3090,10 +3078,12 @@ module AltCoverTests2 = use reader = new StreamReader(stream) let expected = reader.ReadToEnd() - let version = - typeof - .Assembly.GetName() - .Version.ToString() + let recorderVersion() = + use stream = recorderStream () + use def = AssemblyDefinition.ReadAssembly stream + def.Name.Version.ToString() + + let version = recorderVersion() let result = expected @@ -3126,11 +3116,10 @@ module AltCoverTests2 = Assert.Throws (fun () -> - Instrument.I.instrumentationVisitorWrapper - (fun _ _ -> InvalidOperationException("Bang") |> raise) - state - AfterType - |> ignore) + ignore (Instrument.I.instrumentationVisitorWrapper + (fun _ _ -> InvalidOperationException("Bang") |> raise) + state + AfterType)) |> ignore let output = Path.GetTempFileName() @@ -3171,11 +3160,10 @@ module AltCoverTests2 = Assert.Throws (fun () -> - Instrument.I.instrumentationVisitorWrapper - (fun _ _ -> InvalidOperationException("Bang") |> raise) - state - AfterType - |> ignore) + ignore (Instrument.I.instrumentationVisitorWrapper + (fun _ _ -> InvalidOperationException("Bang") |> raise) + state + AfterType)) |> ignore Assert.That(support.TaskAssembly.FullName, Is.Not.Null) // nothing to raise an object disposed exception with @@ -3204,11 +3192,10 @@ module AltCoverTests2 = // Would be NullreferenceException if we tried it Assert.Throws (fun () -> - Instrument.I.instrumentationVisitorWrapper - (fun _ _ -> InvalidOperationException("Bang") |> raise) - state - AfterType - |> ignore) + ignore (Instrument.I.instrumentationVisitorWrapper + (fun _ _ -> InvalidOperationException("Bang") |> raise) + state + AfterType)) |> ignore [] @@ -3225,11 +3212,10 @@ module AltCoverTests2 = Assert.Throws (fun () -> - Instrument.I.instrumentationVisitorWrapper - (fun _ _ -> InvalidOperationException("Bang") |> raise) - state - Finish - |> ignore) + ignore (Instrument.I.instrumentationVisitorWrapper + (fun _ _ -> InvalidOperationException("Bang") |> raise) + state + Finish)) |> ignore let output = Path.GetTempFileName() diff --git a/AltCover.Tests/Tests3.fs b/AltCover.Tests/Tests3.fs index 68e486c74..78718e51d 100644 --- a/AltCover.Tests/Tests3.fs +++ b/AltCover.Tests/Tests3.fs @@ -1072,7 +1072,7 @@ module AltCoverTests3 = try CoverageParameters.theInputDirectories.Clear() CoverageParameters.theOutputDirectories.Clear() - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false let options = Main.I.declareOptions () @@ -1099,7 +1099,7 @@ module AltCoverTests3 = |> List.zip ([ "."; ".." ] |> List.map (pcom "__Instrumented")) |> List.iter Assert.AreEqual - CoverageParameters.inplace := true + CoverageParameters.inplace.Value <- true CoverageParameters.theOutputDirectories.Add "maybe" CoverageParameters.outputDirectories () @@ -1111,7 +1111,7 @@ module AltCoverTests3 = finally CoverageParameters.theOutputDirectories.Clear() CoverageParameters.theInputDirectories.Clear() - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false [] let ParsingDuplicateInputGivesFailure () = @@ -1433,7 +1433,7 @@ module AltCoverTests3 = let here = Assembly.GetExecutingAssembly().Location let next = - Path.Combine(Path.GetDirectoryName here, "AltCover.Recorder.dll") + Path.Combine(Path.GetDirectoryName here, "AltCover.Engine.dll") let input = [| "-d"; here; "/d"; next |] @@ -1452,7 +1452,7 @@ module AltCoverTests3 = Assert.That( String.Join(" ", expected), - Is.EqualTo("AltCover.Recorder AltCover.Tests") + Is.EqualTo("AltCover.Engine AltCover.Tests") ) finally Instrument.resolutionTable.Clear() @@ -1778,7 +1778,7 @@ module AltCoverTests3 = Main.init () try - CoverageParameters.local := false + CoverageParameters.local.Value <- false let options = Main.I.declareOptions () let input = [| "--localSource" |] @@ -1792,14 +1792,14 @@ module AltCoverTests3 = Assert.That(CoverageParameters.local.Value, Is.True) finally - CoverageParameters.local := false + CoverageParameters.local.Value <- false [] let ParsingMultipleLocalGivesFailure () = Main.init () try - CoverageParameters.local := false + CoverageParameters.local.Value <- false let options = Main.I.declareOptions () let input = [| "-l"; "--localSource" |] @@ -1816,14 +1816,14 @@ module AltCoverTests3 = Is.EqualTo "--localSource : specify this only once" ) finally - CoverageParameters.local := false + CoverageParameters.local.Value <- false [] let ParsingVisibleGivesVisible () = Main.init () try - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false let options = Main.I.declareOptions () let input = [| "--visibleBranches" |] @@ -1837,14 +1837,14 @@ module AltCoverTests3 = Assert.That(CoverageParameters.coalesceBranches.Value, Is.True) finally - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false [] let ParsingMultipleVisibleGivesFailure () = Main.init () try - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false let options = Main.I.declareOptions () let input = [| "-v"; "--visibleBranches" |] @@ -1861,7 +1861,7 @@ module AltCoverTests3 = Is.EqualTo "--visibleBranches : specify this only once" ) finally - CoverageParameters.coalesceBranches := false + CoverageParameters.coalesceBranches.Value <- false [] let ParsingStaticGivesStatic () = @@ -2271,7 +2271,7 @@ module AltCoverTests3 = Main.init () try - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false let options = Main.I.declareOptions () let input = [| "--inplace" |] @@ -2285,14 +2285,14 @@ module AltCoverTests3 = Assert.That(CoverageParameters.inplace.Value, Is.True) finally - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false [] let ParsingMultipleInPlaceGivesFailure () = Main.init () try - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false let options = Main.I.declareOptions () let input = [| "--inplace"; "--inplace" |] @@ -2309,14 +2309,14 @@ module AltCoverTests3 = Is.EqualTo "--inplace : specify this only once" ) finally - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false [] let ParsingSaveGivesSave () = Main.init () try - CoverageParameters.collect := false + CoverageParameters.collect.Value <- false let options = Main.I.declareOptions () let input = [| "--save" |] @@ -2329,14 +2329,14 @@ module AltCoverTests3 = Assert.That(x, Is.Empty) Assert.That(CoverageParameters.collect.Value, Is.True) finally - CoverageParameters.collect := false + CoverageParameters.collect.Value <- false [] let ParsingMultipleSaveGivesFailure () = Main.init () try - CoverageParameters.collect := false + CoverageParameters.collect.Value <- false let options = Main.I.declareOptions () let input = [| "--save"; "--save" |] @@ -2353,7 +2353,7 @@ module AltCoverTests3 = Is.EqualTo "--save : specify this only once" ) finally - CoverageParameters.collect := false + CoverageParameters.collect.Value <- false [] let ParsingSingleGivesSingle () = @@ -2663,7 +2663,7 @@ module AltCoverTests3 = Main.init () try - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false let options = Main.I.declareOptions () let input = [| "--dropReturnCode" |] @@ -2677,14 +2677,14 @@ module AltCoverTests3 = Assert.That(CommandLine.dropReturnCode.Value, Is.True) finally - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false [] let ParsingMultipleDropGivesFailure () = Main.init () try - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false let options = Main.I.declareOptions () let input = @@ -2704,7 +2704,7 @@ module AltCoverTests3 = Is.EqualTo "--dropReturnCode : specify this only once" ) finally - CommandLine.dropReturnCode := false + CommandLine.dropReturnCode.Value <- false [] let ParsingDeferWorks () = @@ -2725,7 +2725,7 @@ module AltCoverTests3 = Assert.That(CoverageParameters.defer.Value) Assert.That(CoverageParameters.deferOpCode (), Is.EqualTo OpCodes.Ldc_I4_1) finally - CoverageParameters.defer := false + CoverageParameters.defer.Value <- false [] let ParsingMultipleDeferGivesFailure () = @@ -2749,7 +2749,7 @@ module AltCoverTests3 = ) finally - CoverageParameters.defer := false + CoverageParameters.defer.Value <- false [] let ParsingQuietWorks () = @@ -2992,7 +2992,7 @@ module AltCoverTests3 = let options = Main.I.declareOptions () let saved = (Console.Out, Console.Error) CommandLine.error <- [] - CoverageParameters.inplace := true + CoverageParameters.inplace.Value <- true try use stdout = new StringWriter() @@ -3024,7 +3024,7 @@ module AltCoverTests3 = + " already exists" ] ) finally - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false Console.SetOut(fst saved) Console.SetError(snd saved) @@ -3035,7 +3035,7 @@ module AltCoverTests3 = let options = Main.I.declareOptions () let saved = (Console.Out, Console.Error) CommandLine.error <- [] - CoverageParameters.inplace := true + CoverageParameters.inplace.Value <- true try use stdout = new StringWriter() @@ -3101,7 +3101,7 @@ module AltCoverTests3 = Is.EqualTo here ) finally - CoverageParameters.inplace := false + CoverageParameters.inplace.Value <- false Console.SetOut(fst saved) Console.SetError(snd saved) @@ -3110,8 +3110,8 @@ module AltCoverTests3 = Main.init () let one = ref false let two = ref false - let set2 () = two := true - Main.I.imageLoadResilient (fun () -> one := true) set2 + let set2 () = two.Value <- true + Main.I.imageLoadResilient (fun () -> one.Value <- true) set2 Assert.That(one.Value) Assert.That(two.Value, Is.False) set2 () @@ -3125,11 +3125,11 @@ module AltCoverTests3 = let set1 f () = f () - one := true + one.Value <- true let io () = IOException("fail") |> raise - Main.I.imageLoadResilient (set1 io) (fun () -> two := true) + Main.I.imageLoadResilient (set1 io) (fun () -> two.Value <- true) Assert.That(one.Value, Is.False) Assert.That(two.Value) set1 ignore () @@ -3143,12 +3143,12 @@ module AltCoverTests3 = let set1 f () = f () - one := true + one.Value <- true let bif () = BadImageFormatException("fail") |> raise - Main.I.imageLoadResilient (set1 bif) (fun () -> two := true) + Main.I.imageLoadResilient (set1 bif) (fun () -> two.Value <- true) Assert.That(one.Value, Is.False) Assert.That(two.Value) set1 ignore () @@ -3162,11 +3162,11 @@ module AltCoverTests3 = let set1 f () = f () - one := true + one.Value <- true let arg () = ArgumentException("fail") |> raise - Main.I.imageLoadResilient (set1 arg) (fun () -> two := true) + Main.I.imageLoadResilient (set1 arg) (fun () -> two.Value <- true) Assert.That(one.Value, Is.False) Assert.That(two.Value) set1 ignore () @@ -3897,8 +3897,7 @@ module AltCoverTests3 = let x = Assert.Throws (fun () -> - message.Invoke(subject, [| "x" :> obj |]) - |> ignore) + ignore (message.Invoke(subject, [| "x" :> obj |]))) Assert.That( x.InnerException, @@ -4051,8 +4050,7 @@ module AltCoverTests3 = let x = Assert.Throws (fun () -> - message.Invoke(subject, [| "x" :> obj |]) - |> ignore) + ignore (message.Invoke(subject, [| "x" :> obj |]))) Assert.That( x.InnerException, diff --git a/AltCover.Tests/XTests.fs b/AltCover.Tests/XTests.fs index b3ef8e5f2..1ea991021 100644 --- a/AltCover.Tests/XTests.fs +++ b/AltCover.Tests/XTests.fs @@ -1043,14 +1043,13 @@ module AltCoverXTests = let path = Path.Combine(AltCoverTests.dir, "Sample4.dll") - let recpath = - Path.Combine(AltCoverTests.dir, "AltCover.Recorder.dll") - let def = Mono.Cecil.AssemblyDefinition.ReadAssembly path - let recdef = - Mono.Cecil.AssemblyDefinition.ReadAssembly recpath + use recstream = AltCoverTests2.recorderStream() + + use recdef = + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream ProgramDatabase.readSymbols def let unique = Guid.NewGuid().ToString() @@ -1076,7 +1075,8 @@ module AltCoverXTests = let input = { InstrumentContext.Build [] with - RecordingAssembly = recdef } + RecordingAssembly = recdef + RecorderSource = recstream } let result = Instrument.I.instrumentationVisitor input visited @@ -1086,11 +1086,8 @@ module AltCoverXTests = test' <@ File.Exists created @> (created + " not found") let isWindows = -#if NET472 System.Environment.GetEnvironmentVariable("OS") = "Windows_NT" -#else - true -#endif + test' <@ isWindows |> not || File.Exists(Path.ChangeExtension(created, ".pdb")) @> @@ -1108,11 +1105,10 @@ module AltCoverXTests = let def = Mono.Cecil.AssemblyDefinition.ReadAssembly path - let recpath = - Path.Combine(AltCoverTests.dir, "AltCover.Recorder.dll") + use recstream = AltCoverTests2.recorderStream() - let recdef = - Mono.Cecil.AssemblyDefinition.ReadAssembly recpath + use recdef = + Mono.Cecil.AssemblyDefinition.ReadAssembly recstream ProgramDatabase.readSymbols def let unique = Guid.NewGuid().ToString() @@ -1138,7 +1134,8 @@ module AltCoverXTests = let input = { InstrumentContext.Build [] with - RecordingAssembly = recdef } + RecordingAssembly = recdef + RecorderSource = recstream } let result = Instrument.I.instrumentationVisitor input visited @@ -1193,11 +1190,8 @@ module AltCoverXTests = test' <@ File.Exists created @> (created + " not found") let isWindows = -#if NET472 System.Environment.GetEnvironmentVariable("OS") = "Windows_NT" -#else - true -#endif + test' <@ isWindows |> not || File.Exists(Path.ChangeExtension(created, ".pdb")) @> @@ -1272,9 +1266,10 @@ module AltCoverXTests = if create |> File.Exists |> not then try CoverageParameters.theReportFormat <- Some ReportFormat.NCover - - let from = - Path.Combine(AltCoverTests.dir, "AltCover.Recorder.dll") + use from = + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("AltCover.Tests.AltCover.Recorder.net20.dll") let updated = Instrument.I.prepareAssembly from Instrument.I.writeAssembly updated create diff --git a/AltCover.Tests/issue122.cobertura b/AltCover.Tests/issue122.cobertura index e17ecaa24..820bc0255 100644 --- a/AltCover.Tests/issue122.cobertura +++ b/AltCover.Tests/issue122.cobertura @@ -1,11 +1,11 @@ - + altcover/Sample1 - + @@ -21,7 +21,7 @@ - + diff --git a/AltCover.Tests/issue122.xml b/AltCover.Tests/issue122.xml index 967f53146..521d86782 100644 --- a/AltCover.Tests/issue122.xml +++ b/AltCover.Tests/issue122.xml @@ -20,7 +20,7 @@ 2018-02-22T08:50:13.1034471Z Sample1 - + diff --git a/AltCover.Toolkit/AltCover.Toolkit.fsproj b/AltCover.Toolkit/AltCover.Toolkit.fsproj index 65ea39b4e..336deabd9 100644 --- a/AltCover.Toolkit/AltCover.Toolkit.fsproj +++ b/AltCover.Toolkit/AltCover.Toolkit.fsproj @@ -7,8 +7,6 @@ AltCover.Toolkit false true - true - true RUNNER $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -17,6 +15,15 @@ --keyfile:$(ProjectDir)..\Build\Infrastructure.snk + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) 4 @@ -44,6 +51,7 @@ + @@ -55,7 +63,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -75,6 +83,7 @@ + contentfiles diff --git a/AltCover.Toolkit/CoverageFormats.fs b/AltCover.Toolkit/CoverageFormats.fs index d80e1ea1a..f412cc4c7 100644 --- a/AltCover.Toolkit/CoverageFormats.fs +++ b/AltCover.Toolkit/CoverageFormats.fs @@ -106,7 +106,7 @@ module CoverageFormats = |> Seq.iter (fun f -> files.Add( - f.Attribute(XName.Get "fullPath").Value, + f.Attribute(XName.Get "fullPath").Value.Replace('\\', '/'), f.Attribute(XName.Get "uid").Value )) @@ -118,10 +118,8 @@ module CoverageFormats = let sc = s.Attribute(XName.Get "column").Value let el = s.Attribute(XName.Get "endline").Value let ec = s.Attribute(XName.Get "endcolumn").Value - - let uid = - files.[s.Attribute(XName.Get "document").Value] - + let key = s.Attribute(XName.Get "document").Value.Replace('\\', '/') + let uid = files.[key] let vc = parse <| s.Attribute(XName.Get "visitcount").Value diff --git a/AltCover.Toolkit/OpenCover.fs b/AltCover.Toolkit/OpenCover.fs index 996de6c25..d392b2ccf 100644 --- a/AltCover.Toolkit/OpenCover.fs +++ b/AltCover.Toolkit/OpenCover.fs @@ -366,7 +366,7 @@ module OpenCover = ))) let private hash = - new System.Security.Cryptography.SHA1CryptoServiceProvider() + sha1Hash() let internal fixFormatModule (m: XElement) (files: string array) = // supply empty module level @@ -779,6 +779,110 @@ coverlet on Tests.AltCoverRunnerTests/PostprocessShouldRestoreDegenerateOpenCove (tracked: Map) (methods: (string * XElement seq) seq) : (Summary * XElement array) = + let metadataToken (group: string * XElement seq) = + let mt = XElement(XName.Get "MetadataToken") + group + |> snd + |> Seq.map (fun m -> m.Element(XName.Get "MetadataToken").Value) + |> Seq.tryFind (String.IsNullOrWhiteSpace >> not) + |> Option.iter (fun t -> mt.Value <- t) + mt + + let fileRef modu (group: string * XElement seq) = + group + |> snd + |> Seq.collect (fun x -> x.Elements(XName.Get "FileRef")) + |> Seq.map (fun f -> f.Attribute(XName.Get "uid")) + |> Seq.filter (isNull >> not) + |> Seq.tryHead + |> Option.map + (fun a -> + let fr0 = XElement(XName.Get "FileRef") + let newfile = mapFile files a modu + fr0.SetAttributeValue(XName.Get "uid", newfile) + fr0) + + let sequencePoints modu (group: string * XElement seq) = + let sp = XElement(XName.Get "SequencePoints") + let sps = + group + |> snd + |> Seq.collect (fun m -> m.Descendants(XName.Get "SequencePoint")) + |> Seq.groupBy + (fun s -> + s + |> attributeOrEmpty "sl" + |> Int32.TryParse + |> snd, + s + |> attributeOrEmpty "sc" + |> Int32.TryParse + |> snd) + + let (vs, newsps) = mergePoints files modu tracked sps + newsps + |> Seq.iter + (fun s -> + s.SetAttributeValue(XName.Get "bec", 0) + s.SetAttributeValue(XName.Get "bev", 0)) + + sp.Add newsps + (sp, newsps, vs) + + let branchPoints modu (group: string * XElement seq) = + let bp = XElement(XName.Get "BranchPoints") + + let bps = + group + |> snd + |> Seq.collect (fun m -> m.Descendants(XName.Get "BranchPoint")) + |> Seq.groupBy + (fun s -> + (s + |> attributeOrEmpty "sl" + |> Int32.TryParse + |> snd, + s + |> attributeOrEmpty "offset" + |> Int32.TryParse + |> snd), + s + |> attributeOrEmpty "endoffset" + |> Int32.TryParse + |> snd) + + let (vb, newbps) = mergePoints files modu tracked bps + bp.Add newbps + (bp, newbps, vb) + + let methodPoints modu (group: string * XElement seq) = + let mpn = XName.Get "MethodPoint" + + let methodPoints = + group + |> snd + |> Seq.collect (fun x -> x.Elements mpn) + + let mpv = methodPoints |> mergeCounts + + let mp = + methodPoints + |> Seq.tryHead + |> Option.map + (fun r -> + let mp0 = XElement r + mp0.SetAttributeValue(XName.Get "vc", mpv) + + r.Attribute(XName.Get "fileid") + |> Option.ofObj + |> Option.iter + (fun a -> + let newfile = mapFile files a modu + mp0.SetAttributeValue(XName.Get "fileid", newfile)) + + mp0) + (mp, mpv) + let s, x = methods |> Seq.fold @@ -786,111 +890,21 @@ coverlet on Tests.AltCoverRunnerTests/PostprocessShouldRestoreDegenerateOpenCove let rep = group |> snd |> Seq.head let sm = XElement(XName.Get "Summary") - let mt = XElement(XName.Get "MetadataToken") - - group - |> snd - |> Seq.map (fun m -> m.Element(XName.Get "MetadataToken").Value) - |> Seq.tryFind (String.IsNullOrWhiteSpace >> not) - |> Option.iter (fun t -> mt.Value <- t) + let mt = metadataToken group let name = XElement(XName.Get "Name", fst group) let modu = rep.Parent.Parent.Parent.Parent - let fr = - group - |> snd - |> Seq.collect (fun x -> x.Elements(XName.Get "FileRef")) - |> Seq.map (fun f -> f.Attribute(XName.Get "uid")) - |> Seq.filter (isNull >> not) - |> Seq.tryHead - |> Option.map - (fun a -> - let fr0 = XElement(XName.Get "FileRef") - let newfile = mapFile files a modu - fr0.SetAttributeValue(XName.Get "uid", newfile) - fr0) - - let sp = XElement(XName.Get "SequencePoints") - - let sps = - group - |> snd - |> Seq.collect (fun m -> m.Descendants(XName.Get "SequencePoint")) - |> Seq.groupBy - (fun s -> - s - |> attributeOrEmpty "sl" - |> Int32.TryParse - |> snd, - s - |> attributeOrEmpty "sc" - |> Int32.TryParse - |> snd) - - let (vs, newsps) = mergePoints files modu tracked sps - sp.Add newsps - - let bp = XElement(XName.Get "BranchPoints") - - let bps = - group - |> snd - |> Seq.collect (fun m -> m.Descendants(XName.Get "BranchPoint")) - |> Seq.groupBy - (fun s -> - (s - |> attributeOrEmpty "sl" - |> Int32.TryParse - |> snd, - s - |> attributeOrEmpty "offset" - |> Int32.TryParse - |> snd), - s - |> attributeOrEmpty "endoffset" - |> Int32.TryParse - |> snd) - - let (vb, newbps) = mergePoints files modu tracked bps - bp.Add newbps + let fr = fileRef modu group + let (sp, newsps, vs) = sequencePoints modu group + let (bp, newbps, vb) = branchPoints modu group // bec, bev heuristic - newsps - |> Seq.iter - (fun s -> - s.SetAttributeValue(XName.Get "bec", 0) - s.SetAttributeValue(XName.Get "bev", 0)) - if newsps |> Seq.isEmpty |> not && newbps |> Seq.isEmpty |> not then branchEntryHeuristic newsps newbps - let mpn = XName.Get "MethodPoint" - - let methodPoints = - group - |> snd - |> Seq.collect (fun x -> x.Elements mpn) - - let mpv = methodPoints |> mergeCounts - - let mp = - methodPoints - |> Seq.tryHead - |> Option.map - (fun r -> - let mp0 = XElement r - mp0.SetAttributeValue(XName.Get "vc", mpv) - - r.Attribute(XName.Get "fileid") - |> Option.ofObj - |> Option.iter - (fun a -> - let newfile = mapFile files a modu - mp0.SetAttributeValue(XName.Get "fileid", newfile)) - - mp0) + let (mp, mpv) = methodPoints modu group let merge = XElement(XName.Get "Method") @@ -1011,6 +1025,36 @@ coverlet on Tests.AltCoverRunnerTests/PostprocessShouldRestoreDegenerateOpenCove (tracked: Map) (modules: XElement seq) = + let findFiles (f:XElement) = + let foundFiles = + modules + |> Seq.collect (fun m -> m.Descendants(XName.Get "File")) + |> Seq.map (attributeOrEmpty "fullPath") + |> Seq.distinct + |> Seq.filter (String.IsNullOrWhiteSpace >> not) + |> Seq.sort + + foundFiles + |> Seq.iter + (fun file -> + XElement( + XName.Get "File", + XAttribute(XName.Get "uid", Map.find file files), + XAttribute(XName.Get "fullPath", file) + ) + |> f.Add) + + let findClasses (c:XElement) = + let classes = + modules + |> Seq.collect (fun m -> m.Descendants(XName.Get "Class")) + |> Seq.filter (fun x -> x.Attribute(XName.Get "skippedDueTo") |> isNull) + |> Seq.groupBy (fun x -> x.Element(XName.Get "FullName").Value) + + let msummary, merged = mergeClasses files tracked classes + c.Add merged + msummary + let r = modules |> Seq.head let merge = XElement(XName.Get "Module") @@ -1031,36 +1075,11 @@ coverlet on Tests.AltCoverRunnerTests/PostprocessShouldRestoreDegenerateOpenCove let f = XElement(XName.Get "Files") merge.Add f - - let foundFiles = - modules - |> Seq.collect (fun m -> m.Descendants(XName.Get "File")) - |> Seq.map (attributeOrEmpty "fullPath") - |> Seq.distinct - |> Seq.filter (String.IsNullOrWhiteSpace >> not) - |> Seq.sort - - foundFiles - |> Seq.iter - (fun file -> - XElement( - XName.Get "File", - XAttribute(XName.Get "uid", Map.find file files), - XAttribute(XName.Get "fullPath", file) - ) - |> f.Add) + findFiles f let c = XElement(XName.Get "Classes") merge.Add c - - let classes = - modules - |> Seq.collect (fun m -> m.Descendants(XName.Get "Class")) - |> Seq.filter (fun x -> x.Attribute(XName.Get "skippedDueTo") |> isNull) - |> Seq.groupBy (fun x -> x.Element(XName.Get "FullName").Value) - - let msummary, merged = mergeClasses files tracked classes - c.Add merged + let msummary = findClasses c msummary.Xml.Attributes() |> Seq.map XAttribute @@ -1200,14 +1219,28 @@ coverlet on Tests.AltCoverRunnerTests/PostprocessShouldRestoreDegenerateOpenCove [] let JsonToXml (document: string) = - document - |> NativeJson.fromJsonText - |> NativeJson.jsonToXml - |> NativeJson.orderXml + let json = + document + |> NativeJson.fromJsonText + let xml = + json + |> NativeJson.jsonToXml + |> NativeJson.orderXml + + // heuristic for coverlet vs altcover + let sp = json.Values + |> Seq.collect (fun m -> m.Values) + |> Seq.collect (fun d -> d.Values) + |> Seq.collect (fun c -> c.Values) + |> Seq.filter (fun m -> m.SeqPnts.IsNotNull) + |> Seq.collect (fun m -> m.SeqPnts) + |> Seq.isEmpty |> not + PostProcess xml (if sp then BranchOrdinal.Offset else BranchOrdinal.SL) + xml [] -() +() \ No newline at end of file diff --git a/AltCover.Toolkit/Xml.fs b/AltCover.Toolkit/Xml.fs index 726660626..d28ae90b0 100644 --- a/AltCover.Toolkit/Xml.fs +++ b/AltCover.Toolkit/Xml.fs @@ -26,9 +26,9 @@ module XmlTypes = let cn = xmlDocument.ChildNodes - match cn.OfType() |> Seq.tryHead with - | None -> () - | Some doctype -> + cn.OfType() + |> Seq.tryHead + |> Option.iter (fun doctype -> let xDoctype = document.DocumentType let newDoctype = @@ -40,11 +40,11 @@ module XmlTypes = ) xmlDocument.ReplaceChild(newDoctype, doctype) - |> ignore + |> ignore) - let xDeclaration = document.Declaration - - if xDeclaration.IsNotNull then + document.Declaration + |> Option.ofObj + |> Option.iter (fun xDeclaration -> let xmlDeclaration = xmlDocument.CreateXmlDeclaration( xDeclaration.Version, @@ -53,7 +53,7 @@ module XmlTypes = ) xmlDocument.InsertBefore(xmlDeclaration, xmlDocument.FirstChild) - |> ignore + |> ignore) xmlDocument @@ -69,9 +69,9 @@ module XmlTypes = let xdoc = XDocument.Load(nodeReader) let cn = xmlDocument.ChildNodes - match cn.OfType() |> Seq.tryHead with - | None -> () - | Some doctype -> + cn.OfType() + |> Seq.tryHead + |> Option.iter (fun doctype -> xdoc.AddFirst( XDocumentType( nullIfEmpty doctype.Name, @@ -79,15 +79,12 @@ module XmlTypes = nullIfEmpty doctype.SystemId, nullIfEmpty doctype.InternalSubset ) - ) - - let decl' = - cn.OfType() |> Seq.tryHead + )) - match decl' with - | None -> () - | Some decl -> - xdoc.Declaration <- XDeclaration(decl.Version, decl.Encoding, decl.Standalone) + cn.OfType() + |> Seq.tryHead + |> Option.iter (fun decl -> + xdoc.Declaration <- XDeclaration(decl.Version, decl.Encoding, decl.Standalone)) cn.OfType() |> Seq.rev diff --git a/AltCover.Toolkit/XmlInternal.fs b/AltCover.Toolkit/XmlInternal.fs index 67fbcc9c4..20107ac07 100644 --- a/AltCover.Toolkit/XmlInternal.fs +++ b/AltCover.Toolkit/XmlInternal.fs @@ -31,7 +31,7 @@ module internal XmlUtilities = let resource = here.GetName().Name + match format with - | AltCover.ReportFormat.NCover -> ".xsd.NCover.xsd" + | AltCover.ReportFormat.NCover -> ".xsd.NCoverEmbedded.xsd" | _ -> ".xsd.OpenCover.xsd" use stream = here.GetManifestResourceStream(resource) diff --git a/AltCover.Toolkit/xsd/NCoverEmbedded.xsd b/AltCover.Toolkit/xsd/NCoverEmbedded.xsd new file mode 100644 index 000000000..5c9b63600 --- /dev/null +++ b/AltCover.Toolkit/xsd/NCoverEmbedded.xsd @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Toolkit/xsd/OpenCover.xsd b/AltCover.Toolkit/xsd/OpenCover.xsd index dd88e15e5..5f0c17c86 100644 --- a/AltCover.Toolkit/xsd/OpenCover.xsd +++ b/AltCover.Toolkit/xsd/OpenCover.xsd @@ -43,6 +43,7 @@ + diff --git a/AltCover.Toolkit/xsl/OpenCoverToNCover.xsl b/AltCover.Toolkit/xsl/OpenCoverToNCover.xsl index befccc048..c4f41ad68 100644 --- a/AltCover.Toolkit/xsl/OpenCoverToNCover.xsl +++ b/AltCover.Toolkit/xsl/OpenCoverToNCover.xsl @@ -20,8 +20,6 @@ - - @@ -36,6 +34,8 @@ + + @@ -44,6 +44,9 @@ + + + diff --git a/AltCover.Toolkit/xsl/OpenCoverToNCoverEx.xsl b/AltCover.Toolkit/xsl/OpenCoverToNCoverEx.xsl index 57e48e87a..872dff7ef 100644 --- a/AltCover.Toolkit/xsl/OpenCoverToNCoverEx.xsl +++ b/AltCover.Toolkit/xsl/OpenCoverToNCoverEx.xsl @@ -20,8 +20,6 @@ - - @@ -34,16 +32,13 @@ - - - + + - - @@ -51,12 +46,19 @@ - + + + + + + + + diff --git a/AltCover.UICommon/AltCover.UICommon.fsproj b/AltCover.UICommon/AltCover.UICommon.fsproj index 76e1ab34a..1a1446293 100644 --- a/AltCover.UICommon/AltCover.UICommon.fsproj +++ b/AltCover.UICommon/AltCover.UICommon.fsproj @@ -7,8 +7,6 @@ AltCover.UICommon false true - true - true GUI;LITEVERSION $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -17,6 +15,15 @@ false + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) 4 @@ -52,7 +59,7 @@ - + @@ -83,6 +90,7 @@ + @@ -100,7 +108,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -113,7 +121,8 @@ - + + contentfiles diff --git a/AltCover.UICommon/Compatibility.fs b/AltCover.UICommon/Compatibility.fs new file mode 100644 index 000000000..51253a300 --- /dev/null +++ b/AltCover.UICommon/Compatibility.fs @@ -0,0 +1,35 @@ +namespace AltCover + +open System +open System.Diagnostics.CodeAnalysis +open System.Net +open System.Security.Cryptography + +// netstandard 2.0 APIs obsoleted at net 6.0+ + +[] +[] +module Compatibility = +#if !GUI + [] + let internal sha1Hash () : SHA1 = + new SHA1CryptoServiceProvider() :> SHA1 +#endif + + [] + let internal createHttp (path:Uri) = + WebRequest.CreateHttp(path) :> WebRequest + +#if GUI + [] + let internal readAllText (path:Uri) = + use client = new System.Net.WebClient() + client.DownloadString(path) +#endif \ No newline at end of file diff --git a/AltCover.UICommon/CoverageFile.fs b/AltCover.UICommon/CoverageFile.fs index a4c765694..027240d8d 100644 --- a/AltCover.UICommon/CoverageFile.fs +++ b/AltCover.UICommon/CoverageFile.fs @@ -32,6 +32,11 @@ type InvalidFile = { File: FileInfo; Fault: Exception } module Transformer = // now, what was this for?? + [] + [] let internal defaultHelper (_: XDocument) (document: XDocument) = document let internal loadTransform (path: string) = @@ -136,29 +141,84 @@ module Transformer = report - // PartCover to NCover style sheet - let internal convertFile - (helper: XmlCoverageType -> XDocument -> XDocument -> XDocument) - (document: XDocument) - = - let schemas = XmlSchemaSet() + let private resourceStream n = + new StreamReader( + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream(n) + ) - use sr1 = + let private processOpenCover + (helper: XmlCoverageType -> XDocument -> XDocument -> XDocument) + (schemas:XmlSchemaSet) (document:XDocument) + (ocreader:XmlReader) (ncreader:XmlReader) : Either = + schemas.Add(String.Empty, ocreader) |> ignore + document.Validate(schemas, null) + + let report = transformFromOpenCover document + + let fixedup = + helper XmlCoverageType.OpenCover document report + // Consistency check our XSLT + let schemas2 = XmlSchemaSet() + schemas2.Add(String.Empty, ncreader) |> ignore + fixedup.Validate(schemas2, null) + + // Fix for column-defective OpenCover + let lineOnly = + fixedup.Descendants(XName.Get "seqpnt") + |> Seq.forall + (fun s -> + let columns = (s.Attribute(XName.Get "column").Value, + s.Attribute(XName.Get "endcolumn").Value) + s.Attribute(XName.Get "line").Value = s + .Attribute( + XName.Get "endline" + ) + .Value + && (columns = ("1", "2") || // For coverlet derived OpenCover (either from coverlet XML or via JsonToXml) + columns = ("0", "0"))) // For OpenCover on C++/CLI + + if lineOnly then + fixedup.Root.Add(XAttribute(XName.Get "lineonly", "true")) + + Right fixedup + + let private processCobertura + (helper: XmlCoverageType -> XDocument -> XDocument -> XDocument) + (schemas:XmlSchemaSet) (document:XDocument) + (ncreader:XmlReader) : Either = + use cr = new StreamReader( Assembly .GetExecutingAssembly() - .GetManifestResourceStream("AltCover.UICommon.OpenCover.xsd") + .GetManifestResourceStream("AltCover.UICommon.Cobertura.xsd") ) - use ocreader = XmlReader.Create(sr1) + use creader = XmlReader.Create(cr) + schemas.Add(String.Empty, creader) |> ignore + document.Validate(schemas, null) + let report = transformFromCobertura document - use sr2 = - new StreamReader( - Assembly - .GetExecutingAssembly() - .GetManifestResourceStream("AltCover.UICommon.NCover.xsd") - ) + let fixedup = + helper XmlCoverageType.Cobertura document report + // Consistency check our XSLT + let schemas2 = XmlSchemaSet() + schemas2.Add(String.Empty, ncreader) |> ignore + fixedup.Validate(schemas2, null) + Right fixedup + // OpenCover to NCover style sheet + let internal convertFile + (helper: XmlCoverageType -> XDocument -> XDocument -> XDocument) + (document: XDocument) + = + let schemas = XmlSchemaSet() + + use sr1 = resourceStream "AltCover.UICommon.OpenCover.xsd" + use ocreader = XmlReader.Create(sr1) + + use sr2 = resourceStream "AltCover.UICommon.NCoverEmbedded.xsd" use ncreader = XmlReader.Create(sr2) try @@ -166,62 +226,14 @@ module Transformer = match document.Root.Name.LocalName with | x when x = "CoverageSession" -> // Assume OpenCover - schemas.Add(String.Empty, ocreader) |> ignore - document.Validate(schemas, null) - - let report = transformFromOpenCover document - - let fixedup = - helper XmlCoverageType.OpenCover document report - // Consistency check our XSLT - let schemas2 = XmlSchemaSet() - schemas2.Add(String.Empty, ncreader) |> ignore - fixedup.Validate(schemas2, null) - - // Fix for column-defective OpenCover - let lineOnly = - fixedup.Descendants(XName.Get "seqpnt") - |> Seq.forall - (fun s -> - let columns = (s.Attribute(XName.Get "column").Value, - s.Attribute(XName.Get "endcolumn").Value) - s.Attribute(XName.Get "line").Value = s - .Attribute( - XName.Get "endline" - ) - .Value - && (columns = ("1", "2") || // For coverlet derived OpenCover (either from coverlet XML or via JsonToXml) - columns = ("0", "0"))) // For OpenCover on C++/CLI - - if lineOnly then - fixedup.Root.Add(XAttribute(XName.Get "lineonly", "true")) - - Right fixedup + processOpenCover helper schemas document ocreader ncreader | _ -> let root = document.Root if root.Name.LocalName = "coverage" && root.Attribute(XName.Get "line-rate").IsNotNull then // Cobertura - use cr = - new StreamReader( - Assembly - .GetExecutingAssembly() - .GetManifestResourceStream("AltCover.UICommon.Cobertura.xsd") - ) - - use creader = XmlReader.Create(cr) - schemas.Add(String.Empty, creader) |> ignore - document.Validate(schemas, null) - let report = transformFromCobertura document - - let fixedup = - helper XmlCoverageType.Cobertura document report - // Consistency check our XSLT - let schemas2 = XmlSchemaSet() - schemas2.Add(String.Empty, ncreader) |> ignore - fixedup.Validate(schemas2, null) - Right fixedup + processCobertura helper schemas document ocreader else // Assume NCover schemas.Add(String.Empty, ncreader) |> ignore diff --git a/AltCover.UICommon/CoverageFileTree.fs b/AltCover.UICommon/CoverageFileTree.fs index 1a2bc898e..f7f102d0b 100644 --- a/AltCover.UICommon/CoverageFileTree.fs +++ b/AltCover.UICommon/CoverageFileTree.fs @@ -153,7 +153,14 @@ module CoverageFileTree = |> Seq.map (fun s -> let d = s.GetAttribute("document", String.Empty) - { (d |> getFileName) with Navigator = s }) + let state = { (d |> getFileName) with Navigator = s } + // get any embed and tweak state and icon accordingly + match GuiCommon.Embed s d with + | None -> state + | Some _ -> { state with Exists = true + Stale = false + Icon = environment.Icons.Source } + ) |> Seq.distinctBy (fun s -> s.FullName) // allows for same name, different path |> Seq.sortBy (fun s -> s.FileName |> upcase) |> Seq.toList diff --git a/AltCover.UICommon/GuiCommon.fs b/AltCover.UICommon/GuiCommon.fs index 5286f5ccc..4b46f6f84 100644 --- a/AltCover.UICommon/GuiCommon.fs +++ b/AltCover.UICommon/GuiCommon.fs @@ -3,6 +3,7 @@ namespace AltCover open System open System.Diagnostics.CodeAnalysis open System.IO +open System.IO.Compression open System.Xml.XPath open System.Net @@ -58,6 +59,16 @@ module GuiCommon = (name, MethodType.Normal) // -------------------------- Source file Handling --------------------------- + let Embed (node:XPathNavigator) (document: string) = + node.SelectAncestors("module", String.Empty, false) + |> Seq.cast + |> Seq.collect(fun n -> n.SelectDescendants("altcover.file", String.Empty, false) + |> Seq.cast) + |> Seq.filter (fun n -> n.GetAttribute("document", String.Empty) = document) + |> Seq.map (fun n -> n.GetAttribute("embed", String.Empty)) + |> Seq.filter (String.IsNullOrWhiteSpace >> not) + |> Seq.tryHead + [] [ info.Exists + | Embed (_, s) -> s |> String.IsNullOrWhiteSpace |> not | Url u -> - let request = WebRequest.CreateHttp(u) + let request = createHttp(u) request.Method <- "HEAD" try @@ -80,8 +93,9 @@ module GuiCommon = && (response :?> HttpWebResponse).StatusCode |> int < 400 with :? WebException -> false - member self.FullName = + member internal self.FullName = match self with + | Embed (name, _) -> name | File info -> if info |> isNull then String.Empty @@ -89,19 +103,32 @@ module GuiCommon = info.FullName | Url u -> u.AbsoluteUri - member self.Outdated epoch = + member internal self.Outdated epoch = match self with | File info -> if info.Exists then info.LastWriteTimeUtc > epoch else false // can't tell; should show as non-existing - | _ -> false // Sensible SourceLink assumed + | _ -> false // Embed or ensible SourceLink assumed member self.ReadAllText() = match self with | File info -> info.FullName |> File.ReadAllText - | Url u -> - use client = new System.Net.WebClient() - client.DownloadString(u) + | Url u -> readAllText u + | Embed (_,source) -> let data = Convert.FromBase64String source + use raw = new MemoryStream(data) + use expanded = new MemoryStream() + // Get deflation working with this one weird trick + // Dispose the deflate stream w/o closing the one it points at! + do + use expand = new DeflateStream(raw, CompressionMode.Decompress, true) + expand.CopyTo expanded + System.Text.Encoding.UTF8.GetString(expanded.GetBuffer(), + 0, int expanded.Length) + + member internal self.MakeEmbedded (filename: string) (source: string option) = + match (self, source) with + | (File info, Some _) -> Embed (filename, source.Value) + | _ -> self let GetSource (document: string) = if diff --git a/AltCover.UICommon/HandlerCommon.fs b/AltCover.UICommon/HandlerCommon.fs index 55a321fd8..07786dab9 100644 --- a/AltCover.UICommon/HandlerCommon.fs +++ b/AltCover.UICommon/HandlerCommon.fs @@ -43,7 +43,10 @@ module HandlerCommon = else let filename = Option.get document window.Title <- "AltCover.Visualizer - " + filename - let info = GetSource(filename) + // get embed if any & fold it in here + let embed = GuiCommon.Embed methodPath filename + let info = GetSource(filename).MakeEmbedded filename embed + let lineNumber = Int32.TryParse(line |> Option.get) |> snd @@ -118,14 +121,14 @@ module HandlerCommon = [] - let TagCoverage (methodPath: XPathNavigator) (fileName: string) (sourceLines: int) = + let TagCoverage (methodPath: XPathNavigator) (file: Source) (sourceLines: int) = let lineOnly = methodPath.Select("//coverage[@lineonly]") |> Seq.cast |> Seq.isEmpty |> not - methodPath.Select("//seqpnt[@document='" + fileName + "']") + methodPath.Select("//seqpnt[@document='" + file.FullName + "']") // TODO encapsulate more |> Seq.cast |> Seq.map (coverageToTag lineOnly) |> Seq.filter (filterCoverage sourceLines) @@ -175,10 +178,9 @@ module HandlerCommon = 0 - let TagBranches (methodPath: XPathNavigator) (fileName: string) = - (methodPath.Select("//method[@document='" + fileName + "']") + let TagBranches (methodPath: XPathNavigator) (file: Source) = + (methodPath.Select("//branch[@document='" + file.FullName + "']") // TODO |> Seq.cast - |> Seq.collect (fun n -> n.Select("./branch") |> Seq.cast) |> Seq.groupBy (fun n -> n.GetAttribute("line", String.Empty)) |> Seq.toList |> Seq.map diff --git a/AltCover.UICommon/Lcov.fs b/AltCover.UICommon/Lcov.fs index 3b608eef6..c324c2c9f 100644 --- a/AltCover.UICommon/Lcov.fs +++ b/AltCover.UICommon/Lcov.fs @@ -59,14 +59,14 @@ module internal Lcov = | FN _ | DA _ | BRDA _ -> true - | _ -> r |> sprintf "%A" |> InvalidDataException |> raise) + | _ -> raise (r |> sprintf "%A" |> InvalidDataException )) |> Seq.sortBy (fun r -> match r with | FN (a, _) -> 4 * a | DA (a, _) -> (4 * a) + 1 | BRDA (a, _, _, _) -> (4 * a) + 2 - | _ -> r |> sprintf "%A" |> InvalidDataException |> raise) + | _ -> raise (r |> sprintf "%A" |> InvalidDataException)) |> Seq.fold (fun x r -> // match r with @@ -137,7 +137,7 @@ module internal Lcov = x.Add br x - | _ -> r |> sprintf "%A" |> InvalidDataException |> raise) + | _ -> raise (r |> sprintf "%A" |> InvalidDataException)) null |> ignore @@ -164,10 +164,9 @@ module internal Lcov = | n :: v :: _ -> DA(n |> Int32.TryParse |> snd, v |> Int32.TryParse |> snd) | _ -> - line - |> sprintf "%A" - |> InvalidDataException - |> raise + raise (line + |> sprintf "%A" + |> InvalidDataException) | l when l.StartsWith("BRDA:", StringComparison.Ordinal) -> match (l.Substring 5).Split(',') |> Array.toList with | n :: v :: x :: y :: _ -> @@ -178,10 +177,9 @@ module internal Lcov = y |> Int32.TryParse |> snd ) | _ -> - line - |> sprintf "%A" - |> InvalidDataException - |> raise + raise (line + |> sprintf "%A" + |> InvalidDataException) | _ -> Other) |> Seq.fold (fun (i, l) r -> diff --git a/AltCover.ValidateGendarmeEmulation/AltCover.ValidateGendarmeEmulation.fsproj b/AltCover.ValidateGendarmeEmulation/AltCover.ValidateGendarmeEmulation.fsproj index 14053e755..2e63187fe 100644 --- a/AltCover.ValidateGendarmeEmulation/AltCover.ValidateGendarmeEmulation.fsproj +++ b/AltCover.ValidateGendarmeEmulation/AltCover.ValidateGendarmeEmulation.fsproj @@ -1,7 +1,7 @@  - net5.0;net472 + net6.0;net472 false $(USERPROFILE)\.nuget\packages $(HOME)/.nuget/packages @@ -22,11 +22,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + $(GendarmeToolDir)Gendarme.Framework.dll @@ -75,10 +75,11 @@ runtime; build; native; contentfiles; analyzers - + - + + contentfiles diff --git a/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj b/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj index 3165964d8..dfe3a99c9 100644 --- a/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj +++ b/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj @@ -1,7 +1,7 @@  - net5.0;net472 + net6.0;net472 false false AltCover.Tests.Visualizer @@ -19,7 +19,7 @@ TRACE;$(GlobalDefineConstants) --keyfile:$(ProjectDir)..\Build\Infrastructure.snk - + 988 @@ -35,9 +35,9 @@ all runtime; build; native; contentfiles; analyzers - + - + @@ -64,7 +64,8 @@ - + + contentfiles diff --git a/AltCover.Visualizer.sln b/AltCover.Visualizer.sln index 97de22f27..36a11340e 100644 --- a/AltCover.Visualizer.sln +++ b/AltCover.Visualizer.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29324.140 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.Avalonia", "AltCover.Avalonia\AltCover.Avalonia.fsproj", "{48032486-334E-4D3A-B6B6-4E3165A33FBD}" EndProject diff --git a/AltCover.Visualizer/AltCover.Visualizer.fsproj b/AltCover.Visualizer/AltCover.Visualizer.fsproj index 2cc8212be..0ea3295b7 100644 --- a/AltCover.Visualizer/AltCover.Visualizer.fsproj +++ b/AltCover.Visualizer/AltCover.Visualizer.fsproj @@ -11,8 +11,6 @@ altcover.visualizer AltCover.Visualizer true - true - true GUI $(ProjectDir)../ $(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/ @@ -23,6 +21,15 @@ false + + false + false + + + true + true + + TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) --tailcalls+ --keyfile:$(ProjectDir)..\Build\Infrastructure.snk @@ -54,7 +61,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -100,7 +107,8 @@ - + + contentfiles diff --git a/AltCover.Visualizer/Visualizer.fs b/AltCover.Visualizer/Visualizer.fs index 66a7936c4..711a0f795 100644 --- a/AltCover.Visualizer/Visualizer.fs +++ b/AltCover.Visualizer/Visualizer.fs @@ -90,14 +90,24 @@ module private Gui = active +#if NET472 + [] + [] + let private urlHook _ link = + Browser.ShowUrl(Uri link) +#endif + let private prepareAboutDialog (handler: Handler) = #if !NET472 handler.aboutVisualizer.TransientFor <- handler.mainWindow #else - AboutDialog.SetUrlHook(fun _ link -> Browser.ShowUrl(Uri link)) + AboutDialog.SetUrlHook(urlHook) |> ignore - LinkButton.SetUriHook(fun _ link -> Browser.ShowUrl(Uri link)) + LinkButton.SetUriHook(urlHook) |> ignore handler.aboutVisualizer.ActionArea.Children.OfType