morphit/node_modules/cborg/test/node-test-bin.js

419 lines
18 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* eslint-env mocha */
import * as chai from 'chai'
import { exec } from 'child_process'
import process from 'process'
import path from 'path'
import { platform } from 'os'
import { fileURLToPath } from 'url'
const { assert } = chai
const fixture1JsonString = '{"a":1,"b":[2,3],"smile":"😀"}'
const fixture1JsonPrettyString =
`{
"a": 1,
"b": [
2,
3
],
"smile": "😀"
}
`
const fixture1HexString = 'a3616101616282020365736d696c6564f09f9880'
const fixture1Bin = fromHex(fixture1HexString)
const fixture1BinString = new TextDecoder().decode(fixture1Bin)
const fixture1DiagnosticString =
`a3 # map(3)
61 # string(1)
61 # "a"
01 # uint(1)
61 # string(1)
62 # "b"
82 # array(2)
02 # uint(2)
03 # uint(3)
65 # string(5)
736d696c65 # "smile"
64 # string(2)
f09f9880 # "😀"
`
const fixture2HexString = 'a4616101616282020363627566440102036165736d696c6564f09f9880'
const fixture2DiagnosticString =
`a4 # map(4)
61 # string(1)
61 # "a"
01 # uint(1)
61 # string(1)
62 # "b"
82 # array(2)
02 # uint(2)
03 # uint(3)
63 # string(3)
627566 # "buf"
44 # bytes(4)
01020361 # "\\x01\\x02\\x03a"
65 # string(5)
736d696c65 # "smile"
64 # string(2)
f09f9880 # "😀"
`
const binPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../lib/bin.js')
function fromHex (hex) {
return new Uint8Array(hex.split('')
.map((/** @type {string} */ c, /** @type {number} */ i, /** @type {string[]} */ d) => i % 2 === 0 ? `0x${c}${d[i + 1]}` : '')
.filter(Boolean)
.map((/** @type {string} */ e) => parseInt(e, 16)))
}
async function execBin (cmd, stdin) {
return new Promise((resolve, reject) => {
const cp = exec(`"${process.execPath}" "${binPath}" ${cmd}`, (err, stdout, stderr) => {
if (err) {
err.stdout = stdout
err.stderr = stderr
return reject(err)
}
resolve({ stdout, stderr })
})
if (stdin != null) {
cp.on('spawn', () => {
cp.stdin.write(stdin)
cp.stdin.end()
})
}
})
}
describe('Bin', () => {
it('usage', async () => {
try {
await execBin('')
assert.fail('should have errored')
} catch (e) {
assert.strictEqual(e.stdout, '')
assert.strictEqual(e.stderr,
`Usage: cborg <command> <args>
Valid commands:
\tbin2diag [--width <width>] [binary input]
\tbin2hex [binary input]
\tbin2json [--pretty] [binary input]
\tdiag2bin [diagnostic input]
\tdiag2hex [diagnostic input]
\tdiag2json [--pretty] [diagnostic input]
\thex2bin [hex input]
\thex2diag [--width <width>] [hex input]
\thex2json [--pretty] [hex input]
\tjson2bin '[json input]'
\tjson2diag [--width <width>] '[json input]'
\tjson2hex '[json input]'
Input may either be supplied as an argument or piped via stdin
`)
}
})
it('bad cmd', async () => {
try {
await execBin('blip')
assert.fail('should have errored')
} catch (e) {
assert.strictEqual(e.stdout, '')
assert.strictEqual(e.stderr,
`Unknown command: 'blip'
Usage: cborg <command> <args>
Valid commands:
\tbin2diag [--width <width>] [binary input]
\tbin2hex [binary input]
\tbin2json [--pretty] [binary input]
\tdiag2bin [diagnostic input]
\tdiag2hex [diagnostic input]
\tdiag2json [--pretty] [diagnostic input]
\thex2bin [hex input]
\thex2diag [--width <width>] [hex input]
\thex2json [--pretty] [hex input]
\tjson2bin '[json input]'
\tjson2diag [--width <width>] '[json input]'
\tjson2hex '[json input]'
Input may either be supplied as an argument or piped via stdin
`)
}
})
it('help', async () => {
const { stdout, stderr } = await execBin('help')
assert.strictEqual(stdout, '')
assert.strictEqual(stderr,
`Usage: cborg <command> <args>
Valid commands:
\tbin2diag [--width <width>] [binary input]
\tbin2hex [binary input]
\tbin2json [--pretty] [binary input]
\tdiag2bin [diagnostic input]
\tdiag2hex [diagnostic input]
\tdiag2json [--pretty] [diagnostic input]
\thex2bin [hex input]
\thex2diag [--width <width>] [hex input]
\thex2json [--pretty] [hex input]
\tjson2bin '[json input]'
\tjson2diag [--width <width>] '[json input]'
\tjson2hex '[json input]'
Input may either be supplied as an argument or piped via stdin
`)
})
it('bin2diag (stdin)', async () => {
const { stdout, stderr } = await execBin('bin2diag', fixture1Bin)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1DiagnosticString)
})
it('bin2hex (stdin)', async () => {
const { stdout, stderr } = await execBin('bin2hex', fixture1Bin)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, `${fixture1HexString}\n`)
})
it('bin2json (stdin)', async () => {
const { stdout, stderr } = await execBin('bin2json', fixture1Bin)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, `${fixture1JsonString}\n`)
})
it('bin2json pretty (stdin)', async () => {
const { stdout, stderr } = await execBin('bin2json --pretty', fixture1Bin)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1JsonPrettyString)
})
for (const stdin of [true, false]) {
if (platform() !== 'win32' || stdin) { // multiline CLI input is hard (impossible?) on Windows
it(`diag2bin${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`diag2bin '${fixture1DiagnosticString}'`)
: await execBin('diag2bin', fixture1DiagnosticString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1BinString)
})
it(`diag2hex${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`diag2hex '${fixture1DiagnosticString}'`)
: await execBin('diag2hex', fixture1DiagnosticString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, `${fixture1HexString}\n`)
})
it(`diag2json${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`diag2json '${fixture1DiagnosticString}'`)
: await execBin('diag2json', fixture1DiagnosticString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, `${fixture1JsonString}\n`)
})
it(`diag2json pretty${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`diag2json --pretty '${fixture1DiagnosticString}'`)
: await execBin('diag2json --pretty', fixture1DiagnosticString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1JsonPrettyString)
})
}
it(`hex2bin${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`hex2bin ${fixture1HexString}`)
: await execBin('hex2bin', fixture1HexString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1BinString)
})
it(`hex2diag${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`hex2diag ${fixture2HexString}`)
: await execBin('hex2diag', fixture2HexString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture2DiagnosticString)
})
it(`hex2json${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`hex2json ${fixture1HexString}`)
: await execBin('hex2json', fixture1HexString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, `${fixture1JsonString}\n`)
})
it(`hex2json pretty${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`hex2json --pretty ${fixture1HexString}`)
: await execBin('hex2json --pretty', fixture1HexString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1JsonPrettyString)
})
it(`json2bin${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin('json2bin "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"😀\\"}"')
: await execBin('json2bin', fixture1JsonString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1BinString)
})
it(`json2diag${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin('json2diag "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"😀\\"}"')
: await execBin('json2diag', fixture1JsonString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, fixture1DiagnosticString)
})
it(`json2hex${stdin ? ' (stdin)' : ''}`, async () => {
const { stdout, stderr } = !stdin
? await execBin(`json2hex "${fixture1JsonString.replace(/"/g, '\\"')}"`)
: await execBin('json2hex', fixture1JsonString)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, `${fixture1HexString}\n`)
})
}
// complicated nesting to test indenting algorithm
it('diag indenting', async () => {
const { stdout, stderr } = await execBin('json2diag', '{"a":[],"b":{},"c":{"a":1,"b":{"a":{"a":{}}}},"d":{"a":{"a":{"a":1},"b":2,"c":[]}},"e":[[[[{"a":{}}]]]],"f":1}')
assert.strictEqual(stderr, '')
assert.strictEqual(stdout,
`a6 # map(6)
61 # string(1)
61 # "a"
80 # array(0)
61 # string(1)
62 # "b"
a0 # map(0)
61 # string(1)
63 # "c"
a2 # map(2)
61 # string(1)
61 # "a"
01 # uint(1)
61 # string(1)
62 # "b"
a1 # map(1)
61 # string(1)
61 # "a"
a1 # map(1)
61 # string(1)
61 # "a"
a0 # map(0)
61 # string(1)
64 # "d"
a1 # map(1)
61 # string(1)
61 # "a"
a3 # map(3)
61 # string(1)
61 # "a"
a1 # map(1)
61 # string(1)
61 # "a"
01 # uint(1)
61 # string(1)
62 # "b"
02 # uint(2)
61 # string(1)
63 # "c"
80 # array(0)
61 # string(1)
65 # "e"
81 # array(1)
81 # array(1)
81 # array(1)
81 # array(1)
a1 # map(1)
61 # string(1)
61 # "a"
a0 # map(0)
61 # string(1)
66 # "f"
01 # uint(1)
`)
})
describe('diag length bytes', () => {
// issue #137 - array and map length bytes were missing for lengths >= 24
it('array with 24 elements', async () => {
// 98 18 = array(24), then 24 uint(1) values
const hex = '9818' + '01'.repeat(24)
const { stdout, stderr } = await execBin(`hex2diag ${hex}`)
assert.strictEqual(stderr, '')
assert.ok(stdout.startsWith('98 18 # array(24)\n'))
})
it('map with 24 entries', async () => {
// b8 18 = map(24), then 24 pairs of string('a')=uint(1)
const hex = 'b818' + '616101'.repeat(24)
const { stdout, stderr } = await execBin(`hex2diag ${hex}`)
assert.strictEqual(stderr, '')
assert.ok(stdout.startsWith('b8 18 # map(24)\n'))
})
it('compact', async () => {
const { stdout, stderr } = await execBin('json2diag', '"aaaaaaaaaaaaaaaaaaaaaaa"')
assert.strictEqual(stderr, '')
assert.strictEqual(stdout,
`77 # string(23)
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
`)
})
it('1-byte', async () => {
const { stdout, stderr } = await execBin('json2diag', '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"')
assert.strictEqual(stderr, '')
assert.strictEqual(stdout,
`78 23 # string(35)
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
616161616161616161616161 # "aaaaaaaaaaaa"
`)
})
it('2-byte', async () => {
const { stdout, stderr } = await execBin('json2diag', '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"')
assert.strictEqual(stderr, '')
assert.strictEqual(stdout,
`79 0100 # string(256)
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
616161 # "aaa"
`)
})
})
it('diag non-utf8 and non-printable ascii', async () => {
const input = '7864f55ff8f12508b63ef2bfeca7557ae90df6311a5ec1631b4a1fa843310bd9c3a710eaace5a1bdd72ad0bfe049771c11e756338bd93865e645f1adec9b9c99ef407fbd4fc6859e7904c5ad7dc9bd10a5cc16973d5b28ec1a6dd43d9f82f9f18c3d03418e35'
let { stdout, stderr } = await execBin(`hex2diag ${input}`)
assert.strictEqual(stderr, '')
assert.strictEqual(stdout,
`78 64 # string(86)
f55ff8f12508b63ef2bfeca7557ae90df6311a5ec1631b # "õ_øñ%\\x08¶>ò¿ì§Uzé\\x0dö1\\x1a^Ác\\x1b"
4a1fa843310bd9c3a710eaace5a1bdd72ad0bfe049771c # "J\\x1f¨C1\\x0bÙç\\x10ê¬å¡½×*пàIw\\x1c"
11e756338bd93865e645f1adec9b9c99ef407fbd4fc685 # "\\x11çV3\\x8bÙ8eæEñ\\xadì\\x9b\\x9c\\x99ï@\\x7f½OÆ\\x85"
9e7904c5ad7dc9bd10a5cc16973d5b28ec1a6dd43d9f82 # "\\x9ey\\x04Å\\xad}ɽ\\x10¥Ì\\x16\\x97=[(ì\\x1amÔ=\\x9f\\x82"
f9f18c3d03418e35 # "ùñ\\x8c=\\x03A\\x8e5"
`)
// round-trip
;({ stdout, stderr } = await execBin('diag2hex', stdout))
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, `${input}\n`)
})
})