Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/SwaggerProvider.Tests/SwaggerProvider.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<Compile Include="PathResolutionTests.fs" />
<Compile Include="SsrfSecurityTests.fs" />
<Compile Include="RuntimeHelpersTests.fs" />
<Compile Include="UtilsTests.fs" />
<None Include="paket.references" />
<ProjectReference Include="..\..\src\SwaggerProvider.DesignTime\SwaggerProvider.DesignTime.fsproj" />
</ItemGroup>
Expand Down
73 changes: 73 additions & 0 deletions tests/SwaggerProvider.Tests/UtilsTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
namespace SwaggerProvider.Tests.UtilsTests

open Xunit
open FsUnitTyped
open SwaggerProvider.Internal

/// Unit tests for UniqueNameGenerator β€” used by all DefinitionCompilers and OperationCompilers
/// to de-duplicate property and method names within a given type scope.
module UniqueNameGeneratorTests =

[<Fact>]
let ``first use of a name is returned unchanged``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "Foo" |> shouldEqual "Foo"

[<Fact>]
let ``second use of same name gets numeric suffix 1``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "Bar" |> ignore
gen.MakeUnique "Bar" |> shouldEqual "Bar1"

[<Fact>]
let ``third use of same name gets numeric suffix 2``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "Bar" |> ignore
gen.MakeUnique "Bar" |> ignore
gen.MakeUnique "Bar" |> shouldEqual "Bar2"

[<Fact>]
let ``collision detection is case-insensitive``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "Foo" |> ignore
// "foo" collides with "Foo" because comparison is case-insensitive
gen.MakeUnique "foo" |> shouldEqual "foo1"

[<Fact>]
let ``original casing of the returned name is preserved``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "MyProperty" |> shouldEqual "MyProperty"

[<Fact>]
let ``suffix casing follows the input not the stored key``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "myMethod" |> ignore
// Suffix is appended to the original input, preserving its casing
gen.MakeUnique "myMethod" |> shouldEqual "myMethod1"
Comment on lines +45 to +46
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test suffix casing follows the input not the stored key doesn’t currently exercise the scenario described by its name/comment: both calls use the same casing ("myMethod"), and the suffix is numeric so casing can’t differ. Consider changing the second call to a different-cased input (e.g., first "myMethod" then "MYMETHOD" expecting "MYMETHOD1"), or renaming the test to match what it actually asserts.

Suggested change
// Suffix is appended to the original input, preserving its casing
gen.MakeUnique "myMethod" |> shouldEqual "myMethod1"
// Suffix is appended to the current input ("MYMETHOD"), preserving its casing
gen.MakeUnique "MYMETHOD" |> shouldEqual "MYMETHOD1"

Copilot uses AI. Check for mistakes.

[<Fact>]
let ``different names do not collide``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "Alpha" |> shouldEqual "Alpha"
gen.MakeUnique "Beta" |> shouldEqual "Beta"
gen.MakeUnique "Gamma" |> shouldEqual "Gamma"

[<Fact>]
let ``numeric suffixes increment sequentially``() =
let gen = UniqueNameGenerator()
let names = [ for _ in 0..4 -> gen.MakeUnique "X" ]
names |> shouldEqual [ "X"; "X1"; "X2"; "X3"; "X4" ]

[<Fact>]
let ``name equal to a previously suffixed name is also de-duplicated``() =
// After generating "Op" and "Op1", adding "Op1" should produce "Op11"
let gen = UniqueNameGenerator()
gen.MakeUnique "Op" |> ignore // reserves "op"
gen.MakeUnique "Op" |> ignore // reserves "op1"
gen.MakeUnique "Op1" |> shouldEqual "Op11" // "op1" is taken β†’ try "op11"

[<Fact>]
let ``empty string is accepted as input``() =
let gen = UniqueNameGenerator()
gen.MakeUnique "" |> shouldEqual ""
gen.MakeUnique "" |> shouldEqual "1"
Loading