koffi 0.9.30 → 0.9.33
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/package.json +1 -1
- package/src/call.hh +2 -1
- package/src/call_arm32.cc +27 -15
- package/src/call_arm64.cc +4 -9
- package/src/call_x64_sysv.cc +4 -9
- package/src/call_x64_sysv_fwd.S +13 -3
- package/src/call_x64_win.cc +4 -9
- package/src/call_x86.cc +18 -16
- package/src/ffi.cc +93 -46
- package/src/ffi.hh +11 -6
- package/src/util.cc +35 -1
- package/src/util.hh +2 -0
- package/test/tests/misc.c +62 -1
- package/test/tests/misc.js +49 -1
- package/vendor/node-addon-api/CHANGELOG.md +57 -0
- package/vendor/node-addon-api/README.md +3 -3
- package/vendor/node-addon-api/doc/array_buffer.md +2 -2
- package/vendor/node-addon-api/doc/buffer.md +2 -2
- package/vendor/node-addon-api/doc/class_property_descriptor.md +13 -5
- package/vendor/node-addon-api/doc/env.md +5 -5
- package/vendor/node-addon-api/doc/object.md +12 -33
- package/vendor/node-addon-api/doc/object_reference.md +1 -1
- package/vendor/node-addon-api/doc/object_wrap.md +27 -0
- package/vendor/node-addon-api/doc/reference.md +2 -2
- package/vendor/node-addon-api/doc/threadsafe_function.md +3 -3
- package/vendor/node-addon-api/doc/typed_threadsafe_function.md +2 -2
- package/vendor/node-addon-api/napi-inl.h +111 -61
- package/vendor/node-addon-api/napi.h +79 -59
- package/vendor/node-addon-api/package.json +22 -6
- package/vendor/node-addon-api/test/async_context.cc +15 -0
- package/vendor/node-addon-api/test/async_context.js +69 -33
- package/vendor/node-addon-api/test/binding.cc +2 -0
- package/vendor/node-addon-api/test/binding.gyp +7 -0
- package/vendor/node-addon-api/test/common/index.js +23 -22
- package/vendor/node-addon-api/test/common/test_helper.h +10 -0
- package/vendor/node-addon-api/test/error_terminating_environment.js +1 -0
- package/vendor/node-addon-api/test/function.cc +29 -0
- package/vendor/node-addon-api/test/function.js +35 -23
- package/vendor/node-addon-api/test/index.js +40 -17
- package/vendor/node-addon-api/test/object/object.cc +2 -0
- package/vendor/node-addon-api/test/object/set_property.cc +8 -0
- package/vendor/node-addon-api/test/object/set_property.js +6 -5
- package/vendor/node-addon-api/test/object/subscript_operator.cc +19 -3
- package/vendor/node-addon-api/test/objectwrap_function.cc +45 -0
- package/vendor/node-addon-api/test/objectwrap_function.js +22 -0
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +1 -1
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +2 -2
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.cc +1 -1
- package/vendor/node-addon-api/tools/clang-format.js +4 -1
- package/vendor/node-addon-api/unit-test/README.md +28 -0
- package/vendor/node-addon-api/unit-test/binding-file-template.js +39 -0
- package/vendor/node-addon-api/unit-test/binding.gyp +72 -0
- package/vendor/node-addon-api/unit-test/exceptions.js +32 -0
- package/vendor/node-addon-api/unit-test/generate-binding-cc.js +61 -0
- package/vendor/node-addon-api/unit-test/injectTestParams.js +101 -0
- package/vendor/node-addon-api/unit-test/listOfTestModules.js +88 -0
- package/vendor/node-addon-api/unit-test/matchModules.js +65 -0
- package/vendor/node-addon-api/unit-test/setup.js +13 -0
- package/vendor/node-addon-api/unit-test/spawnTask.js +26 -0
- package/vendor/node-addon-api/unit-test/test.js +30 -0
|
@@ -7,10 +7,10 @@ const noop = () => {};
|
|
|
7
7
|
|
|
8
8
|
const mustCallChecks = [];
|
|
9
9
|
|
|
10
|
-
function runCallChecks(exitCode) {
|
|
10
|
+
function runCallChecks (exitCode) {
|
|
11
11
|
if (exitCode !== 0) return;
|
|
12
12
|
|
|
13
|
-
const failed = mustCallChecks.filter(function(context) {
|
|
13
|
+
const failed = mustCallChecks.filter(function (context) {
|
|
14
14
|
if ('minimum' in context) {
|
|
15
15
|
context.messageSegment = `at least ${context.minimum}`;
|
|
16
16
|
return context.actual < context.minimum;
|
|
@@ -20,25 +20,25 @@ function runCallChecks(exitCode) {
|
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
failed.forEach(function(context) {
|
|
23
|
+
failed.forEach(function (context) {
|
|
24
24
|
console.log('Mismatched %s function calls. Expected %s, actual %d.',
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
context.name,
|
|
26
|
+
context.messageSegment,
|
|
27
|
+
context.actual);
|
|
28
28
|
console.log(context.stack.split('\n').slice(2).join('\n'));
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
if (failed.length) process.exit(1);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
exports.mustCall = function(fn, exact) {
|
|
34
|
+
exports.mustCall = function (fn, exact) {
|
|
35
35
|
return _mustCallInner(fn, exact, 'exact');
|
|
36
36
|
};
|
|
37
|
-
exports.mustCallAtLeast = function(fn, minimum) {
|
|
37
|
+
exports.mustCallAtLeast = function (fn, minimum) {
|
|
38
38
|
return _mustCallInner(fn, minimum, 'minimum');
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
function _mustCallInner(fn, criteria, field) {
|
|
41
|
+
function _mustCallInner (fn, criteria, field) {
|
|
42
42
|
if (typeof fn === 'number') {
|
|
43
43
|
criteria = fn;
|
|
44
44
|
fn = noop;
|
|
@@ -49,8 +49,7 @@ function _mustCallInner(fn, criteria, field) {
|
|
|
49
49
|
criteria = 1;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (typeof criteria !== 'number')
|
|
53
|
-
throw new TypeError(`Invalid ${field} value: ${criteria}`);
|
|
52
|
+
if (typeof criteria !== 'number') { throw new TypeError(`Invalid ${field} value: ${criteria}`); }
|
|
54
53
|
|
|
55
54
|
const context = {
|
|
56
55
|
[field]: criteria,
|
|
@@ -64,50 +63,52 @@ function _mustCallInner(fn, criteria, field) {
|
|
|
64
63
|
|
|
65
64
|
mustCallChecks.push(context);
|
|
66
65
|
|
|
67
|
-
return function() {
|
|
66
|
+
return function () {
|
|
68
67
|
context.actual++;
|
|
69
68
|
return fn.apply(this, arguments);
|
|
70
69
|
};
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
exports.mustNotCall = function(msg) {
|
|
74
|
-
return function mustNotCall() {
|
|
72
|
+
exports.mustNotCall = function (msg) {
|
|
73
|
+
return function mustNotCall () {
|
|
75
74
|
assert.fail(msg || 'function should not have been called');
|
|
76
75
|
};
|
|
77
76
|
};
|
|
78
77
|
|
|
79
|
-
exports.runTest = async function(test, buildType, buildPathRoot = process.env.
|
|
78
|
+
exports.runTest = async function (test, buildType, buildPathRoot = process.env.BUILD_PATH || '') {
|
|
80
79
|
buildType = buildType || process.config.target_defaults.default_configuration || 'Release';
|
|
81
80
|
|
|
82
81
|
const bindings = [
|
|
83
82
|
path.join(buildPathRoot, `../build/${buildType}/binding.node`),
|
|
84
83
|
path.join(buildPathRoot, `../build/${buildType}/binding_noexcept.node`),
|
|
85
84
|
path.join(buildPathRoot, `../build/${buildType}/binding_noexcept_maybe.node`),
|
|
85
|
+
path.join(buildPathRoot, `../build/${buildType}/binding_custom_namespace.node`)
|
|
86
86
|
].map(it => require.resolve(it));
|
|
87
87
|
|
|
88
88
|
for (const item of bindings) {
|
|
89
89
|
await Promise.resolve(test(require(item)))
|
|
90
90
|
.finally(exports.mustCall());
|
|
91
91
|
}
|
|
92
|
-
}
|
|
92
|
+
};
|
|
93
93
|
|
|
94
|
-
exports.runTestWithBindingPath = async function(test, buildType, buildPathRoot = process.env.
|
|
94
|
+
exports.runTestWithBindingPath = async function (test, buildType, buildPathRoot = process.env.BUILD_PATH || '') {
|
|
95
95
|
buildType = buildType || process.config.target_defaults.default_configuration || 'Release';
|
|
96
96
|
|
|
97
97
|
const bindings = [
|
|
98
98
|
path.join(buildPathRoot, `../build/${buildType}/binding.node`),
|
|
99
99
|
path.join(buildPathRoot, `../build/${buildType}/binding_noexcept.node`),
|
|
100
100
|
path.join(buildPathRoot, `../build/${buildType}/binding_noexcept_maybe.node`),
|
|
101
|
+
path.join(buildPathRoot, `../build/${buildType}/binding_custom_namespace.node`)
|
|
101
102
|
].map(it => require.resolve(it));
|
|
102
103
|
|
|
103
104
|
for (const item of bindings) {
|
|
104
105
|
await test(item);
|
|
105
106
|
}
|
|
106
|
-
}
|
|
107
|
+
};
|
|
107
108
|
|
|
108
|
-
exports.runTestWithBuildType = async function(test, buildType) {
|
|
109
|
+
exports.runTestWithBuildType = async function (test, buildType) {
|
|
109
110
|
buildType = buildType || process.config.target_defaults.default_configuration || 'Release';
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
112
|
+
await Promise.resolve(test(buildType))
|
|
113
|
+
.finally(exports.mustCall());
|
|
114
|
+
};
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
namespace Napi {
|
|
5
5
|
|
|
6
|
+
// Needs this here since the MaybeUnwrap() functions need to be in the
|
|
7
|
+
// same namespace as their arguments for C++ argument-dependent lookup
|
|
8
|
+
#ifdef NAPI_CPP_CUSTOM_NAMESPACE
|
|
9
|
+
namespace NAPI_CPP_CUSTOM_NAMESPACE {
|
|
10
|
+
#endif
|
|
11
|
+
|
|
6
12
|
// Use this when a variable or parameter is unused in order to explicitly
|
|
7
13
|
// silence a compiler warning about that.
|
|
8
14
|
template <typename T>
|
|
@@ -58,4 +64,8 @@ inline bool MaybeUnwrapTo(MaybeOrValue<T> maybe, T* out) {
|
|
|
58
64
|
#endif
|
|
59
65
|
}
|
|
60
66
|
|
|
67
|
+
#ifdef NAPI_CPP_CUSTOM_NAMESPACE
|
|
68
|
+
} // namespace NAPI_CPP_CUSTOM_NAMESPACE
|
|
69
|
+
#endif
|
|
70
|
+
|
|
61
71
|
} // namespace Napi
|
|
@@ -70,6 +70,7 @@ test(`./build/${buildType}/binding.node`, true);
|
|
|
70
70
|
test(`./build/${buildType}/binding_noexcept.node`, true);
|
|
71
71
|
test(`./build/${buildType}/binding_swallowexcept.node`, false);
|
|
72
72
|
test(`./build/${buildType}/binding_swallowexcept_noexcept.node`, false);
|
|
73
|
+
test(`./build/${buildType}/binding_custom_namespace.node`, true);
|
|
73
74
|
|
|
74
75
|
function test(bindingPath, process_should_abort) {
|
|
75
76
|
const number_of_test_cases = 5;
|
|
@@ -69,6 +69,16 @@ Value CallWithVector(const CallbackInfo& info) {
|
|
|
69
69
|
return MaybeUnwrap(func.Call(args));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
Value CallWithVectorUsingCppWrapper(const CallbackInfo& info) {
|
|
73
|
+
Function func = info[0].As<Function>();
|
|
74
|
+
std::vector<Value> args;
|
|
75
|
+
args.reserve(3);
|
|
76
|
+
args.push_back(info[1]);
|
|
77
|
+
args.push_back(info[2]);
|
|
78
|
+
args.push_back(info[3]);
|
|
79
|
+
return MaybeUnwrap(func.Call(args));
|
|
80
|
+
}
|
|
81
|
+
|
|
72
82
|
Value CallWithCStyleArray(const CallbackInfo& info) {
|
|
73
83
|
Function func = info[0].As<Function>();
|
|
74
84
|
std::vector<napi_value> args;
|
|
@@ -108,6 +118,17 @@ Value CallWithReceiverAndVector(const CallbackInfo& info) {
|
|
|
108
118
|
return MaybeUnwrap(func.Call(receiver, args));
|
|
109
119
|
}
|
|
110
120
|
|
|
121
|
+
Value CallWithReceiverAndVectorUsingCppWrapper(const CallbackInfo& info) {
|
|
122
|
+
Function func = info[0].As<Function>();
|
|
123
|
+
Value receiver = info[1];
|
|
124
|
+
std::vector<Value> args;
|
|
125
|
+
args.reserve(3);
|
|
126
|
+
args.push_back(info[2]);
|
|
127
|
+
args.push_back(info[3]);
|
|
128
|
+
args.push_back(info[4]);
|
|
129
|
+
return MaybeUnwrap(func.Call(receiver, args));
|
|
130
|
+
}
|
|
131
|
+
|
|
111
132
|
Value CallWithInvalidReceiver(const CallbackInfo& info) {
|
|
112
133
|
Function func = info[0].As<Function>();
|
|
113
134
|
return MaybeUnwrapOr(func.Call(Value(), std::initializer_list<napi_value>{}),
|
|
@@ -213,11 +234,15 @@ Object InitFunction(Env env) {
|
|
|
213
234
|
Function::New(env, ValueCallbackWithData, nullptr, &testData);
|
|
214
235
|
exports["callWithArgs"] = Function::New(env, CallWithArgs);
|
|
215
236
|
exports["callWithVector"] = Function::New(env, CallWithVector);
|
|
237
|
+
exports["callWithVectorUsingCppWrapper"] =
|
|
238
|
+
Function::New(env, CallWithVectorUsingCppWrapper);
|
|
216
239
|
exports["callWithCStyleArray"] = Function::New(env, CallWithCStyleArray);
|
|
217
240
|
exports["callWithReceiverAndCStyleArray"] =
|
|
218
241
|
Function::New(env, CallWithReceiverAndCStyleArray);
|
|
219
242
|
exports["callWithReceiverAndArgs"] = Function::New(env, CallWithReceiverAndArgs);
|
|
220
243
|
exports["callWithReceiverAndVector"] = Function::New(env, CallWithReceiverAndVector);
|
|
244
|
+
exports["callWithReceiverAndVectorUsingCppWrapper"] =
|
|
245
|
+
Function::New(env, CallWithReceiverAndVectorUsingCppWrapper);
|
|
221
246
|
exports["callWithInvalidReceiver"] = Function::New(env, CallWithInvalidReceiver);
|
|
222
247
|
exports["callConstructorWithArgs"] = Function::New(env, CallConstructorWithArgs);
|
|
223
248
|
exports["callConstructorWithVector"] = Function::New(env, CallConstructorWithVector);
|
|
@@ -246,6 +271,8 @@ Object InitFunction(Env env) {
|
|
|
246
271
|
Function::New<ValueCallbackWithData>(env, nullptr, &testData);
|
|
247
272
|
exports["callWithArgs"] = Function::New<CallWithArgs>(env);
|
|
248
273
|
exports["callWithVector"] = Function::New<CallWithVector>(env);
|
|
274
|
+
exports["callWithVectorUsingCppWrapper"] =
|
|
275
|
+
Function::New<CallWithVectorUsingCppWrapper>(env);
|
|
249
276
|
exports["callWithCStyleArray"] = Function::New<CallWithCStyleArray>(env);
|
|
250
277
|
exports["callWithReceiverAndCStyleArray"] =
|
|
251
278
|
Function::New<CallWithReceiverAndCStyleArray>(env);
|
|
@@ -253,6 +280,8 @@ Object InitFunction(Env env) {
|
|
|
253
280
|
Function::New<CallWithReceiverAndArgs>(env);
|
|
254
281
|
exports["callWithReceiverAndVector"] =
|
|
255
282
|
Function::New<CallWithReceiverAndVector>(env);
|
|
283
|
+
exports["callWithReceiverAndVectorUsingCppWrapper"] =
|
|
284
|
+
Function::New<CallWithReceiverAndVectorUsingCppWrapper>(env);
|
|
256
285
|
exports["callWithInvalidReceiver"] =
|
|
257
286
|
Function::New<CallWithInvalidReceiver>(env);
|
|
258
287
|
exports["callConstructorWithArgs"] =
|
|
@@ -8,71 +8,81 @@ module.exports = require('./common').runTest(binding => {
|
|
|
8
8
|
testLambda(binding.function.lambda);
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
function test(binding) {
|
|
11
|
+
function test (binding) {
|
|
12
12
|
assert.strictEqual(binding.emptyConstructor(true), true);
|
|
13
13
|
assert.strictEqual(binding.emptyConstructor(false), false);
|
|
14
14
|
|
|
15
15
|
let obj = {};
|
|
16
16
|
assert.deepStrictEqual(binding.voidCallback(obj), undefined);
|
|
17
|
-
assert.deepStrictEqual(obj, {
|
|
17
|
+
assert.deepStrictEqual(obj, { foo: 'bar' });
|
|
18
18
|
|
|
19
|
-
assert.deepStrictEqual(binding.valueCallback(), {
|
|
19
|
+
assert.deepStrictEqual(binding.valueCallback(), { foo: 'bar' });
|
|
20
20
|
|
|
21
21
|
let args = null;
|
|
22
22
|
let ret = null;
|
|
23
23
|
let receiver = null;
|
|
24
|
-
function testFunction() {
|
|
24
|
+
function testFunction () {
|
|
25
25
|
receiver = this;
|
|
26
26
|
args = [].slice.call(arguments);
|
|
27
27
|
return ret;
|
|
28
28
|
}
|
|
29
|
-
function testConstructor() {
|
|
29
|
+
function testConstructor () {
|
|
30
30
|
args = [].slice.call(arguments);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function makeCallbackTestFunction(receiver, expectedOne, expectedTwo, expectedThree) {
|
|
34
|
-
return function callback(one, two, three) {
|
|
33
|
+
function makeCallbackTestFunction (receiver, expectedOne, expectedTwo, expectedThree) {
|
|
34
|
+
return function callback (one, two, three) {
|
|
35
35
|
assert.strictEqual(this, receiver);
|
|
36
36
|
assert.strictEqual(one, expectedOne);
|
|
37
37
|
assert.strictEqual(two, expectedTwo);
|
|
38
38
|
assert.strictEqual(three, expectedThree);
|
|
39
|
-
}
|
|
39
|
+
};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
ret = 4;
|
|
43
43
|
assert.strictEqual(binding.callWithArgs(testFunction, 1, 2, 3), 4);
|
|
44
44
|
assert.strictEqual(receiver, undefined);
|
|
45
|
-
assert.deepStrictEqual(args, [
|
|
45
|
+
assert.deepStrictEqual(args, [1, 2, 3]);
|
|
46
46
|
|
|
47
47
|
ret = 5;
|
|
48
48
|
assert.strictEqual(binding.callWithVector(testFunction, 2, 3, 4), 5);
|
|
49
49
|
assert.strictEqual(receiver, undefined);
|
|
50
|
-
assert.deepStrictEqual(args, [
|
|
50
|
+
assert.deepStrictEqual(args, [2, 3, 4]);
|
|
51
|
+
|
|
52
|
+
ret = 5;
|
|
53
|
+
assert.strictEqual(binding.callWithVectorUsingCppWrapper(testFunction, 2, 3, 4), 5);
|
|
54
|
+
assert.strictEqual(receiver, undefined);
|
|
55
|
+
assert.deepStrictEqual(args, [2, 3, 4]);
|
|
51
56
|
|
|
52
57
|
ret = 6;
|
|
53
58
|
assert.strictEqual(binding.callWithReceiverAndArgs(testFunction, obj, 3, 4, 5), 6);
|
|
54
59
|
assert.deepStrictEqual(receiver, obj);
|
|
55
|
-
assert.deepStrictEqual(args, [
|
|
60
|
+
assert.deepStrictEqual(args, [3, 4, 5]);
|
|
56
61
|
|
|
57
62
|
ret = 7;
|
|
58
63
|
assert.strictEqual(binding.callWithReceiverAndVector(testFunction, obj, 4, 5, 6), 7);
|
|
59
64
|
assert.deepStrictEqual(receiver, obj);
|
|
60
|
-
assert.deepStrictEqual(args, [
|
|
65
|
+
assert.deepStrictEqual(args, [4, 5, 6]);
|
|
66
|
+
|
|
67
|
+
ret = 7;
|
|
68
|
+
assert.strictEqual(binding.callWithReceiverAndVectorUsingCppWrapper(testFunction, obj, 4, 5, 6), 7);
|
|
69
|
+
assert.deepStrictEqual(receiver, obj);
|
|
70
|
+
assert.deepStrictEqual(args, [4, 5, 6]);
|
|
61
71
|
|
|
62
72
|
ret = 8;
|
|
63
73
|
assert.strictEqual(binding.callWithCStyleArray(testFunction, 5, 6, 7), ret);
|
|
64
74
|
assert.deepStrictEqual(receiver, undefined);
|
|
65
|
-
assert.deepStrictEqual(args, [
|
|
75
|
+
assert.deepStrictEqual(args, [5, 6, 7]);
|
|
66
76
|
|
|
67
77
|
ret = 9;
|
|
68
78
|
assert.strictEqual(binding.callWithReceiverAndCStyleArray(testFunction, obj, 6, 7, 8), ret);
|
|
69
79
|
assert.deepStrictEqual(receiver, obj);
|
|
70
|
-
assert.deepStrictEqual(args, [
|
|
80
|
+
assert.deepStrictEqual(args, [6, 7, 8]);
|
|
71
81
|
|
|
72
82
|
ret = 10;
|
|
73
83
|
assert.strictEqual(binding.callWithFunctionOperator(testFunction, 7, 8, 9), ret);
|
|
74
84
|
assert.strictEqual(receiver, undefined);
|
|
75
|
-
assert.deepStrictEqual(args, [
|
|
85
|
+
assert.deepStrictEqual(args, [7, 8, 9]);
|
|
76
86
|
|
|
77
87
|
assert.throws(() => {
|
|
78
88
|
binding.callWithInvalidReceiver();
|
|
@@ -80,33 +90,35 @@ function test(binding) {
|
|
|
80
90
|
|
|
81
91
|
obj = binding.callConstructorWithArgs(testConstructor, 5, 6, 7);
|
|
82
92
|
assert(obj instanceof testConstructor);
|
|
83
|
-
assert.deepStrictEqual(args, [
|
|
93
|
+
assert.deepStrictEqual(args, [5, 6, 7]);
|
|
84
94
|
|
|
85
95
|
obj = binding.callConstructorWithVector(testConstructor, 6, 7, 8);
|
|
86
96
|
assert(obj instanceof testConstructor);
|
|
87
|
-
assert.deepStrictEqual(args, [
|
|
97
|
+
assert.deepStrictEqual(args, [6, 7, 8]);
|
|
88
98
|
|
|
89
99
|
obj = binding.callConstructorWithCStyleArray(testConstructor, 7, 8, 9);
|
|
90
100
|
assert(obj instanceof testConstructor);
|
|
91
|
-
assert.deepStrictEqual(args, [
|
|
101
|
+
assert.deepStrictEqual(args, [7, 8, 9]);
|
|
92
102
|
|
|
93
103
|
obj = {};
|
|
94
104
|
assert.deepStrictEqual(binding.voidCallbackWithData(obj), undefined);
|
|
95
|
-
assert.deepStrictEqual(obj, {
|
|
105
|
+
assert.deepStrictEqual(obj, { foo: 'bar', data: 1 });
|
|
96
106
|
|
|
97
|
-
assert.deepStrictEqual(binding.valueCallbackWithData(), {
|
|
107
|
+
assert.deepStrictEqual(binding.valueCallbackWithData(), { foo: 'bar', data: 1 });
|
|
98
108
|
|
|
99
109
|
assert.strictEqual(binding.voidCallback.name, 'voidCallback');
|
|
100
110
|
assert.strictEqual(binding.valueCallback.name, 'valueCallback');
|
|
101
111
|
|
|
102
|
-
let testConstructCall
|
|
112
|
+
let testConstructCall;
|
|
103
113
|
binding.isConstructCall((result) => { testConstructCall = result; });
|
|
104
114
|
assert.ok(!testConstructCall);
|
|
115
|
+
/* eslint-disable no-new, new-cap */
|
|
105
116
|
new binding.isConstructCall((result) => { testConstructCall = result; });
|
|
117
|
+
/* eslint-enable no-new, new-cap */
|
|
106
118
|
assert.ok(testConstructCall);
|
|
107
119
|
|
|
108
120
|
obj = {};
|
|
109
|
-
binding.makeCallbackWithArgs(makeCallbackTestFunction(obj,
|
|
121
|
+
binding.makeCallbackWithArgs(makeCallbackTestFunction(obj, '1', '2', '3'), obj, '1', '2', '3');
|
|
110
122
|
binding.makeCallbackWithVector(makeCallbackTestFunction(obj, 4, 5, 6), obj, 4, 5, 6);
|
|
111
123
|
binding.makeCallbackWithCStyleArray(makeCallbackTestFunction(obj, 7, 8, 9), obj, 7, 8, 9);
|
|
112
124
|
assert.throws(() => {
|
|
@@ -114,7 +126,7 @@ function test(binding) {
|
|
|
114
126
|
});
|
|
115
127
|
}
|
|
116
128
|
|
|
117
|
-
function testLambda(binding) {
|
|
129
|
+
function testLambda (binding) {
|
|
118
130
|
assert.ok(binding.lambdaWithNoCapture());
|
|
119
131
|
assert.ok(binding.lambdaWithCapture());
|
|
120
132
|
assert.ok(binding.lambdaWithMoveOnlyCapture());
|
|
@@ -4,7 +4,7 @@ const majorNodeVersion = process.versions.node.split('.')[0];
|
|
|
4
4
|
|
|
5
5
|
if (typeof global.gc !== 'function') {
|
|
6
6
|
// Construct the correct (version-dependent) command-line args.
|
|
7
|
-
|
|
7
|
+
const args = ['--expose-gc'];
|
|
8
8
|
const majorV8Version = process.versions.v8.split('.')[0];
|
|
9
9
|
if (majorV8Version < 9) {
|
|
10
10
|
args.push('--no-concurrent-array-buffer-freeing');
|
|
@@ -15,7 +15,7 @@ if (typeof global.gc !== 'function') {
|
|
|
15
15
|
args.push(__filename);
|
|
16
16
|
|
|
17
17
|
const child = require('./napi_child').spawnSync(process.argv[0], args, {
|
|
18
|
-
stdio: 'inherit'
|
|
18
|
+
stdio: 'inherit'
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
if (child.signal) {
|
|
@@ -27,17 +27,36 @@ if (typeof global.gc !== 'function') {
|
|
|
27
27
|
process.exit(process.exitCode);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
const testModules = [];
|
|
31
|
+
|
|
30
32
|
const fs = require('fs');
|
|
31
33
|
const path = require('path');
|
|
32
34
|
|
|
33
|
-
let
|
|
35
|
+
let filterCondition = process.env.npm_config_filter || '';
|
|
36
|
+
let filterConditionFiles = [];
|
|
37
|
+
|
|
38
|
+
if (filterCondition !== '') {
|
|
39
|
+
filterCondition = require('../unit-test/matchModules').matchWildCards(process.env.npm_config_filter);
|
|
40
|
+
filterConditionFiles = filterCondition.split(' ').length > 0 ? filterCondition.split(' ') : [filterCondition];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const filterConditionsProvided = filterConditionFiles.length > 0;
|
|
44
|
+
|
|
45
|
+
function checkFilterCondition (fileName, parsedFilepath) {
|
|
46
|
+
let result = false;
|
|
47
|
+
|
|
48
|
+
if (!filterConditionsProvided) return true;
|
|
49
|
+
if (filterConditionFiles.includes(parsedFilepath)) result = true;
|
|
50
|
+
if (filterConditionFiles.includes(fileName)) result = true;
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
34
53
|
|
|
35
54
|
// TODO(RaisinTen): Update this when the test filenames
|
|
36
55
|
// are changed into test_*.js.
|
|
37
|
-
function loadTestModules(currentDirectory = __dirname, pre = '') {
|
|
56
|
+
function loadTestModules (currentDirectory = __dirname, pre = '') {
|
|
38
57
|
fs.readdirSync(currentDirectory).forEach((file) => {
|
|
39
58
|
if (currentDirectory === __dirname && (
|
|
40
|
-
|
|
59
|
+
file === 'binding.cc' ||
|
|
41
60
|
file === 'binding.gyp' ||
|
|
42
61
|
file === 'build' ||
|
|
43
62
|
file === 'common' ||
|
|
@@ -50,15 +69,19 @@ function loadTestModules(currentDirectory = __dirname, pre = '') {
|
|
|
50
69
|
return;
|
|
51
70
|
}
|
|
52
71
|
const absoluteFilepath = path.join(currentDirectory, file);
|
|
72
|
+
const parsedFilepath = path.parse(file);
|
|
73
|
+
const parsedPath = path.parse(currentDirectory);
|
|
74
|
+
|
|
53
75
|
if (fs.statSync(absoluteFilepath).isDirectory()) {
|
|
54
76
|
if (fs.existsSync(absoluteFilepath + '/index.js')) {
|
|
55
|
-
|
|
77
|
+
if (checkFilterCondition(parsedFilepath.name, parsedPath.base)) {
|
|
78
|
+
testModules.push(pre + file);
|
|
79
|
+
}
|
|
56
80
|
} else {
|
|
57
81
|
loadTestModules(absoluteFilepath, pre + file + '/');
|
|
58
82
|
}
|
|
59
83
|
} else {
|
|
60
|
-
|
|
61
|
-
if (parsedFilepath.ext === '.js') {
|
|
84
|
+
if (parsedFilepath.ext === '.js' && checkFilterCondition(parsedFilepath.name, parsedPath.base)) {
|
|
62
85
|
testModules.push(pre + parsedFilepath.name);
|
|
63
86
|
}
|
|
64
87
|
}
|
|
@@ -69,7 +92,7 @@ loadTestModules();
|
|
|
69
92
|
|
|
70
93
|
process.config.target_defaults.default_configuration =
|
|
71
94
|
fs
|
|
72
|
-
.readdirSync(path.join(__dirname, 'build'))
|
|
95
|
+
.readdirSync(path.join(__dirname, process.env.REL_BUILD_PATH || '', 'build'))
|
|
73
96
|
.filter((item) => (item === 'Debug' || item === 'Release'))[0];
|
|
74
97
|
|
|
75
98
|
let napiVersion = Number(process.versions.napi);
|
|
@@ -87,7 +110,7 @@ if (napiVersion < 3) {
|
|
|
87
110
|
testModules.splice(testModules.indexOf('version_management'), 1);
|
|
88
111
|
}
|
|
89
112
|
|
|
90
|
-
if (napiVersion < 4) {
|
|
113
|
+
if (napiVersion < 4 && !filterConditionsProvided) {
|
|
91
114
|
testModules.splice(testModules.indexOf('asyncprogressqueueworker'), 1);
|
|
92
115
|
testModules.splice(testModules.indexOf('asyncprogressworker'), 1);
|
|
93
116
|
testModules.splice(testModules.indexOf('threadsafe_function/threadsafe_function_ctx'), 1);
|
|
@@ -98,36 +121,36 @@ if (napiVersion < 4) {
|
|
|
98
121
|
testModules.splice(testModules.indexOf('threadsafe_function/threadsafe_function'), 1);
|
|
99
122
|
}
|
|
100
123
|
|
|
101
|
-
if (napiVersion < 5) {
|
|
124
|
+
if (napiVersion < 5 && !filterConditionsProvided) {
|
|
102
125
|
testModules.splice(testModules.indexOf('date'), 1);
|
|
103
126
|
}
|
|
104
127
|
|
|
105
|
-
if (napiVersion < 6) {
|
|
128
|
+
if (napiVersion < 6 && !filterConditionsProvided) {
|
|
106
129
|
testModules.splice(testModules.indexOf('addon'), 1);
|
|
107
130
|
testModules.splice(testModules.indexOf('addon_data'), 1);
|
|
108
131
|
testModules.splice(testModules.indexOf('bigint'), 1);
|
|
109
132
|
testModules.splice(testModules.indexOf('typedarray-bigint'), 1);
|
|
110
133
|
}
|
|
111
134
|
|
|
112
|
-
if (majorNodeVersion < 12) {
|
|
135
|
+
if (majorNodeVersion < 12 && !filterConditionsProvided) {
|
|
113
136
|
testModules.splice(testModules.indexOf('objectwrap_worker_thread'), 1);
|
|
114
137
|
testModules.splice(testModules.indexOf('error_terminating_environment'), 1);
|
|
115
138
|
}
|
|
116
139
|
|
|
117
|
-
if (napiVersion < 8) {
|
|
140
|
+
if (napiVersion < 8 && !filterConditionsProvided) {
|
|
118
141
|
testModules.splice(testModules.indexOf('object/object_freeze_seal'), 1);
|
|
119
142
|
}
|
|
120
143
|
|
|
121
|
-
(async function() {
|
|
144
|
+
(async function () {
|
|
122
145
|
console.log(`Testing with Node-API Version '${napiVersion}'.`);
|
|
123
146
|
|
|
124
|
-
console.log('Starting test suite\n');
|
|
147
|
+
if (filterConditionsProvided) { console.log('Starting test suite\n', testModules); } else { console.log('Starting test suite\n'); }
|
|
125
148
|
|
|
126
149
|
// Requiring each module runs tests in the module.
|
|
127
150
|
for (const name of testModules) {
|
|
128
151
|
console.log(`Running test '${name}'`);
|
|
129
152
|
await require('./' + name);
|
|
130
|
-
}
|
|
153
|
+
}
|
|
131
154
|
|
|
132
155
|
console.log('\nAll tests passed!');
|
|
133
156
|
})().catch((error) => {
|
|
@@ -11,6 +11,7 @@ Value GetPropertyWithCStyleString(const CallbackInfo& info);
|
|
|
11
11
|
Value GetPropertyWithCppStyleString(const CallbackInfo& info);
|
|
12
12
|
|
|
13
13
|
// Native wrappers for testing Object::Set()
|
|
14
|
+
Value SetPropertyWithUint32(const CallbackInfo& info);
|
|
14
15
|
Value SetPropertyWithNapiValue(const CallbackInfo& info);
|
|
15
16
|
Value SetPropertyWithNapiWrapperValue(const CallbackInfo& info);
|
|
16
17
|
Value SetPropertyWithCStyleString(const CallbackInfo& info);
|
|
@@ -299,6 +300,7 @@ Object InitObject(Env env) {
|
|
|
299
300
|
exports["getPropertyWithCStyleString"] = Function::New(env, GetPropertyWithCStyleString);
|
|
300
301
|
exports["getPropertyWithCppStyleString"] = Function::New(env, GetPropertyWithCppStyleString);
|
|
301
302
|
|
|
303
|
+
exports["setPropertyWithUint32"] = Function::New(env, SetPropertyWithUint32);
|
|
302
304
|
exports["setPropertyWithNapiValue"] = Function::New(env, SetPropertyWithNapiValue);
|
|
303
305
|
exports["setPropertyWithNapiWrapperValue"] = Function::New(env, SetPropertyWithNapiWrapperValue);
|
|
304
306
|
exports["setPropertyWithCStyleString"] = Function::New(env, SetPropertyWithCStyleString);
|
|
@@ -19,6 +19,14 @@ Value SetPropertyWithNapiWrapperValue(const CallbackInfo& info) {
|
|
|
19
19
|
return Boolean::New(info.Env(), MaybeUnwrapOr(obj.Set(key, value), false));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
Value SetPropertyWithUint32(const CallbackInfo& info) {
|
|
23
|
+
Object obj = info[0].As<Object>();
|
|
24
|
+
Number key = info[1].As<Number>();
|
|
25
|
+
Value value = info[2];
|
|
26
|
+
return Boolean::New(info.Env(),
|
|
27
|
+
MaybeUnwrapOr(obj.Set(key.Uint32Value(), value), false));
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
Value SetPropertyWithCStyleString(const CallbackInfo& info) {
|
|
23
31
|
Object obj = info[0].As<Object>();
|
|
24
32
|
String jsKey = info[1].As<String>();
|
|
@@ -4,14 +4,14 @@ const assert = require('assert');
|
|
|
4
4
|
|
|
5
5
|
module.exports = require('../common').runTest(test);
|
|
6
6
|
|
|
7
|
-
function test(binding) {
|
|
8
|
-
function testSetProperty(nativeSetProperty) {
|
|
7
|
+
function test (binding) {
|
|
8
|
+
function testSetProperty (nativeSetProperty, key = 'test') {
|
|
9
9
|
const obj = {};
|
|
10
|
-
assert.strictEqual(nativeSetProperty(obj,
|
|
11
|
-
assert.strictEqual(obj
|
|
10
|
+
assert.strictEqual(nativeSetProperty(obj, key, 1), true);
|
|
11
|
+
assert.strictEqual(obj[key], 1);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function testShouldThrowErrorIfKeyIsInvalid(nativeSetProperty) {
|
|
14
|
+
function testShouldThrowErrorIfKeyIsInvalid (nativeSetProperty) {
|
|
15
15
|
assert.throws(() => {
|
|
16
16
|
nativeSetProperty(undefined, 'test', 1);
|
|
17
17
|
}, /Cannot convert undefined or null to object/);
|
|
@@ -21,6 +21,7 @@ function test(binding) {
|
|
|
21
21
|
testSetProperty(binding.object.setPropertyWithNapiWrapperValue);
|
|
22
22
|
testSetProperty(binding.object.setPropertyWithCStyleString);
|
|
23
23
|
testSetProperty(binding.object.setPropertyWithCppStyleString);
|
|
24
|
+
testSetProperty(binding.object.setPropertyWithUint32, 12);
|
|
24
25
|
|
|
25
26
|
testShouldThrowErrorIfKeyIsInvalid(binding.object.setPropertyWithNapiValue);
|
|
26
27
|
testShouldThrowErrorIfKeyIsInvalid(binding.object.setPropertyWithNapiWrapperValue);
|
|
@@ -1,22 +1,38 @@
|
|
|
1
1
|
#include "napi.h"
|
|
2
|
+
#include "test_helper.h"
|
|
2
3
|
|
|
3
4
|
using namespace Napi;
|
|
4
5
|
|
|
5
6
|
Value SubscriptGetWithCStyleString(const CallbackInfo& info) {
|
|
6
|
-
Object obj = info[0].As<Object>();
|
|
7
7
|
String jsKey = info[1].As<String>();
|
|
8
|
+
|
|
9
|
+
// make sure const case compiles
|
|
10
|
+
const Object obj2 = info[0].As<Object>();
|
|
11
|
+
MaybeUnwrap(obj2[jsKey.Utf8Value().c_str()]).As<Boolean>();
|
|
12
|
+
|
|
13
|
+
Object obj = info[0].As<Object>();
|
|
8
14
|
return obj[jsKey.Utf8Value().c_str()];
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
Value SubscriptGetWithCppStyleString(const CallbackInfo& info) {
|
|
12
|
-
Object obj = info[0].As<Object>();
|
|
13
18
|
String jsKey = info[1].As<String>();
|
|
19
|
+
|
|
20
|
+
// make sure const case compiles
|
|
21
|
+
const Object obj2 = info[0].As<Object>();
|
|
22
|
+
MaybeUnwrap(obj2[jsKey.Utf8Value()]).As<Boolean>();
|
|
23
|
+
|
|
24
|
+
Object obj = info[0].As<Object>();
|
|
14
25
|
return obj[jsKey.Utf8Value()];
|
|
15
26
|
}
|
|
16
27
|
|
|
17
28
|
Value SubscriptGetAtIndex(const CallbackInfo& info) {
|
|
18
|
-
Object obj = info[0].As<Object>();
|
|
19
29
|
uint32_t index = info[1].As<Napi::Number>();
|
|
30
|
+
|
|
31
|
+
// make sure const case compiles
|
|
32
|
+
const Object obj2 = info[0].As<Object>();
|
|
33
|
+
MaybeUnwrap(obj2[index]).As<Boolean>();
|
|
34
|
+
|
|
35
|
+
Object obj = info[0].As<Object>();
|
|
20
36
|
return obj[index];
|
|
21
37
|
}
|
|
22
38
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#include <napi.h>
|
|
2
|
+
#include <unordered_map>
|
|
3
|
+
#include "test_helper.h"
|
|
4
|
+
|
|
5
|
+
class FunctionTest : public Napi::ObjectWrap<FunctionTest> {
|
|
6
|
+
public:
|
|
7
|
+
FunctionTest(const Napi::CallbackInfo& info)
|
|
8
|
+
: Napi::ObjectWrap<FunctionTest>(info) {}
|
|
9
|
+
|
|
10
|
+
static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& info) {
|
|
11
|
+
// If called with a "true" argument, throw an exeption to test the handling.
|
|
12
|
+
if (!info[0].IsUndefined() && MaybeUnwrap(info[0].ToBoolean())) {
|
|
13
|
+
NAPI_THROW(Napi::Error::New(info.Env(), "an exception"), Napi::Value());
|
|
14
|
+
}
|
|
15
|
+
// Otherwise, act as a factory.
|
|
16
|
+
std::vector<napi_value> args;
|
|
17
|
+
for (size_t i = 0; i < info.Length(); i++) args.push_back(info[i]);
|
|
18
|
+
return MaybeUnwrap(GetConstructor(info.Env()).New(args));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Constructor-per-env map in a static member because env.SetInstanceData()
|
|
22
|
+
// would interfere with Napi::Addon<T>
|
|
23
|
+
static std::unordered_map<napi_env, Napi::FunctionReference> constructors;
|
|
24
|
+
|
|
25
|
+
static void Initialize(Napi::Env env, Napi::Object exports) {
|
|
26
|
+
const char* name = "FunctionTest";
|
|
27
|
+
Napi::Function func = DefineClass(env, name, {});
|
|
28
|
+
constructors[env] = Napi::Persistent(func);
|
|
29
|
+
env.AddCleanupHook([env] { constructors.erase(env); });
|
|
30
|
+
exports.Set(name, func);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static Napi::Function GetConstructor(Napi::Env env) {
|
|
34
|
+
return constructors[env].Value();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
std::unordered_map<napi_env, Napi::FunctionReference>
|
|
39
|
+
FunctionTest::constructors;
|
|
40
|
+
|
|
41
|
+
Napi::Object InitObjectWrapFunction(Napi::Env env) {
|
|
42
|
+
Napi::Object exports = Napi::Object::New(env);
|
|
43
|
+
FunctionTest::Initialize(env, exports);
|
|
44
|
+
return exports;
|
|
45
|
+
}
|