11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst vm = require('vm');
61cb0ef41Sopenharmony_ciconst binding = require(`./build/${common.buildType}/binding`);
71cb0ef41Sopenharmony_ciconst makeCallback = binding.makeCallback;
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cifunction myMultiArgFunc(arg1, arg2, arg3) {
101cb0ef41Sopenharmony_ci  assert.strictEqual(arg1, 1);
111cb0ef41Sopenharmony_ci  assert.strictEqual(arg2, 2);
121cb0ef41Sopenharmony_ci  assert.strictEqual(arg3, 3);
131cb0ef41Sopenharmony_ci  return 42;
141cb0ef41Sopenharmony_ci}
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci/**
171cb0ef41Sopenharmony_ci * Resource should be able to be arbitrary objects without special internal
181cb0ef41Sopenharmony_ci * slots. Testing with plain object here.
191cb0ef41Sopenharmony_ci */
201cb0ef41Sopenharmony_ciconst resource = {};
211cb0ef41Sopenharmony_ciassert.strictEqual(makeCallback(resource, process, common.mustCall(function() {
221cb0ef41Sopenharmony_ci  assert.strictEqual(arguments.length, 0);
231cb0ef41Sopenharmony_ci  assert.strictEqual(this, process);
241cb0ef41Sopenharmony_ci  return 42;
251cb0ef41Sopenharmony_ci})), 42);
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciassert.strictEqual(makeCallback(resource, process, common.mustCall(function(x) {
281cb0ef41Sopenharmony_ci  assert.strictEqual(arguments.length, 1);
291cb0ef41Sopenharmony_ci  assert.strictEqual(this, process);
301cb0ef41Sopenharmony_ci  assert.strictEqual(x, 1337);
311cb0ef41Sopenharmony_ci  return 42;
321cb0ef41Sopenharmony_ci}), 1337), 42);
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciassert.strictEqual(makeCallback(resource, this,
351cb0ef41Sopenharmony_ci                                common.mustCall(myMultiArgFunc), 1, 2, 3), 42);
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci// TODO(node-api): napi_make_callback needs to support
381cb0ef41Sopenharmony_ci// strings passed for the func argument
391cb0ef41Sopenharmony_ci//
401cb0ef41Sopenharmony_ci// const recv = {
411cb0ef41Sopenharmony_ci//   one: common.mustCall(function() {
421cb0ef41Sopenharmony_ci//     assert.strictEqual(0, arguments.length);
431cb0ef41Sopenharmony_ci//     assert.strictEqual(this, recv);
441cb0ef41Sopenharmony_ci//     return 42;
451cb0ef41Sopenharmony_ci//   }),
461cb0ef41Sopenharmony_ci//   two: common.mustCall(function(x) {
471cb0ef41Sopenharmony_ci//     assert.strictEqual(1, arguments.length);
481cb0ef41Sopenharmony_ci//     assert.strictEqual(this, recv);
491cb0ef41Sopenharmony_ci//     assert.strictEqual(x, 1337);
501cb0ef41Sopenharmony_ci//     return 42;
511cb0ef41Sopenharmony_ci//   }),
521cb0ef41Sopenharmony_ci// };
531cb0ef41Sopenharmony_ci//
541cb0ef41Sopenharmony_ci// assert.strictEqual(makeCallback(recv, 'one'), 42);
551cb0ef41Sopenharmony_ci// assert.strictEqual(makeCallback(recv, 'two', 1337), 42);
561cb0ef41Sopenharmony_ci//
571cb0ef41Sopenharmony_ci// // Check that callbacks on a receiver from a different context works.
581cb0ef41Sopenharmony_ci// const foreignObject = vm.runInNewContext('({ fortytwo() { return 42; } })');
591cb0ef41Sopenharmony_ci// assert.strictEqual(makeCallback(foreignObject, 'fortytwo'), 42);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci// Check that the callback is made in the context of the receiver.
631cb0ef41Sopenharmony_ciconst target = vm.runInNewContext(`
641cb0ef41Sopenharmony_ci    (function($Object) {
651cb0ef41Sopenharmony_ci      if (Object === $Object)
661cb0ef41Sopenharmony_ci        throw new Error('bad');
671cb0ef41Sopenharmony_ci      return Object;
681cb0ef41Sopenharmony_ci    })
691cb0ef41Sopenharmony_ci`);
701cb0ef41Sopenharmony_ciassert.notStrictEqual(makeCallback(resource, process, target, Object), Object);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci// Runs in inner context.
731cb0ef41Sopenharmony_ciconst forward = vm.runInNewContext(`
741cb0ef41Sopenharmony_ci    (function(forward) {
751cb0ef41Sopenharmony_ci      return forward(Object);
761cb0ef41Sopenharmony_ci    })
771cb0ef41Sopenharmony_ci`);
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci// Runs in outer context.
801cb0ef41Sopenharmony_cifunction endpoint($Object) {
811cb0ef41Sopenharmony_ci  if (Object === $Object)
821cb0ef41Sopenharmony_ci    throw new Error('bad');
831cb0ef41Sopenharmony_ci  return Object;
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ciassert.strictEqual(makeCallback(resource, process, forward, endpoint), Object);
87