Skip to content

Commit fc4585f

Browse files
JoseExpositomhdawson
authored andcommitted
test: dd tests for Function constructors
PR-URL: #937 Reviewed-By: Michael Dawson <[email protected]>
1 parent 87b7aae commit fc4585f

File tree

2 files changed

+168
-9
lines changed

2 files changed

+168
-9
lines changed

test/function.cc

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ namespace {
66

77
int testData = 1;
88

9+
Boolean EmptyConstructor(const CallbackInfo& info) {
10+
auto env = info.Env();
11+
bool isEmpty = info[0].As<Boolean>();
12+
Function function = isEmpty ? Function() : Function(env, Object::New(env));
13+
return Boolean::New(env, function.IsEmpty());
14+
}
15+
916
void VoidCallback(const CallbackInfo& info) {
1017
auto env = info.Env();
1118
Object obj = info[0].As<Object>();
@@ -45,8 +52,9 @@ Value ValueCallbackWithData(const CallbackInfo& info) {
4552
}
4653

4754
Value CallWithArgs(const CallbackInfo& info) {
48-
Function func = info[0].As<Function>();
49-
return func({ info[1], info[2], info[3] });
55+
Function func = info[0].As<Function>();
56+
return func.Call(
57+
std::initializer_list<napi_value>{info[1], info[2], info[3]});
5058
}
5159

5260
Value CallWithVector(const CallbackInfo& info) {
@@ -59,6 +67,27 @@ Value CallWithVector(const CallbackInfo& info) {
5967
return func.Call(args);
6068
}
6169

70+
Value CallWithCStyleArray(const CallbackInfo& info) {
71+
Function func = info[0].As<Function>();
72+
std::vector<napi_value> args;
73+
args.reserve(3);
74+
args.push_back(info[1]);
75+
args.push_back(info[2]);
76+
args.push_back(info[3]);
77+
return func.Call(args.size(), args.data());
78+
}
79+
80+
Value CallWithReceiverAndCStyleArray(const CallbackInfo& info) {
81+
Function func = info[0].As<Function>();
82+
Value receiver = info[1];
83+
std::vector<napi_value> args;
84+
args.reserve(3);
85+
args.push_back(info[2]);
86+
args.push_back(info[3]);
87+
args.push_back(info[4]);
88+
return func.Call(receiver, args.size(), args.data());
89+
}
90+
6291
Value CallWithReceiverAndArgs(const CallbackInfo& info) {
6392
Function func = info[0].As<Function>();
6493
Value receiver = info[1];
@@ -96,17 +125,81 @@ Value CallConstructorWithVector(const CallbackInfo& info) {
96125
return func.New(args);
97126
}
98127

128+
Value CallConstructorWithCStyleArray(const CallbackInfo& info) {
129+
Function func = info[0].As<Function>();
130+
std::vector<napi_value> args;
131+
args.reserve(3);
132+
args.push_back(info[1]);
133+
args.push_back(info[2]);
134+
args.push_back(info[3]);
135+
return func.New(args.size(), args.data());
136+
}
137+
99138
void IsConstructCall(const CallbackInfo& info) {
100139
Function callback = info[0].As<Function>();
101140
bool isConstructCall = info.IsConstructCall();
102141
callback({Napi::Boolean::New(info.Env(), isConstructCall)});
103142
}
104143

144+
void MakeCallbackWithArgs(const CallbackInfo& info) {
145+
Env env = info.Env();
146+
Function callback = info[0].As<Function>();
147+
Object resource = info[1].As<Object>();
148+
149+
AsyncContext context(env, "function_test_context", resource);
150+
151+
callback.MakeCallback(
152+
resource,
153+
std::initializer_list<napi_value>{info[2], info[3], info[4]},
154+
context);
155+
}
156+
157+
void MakeCallbackWithVector(const CallbackInfo& info) {
158+
Env env = info.Env();
159+
Function callback = info[0].As<Function>();
160+
Object resource = info[1].As<Object>();
161+
162+
AsyncContext context(env, "function_test_context", resource);
163+
164+
std::vector<napi_value> args;
165+
args.reserve(3);
166+
args.push_back(info[2]);
167+
args.push_back(info[3]);
168+
args.push_back(info[4]);
169+
callback.MakeCallback(resource, args, context);
170+
}
171+
172+
void MakeCallbackWithCStyleArray(const CallbackInfo& info) {
173+
Env env = info.Env();
174+
Function callback = info[0].As<Function>();
175+
Object resource = info[1].As<Object>();
176+
177+
AsyncContext context(env, "function_test_context", resource);
178+
179+
std::vector<napi_value> args;
180+
args.reserve(3);
181+
args.push_back(info[2]);
182+
args.push_back(info[3]);
183+
args.push_back(info[4]);
184+
callback.MakeCallback(resource, args.size(), args.data(), context);
185+
}
186+
187+
void MakeCallbackWithInvalidReceiver(const CallbackInfo& info) {
188+
Function callback = info[0].As<Function>();
189+
callback.MakeCallback(Value(), std::initializer_list<napi_value>{});
190+
}
191+
192+
Value CallWithFunctionOperator(const CallbackInfo& info) {
193+
Function func = info[0].As<Function>();
194+
return func({info[1], info[2], info[3]});
195+
}
196+
105197
} // end anonymous namespace
106198

107199
Object InitFunction(Env env) {
108200
Object result = Object::New(env);
109201
Object exports = Object::New(env);
202+
exports["emptyConstructor"] = Function::New(env, EmptyConstructor);
110203
exports["voidCallback"] = Function::New(env, VoidCallback, "voidCallback");
111204
exports["valueCallback"] = Function::New(env, ValueCallback, std::string("valueCallback"));
112205
exports["voidCallbackWithData"] =
@@ -115,15 +208,30 @@ Object InitFunction(Env env) {
115208
Function::New(env, ValueCallbackWithData, nullptr, &testData);
116209
exports["callWithArgs"] = Function::New(env, CallWithArgs);
117210
exports["callWithVector"] = Function::New(env, CallWithVector);
211+
exports["callWithCStyleArray"] = Function::New(env, CallWithCStyleArray);
212+
exports["callWithReceiverAndCStyleArray"] =
213+
Function::New(env, CallWithReceiverAndCStyleArray);
118214
exports["callWithReceiverAndArgs"] = Function::New(env, CallWithReceiverAndArgs);
119215
exports["callWithReceiverAndVector"] = Function::New(env, CallWithReceiverAndVector);
120216
exports["callWithInvalidReceiver"] = Function::New(env, CallWithInvalidReceiver);
121217
exports["callConstructorWithArgs"] = Function::New(env, CallConstructorWithArgs);
122218
exports["callConstructorWithVector"] = Function::New(env, CallConstructorWithVector);
219+
exports["callConstructorWithCStyleArray"] =
220+
Function::New(env, CallConstructorWithCStyleArray);
123221
exports["isConstructCall"] = Function::New(env, IsConstructCall);
222+
exports["makeCallbackWithArgs"] = Function::New(env, MakeCallbackWithArgs);
223+
exports["makeCallbackWithVector"] =
224+
Function::New(env, MakeCallbackWithVector);
225+
exports["makeCallbackWithCStyleArray"] =
226+
Function::New(env, MakeCallbackWithCStyleArray);
227+
exports["makeCallbackWithInvalidReceiver"] =
228+
Function::New(env, MakeCallbackWithInvalidReceiver);
229+
exports["callWithFunctionOperator"] =
230+
Function::New(env, CallWithFunctionOperator);
124231
result["plain"] = exports;
125232

126233
exports = Object::New(env);
234+
exports["emptyConstructor"] = Function::New(env, EmptyConstructor);
127235
exports["voidCallback"] = Function::New<VoidCallback>(env, "voidCallback");
128236
exports["valueCallback"] =
129237
Function::New<ValueCallback>(env, std::string("valueCallback"));
@@ -133,6 +241,9 @@ Object InitFunction(Env env) {
133241
Function::New<ValueCallbackWithData>(env, nullptr, &testData);
134242
exports["callWithArgs"] = Function::New<CallWithArgs>(env);
135243
exports["callWithVector"] = Function::New<CallWithVector>(env);
244+
exports["callWithCStyleArray"] = Function::New<CallWithCStyleArray>(env);
245+
exports["callWithReceiverAndCStyleArray"] =
246+
Function::New<CallWithReceiverAndCStyleArray>(env);
136247
exports["callWithReceiverAndArgs"] =
137248
Function::New<CallWithReceiverAndArgs>(env);
138249
exports["callWithReceiverAndVector"] =
@@ -143,7 +254,18 @@ Object InitFunction(Env env) {
143254
Function::New<CallConstructorWithArgs>(env);
144255
exports["callConstructorWithVector"] =
145256
Function::New<CallConstructorWithVector>(env);
257+
exports["callConstructorWithCStyleArray"] =
258+
Function::New<CallConstructorWithCStyleArray>(env);
146259
exports["isConstructCall"] = Function::New<IsConstructCall>(env);
260+
exports["makeCallbackWithArgs"] = Function::New<MakeCallbackWithArgs>(env);
261+
exports["makeCallbackWithVector"] =
262+
Function::New<MakeCallbackWithVector>(env);
263+
exports["makeCallbackWithCStyleArray"] =
264+
Function::New<MakeCallbackWithCStyleArray>(env);
265+
exports["makeCallbackWithInvalidReceiver"] =
266+
Function::New<MakeCallbackWithInvalidReceiver>(env);
267+
exports["callWithFunctionOperator"] =
268+
Function::New<CallWithFunctionOperator>(env);
147269
result["templated"] = exports;
148270
return result;
149271
}

test/function.js

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ test(require(`./build/${buildType}/binding.node`).function.templated);
88
test(require(`./build/${buildType}/binding_noexcept.node`).function.templated);
99

1010
function test(binding) {
11+
assert.strictEqual(binding.emptyConstructor(true), true);
12+
assert.strictEqual(binding.emptyConstructor(false), false);
13+
1114
let obj = {};
1215
assert.deepStrictEqual(binding.voidCallback(obj), undefined);
1316
assert.deepStrictEqual(obj, { "foo": "bar" });
@@ -26,26 +29,50 @@ function test(binding) {
2629
args = [].slice.call(arguments);
2730
}
2831

32+
function makeCallbackTestFunction(receiver, expectedOne, expectedTwo, expectedThree) {
33+
return function callback(one, two, three) {
34+
assert.strictEqual(this, receiver);
35+
assert.strictEqual(one, expectedOne);
36+
assert.strictEqual(two, expectedTwo);
37+
assert.strictEqual(three, expectedThree);
38+
}
39+
}
40+
2941
ret = 4;
30-
assert.equal(binding.callWithArgs(testFunction, 1, 2, 3), 4);
42+
assert.strictEqual(binding.callWithArgs(testFunction, 1, 2, 3), 4);
3143
assert.strictEqual(receiver, undefined);
3244
assert.deepStrictEqual(args, [ 1, 2, 3 ]);
3345

3446
ret = 5;
35-
assert.equal(binding.callWithVector(testFunction, 2, 3, 4), 5);
47+
assert.strictEqual(binding.callWithVector(testFunction, 2, 3, 4), 5);
3648
assert.strictEqual(receiver, undefined);
3749
assert.deepStrictEqual(args, [ 2, 3, 4 ]);
3850

3951
ret = 6;
40-
assert.equal(binding.callWithReceiverAndArgs(testFunction, obj, 3, 4, 5), 6);
52+
assert.strictEqual(binding.callWithReceiverAndArgs(testFunction, obj, 3, 4, 5), 6);
4153
assert.deepStrictEqual(receiver, obj);
4254
assert.deepStrictEqual(args, [ 3, 4, 5 ]);
4355

4456
ret = 7;
45-
assert.equal(binding.callWithReceiverAndVector(testFunction, obj, 4, 5, 6), 7);
57+
assert.strictEqual(binding.callWithReceiverAndVector(testFunction, obj, 4, 5, 6), 7);
4658
assert.deepStrictEqual(receiver, obj);
4759
assert.deepStrictEqual(args, [ 4, 5, 6 ]);
4860

61+
ret = 8;
62+
assert.strictEqual(binding.callWithCStyleArray(testFunction, 5, 6, 7), ret);
63+
assert.deepStrictEqual(receiver, undefined);
64+
assert.deepStrictEqual(args, [ 5, 6, 7 ]);
65+
66+
ret = 9;
67+
assert.strictEqual(binding.callWithReceiverAndCStyleArray(testFunction, obj, 6, 7, 8), ret);
68+
assert.deepStrictEqual(receiver, obj);
69+
assert.deepStrictEqual(args, [ 6, 7, 8 ]);
70+
71+
ret = 10;
72+
assert.strictEqual(binding.callWithFunctionOperator(testFunction, 7, 8, 9), ret);
73+
assert.strictEqual(receiver, undefined);
74+
assert.deepStrictEqual(args, [ 7, 8, 9 ]);
75+
4976
assert.throws(() => {
5077
binding.callWithInvalidReceiver();
5178
}, /Invalid (pointer passed as )?argument/);
@@ -58,20 +85,30 @@ function test(binding) {
5885
assert(obj instanceof testConstructor);
5986
assert.deepStrictEqual(args, [ 6, 7, 8 ]);
6087

88+
obj = binding.callConstructorWithCStyleArray(testConstructor, 7, 8, 9);
89+
assert(obj instanceof testConstructor);
90+
assert.deepStrictEqual(args, [ 7, 8, 9 ]);
91+
6192
obj = {};
6293
assert.deepStrictEqual(binding.voidCallbackWithData(obj), undefined);
6394
assert.deepStrictEqual(obj, { "foo": "bar", "data": 1 });
6495

6596
assert.deepStrictEqual(binding.valueCallbackWithData(), { "foo": "bar", "data": 1 });
6697

67-
assert.equal(binding.voidCallback.name, 'voidCallback');
68-
assert.equal(binding.valueCallback.name, 'valueCallback');
98+
assert.strictEqual(binding.voidCallback.name, 'voidCallback');
99+
assert.strictEqual(binding.valueCallback.name, 'valueCallback');
69100

70101
let testConstructCall = undefined;
71102
binding.isConstructCall((result) => { testConstructCall = result; });
72103
assert.ok(!testConstructCall);
73104
new binding.isConstructCall((result) => { testConstructCall = result; });
74105
assert.ok(testConstructCall);
75106

76-
// TODO: Function::MakeCallback tests
107+
obj = {};
108+
binding.makeCallbackWithArgs(makeCallbackTestFunction(obj, "1", "2", "3"), obj, "1", "2", "3");
109+
binding.makeCallbackWithVector(makeCallbackTestFunction(obj, 4, 5, 6), obj, 4, 5, 6);
110+
binding.makeCallbackWithCStyleArray(makeCallbackTestFunction(obj, 7, 8, 9), obj, 7, 8, 9);
111+
assert.throws(() => {
112+
binding.makeCallbackWithInvalidReceiver(() => {});
113+
});
77114
}

0 commit comments

Comments
 (0)