diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 33cc1ae3..f9cdc50e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-reportgenerator-globaltool": { - "version": "5.3.6", + "version": "5.3.8", "commands": [ "reportgenerator" ], @@ -38,7 +38,7 @@ "rollForward": false }, "nbgv": { - "version": "3.6.139", + "version": "3.6.141", "commands": [ "nbgv" ], diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index eea56dd0..3ae7fbe3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.300' + dotnet-version: '8.0.400' - name: Tools run: dotnet tool restore - name: Setup @@ -63,7 +63,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.300' + dotnet-version: '8.0.400' - name: Tools run: dotnet tool restore - name: Setup diff --git a/AltCover.Api.Tests/AltCover.Api.Tests.fsproj b/AltCover.Api.Tests/AltCover.Api.Tests.fsproj index 23af45cd..e7549747 100644 --- a/AltCover.Api.Tests/AltCover.Api.Tests.fsproj +++ b/AltCover.Api.Tests/AltCover.Api.Tests.fsproj @@ -10,6 +10,8 @@ $(AssemblySearchPaths);{GAC} DEBUG;TRACE MSB3277 + NU1901;NU1902;NU1903;$(NoWarn) + NU1901;NU1902;NU1903 diff --git a/AltCover.Api.Tests/FSApiTests.fs b/AltCover.Api.Tests/FSApiTests.fs index 2e6e16fb..5ca097c8 100644 --- a/AltCover.Api.Tests/FSApiTests.fs +++ b/AltCover.Api.Tests/FSApiTests.fs @@ -893,7 +893,7 @@ module FSApiTests = |> Seq.iter (fun a -> a.Value <- "false") let cob = - CoverageFormats.ConvertToCobertura doc + CoverageFormats.ConvertToCobertura doc [] use stream2 = new MemoryStream() cob.Save stream2 @@ -947,7 +947,7 @@ module FSApiTests = |> Seq.iter (fun a -> a.Value <- "false") let cob = - CoverageFormats.ConvertToCobertura doc + CoverageFormats.ConvertToCobertura doc [ "d:/a01/_work/5/s/src/" ] use stream2 = new MemoryStream() cob.Save stream2 @@ -1200,6 +1200,8 @@ module FSApiTests = let collectFragments = [ DotNet.I.toCollectFromArgArgumentList + >> (List.map (fun (_, n, _) -> n)) + DotNet.I.toCollectListArgArgumentList >> (List.map (fun (_, n, _) -> n)) _.Verbosity >> DotNet.I.toSharedFromValueArgumentList diff --git a/AltCover.Avalonia/AltCover.Avalonia.fsproj b/AltCover.Avalonia/AltCover.Avalonia.fsproj index 2575da3b..f98dc375 100644 --- a/AltCover.Avalonia/AltCover.Avalonia.fsproj +++ b/AltCover.Avalonia/AltCover.Avalonia.fsproj @@ -11,6 +11,7 @@ True $(ProjectDir)../AltCover.Visualizer/Resource.res NU1902,NU1903,NU1904 + NU1901;NU1902;NU1903;NU1904 @@ -29,10 +30,10 @@ AltCover.App.xaml - + AltCover.AboutBox.xaml - + diff --git a/AltCover.Cake/Options.cs b/AltCover.Cake/Options.cs index b67d8414..6642a5fd 100644 --- a/AltCover.Cake/Options.cs +++ b/AltCover.Cake/Options.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Text; +using System.Linq; using FSDotNet = AltCover.DotNet; @@ -326,6 +326,11 @@ public class CollectOptions : Abstract.ICollectOptions Justification = "Lcov is a name")] public virtual string Cobertura => String.Empty; + /// + /// Corresponds to command line option `-p, --package=VALUE` + /// + public IEnumerable Packages => Enumerable.Empty(); + /// /// Corresponds to command line option `-o, --outputFile=VALUE` /// diff --git a/AltCover.DotNet/DotNet.fs b/AltCover.DotNet/DotNet.fs index f69f431f..5f4e3ce8 100644 --- a/AltCover.DotNet/DotNet.fs +++ b/AltCover.DotNet/DotNet.fs @@ -70,11 +70,16 @@ module DotNet = let private arg name (s: string) = (sprintf """AltCover%s""" name, s) let private listArg name (s: String seq) = - (sprintf """AltCover%s""" name, String.Join("|", s)) + (sprintf """AltCover%s""" name, String.Join("|", s) + "|") let private isSet s = s |> String.IsNullOrWhiteSpace |> not - let private fromList name (s: String seq) = (listArg name s, s.Any()) + let private fromList name (s: String seq) = + let s' = + s |> Seq.filter (String.IsNullOrWhiteSpace >> not) + + (listArg name s', s'.Any()) + let internal fromArg name s = (arg name s, isSet s) let internal fromValue name (s: obj) (b: bool) = (arg name <| s.ToString(), b) @@ -136,6 +141,12 @@ module DotNet = fromArg, "Threshold", collect.Threshold //=`"coverage threshold required" fromArg, "SummaryFormat", collect.SummaryFormat ] //=[BROCN+]` one or more of TeamCity Block format/TeamCity bRanch format/Classic OpenCover/CRAP score or none at all; `+` means the same as `OC` which is also the default + [] + let internal toCollectListArgArgumentList (collect: Abstract.ICollectOptions) = + [ fromList, "Packages", collect.Packages ] //=`"pipe `'|'` separated list of method name regexs" + let internal toSharedFromValueArgumentList (verbosity: System.Diagnostics.TraceLevel) : ((string -> obj -> bool -> (string * string) * bool) * string * obj * bool) list = @@ -181,6 +192,9 @@ module DotNet = collect |> I.toCollectFromArgArgumentList |> List.map (fun (f, n, a) -> f n a) + collect + |> I.toCollectListArgArgumentList + |> List.map (fun (f, n, a) -> f n a) Math.Min(int prepare.Verbosity, int collect.Verbosity) |> enum diff --git a/AltCover.DotNet/DotNet.fsi b/AltCover.DotNet/DotNet.fsi index 44f81366..520add81 100644 --- a/AltCover.DotNet/DotNet.fsi +++ b/AltCover.DotNet/DotNet.fsi @@ -94,6 +94,10 @@ module DotNet = begin val toCollectFromArgArgumentList : collect:Abstract.ICollectOptions -> ((string -> string -> (string*string)* bool) * string * System.String) list + val toCollectListArgArgumentList : + collect:Abstract.ICollectOptions -> + ((string -> #seq -> (string*string) * bool) * string * + System.String seq) list val toSharedFromValueArgumentList : verbosity : System.Diagnostics.TraceLevel -> ((string -> obj -> bool -> (string*string)*bool) * string * obj * bool) list diff --git a/AltCover.DotNet/Options.fs b/AltCover.DotNet/Options.fs index 7e489876..612300b3 100644 --- a/AltCover.DotNet/Options.fs +++ b/AltCover.DotNet/Options.fs @@ -44,6 +44,8 @@ module Options = Justification = "Cobertura is a name")>] member val Cobertura = String.Empty with get, set + member val Packages = Seq.empty with get, set + member val OutputFile = String.Empty with get, set member val CommandLine = Seq.empty with get, set member val ExposeReturnCode = true with get, set @@ -71,6 +73,8 @@ module Options = Justification = "Cobertura is a name")>] member self.Cobertura = self.Cobertura + member self.Packages = self.Packages + member self.OutputFile = self.OutputFile member self.CommandLine = self.CommandLine diff --git a/AltCover.Engine/Abstract.fs b/AltCover.Engine/Abstract.fs index fdfff30b..8c049c18 100644 --- a/AltCover.Engine/Abstract.fs +++ b/AltCover.Engine/Abstract.fs @@ -77,6 +77,10 @@ module Abstract = Justification="Cobertura is a name")>] //// no doc abstract member Cobertura : String with get /// + /// Corresponds to command line option `-p, --package=VALUE` + /// + abstract member Packages : IEnumerable with get + /// /// Corresponds to command line option `-o, --outputFile=VALUE` /// abstract member OutputFile : String with get diff --git a/AltCover.Engine/AltCover.fs b/AltCover.Engine/AltCover.fs index 6e44ab64..0a15ccc3 100644 --- a/AltCover.Engine/AltCover.fs +++ b/AltCover.Engine/AltCover.fs @@ -104,6 +104,12 @@ module AltCover = | Abstract a -> a.Cobertura | TypeSafe t -> t.Cobertura.AsString() + member self.Packages = + match self with + | Primitive p -> p.Packages + | Abstract a -> a.Packages + | TypeSafe t -> t.Packages.AsStrings() + member self.OutputFile = match self with | Primitive p -> p.OutputFile @@ -145,6 +151,7 @@ module AltCover = member self.LcovReport = self.LcovReport member self.Threshold = self.Threshold member self.Cobertura = self.Cobertura + member self.Packages = self.Packages member self.OutputFile = self.OutputFile member self.CommandLine = self.CommandLine diff --git a/AltCover.Engine/AltCover.fsi b/AltCover.Engine/AltCover.fsi index 64bed3b9..1d1cae30 100644 --- a/AltCover.Engine/AltCover.fsi +++ b/AltCover.Engine/AltCover.fsi @@ -100,6 +100,10 @@ namespace AltCoverFake.DotNet.Testing /// member Cobertura : System.String /// + /// Corresponds to command line option `-p, --package=VALUE` + /// + member Packages : seq + /// /// Corresponds to command line option `-o, --outputFile=VALUE` /// member OutputFile : System.String diff --git a/AltCover.Engine/Args.fs b/AltCover.Engine/Args.fs index 1b129c35..625512e9 100644 --- a/AltCover.Engine/Args.fs +++ b/AltCover.Engine/Args.fs @@ -129,6 +129,12 @@ module internal Args = [ parameters; trailing ] |> List.concat let internal buildCollect (args: Abstract.ICollectOptions) = + let packages = + args.Packages + |> Seq.map (fun p -> [ "-p"; p ]) + |> Seq.toList + |> List.concat + let argsList = args.CommandLine |> Seq.toList @@ -156,6 +162,7 @@ module internal Args = item "-l" args.LcovReport item "-t" args.Threshold item "-c" args.Cobertura + packages item "-o" args.OutputFile flag "--collect" (exe |> String.IsNullOrWhiteSpace) flag "--dropReturnCode" (args.ExposeReturnCode |> not) diff --git a/AltCover.Engine/Cobertura.fs b/AltCover.Engine/Cobertura.fs index d9599d5b..8d427095 100644 --- a/AltCover.Engine/Cobertura.fs +++ b/AltCover.Engine/Cobertura.fs @@ -17,6 +17,9 @@ module internal Cobertura = let internal path: Option ref = ref None + let internal packages: string list ref = + ref List.empty + module internal I = let internal setRate hits total (rate: string) (target: XElement) = @@ -157,8 +160,12 @@ module internal Cobertura = |> Seq.map (fun (a, s) -> a, s |> Seq.map fst) |> Seq.sortBy fst // seq of (directory, files full names) + let packaged = + packages.Value + |> Seq.map (fun x -> x, Seq.empty) + let groupable = // seq of ((directory, files full names), facets) - rawsources + Seq.concat [ packaged; rawsources ] |> Seq.map (fun x -> (x, x |> fst |> splitPath)) let groups = // seq of (root, seq of ((directory, files full names), facets)) @@ -168,6 +175,7 @@ module internal Cobertura = groups |> Seq.map (snd >> extractSource) results + |> Seq.sortBy fst |> Seq.iter (fun f -> target.Descendants("sources".X) |> Seq.iter _.Add(XElement("source".X, XText(fst f)))) @@ -267,7 +275,7 @@ module internal Cobertura = (mname, signature) (key, (signature, m))) - |> LCov.sortByFirst + |> LCov.sortByFirst id |> Seq.fold (processMethod document methods) (0, 0) let processClass @@ -528,7 +536,7 @@ module internal Cobertura = fn.Substring(start, argsAt - start) (key, (signature, method))) - |> LCov.sortByFirst + |> LCov.sortByFirst id |> Seq.filter (fun (_, (_, mt)) -> mt.Descendants("SequencePoint".X) |> Seq.isEmpty diff --git a/AltCover.Engine/LCov.fs b/AltCover.Engine/LCov.fs index f58e8798..6002578b 100644 --- a/AltCover.Engine/LCov.fs +++ b/AltCover.Engine/LCov.fs @@ -19,7 +19,7 @@ module internal LCov = let internal path: Option ref = ref None - let internal sortByFirst s = s |> Seq.sortBy fst + let internal sortByFirst f s = s |> Seq.sortBy (fst >> f) module internal I = @@ -40,21 +40,34 @@ module internal LCov = ) |> Seq.min - let getVC (mp: XElement) = - mp.Attribute("vc".X) - |> Option.ofObj - |> Option.map _.Value - |> Option.defaultValue "0" + [] + [] + let internal slOfPartialMethod (m: XElement * XElement seq) = + let (_, s) = m - let internal multiSort (by: 'a -> int) (l: (string * 'a seq) seq) = + s + |> Seq.map (_.Attribute("sl".X).Value >> Int32.TryParse >> snd) + |> Seq.min + + let internal multiSort f (by: 'a -> int) (l: (string * 'a seq) seq) = l |> Seq.map (fun (f, ms) -> (f, ms |> Seq.sortBy by |> Seq.toList)) - |> sortByFirst + |> sortByFirst f let internal multiSortByNameAndPartialStartLine (l: (string * (XElement * XElement seq) seq) seq) = - multiSort lineOfPartialMethod l + multiSort id lineOfPartialMethod l + + let internal multiSortByNameAndPartialOpenCoverStartLine + documents + (l: (string * (XElement * XElement seq) seq) seq) + = + multiSort (fun d -> Map.find d documents) slOfPartialMethod l [ report.Descendants("Module".X) |> Seq.iter (fun assembly -> - assembly.Descendants("File".X) - |> Seq.sortBy _.Attribute("fullPath".X).Value - |> Seq.iter (fun f -> + let documents = + assembly.Descendants("File".X) + |> Seq.sortBy _.Attribute("fullPath".X).Value + |> Seq.map (fun f -> + (f.Attribute("uid".X).Value, f.Attribute("fullPath".X).Value)) + |> Map.ofSeq + + assembly.Descendants("Method".X) + |> Seq.collect (fun m -> + m.Descendants("SequencePoint".X) + |> Seq.groupBy _.Attribute("fileid".X).Value + |> Seq.map (fun (d, l) -> (d, (m, l)))) + |> Seq.groupBy fst + |> Seq.sortBy (fun (d, _) -> Map.find d documents) + |> Seq.map (fun (d, dmlist) -> d, dmlist |> Seq.map snd) + |> (I.multiSortByNameAndPartialOpenCoverStartLine documents) + |> Seq.iter (fun (uid, methods) -> //If available, a tracefile begins with the testname which // is stored in the following format: // @@ -267,65 +294,40 @@ FN:4,(anonymous_0) // containing filename and coverage data: // // SF: - writer.WriteLine("SF:" + f.Attribute("fullPath".X).Value) + writer.WriteLine("SF:" + (Map.find uid documents)) - let uid = f.Attribute("uid".X).Value - let p = f.Parent.Parent + let fullname (m: XElement) = + (m.Descendants("Name".X) |> Seq.head).Value // Following is a list of line numbers for each function name found in the // source file: // // FN:, - let methods = - p.Descendants("Method".X) - |> Seq.filter ( - _.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 - ms - |> Seq.iter (fun m -> - m.Descendants("SequencePoint".X) - |> Seq.filter (fun s -> s.Attribute("fileid".X).Value == uid) - |> Seq.tryHead - |> Option.iter (fun s -> - let n = - (m.Descendants("Name".X) |> Seq.head).Value - - let sl = s.Attribute("sl".X).Value - - if sl |> String.IsNullOrWhiteSpace |> not then - writer.WriteLine("FN:" + s.Attribute("sl".X).Value + "," + n))) + methods + |> Seq.iter (fun m -> + let l = + (I.slOfPartialMethod m) + .ToString(CultureInfo.InvariantCulture) - FN methods + 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: // // FNDA:, - let FNDA (ms: XElement list) = // fsharplint:disable-line NonPublicValuesNames - ms - |> Seq.iter (fun m -> - m.Descendants("SequencePoint".X) - |> Seq.filter (fun s -> s.Attribute("fileid".X).Value == uid) - |> Seq.tryHead - |> Option.iter (fun s -> - let n = - (m.Descendants("Name".X) |> Seq.head).Value - - let mp = - m.Descendants("MethodPoint".X) |> Seq.head - - let sl = s.Attribute("sl".X).Value - - let vc = I.getVC mp - - if sl |> String.IsNullOrWhiteSpace |> not then - writer.WriteLine("FNDA:" + vc + "," + n))) + let hit = + methods + |> Seq.fold + (fun (n: int) (m, _) -> + let v = + (m.Descendants("SequencePoint".X) |> Seq.head) + .Attribute("vc".X) + .Value - FNDA methods + let name = fullname m + writer.WriteLine("FNDA:" + v + "," + name) + n.Increment(v != "0")) + 0 // This list is followed by two lines containing the number of functions // found and hit: // @@ -336,21 +338,9 @@ FN:4,(anonymous_0) + methods.Length.ToString(CultureInfo.InvariantCulture) ) - let hit = - methods - |> 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 = I.getVC s - v.IsNotNull && v != "0")) - writer.WriteLine( "FNH:" - + hit.Length.ToString(CultureInfo.InvariantCulture) + + hit.ToString(CultureInfo.InvariantCulture) ) // Branch coverage information is stored which one line per branch: // @@ -405,7 +395,7 @@ FN:4,(anonymous_0) + brh.ToString(CultureInfo.InvariantCulture) ) - branch methods + branch (methods |> List.map fst) // Then there is a list of execution counts for each instrumented line // (i.e. a line which resulted in executable code): // @@ -416,26 +406,26 @@ FN:4,(anonymous_0) // checksumming algorithm. let (lf, lh) = methods - |> Seq.collect _.Descendants("SequencePoint".X) - |> Seq.filter (fun s -> s.Attribute("fileid".X).Value == uid) - |> Seq.filter (fun b -> - b.Attribute("sl".X).Value - |> String.IsNullOrWhiteSpace - |> not) - |> Seq.groupBy (_.Attribute("sl".X).Value >> Int32.TryParse >> snd) - |> Seq.sortBy fst + |> Seq.collect snd + |> Seq.filter ( + _.Attribute("sl".X).Value + >> String.IsNullOrWhiteSpace + >> not + ) + |> Seq.groupBy _.Attribute("sl".X).Value + |> Seq.sortBy (fst >> Int32.TryParse >> snd) |> Seq.fold - (fun (f, h) (line, points) -> - let sl = - line.ToString(CultureInfo.InvariantCulture) - - let vc = I.computeVisitCount points "vc" + (fun (f, (h: int)) (sl, bs) -> + let vc = I.computeVisitCount bs "vc" - let vcs = - vc.ToString(CultureInfo.InvariantCulture) + writer.WriteLine( + "DA:" + + sl + + "," + + vc.ToString(CultureInfo.InvariantCulture) + ) - writer.WriteLine("DA:" + sl + "," + vcs) - (f + 1, h + (if vcs == "0" then 0 else 1))) + (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: diff --git a/AltCover.Engine/Primitive.fs b/AltCover.Engine/Primitive.fs index 66feb216..8c5afc91 100644 --- a/AltCover.Engine/Primitive.fs +++ b/AltCover.Engine/Primitive.fs @@ -31,6 +31,7 @@ module Primitive = "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Cobertura is a name")>] Cobertura: String + Packages: String seq OutputFile: String CommandLine: String seq ExposeReturnCode: bool @@ -43,6 +44,7 @@ module Primitive = LcovReport = String.Empty Threshold = String.Empty Cobertura = String.Empty + Packages = [] OutputFile = String.Empty CommandLine = [] ExposeReturnCode = true diff --git a/AltCover.Engine/Primitive.fsi b/AltCover.Engine/Primitive.fsi index 9c5cb92e..862a216b 100644 --- a/AltCover.Engine/Primitive.fsi +++ b/AltCover.Engine/Primitive.fsi @@ -60,6 +60,10 @@ namespace AltCoverFake.DotNet.Testing /// Cobertura: System.String /// + /// Corresponds to command line option `-p, --package=VALUE` + /// + Packages : seq + /// /// Corresponds to command line option `-o, --outputFile=VALUE` /// OutputFile: System.String diff --git a/AltCover.Engine/Runner.fs b/AltCover.Engine/Runner.fs index 1d5dc1ce..c685903d 100644 --- a/AltCover.Engine/Runner.fs +++ b/AltCover.Engine/Runner.fs @@ -198,6 +198,7 @@ module internal Runner = executable.Value <- None LCov.path.Value <- None Cobertura.path.Value <- None + Cobertura.packages.Value <- List.empty Json.path.Value <- None collect.Value <- false threshold <- None @@ -827,6 +828,15 @@ module internal Runner = else Cobertura.path.Value <- x |> canonicalPath |> Some I.addCoberturaSummary ())) + ("p|package=", + (fun x -> + if x |> String.IsNullOrWhiteSpace |> not then + Cobertura.packages.Value <- x :: Cobertura.packages.Value + else + CommandLine.error <- + CommandLine.Format.Local("InvalidValue", "--package", x) + :: CommandLine.error)) + ("o|outputFile=", (fun x -> if CommandLine.validatePath "--outputFile" x then diff --git a/AltCover.Engine/Strings.eo.resx b/AltCover.Engine/Strings.eo.resx index 3ed9036b..d97bc31e 100644 --- a/AltCover.Engine/Strings.eo.resx +++ b/AltCover.Engine/Strings.eo.resx @@ -157,7 +157,7 @@ Vidu ankaŭ '--inplace' AltCover [/i[nputDirectory]=VALO] [/o[utputDirectory]=VALO] [/y|symbolDirectory=VALO] [/d[ependency]=VALO] [/k[ey]=VALO] [/sn|strongNameKey=VALO] [/r[eport]=VALO] [/f[ileFilter]=VALO] [/p[athFilter]=VALO] [/s|assemblyFilter=VALO] [/e|assemblyExcludeFilter=VALO] [/t[ypeFilter]=VALO] [/m[ethodFilter]=VALO] [/a[ttributeFilter]=VALO] [/attributetoplevel=VALO] [/typetoplevel=VALO] [/methodtoplevel=VALO] [--l[ocalSource]] [/c[allContext]=VALO] [/reportFormat=VALO] [--inplace] [--save] [--zipfile] [--methodpoint] [--single] [--linecover] [--branchcover] [--dropReturnCode] [--sourcelink] [--defer] [--v[isibleBranches]] [/showstatic[=VALO]] [--showGenerated] [--trivia] [--portable] [-q] [--verbose] [--?|help|h] [-- ] [...] aŭ -AltCover Runner [/r[ecorderDirectory]=VALO] [/w[orkingDirectory]=VALO] [/x|executable=VALO] [--collect] [/l[covReport]=VALO] [/t[hreshold]=VALO] [/c[obertura]=VALO] [/o[utputFile]=VALO] [--dropReturnCode] [/summary|teamcity[=VALO]] [-q] [--verbose] [--?|help|h] [-- ] [...] +AltCover Runner [/r[ecorderDirectory]=VALO] [/w[orkingDirectory]=VALO] [/x|executable=VALO] [--collect] [/l[covReport]=VALO] [/t[hreshold]=VALO] [/c[obertura]=VALO] [/p[ackage]=VALO] [/o[utputFile]=VALO] [--dropReturnCode] [/summary|teamcity[=VALO]] [-q] [--verbose] [--?|help|h] [-- ] [...] aŭ AltCover ImportModule aŭ @@ -474,4 +474,7 @@ Se la opcio ne ĉeestas, tiam la defaŭlta estas 'OC'. Malsukcesis forigi dosieron {0} + + Lauvola, multobla: paka radika vojo por Cobertura-raportoj + \ No newline at end of file diff --git a/AltCover.Engine/Strings.resx b/AltCover.Engine/Strings.resx index ae2534d2..7603e40f 100644 --- a/AltCover.Engine/Strings.resx +++ b/AltCover.Engine/Strings.resx @@ -157,7 +157,7 @@ See also '--inplace' AltCover [/i[nputDirectory]=VALUE] [/o[utputDirectory]=VALUE] [/y|symbolDirectory=VALUE] [/d[ependency]=VALUE] [/k[ey]=VALUE] [/sn|strongNameKey=VALUE] [/r[eport]=VALUE] [/f[ileFilter]=VALUE] [/p[athFilter]=VALUE] [/s|assemblyFilter=VALUE] [/e|assemblyExcludeFilter=VALUE] [/t[ypeFilter]=VALUE] [/m[ethodFilter]=VALUE] [/a[ttributeFilter]=VALUE] [/attributetoplevel=VALUE] [/typetoplevel=VALUE] [/methodtoplevel=VALUE] [--l[ocalSource]] [/c[allContext]=VALUE] [/reportFormat=VALUE] [--inplace] [--save] [--zipfile] [--methodpoint] [--single] [--linecover] [--branchcover] [--dropReturnCode] [--sourcelink] [--defer] [--v[isibleBranches]] [/showstatic[=VALUE]] [--showGenerated] [--trivia] [--portable] [-q] [--verbose] [--?|help|h] [-- ] [...] or -AltCover Runner [/r[ecorderDirectory]=VALUE] [/w[orkingDirectory]=VALUE] [/x|executable=VALUE] [--collect] [/l[covReport]=VALUE] [/t[hreshold]=VALUE] [/c[obertura]=VALUE] [/o[utputFile]=VALUE] [--dropReturnCode] [/summary|teamcity[=VALUE]] [-q] [--verbose] [--?|help|h] [-- ] [...] +AltCover Runner [/r[ecorderDirectory]=VALUE] [/w[orkingDirectory]=VALUE] [/x|executable=VALUE] [--collect] [/l[covReport]=VALUE] [/t[hreshold]=VALUE] [/c[obertura]=VALUE] [/p[ackage]=VALUE] [/o[utputFile]=VALUE] [--dropReturnCode] [/summary|teamcity[=VALUE]] [-q] [--verbose] [--?|help|h] [-- ] [...] or AltCover ImportModule or @@ -478,4 +478,7 @@ If the option is not present, then the default is 'OC'. Failed to delete file {0} + + Optional, multiple: package root path for Cobertura reports + \ No newline at end of file diff --git a/AltCover.Engine/Tasks.fs b/AltCover.Engine/Tasks.fs index 5f76bb11..0c25ed24 100644 --- a/AltCover.Engine/Tasks.fs +++ b/AltCover.Engine/Tasks.fs @@ -221,6 +221,11 @@ type Collect() = [] member val Cobertura = String.Empty with get, set + [] + member val Packages: string array = [||] with get, set + member val OutputFile = String.Empty with get, set [ member Cobertura : string with get, set /// + /// Corresponds to command line option `-p, --package=VALUE` + /// + member Packages : string array with get, set + /// /// Corresponds to command line option `-o, --outputFile=VALUE` /// member OutputFile : string with get, set diff --git a/AltCover.Engine/TypeSafe.fs b/AltCover.Engine/TypeSafe.fs index 34241dc5..facd66e3 100644 --- a/AltCover.Engine/TypeSafe.fs +++ b/AltCover.Engine/TypeSafe.fs @@ -59,6 +59,22 @@ module TypeSafe = | NoCommand -> Seq.empty | CommandArguments c -> c |> Seq.map _.AsString() + [] + type Package = + | Package of String + member self.AsString() = + match self with + | Package s -> s + + [] + type Packages = + | Packages of Package seq + | NoPackage + member self.AsStrings() = + match self with + | NoPackage -> Seq.empty + | Packages c -> c |> Seq.map _.AsString() + [] type Thresholds = { Statements: uint8 @@ -249,6 +265,7 @@ module TypeSafe = "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Cobertura is a name")>] Cobertura: FilePath + Packages: Packages OutputFile: FilePath CommandLine: CommandLine ExposeReturnCode: Flag @@ -261,6 +278,7 @@ module TypeSafe = LcovReport = NoFile Threshold = NoThreshold Cobertura = NoFile + Packages = NoPackage OutputFile = NoFile CommandLine = NoCommand ExposeReturnCode = Set diff --git a/AltCover.Engine/TypeSafe.fsi b/AltCover.Engine/TypeSafe.fsi index b30ac438..aabf4fc3 100644 --- a/AltCover.Engine/TypeSafe.fsi +++ b/AltCover.Engine/TypeSafe.fsi @@ -115,6 +115,45 @@ namespace AltCoverFake.DotNet.Testing member AsStrings : unit -> seq end // ``` +// ### Cobertura package roots +// ``` + /// + /// Corresponds to a value after `-- ` on the command line + /// + [] + type Package = + /// + /// Strongly typed string value + /// + | Package of System.String + with + /// + /// Returns the string to be used in the effective command line + /// + ///the string to be used in the effective command line + member AsString : unit -> System.String + end + /// + /// Corresponds to the values after `-- ` on the command line + /// + [] + type Packages = + /// + /// Strongly typed string collection + /// + | Packages of seq + /// + /// Nothing + /// + | NoPackage + with + /// + /// Returns the strings to be used in the effective command line + /// + ///the strings to be used in the effective command line + member AsStrings : unit -> seq + end +// ``` // ### Coverage thresholds // ``` /// @@ -490,6 +529,10 @@ namespace AltCoverFake.DotNet.Testing /// Cobertura: FilePath /// + /// Corresponds to command line option `-p, --package=VALUE` + /// + Packages : Packages + /// /// Corresponds to command line option `-o, --outputFile=VALUE` /// OutputFile: FilePath diff --git a/AltCover.Engine/Visitor.fs b/AltCover.Engine/Visitor.fs index 4ee0dd00..ad07d002 100644 --- a/AltCover.Engine/Visitor.fs +++ b/AltCover.Engine/Visitor.fs @@ -1194,11 +1194,11 @@ module internal Visitor = | _ -> seq let getSequencePoint (dbg: IDictionary) (i: Instruction) = - dbg.TryGetValue(i.Offset) |> snd + i.Offset |> dbg.TryGetValue |> snd let internal findEffectiveSequencePoint genuine - (dbg: Dictionary) + (dbg: IDictionary) (instructions: Instruction seq) = instructions @@ -1208,7 +1208,7 @@ module internal Visitor = |> Seq.tryFind isSequencePoint let internal findSequencePoint - (dbg: Dictionary) + (dbg: IDictionary) (instructions: Instruction seq) = findEffectiveSequencePoint Genuine dbg instructions @@ -1304,7 +1304,7 @@ module internal Visitor = else firstOfSequencePoint dbg p - let internal getJumps (dbg: Dictionary) (i: Instruction) = + let internal getJumps (dbg: IDictionary) (i: Instruction) = let terminal = lastOfSequencePoint dbg i let next = i.Next @@ -1404,7 +1404,7 @@ module internal Visitor = let private extractBranchPoints (v0t: TypeReference option) - (dbg: Dictionary) + (dbg: IDictionary) rawInstructions interesting vc @@ -1481,15 +1481,15 @@ module internal Visitor = Key = i })) |> Seq.choose id |> processBranches - |> Seq.map BranchPoint + |> Seq.map BranchPoint // AltCover.Visitor/I/Pipe #2 stage #10 |> Seq.toList let internal validateInstruction (dbg: IDictionary) (x: Instruction) = - let (_, s) = dbg.TryGetValue x.Offset - s.IsNotNull && (s.IsHidden |> not) + let (yes, s) = dbg.TryGetValue x.Offset + yes && (s.IsHidden |> not) let internal trivial = HashSet( @@ -1502,21 +1502,14 @@ module internal Visitor = ) let internal isNonTrivialSeqPnt - (dbg: Dictionary) + (dbg: IDictionary) (x: Instruction) = if CoverageParameters.trivia.Value then let rest = // rest of the sequence point Seq.unfold (fun (i: Instruction) -> - if - i |> isNull - || i.Offset - |> dbg.TryGetValue - |> snd - |> isNull - |> not - then + if i |> isNull || i.Offset |> dbg.ContainsKey then None else Some(i, i.Next)) @@ -1539,13 +1532,12 @@ module internal Visitor = let splut = Dictionary() do - let dbg = m.Method.DebugInformation - - if dbg.IsNotNull && dbg.HasSequencePoints then + m.Method.DebugInformation + |> Option.ofObj + |> Option.filter _.HasSequencePoints + |> Option.iter (fun dbg -> dbg.SequencePoints - |> Seq.iter (fun s -> splut.Add(s.Offset, s)) - - // build more look-up tables + |> Seq.iter (fun s -> splut.Add(s.Offset, s))) let instructions = [ rawInstructions |> Seq.cast ] @@ -1592,11 +1584,11 @@ module internal Visitor = else instructions.OrderByDescending(fun (x: Instruction) -> x.Offset) |> Seq.mapi (fun i x -> - let s = splut.TryGetValue(x.Offset) |> snd + let s = x.Offset |> splut.TryGetValue |> snd MethodPoint { Instruction = x - SeqPnt = s |> SeqPnt.Build |> Some + SeqPnt = s |> SeqPnt.Build |> Some // AltCover.Visitor/I/sp@1 Uid = i + point Interesting = wanted interesting s DefaultVisitCount = m.DefaultVisitCount }) @@ -1739,7 +1731,7 @@ module internal Visitor = "UseCorrectCasingRule", Scope = "member", // MethodDefinition Target = - "AltCover.Visitor/I/sp@1599-2::Invoke(AltCover.SeqPnt)", + "AltCover.Visitor/I/sp@1591-2::Invoke(AltCover.SeqPnt)", Justification = "Inlined library code")>] [AltCover.Fake.DotNet.Testing.AltCover NoCanonicalDirectories;FAKEAPI - MSB3277;MSB3245 + MSB3277;MSB3245;NU1901;NU1902;NU1903;NU1904 NU1701;NU1605;NU1902,NU1903,NU1904 @@ -42,9 +42,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers diff --git a/AltCover.Fake.DotNet.Testing.AltCover/AltCoverCommand.fs b/AltCover.Fake.DotNet.Testing.AltCover/AltCoverCommand.fs index e5b783d7..329be362 100644 --- a/AltCover.Fake.DotNet.Testing.AltCover/AltCoverCommand.fs +++ b/AltCover.Fake.DotNet.Testing.AltCover/AltCoverCommand.fs @@ -40,6 +40,7 @@ module AltCoverCommand = LcovReport = a.LcovReport Threshold = a.Threshold Cobertura = a.Cobertura + Packages = a.Packages OutputFile = a.OutputFile CommandLine = a.CommandLine ExposeReturnCode = a.ExposeReturnCode @@ -59,6 +60,7 @@ module AltCoverCommand = LcovReport = a.LcovReport Threshold = a.Threshold Cobertura = a.Cobertura + Packages = a.Packages OutputFile = a.OutputFile CommandLine = args |> toSeq ExposeReturnCode = a.ExposeReturnCode @@ -328,30 +330,30 @@ module AltCoverCommand = "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = - "AltCoverFake.DotNet.Testing.AltCoverCommand+withMono@300T.#monoPath", + "AltCoverFake.DotNet.Testing.AltCoverCommand+withMono@302T.#monoPath", Justification = "Generated code")>] [] [] [] [] () \ No newline at end of file diff --git a/AltCover.Fake/AltCover.Fake.fsproj b/AltCover.Fake/AltCover.Fake.fsproj index f5f6e1ed..81d46312 100644 --- a/AltCover.Fake/AltCover.Fake.fsproj +++ b/AltCover.Fake/AltCover.Fake.fsproj @@ -6,6 +6,7 @@ AltCover.Fake RUNNER NU1701;NU1605;NU1902,NU1903,NU1904 + NU1901;NU1902;NU1903;NU1904 @@ -22,15 +23,16 @@ - - + + all runtime; build; native; contentfiles; analyzers contentfiles - + + diff --git a/AltCover.FontSupport/AltCover.FontSupport.csproj b/AltCover.FontSupport/AltCover.FontSupport.csproj index 0813972b..67c7238d 100644 --- a/AltCover.FontSupport/AltCover.FontSupport.csproj +++ b/AltCover.FontSupport/AltCover.FontSupport.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/AltCover.PowerShell/Command.fs b/AltCover.PowerShell/Command.fs index 558368eb..08274048 100644 --- a/AltCover.PowerShell/Command.fs +++ b/AltCover.PowerShell/Command.fs @@ -181,6 +181,20 @@ type InvokeAltCoverCommand() = [] member val Cobertura = String.Empty with get, set + /// + /// Package roots for cobertura reports + /// + [] + [] + [] + member val Package: string array = [||] with get, set + /// /// Write the recorded coverage to this file rather than overwriting the original report file. /// @@ -678,6 +692,7 @@ type InvokeAltCoverCommand() = LcovReport = self.LcovReport Threshold = self.Threshold Cobertura = self.Cobertura + Packages = self.Package OutputFile = self.OutputFile CommandLine = self.CommandLine ExposeReturnCode = not self.DropReturnCode.IsPresent diff --git a/AltCover.PowerShell/CoverageFormats.fs b/AltCover.PowerShell/CoverageFormats.fs index 989330c1..db91836b 100644 --- a/AltCover.PowerShell/CoverageFormats.fs +++ b/AltCover.PowerShell/CoverageFormats.fs @@ -248,6 +248,26 @@ type ConvertToCoberturaCommand() = ValueFromPipelineByPropertyName = false)>] member val OutputFile: string = String.Empty with get, set + /// + /// Output as file path + /// + [] + [] + [] + [] + member val Package: string array = [||] with get, set + /// /// Create transformed document /// @@ -264,7 +284,7 @@ type ConvertToCoberturaCommand() = self.XDocument <- XDocument.Load self.InputFile let rewrite = - AltCover.CoverageFormats.ConvertToCobertura self.XDocument + AltCover.CoverageFormats.ConvertToCobertura self.XDocument self.Package if self.OutputFile diff --git a/AltCover.Tests/AltCover.Runner.Usage.txt b/AltCover.Tests/AltCover.Runner.Usage.txt index f64ca3e0..53f4806e 100644 --- a/AltCover.Tests/AltCover.Runner.Usage.txt +++ b/AltCover.Tests/AltCover.Runner.Usage.txt @@ -30,6 +30,8 @@ such methods. -c, --cobertura=VALUE Optional: File for Cobertura format version of the collected data + -p, --package=VALUE Optional, multiple: package root path for + Cobertura reports -o, --outputFile=VALUE Optional: write the recorded coverage to this file rather than overwriting the original report file. --dropReturnCode Optional: Do not report any non-zero return code diff --git a/AltCover.Tests/AltCover.Tests.fsproj b/AltCover.Tests/AltCover.Tests.fsproj index fe2611d7..acb1eddf 100644 --- a/AltCover.Tests/AltCover.Tests.fsproj +++ b/AltCover.Tests/AltCover.Tests.fsproj @@ -7,6 +7,8 @@ MONO WINDOWS TRACE;RUNNER_TESTS;$(ExtraDefines) + NU1901;NU1902;NU1903;$(NoWarn) + NU1901;NU1902;NU1903 diff --git a/AltCover.Tests/AltCoverFSharpTypes.n3.xml b/AltCover.Tests/AltCoverFSharpTypes.n3.xml index 498bf0ae..54d32974 100644 --- a/AltCover.Tests/AltCoverFSharpTypes.n3.xml +++ b/AltCover.Tests/AltCoverFSharpTypes.n3.xml @@ -75,7 +75,7 @@ - 100663319 + 100663320 Tests.DU/MyUnion Tests.DU/MyUnion::as_bar() @@ -93,7 +93,7 @@ - 100663320 + 100663321 Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Tests.DU/MyUnion> Tests.DU/MyUnion::get_MyBar() @@ -110,11 +110,11 @@ - 100663340 + 100663341 Tests.DU/MyUnion Tests.DU/get_MyBar@46::Invoke(Microsoft.FSharp.Core.Unit) - + @@ -124,7 +124,7 @@ - 100663341 + 100663342 System.Void Tests.DU/MyClass::.ctor() @@ -141,7 +141,7 @@ - 100663344 + 100663345 Tests.M/Thing Tests.M::makeThing(System.String) @@ -152,7 +152,7 @@ - 100663345 + 100663346 System.Void Tests.M::testMakeThing() @@ -170,7 +170,7 @@ - 100663355 + 100663357 System.Byte[] Tests.M/Thing::bytes() diff --git a/AltCover.Tests/Expecto.fs b/AltCover.Tests/Expecto.fs index 79b726e9..5a6d137b 100644 --- a/AltCover.Tests/Expecto.fs +++ b/AltCover.Tests/Expecto.fs @@ -130,6 +130,10 @@ module ExpectoTestManifest = "Runner.ParsingMultipleCoberturaGivesFailure" Tests.AltCoverRunnerTests.ParsingNoCoberturaGivesFailure, "Runner.ParsingNoCoberturaGivesFailure" + Tests.AltCoverRunnerTests.ParsingNoPackagesGivesFailure, + "Runner.ParsingPackagesGivesPackages" + Tests.AltCoverRunnerTests.ParsingPackagesGivesPackages, + "Runner.ParsingNoPackagesGivesFailure" Tests.AltCoverRunnerTests.ParsingOutputGivesOutput, "Runner.ParsingOutputGivesOutput" Tests.AltCoverRunnerTests.ParsingMultipleOutputGivesFailure, diff --git a/AltCover.Tests/NCover122.cobertura b/AltCover.Tests/NCover122.cobertura index e24afa5b..e521cc64 100644 --- a/AltCover.Tests/NCover122.cobertura +++ b/AltCover.Tests/NCover122.cobertura @@ -2,12 +2,12 @@ - altcover/Sample1 + altcover/ - + @@ -19,7 +19,7 @@ - + diff --git a/AltCover.Tests/NCoverWithPartials.cob.xml b/AltCover.Tests/NCoverWithPartials.cob.xml index 9ef7e26c..50105846 100644 --- a/AltCover.Tests/NCoverWithPartials.cob.xml +++ b/AltCover.Tests/NCoverWithPartials.cob.xml @@ -3,7 +3,7 @@ C:/ - d:/a01/_work/5/s/src/vctools/crt/crtw32/msilcrt + d:/a01/_work/5/s/src/ @@ -48,7 +48,7 @@ - + diff --git a/AltCover.Tests/OpenCoverForPester.coverlet.xml b/AltCover.Tests/OpenCoverForPester.coverlet.xml index cdf523a5..4b2d87c1 100644 --- a/AltCover.Tests/OpenCoverForPester.coverlet.xml +++ b/AltCover.Tests/OpenCoverForPester.coverlet.xml @@ -153,7 +153,7 @@ - 100663323 + 100663324 Tests.DU/MyUnion Tests.DU/MyUnion::AsBar() @@ -177,7 +177,7 @@ - 100663324 + 100663325 Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Tests.DU/MyUnion> Tests.DU/MyUnion::get_MyBar() @@ -194,7 +194,7 @@ - 100663346 + 100663347 System.Int32 Tests.DU/MyClass::get_Property() @@ -211,7 +211,7 @@ - 100663355 + 100663356 System.Tuple`2<System.Double,System.Double> Tests.DU/compute@74::Invoke(System.Double,System.Double,System.Double) @@ -228,7 +228,7 @@ - 100663361 + 100663362 Tests.M/Thing Tests.M::makeThing(System.String) @@ -239,7 +239,7 @@ - 100663362 + 100663363 System.Void Tests.M::testMakeThing() @@ -266,7 +266,7 @@ - 100663372 + 100663374 System.Byte[] Tests.M/Thing::Bytes() diff --git a/AltCover.Tests/OpenCoverWithPartials.lcov b/AltCover.Tests/OpenCoverWithPartials.lcov index 9a775e48..456ba4e8 100644 --- a/AltCover.Tests/OpenCoverWithPartials.lcov +++ b/AltCover.Tests/OpenCoverWithPartials.lcov @@ -20,10 +20,10 @@ 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[]) +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 BRDA:38,11,0,1 diff --git a/AltCover.Tests/Runner.Tests.fs b/AltCover.Tests/Runner.Tests.fs index 6f468df1..66eef823 100644 --- a/AltCover.Tests/Runner.Tests.fs +++ b/AltCover.Tests/Runner.Tests.fs @@ -604,7 +604,7 @@ module AltCoverRunnerTests = let ShouldHaveExpectedOptions () = Runner.init () let options = Runner.declareOptions () - let optionCount = 12 + let optionCount = 13 let optionNames = options @@ -1677,6 +1677,60 @@ module AltCoverRunnerTests = Runner.I.initSummary () Cobertura.path.Value <- None) + [] + let ParsingPackagesGivesPackages () = + Runner.init () + + lock Cobertura.packages (fun () -> + try + Cobertura.packages.Value <- [] + Runner.I.initSummary () + + let options = Runner.declareOptions () + let unique = Guid.NewGuid().ToString() + let unique2 = Guid.NewGuid().ToString() + + let input = + [| "-p"; unique; "--package"; unique2 |] + + let parse = + CommandLine.parseCommandLine input options + + match parse with + | Right(x, y) -> + Assert.That(y, Is.SameAs options) + Assert.That(x, Is.Empty) + test <@ Cobertura.packages.Value = [ unique2; unique ] @> + + finally + Runner.I.initSummary () + Cobertura.packages.Value <- []) + + [] + let ParsingNoPackagesGivesFailure () = + Runner.init () + + lock Cobertura.packages (fun () -> + try + Cobertura.packages.Value <- [] + Runner.I.initSummary () + + let options = Runner.declareOptions () + let blank = " " + let input = [| "-p"; blank |] + + let parse = + CommandLine.parseCommandLine input options + + match parse with + | Left(x, y) -> + Assert.That(y, Is.SameAs options) + Assert.That(x, Is.EqualTo "UsageError") + test <@ CommandLine.error = [ "--package : cannot be ' '" ] @> + finally + Runner.I.initSummary () + Cobertura.packages.Value <- []) + [] let ParsingOutputGivesOutput () = Runner.init () @@ -6332,6 +6386,7 @@ module AltCoverRunnerTests = ) Cobertura.path.Value <- Some unique + Cobertura.packages.Value <- [ "altcover" ] unique |> Path.GetDirectoryName @@ -6379,9 +6434,7 @@ module AltCoverRunnerTests = .Replace( """version="3.0.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) @@ -6462,9 +6515,7 @@ module AltCoverRunnerTests = .Replace( """version="8.8.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) @@ -6498,6 +6549,7 @@ module AltCoverRunnerTests = ) Cobertura.path.Value <- Some unique + Cobertura.packages.Value <- [ "d:/a01/_work/5/s/src/" ] unique |> Path.GetDirectoryName @@ -6545,9 +6597,7 @@ module AltCoverRunnerTests = .Replace( """version="8.2.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) @@ -6628,9 +6678,7 @@ module AltCoverRunnerTests = .Replace( """version="3.0.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) @@ -6713,9 +6761,7 @@ module AltCoverRunnerTests = .Replace( """version="3.0.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) @@ -6798,9 +6844,7 @@ module AltCoverRunnerTests = .Replace( """version="3.0.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) .Replace( // different computations TODO!! """complexity="2.2""", @@ -6895,9 +6939,7 @@ module AltCoverRunnerTests = .Replace( """version="3.0.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) @@ -7128,9 +7170,7 @@ module AltCoverRunnerTests = .Replace( """version="3.5.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That(result.Replace("\r", String.Empty), Is.EqualTo expected, result) @@ -7203,9 +7243,7 @@ module AltCoverRunnerTests = .Replace( """version="8.2.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That( @@ -7284,11 +7322,9 @@ module AltCoverRunnerTests = .Replace("\r", String.Empty) .Replace("\\", "/") .Replace( - """version="3.0.0.0""", + """version="8.8.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That( @@ -7369,9 +7405,7 @@ module AltCoverRunnerTests = .Replace( """version="3.0.0.0""", "version=\"" - + typeof.Assembly - .GetName() - .Version.ToString() + + AssemblyVersionInformation.AssemblyVersion ) Assert.That( diff --git a/AltCover.Tests/Sample4.coverlet.lcov b/AltCover.Tests/Sample4.coverlet.lcov index 4521ed2e..d63f688c 100644 --- a/AltCover.Tests/Sample4.coverlet.lcov +++ b/AltCover.Tests/Sample4.coverlet.lcov @@ -12,28 +12,41 @@ LF:1 end_of_record 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) -FN:54,System.Void Tests.DU::testMakeUnion() +FN:18,System.Byte[] Tests.M/Thing::bytes() +FN:20,Tests.M/Thing Tests.M::makeThing(System.String) +FN:24,System.Void Tests.M::testMakeThing() FN:36,Tests.DU/MyUnion Tests.DU/MyUnion::as_bar() FN:44,Microsoft.FSharp.Core.FSharpFunc`2 Tests.DU/MyUnion::get_MyBar() -FN:47,System.Int32 Tests.DU/MyClass::get_Property() FN:46,System.Void Tests.DU/MyClass::.ctor() -FN:20,Tests.M/Thing Tests.M::makeThing(System.String) -FN:24,System.Void Tests.M::testMakeThing() -FN:18,System.Byte[] Tests.M/Thing::bytes() -FNDA:1,Tests.DU/MyUnion Tests.DU::returnFoo(System.Int32) -FNDA:1,Tests.DU/MyUnion Tests.DU::returnBar(System.String) -FNDA:1,System.Void Tests.DU::testMakeUnion() +FN:47,System.Int32 Tests.DU/MyClass::get_Property() +FN:49,Tests.DU/MyUnion Tests.DU::returnFoo(System.Int32) +FN:50,Tests.DU/MyUnion Tests.DU::returnBar(System.String) +FN:54,System.Void Tests.DU::testMakeUnion() +FNDA:1,System.Byte[] Tests.M/Thing::bytes() +FNDA:2,Tests.M/Thing Tests.M::makeThing(System.String) +FNDA:1,System.Void Tests.M::testMakeThing() FNDA:1,Tests.DU/MyUnion Tests.DU/MyUnion::as_bar() FNDA:0,Microsoft.FSharp.Core.FSharpFunc`2 Tests.DU/MyUnion::get_MyBar() -FNDA:0,System.Int32 Tests.DU/MyClass::get_Property() FNDA:0,System.Void Tests.DU/MyClass::.ctor() -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() +FNDA:0,System.Int32 Tests.DU/MyClass::get_Property() +FNDA:1,Tests.DU/MyUnion Tests.DU::returnFoo(System.Int32) +FNDA:1,Tests.DU/MyUnion Tests.DU::returnBar(System.String) +FNDA:1,System.Void Tests.DU::testMakeUnion() FNF:10 FNH:7 +BRDA:24,0,0,1 +BRDA:24,0,1,- +BRDA:24,0,0,1 +BRDA:24,0,1,- +BRDA:25,0,0,1 +BRDA:25,0,1,- +BRDA:25,0,0,1 +BRDA:25,0,1,- +BRDA:36,0,0,- +BRDA:36,0,1,1 +BRDA:36,0,2,- +BRDA:36,0,3,- +BRDA:36,0,4,- BRDA:54,0,0,1 BRDA:54,0,1,- BRDA:54,0,0,1 @@ -46,19 +59,6 @@ BRDA:56,0,0,1 BRDA:56,0,1,- BRDA:56,0,0,1 BRDA:56,0,1,- -BRDA:36,0,0,- -BRDA:36,0,1,1 -BRDA:36,0,2,- -BRDA:36,0,3,- -BRDA:36,0,4,- -BRDA:24,0,0,1 -BRDA:24,0,1,- -BRDA:24,0,0,1 -BRDA:24,0,1,- -BRDA:25,0,0,1 -BRDA:25,0,1,- -BRDA:25,0,0,1 -BRDA:25,0,1,- BRF:25 BRH:11 DA:18,1 diff --git a/AltCover.Tests/XTests.fs b/AltCover.Tests/XTests.fs index b740966f..88b7f5b3 100644 --- a/AltCover.Tests/XTests.fs +++ b/AltCover.Tests/XTests.fs @@ -237,6 +237,7 @@ module AltCoverXTests = Threshold = TypeSafe.Threshold t SummaryFormat = TypeSafe.BPlus Verbosity = System.Diagnostics.TraceLevel.Verbose + Packages = TypeSafe.Packages [ TypeSafe.Package "/agent/" ] Executable = TypeSafe.Tool "dotnet" } let instance = @@ -254,6 +255,8 @@ module AltCoverXTests = "dotnet" "-t" "S23B16M7C3" + "-p" + "/agent/" "--summary:BOC" "--verbose" ] @> @@ -263,7 +266,7 @@ module AltCoverXTests = test <@ - validate.ToString() = "altcover Runner -x dotnet -t S23B16M7C3 --summary:BOC --verbose" + validate.ToString() = "altcover Runner -x dotnet -t S23B16M7C3 -p /agent/ --summary:BOC --verbose" @> [] @@ -318,9 +321,12 @@ module AltCoverXTests = let subject = TypeSafe.CollectOptions.Create() - let scan = - (AltCover.CollectOptions.TypeSafe subject) - .Validate(true) + let instance = + AltCover.CollectOptions.TypeSafe subject + + let scan = instance.Validate(true) + + test <@ instance |> Args.collect = [ "Runner"; "--collect" ] @> test <@ scan.Length = 1 @> diff --git a/AltCover.Toolkit/CoverageFormats.fs b/AltCover.Toolkit/CoverageFormats.fs index 543ea1e6..b459db55 100644 --- a/AltCover.Toolkit/CoverageFormats.fs +++ b/AltCover.Toolkit/CoverageFormats.fs @@ -25,11 +25,17 @@ module CoverageFormats = [] - let ConvertToCobertura (document: XDocument) = + let ConvertToCobertura (document: XDocument) (packages: string seq) = let format = XmlUtilities.discoverFormat document - AltCover.Cobertura.convertReport document format + try + AltCover.Cobertura.packages.Value <- packages |> Seq.toList + + AltCover.Cobertura.convertReport document format + + finally + AltCover.Cobertura.packages.Value <- [] let ConvertToJson (document: XDocument) = let format = diff --git a/AltCover.Toolkit/CoverageFormats.fsi b/AltCover.Toolkit/CoverageFormats.fsi index ee749444..d5fcba5d 100644 --- a/AltCover.Toolkit/CoverageFormats.fsi +++ b/AltCover.Toolkit/CoverageFormats.fsi @@ -24,9 +24,10 @@ namespace AltCover /// Writes the Cobertura report to the object pipeline as an `XDocument`, and optionally to a file. /// /// The report to convert. + /// Possibly empty list of package root folders. /// The converted document val ConvertToCobertura : - document:System.Xml.Linq.XDocument -> System.Xml.Linq.XDocument + document:System.Xml.Linq.XDocument -> packages : string seq -> System.Xml.Linq.XDocument /// /// Takes either OpenCover or classic NCover format input as an `XDocument`, as an argument or from the object pipeline. Writes the JSON report to a atring. diff --git a/AltCover.sln b/AltCover.sln index 07440fce..d90ed49e 100644 --- a/AltCover.sln +++ b/AltCover.sln @@ -57,6 +57,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Items", "Build Items" Directory.Packages.props = Directory.Packages.props .config\dotnet-tools.json = .config\dotnet-tools.json Build\dump-uncovered.ps1 = Build\dump-uncovered.ps1 + Fragments.txt = Fragments.txt Build\get-token.fsx = Build\get-token.fsx global.json = global.json Build\Infrastructure.snk = Build\Infrastructure.snk diff --git a/Build/Build.fsproj b/Build/Build.fsproj index 37e13afd..70777e58 100644 --- a/Build/Build.fsproj +++ b/Build/Build.fsproj @@ -1,7 +1,8 @@  - + NU1902,NU1903,NU1904 + NU1901;NU1902;NU1903;NU1904 @@ -50,5 +51,4 @@ ..\ThirdParty\Manatee.Json.dll - - + \ No newline at end of file diff --git a/Build/DriveApi.fsproj b/Build/DriveApi.fsproj index f31ff180..e05060d3 100644 --- a/Build/DriveApi.fsproj +++ b/Build/DriveApi.fsproj @@ -4,6 +4,7 @@ Exe net8.0 MSB3243;NU1902,NU1903,NU1904 + NU1901;NU1902;NU1903;NU1904 @@ -13,8 +14,8 @@ - - + + \ No newline at end of file diff --git a/Build/Setup.fsproj b/Build/Setup.fsproj index 38fc25bf..7b878a43 100644 --- a/Build/Setup.fsproj +++ b/Build/Setup.fsproj @@ -2,6 +2,7 @@ NU1902,NU1903,NU1904 + NU1901;NU1902;NU1903;NU1904 @@ -17,5 +18,4 @@ - - + \ No newline at end of file diff --git a/Build/actions.fs b/Build/actions.fs index 92d37f5f..256ba107 100644 --- a/Build/actions.fs +++ b/Build/actions.fs @@ -663,7 +663,7 @@ a:hover {color: #ecc;} let trackedFormat = """ - + """ coverageDocument.Descendants(XName.Get("TrackedMethods")) diff --git a/Build/targets.fs b/Build/targets.fs index 9054eca1..323d3998 100644 --- a/Build/targets.fs +++ b/Build/targets.fs @@ -8061,83 +8061,6 @@ module Targets = Assert.That(opencoverFiles, Is.EquivalentTo o1expect, "opencoverFiles") - let opencover2Files = - xml - |> List.filter (fun x -> - let root = (snd x).Root - root.Name.LocalName = "CoverageSession") - |> List.filter (fun x -> - try - (snd x).Validate(opencoverStrict, null) - false - with :? XmlSchemaValidationException -> - true) - |> List.map fst - - let o2expect = - [ // embeds - "__AltCover.Api.Tests/OpenCover.xml" - "AltCover.Api.Tests/OpenCover.xml" - "_DotnetTestBranchCover/coverage.xml" - "_DotnetTestBranchCoverInPlace/coverage.xml" - "_DotnetTestLineCover/coverage.xml" - "_DotnetTestLineCoverInPlace/coverage.xml" - "_Issue23/coverage.xml" - "_Issue67/coverage.xml" - "AltCover.Tests/HandRolledMonoCoverage.xml" - "AltCover.Tests/OpenCoverWithEmbeds.xml" - "AltCover.Tests/OpenCoverWithPartials.xml" - "AltCover.Tests/Sample4FullTracking.xml" - "_Reports/AltCoverAsyncAwaitTests.xml" - "_Reports/Pester.xml" - "_Reports/RawPester.xml" - "RegressionTesting/issue37/coverage.xml" - "Samples/Sample16/Test/_Issue72/combined.Test.xml" - "Samples/Sample16/Test/_Issue72/original.Test.xml" - "Samples/Sample16/Test/_Reports/solution.Test.xml" - "Samples/Sample16/Test/_Reports/solution.Test2.xml" - // coverlet - "Samples/Sample32/coverlet.opencover.6.0.2.xml" - "AltCover.Api.Tests/OpenCoverForPester.coverlet.xml" - "AltCover.Tests/OpenCoverForPester.coverlet.expected.xml" - "__AltCover.Api.Tests/OpenCoverForPester.coverlet.xml" - "AltCover.Tests/Sample21.coverage.opencover.xml" - "AltCover.Tests/Sample4.coverlet.xml" ] - @ if Environment.isWindows then - [ "_Issue156/Tests/coverage.xml" ] - else - [] - - let o3expect = // embeds - !!(@"./**/JsonWithPartials*Xml.xml") |> Seq.toList - - let o4expect = // coverlet - !!(@"./_Reports/**/*.coverlet.xml") |> Seq.toList - - let o5expect = // coverlet - !!(@"./**/coverage.opencover.xml") |> Seq.toList - - let oexpect = - [ o1expect - o2expect - o3expect - o4expect - o5expect ] - |> List.concat - |> List.map Path.getFullName - |> List.filter File.Exists - - Assert.That(opencover2Files, Is.EquivalentTo oexpect, "opencover2Files") - - // let noncoverFiles = - // xml - // |> List.filter (fun x -> let root = (snd x).Root - // root.Name.LocalName <> "CoverageSession" && - // root.Name.LocalName <> "coverage") - - // |> List.map fst - // Assert.That(noncoverFiles, Is.EquivalentTo []) - let issue71 = !!(@"./**/*.exn") |> Seq.toList diff --git a/Directory.Packages.props b/Directory.Packages.props index b0fa08ea..dd70c956 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,12 +5,12 @@ - - - - - - + + + + + + @@ -20,34 +20,34 @@ - + - - + + - - - - - - - - - - + + + + + + + + + + - + - + - + @@ -61,7 +61,7 @@ - + diff --git a/FakeForAltCoverBuild.sln b/FakeForAltCoverBuild.sln index 298a7c32..5327addf 100644 --- a/FakeForAltCoverBuild.sln +++ b/FakeForAltCoverBuild.sln @@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Directory.Build.props = Directory.Build.props Directory.Packages.props = Directory.Packages.props Build\DriveApi.fsx = Build\DriveApi.fsx + global.json = global.json .github\workflows\main.yml = .github\workflows\main.yml Build\Pester.Tests.ps1 = Build\Pester.Tests.ps1 ReleaseNotes.md = ReleaseNotes.md diff --git a/Fragments.txt b/Fragments.txt new file mode 100644 index 00000000..88edf84a --- /dev/null +++ b/Fragments.txt @@ -0,0 +1,7 @@ +Instrument for runner + +C:\Users\email\Documents\Github\altcover\_Binaries\AltCover\Release+AnyCPU\net472\AltCover.exe -o ./__UnitTestWithAltCoverRunner -s "\.DataCollector" -s Sample -s Microsoft -s testhost -t "System\." -t "Sample3\.Class2" -t Microsoft -t ICSharpCode -t " diff --git a/version.json b/version.json index e8075cdb..80a08a5a 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "8.8", + "version": "8.9", "release": { "branchName": "release/v{version}", "versionIncrement": "build",