UNPKG

koffi

Version:

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

201 lines (179 loc) 5.45 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 ({ asyncprogressworker }) { await success(asyncprogressworker); await fail(asyncprogressworker); await signalTest(asyncprogressworker.doMalignTest); await signalTest(asyncprogressworker.doSignalAfterProgressTest); await asyncProgressWorkerCallbackOverloads(asyncprogressworker.runWorkerWithCb); await asyncProgressWorkerRecvOverloads(asyncprogressworker.runWorkerWithRecv); await asyncProgressWorkerNoCbOverloads(asyncprogressworker.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' } ]); }).catch(common.mustNotCall()); resolve(); }); } 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' } ]); }).catch(common.mustNotCall()); resolve(); }); } } 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' } ]); }).catch(common.mustNotCall()); resolve(); }); } } function success (binding) { return new Promise((resolve, reject) => { const expected = [0, 1, 2, 3]; const actual = []; binding.doWork(expected.length, common.mustCall((err) => { if (err) { reject(err); } }), common.mustCall((_progress) => { actual.push(_progress); if (actual.length === expected.length) { assert.deepEqual(actual, expected); resolve(); } }, expected.length) ); }); } function fail (binding) { return new Promise((resolve) => { binding.doWork(-1, common.mustCall((err) => { assert.throws(() => { throw err; }, /test error/); resolve(); }), common.mustNotCall() ); }); } function signalTest (bindingFunction) { return new Promise((resolve, reject) => { bindingFunction( common.mustCall((err) => { if (err) { return reject(err); } resolve(); }), common.mustCallAtLeast((error, reason) => { try { assert(!error, reason); } catch (e) { reject(e); } }, 1) ); }); }