cborg 1.6.2 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/lib/bin.js CHANGED
@@ -14,15 +14,18 @@ var process__default = /*#__PURE__*/_interopDefaultLegacy(process);
14
14
  function usage(code) {
15
15
  console.error('Usage: cborg <command> <args>');
16
16
  console.error('Valid commands:');
17
- console.error('\thex2diag [hex input]');
18
- console.error('\thex2bin [hex input]');
19
- console.error('\thex2json [--pretty] [hex input]');
20
- console.error('\tbin2hex [binary input]');
21
17
  console.error('\tbin2diag [binary input]');
18
+ console.error('\tbin2hex [binary input]');
22
19
  console.error('\tbin2json [--pretty] [binary input]');
23
- console.error('\tjson2hex \'[json input]\'');
24
- console.error('\tjson2diag \'[json input]\'');
20
+ console.error('\tdiag2bin [diagnostic input]');
21
+ console.error('\tdiag2hex [diagnostic input]');
22
+ console.error('\tdiag2json [--pretty] [diagnostic input]');
23
+ console.error('\thex2bin [hex input]');
24
+ console.error('\thex2diag [hex input]');
25
+ console.error('\thex2json [--pretty] [hex input]');
25
26
  console.error('\tjson2bin \'[json input]\'');
27
+ console.error('\tjson2diag \'[json input]\'');
28
+ console.error('\tjson2hex \'[json input]\'');
26
29
  console.error('Input may either be supplied as an argument or piped via stdin');
27
30
  process__default["default"].exit(code || 0);
28
31
  }
@@ -54,22 +57,13 @@ async function run() {
54
57
  case 'help': {
55
58
  return usage(0);
56
59
  }
57
- case 'hex2json': {
58
- const {argv, pretty} = argvPretty();
59
- const bin = fromHex(argv.length < 4 ? (await fromStdin()).toString() : argv[3]);
60
- return console.log(JSON.stringify(decode.decode(bin), undefined, pretty ? 2 : undefined));
61
- }
62
- case 'hex2diag': {
63
- const bin = fromHex(process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3]);
60
+ case 'bin2diag': {
61
+ const bin = process__default["default"].argv.length < 4 ? await fromStdin() : new TextEncoder().encode(process__default["default"].argv[3]);
64
62
  for (const line of diagnostic.tokensToDiagnostic(bin)) {
65
63
  console.log(line);
66
64
  }
67
65
  return;
68
66
  }
69
- case 'hex2bin': {
70
- const bin = fromHex(process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3]);
71
- return process__default["default"].stdout.write(bin);
72
- }
73
67
  case 'bin2hex': {
74
68
  const bin = process__default["default"].argv.length < 4 ? await fromStdin() : new TextEncoder().encode(process__default["default"].argv[3]);
75
69
  return console.log(byteUtils.toHex(bin));
@@ -79,17 +73,39 @@ async function run() {
79
73
  const bin = argv.length < 4 ? await fromStdin() : new TextEncoder().encode(argv[3]);
80
74
  return console.log(JSON.stringify(decode.decode(bin), undefined, pretty ? 2 : undefined));
81
75
  }
82
- case 'bin2diag': {
83
- const bin = process__default["default"].argv.length < 4 ? await fromStdin() : new TextEncoder().encode(process__default["default"].argv[3]);
76
+ case 'diag2bin': {
77
+ const bin = diagnostic.fromDiag(process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3]);
78
+ return process__default["default"].stdout.write(bin);
79
+ }
80
+ case 'diag2hex': {
81
+ const bin = diagnostic.fromDiag(process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3]);
82
+ return console.log(byteUtils.toHex(bin));
83
+ }
84
+ case 'diag2json': {
85
+ const {argv, pretty} = argvPretty();
86
+ const bin = diagnostic.fromDiag(argv.length < 4 ? (await fromStdin()).toString() : argv[3]);
87
+ return console.log(JSON.stringify(decode.decode(bin), undefined, pretty ? 2 : undefined));
88
+ }
89
+ case 'hex2bin': {
90
+ const bin = fromHex(process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3]);
91
+ return process__default["default"].stdout.write(bin);
92
+ }
93
+ case 'hex2diag': {
94
+ const bin = fromHex(process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3]);
84
95
  for (const line of diagnostic.tokensToDiagnostic(bin)) {
85
96
  console.log(line);
86
97
  }
87
98
  return;
88
99
  }
89
- case 'json2hex': {
100
+ case 'hex2json': {
101
+ const {argv, pretty} = argvPretty();
102
+ const bin = fromHex(argv.length < 4 ? (await fromStdin()).toString() : argv[3]);
103
+ return console.log(JSON.stringify(decode.decode(bin), undefined, pretty ? 2 : undefined));
104
+ }
105
+ case 'json2bin': {
90
106
  const inp = process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3];
91
107
  const obj = JSON.parse(inp);
92
- return console.log(byteUtils.toHex(encode.encode(obj)));
108
+ return process__default["default"].stdout.write(encode.encode(obj));
93
109
  }
94
110
  case 'json2diag': {
95
111
  const inp = process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3];
@@ -99,10 +115,10 @@ async function run() {
99
115
  }
100
116
  return;
101
117
  }
102
- case 'json2bin': {
118
+ case 'json2hex': {
103
119
  const inp = process__default["default"].argv.length < 4 ? (await fromStdin()).toString() : process__default["default"].argv[3];
104
120
  const obj = JSON.parse(inp);
105
- return process__default["default"].stdout.write(encode.encode(obj));
121
+ return console.log(byteUtils.toHex(encode.encode(obj)));
106
122
  }
107
123
  default: {
108
124
  if (process__default["default"].argv.findIndex(a => a.endsWith('mocha')) === -1) {
@@ -4,9 +4,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var decode = require('./decode.js');
6
6
  var byteUtils = require('./byte-utils.js');
7
+ var _0uint = require('./0uint.js');
7
8
 
9
+ const utf8Encoder = new TextEncoder();
10
+ const utf8Decoder = new TextDecoder();
8
11
  function* tokensToDiagnostic(inp, width = 100) {
9
- const tokeniser = new decode.Tokeniser(inp);
12
+ const tokeniser = new decode.Tokeniser(inp, { retainStringBytes: true });
10
13
  let pos = 0;
11
14
  const indent = [];
12
15
  const slc = (start, length) => {
@@ -17,6 +20,7 @@ function* tokensToDiagnostic(inp, width = 100) {
17
20
  let margin = ''.padStart(indent.length * 2, ' ');
18
21
  let vLength = token.encodedLength - 1;
19
22
  let v = String(token.value);
23
+ let outp = `${ margin }${ slc(0, 1) }`;
20
24
  const str = token.type.name === 'bytes' || token.type.name === 'string';
21
25
  if (token.type.name === 'string') {
22
26
  v = v.length;
@@ -25,7 +29,29 @@ function* tokensToDiagnostic(inp, width = 100) {
25
29
  v = token.value.length;
26
30
  vLength -= v;
27
31
  }
28
- let outp = `${ margin }${ slc(0, 1) } ${ slc(1, vLength) }`;
32
+ let multilen;
33
+ switch (token.type.name) {
34
+ case 'string':
35
+ case 'bytes':
36
+ case 'map':
37
+ case 'array':
38
+ multilen = token.type.name === 'string' ? utf8Encoder.encode(token.value).length : token.value.length;
39
+ if (multilen >= _0uint.uintBoundaries[0]) {
40
+ if (multilen < _0uint.uintBoundaries[1]) {
41
+ outp += ` ${ slc(1, 1) }`;
42
+ } else if (multilen < _0uint.uintBoundaries[2]) {
43
+ outp += ` ${ slc(1, 2) }`;
44
+ } else if (multilen < _0uint.uintBoundaries[3]) {
45
+ outp += ` ${ slc(1, 4) }`;
46
+ } else if (multilen < _0uint.uintBoundaries[4]) {
47
+ outp += ` ${ slc(1, 8) }`;
48
+ }
49
+ }
50
+ break;
51
+ default:
52
+ outp += ` ${ slc(1, vLength) }`;
53
+ break;
54
+ }
29
55
  outp = outp.padEnd(width / 2, ' ');
30
56
  outp += `# ${ margin }${ token.type.name }`;
31
57
  if (token.type.name !== v) {
@@ -33,15 +59,22 @@ function* tokensToDiagnostic(inp, width = 100) {
33
59
  }
34
60
  yield outp;
35
61
  if (str) {
62
+ let asString = token.type.name === 'string';
36
63
  margin += ' ';
37
- const repr = token.type.name === 'bytes' ? token.value : new TextEncoder().encode(token.value);
64
+ let repr = asString ? utf8Encoder.encode(token.value) : token.value;
65
+ if (asString && token.byteValue !== undefined) {
66
+ if (repr.length !== token.byteValue.length) {
67
+ repr = token.byteValue;
68
+ asString = false;
69
+ }
70
+ }
38
71
  const wh = (width / 2 - margin.length - 1) / 2;
39
72
  let snip = 0;
40
73
  while (repr.length - snip > 0) {
41
74
  const piece = repr.slice(snip, snip + wh);
42
75
  snip += piece.length;
43
- const st = token.type.name === 'string' ? new TextDecoder().decode(piece) : piece.reduce((p, c) => {
44
- if (c < 32 || c === 127) {
76
+ const st = asString ? utf8Decoder.decode(piece) : piece.reduce((p, c) => {
77
+ if (c < 32 || c >= 127 && c < 161 || c === 173) {
45
78
  return `${ p }\\x${ c.toString(16).padStart(2, '0') }`;
46
79
  }
47
80
  return `${ p }${ String.fromCharCode(c) }`;
@@ -73,5 +106,16 @@ function* tokensToDiagnostic(inp, width = 100) {
73
106
  pos += token.encodedLength;
74
107
  }
75
108
  }
109
+ function fromDiag(input) {
110
+ if (typeof input !== 'string') {
111
+ throw new TypeError('Expected string input');
112
+ }
113
+ input = input.replace(/#.*?$/mg, '').replace(/[\s\r\n]+/mg, '');
114
+ if (/[^a-f0-9]/i.test(input)) {
115
+ throw new TypeError('Input string was not CBOR diagnostic format');
116
+ }
117
+ return byteUtils.fromHex(input);
118
+ }
76
119
 
120
+ exports.fromDiag = fromDiag;
77
121
  exports.tokensToDiagnostic = tokensToDiagnostic;
package/cjs/lib/token.js CHANGED
@@ -35,6 +35,7 @@ class Token {
35
35
  this.value = value;
36
36
  this.encodedLength = encodedLength;
37
37
  this.encodedBytes = undefined;
38
+ this.byteValue = undefined;
38
39
  }
39
40
  toString() {
40
41
  return `Token[${ this.type }].${ this.value }`;
@@ -4,6 +4,7 @@ var chai = require('chai');
4
4
  var child_process = require('child_process');
5
5
  var process = require('process');
6
6
  var path = require('path');
7
+ var os = require('os');
7
8
  var url = require('url');
8
9
  require('../lib/bin.js');
9
10
 
@@ -14,6 +15,52 @@ var process__default = /*#__PURE__*/_interopDefaultLegacy(process);
14
15
  var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
15
16
 
16
17
  const {assert} = chai__default["default"];
18
+ const fixture1JsonString = '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}';
19
+ const fixture1JsonPrettyString = `{
20
+ "a": 1,
21
+ "b": [
22
+ 2,
23
+ 3
24
+ ],
25
+ "smile": "😀"
26
+ }
27
+ `;
28
+ const fixture1HexString = 'a3616101616282020365736d696c6564f09f9880';
29
+ const fixture1Bin = fromHex(fixture1HexString);
30
+ const fixture1BinString = new TextDecoder().decode(fixture1Bin);
31
+ const fixture1DiagnosticString = `a3 # map(3)
32
+ 61 # string(1)
33
+ 61 # "a"
34
+ 01 # uint(1)
35
+ 61 # string(1)
36
+ 62 # "b"
37
+ 82 # array(2)
38
+ 02 # uint(2)
39
+ 03 # uint(3)
40
+ 65 # string(5)
41
+ 736d696c65 # "smile"
42
+ 64 # string(2)
43
+ f09f9880 # "😀"
44
+ `;
45
+ const fixture2HexString = 'a4616101616282020363627566440102036165736d696c6564f09f9880';
46
+ const fixture2DiagnosticString = `a4 # map(4)
47
+ 61 # string(1)
48
+ 61 # "a"
49
+ 01 # uint(1)
50
+ 61 # string(1)
51
+ 62 # "b"
52
+ 82 # array(2)
53
+ 02 # uint(2)
54
+ 03 # uint(3)
55
+ 63 # string(3)
56
+ 627566 # "buf"
57
+ 44 # bytes(4)
58
+ 01020361 # "\\x01\\x02\\x03a"
59
+ 65 # string(5)
60
+ 736d696c65 # "smile"
61
+ 64 # string(2)
62
+ f09f9880 # "😀"
63
+ `;
17
64
  const binPath = path__default["default"].join(path__default["default"].dirname(url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('node-test/node-test-bin.js', document.baseURI).href)))), '../lib/bin.js');
18
65
  function fromHex(hex) {
19
66
  return new Uint8Array(hex.split('').map((c, i, d) => i % 2 === 0 ? `0x${ c }${ d[i + 1] }` : '').filter(Boolean).map(e => parseInt(e, 16)));
@@ -48,15 +95,18 @@ describe('Bin', () => {
48
95
  assert.strictEqual(e.stdout, '');
49
96
  assert.strictEqual(e.stderr, `Usage: cborg <command> <args>
50
97
  Valid commands:
51
- \thex2diag [hex input]
52
- \thex2bin [hex input]
53
- \thex2json [--pretty] [hex input]
54
- \tbin2hex [binary input]
55
98
  \tbin2diag [binary input]
99
+ \tbin2hex [binary input]
56
100
  \tbin2json [--pretty] [binary input]
57
- \tjson2hex '[json input]'
58
- \tjson2diag '[json input]'
101
+ \tdiag2bin [diagnostic input]
102
+ \tdiag2hex [diagnostic input]
103
+ \tdiag2json [--pretty] [diagnostic input]
104
+ \thex2bin [hex input]
105
+ \thex2diag [hex input]
106
+ \thex2json [--pretty] [hex input]
59
107
  \tjson2bin '[json input]'
108
+ \tjson2diag '[json input]'
109
+ \tjson2hex '[json input]'
60
110
  Input may either be supplied as an argument or piped via stdin
61
111
  `);
62
112
  }
@@ -70,15 +120,18 @@ Input may either be supplied as an argument or piped via stdin
70
120
  assert.strictEqual(e.stderr, `Unknown command: 'blip'
71
121
  Usage: cborg <command> <args>
72
122
  Valid commands:
73
- \thex2diag [hex input]
74
- \thex2bin [hex input]
75
- \thex2json [--pretty] [hex input]
76
- \tbin2hex [binary input]
77
123
  \tbin2diag [binary input]
124
+ \tbin2hex [binary input]
78
125
  \tbin2json [--pretty] [binary input]
79
- \tjson2hex '[json input]'
80
- \tjson2diag '[json input]'
126
+ \tdiag2bin [diagnostic input]
127
+ \tdiag2hex [diagnostic input]
128
+ \tdiag2json [--pretty] [diagnostic input]
129
+ \thex2bin [hex input]
130
+ \thex2diag [hex input]
131
+ \thex2json [--pretty] [hex input]
81
132
  \tjson2bin '[json input]'
133
+ \tjson2diag '[json input]'
134
+ \tjson2hex '[json input]'
82
135
  Input may either be supplied as an argument or piped via stdin
83
136
  `);
84
137
  }
@@ -88,137 +141,103 @@ Input may either be supplied as an argument or piped via stdin
88
141
  assert.strictEqual(stdout, '');
89
142
  assert.strictEqual(stderr, `Usage: cborg <command> <args>
90
143
  Valid commands:
91
- \thex2diag [hex input]
92
- \thex2bin [hex input]
93
- \thex2json [--pretty] [hex input]
94
- \tbin2hex [binary input]
95
144
  \tbin2diag [binary input]
145
+ \tbin2hex [binary input]
96
146
  \tbin2json [--pretty] [binary input]
97
- \tjson2hex '[json input]'
98
- \tjson2diag '[json input]'
147
+ \tdiag2bin [diagnostic input]
148
+ \tdiag2hex [diagnostic input]
149
+ \tdiag2json [--pretty] [diagnostic input]
150
+ \thex2bin [hex input]
151
+ \thex2diag [hex input]
152
+ \thex2json [--pretty] [hex input]
99
153
  \tjson2bin '[json input]'
154
+ \tjson2diag '[json input]'
155
+ \tjson2hex '[json input]'
100
156
  Input may either be supplied as an argument or piped via stdin
101
157
  `);
102
158
  });
159
+ it('bin2diag (stdin)', async () => {
160
+ const {stdout, stderr} = await execBin('bin2diag', fixture1Bin);
161
+ assert.strictEqual(stderr, '');
162
+ assert.strictEqual(stdout, fixture1DiagnosticString);
163
+ });
164
+ it('bin2hex (stdin)', async () => {
165
+ const {stdout, stderr} = await execBin('bin2hex', fixture1Bin);
166
+ assert.strictEqual(stderr, '');
167
+ assert.strictEqual(stdout, `${ fixture1HexString }\n`);
168
+ });
169
+ it('bin2json (stdin)', async () => {
170
+ const {stdout, stderr} = await execBin('bin2json', fixture1Bin);
171
+ assert.strictEqual(stderr, '');
172
+ assert.strictEqual(stdout, `${ fixture1JsonString }\n`);
173
+ });
174
+ it('bin2json pretty (stdin)', async () => {
175
+ const {stdout, stderr} = await execBin('bin2json --pretty', fixture1Bin);
176
+ assert.strictEqual(stderr, '');
177
+ assert.strictEqual(stdout, fixture1JsonPrettyString);
178
+ });
103
179
  for (const stdin of [
104
180
  true,
105
181
  false
106
182
  ]) {
107
- it(`hex2json${ stdin ? ' (stdin)' : '' }`, async () => {
108
- const {stdout, stderr} = stdin ? await execBin('hex2json a3616101616282020365736d696c6564f09f9880') : await execBin('hex2json', 'a3616101616282020365736d696c6564f09f9880');
109
- assert.strictEqual(stderr, '');
110
- assert.strictEqual(stdout, '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}\n');
111
- });
112
- it(`hex2json pretty${ stdin ? ' (stdin)' : '' }`, async () => {
113
- const {stdout, stderr} = stdin ? await execBin('hex2json --pretty a3616101616282020365736d696c6564f09f9880') : await execBin('hex2json --pretty', 'a3616101616282020365736d696c6564f09f9880');
183
+ if (os.platform() !== 'win32' || stdin) {
184
+ it(`diag2bin${ stdin ? ' (stdin)' : '' }`, async () => {
185
+ const {stdout, stderr} = !stdin ? await execBin(`diag2bin '${ fixture1DiagnosticString }'`) : await execBin('diag2bin', fixture1DiagnosticString);
186
+ assert.strictEqual(stderr, '');
187
+ assert.strictEqual(stdout, fixture1BinString);
188
+ });
189
+ it(`diag2hex${ stdin ? ' (stdin)' : '' }`, async () => {
190
+ const {stdout, stderr} = !stdin ? await execBin(`diag2hex '${ fixture1DiagnosticString }'`) : await execBin('diag2hex', fixture1DiagnosticString);
191
+ assert.strictEqual(stderr, '');
192
+ assert.strictEqual(stdout, `${ fixture1HexString }\n`);
193
+ });
194
+ it(`diag2json${ stdin ? ' (stdin)' : '' }`, async () => {
195
+ const {stdout, stderr} = !stdin ? await execBin(`diag2json '${ fixture1DiagnosticString }'`) : await execBin('diag2json', fixture1DiagnosticString);
196
+ assert.strictEqual(stderr, '');
197
+ assert.strictEqual(stdout, `${ fixture1JsonString }\n`);
198
+ });
199
+ it(`diag2json pretty${ stdin ? ' (stdin)' : '' }`, async () => {
200
+ const {stdout, stderr} = !stdin ? await execBin(`diag2json --pretty '${ fixture1DiagnosticString }'`) : await execBin('diag2json --pretty', fixture1DiagnosticString);
201
+ assert.strictEqual(stderr, '');
202
+ assert.strictEqual(stdout, fixture1JsonPrettyString);
203
+ });
204
+ }
205
+ it(`hex2bin${ stdin ? ' (stdin)' : '' }`, async () => {
206
+ const {stdout, stderr} = !stdin ? await execBin(`hex2bin ${ fixture1HexString }`) : await execBin('hex2bin', fixture1HexString);
114
207
  assert.strictEqual(stderr, '');
115
- assert.strictEqual(stdout, `{
116
- "a": 1,
117
- "b": [
118
- 2,
119
- 3
120
- ],
121
- "smile": "😀"
122
- }
123
- `);
208
+ assert.strictEqual(stdout, fixture1BinString);
124
209
  });
125
210
  it(`hex2diag${ stdin ? ' (stdin)' : '' }`, async () => {
126
- const {stdout, stderr} = stdin ? await execBin('hex2diag a4616101616282020363627566440102036165736d696c6564f09f9880') : await execBin('hex2diag', 'a4616101616282020363627566440102036165736d696c6564f09f9880');
211
+ const {stdout, stderr} = !stdin ? await execBin(`hex2diag ${ fixture2HexString }`) : await execBin('hex2diag', fixture2HexString);
127
212
  assert.strictEqual(stderr, '');
128
- assert.strictEqual(stdout, `a4 # map(4)
129
- 61 # string(1)
130
- 61 # "a"
131
- 01 # uint(1)
132
- 61 # string(1)
133
- 62 # "b"
134
- 82 # array(2)
135
- 02 # uint(2)
136
- 03 # uint(3)
137
- 63 # string(3)
138
- 627566 # "buf"
139
- 44 # bytes(4)
140
- 01020361 # "\\x01\\x02\\x03a"
141
- 65 # string(5)
142
- 736d696c65 # "smile"
143
- 64 f09f # string(2)
144
- f09f9880 # "😀"
145
- `);
213
+ assert.strictEqual(stdout, fixture2DiagnosticString);
146
214
  });
147
- it(`hex2bin${ stdin ? ' (stdin)' : '' }`, async () => {
148
- const {stdout, stderr} = stdin ? await execBin('hex2bin a3616101616282020365736d696c6564f09f9880') : await execBin('hex2bin', 'a3616101616282020365736d696c6564f09f9880');
215
+ it(`hex2json${ stdin ? ' (stdin)' : '' }`, async () => {
216
+ const {stdout, stderr} = !stdin ? await execBin(`hex2json ${ fixture1HexString }`) : await execBin('hex2json', fixture1HexString);
149
217
  assert.strictEqual(stderr, '');
150
- assert.strictEqual(stdout, new TextDecoder().decode(fromHex('a3616101616282020365736d696c6564f09f9880')));
218
+ assert.strictEqual(stdout, `${ fixture1JsonString }\n`);
151
219
  });
152
- it(`json2hex${ stdin ? ' (stdin)' : '' }`, async () => {
153
- const {stdout, stderr} = stdin ? await execBin('json2hex "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2hex', '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}');
220
+ it(`hex2json pretty${ stdin ? ' (stdin)' : '' }`, async () => {
221
+ const {stdout, stderr} = !stdin ? await execBin(`hex2json --pretty ${ fixture1HexString }`) : await execBin('hex2json --pretty', fixture1HexString);
154
222
  assert.strictEqual(stderr, '');
155
- assert.strictEqual(stdout, 'a3616101616282020365736d696c6564f09f9880\n');
223
+ assert.strictEqual(stdout, fixture1JsonPrettyString);
156
224
  });
157
225
  it(`json2bin${ stdin ? ' (stdin)' : '' }`, async () => {
158
- const {stdout, stderr} = stdin ? await execBin('json2bin "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2bin', '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}');
226
+ const {stdout, stderr} = !stdin ? await execBin('json2bin "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2bin', fixture1JsonString);
159
227
  assert.strictEqual(stderr, '');
160
- assert.strictEqual(stdout, new TextDecoder().decode(fromHex('a3616101616282020365736d696c6564f09f9880')));
228
+ assert.strictEqual(stdout, fixture1BinString);
161
229
  });
162
230
  it(`json2diag${ stdin ? ' (stdin)' : '' }`, async () => {
163
- const {stdout, stderr} = stdin ? await execBin('json2diag "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2diag', '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}');
231
+ const {stdout, stderr} = !stdin ? await execBin('json2diag "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2diag', fixture1JsonString);
164
232
  assert.strictEqual(stderr, '');
165
- assert.strictEqual(stdout, `a3 # map(3)
166
- 61 # string(1)
167
- 61 # "a"
168
- 01 # uint(1)
169
- 61 # string(1)
170
- 62 # "b"
171
- 82 # array(2)
172
- 02 # uint(2)
173
- 03 # uint(3)
174
- 65 # string(5)
175
- 736d696c65 # "smile"
176
- 64 f09f # string(2)
177
- f09f9880 # "😀"
178
- `);
233
+ assert.strictEqual(stdout, fixture1DiagnosticString);
234
+ });
235
+ it(`json2hex${ stdin ? ' (stdin)' : '' }`, async () => {
236
+ const {stdout, stderr} = !stdin ? await execBin(`json2hex "${ fixture1JsonString.replace(/"/g, '\\"') }"`) : await execBin('json2hex', fixture1JsonString);
237
+ assert.strictEqual(stderr, '');
238
+ assert.strictEqual(stdout, `${ fixture1HexString }\n`);
179
239
  });
180
240
  }
181
- it('bin2diag (stdin)', async () => {
182
- const {stdout, stderr} = await execBin('bin2diag', fromHex('a3616101616282020365736d696c6564f09f9880'));
183
- assert.strictEqual(stderr, '');
184
- assert.strictEqual(stdout, `a3 # map(3)
185
- 61 # string(1)
186
- 61 # "a"
187
- 01 # uint(1)
188
- 61 # string(1)
189
- 62 # "b"
190
- 82 # array(2)
191
- 02 # uint(2)
192
- 03 # uint(3)
193
- 65 # string(5)
194
- 736d696c65 # "smile"
195
- 64 f09f # string(2)
196
- f09f9880 # "😀"
197
- `);
198
- });
199
- it('bin2json (stdin)', async () => {
200
- const {stdout, stderr} = await execBin('bin2json', fromHex('a3616101616282020365736d696c6564f09f9880'));
201
- assert.strictEqual(stderr, '');
202
- assert.strictEqual(stdout, '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}\n');
203
- });
204
- it('bin2json pretty (stdin)', async () => {
205
- const {stdout, stderr} = await execBin('bin2json --pretty', fromHex('a3616101616282020365736d696c6564f09f9880'));
206
- assert.strictEqual(stderr, '');
207
- assert.strictEqual(stdout, `{
208
- "a": 1,
209
- "b": [
210
- 2,
211
- 3
212
- ],
213
- "smile": "😀"
214
- }
215
- `);
216
- });
217
- it('bin2hex (stdin)', async () => {
218
- const {stdout, stderr} = await execBin('bin2hex', fromHex('a3616101616282020365736d696c6564f09f9880'));
219
- assert.strictEqual(stderr, '');
220
- assert.strictEqual(stdout, 'a3616101616282020365736d696c6564f09f9880\n');
221
- });
222
241
  it('diag indenting', async () => {
223
242
  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}');
224
243
  assert.strictEqual(stderr, '');
@@ -277,4 +296,54 @@ Input may either be supplied as an argument or piped via stdin
277
296
  01 # uint(1)
278
297
  `);
279
298
  });
299
+ describe('diag length bytes', () => {
300
+ it('compact', async () => {
301
+ const {stdout, stderr} = await execBin('json2diag', '"aaaaaaaaaaaaaaaaaaaaaaa"');
302
+ assert.strictEqual(stderr, '');
303
+ assert.strictEqual(stdout, `77 # string(23)
304
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
305
+ `);
306
+ });
307
+ it('1-byte', async () => {
308
+ const {stdout, stderr} = await execBin('json2diag', '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"');
309
+ assert.strictEqual(stderr, '');
310
+ assert.strictEqual(stdout, `78 23 # string(35)
311
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
312
+ 616161616161616161616161 # "aaaaaaaaaaaa"
313
+ `);
314
+ });
315
+ it('2-byte', async () => {
316
+ const {stdout, stderr} = await execBin('json2diag', '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"');
317
+ assert.strictEqual(stderr, '');
318
+ assert.strictEqual(stdout, `79 0100 # string(256)
319
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
320
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
321
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
322
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
323
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
324
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
325
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
326
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
327
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
328
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
329
+ 6161616161616161616161616161616161616161616161 # "aaaaaaaaaaaaaaaaaaaaaaa"
330
+ 616161 # "aaa"
331
+ `);
332
+ });
333
+ });
334
+ it('diag non-utf8 and non-printable ascii', async () => {
335
+ const input = '7864f55ff8f12508b63ef2bfeca7557ae90df6311a5ec1631b4a1fa843310bd9c3a710eaace5a1bdd72ad0bfe049771c11e756338bd93865e645f1adec9b9c99ef407fbd4fc6859e7904c5ad7dc9bd10a5cc16973d5b28ec1a6dd43d9f82f9f18c3d03418e35';
336
+ let {stdout, stderr} = await execBin(`hex2diag ${ input }`);
337
+ assert.strictEqual(stderr, '');
338
+ assert.strictEqual(stdout, `78 64 # string(86)
339
+ f55ff8f12508b63ef2bfeca7557ae90df6311a5ec1631b # "õ_øñ%\\x08¶>ò¿ì§Uzé\\x0dö1\\x1a^Ác\\x1b"
340
+ 4a1fa843310bd9c3a710eaace5a1bdd72ad0bfe049771c # "J\\x1f¨C1\\x0bÙç\\x10ê¬å¡½×*пàIw\\x1c"
341
+ 11e756338bd93865e645f1adec9b9c99ef407fbd4fc685 # "\\x11çV3\\x8bÙ8eæEñ\\xadì\\x9b\\x9c\\x99ï@\\x7f½OÆ\\x85"
342
+ 9e7904c5ad7dc9bd10a5cc16973d5b28ec1a6dd43d9f82 # "\\x9ey\\x04Å\\xad}ɽ\\x10¥Ì\\x16\\x97=[(ì\\x1amÔ=\\x9f\\x82"
343
+ f9f18c3d03418e35 # "ùñ\\x8c=\\x03A\\x8e5"
344
+ `);
345
+ ({stdout, stderr} = await execBin('diag2hex', stdout));
346
+ assert.strictEqual(stderr, '');
347
+ assert.strictEqual(stdout, `${ input }\n`);
348
+ });
280
349
  });