From afe3e61012811c3f18e919d465df86cc7617a742 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 21:04:50 +0800 Subject: [PATCH 01/15] tests: 1 more test for howLikelyProjectIsLibrary fn --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 7 ++++++- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 601d476de..dd5cbcfcd 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -30,7 +30,12 @@ let hasEntryPoint (checkFileResults: FSharpCheckFileResults) (maybeProjectCheckR | None -> false -let excludedProjectNames = [ "test"; "console" ] +let private excludedProjectNames = + [ + "test" + "console" + "CLI" + ] let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultByProjectName = let nameSegments = Helper.Naming.QuickFixes.splitByCaseChange projectFileName diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 65e95c40a..65b1a5d06 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -168,3 +168,11 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = howLikelyProjectIsLibrary "FooLib", LibraryHeuristicResultByProjectName.Likely ) + + [] + member this.``Unlikely to be library if contains "CLI" in name``() = + Assert.AreEqual( + howLikelyProjectIsLibrary "FooCLI", + LibraryHeuristicResultByProjectName.Unlikely + ) + From 3a13b5b3a6aba5506a27f9a0285073491f5c8b07 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 21:20:11 +0800 Subject: [PATCH 02/15] tests: swap expected<->actual elements They were placed the other way around. --- .../NoAsyncRunSynchronouslyInLibrary.fs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 65b1a5d06..c9bfdcad2 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -134,45 +134,46 @@ let Foo() = [] type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = + [] member this.``Unlikely to be library if contains "test" in name``() = Assert.AreEqual( - howLikelyProjectIsLibrary "TestProject", - LibraryHeuristicResultByProjectName.Unlikely + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "TestProject" ) [] member this.``Unlikely to be library if contains "console" in name``() = Assert.AreEqual( - howLikelyProjectIsLibrary "FooConsole", - LibraryHeuristicResultByProjectName.Unlikely + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "FooConsole" ) [] member this.``Likely to be library if contains Contains "Lib" as a PascalCase segment``() = Assert.AreEqual( - howLikelyProjectIsLibrary "LibFoo", - LibraryHeuristicResultByProjectName.Likely + LibraryHeuristicResultByProjectName.Likely, + howLikelyProjectIsLibrary "LibFoo" ) [] member this.``Uncertain if contains contains "Lib" but not as a PascalCase segment``() = Assert.AreEqual( - howLikelyProjectIsLibrary "LibreOfficeProg", - LibraryHeuristicResultByProjectName.Uncertain + LibraryHeuristicResultByProjectName.Uncertain, + howLikelyProjectIsLibrary "LibreOfficeProg" ) [] member this.``Likely to be library if contains ends with "lib" (case-insensitive)``() = Assert.AreEqual( - howLikelyProjectIsLibrary "FooLib", - LibraryHeuristicResultByProjectName.Likely + LibraryHeuristicResultByProjectName.Likely, + howLikelyProjectIsLibrary "FooLib" ) [] member this.``Unlikely to be library if contains "CLI" in name``() = Assert.AreEqual( - howLikelyProjectIsLibrary "FooCLI", - LibraryHeuristicResultByProjectName.Unlikely + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "FooCLI" ) From 9a6ee47188493df88dc9c2ab51112fa97e0ff685 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 21:32:43 +0800 Subject: [PATCH 03/15] Core(NoAsyncRunSyncInLib): make new test pass --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index dd5cbcfcd..7ff3d3b1c 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -41,7 +41,7 @@ let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultB let nameSegments = Helper.Naming.QuickFixes.splitByCaseChange projectFileName if nameSegments |> Seq.contains "Lib" then Likely - elif excludedProjectNames |> List.exists (fun name -> projectFileName.ToLowerInvariant().Contains name) then + elif excludedProjectNames |> List.exists (fun name -> projectFileName.ToLowerInvariant().Contains(name.ToLowerInvariant())) then Unlikely elif projectFileName.ToLowerInvariant().EndsWith "lib" then Likely From 5c3b3131b40bdfadcc54ca16f1d5ddde5e832fa4 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 21:35:28 +0800 Subject: [PATCH 04/15] tests: yet another lib heuristic unit test --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index c9bfdcad2..fa5a1d470 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -177,3 +177,10 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = howLikelyProjectIsLibrary "FooCLI" ) + [] + member this.``Uncertain to be library if contains "cli" in name not related to CLI``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Uncertain, + howLikelyProjectIsLibrary "InclinedDriver" + ) + From a554cae7952683ff32f1cd7f9be9c0c4ac93d0ae Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 21:44:08 +0800 Subject: [PATCH 05/15] Core(NoAsyncRunSyncInLib): make new test pass --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 7ff3d3b1c..dfa7c6d81 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -30,7 +30,7 @@ let hasEntryPoint (checkFileResults: FSharpCheckFileResults) (maybeProjectCheckR | None -> false -let private excludedProjectNames = +let private projectNamesUnlikelyToBeLibraries = [ "test" "console" @@ -41,7 +41,7 @@ let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultB let nameSegments = Helper.Naming.QuickFixes.splitByCaseChange projectFileName if nameSegments |> Seq.contains "Lib" then Likely - elif excludedProjectNames |> List.exists (fun name -> projectFileName.ToLowerInvariant().Contains(name.ToLowerInvariant())) then + elif nameSegments |> Seq.exists (fun segment -> projectNamesUnlikelyToBeLibraries |> Seq.exists (fun noLibName -> noLibName.ToLowerInvariant() = segment.ToLowerInvariant())) then Unlikely elif projectFileName.ToLowerInvariant().EndsWith "lib" then Likely From 21eb9e9055b012f167f53216cc006f24b718ee65 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 22:38:31 +0800 Subject: [PATCH 06/15] tests: yet another lib heuristic unit test (camelCase) --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index fa5a1d470..d722f247a 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -184,3 +184,10 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = howLikelyProjectIsLibrary "InclinedDriver" ) + [] + member this.``Likely to be library if it starts with "lib", e.g. camelCase``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Likely, + howLikelyProjectIsLibrary "libFoo" + ) + From 8dec8427eb73a437e867b855c733a6e5b5d89c74 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 23:03:30 +0800 Subject: [PATCH 07/15] Core(NoAsyncRunSyncInLib): make new test pass --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index dfa7c6d81..52d6bfef2 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -38,8 +38,10 @@ let private projectNamesUnlikelyToBeLibraries = ] let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultByProjectName = - let nameSegments = Helper.Naming.QuickFixes.splitByCaseChange projectFileName - if nameSegments |> Seq.contains "Lib" then + let nameSegments = + Helper.Naming.QuickFixes.splitByCaseChange projectFileName + |> Seq.map (fun segment -> segment.ToLowerInvariant()) + if nameSegments |> Seq.contains "lib" then Likely elif nameSegments |> Seq.exists (fun segment -> projectNamesUnlikelyToBeLibraries |> Seq.exists (fun noLibName -> noLibName.ToLowerInvariant() = segment.ToLowerInvariant())) then Unlikely From 1eaa1560edc21d6542da502a80ba1f063f402824 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 23:48:13 +0800 Subject: [PATCH 08/15] Core: refactor to reduce invocations to LowerInvariant() --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 52d6bfef2..7dbffafb5 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -36,6 +36,7 @@ let private projectNamesUnlikelyToBeLibraries = "console" "CLI" ] + |> Seq.map (fun name -> name.ToLowerInvariant()) let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultByProjectName = let nameSegments = @@ -43,7 +44,13 @@ let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultB |> Seq.map (fun segment -> segment.ToLowerInvariant()) if nameSegments |> Seq.contains "lib" then Likely - elif nameSegments |> Seq.exists (fun segment -> projectNamesUnlikelyToBeLibraries |> Seq.exists (fun noLibName -> noLibName.ToLowerInvariant() = segment.ToLowerInvariant())) then + elif + nameSegments + |> Seq.exists ( + fun segment -> + projectNamesUnlikelyToBeLibraries + |> Seq.exists (fun noLibName -> noLibName = segment) + ) then Unlikely elif projectFileName.ToLowerInvariant().EndsWith "lib" then Likely From 988ecd619aff2650493a6ba2528e48a69fafcb0f Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Wed, 4 Feb 2026 23:56:16 +0800 Subject: [PATCH 09/15] Core(NoAsyncRunSyncInLib): refactor to respect DRY --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 7dbffafb5..bc7b3ea87 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -39,10 +39,11 @@ let private projectNamesUnlikelyToBeLibraries = |> Seq.map (fun name -> name.ToLowerInvariant()) let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultByProjectName = + let libraryAbbrev = "lib" let nameSegments = Helper.Naming.QuickFixes.splitByCaseChange projectFileName |> Seq.map (fun segment -> segment.ToLowerInvariant()) - if nameSegments |> Seq.contains "lib" then + if nameSegments |> Seq.contains libraryAbbrev then Likely elif nameSegments @@ -52,7 +53,7 @@ let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultB |> Seq.exists (fun noLibName -> noLibName = segment) ) then Unlikely - elif projectFileName.ToLowerInvariant().EndsWith "lib" then + elif projectFileName.ToLowerInvariant().EndsWith libraryAbbrev then Likely else Uncertain From ce00eb2136c6afbd41721c1fa3f87669b2eecc86 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Feb 2026 00:20:42 +0800 Subject: [PATCH 10/15] tests: yet another lib heuristic unit test (dot separator) --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index d722f247a..53f903bcd 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -191,3 +191,9 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = howLikelyProjectIsLibrary "libFoo" ) + [] + member this.``Unlikely to be library if it contains "console", but segments are separated by dots``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "foo.console.app" + ) From f8e272e0ee585bac88c4c6c3138759a310ece2e8 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Feb 2026 00:34:17 +0800 Subject: [PATCH 11/15] Core(NoAsyncRunSyncInLib): make new test pass --- .../Smells/NoAsyncRunSynchronouslyInLibrary.fs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index bc7b3ea87..560758fa5 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -38,6 +38,13 @@ let private projectNamesUnlikelyToBeLibraries = ] |> Seq.map (fun name -> name.ToLowerInvariant()) +let private possibleProjectNameSegmentSeparators = + [| + '.' + '_' + '-' + |] + let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultByProjectName = let libraryAbbrev = "lib" let nameSegments = @@ -49,8 +56,12 @@ let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultB nameSegments |> Seq.exists ( fun segment -> - projectNamesUnlikelyToBeLibraries - |> Seq.exists (fun noLibName -> noLibName = segment) + let subSegments = segment.Split possibleProjectNameSegmentSeparators + subSegments + |> Seq.exists (fun subSegment -> + projectNamesUnlikelyToBeLibraries + |> Seq.exists (fun noLibName -> noLibName = subSegment) + ) ) then Unlikely elif projectFileName.ToLowerInvariant().EndsWith libraryAbbrev then From 99ce12397c239682c2b2c2ce2bbf4ceb72e31681 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Feb 2026 01:09:38 +0800 Subject: [PATCH 12/15] tests: yet another lib heuristic unit test This one should have been the first one. --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 53f903bcd..9dc6d3375 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -135,6 +135,13 @@ let Foo() = [] type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = + [] + member this.``Unlikely to be library if contains "tests" in name``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "IntegrationTests" + ) + [] member this.``Unlikely to be library if contains "test" in name``() = Assert.AreEqual( From 0b7179fde0e044351225fe4640de0c185f4e0d77 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Feb 2026 01:11:31 +0800 Subject: [PATCH 13/15] Core(NoAsyncRunSyncInLib): make new test pass --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 560758fa5..788a242c2 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -32,6 +32,7 @@ let hasEntryPoint (checkFileResults: FSharpCheckFileResults) (maybeProjectCheckR let private projectNamesUnlikelyToBeLibraries = [ + "tests" "test" "console" "CLI" From 15041408a7226062c61eda2561d7b3717def37ac Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Feb 2026 01:12:58 +0800 Subject: [PATCH 14/15] tests: better example for unit test Because "TestProject" sounded more like a sample project than one for automated tests. --- .../Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 9dc6d3375..b0e252aa2 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -146,7 +146,7 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = member this.``Unlikely to be library if contains "test" in name``() = Assert.AreEqual( LibraryHeuristicResultByProjectName.Unlikely, - howLikelyProjectIsLibrary "TestProject" + howLikelyProjectIsLibrary "TestSuite" ) [] From f6f65e0cd1e49672cd1fc21da155d5d6a13e54a5 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Thu, 5 Feb 2026 01:17:37 +0800 Subject: [PATCH 15/15] tests,Core: more segment names & unittests for lib heuristic For completeness. --- .../NoAsyncRunSynchronouslyInLibrary.fs | 2 ++ .../NoAsyncRunSynchronouslyInLibrary.fs | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index 788a242c2..aa854f1a5 100644 --- a/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/src/FSharpLint.Core/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -34,8 +34,10 @@ let private projectNamesUnlikelyToBeLibraries = [ "tests" "test" + "testing" "console" "CLI" + "TUI" ] |> Seq.map (fun name -> name.ToLowerInvariant()) diff --git a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs index b0e252aa2..f7ad9fddf 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Smells/NoAsyncRunSynchronouslyInLibrary.fs @@ -142,6 +142,13 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = howLikelyProjectIsLibrary "IntegrationTests" ) + [] + member this.``Unlikely to be library if contains "testing" in name``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "UnitTesting" + ) + [] member this.``Unlikely to be library if contains "test" in name``() = Assert.AreEqual( @@ -191,6 +198,13 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = howLikelyProjectIsLibrary "InclinedDriver" ) + [] + member this.``Unlikely to be library if contains "TUI" in name``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "FooTUI" + ) + [] member this.``Likely to be library if it starts with "lib", e.g. camelCase``() = Assert.AreEqual( @@ -204,3 +218,18 @@ type TestNoAsyncRunSynchronouslyInLibraryHeuristic() = LibraryHeuristicResultByProjectName.Unlikely, howLikelyProjectIsLibrary "foo.console.app" ) + + [] + member this.``Unlikely to be library if it contains "console", but segments are separated by dashes``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "foo-console-app" + ) + + [] + member this.``Unlikely to be library if it contains "console", but segments are separated by underscores``() = + Assert.AreEqual( + LibraryHeuristicResultByProjectName.Unlikely, + howLikelyProjectIsLibrary "foo_console_app" + ) +