diff --git a/tests/SwaggerProvider.Tests/Schema.V2SchemaCompilationTests.fs b/tests/SwaggerProvider.Tests/Schema.V2SchemaCompilationTests.fs index e904912..3b798e4 100644 --- a/tests/SwaggerProvider.Tests/Schema.V2SchemaCompilationTests.fs +++ b/tests/SwaggerProvider.Tests/Schema.V2SchemaCompilationTests.fs @@ -289,6 +289,67 @@ let ``v2 allOf inheritance derived type has its own property``() = let dogType = types |> List.find(fun t -> t.Name = "Dog") dogType.GetDeclaredProperty("Breed") |> isNull |> shouldEqual false +// ── V2 allOf single $ref collapse ───────────────────────────────────────────── + +/// Swagger 2.0 schema where Alias wraps Pet via allOf with a single $ref and no +/// own properties. The compiler should collapse Alias into Pet. +let private v2AllOfSingleRefSchema = + """{ + "swagger": "2.0", + "info": { "title": "AliasTest", "version": "1.0.0" }, + "basePath": "/", + "paths": {}, + "definitions": { + "Pet": { + "type": "object", + "properties": { + "id": { "type": "integer" } + } + }, + "Alias": { + "allOf": [ { "$ref": "#/definitions/Pet" } ] + } + } +}""" + +[] +let ``v2 allOf single ref collapses to the referenced type``() = + let types = compileV2Schema v2AllOfSingleRefSchema + types |> List.exists(fun t -> t.Name = "Pet") |> shouldEqual true + +[] +let ``v2 allOf single ref does not produce a separate wrapper type``() = + let types = compileV2Schema v2AllOfSingleRefSchema + types |> List.exists(fun t -> t.Name = "Alias") |> shouldEqual false + +// ── V2 top-level string enum ────────────────────────────────────────────────── + +/// Swagger 2.0 schema with a top-level string enum definition. +let private v2StringEnumSchema = + """{ + "swagger": "2.0", + "info": { "title": "EnumTest", "version": "1.0.0" }, + "basePath": "/", + "paths": {}, + "definitions": { + "Color": { + "type": "string", + "enum": ["red", "green", "blue"] + } + } +}""" + +[] +let ``v2 top-level string enum compiles to a named enum type``() = + let types = compileV2Schema v2StringEnumSchema + types |> List.exists(fun t -> t.Name = "Color") |> shouldEqual true + +[] +let ``v2 top-level string enum type is an enum``() = + let types = compileV2Schema v2StringEnumSchema + let colorType = types |> List.find(fun t -> t.Name = "Color") + colorType.IsEnum |> shouldEqual true + // ── ToString tests ─────────────────────────────────────────────────────────── [] diff --git a/tests/SwaggerProvider.Tests/Schema.V3SchemaCompilationTests.fs b/tests/SwaggerProvider.Tests/Schema.V3SchemaCompilationTests.fs index df8f4f8..a63e1ed 100644 --- a/tests/SwaggerProvider.Tests/Schema.V3SchemaCompilationTests.fs +++ b/tests/SwaggerProvider.Tests/Schema.V3SchemaCompilationTests.fs @@ -452,6 +452,50 @@ let ``anyOf with multiple refs emits the referenced component types``() = types |> List.exists(fun t -> t.Name = "Fish") |> shouldEqual true types |> List.exists(fun t -> t.Name = "Bird") |> shouldEqual true +// ── $ref to enum type → property uses the named enum type ──────────────────── + +/// OpenAPI 3.0 schema where Task.status references Status (a string enum) via $ref. +let private refToEnumSchema = + """{ + "openapi": "3.0.0", + "info": { "title": "Test", "version": "1.0.0" }, + "paths": {}, + "components": { + "schemas": { + "Status": { + "type": "string", + "enum": ["open", "closed"] + }, + "Task": { + "type": "object", + "required": ["status"], + "properties": { + "status": { "$ref": "#/components/schemas/Status" } + } + } + } + } +}""" + +[] +let ``required property referencing a string enum uses the named enum type``() = + let types = compileV3Schema refToEnumSchema false + let statusType = types |> List.find(fun t -> t.Name = "Status") + let taskType = types |> List.find(fun t -> t.Name = "Task") + let statusProp = taskType.GetDeclaredProperty("Status") + statusProp |> isNull |> shouldEqual false + statusProp.PropertyType |> shouldEqual statusType + +[] +let ``required property referencing a string enum is not wrapped in option``() = + // Required $ref to enum: the property should use the enum type directly (not Option). + let types = compileV3Schema refToEnumSchema false + let statusType = types |> List.find(fun t -> t.Name = "Status") + let taskType = types |> List.find(fun t -> t.Name = "Task") + let statusProp = taskType.GetDeclaredProperty("Status") + statusProp.PropertyType |> shouldEqual statusType + statusProp.PropertyType.IsGenericType |> shouldEqual false + // ── allOf single $ref with extra wrapper properties → new object type ───────── /// OpenAPI 3.0 schema where Extended wraps Base via allOf with a single $ref,