diff --git a/yaml/_type/float.ts b/yaml/_type/float.ts index b8fe8451ff2e..74f812780e72 100644 --- a/yaml/_type/float.ts +++ b/yaml/_type/float.ts @@ -50,8 +50,13 @@ function constructYamlFloat(data: string): number { const SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; -function representYamlFloat(object: number, style?: StyleVariant): string { - if (isNaN(object)) { +function representYamlFloat( + // deno-lint-ignore ban-types + object: number | Number, + style?: StyleVariant, +): string { + const value = object instanceof Number ? object.valueOf() : object; + if (isNaN(value)) { switch (style) { case "lowercase": return ".nan"; @@ -60,7 +65,7 @@ function representYamlFloat(object: number, style?: StyleVariant): string { case "camelcase": return ".NaN"; } - } else if (Number.POSITIVE_INFINITY === object) { + } else if (Number.POSITIVE_INFINITY === value) { switch (style) { case "lowercase": return ".inf"; @@ -69,7 +74,7 @@ function representYamlFloat(object: number, style?: StyleVariant): string { case "camelcase": return ".Inf"; } - } else if (Number.NEGATIVE_INFINITY === object) { + } else if (Number.NEGATIVE_INFINITY === value) { switch (style) { case "lowercase": return "-.inf"; @@ -78,11 +83,11 @@ function representYamlFloat(object: number, style?: StyleVariant): string { case "camelcase": return "-.Inf"; } - } else if (isNegativeZero(object)) { + } else if (isNegativeZero(value)) { return "-0.0"; } - const res = object.toString(10); + const res = value.toString(10); // JS stringifier can build scientific format without dots: 5e-100, // while YAML requires dot: 5.e-100. Fix it with simple hack @@ -91,6 +96,7 @@ function representYamlFloat(object: number, style?: StyleVariant): string { } function isFloat(object: unknown): object is number { + if (object instanceof Number) object = object.valueOf(); return typeof object === "number" && (object % 1 !== 0 || isNegativeZero(object)); } diff --git a/yaml/stringify_test.ts b/yaml/stringify_test.ts index 9aa35958be61..a278b6c26724 100644 --- a/yaml/stringify_test.ts +++ b/yaml/stringify_test.ts @@ -226,49 +226,57 @@ Deno.test({ }); Deno.test({ - name: "stringify() handles float types", + name: "stringify() handles float values", fn() { - const floats = [ - 4.1, - -1.473, - 6.82e-5, - 6.82e-12, - 5e-12, - 0, - -0, - ]; - assertEquals( - stringify(floats), - `- 4.1 -- -1.473 -- 0.0000682 -- 6.82e-12 -- 5.e-12 -- 0 -- -0.0 -`, + assertEquals(stringify(4.1), `4.1\n`); + assertEquals(stringify(-1.473), `-1.473\n`); + assertEquals(stringify(6.82e-5), `0.0000682\n`); + assertEquals(stringify(6.82e-12), `6.82e-12\n`); + assertEquals(stringify(5e-12), `5.e-12\n`); + assertEquals(stringify(0.0), `0\n`); + assertEquals(stringify(-0), `-0.0\n`); + assertEquals(stringify(new Number(1.234)), `1.234\n`); + assertEquals(stringify(new Number(-1.234)), `-1.234\n`); + + assertEquals(stringify(Infinity), `.inf\n`); + assertEquals(stringify(-Infinity), `-.inf\n`); + assertEquals(stringify(NaN), `.nan\n`); + }, +}); +Deno.test({ + name: "stringify() handles float values with styles option", + fn() { + assertEquals( + stringify(Infinity, { + styles: { "tag:yaml.org,2002:float": "uppercase" }, + }), + `.INF\n`, ); - const infNaN = [Infinity, -Infinity, NaN]; assertEquals( - stringify(infNaN), - `- .inf -- -.inf -- .nan -`, + stringify(-Infinity, { + styles: { "tag:yaml.org,2002:float": "uppercase" }, + }), + `-.INF\n`, ); assertEquals( - stringify(infNaN, { styles: { "tag:yaml.org,2002:float": "uppercase" } }), - `- .INF -- -.INF -- .NAN -`, + stringify(NaN, { styles: { "tag:yaml.org,2002:float": "uppercase" } }), + `.NAN\n`, ); assertEquals( - stringify(infNaN, { styles: { "tag:yaml.org,2002:float": "camelcase" } }), - `- .Inf -- -.Inf -- .NaN -`, + stringify(Infinity, { + styles: { "tag:yaml.org,2002:float": "camelcase" }, + }), + `.Inf\n`, + ); + assertEquals( + stringify(-Infinity, { + styles: { "tag:yaml.org,2002:float": "camelcase" }, + }), + `-.Inf\n`, + ); + assertEquals( + stringify(NaN, { styles: { "tag:yaml.org,2002:float": "camelcase" } }), + `.NaN\n`, ); }, });