-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a little bit weird to use due to having to prepend to the `tags` list, but the definition does work if used properly.
- Loading branch information
Showing
4 changed files
with
120 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { test } from 'tap' | ||
import { Document, parse, stringify, Tags, type Scalar } from 'yaml' | ||
|
||
import { bigint } from '.' | ||
|
||
const customTags = (tags: Tags) => ([bigint] as Tags).concat(tags) | ||
|
||
test('parse with n', t => { | ||
const res: bigint = parse(`!bigint 123n`, { | ||
customTags: [bigint] | ||
}) | ||
t.type(res, 'bigint') | ||
t.equal(Number(res), 123) | ||
t.equal(res, 123n) | ||
t.end() | ||
}) | ||
|
||
test('parse without n', t => { | ||
const res: bigint = parse(`!bigint 123`, { customTags }) | ||
t.type(res, 'bigint') | ||
t.equal(Number(res), 123) | ||
t.equal(res, 123n) | ||
t.end() | ||
}) | ||
|
||
test('parse hex, octal, binary', t => { | ||
const cases = [ | ||
'0b11011110101011011011111011101111', | ||
'0b11011110101011011011111011101111n', | ||
'0o33653337357', | ||
'0o33653337357n', | ||
'3735928559', | ||
'3735928559n', | ||
'0xDeAdBeEf', | ||
'0xDeAdBeEfn', | ||
'0xDEADBEEF', | ||
'0xDEADBEEFn', | ||
'0xdeadbeef', | ||
'0xdeadbeefn' | ||
] | ||
for (const c of cases) { | ||
const res: bigint = parse(`!bigint ${c}`, { customTags }) | ||
t.equal(res, 0xdeadbeefn, `${c} value`) | ||
t.type(res, 'bigint', `${c} typeof`) | ||
} | ||
t.end() | ||
}) | ||
|
||
test('parse invalid', t => { | ||
const opt = { customTags } | ||
t.throws(() => parse('!bigint not a number\n', opt)) | ||
t.throws(() => parse('!bigint 123.456\n', opt)) | ||
t.throws(() => parse('!bigint 123x\n', opt)) | ||
t.throws(() => parse('!bigint 0Xbad1dea\n', opt), '0x must be lowercase') | ||
t.throws(() => parse('!bigint 0xBAD1DEAN\n', opt), 'n must be lowercase') | ||
t.throws(() => parse('!bigint 0b012', opt), '2 is invalid binary digit') | ||
t.throws(() => parse('!bigint 0o018', opt), '8 is invalid octal digit') | ||
t.end() | ||
}) | ||
|
||
test('stringify', t => { | ||
const doc = new Document<Scalar, false>(123n, { customTags }) | ||
t.equal(doc.toString(), '!bigint 123n\n') | ||
|
||
doc.contents.value = Object(42n) | ||
t.equal(doc.toString(), '!bigint 42n\n') | ||
|
||
doc.contents.value = 42 | ||
t.throws(() => doc.toString(), { name: 'TypeError' }) | ||
|
||
t.equal( | ||
stringify([123, 123n, BigInt('123'), Object(123n), Object(BigInt(123))], { | ||
customTags | ||
}), | ||
`- 123 | ||
- !bigint 123n | ||
- !bigint 123n | ||
- !bigint 123n | ||
- !bigint 123n | ||
` | ||
) | ||
|
||
t.end() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { Scalar, ScalarTag } from 'yaml' | ||
import { StringifyContext, stringifyString } from 'yaml/util' | ||
|
||
const identify = (value: any) => { | ||
return typeof value === 'bigint' || value instanceof BigInt | ||
} | ||
|
||
/** | ||
* `!bigint` BigInt | ||
* | ||
* [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) values, | ||
* using their conventional `123n` representation. | ||
*/ | ||
export const bigint = { | ||
identify, | ||
tag: '!bigint', | ||
resolve(str: string) { | ||
const match = str.match(/^([1-9][0-9]*|0x[0-9a-fA-F]+|0o[0-7]+|0b[01]+)n?$/) | ||
if (!match) throw new Error('Invalid BigInt value') | ||
return BigInt(match[1]) | ||
}, | ||
stringify(item: Scalar, ctx: StringifyContext, onComment, onChompKeep) { | ||
if (!identify(item.value)) { | ||
throw new TypeError(`${item.value} is not a bigint`) | ||
} | ||
const value = (item.value as BigInt).toString() + 'n' | ||
return stringifyString({ value }, ctx, onComment, onChompKeep) | ||
} | ||
} satisfies ScalarTag |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters