Add a real test!
This commit is contained in:
parent
2034139846
commit
342c46df6f
@ -15,7 +15,8 @@
|
||||
"build:umd:gzip":
|
||||
"npm run build:umd:min && gzip -c9 dist/worker-portal.min.js > dist/worker-portal.min.js.gz",
|
||||
"build": "npm run build:umd:gzip && ls -l dist/",
|
||||
"prepublish": "npm run clean && npm run build"
|
||||
"prepublish": "npm run clean && npm run build",
|
||||
"test": "npm run build:lib && ava --verbose"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -29,6 +30,7 @@
|
||||
},
|
||||
"homepage": "https://gitlab.com/explorigin/worker-portal",
|
||||
"devDependencies": {
|
||||
"ava": "^0.17.0",
|
||||
"babel-cli": "6.18.0",
|
||||
"babel-core": "6.21.0",
|
||||
"babel-eslint": "7.1.1",
|
||||
|
||||
@ -12,14 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
export function isWorker() {
|
||||
try {
|
||||
return self !== window;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function tryJSON(type, destination, id, data) {
|
||||
const packet = [type, destination, id, data];
|
||||
try {
|
||||
@ -29,7 +21,7 @@ function tryJSON(type, destination, id, data) {
|
||||
}
|
||||
}
|
||||
|
||||
export function WorkerPortal(context, worker, serialize) {
|
||||
export function WorkerPortal(context, worker, isSlave, serialize) {
|
||||
const responseMap = new Map();
|
||||
const _worker = worker || self;
|
||||
const contextIndex = Object.keys(context);
|
||||
@ -84,29 +76,25 @@ export function WorkerPortal(context, worker, serialize) {
|
||||
}
|
||||
|
||||
function injectionPointFactory(fnId, callbackFactory) {
|
||||
return () =>
|
||||
new Promise((resolve, reject) => {
|
||||
if (!enabled) {
|
||||
return function(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!enabled && fnId !== 0) {
|
||||
reject(new Error('Portal disabled'));
|
||||
}
|
||||
const id = callCount;
|
||||
callCount += 1;
|
||||
responseMap.set(id, [callbackFactory ? callbackFactory(resolve) : resolve, reject]);
|
||||
post(0, id, fnId, Array.from(arguments));
|
||||
post(0, id, fnId, args);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function resolveExternalInterfaceFactory(resolve) {
|
||||
return linkedFunctionNames => {
|
||||
return (linkedFunctionNames, ...rest) => {
|
||||
const externalInterface = {};
|
||||
linkedFunctionNames.forEach((fnName, index) => {
|
||||
externalInterface[fnName] = injectionPointFactory(index);
|
||||
});
|
||||
if (!isWorker()) {
|
||||
externalInterface._cleanup = injectionPointFactory(linkedFunctionNames.length, resolve =>
|
||||
resolve(cleanup())
|
||||
);
|
||||
}
|
||||
enabled = true;
|
||||
resolve(externalInterface);
|
||||
return contextIndex;
|
||||
@ -125,13 +113,16 @@ export function WorkerPortal(context, worker, serialize) {
|
||||
|
||||
_worker.addEventListener('message', dispatcher);
|
||||
|
||||
if (isWorker()) {
|
||||
if (isSlave) {
|
||||
return new Promise(resolve => {
|
||||
contextIndex.splice(0, 0, '__init', '__cleanup');
|
||||
contextIndex.splice(0, 0, '__init', '__cleanupSlave');
|
||||
context.__init = resolveExternalInterfaceFactory(resolve);
|
||||
context.__cleanup = cleanup;
|
||||
context.__cleanupSlave = cleanup;
|
||||
});
|
||||
}
|
||||
|
||||
return injectionPointFactory(0, resolveExternalInterfaceFactory)(contextIndex);
|
||||
return injectionPointFactory(0, resolveExternalInterfaceFactory)(contextIndex).then(api => ({
|
||||
...api,
|
||||
_cleanup: injectionPointFactory(1, resolve => resolve(cleanup()))
|
||||
}));
|
||||
}
|
||||
|
||||
80
packages/portal/test.js
Normal file
80
packages/portal/test.js
Normal file
@ -0,0 +1,80 @@
|
||||
import test from 'ava';
|
||||
|
||||
import { WorkerPortal } from './lib';
|
||||
|
||||
function FakeWorkerPair() {
|
||||
let cbA = null;
|
||||
let cbB = null;
|
||||
|
||||
const objA = {
|
||||
postMessage: data => {
|
||||
cbB({ data: data });
|
||||
},
|
||||
addEventListener: (eventName, fn) => {
|
||||
cbA = (...r) => {
|
||||
fn(...r);
|
||||
};
|
||||
},
|
||||
removeEventListener: (eventName, fn) => {
|
||||
cbA = null;
|
||||
}
|
||||
};
|
||||
|
||||
const objB = {
|
||||
postMessage: data => {
|
||||
cbA({ data: data });
|
||||
},
|
||||
addEventListener: (eventName, fn) => {
|
||||
cbB = (...r) => {
|
||||
fn(...r);
|
||||
};
|
||||
},
|
||||
removeEventListener: (eventName, fn) => {
|
||||
cbB = null;
|
||||
}
|
||||
};
|
||||
|
||||
return [objA, objB];
|
||||
}
|
||||
|
||||
test('Workers can call and respond equally', async t => {
|
||||
const [a, b] = FakeWorkerPair();
|
||||
|
||||
const slave = WorkerPortal(
|
||||
{
|
||||
slaveAdd: (a, b) => a + b
|
||||
},
|
||||
a,
|
||||
true
|
||||
);
|
||||
const master = WorkerPortal(
|
||||
{
|
||||
masterSubtract: (a, b) => a - b
|
||||
},
|
||||
b,
|
||||
false
|
||||
);
|
||||
|
||||
const masterApi = await master;
|
||||
const slaveApi = await slave;
|
||||
|
||||
t.deepEqual(Object.keys(masterApi), ['__init', '__cleanupSlave', 'slaveAdd', '_cleanup']);
|
||||
t.deepEqual(Object.keys(slaveApi), ['masterSubtract']);
|
||||
|
||||
t.is(await slaveApi.masterSubtract(9, 2), 7);
|
||||
t.is(await masterApi.slaveAdd(9, 2), 11);
|
||||
|
||||
t.is(await masterApi.slaveAdd(5, 2), 7);
|
||||
t.is(await slaveApi.masterSubtract(2, 2), 0);
|
||||
|
||||
await masterApi._cleanup();
|
||||
|
||||
return masterApi
|
||||
.slaveAdd(9, 2)
|
||||
.then(e => {
|
||||
t.fail('Expected rejection');
|
||||
})
|
||||
.catch(e => {
|
||||
t.is(e.message, 'Portal disabled');
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user