Skip to content

Commit c7d413f

Browse files
committed
NoAsyncRunSynchronouslyInLibrary: refactoring
Use new function `howLikelyProjectIsTestOrLibrary` instead of `isInTestProject` and made unit tests for this function.
1 parent beb2841 commit c7d413f

File tree

3 files changed

+64
-16
lines changed

3 files changed

+64
-16
lines changed

src/FSharpLint.Core/FSharpLint.Core.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
<Compile Include="Rules\Smells\RaiseWithTooManyArguments\InvalidArgWithTwoArguments.fs" />
7070
<Compile Include="Rules\Smells\RaiseWithTooManyArguments\FailwithfWithArgumentsMatchingFormatString.fs" />
7171
<Compile Include="Rules\Conventions\FailwithBadUsage.fs" />
72-
<Compile Include="Rules\Conventions\NoAsyncRunSynchronouslyInLibrary.fs" />
7372
<Compile Include="Rules\Conventions\SourceLength\SourceLengthHelper.fs" />
7473
<Compile Include="Rules\Conventions\SourceLength\MaxLinesInLambdaFunction.fs" />
7574
<Compile Include="Rules\Conventions\SourceLength\MaxLinesInMatchLambdaFunction.fs" />
@@ -123,6 +122,7 @@
123122
<Compile Include="Rules\Formatting\Typography\MaxCharactersOnLine.fs" />
124123
<Compile Include="Rules\Formatting\Typography\TrailingWhitespaceOnLine.fs" />
125124
<Compile Include="Rules\Conventions\SourceLength\MaxLinesInFile.fs" />
125+
<Compile Include="Rules\Conventions\NoAsyncRunSynchronouslyInLibrary.fs" />
126126
<Compile Include="Rules\Formatting\Typography\TrailingNewLineInFile.fs" />
127127
<Compile Include="Rules\Formatting\Typography\NoTabCharacters.fs" />
128128
<Compile Include="Rules\Conventions\IndexerAccessorStyleConsistency.fs" />

src/FSharpLint.Core/Rules/Conventions/NoAsyncRunSynchronouslyInLibrary.fs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ open FSharpLint.Framework.Ast
1010
open FSharpLint.Framework.Rules
1111
open FSharpLint.Framework.Utilities
1212

13+
type LibraryHeuristicResultByProjectName =
14+
| Likely
15+
| Unlikely
16+
| Uncertain
17+
1318
let hasEntryPoint (checkFileResults: FSharpCheckFileResults) (maybeProjectCheckResults: FSharpCheckProjectResults option) =
1419
let hasEntryPointInTheSameFile =
1520
match checkFileResults.ImplementationFile with
@@ -26,15 +31,16 @@ let hasEntryPoint (checkFileResults: FSharpCheckFileResults) (maybeProjectCheckR
2631

2732
let excludedProjectNames = [ "test"; "console" ]
2833

29-
let isInTestProject (checkFileResults: FSharpCheckFileResults) =
30-
let namespaceIncludesTest =
31-
match checkFileResults.ImplementationFile with
32-
| Some implFile ->
33-
excludedProjectNames |> List.exists (fun name -> implFile.QualifiedName.ToLowerInvariant().Contains name)
34-
| None -> false
35-
let projectFileInfo = System.IO.FileInfo checkFileResults.ProjectContext.ProjectOptions.ProjectFileName
36-
namespaceIncludesTest
37-
|| excludedProjectNames |> List.exists (fun name -> projectFileInfo.Name.ToLowerInvariant().Contains name)
34+
let howLikelyProjectIsLibrary (projectFileName: string): LibraryHeuristicResultByProjectName =
35+
let nameSegments = Helper.Naming.QuickFixes.splitByCaseChange projectFileName
36+
if nameSegments |> Seq.contains "Lib" then
37+
Likely
38+
elif excludedProjectNames |> List.exists (fun name -> projectFileName.ToLowerInvariant().Contains name) then
39+
Unlikely
40+
elif projectFileName.ToLowerInvariant().EndsWith "lib" then
41+
Likely
42+
else
43+
Uncertain
3844

3945
let extractAttributeNames (attributes: SynAttributes) =
4046
seq {
@@ -94,15 +100,19 @@ let isInObsoleteMethodOrFunction parents =
94100

95101
let checkIfInLibrary (args: AstNodeRuleParams) (range: range) : array<WarningDetails> =
96102
let ruleNotApplicable =
103+
isInObsoleteMethodOrFunction (args.GetParents args.NodeIndex)
104+
||
97105
match args.CheckInfo with
98106
| Some checkFileResults ->
99-
hasEntryPoint checkFileResults args.ProjectCheckInfo
100-
|| isInTestProject checkFileResults
101-
|| isInObsoleteMethodOrFunction (args.GetParents args.NodeIndex)
102-
|| isInTheSameModuleAsTest args.SyntaxArray args.ProjectCheckInfo
107+
let projectFileName = System.IO.FileInfo(checkFileResults.ProjectContext.ProjectOptions.ProjectFileName).Name
108+
match howLikelyProjectIsLibrary projectFileName with
109+
| Likely -> false
110+
| Unlikely -> true
111+
| Uncertain ->
112+
hasEntryPoint checkFileResults args.ProjectCheckInfo
113+
|| isInTheSameModuleAsTest args.SyntaxArray args.ProjectCheckInfo
103114
| None ->
104-
isInObsoleteMethodOrFunction (args.GetParents args.NodeIndex)
105-
|| isInTheSameModuleAsTest args.SyntaxArray args.ProjectCheckInfo
115+
isInTheSameModuleAsTest args.SyntaxArray args.ProjectCheckInfo
106116

107117
if ruleNotApplicable then
108118
Array.empty

tests/FSharpLint.Core.Tests/Rules/Conventions/NoAsyncRunSynchronouslyInLibrary.fs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
open NUnit.Framework
44
open FSharpLint.Framework.Rules
55
open FSharpLint.Rules
6+
open FSharpLint.Rules.NoAsyncRunSynchronouslyInLibrary
67

78
[<TestFixture>]
89
type TestNoAsyncRunSynchronouslyInLibrary() =
@@ -130,3 +131,40 @@ let Foo() =
130131
|> Async.RunSynchronously""")
131132

132133
this.AssertNoWarnings()
134+
135+
[<TestFixture>]
136+
type TestNoAsyncRunSynchronouslyInLibraryHeuristic() =
137+
[<Test>]
138+
member this.``Unlikely to be library if contains "test" in name``() =
139+
Assert.AreEqual(
140+
howLikelyProjectIsLibrary "TestProject",
141+
LibraryHeuristicResultByProjectName.Unlikely
142+
)
143+
144+
[<Test>]
145+
member this.``Unlikely to be library if contains "console" in name``() =
146+
Assert.AreEqual(
147+
howLikelyProjectIsLibrary "FooConsole",
148+
LibraryHeuristicResultByProjectName.Unlikely
149+
)
150+
151+
[<Test>]
152+
member this.``Likely to be library if contains Contains "Lib" as a PascalCase segment``() =
153+
Assert.AreEqual(
154+
howLikelyProjectIsLibrary "LibFoo",
155+
LibraryHeuristicResultByProjectName.Likely
156+
)
157+
158+
[<Test>]
159+
member this.``Uncertain if contains contains "Lib" but not as a PascalCase segment``() =
160+
Assert.AreEqual(
161+
howLikelyProjectIsLibrary "LibreOfficeProg",
162+
LibraryHeuristicResultByProjectName.Uncertain
163+
)
164+
165+
[<Test>]
166+
member this.``Likely to be library if contains ends with "lib" (case-insensitive)``() =
167+
Assert.AreEqual(
168+
howLikelyProjectIsLibrary "FooLib",
169+
LibraryHeuristicResultByProjectName.Likely
170+
)

0 commit comments

Comments
 (0)