diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ae61a3b9..5dd5ab26 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,6 +11,18 @@ on: branches: - master +# per https://www.meziantou.net/how-to-cancel-github-workflows-when-pushing-new-commits-on-a-branch.htm +# https://docs.github.com/en/actions/learn-github-actions/expressions +# https://docs.github.com/en/actions/learn-github-actions/contexts#github-context +concurrency: + # github.workflow: name of the workflow + # github.event.pull_request.number || github.ref: pull request number or branch name if not a pull request + group: ${{ github.workflow }} + #-${{ github.event.pull_request.number || github.ref }} + + # Cancel in-progress runs when a new workflow with the same group name is triggered + cancel-in-progress: true + jobs: windows: runs-on: windows-latest @@ -20,7 +32,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-dotnet@v3 with: - dotnet-version: '7.0.302' + dotnet-version: '7.0.304' - name: Tools run: dotnet tool restore - name: Setup @@ -51,7 +63,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-dotnet@v3 with: - dotnet-version: '7.0.302' + dotnet-version: '7.0.304' - name: Tools run: dotnet tool restore - name: Setup diff --git a/AltCover.Engine/ProgramDatabase.fs b/AltCover.Engine/ProgramDatabase.fs index 5b324fae..a2f1b828 100644 --- a/AltCover.Engine/ProgramDatabase.fs +++ b/AltCover.Engine/ProgramDatabase.fs @@ -272,8 +272,7 @@ module internal ProgramDatabase = let folder = foldername :: (Seq.toList symbolFolders) - |> Seq.map (I.getSymbolsByFolder filename) - |> Seq.choose id + |> Seq.choose (I.getSymbolsByFolder filename) |> Seq.tryFind (I.symbolMatch tokens) sprintf diff --git a/AltCover.Engine/Visitor.fs b/AltCover.Engine/Visitor.fs index ce689168..e30dfa89 100644 --- a/AltCover.Engine/Visitor.fs +++ b/AltCover.Engine/Visitor.fs @@ -284,6 +284,10 @@ module internal CoverageParameters = let mutable internal staticFilter: StaticFilter option = None + let effectiveStaticFilter () = + staticFilter + |> Option.defaultValue StaticFilter.Hidden + let internal showGenerated = ref false let generationFilter = @@ -747,6 +751,15 @@ module internal Visitor = t.Methods |> Seq.exists (fun m -> m.IsAbstract |> not) + [] + let internal stripAnonymous (t: TypeDefinition) = + t.Name.StartsWith("<>f__AnonymousType", StringComparison.Ordinal) + |> not + || CoverageParameters.effectiveStaticFilter () + <> StaticFilter.Hidden + let private visitModule (x: ModuleEntry) (buildSequence: Node -> seq) = zeroPoints () @@ -772,7 +785,8 @@ module internal Visitor = |> Seq.collect (fun x -> x.Module.GetAllTypes() |> Seq.cast - |> Seq.filter stripInterfaces) + |> Seq.filter stripInterfaces + |> Seq.filter stripAnonymous) |> Seq.collect ( (fun t -> let types = @@ -820,7 +834,7 @@ module internal Visitor = + name CoverageParameters.trackingNames - |> Seq.map (fun n -> + |> Seq.choose (fun n -> if n.Chars(0) = '[' then let stripped = n.Trim([| '['; ']' |]) @@ -844,7 +858,6 @@ module internal Visitor = Some n else None) - |> Seq.choose id |> Seq.tryFind (fun _ -> true) |> Option.map (fun n -> let id = methodNumber + 1 @@ -1109,9 +1122,7 @@ module internal Visitor = if significant m then StaticFilter.NoFilter else - match CoverageParameters.staticFilter with - | None -> StaticFilter.Hidden - | Some f -> f + CoverageParameters.effectiveStaticFilter () (m, key)) |> Seq.filter (fun (m, k) -> k <> StaticFilter.Hidden) @@ -1227,10 +1238,10 @@ module internal Visitor = let places = List.concat [ toNext; toJump ] let start = - places |> (boundaryOfList List.minBy) + places |> (boundaryOfList List.minBy) // This line to suppress let finish = - places |> (boundaryOfList List.maxBy) + places |> (boundaryOfList List.maxBy) // This line to suppress let range = Seq.unfold @@ -1377,7 +1388,7 @@ module internal Visitor = // possibly add MoveNext filtering let generated (i: Instruction) = - let before = firstOfSequencePoint dbg i // This line in suppress + let before = firstOfSequencePoint dbg i // This line to suppress let sp = dbg.GetSequencePoint before before.OpCode = OpCodes.Ldloc_0 @@ -1649,18 +1660,18 @@ module internal Visitor = "AvoidMessageChainsRule", Scope = "member", Target = - "AltCover.Visitor/I/generated@1380::Invoke(Mono.Cecil.Cil.Instruction)", + "AltCover.Visitor/I/generated@1391::Invoke(Mono.Cecil.Cil.Instruction)", Justification = "No direct call available")>] [,Microsoft.FSharp.Collections.FSharpList`1)", + "AltCover.Visitor/I/start@1241::Invoke(Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Collections.FSharpList`1)", Justification = "Inlined library code")>] [,Microsoft.FSharp.Collections.FSharpList`1)", + "AltCover.Visitor/I/finish@1244::Invoke(Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Collections.FSharpList`1)", Justification = "Inlined library code")>] () \ No newline at end of file diff --git a/AltCover.Tests/Tests.fs b/AltCover.Tests/Tests.fs index 5631b715..491744b2 100644 --- a/AltCover.Tests/Tests.fs +++ b/AltCover.Tests/Tests.fs @@ -1845,8 +1845,7 @@ module AltCoverTests = Assert.That( methods - |> Seq.map Visitor.I.containingMethod - |> Seq.choose id + |> Seq.choose Visitor.I.containingMethod |> Seq.filter (fun m -> m.Name = "G3"), Is.EquivalentTo [ g3; g3; g3 ] ) @@ -1855,8 +1854,7 @@ module AltCoverTests = Assert.That( methods - |> Seq.map Visitor.I.containingMethod - |> Seq.choose id + |> Seq.choose Visitor.I.containingMethod |> Seq.filter (fun m -> m.Name = "G1"), Is.EquivalentTo [ g1; g1 ] ) @@ -2970,8 +2968,7 @@ module AltCoverTests = let tracks = def.MainModule.GetAllTypes() |> Seq.collect (fun t -> t.Methods) - |> Seq.map (Visitor.I.track) - |> Seq.choose id + |> Seq.choose (Visitor.I.track) |> Seq.toList Assert.That(tracks, Is.EquivalentTo [ (1, "[Test"); (2, "[Test") ]) @@ -3029,8 +3026,7 @@ module AltCoverTests = let tracks = def.MainModule.GetAllTypes() |> Seq.collect (fun t -> t.Methods) - |> Seq.map (Visitor.I.track) - |> Seq.choose id + |> Seq.choose (Visitor.I.track) |> Seq.toList Assert.That( @@ -3069,8 +3065,7 @@ module AltCoverTests = let tracks = def.MainModule.GetAllTypes() |> Seq.collect (fun t -> t.Methods) - |> Seq.map (Visitor.I.track) - |> Seq.choose id + |> Seq.choose (Visitor.I.track) |> Seq.toList Assert.That( @@ -4661,11 +4656,10 @@ module AltCoverTests = Inspection = Inspections.Instrument Track = None DefaultVisitCount = Exemption.None } - |> Seq.map (fun n -> + |> Seq.choose (fun n -> match n with | BranchPoint b -> Some b | _ -> None) - |> Seq.choose id |> Seq.toList // The only overt branching in this function are the 4 match cases // Internal IL conditional branching is a compiler thing from inlining "string" @@ -5642,12 +5636,15 @@ module AltCoverTests = test <@ - classes = [ "Sample21.Tests" + classes = [ "Sample21.Product" + "Sample21.Tests" "Sample21.Traditional" ] @> let expectedMethods = - [ "System.String Sample21.Traditional::DoSomething()" + [ "System.String Sample21.Product::Junk(System.String)" + "System.String Sample21.Traditional::DoSomething()" + "System.Void Sample21.Product::.ctor(System.String)" "System.Void Sample21.Tests::.ctor()" "System.Void Sample21.Tests::Setup()" "System.Void Sample21.Tests::Test1()" @@ -5709,6 +5706,7 @@ module AltCoverTests = [ "Sample21.IModern" "Sample21.Modern1" "Sample21.Modern2" + "Sample21.Product" "Sample21.Tests" "Sample21.Traditional" ] @@ -5717,9 +5715,11 @@ module AltCoverTests = let expectedMethods = [ "System.String Sample21.IModern::DoSomething()" "System.String Sample21.Modern2::DoSomething()" + "System.String Sample21.Product::Junk(System.String)" "System.String Sample21.Traditional::DoSomething()" "System.Void Sample21.Modern1::.ctor()" "System.Void Sample21.Modern2::.ctor()" + "System.Void Sample21.Product::.ctor(System.String)" "System.Void Sample21.Tests::.ctor()" "System.Void Sample21.Tests::Setup()" "System.Void Sample21.Tests::Test1()" diff --git a/AltCover.Tests/Tests2.fs b/AltCover.Tests/Tests2.fs index 61ec91f2..58168413 100644 --- a/AltCover.Tests/Tests2.fs +++ b/AltCover.Tests/Tests2.fs @@ -2109,11 +2109,10 @@ has been prefixed with Ldc_I4_1 (1 byte) Inspection = Inspections.Instrument Track = None DefaultVisitCount = Exemption.None } - |> Seq.map (fun n -> + |> Seq.choose (fun n -> match n with | BranchPoint b -> Some b | _ -> None) - |> Seq.choose id |> Seq.take 2 // start of a switch |> Seq.toList @@ -2207,11 +2206,10 @@ has been prefixed with Ldc_I4_1 (1 byte) Inspection = Inspections.Instrument Track = None DefaultVisitCount = Exemption.None } - |> Seq.map (fun n -> + |> Seq.choose (fun n -> match n with | BranchPoint b -> Some b | _ -> None) - |> Seq.choose id |> Seq.skip 2 |> Seq.take 2 // first of "switch" |> Seq.toList @@ -2298,11 +2296,10 @@ has been prefixed with Ldc_I4_1 (1 byte) Inspection = Inspections.Instrument Track = None DefaultVisitCount = Exemption.None } - |> Seq.map (fun n -> + |> Seq.choose (fun n -> match n with | BranchPoint b -> Some b | _ -> None) - |> Seq.choose id |> Seq.take 2 // start of a switch |> Seq.toList diff --git a/Demo/inspector/Program.fs b/Demo/inspector/Program.fs index 09959500..85650bc4 100644 --- a/Demo/inspector/Program.fs +++ b/Demo/inspector/Program.fs @@ -91,10 +91,8 @@ let inspect (def: AssemblyDefinition) = [] let main argv = argv - |> Seq.map getFileExists - |> Seq.choose id - |> Seq.map loadInCecil - |> Seq.choose id + |> Seq.choose getFileExists + |> Seq.choose loadInCecil |> Seq.iter inspect 0 // return an integer exit code \ No newline at end of file diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 9753d4f9..39c02886 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -3,7 +3,11 @@ A. Start with the Quick Start guide : https://github.com/SteveGilham/altcover/wiki/QuickStart-Guide and read the FAQ : https://github.com/SteveGilham/altcover/wiki/FAQ -# (Habu series release 22) +# (Habu series release 23) +* Omit anonymous types from coverage, in the same way as other compiler generated code (auto-properties, equality and related operations on F# distributed unions, etc.) +* Supports net8.0 preview 5 + +# 8.6.61 (Habu series release 22) * [BUGFIX] prevent possible "The lists had different lengths." exception in the collect phase (Issue 181) * Removes some obsolete code from the `dotnet test` integration * Drop support for Fake 5.23.x diff --git a/Samples/Sample21/UnitTest1.cs b/Samples/Sample21/UnitTest1.cs index 5b7ea01e..1737c520 100644 --- a/Samples/Sample21/UnitTest1.cs +++ b/Samples/Sample21/UnitTest1.cs @@ -2,6 +2,22 @@ namespace Sample21 { + public class Product + { + public Product(string name) + { Name = name; } + + public string Name { get; set; } + + public static string Junk(string name) + { + var product = new Product(name); + var bonus = new { note = "You won!" }; + var shipmentWithBonus = new { address = "Somewhere St.", product, bonus }; + return shipmentWithBonus.ToString(); + } + } + public class Tests { [SetUp] diff --git a/global.json b/global.json index df1081c3..b516c799 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.302", + "version": "7.0.304", "rollForward": "latestMinor" } } \ No newline at end of file