Skip to content

Commit e4f6030

Browse files
authored
Make tests work on all Node versions (#44)
- Make GC tests (arraybuffer, buffer, external) async, to account for different GC behavior with different versions of V8 and ChakraCore, similar to nodejs/node#13121 - In test/index.js, use the --napi-modules and --expose-gc command-line flags automatically. - Add missing entry for object tests in index.js. - Remove check for writable attribute on accessor property descriptors; it should not be there according to the JS spec. - Remove the explicit dependency on node-gyp in package.json. (NPM carries its own copy of node-gyp.) - Fix improper rethrow of an Error caught by reference that caused a double napi_ref delete, which failed in release builds of Node-ChakraCore.
1 parent bc683eb commit e4f6030

File tree

11 files changed

+201
-96
lines changed

11 files changed

+201
-96
lines changed

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
],
1616
"dependencies": {},
1717
"description": "Node.js API (N-API)",
18-
"devDependencies": {
19-
"node-gyp": "^3.6.0"
20-
},
18+
"devDependencies": {},
2119
"directories": {},
2220
"homepage": "https://github.com/nodejs/node-addon-api",
2321
"license": "MIT",
@@ -31,7 +29,7 @@
3129
},
3230
"scripts": {
3331
"pretest": "node-gyp rebuild -C test",
34-
"test": "node --expose-gc test"
32+
"test": "node test"
3533
},
3634
"version": "0.3.0"
3735
}

test/arraybuffer.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Value CreateBuffer(const CallbackInfo& info) {
3535
}
3636

3737
Value CreateExternalBuffer(const CallbackInfo& info) {
38+
finalizeCount = 0;
39+
3840
ArrayBuffer buffer = ArrayBuffer::New(info.Env(), testData, testLength);
3941

4042
if (buffer.ByteLength() != testLength) {
@@ -50,6 +52,8 @@ Value CreateExternalBuffer(const CallbackInfo& info) {
5052
}
5153

5254
Value CreateExternalBufferWithFinalize(const CallbackInfo& info) {
55+
finalizeCount = 0;
56+
5357
uint8_t* data = new uint8_t[testLength];
5458

5559
ArrayBuffer buffer = ArrayBuffer::New(
@@ -74,6 +78,8 @@ Value CreateExternalBufferWithFinalize(const CallbackInfo& info) {
7478
}
7579

7680
Value CreateExternalBufferWithFinalizeHint(const CallbackInfo& info) {
81+
finalizeCount = 0;
82+
7783
uint8_t* data = new uint8_t[testLength];
7884

7985
char* hint = nullptr;

test/arraybuffer.js

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,52 @@
22
const buildType = process.config.target_defaults.default_configuration;
33
const binding = require(`./build/${buildType}/binding.node`);
44
const assert = require('assert');
5+
const testUtil = require('./testUtil');
56

6-
let test = binding.arraybuffer.createBuffer();
7-
binding.arraybuffer.checkBuffer(test);
8-
assert.ok(test instanceof ArrayBuffer);
7+
testUtil.runGCTests([
8+
'Internal ArrayBuffer',
9+
() => {
10+
const test = binding.arraybuffer.createBuffer();
11+
binding.arraybuffer.checkBuffer(test);
12+
assert.ok(test instanceof ArrayBuffer);
913

10-
let test2 = test.slice(0);
11-
binding.arraybuffer.checkBuffer(test2);
14+
const test2 = test.slice(0);
15+
binding.arraybuffer.checkBuffer(test2);
16+
},
1217

13-
test = binding.arraybuffer.createExternalBuffer();
14-
binding.arraybuffer.checkBuffer(test);
15-
assert.ok(test instanceof ArrayBuffer);
18+
'External ArrayBuffer',
19+
() => {
20+
const test = binding.arraybuffer.createExternalBuffer();
21+
binding.arraybuffer.checkBuffer(test);
22+
assert.ok(test instanceof ArrayBuffer);
23+
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
24+
},
25+
() => {
26+
global.gc();
27+
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
28+
},
1629

17-
test = binding.arraybuffer.createExternalBufferWithFinalize();
18-
binding.arraybuffer.checkBuffer(test);
19-
assert.ok(test instanceof ArrayBuffer);
20-
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
21-
test = null;
22-
global.gc();
23-
assert.strictEqual(1, binding.arraybuffer.getFinalizeCount());
30+
'External ArrayBuffer with finalizer',
31+
() => {
32+
const test = binding.arraybuffer.createExternalBufferWithFinalize();
33+
binding.arraybuffer.checkBuffer(test);
34+
assert.ok(test instanceof ArrayBuffer);
35+
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
36+
},
37+
() => {
38+
global.gc();
39+
assert.strictEqual(1, binding.arraybuffer.getFinalizeCount());
40+
},
2441

25-
test = binding.arraybuffer.createExternalBufferWithFinalizeHint();
26-
binding.arraybuffer.checkBuffer(test);
27-
assert.ok(test instanceof ArrayBuffer);
28-
assert.strictEqual(1, binding.arraybuffer.getFinalizeCount());
29-
test = null;
30-
global.gc();
31-
assert.strictEqual(2, binding.arraybuffer.getFinalizeCount());
42+
'External ArrayBuffer with finalizer hint',
43+
() => {
44+
const test = binding.arraybuffer.createExternalBufferWithFinalizeHint();
45+
binding.arraybuffer.checkBuffer(test);
46+
assert.ok(test instanceof ArrayBuffer);
47+
assert.strictEqual(0, binding.arraybuffer.getFinalizeCount());
48+
},
49+
() => {
50+
global.gc();
51+
assert.strictEqual(1, binding.arraybuffer.getFinalizeCount());
52+
},
53+
]);

test/buffer.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Value CreateBuffer(const CallbackInfo& info) {
3737
}
3838

3939
Value CreateExternalBuffer(const CallbackInfo& info) {
40+
finalizeCount = 0;
41+
4042
Buffer<uint16_t> buffer = Buffer<uint16_t>::New(
4143
info.Env(),
4244
testData,
@@ -55,6 +57,8 @@ Value CreateExternalBuffer(const CallbackInfo& info) {
5557
}
5658

5759
Value CreateExternalBufferWithFinalize(const CallbackInfo& info) {
60+
finalizeCount = 0;
61+
5862
uint16_t* data = new uint16_t[testLength];
5963

6064
Buffer<uint16_t> buffer = Buffer<uint16_t>::New(
@@ -79,6 +83,8 @@ Value CreateExternalBufferWithFinalize(const CallbackInfo& info) {
7983
}
8084

8185
Value CreateExternalBufferWithFinalizeHint(const CallbackInfo& info) {
86+
finalizeCount = 0;
87+
8288
uint16_t* data = new uint16_t[testLength];
8389

8490
char* hint = nullptr;

test/buffer.js

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,60 @@
22
const buildType = process.config.target_defaults.default_configuration;
33
const binding = require(`./build/${buildType}/binding.node`);
44
const assert = require('assert');
5+
const testUtil = require('./testUtil');
56

6-
let test = binding.buffer.createBuffer();
7-
binding.buffer.checkBuffer(test);
8-
assert.ok(test instanceof Buffer);
7+
testUtil.runGCTests([
8+
'Internal Buffer',
9+
() => {
10+
const test = binding.buffer.createBuffer();
11+
binding.buffer.checkBuffer(test);
12+
assert.ok(test instanceof Buffer);
913

10-
let test2 = Buffer.alloc(test.length);
11-
test.copy(test2);
12-
binding.buffer.checkBuffer(test2);
14+
const test2 = Buffer.alloc(test.length);
15+
test.copy(test2);
16+
binding.buffer.checkBuffer(test2);
17+
},
1318

14-
test = binding.buffer.createBufferCopy();
15-
binding.buffer.checkBuffer(test);
16-
assert.ok(test instanceof Buffer);
19+
'Buffer copy',
20+
() => {
21+
const test = binding.buffer.createBufferCopy();
22+
binding.buffer.checkBuffer(test);
23+
assert.ok(test instanceof Buffer);
24+
},
1725

18-
test = binding.buffer.createExternalBuffer();
19-
binding.buffer.checkBuffer(test);
20-
assert.ok(test instanceof Buffer);
26+
'External Buffer',
27+
() => {
28+
const test = binding.buffer.createExternalBuffer();
29+
binding.buffer.checkBuffer(test);
30+
assert.ok(test instanceof Buffer);
31+
assert.strictEqual(0, binding.buffer.getFinalizeCount());
32+
},
33+
() => {
34+
global.gc();
35+
assert.strictEqual(0, binding.buffer.getFinalizeCount());
36+
},
2137

22-
test = binding.buffer.createExternalBufferWithFinalize();
23-
binding.buffer.checkBuffer(test);
24-
assert.ok(test instanceof Buffer);
25-
assert.strictEqual(0, binding.buffer.getFinalizeCount());
26-
test = null;
27-
global.gc();
28-
assert.strictEqual(1, binding.buffer.getFinalizeCount());
38+
'External Buffer with finalizer',
39+
() => {
40+
const test = binding.buffer.createExternalBufferWithFinalize();
41+
binding.buffer.checkBuffer(test);
42+
assert.ok(test instanceof Buffer);
43+
assert.strictEqual(0, binding.buffer.getFinalizeCount());
44+
},
45+
() => {
46+
global.gc();
47+
assert.strictEqual(1, binding.buffer.getFinalizeCount());
48+
},
2949

30-
test = binding.buffer.createExternalBufferWithFinalizeHint();
31-
binding.buffer.checkBuffer(test);
32-
assert.ok(test instanceof Buffer);
33-
assert.strictEqual(1, binding.buffer.getFinalizeCount());
34-
test = null;
35-
global.gc();
36-
assert.strictEqual(2, binding.buffer.getFinalizeCount());
50+
'External Buffer with finalizer hint',
51+
() => {
52+
const test = binding.buffer.createExternalBufferWithFinalizeHint();
53+
binding.buffer.checkBuffer(test);
54+
assert.ok(test instanceof Buffer);
55+
assert.strictEqual(0, binding.buffer.getFinalizeCount());
56+
},
57+
() => {
58+
global.gc();
59+
assert.strictEqual(1, binding.buffer.getFinalizeCount());
60+
},
61+
]);

test/error.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void CatchAndRethrowError(const CallbackInfo& info) {
5151
thrower({});
5252
} catch (Error& e) {
5353
e.Set("caught", Boolean::New(info.Env(), true));
54-
throw e;
54+
throw;
5555
}
5656
}
5757

@@ -68,7 +68,7 @@ void CatchAndRethrowErrorThatEscapesScope(const CallbackInfo& info) {
6868
ThrowErrorThatEscapesScope(info);
6969
} catch (Error& e) {
7070
e.Set("caught", Boolean::New(info.Env(), true));
71-
throw e;
71+
throw;
7272
}
7373
}
7474

test/external.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ int testData = 1;
88
int finalizeCount = 0;
99

1010
Value CreateExternal(const CallbackInfo& info) {
11+
finalizeCount = 0;
1112
return External<int>::New(info.Env(), &testData);
1213
}
1314

1415
Value CreateExternalWithFinalize(const CallbackInfo& info) {
16+
finalizeCount = 0;
1517
return External<int>::New(info.Env(), new int(1),
1618
[](Env env, int* data) {
1719
delete data;
@@ -20,6 +22,7 @@ Value CreateExternalWithFinalize(const CallbackInfo& info) {
2022
}
2123

2224
Value CreateExternalWithFinalizeHint(const CallbackInfo& info) {
25+
finalizeCount = 0;
2326
char* hint = nullptr;
2427
return External<int>::New(info.Env(), new int(1),
2528
[](Env env, int* data, char* hint) {

test/external.js

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,39 @@
22
const buildType = process.config.target_defaults.default_configuration;
33
const binding = require(`./build/${buildType}/binding.node`);
44
const assert = require('assert');
5+
const testUtil = require('./testUtil');
56

6-
assert.strictEqual(0, binding.external.getFinalizeCount());
7+
testUtil.runGCTests([
8+
'External without finalizer',
9+
() => {
10+
const test = binding.external.createExternal();
11+
assert.strictEqual(typeof test, 'object');
12+
binding.external.checkExternal(test);
13+
assert.strictEqual(0, binding.external.getFinalizeCount());
14+
},
15+
() => {
16+
assert.strictEqual(0, binding.external.getFinalizeCount());
17+
},
718

8-
let test = binding.external.createExternal();
9-
assert.strictEqual(typeof test, 'object');
10-
binding.external.checkExternal(test);
11-
test = null;
12-
global.gc();
13-
assert.strictEqual(0, binding.external.getFinalizeCount());
19+
'External with finalizer',
20+
() => {
21+
const test = binding.external.createExternalWithFinalize();
22+
assert.strictEqual(typeof test, 'object');
23+
binding.external.checkExternal(test);
24+
assert.strictEqual(0, binding.external.getFinalizeCount());
25+
},
26+
() => {
27+
assert.strictEqual(1, binding.external.getFinalizeCount());
28+
},
1429

15-
test = binding.external.createExternalWithFinalize();
16-
assert.strictEqual(typeof test, 'object');
17-
binding.external.checkExternal(test);
18-
test = null;
19-
global.gc();
20-
assert.strictEqual(1, binding.external.getFinalizeCount());
21-
22-
test = binding.external.createExternalWithFinalizeHint();
23-
assert.strictEqual(typeof test, 'object');
24-
binding.external.checkExternal(test);
25-
test = null;
26-
global.gc();
27-
assert.strictEqual(2, binding.external.getFinalizeCount());
30+
'External with finalizer hint',
31+
() => {
32+
const test = binding.external.createExternalWithFinalizeHint();
33+
assert.strictEqual(typeof test, 'object');
34+
binding.external.checkExternal(test);
35+
assert.strictEqual(0, binding.external.getFinalizeCount());
36+
},
37+
() => {
38+
assert.strictEqual(1, binding.external.getFinalizeCount());
39+
},
40+
]);

test/index.js

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
'use strict';
22

3-
if (typeof global.gc !== 'function') {
4-
throw new Error('Tests require --expose-gc flag.')
5-
}
6-
73
let testModules = [
8-
'arraybuffer',
9-
'asyncworker',
10-
'buffer',
11-
'error',
12-
'external',
13-
'function',
14-
'name',
15-
'typedarray',
4+
'arraybuffer',
5+
'asyncworker',
6+
'buffer',
7+
'error',
8+
'external',
9+
'function',
10+
'name',
11+
'object',
12+
'typedaray',
1613
];
1714

18-
testModules.forEach(name => {
19-
try {
20-
require('./' + name);
21-
}
22-
catch (e) {
23-
console.error(e);
24-
}
25-
});
15+
if (typeof global.gc === 'function') {
16+
// Requiring each module runs tests in the module.
17+
testModules.forEach(name => {
18+
require('./' + name);
19+
});
20+
} else {
21+
// Make it easier to run with the correct (version-dependent) command-line args.
22+
const args = [ '--expose-gc', __filename ];
23+
if (require('../index').isNodeApiBuiltin) {
24+
args.splice(0, 0, '--napi-modules');
25+
}
26+
const child = require('child_process').spawnSync(process.argv[0], args, {
27+
stdio: 'inherit',
28+
});
29+
process.exitCode = child.status;
30+
}

test/object.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ function testDefineProperties(nameType) {
1919
const obj = {};
2020
binding.object.defineProperties(obj, nameType);
2121

22-
assertPropertyIsNot(obj, 'readonlyAccessor', 'writable');
2322
assertPropertyIsNot(obj, 'readonlyAccessor', 'enumerable');
2423
assertPropertyIsNot(obj, 'readonlyAccessor', 'configurable');
2524
assert.strictEqual(obj.readonlyAccessor, true);
2625

27-
assertPropertyIs(obj, 'readwriteAccessor', 'writable');
2826
assertPropertyIsNot(obj, 'readwriteAccessor', 'enumerable');
2927
assertPropertyIsNot(obj, 'readwriteAccessor', 'configurable');
3028
obj.readwriteAccessor = false;

0 commit comments

Comments
 (0)