UNPKG

koffi

Version:

Fast and simple C FFI (foreign function interface) for Node.js

181 lines (160 loc) 5.09 kB
'use strict'; const common = require('./common'); const assert = require('assert'); module.exports = common.runTest(test); const nodeVersion = process.versions.node.split('.')[0]; let asyncHooks; function checkAsyncHooks () { if (nodeVersion >= 8) { if (asyncHooks === undefined) { asyncHooks = require('async_hooks'); } return true; } return false; } async function test ({ asyncprogressqueueworker }) { await success(asyncprogressqueueworker); await fail(asyncprogressqueueworker); await asyncProgressWorkerCallbackOverloads(asyncprogressqueueworker.runWorkerWithCb); await asyncProgressWorkerRecvOverloads(asyncprogressqueueworker.runWorkerWithRecv); await asyncProgressWorkerNoCbOverloads(asyncprogressqueueworker.runWorkerNoCb); } async function asyncProgressWorkerCallbackOverloads (bindingFunction) { bindingFunction(common.mustCall()); if (!checkAsyncHooks()) { return; } const hooks = common.installAysncHooks('cbResources'); const triggerAsyncId = asyncHooks.executionAsyncId(); await new Promise((resolve, reject) => { bindingFunction(common.mustCall(), 'cbResources'); hooks.then(actual => { assert.deepStrictEqual(actual, [ { eventName: 'init', type: 'cbResources', triggerAsyncId: triggerAsyncId, resource: {} }, { eventName: 'before' }, { eventName: 'after' }, { eventName: 'destroy' } ]); resolve(); }).catch((err) => reject(err)); }); } async function asyncProgressWorkerRecvOverloads (bindingFunction) { const recvObject = { a: 4 }; function cb () { assert.strictEqual(this.a, recvObject.a); } bindingFunction(recvObject, common.mustCall(cb)); if (!checkAsyncHooks()) { return; } const asyncResources = [ { resName: 'cbRecvResources', resObject: {} }, { resName: 'cbRecvResourcesObject', resObject: { foo: 'bar' } } ]; for (const asyncResource of asyncResources) { const asyncResName = asyncResource.resName; const asyncResObject = asyncResource.resObject; const hooks = common.installAysncHooks(asyncResource.resName); const triggerAsyncId = asyncHooks.executionAsyncId(); await new Promise((resolve, reject) => { if (Object.keys(asyncResObject).length === 0) { bindingFunction(recvObject, common.mustCall(cb), asyncResName); } else { bindingFunction(recvObject, common.mustCall(cb), asyncResName, asyncResObject); } hooks.then(actual => { assert.deepStrictEqual(actual, [ { eventName: 'init', type: asyncResName, triggerAsyncId: triggerAsyncId, resource: asyncResObject }, { eventName: 'before' }, { eventName: 'after' }, { eventName: 'destroy' } ]); resolve(); }).catch((err) => reject(err)); }); } } async function asyncProgressWorkerNoCbOverloads (bindingFunction) { bindingFunction(common.mustCall()); if (!checkAsyncHooks()) { return; } const asyncResources = [ { resName: 'noCbResources', resObject: {} }, { resName: 'noCbResourcesObject', resObject: { foo: 'bar' } } ]; for (const asyncResource of asyncResources) { const asyncResName = asyncResource.resName; const asyncResObject = asyncResource.resObject; const hooks = common.installAysncHooks(asyncResource.resName); const triggerAsyncId = asyncHooks.executionAsyncId(); await new Promise((resolve, reject) => { if (Object.keys(asyncResObject).length === 0) { bindingFunction(asyncResName, common.mustCall(() => {})); } else { bindingFunction(asyncResName, asyncResObject, common.mustCall(() => {})); } hooks.then(actual => { assert.deepStrictEqual(actual, [ { eventName: 'init', type: asyncResName, triggerAsyncId: triggerAsyncId, resource: asyncResObject }, { eventName: 'before' }, { eventName: 'after' }, { eventName: 'destroy' } ]); resolve(); }).catch((err) => reject(err)); }); } } function success (binding) { return new Promise((resolve, reject) => { const expected = [0, 1, 2, 3]; const actual = []; const worker = binding.createWork(expected.length, common.mustCall((err) => { if (err) { reject(err); } else { // All queued items shall be invoked before complete callback. assert.deepEqual(actual, expected); resolve(); } }), common.mustCall((_progress) => { actual.push(_progress); }, expected.length) ); binding.queueWork(worker); }); } function fail (binding) { return new Promise((resolve, reject) => { const worker = binding.createWork(-1, common.mustCall((err) => { assert.throws(() => { throw err; }, /test error/); resolve(); }), common.mustNotCall() ); binding.queueWork(worker); }); }