-
Notifications
You must be signed in to change notification settings - Fork 176
Expand file tree
/
Copy pathmsgpack-test-suite.test.ts
More file actions
129 lines (119 loc) · 3.89 KB
/
msgpack-test-suite.test.ts
File metadata and controls
129 lines (119 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import assert from "assert";
import util from "util";
import { Exam } from "msgpack-test-js";
import { MsgTimestamp } from "msg-timestamp";
import {
encode,
decode,
ExtensionCodec,
EXT_TIMESTAMP,
encodeTimeSpecToTimestamp,
__WASM_AVAILABLE,
} from "@msgpack/msgpack";
// eslint-disable-next-line no-console
console.log("# configuration", { __WASM_AVAILABLE });
const extensionCodec = new ExtensionCodec();
extensionCodec.register({
type: EXT_TIMESTAMP,
encode: (input) => {
if (input instanceof MsgTimestamp) {
return encodeTimeSpecToTimestamp({
sec: input.getTime(),
nsec: input.getNano(),
});
} else {
return null;
}
},
decode: (data: Uint8Array) => {
return MsgTimestamp.parse(Buffer.from(data));
},
});
const TEST_TYPES = {
array: 1,
bignum: 0, // TODO
binary: 1,
bool: 1,
map: 1,
nil: 1,
number: 1,
string: 1,
timestamp: 1,
};
describe("msgpack-test-suite", () => {
Exam.getExams(TEST_TYPES).forEach((exam) => {
const types = exam.getTypes(TEST_TYPES);
const first = types[0];
const title = `${first}: ${exam.stringify(first)}`;
it(`encodes ${title}`, () => {
types.forEach((type) => {
const value = exam.getValue(type);
const buffer = Buffer.from(encode(value, { extensionCodec }));
if (exam.matchMsgpack(buffer)) {
assert(true, exam.stringify(type));
} else {
const msg = `encode(${util.inspect(value)}): expect ${util.inspect(buffer)} to be one of ${util.inspect(
exam.getMsgpacks(),
)}`;
assert(false, msg);
}
});
});
it(`decodes ${title}`, () => {
const msgpacks = exam.getMsgpacks();
msgpacks.forEach((encoded, idx) => {
const value = decode(encoded, { extensionCodec });
if (exam.matchValue(value)) {
assert(true, exam.stringify(idx));
} else {
const values = exam.getTypes().map((type) => exam.getValue(type));
const msg = `decode(${util.inspect(encoded)}): expect ${util.inspect(value)} to be one of ${util.inspect(
values,
)}`;
assert(false, msg);
}
});
});
});
context("specs not covered by msgpack-test-js", () => {
// by detecting test coverage
const SPECS = {
FLOAT64_POSITIVE_INF: Number.POSITIVE_INFINITY,
FLOAT64_NEGATIVE_INF: Number.NEGATIVE_INFINITY,
FLOAT64_NAN: Number.NaN,
STR16: "a".repeat(0x100),
STR16_MBS: "🌏".repeat(0x100),
STR32: "b".repeat(0x10_000),
STR32_MBS: "🍣".repeat(0x10_000),
STR32LARGE: "c".repeat(0x50_000), // may cause "RangeError: Maximum call stack size exceeded" in simple implelementions
STR_INCLUDING_NUL: "foo\0bar\0",
STR_BROKEN_FF: "\xff",
BIN16: new Uint8Array(0x100).fill(0xff),
BIN32: new Uint8Array(0x10_000).fill(0xff),
BIN32LARGE: new Uint8Array(0x50_000).fill(0xff), // regression: caused "RangeError: Maximum call stack size exceeded"
ARRAY16: new Array<boolean>(0x100).fill(true),
ARRAY32: new Array<boolean>(0x10000).fill(true),
MAP16: new Array<null>(0x100).fill(null).reduce<Record<string, number>>((acc, _val, i) => {
acc[`k${i}`] = i;
return acc;
}, {}),
MAP32: new Array<null>(0x10000).fill(null).reduce<Record<string, number>>((acc, _val, i) => {
acc[`k${i}`] = i;
return acc;
}, {}),
MIXED: new Array(0x10).fill(Number.MAX_SAFE_INTEGER),
} as Record<string, any>;
for (const name of Object.keys(SPECS)) {
const value = SPECS[name];
it(`encodes and decodes ${name}`, () => {
const encoded = encode(value);
assert.deepStrictEqual(decode(new Uint8Array(encoded)), value);
});
}
});
describe("encoding in minimum values", () => {
it("int 8", () => {
assert.deepStrictEqual(encode(-128), Uint8Array.from([0xd0, 0x80]));
});
});
});