Skip to content

Commit

Permalink
Fix OpenAPI YAML converts strings to boolean (#5456)
Browse files Browse the repository at this point in the history
Problem: yaml 1.1 treats some string as other types of value. Check out:
https://perlpunk.github.io/yaml-test-schema/schemas.html
Fix: #5377
Solution: make serialization compatible with YAML 1.1
Todo: test other types (in next PR).
  • Loading branch information
wanlwanl authored Jan 14, 2025
1 parent 84ebce0 commit c0a9a53
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .chronus/changes/wanl-fix-noway-yaml-2024-11-27-14-31-43.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/openapi3"
---

Fix: OpenAPI YAML converts strings to boolean
1 change: 1 addition & 0 deletions packages/openapi3/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,7 @@ function serializeDocument(root: OpenAPI3Document, fileType: FileType): string {
singleQuote: true,
aliasDuplicateObjects: false,
lineWidth: 0,
compat: "yaml-1.1",
});
}
}
Expand Down
79 changes: 79 additions & 0 deletions packages/openapi3/test/emit-openapi.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { describe, expect, it } from "vitest";
import { emitOpenApiWithDiagnostics } from "./test-host.js";

describe("Scalar formats of serialized document in YAML", () => {
it("should add single quote for y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF", async () => {
const [_, __, content] = await emitOpenApiWithDiagnostics(`
enum TestEnum {
y: "y",
Y: "Y",
yes: "yes",
Yes: "Yes",
YES: "YES",
yEs: "yEs",
n: "n",
N: "N",
no: "no",
No: "No",
NO: "NO",
nO: "nO",
"true": "true",
True: "True",
TRUE: "TRUE",
tRUE: "tRUE",
"false": "false",
False: "False",
FALSE: "FALSE",
fALSE: "fALSE",
on: "on",
On: "On",
ON: "ON",
oN: "oN",
off: "off",
Off: "Off",
OFF: "OFF",
oFF: "oFF"
}
`);
expect(content).toBe(`openapi: 3.0.0
info:
title: (title)
version: 0.0.0
tags: []
paths: {}
components:
schemas:
TestEnum:
type: string
enum:
- 'y'
- 'Y'
- 'yes'
- 'Yes'
- 'YES'
- yEs
- 'n'
- 'N'
- 'no'
- 'No'
- 'NO'
- nO
- 'true'
- 'True'
- 'TRUE'
- tRUE
- 'false'
- 'False'
- 'FALSE'
- fALSE
- 'on'
- 'On'
- 'ON'
- oN
- 'off'
- 'Off'
- 'OFF'
- oFF
`);
});
});
10 changes: 6 additions & 4 deletions packages/openapi3/test/test-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { RestTestLibrary } from "@typespec/rest/testing";
import { VersioningTestLibrary } from "@typespec/versioning/testing";
import { XmlTestLibrary } from "@typespec/xml/testing";
import { ok } from "assert";
import { parse } from "yaml";
import { OpenAPI3EmitterOptions } from "../src/lib.js";
import { OpenAPI3TestLibrary } from "../src/testing/index.js";
import { OpenAPI3Document } from "../src/types.js";
Expand Down Expand Up @@ -56,9 +57,10 @@ export async function createOpenAPITestRunner({
export async function emitOpenApiWithDiagnostics(
code: string,
options: OpenAPI3EmitterOptions = {},
): Promise<[OpenAPI3Document, readonly Diagnostic[]]> {
): Promise<[OpenAPI3Document, readonly Diagnostic[], string]> {
const runner = await createOpenAPITestRunner();
const outputFile = resolveVirtualPath("openapi.json");
const fileType = options["file-type"] || "yaml";
const outputFile = resolveVirtualPath("openapi" + fileType === "json" ? ".json" : ".yaml");
const diagnostics = await runner.diagnose(code, {
noEmit: false,
emit: ["@typespec/openapi3"],
Expand All @@ -68,8 +70,8 @@ export async function emitOpenApiWithDiagnostics(
});
const content = runner.fs.get(outputFile);
ok(content, "Expected to have found openapi output");
const doc = JSON.parse(content);
return [doc, diagnostics];
const doc = fileType === "json" ? JSON.parse(content) : parse(content);
return [doc, diagnostics, content];
}

export async function diagnoseOpenApiFor(code: string, options: OpenAPI3EmitterOptions = {}) {
Expand Down

0 comments on commit c0a9a53

Please sign in to comment.