-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
Expand file tree
/
Copy pathtest-runner-v8-deserializer.mjs
More file actions
128 lines (111 loc) Β· 4.77 KB
/
test-runner-v8-deserializer.mjs
File metadata and controls
128 lines (111 loc) Β· 4.77 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
// Flags: --expose-internals --no-warnings
import * as common from '../common/index.mjs';
import { describe, it, beforeEach } from 'node:test';
import assert from 'node:assert';
import { finished } from 'node:stream/promises';
import { DefaultSerializer } from 'node:v8';
import serializer from 'internal/test_runner/reporter/v8-serializer';
import runner from 'internal/test_runner/runner';
class ExtendedArray extends Array {}
async function toArray(chunks) {
const arr = [];
for await (const i of chunks) arr.push(i);
return arr;
}
const chunks = await toArray(serializer([
{ type: 'test:diagnostic', data: { nesting: 0, details: {}, message: 'diagnostic' } },
]));
const defaultSerializer = new DefaultSerializer();
defaultSerializer.writeHeader();
const headerLength = defaultSerializer.releaseBuffer().length;
describe('v8 deserializer', common.mustCall(() => {
let fileTest;
let reported;
beforeEach(common.mustCallAtLeast(() => {
reported = [];
fileTest = new runner.FileTest({
name: 'filetest',
harness: { config: {} },
});
fileTest.reporter.on('data', (data) => reported.push(data));
assert(fileTest.isClearToSend());
}));
async function collectReported(chunks) {
chunks.forEach((chunk) => fileTest.parseMessage(chunk));
fileTest.drain();
fileTest.reporter.end();
await finished(fileTest.reporter);
return reported;
}
it('should do nothing when no chunks', async () => {
const reported = await collectReported([]);
assert.deepStrictEqual(reported, []);
});
it('should deserialize a chunk with no serialization', async () => {
const reported = await collectReported([Buffer.from('unknown')]);
assert.deepStrictEqual(reported, [
{ data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' },
]);
});
it('should deserialize a serialized chunk', async () => {
const reported = await collectReported(chunks);
assert.deepStrictEqual(reported, [
{ data: { nesting: 0, details: {}, message: 'diagnostic' }, type: 'test:diagnostic' },
]);
});
it('should deserialize a serialized chunk after non-serialized chunk', async () => {
const reported = await collectReported([Buffer.concat([Buffer.from('unknown'), ...chunks])]);
assert.deepStrictEqual(reported, [
{ data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' },
{ data: { nesting: 0, details: {}, message: 'diagnostic' }, type: 'test:diagnostic' },
]);
});
it('should deserialize a serialized chunk before non-serialized output', async () => {
const reported = await collectReported([Buffer.concat([ ...chunks, Buffer.from('unknown')])]);
assert.deepStrictEqual(reported, [
{ data: { nesting: 0, details: {}, message: 'diagnostic' }, type: 'test:diagnostic' },
{ data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' },
]);
});
it('should restore assertion metadata without leaking internal transport fields', async () => {
let assertionError;
try {
assert.deepStrictEqual(new ExtendedArray('hello'), ['hello']);
} catch (error) {
assertionError = error;
}
assert(assertionError);
const [chunk] = await toArray(serializer([{
type: 'test:diagnostic',
data: { nesting: 0, details: { error: assertionError }, message: 'diagnostic' },
}]));
const reported = await collectReported([chunk]);
const detailError = reported[0].data.details.error;
assert.strictEqual(detailError.actual.constructor.name, 'ExtendedArray');
assert.strictEqual(Object.hasOwn(reported[0].data.details, 'assertionPrototypeMetadata'), false);
});
const headerPosition = headerLength * 2 + 4;
for (let i = 0; i < headerPosition + 5; i++) {
const message = `should deserialize a serialized message split into two chunks {...${i},${i + 1}...}`;
it(message, async () => {
const data = chunks[0];
const reported = await collectReported([data.subarray(0, i), data.subarray(i)]);
assert.deepStrictEqual(reported, [
{ data: { nesting: 0, details: {}, message: 'diagnostic' }, type: 'test:diagnostic' },
]);
});
it(`${message} wrapped by non-serialized data`, async () => {
const data = chunks[0];
const reported = await collectReported([
Buffer.concat([Buffer.from('unknown'), data.subarray(0, i)]),
Buffer.concat([data.subarray(i), Buffer.from('unknown')]),
]);
assert.deepStrictEqual(reported, [
{ data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' },
{ data: { nesting: 0, details: {}, message: 'diagnostic' }, type: 'test:diagnostic' },
{ data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' },
]);
}
);
}
}));