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
8 changes: 8 additions & 0 deletions src/Trax.Cli/Program.Coverage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Diagnostics.CodeAnalysis;

// The CLI entry point in Program.cs is a top-level program that's never invoked
// during unit tests (tests target GenerateCommand.Handle directly). The synthesized
// Program class gets a partial declaration here so we can mark the auto-generated
// Main method as excluded from coverage rather than carrying a permanent 0%.
[ExcludeFromCodeCoverage]
internal partial class Program;
62 changes: 62 additions & 0 deletions tests/Trax.Cli.Tests/Fixtures/Schemas/openapi-more-edges.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"openapi": "3.0.0",
"info": { "title": "More Edges", "version": "1.0" },
"paths": {
"/a/list": {
"get": {
"operationId": "listThings",
"responses": { "200": { "description": "ok" } }
}
},
"/b/list": {
"get": {
"operationId": "listThings",
"responses": { "200": { "description": "ok" } }
}
},
"/c/list": {
"get": {
"operationId": "listThings",
"responses": { "200": { "description": "ok" } }
}
},
"/with-status": {
"get": {
"operationId": "getStatus",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Status" }
}
}
}
}
}
},
"/with-status-again": {
"get": {
"operationId": "getStatus2",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Status" }
}
}
}
}
}
}
},
"components": {
"schemas": {
"Status": {
"type": "string",
"enum": ["Active", "Inactive", "Pending"]
}
}
}
}
52 changes: 52 additions & 0 deletions tests/Trax.Cli.Tests/UnitTests/OpenApiMoreEdgesTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using FluentAssertions;
using Trax.Cli.Schema.OpenApi;

namespace Trax.Cli.Tests.UnitTests;

[TestFixture]
public class OpenApiMoreEdgesTests
{
private static string FixturePath(string name) =>
Path.Combine(TestContext.CurrentContext.TestDirectory, "Fixtures", "Schemas", name);

[Test]
public void Parse_OperationIdCollision_NoPathParams_FallsBackToNumericSuffix()
{
var parser = new OpenApiSchemaParser();
var schema = parser.Parse(FixturePath("openapi-more-edges.json"));

// Three GET ops with operationId "listThings" and no path params force the
// numeric fallback in EnsureUniqueOperationName.
var listOps = schema
.Operations.Where(o => o.Name.StartsWith("ListThings", StringComparison.Ordinal))
.Select(o => o.Name)
.ToList();

listOps.Should().HaveCount(3);
listOps.Should().Contain("ListThings");
listOps.Should().Contain(n => n.EndsWith("2") || n.EndsWith("3"));
}

[Test]
public void Parse_StringEnumComponent_BuildsApiEnum()
{
var parser = new OpenApiSchemaParser();
var schema = parser.Parse(FixturePath("openapi-more-edges.json"));

var statusEnum = schema.Enums.SingleOrDefault(e => e.Name == "Status");
statusEnum.Should().NotBeNull();
statusEnum!.Values.Should().BeEquivalentTo("Active", "Inactive", "Pending");
}

[Test]
public void Parse_RepeatedRef_ReusesCachedType()
{
// Two operations both reference Status — second resolution hits the
// _resolvedTypes/_resolvedEnums cache rather than building a fresh entry.
var parser = new OpenApiSchemaParser();
var schema = parser.Parse(FixturePath("openapi-more-edges.json"));

// One enum entry total even though referenced twice.
schema.Enums.Where(e => e.Name == "Status").Should().HaveCount(1);
}
}
Loading