fix(yaml): handle float number instances (#5896)

initial commit
This commit is contained in:
Tim Reichen 2024-09-03 10:50:34 +02:00 committed by GitHub
parent 2d6c45e325
commit 25de700ed5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 43 deletions

View File

@ -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));
}

View File

@ -226,49 +226,57 @@ Deno.test({
});
Deno.test({
name: "stringify() handles float types",
name: "stringify() handles float values",
fn() {
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() {
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
`,
);
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(-Infinity, {
styles: { "tag:yaml.org,2002:float": "uppercase" },
}),
`-.INF\n`,
);
assertEquals(
stringify(infNaN, { styles: { "tag:yaml.org,2002:float": "camelcase" } }),
`- .Inf
- -.Inf
- .NaN
`,
stringify(NaN, { styles: { "tag:yaml.org,2002:float": "uppercase" } }),
`.NAN\n`,
);
assertEquals(
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`,
);
},
});