Skip to content

Commit cd83f7e

Browse files
bnoordhuisrvagg
authored andcommitted
test: add node::MakeCallback() test coverage
PR-URL: #3478 Reviewed-By: Trevor Norris <[email protected]>
1 parent 08da5c2 commit cd83f7e

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

test/addons/make-callback/binding.cc

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "node.h"
2+
#include "v8.h"
3+
4+
#include "../../../src/util.h"
5+
6+
#include <vector>
7+
8+
namespace {
9+
10+
void MakeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
11+
CHECK(args[0]->IsObject());
12+
CHECK(args[1]->IsFunction() || args[1]->IsString());
13+
auto isolate = args.GetIsolate();
14+
auto recv = args[0].As<v8::Object>();
15+
std::vector<v8::Local<v8::Value>> argv;
16+
for (size_t n = 2; n < static_cast<size_t>(args.Length()); n += 1) {
17+
argv.push_back(args[n]);
18+
}
19+
v8::Local<v8::Value> result;
20+
if (args[1]->IsFunction()) {
21+
auto method = args[1].As<v8::Function>();
22+
result =
23+
node::MakeCallback(isolate, recv, method, argv.size(), argv.data());
24+
} else if (args[1]->IsString()) {
25+
auto method = args[1].As<v8::String>();
26+
result =
27+
node::MakeCallback(isolate, recv, method, argv.size(), argv.data());
28+
} else {
29+
UNREACHABLE();
30+
}
31+
args.GetReturnValue().Set(result);
32+
}
33+
34+
void Initialize(v8::Local<v8::Object> target) {
35+
NODE_SET_METHOD(target, "makeCallback", MakeCallback);
36+
}
37+
38+
} // namespace anonymous
39+
40+
NODE_MODULE(binding, Initialize)

test/addons/make-callback/binding.gyp

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'binding',
5+
'sources': [ 'binding.cc' ]
6+
}
7+
]
8+
}

test/addons/make-callback/test.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
3+
const common = require('../../common');
4+
const assert = require('assert');
5+
const vm = require('vm');
6+
const binding = require('./build/Release/binding');
7+
const makeCallback = binding.makeCallback;
8+
9+
assert.strictEqual(42, makeCallback(process, common.mustCall(function() {
10+
assert.strictEqual(0, arguments.length);
11+
assert.strictEqual(this, process);
12+
return 42;
13+
})));
14+
15+
assert.strictEqual(42, makeCallback(process, common.mustCall(function(x) {
16+
assert.strictEqual(1, arguments.length);
17+
assert.strictEqual(this, process);
18+
assert.strictEqual(x, 1337);
19+
return 42;
20+
}), 1337));
21+
22+
const recv = {
23+
one: common.mustCall(function() {
24+
assert.strictEqual(0, arguments.length);
25+
assert.strictEqual(this, recv);
26+
return 42;
27+
}),
28+
two: common.mustCall(function(x) {
29+
assert.strictEqual(1, arguments.length);
30+
assert.strictEqual(this, recv);
31+
assert.strictEqual(x, 1337);
32+
return 42;
33+
}),
34+
};
35+
36+
assert.strictEqual(42, makeCallback(recv, 'one'));
37+
assert.strictEqual(42, makeCallback(recv, 'two', 1337));
38+
39+
// Check that the callback is made in the context of the receiver.
40+
const target = vm.runInNewContext(`
41+
(function($Object) {
42+
if (Object === $Object)
43+
throw Error('bad');
44+
return Object;
45+
})
46+
`);
47+
assert.notStrictEqual(Object, makeCallback(process, target, Object));
48+
49+
// Runs in inner context.
50+
const forward = vm.runInNewContext(`
51+
(function(forward) {
52+
return forward(Object);
53+
})
54+
`);
55+
// Runs in outer context.
56+
const endpoint = function($Object) {
57+
if (Object === $Object)
58+
throw Error('bad');
59+
return Object;
60+
};
61+
assert.strictEqual(Object, makeCallback(process, forward, endpoint));

0 commit comments

Comments
 (0)