Skip to content

Commit c1b3f86

Browse files
committed
test: string tests together
* Use promises and async/await to ensure that one test finishes before another one starts. This prevents errors thrown in one test from appearing to originate from another test. * Perform garbage collection consistently, via `testUtil.runGCTests()`, to ensure that it is performed correctly and that its results are awaited. PR-URL: nodejs/node-addon-api#773 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent e2890cf commit c1b3f86

26 files changed

+381
-323
lines changed

test/addon_data.js

+28-19
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,37 @@ const { spawn } = require('child_process');
55
const readline = require('readline');
66
const path = require('path');
77

8-
test(path.resolve(__dirname, `./build/${buildType}/binding.node`));
9-
test(path.resolve(__dirname, `./build/${buildType}/binding_noexcept.node`));
8+
module.exports =
9+
test(path.resolve(__dirname, `./build/${buildType}/binding.node`))
10+
.then(() =>
11+
test(path.resolve(__dirname,
12+
`./build/${buildType}/binding_noexcept.node`)));
1013

1114
// Make sure the instance data finalizer is called at process exit. If the hint
1215
// is non-zero, it will be printed out by the child process.
1316
function testFinalizer(bindingName, hint, expected) {
14-
bindingName = bindingName.split('\\').join('\\\\');
15-
const child = spawn(process.execPath, [
16-
'-e',
17-
`require('${bindingName}').addon_data(${hint}).verbose = true;`
18-
]);
19-
const actual = [];
20-
readline
21-
.createInterface({ input: child.stderr })
22-
.on('line', (line) => {
23-
if (expected.indexOf(line) >= 0) {
24-
actual.push(line);
25-
}
26-
})
27-
.on('close', () => assert.deepStrictEqual(expected, actual));
17+
return new Promise((resolve) => {
18+
bindingName = bindingName.split('\\').join('\\\\');
19+
const child = spawn(process.execPath, [
20+
'-e',
21+
`require('${bindingName}').addon_data(${hint}).verbose = true;`
22+
]);
23+
const actual = [];
24+
readline
25+
.createInterface({ input: child.stderr })
26+
.on('line', (line) => {
27+
if (expected.indexOf(line) >= 0) {
28+
actual.push(line);
29+
}
30+
})
31+
.on('close', () => {
32+
assert.deepStrictEqual(expected, actual);
33+
resolve();
34+
});
35+
});
2836
}
2937

30-
function test(bindingName) {
38+
async function test(bindingName) {
3139
const binding = require(bindingName).addon_data(0);
3240

3341
// Make sure it is possible to get/set instance data.
@@ -37,6 +45,7 @@ function test(bindingName) {
3745
binding.verbose = false;
3846
assert.strictEqual(binding.verbose.verbose, false);
3947

40-
testFinalizer(bindingName, 0, ['addon_data: Addon::~Addon']);
41-
testFinalizer(bindingName, 42, ['addon_data: Addon::~Addon', 'hint: 42']);
48+
await testFinalizer(bindingName, 0, ['addon_data: Addon::~Addon']);
49+
await testFinalizer(bindingName, 42,
50+
['addon_data: Addon::~Addon', 'hint: 42']);
4251
}

test/arraybuffer.js

+9-19
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ const buildType = process.config.target_defaults.default_configuration;
33
const assert = require('assert');
44
const testUtil = require('./testUtil');
55

6-
test(require(`./build/${buildType}/binding.node`));
7-
test(require(`./build/${buildType}/binding_noexcept.node`));
6+
module.exports = test(require(`./build/${buildType}/binding.node`))
7+
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
88

99
function test(binding) {
10-
testUtil.runGCTests([
10+
return testUtil.runGCTests([
1111
'Internal ArrayBuffer',
1212
() => {
1313
const test = binding.arraybuffer.createBuffer();
@@ -25,10 +25,8 @@ function test(binding) {
2525
assert.ok(test instanceof ArrayBuffer);
2626
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
2727
},
28-
() => {
29-
global.gc();
30-
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
31-
},
28+
29+
() => assert.strictEqual(0, binding.arraybuffer.getFinalizeCount()),
3230

3331
'External ArrayBuffer with finalizer',
3432
() => {
@@ -37,12 +35,8 @@ function test(binding) {
3735
assert.ok(test instanceof ArrayBuffer);
3836
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
3937
},
40-
() => {
41-
global.gc();
42-
},
43-
() => {
44-
assert.strictEqual(1, binding.arraybuffer.getFinalizeCount());
45-
},
38+
39+
() => assert.strictEqual(1, binding.arraybuffer.getFinalizeCount()),
4640

4741
'External ArrayBuffer with finalizer hint',
4842
() => {
@@ -51,12 +45,8 @@ function test(binding) {
5145
assert.ok(test instanceof ArrayBuffer);
5246
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
5347
},
54-
() => {
55-
global.gc();
56-
},
57-
() => {
58-
assert.strictEqual(1, binding.arraybuffer.getFinalizeCount());
59-
},
48+
49+
() => assert.strictEqual(1, binding.arraybuffer.getFinalizeCount()),
6050

6151
'ArrayBuffer with constructor',
6252
() => {

test/asyncprogressqueueworker.cc

-9
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,6 @@ class TestWorker : public AsyncProgressQueueWorker<ProgressData> {
3737
worker->Queue();
3838
}
3939

40-
static void CancelWork(const CallbackInfo& info) {
41-
auto wrap = info[0].As<Napi::External<TestWorker>>();
42-
auto worker = wrap.Data();
43-
// We cannot cancel a worker if it got started. So we have to do a quick cancel.
44-
worker->Queue();
45-
worker->Cancel();
46-
}
47-
4840
protected:
4941
void Execute(const ExecutionProgress& progress) override {
5042
using namespace std::chrono_literals;
@@ -89,7 +81,6 @@ Object InitAsyncProgressQueueWorker(Env env) {
8981
Object exports = Object::New(env);
9082
exports["createWork"] = Function::New(env, TestWorker::CreateWork);
9183
exports["queueWork"] = Function::New(env, TestWorker::QueueWork);
92-
exports["cancelWork"] = Function::New(env, TestWorker::CancelWork);
9384
return exports;
9485
}
9586

test/asyncprogressqueueworker.js

+33-48
Original file line numberDiff line numberDiff line change
@@ -4,60 +4,45 @@ const common = require('./common')
44
const assert = require('assert');
55
const os = require('os');
66

7-
test(require(`./build/${buildType}/binding.node`));
8-
test(require(`./build/${buildType}/binding_noexcept.node`));
7+
module.exports = test(require(`./build/${buildType}/binding.node`))
8+
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
99

10-
function test({ asyncprogressqueueworker }) {
11-
success(asyncprogressqueueworker);
12-
fail(asyncprogressqueueworker);
13-
cancel(asyncprogressqueueworker);
14-
return;
10+
async function test({ asyncprogressqueueworker }) {
11+
await success(asyncprogressqueueworker);
12+
await fail(asyncprogressqueueworker);
1513
}
1614

1715
function success(binding) {
18-
const expected = [0, 1, 2, 3];
19-
const actual = [];
20-
const worker = binding.createWork(expected.length,
21-
common.mustCall((err) => {
22-
if (err) {
23-
assert.fail(err);
24-
}
25-
// All queued items shall be invoked before complete callback.
26-
assert.deepEqual(actual, expected);
27-
}),
28-
common.mustCall((_progress) => {
29-
actual.push(_progress);
30-
}, expected.length)
31-
);
32-
binding.queueWork(worker);
16+
return new Promise((resolve, reject) => {
17+
const expected = [0, 1, 2, 3];
18+
const actual = [];
19+
const worker = binding.createWork(expected.length,
20+
common.mustCall((err) => {
21+
if (err) {
22+
reject(err);
23+
} else {
24+
// All queued items shall be invoked before complete callback.
25+
assert.deepEqual(actual, expected);
26+
resolve();
27+
}
28+
}),
29+
common.mustCall((_progress) => {
30+
actual.push(_progress);
31+
}, expected.length)
32+
);
33+
binding.queueWork(worker);
34+
});
3335
}
3436

3537
function fail(binding) {
36-
const worker = binding.createWork(-1,
37-
common.mustCall((err) => {
38-
assert.throws(() => { throw err }, /test error/)
39-
}),
40-
() => {
41-
assert.fail('unexpected progress report');
42-
}
43-
);
44-
binding.queueWork(worker);
45-
}
46-
47-
function cancel(binding) {
48-
// make sure the work we are going to cancel will not be
49-
// able to start by using all the threads in the pool.
50-
for (let i = 0; i < os.cpus().length; ++i) {
51-
const worker = binding.createWork(-1, () => {}, () => {});
38+
return new Promise((resolve, reject) => {
39+
const worker = binding.createWork(-1,
40+
common.mustCall((err) => {
41+
assert.throws(() => { throw err }, /test error/);
42+
resolve();
43+
}),
44+
common.mustNotCall()
45+
);
5246
binding.queueWork(worker);
53-
}
54-
const worker = binding.createWork(-1,
55-
() => {
56-
assert.fail('unexpected callback');
57-
},
58-
() => {
59-
assert.fail('unexpected progress report');
60-
}
61-
);
62-
binding.cancelWork(worker);
47+
});
6348
}

test/asyncprogressworker.js

+32-29
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,43 @@ const buildType = process.config.target_defaults.default_configuration;
33
const common = require('./common')
44
const assert = require('assert');
55

6-
test(require(`./build/${buildType}/binding.node`));
7-
test(require(`./build/${buildType}/binding_noexcept.node`));
6+
module.exports = test(require(`./build/${buildType}/binding.node`))
7+
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
88

9-
function test({ asyncprogressworker }) {
10-
success(asyncprogressworker);
11-
fail(asyncprogressworker);
12-
return;
9+
async function test({ asyncprogressworker }) {
10+
await success(asyncprogressworker);
11+
await fail(asyncprogressworker);
1312
}
1413

1514
function success(binding) {
16-
const expected = [0, 1, 2, 3];
17-
const actual = [];
18-
binding.doWork(expected.length,
19-
common.mustCall((err) => {
20-
if (err) {
21-
assert.fail(err);
22-
}
23-
}),
24-
common.mustCall((_progress) => {
25-
actual.push(_progress);
26-
if (actual.length === expected.length) {
27-
assert.deepEqual(actual, expected);
28-
}
29-
}, expected.length)
30-
);
15+
return new Promise((resolve, reject) => {
16+
const expected = [0, 1, 2, 3];
17+
const actual = [];
18+
binding.doWork(expected.length,
19+
common.mustCall((err) => {
20+
if (err) {
21+
reject(err);
22+
}
23+
}),
24+
common.mustCall((_progress) => {
25+
actual.push(_progress);
26+
if (actual.length === expected.length) {
27+
assert.deepEqual(actual, expected);
28+
resolve();
29+
}
30+
}, expected.length)
31+
);
32+
});
3133
}
3234

3335
function fail(binding) {
34-
binding.doWork(-1,
35-
common.mustCall((err) => {
36-
assert.throws(() => { throw err }, /test error/)
37-
}),
38-
() => {
39-
assert.fail('unexpected progress report');
40-
}
41-
);
36+
return new Promise((resolve) => {
37+
binding.doWork(-1,
38+
common.mustCall((err) => {
39+
assert.throws(() => { throw err }, /test error/)
40+
resolve();
41+
}),
42+
common.mustNotCall()
43+
);
44+
});
4245
}

test/asyncworker-nocallback.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
const buildType = process.config.target_defaults.default_configuration;
33
const common = require('./common');
44

5-
test(require(`./build/${buildType}/binding.node`));
6-
test(require(`./build/${buildType}/binding_noexcept.node`));
5+
module.exports = test(require(`./build/${buildType}/binding.node`))
6+
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
77

8-
function test(binding) {
9-
const resolving = binding.asyncworker.doWorkNoCallback(true, {});
10-
resolving.then(common.mustCall()).catch(common.mustNotCall());
8+
async function test(binding) {
9+
await binding.asyncworker.doWorkNoCallback(true, {})
10+
.then(common.mustCall()).catch(common.mustNotCall());
1111

12-
const rejecting = binding.asyncworker.doWorkNoCallback(false, {});
13-
rejecting.then(common.mustNotCall()).catch(common.mustCall());
14-
return;
15-
}
12+
await binding.asyncworker.doWorkNoCallback(false, {})
13+
.then(common.mustNotCall()).catch(common.mustCall());
14+
}

test/asyncworker-persistent.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function test(binding, succeed) {
2121
}));
2222
}
2323

24-
test(binding.persistentasyncworker, false)
24+
module.exports = test(binding.persistentasyncworker, false)
2525
.then(() => test(binding.persistentasyncworker, true))
2626
.then(() => test(noexceptBinding.persistentasyncworker, false))
2727
.then(() => test(noexceptBinding.persistentasyncworker, true));

0 commit comments

Comments
 (0)