diff --git a/yaml/_type/int.ts b/yaml/_type/int.ts index 494cf4622..f0d2e4b37 100644 --- a/yaml/_type/int.ts +++ b/yaml/_type/int.ts @@ -131,6 +131,7 @@ function constructYamlInteger(data: string): number { } function isInteger(object: unknown): object is number { + if (object instanceof Number) object = object.valueOf(); return typeof object === "number" && object % 1 === 0 && !isNegativeZero(object); } @@ -142,21 +143,31 @@ export const int: Type<"scalar", number> = { kind: "scalar", predicate: isInteger, represent: { - binary(obj: number): string { - return obj >= 0 - ? `0b${obj.toString(2)}` - : `-0b${obj.toString(2).slice(1)}`; + // deno-lint-ignore ban-types + binary(object: number | Number): string { + const value = object instanceof Number ? object.valueOf() : object; + return value >= 0 + ? `0b${value.toString(2)}` + : `-0b${value.toString(2).slice(1)}`; }, - octal(obj: number): string { - return obj >= 0 ? `0${obj.toString(8)}` : `-0${obj.toString(8).slice(1)}`; + // deno-lint-ignore ban-types + octal(object: number | Number): string { + const value = object instanceof Number ? object.valueOf() : object; + return value >= 0 + ? `0${value.toString(8)}` + : `-0${value.toString(8).slice(1)}`; }, - decimal(obj: number): string { - return obj.toString(10); + // deno-lint-ignore ban-types + decimal(object: number | Number): string { + const value = object instanceof Number ? object.valueOf() : object; + return value.toString(10); }, - hexadecimal(obj: number): string { - return obj >= 0 - ? `0x${obj.toString(16).toUpperCase()}` - : `-0x${obj.toString(16).toUpperCase().slice(1)}`; + // deno-lint-ignore ban-types + hexadecimal(object: number | Number): string { + const value = object instanceof Number ? object.valueOf() : object; + return value >= 0 + ? `0x${value.toString(16).toUpperCase()}` + : `-0x${value.toString(16).toUpperCase().slice(1)}`; }, }, resolve: resolveYamlInteger, diff --git a/yaml/stringify_test.ts b/yaml/stringify_test.ts index a278b6c26..9c1638446 100644 --- a/yaml/stringify_test.ts +++ b/yaml/stringify_test.ts @@ -77,11 +77,18 @@ Deno.test({ }); Deno.test({ - name: "stringify() serializes integers", + name: "stringify() handles integers", fn() { assertEquals(stringify(42), "42\n"); assertEquals(stringify(-42), "-42\n"); + assertEquals(stringify(new Number(42)), "42\n"); + assertEquals(stringify(new Number(-42)), "-42\n"); + }, +}); +Deno.test({ + name: "stringify() handles integers with styles option", + fn() { // binary, octal, and hexadecimal can be specified in styles options assertEquals( stringify(42, { styles: { "!!int": "binary" } }), @@ -91,6 +98,10 @@ Deno.test({ stringify(-42, { styles: { "!!int": "binary" } }), "-0b101010\n", ); + assertEquals( + stringify(new Number(42), { styles: { "!!int": "binary" } }), + "0b101010\n", + ); assertEquals( stringify(42, { styles: { "!!int": "octal" } }), "052\n", @@ -99,6 +110,10 @@ Deno.test({ stringify(-42, { styles: { "!!int": "octal" } }), "-052\n", ); + assertEquals( + stringify(new Number(42), { styles: { "!!int": "octal" } }), + "052\n", + ); assertEquals( stringify(42, { styles: { "!!int": "hexadecimal" } }), "0x2A\n", @@ -107,6 +122,15 @@ Deno.test({ stringify(-42, { styles: { "!!int": "hexadecimal" } }), "-0x2A\n", ); + assertEquals( + stringify(new Number(42), { styles: { "!!int": "hexadecimal" } }), + "0x2A\n", + ); + assertThrows( + () => stringify(42, { styles: { "!!int": "camelcase" } }), + TypeError, + '! tag resolver accepts not "camelcase" style', + ); }, });