Skip to content

Commit

Permalink
feature: supertape: add support of worker_threads
Browse files Browse the repository at this point in the history
  • Loading branch information
coderaiser committed Jan 26, 2024
1 parent c19242f commit 64c7acb
Show file tree
Hide file tree
Showing 21 changed files with 367 additions and 70 deletions.
3 changes: 2 additions & 1 deletion .nycrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"all": true,
"exclude": [
"**/lib/**/{fixture,*.spec.{js,mjs}}",
".*"
".*",
"**/packages/supertape/bin/*.mjs"
],
"branches": 100,
"lines": 100,
Expand Down
1 change: 0 additions & 1 deletion packages/formatter-progress-bar/lib/progress-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const {red} = chalk;
const formatErrorsCount = (a) => a ? red(a) : OK;

const isStr = (a) => typeof a === 'string';

const {stderr} = process;

let SUPERTAPE_PROGRESS_BAR;
Expand Down
2 changes: 1 addition & 1 deletion packages/supertape/.madrun.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const env = {
};

export default {
'test': () => [env, `bin/supertape.mjs '{bin,lib}/**/*.spec.{js,mjs}'`],
'test': () => [env, `bin/tracer.mjs '{bin,lib}/**/*.spec.{js,mjs}'`],
'test:dts': () => 'check-dts test/*.ts',
'watch:test': async () => `nodemon -w lib -w test -x "${await cutEnv('test')}"`,
'lint': () => 'putout .',
Expand Down
6 changes: 5 additions & 1 deletion packages/supertape/.nycrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"check-coverage": true,
"all": true,
"exclude": [".*", "{bin,lib}/**/{fixture,*.spec.{js,mjs}}"],
"exclude": [
".*",
"{bin,lib}/**/{fixture,*.spec.{js,mjs}}",
"bin/**/*.mjs"
],
"branches": 100,
"lines": 100,
"functions": 100,
Expand Down
45 changes: 45 additions & 0 deletions packages/supertape/bin/communication.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
parentPort,
workerData,
} from 'node:worker_threads';
import {EventEmitter} from 'node:events';

const {assign} = Object;

export const createCommunication = (argv) => {
if (parentPort)
return {
parentPort,
workerData,
};

const {newWorker, newParentPort} = fakeWorkers();

return {
worker: newWorker,
parentPort: newParentPort,
workerData: argv,
};
};

export function fakeWorkers() {
const newWorker = new EventEmitter();
const newParentPort = new EventEmitter();

assign(newWorker, {
postMessage: (a) => {
newParentPort.emit('message', a);
},
});

assign(newParentPort, {
postMessage: (a) => {
newWorker.emit('message', a);
},
});

return {
newParentPort,
newWorker,
};
}
63 changes: 63 additions & 0 deletions packages/supertape/bin/formatter.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {EventEmitter} from 'node:events';

export const createFormatter = (parentPort) => {
const formatter = new EventEmitter();

formatter.on('start', ({total}) => {
parentPort.postMessage(['start', {
total,
}]);
});

formatter.on('test', ({test}) => {
parentPort.postMessage(['test', {
test,
}]);
});

formatter.on('test:end', ({count, total, failed, test}) => {
parentPort.postMessage(['test:end', {
total,
count,
failed,
test,
}]);
});

formatter.on('comment', (message) => {
parentPort.postMessage(['test:end', {
message,
}]);
});

formatter.on('test:success', ({count, message}) => {
parentPort.postMessage(['test:success', {
count,
message,
}]);
});

formatter.on('test:fail', ({at, count, message, operator, result, expected, output, errorStack}) => {
parentPort.postMessage(['fail', {
at,
count,
message,
operator,
result: JSON.stringify(result),
expected: JSON.stringify(expected),
output,
errorStack,
}]);
});

formatter.on('end', ({count, passed, failed, skiped}) => {
parentPort.postMessage(['end', {
count,
passed,
failed,
skiped,
}]);
});

return formatter;
};
28 changes: 28 additions & 0 deletions packages/supertape/bin/subscribe.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import keyPress from '@putout/cli-keypress';
import harnessCreator from '../lib/formatter/harness.js';

const {createHarness} = harnessCreator;

const resolveFormatter = async (name) => await import(`@supertape/formatter-${name}`);

export async function subscribe({name, quiet, exit, worker, stdout}) {
const {isStop} = keyPress();
const harness = createHarness(await resolveFormatter(name));

if (!quiet)
harness.pipe(stdout);

worker.on('exit', (code) => {
exit(code);
});

worker.on('message', ([type, a]) => {
harness.write({
type,
...a,
});

if (isStop())
worker.postMessage(['stop']);
});
}
30 changes: 26 additions & 4 deletions packages/supertape/bin/supertape.mjs
Original file line number Diff line number Diff line change
@@ -1,18 +1,40 @@
#!/usr/bin/env node

import process from 'node:process';
import cli from '../lib/cli.js';
import {createCommunication} from './communication.mjs';
import {subscribe} from './subscribe.mjs';
import {createFormatter} from './formatter.mjs';
import {parseArgs} from '../lib/cli/parse-args.js';

const {
worker,
parentPort,
workerData,
} = createCommunication(process.argv);

const args = parseArgs(process.argv.slice(2));

const {
stdout,
stderr,
exit,
} = process;

export default cli({
const workerFormatter = createFormatter(parentPort);

if (worker)
subscribe({
name: args.format,
quiet: args.quiet,
exit,
worker,
stdout,
});

export default await cli({
stdout,
stderr,
exit,
cwd: process.cwd(),
argv: process.argv.slice(2),
argv: workerData.slice(2),
workerFormatter,
});
2 changes: 1 addition & 1 deletion packages/supertape/bin/supertape.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import test from '../lib/supertape.js';

const require = createRequire(import.meta.url);

const name = new URL('supertape.mjs', import.meta.url).pathname;
const name = new URL('tracer.mjs', import.meta.url).pathname;
const run = runsome(name);

test('supertape: bin: -v', (t) => {
Expand Down
3 changes: 3 additions & 0 deletions packages/supertape/bin/trace.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const createTrace = (parentPort) => (event, data) => {
parentPort?.postMessage([event, data]);
};
34 changes: 34 additions & 0 deletions packages/supertape/bin/trace.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
test,
stub,
} from 'supertape';
import tryCatch from 'try-catch';
import {createTrace} from './trace.mjs';

test('supertape: bin: trace: parentPort', (t) => {
const data = {};
const postMessage = stub();
const parentPort = {
postMessage,
};

const trace = createTrace(parentPort);

trace('start', data);

const args = [
['start', data],
];

t.calledWith(postMessage, args);
t.end();
});

test('supertape: bin: trace: no parentPort', (t) => {
const data = {};
const trace = createTrace();
const [error] = tryCatch(trace, 'start', data);

t.notOk(error);
t.end();
});
37 changes: 37 additions & 0 deletions packages/supertape/bin/tracer.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env node

import process from 'node:process';
import {Worker} from 'node:worker_threads';
import {parseArgs} from '../lib/cli/parse-args.js';
import {subscribe} from './subscribe.mjs';

const {
cwd,
exit,
stdout,
} = process;

const args = parseArgs(process.argv.slice(2));
const write = stdout.write.bind(stdout);

if (!args.worker) {
await import('./supertape.mjs');
exit();
}

const slave = new URL('./supertape.mjs', import.meta.url);

const worker = new Worker(slave, {
workerData: process.argv,
stdin: true,
});

await subscribe({
name: args.format,
args,
worker,
exit,
cwd,
write,
stdout,
});
Loading

0 comments on commit 64c7acb

Please sign in to comment.