micro-should
Advanced tools
Comparing version 0.5.0 to 0.5.1
@@ -6,2 +6,3 @@ /*! micro-should - MIT License (c) 2019 Paul Miller (paulmillr.com) */ | ||
*/ | ||
/** A single test. */ | ||
export interface StackItem { | ||
@@ -22,4 +23,5 @@ message: string; | ||
PRINT_MULTILINE: boolean; | ||
STOP_AT_ERROR: boolean; | ||
MSHOULD_QUIET: boolean; | ||
STOP_ON_ERROR: boolean; | ||
QUIET: boolean; | ||
FAST: number; | ||
} | ||
@@ -74,3 +76,3 @@ export interface DescribeFunction { | ||
declare const it: TestFunction; | ||
export { it, describe, beforeEach, afterEach, it as should }; | ||
export { afterEach, beforeEach, describe, it, it as should }; | ||
export default it; |
149
index.js
@@ -9,13 +9,26 @@ /*! micro-should - MIT License (c) 2019 Paul Miller (paulmillr.com) */ | ||
let onlyStack; | ||
let running = false; | ||
let isRunning = false; | ||
const isCli = 'process' in globalThis; | ||
// Dumb bundlers parse code and assume we have hard dependency on "process". We don't. | ||
// The trick (also import(mod) below) ensures parsers can't see it. | ||
// @ts-ignore | ||
const proc = isCli ? globalThis['process'] : undefined; | ||
const opts = { | ||
PRINT_TREE: true, | ||
PRINT_MULTILINE: true, | ||
STOP_AT_ERROR: true, | ||
MSHOULD_QUIET: isCli && process.env.MSHOULD_QUIET, | ||
STOP_ON_ERROR: true, | ||
QUIET: isCli && ['1', 'true'].includes(proc.env.MSHOULD_QUIET), | ||
FAST: parseFast(proc.env.MSHOULD_FAST), | ||
}; | ||
function isQuiet() { | ||
return opts.MSHOULD_QUIET; | ||
function parseFast(str) { | ||
if (!isCli) | ||
return 0; | ||
let val = str === 'true' ? 1 : Number.parseInt(str, 10); | ||
if (!Number.isSafeInteger(val) || val < 1 || val > 256) | ||
return 0; | ||
return val; | ||
} | ||
function imp(moduleName) { | ||
return import(moduleName); | ||
} | ||
// String formatting utils | ||
@@ -48,3 +61,3 @@ const _c = String.fromCharCode(27); // x1b, control code for terminal colors | ||
function log(...args) { | ||
if (isQuiet()) | ||
if (opts.QUIET) | ||
return logQuiet(false); | ||
@@ -56,6 +69,6 @@ // @ts-ignore | ||
if (fail) { | ||
process.stderr.write(color('red', '!')); | ||
proc.stderr.write(color('red', '!')); | ||
} | ||
else { | ||
process.stdout.write('.'); | ||
proc.stdout.write('.'); | ||
} | ||
@@ -66,3 +79,3 @@ } | ||
// @ts-ignore | ||
if (!isQuiet()) | ||
if (!opts.QUIET) | ||
console.error(error); // loud = show error now. quiet = show in the end | ||
@@ -78,6 +91,2 @@ } | ||
} | ||
function tdiff(start) { | ||
const sec = Math.round((Date.now() - start) / 1000); | ||
return sec < 60 ? `${sec} sec` : `${Math.floor(sec / 60)} min ${sec % 60} sec`; | ||
} | ||
async function runTest(info, printTree = false, multiLine = false, stopAtError = true) { | ||
@@ -90,3 +99,3 @@ if (!printTree && multiLine) | ||
let messages = []; | ||
let onlyLogsToPrint = []; | ||
let onlyStackToLog = []; | ||
let beforeEachFns = []; | ||
@@ -97,3 +106,3 @@ let afterEachFns = []; // will be reversed | ||
if (printTree && info.only) | ||
onlyLogsToPrint.push(`${parent.prefix}${parent.message}`); | ||
onlyStackToLog.push(`${parent.prefix}${parent.message}`); | ||
if (parent.beforeEach) | ||
@@ -105,12 +114,11 @@ beforeEachFns.push(parent.beforeEach); | ||
afterEachFns.reverse(); | ||
if (onlyLogsToPrint.length) | ||
onlyLogsToPrint.forEach((l) => log(l)); | ||
const path = `${messages.join('/')}/`; | ||
const full = path + title; | ||
if (onlyStackToLog.length) | ||
onlyStackToLog.forEach((l) => log(l)); | ||
const path = messages.slice().concat(title).join('/'); | ||
// Skip is always single-line | ||
if (multiLine && !info.skip) { | ||
log(printTree ? `${info.prefix}${title}: ☆` : `☆ ${full}:`); | ||
if (multiLine && !info.skip && !opts.QUIET) { | ||
log(printTree ? `${info.prefix}${title}: ☆` : `☆ ${path}:`); | ||
} | ||
else if (info.skip) { | ||
log(printTree ? `${info.prefix}${title} (skip)` : `☆ ${full} (skip)`); | ||
log(printTree ? `${info.prefix}${title} (skip)` : `☆ ${path} (skip)`); | ||
return true; | ||
@@ -123,14 +131,14 @@ } | ||
// stopAtError = true | false | ||
function logTaskDone(fail = false, suffix = '') { | ||
function formatTaskDone(fail = false, suffix = '') { | ||
const symbol = fail ? '☓' : '✓'; | ||
const clr = fail ? 'red' : 'green'; | ||
const title_ = suffix ? [title, suffix].join('/') : title; | ||
const full_ = suffix ? [full, suffix].join('/') : full; | ||
log(printTree | ||
const full_ = suffix ? [path, suffix].join('/') : path; | ||
return printTree | ||
? `${info.childPrefix}` + color(clr, `${title_}: ${symbol}`) | ||
: color(clr, `${symbol} ${full_}`)); | ||
: color(clr, `${symbol} ${full_}`); | ||
} | ||
// Emit | ||
function logErrorStack(suffix) { | ||
if (isQuiet()) { | ||
if (opts.QUIET) { | ||
// when quiet, either stop & log trace; or log ! | ||
@@ -140,3 +148,3 @@ if (stopAtError) { | ||
console.error(); | ||
console.error(color('red', `☓ ${full}/${suffix}`)); | ||
console.error(formatTaskDone(true, suffix)); | ||
} | ||
@@ -150,3 +158,3 @@ else { | ||
// when loud, log (maybe formatted) tree structure | ||
logTaskDone(true, suffix); | ||
console.error(formatTaskDone(true, suffix)); | ||
} | ||
@@ -165,3 +173,3 @@ } | ||
else | ||
addToErrorLog(`${full}/beforeEach`, cause); | ||
addToErrorLog(`${path}/beforeEach`, cause); | ||
return false; | ||
@@ -181,3 +189,3 @@ } | ||
else | ||
addToErrorLog(`${full}`, cause); | ||
addToErrorLog(`${path}`, cause); | ||
return false; | ||
@@ -196,7 +204,7 @@ } | ||
else | ||
addToErrorLog(`${full}/afterEach`, cause); | ||
addToErrorLog(`${path}/afterEach`, cause); | ||
return false; | ||
} | ||
} | ||
logTaskDone(); | ||
log(formatTaskDone()); | ||
return true; | ||
@@ -263,3 +271,3 @@ } | ||
function begin(total, workers) { | ||
const features = [isQuiet() ? '+quiet' : '', workers ? `+fast-x${workers}` : ''].filter((a) => a); | ||
const features = [opts.QUIET ? '+quiet' : '', workers ? `+fast-x${workers}` : ''].filter((a) => a); | ||
const modes = features.length ? `(${features.join(' ')}) ` : ''; | ||
@@ -271,23 +279,27 @@ // No need to log stats when tests fit on one screen | ||
function finalize(total, startTime) { | ||
isRunning = false; | ||
console.log(); | ||
if (isQuiet()) | ||
if (opts.QUIET) | ||
console.log(); | ||
const totalFailed = errorLog.length; | ||
const sec = Math.round((Date.now() - startTime) / 1000); | ||
const tdiff = sec < 2 ? '' : sec < 60 ? `in ${sec} sec` : `in ${Math.floor(sec / 60)} min ${sec % 60} sec`; | ||
if (totalFailed) { | ||
console.error(); | ||
console.error(`${color('red', totalFailed)} tests failed`); | ||
if (isQuiet()) { | ||
if (opts.QUIET) { | ||
errorLog.forEach((err) => console.error(err)); | ||
} | ||
if (errorLog.length > 0) | ||
throw new Error(`${errorLog.length} of ${total} tests failed ${tdiff}`); | ||
} | ||
else { | ||
console.log(`${color('green', total)} tests passed in ${tdiff(startTime)}`); | ||
console.log(`${color('green', total)} tests passed ${tdiff}`); | ||
} | ||
return total; | ||
} | ||
async function runTests(forceSequential = false) { | ||
if (running) | ||
if (isRunning) | ||
throw new Error('should.run() has already been called, wait for end'); | ||
if (!forceSequential && isCli && !!process?.env?.MSHOULD_FAST) | ||
if (!forceSequential && opts.FAST) | ||
return runTestsInParallel(); | ||
running = true; | ||
isRunning = true; | ||
const tasks = cloneAndReset(); | ||
@@ -302,7 +314,5 @@ const total = tasks.filter((i) => !!i.test).length; | ||
continue; | ||
await runTest(test, opts.PRINT_TREE, opts.PRINT_MULTILINE, opts.STOP_AT_ERROR); | ||
await runTest(test, opts.PRINT_TREE, opts.PRINT_MULTILINE, opts.STOP_ON_ERROR); | ||
} | ||
finalize(total, startTime); | ||
running = false; | ||
return total; | ||
return finalize(total, startTime); | ||
} | ||
@@ -313,4 +323,4 @@ async function runTestsWhen(importMetaUrl) { | ||
// @ts-ignore | ||
const url = await import('node:url'); | ||
return importMetaUrl === url.pathToFileURL(process.argv[1]).href ? runTests() : undefined; | ||
const { pathToFileURL } = await imp('node:url'); | ||
return importMetaUrl === pathToFileURL(proc.argv[1]).href ? runTests() : undefined; | ||
} | ||
@@ -322,3 +332,3 @@ // Doesn't support tree and multiline | ||
throw new Error('must run in cli'); | ||
if ('deno' in process.versions) | ||
if ('deno' in proc.versions) | ||
return runTests(true); | ||
@@ -328,13 +338,11 @@ const tasks = cloneAndReset().filter((i) => !!i.test); // Filter describe elements | ||
const startTime = Date.now(); | ||
const runTestPar = (info) => runTest(info, false, false, opts.STOP_AT_ERROR); | ||
const runTestPar = (info) => runTest(info, false, false, opts.STOP_ON_ERROR); | ||
let cluster, err; | ||
let totalW = Number.parseInt(process.env.MSHOULD_FAST, 10); | ||
if (totalW === 1) | ||
totalW = 0; | ||
let totalW = opts.FAST; | ||
try { | ||
// @ts-ignore | ||
cluster = (await import('node:cluster')).default; | ||
cluster = (await imp('node:cluster')).default; | ||
// @ts-ignore | ||
if (!totalW) | ||
totalW = (await import('node:os')).cpus().length; | ||
if (totalW === 1) | ||
totalW = (await imp('node:os')).cpus().length; | ||
} | ||
@@ -344,7 +352,7 @@ catch (error) { | ||
} | ||
if (!cluster || !totalW) | ||
if (!cluster || !parseFast(totalW)) | ||
throw new Error('parallel tests are not supported: ' + err); | ||
// the code is ran in workers | ||
if (!cluster.isPrimary) { | ||
process.on('error', (err) => console.log('internal error:', 'child crashed?', err)); | ||
proc.on('error', (err) => console.log('internal error:', 'child crashed?', err)); | ||
let tasksDone = 0; | ||
@@ -359,6 +367,6 @@ const id = cluster.worker.id; | ||
} | ||
process.send({ name: 'parallelTests', worker: strId, tasksDone, errorLog }); | ||
process.exit(); | ||
proc.send({ name: 'parallelTests', worker: strId, tasksDone, errorLog }); | ||
proc.exit(); | ||
} | ||
// the code is ran in primary process | ||
// the code is ran in primary proc | ||
return await new Promise((resolve, reject) => { | ||
@@ -389,11 +397,10 @@ begin(total, totalW); | ||
msg.errorLog.forEach((item) => errorLog.push(item)); | ||
if (workersDone === totalW) { | ||
if (tasksDone === total) { | ||
finalize(total, startTime); | ||
resolve(tasksDone); | ||
} | ||
else { | ||
reject(new Error('internal error: not all tasks have been completed')); | ||
} | ||
} | ||
if (workersDone !== totalW) | ||
return; | ||
if (tasksDone !== total) | ||
return reject(new Error('internal error: not all tasks have been completed')); | ||
// @ts-ignore | ||
globalThis.setTimeout(() => { | ||
resolve(finalize(total, startTime)); | ||
}, 0); | ||
}); | ||
@@ -417,3 +424,3 @@ } | ||
it.opts = opts; | ||
export { it, describe, beforeEach, afterEach, it as should }; | ||
export { afterEach, beforeEach, describe, it, it as should }; | ||
export default it; |
157
index.ts
@@ -7,2 +7,3 @@ /*! micro-should - MIT License (c) 2019 Paul Miller (paulmillr.com) */ | ||
/** A single test. */ | ||
export interface StackItem { | ||
@@ -24,4 +25,5 @@ message: string; | ||
PRINT_MULTILINE: boolean; | ||
STOP_AT_ERROR: boolean; | ||
MSHOULD_QUIET: boolean; | ||
STOP_ON_ERROR: boolean; | ||
QUIET: boolean; | ||
FAST: number; | ||
} | ||
@@ -67,3 +69,2 @@ | ||
declare const process: any; | ||
declare const console: any; | ||
@@ -74,14 +75,27 @@ | ||
let onlyStack: StackItem | undefined; | ||
let running = false; | ||
let isRunning = false; | ||
const isCli = 'process' in globalThis; | ||
// Dumb bundlers parse code and assume we have hard dependency on "process". We don't. | ||
// The trick (also import(mod) below) ensures parsers can't see it. | ||
// @ts-ignore | ||
const proc: any = isCli ? globalThis['process'] : undefined; | ||
const opts: Options = { | ||
PRINT_TREE: true, | ||
PRINT_MULTILINE: true, | ||
STOP_AT_ERROR: true, | ||
MSHOULD_QUIET: isCli && process.env.MSHOULD_QUIET, | ||
STOP_ON_ERROR: true, | ||
QUIET: isCli && ['1', 'true'].includes(proc.env.MSHOULD_QUIET), | ||
FAST: parseFast(proc.env.MSHOULD_FAST), | ||
}; | ||
function isQuiet() { | ||
return opts.MSHOULD_QUIET; | ||
function parseFast(str: string | number): number { | ||
if (!isCli) return 0; | ||
let val = str === 'true' ? 1 : Number.parseInt(str as string, 10); | ||
if (!Number.isSafeInteger(val) || val < 1 || val > 256) return 0; | ||
return val; | ||
} | ||
function imp(moduleName: string): any { | ||
return import(moduleName); | ||
} | ||
// String formatting utils | ||
@@ -116,3 +130,3 @@ const _c = String.fromCharCode(27); // x1b, control code for terminal colors | ||
function log(...args: (string | undefined)[]) { | ||
if (isQuiet()) return logQuiet(false); | ||
if (opts.QUIET) return logQuiet(false); | ||
// @ts-ignore | ||
@@ -123,5 +137,5 @@ console.log(...args); | ||
if (fail) { | ||
process.stderr.write(color('red', '!')); | ||
proc.stderr.write(color('red', '!')); | ||
} else { | ||
process.stdout.write('.'); | ||
proc.stdout.write('.'); | ||
} | ||
@@ -132,3 +146,3 @@ } | ||
// @ts-ignore | ||
if (!isQuiet()) console.error(error); // loud = show error now. quiet = show in the end | ||
if (!opts.QUIET) console.error(error); // loud = show error now. quiet = show in the end | ||
} | ||
@@ -144,7 +158,2 @@ | ||
function tdiff(start: number) { | ||
const sec = Math.round((Date.now() - start) / 1000); | ||
return sec < 60 ? `${sec} sec` : `${Math.floor(sec / 60)} min ${sec % 60} sec`; | ||
} | ||
async function runTest( | ||
@@ -161,3 +170,3 @@ info: StackItem, | ||
let messages: string[] = []; | ||
let onlyLogsToPrint: string[] = []; | ||
let onlyStackToLog: string[] = []; | ||
let beforeEachFns: Function[] = []; | ||
@@ -167,3 +176,3 @@ let afterEachFns: Function[] = []; // will be reversed | ||
messages.push(parent.message); | ||
if (printTree && info.only) onlyLogsToPrint.push(`${parent.prefix}${parent.message}`); | ||
if (printTree && info.only) onlyStackToLog.push(`${parent.prefix}${parent.message}`); | ||
if (parent.beforeEach) beforeEachFns.push(parent.beforeEach); | ||
@@ -173,12 +182,11 @@ if (parent.afterEach) afterEachFns.push(parent.afterEach); | ||
afterEachFns.reverse(); | ||
if (onlyLogsToPrint.length) onlyLogsToPrint.forEach((l) => log(l)); | ||
if (onlyStackToLog.length) onlyStackToLog.forEach((l) => log(l)); | ||
const path = `${messages.join('/')}/`; | ||
const full = path + title; | ||
const path = messages.slice().concat(title).join('/'); | ||
// Skip is always single-line | ||
if (multiLine && !info.skip) { | ||
log(printTree ? `${info.prefix}${title}: ☆` : `☆ ${full}:`); | ||
if (multiLine && !info.skip && !opts.QUIET) { | ||
log(printTree ? `${info.prefix}${title}: ☆` : `☆ ${path}:`); | ||
} else if (info.skip) { | ||
log(printTree ? `${info.prefix}${title} (skip)` : `☆ ${full} (skip)`); | ||
log(printTree ? `${info.prefix}${title} (skip)` : `☆ ${path} (skip)`); | ||
return true; | ||
@@ -192,12 +200,10 @@ } | ||
// stopAtError = true | false | ||
function logTaskDone(fail = false, suffix = '') { | ||
function formatTaskDone(fail = false, suffix = '') { | ||
const symbol = fail ? '☓' : '✓'; | ||
const clr = fail ? 'red' : 'green'; | ||
const title_ = suffix ? [title, suffix].join('/') : title; | ||
const full_ = suffix ? [full, suffix].join('/') : full; | ||
log( | ||
printTree | ||
? `${info.childPrefix}` + color(clr, `${title_}: ${symbol}`) | ||
: color(clr, `${symbol} ${full_}`) | ||
); | ||
const full_ = suffix ? [path, suffix].join('/') : path; | ||
return printTree | ||
? `${info.childPrefix}` + color(clr, `${title_}: ${symbol}`) | ||
: color(clr, `${symbol} ${full_}`); | ||
} | ||
@@ -207,3 +213,3 @@ | ||
function logErrorStack(suffix: string) { | ||
if (isQuiet()) { | ||
if (opts.QUIET) { | ||
// when quiet, either stop & log trace; or log ! | ||
@@ -213,3 +219,3 @@ if (stopAtError) { | ||
console.error(); | ||
console.error(color('red', `☓ ${full}/${suffix}`)); | ||
console.error(formatTaskDone(true, suffix)); | ||
} else { | ||
@@ -221,3 +227,3 @@ // log !, continue | ||
// when loud, log (maybe formatted) tree structure | ||
logTaskDone(true, suffix); | ||
console.error(formatTaskDone(true, suffix)); | ||
} | ||
@@ -234,3 +240,3 @@ } | ||
if (stopAtError) throw cause; | ||
else addToErrorLog(`${full}/beforeEach`, cause); | ||
else addToErrorLog(`${path}/beforeEach`, cause); | ||
@@ -249,3 +255,3 @@ return false; | ||
if (stopAtError) throw cause; | ||
else addToErrorLog(`${full}`, cause); | ||
else addToErrorLog(`${path}`, cause); | ||
return false; | ||
@@ -262,7 +268,7 @@ } | ||
if (stopAtError) throw cause; | ||
else addToErrorLog(`${full}/afterEach`, cause); | ||
else addToErrorLog(`${path}/afterEach`, cause); | ||
return false; | ||
} | ||
} | ||
logTaskDone(); | ||
log(formatTaskDone()); | ||
return true; | ||
@@ -343,3 +349,5 @@ } | ||
function begin(total: number, workers?: number | undefined) { | ||
const features = [isQuiet() ? '+quiet' : '', workers ? `+fast-x${workers}` : ''].filter((a) => a); | ||
const features = [opts.QUIET ? '+quiet' : '', workers ? `+fast-x${workers}` : ''].filter( | ||
(a) => a | ||
); | ||
const modes = features.length ? `(${features.join(' ')}) ` : ''; | ||
@@ -351,20 +359,25 @@ // No need to log stats when tests fit on one screen | ||
function finalize(total: number, startTime: number) { | ||
isRunning = false; | ||
console.log(); | ||
if (isQuiet()) console.log(); | ||
if (opts.QUIET) console.log(); | ||
const totalFailed = errorLog.length; | ||
const sec = Math.round((Date.now() - startTime) / 1000); | ||
const tdiff = | ||
sec < 2 ? '' : sec < 60 ? `in ${sec} sec` : `in ${Math.floor(sec / 60)} min ${sec % 60} sec`; | ||
if (totalFailed) { | ||
console.error(); | ||
console.error(`${color('red', totalFailed)} tests failed`); | ||
if (isQuiet()) { | ||
if (opts.QUIET) { | ||
errorLog.forEach((err) => console.error(err)); | ||
} | ||
if (errorLog.length > 0) | ||
throw new Error(`${errorLog.length} of ${total} tests failed ${tdiff}`); | ||
} else { | ||
console.log(`${color('green', total)} tests passed in ${tdiff(startTime)}`); | ||
console.log(`${color('green', total)} tests passed ${tdiff}`); | ||
} | ||
return total; | ||
} | ||
async function runTests(forceSequential = false) { | ||
if (running) throw new Error('should.run() has already been called, wait for end'); | ||
if (!forceSequential && isCli && !!process?.env?.MSHOULD_FAST) return runTestsInParallel(); | ||
running = true; | ||
if (isRunning) throw new Error('should.run() has already been called, wait for end'); | ||
if (!forceSequential && opts.FAST) return runTestsInParallel(); | ||
isRunning = true; | ||
const tasks = cloneAndReset(); | ||
@@ -377,7 +390,5 @@ const total = tasks.filter((i) => !!i.test).length; | ||
if (!test.test) continue; | ||
await runTest(test, opts.PRINT_TREE, opts.PRINT_MULTILINE, opts.STOP_AT_ERROR); | ||
await runTest(test, opts.PRINT_TREE, opts.PRINT_MULTILINE, opts.STOP_ON_ERROR); | ||
} | ||
finalize(total, startTime); | ||
running = false; | ||
return total; | ||
return finalize(total, startTime); | ||
} | ||
@@ -388,4 +399,4 @@ | ||
// @ts-ignore | ||
const url = await import('node:url'); | ||
return importMetaUrl === url.pathToFileURL(process.argv[1]).href ? runTests() : undefined; | ||
const { pathToFileURL } = await imp('node:url'); | ||
return importMetaUrl === pathToFileURL(proc.argv[1]).href ? runTests() : undefined; | ||
} | ||
@@ -397,24 +408,23 @@ | ||
if (!isCli) throw new Error('must run in cli'); | ||
if ('deno' in process.versions) return runTests(true); | ||
if ('deno' in proc.versions) return runTests(true); | ||
const tasks = cloneAndReset().filter((i) => !!i.test); // Filter describe elements | ||
const total = tasks.length; | ||
const startTime = Date.now(); | ||
const runTestPar = (info: StackItem) => runTest(info, false, false, opts.STOP_AT_ERROR); | ||
const runTestPar = (info: StackItem) => runTest(info, false, false, opts.STOP_ON_ERROR); | ||
let cluster: any, err: any; | ||
let totalW = Number.parseInt(process.env.MSHOULD_FAST, 10); | ||
if (totalW === 1) totalW = 0; | ||
let totalW = opts.FAST; | ||
try { | ||
// @ts-ignore | ||
cluster = (await import('node:cluster')).default; | ||
cluster = (await imp('node:cluster')).default; | ||
// @ts-ignore | ||
if (!totalW) totalW = (await import('node:os')).cpus().length; | ||
if (totalW === 1) totalW = (await imp('node:os')).cpus().length; | ||
} catch (error) { | ||
err = error; | ||
} | ||
if (!cluster || !totalW!) throw new Error('parallel tests are not supported: ' + err); | ||
if (!cluster || !parseFast(totalW)) throw new Error('parallel tests are not supported: ' + err); | ||
// the code is ran in workers | ||
if (!cluster.isPrimary) { | ||
process.on('error', (err: any) => console.log('internal error:', 'child crashed?', err)); | ||
proc.on('error', (err: any) => console.log('internal error:', 'child crashed?', err)); | ||
let tasksDone = 0; | ||
@@ -428,7 +438,7 @@ const id = cluster.worker.id; | ||
} | ||
process.send({ name: 'parallelTests', worker: strId, tasksDone, errorLog }); | ||
process.exit(); | ||
proc.send({ name: 'parallelTests', worker: strId, tasksDone, errorLog }); | ||
proc.exit(); | ||
} | ||
// the code is ran in primary process | ||
// the code is ran in primary proc | ||
return await new Promise((resolve, reject) => { | ||
@@ -458,10 +468,9 @@ begin(total, totalW); | ||
msg.errorLog.forEach((item) => errorLog.push(item)); | ||
if (workersDone === totalW) { | ||
if (tasksDone === total) { | ||
finalize(total, startTime); | ||
resolve(tasksDone); | ||
} else { | ||
reject(new Error('internal error: not all tasks have been completed')); | ||
} | ||
} | ||
if (workersDone !== totalW) return; | ||
if (tasksDone !== total) | ||
return reject(new Error('internal error: not all tasks have been completed')); | ||
// @ts-ignore | ||
globalThis.setTimeout(() => { | ||
resolve(finalize(total, startTime)); | ||
}, 0); | ||
}); | ||
@@ -487,3 +496,3 @@ } | ||
export { it, describe, beforeEach, afterEach, it as should }; | ||
export { afterEach, beforeEach, describe, it, it as should }; | ||
export default it; |
{ | ||
"name": "micro-should", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"description": "Micro testing framework with familiar syntax, multi-env ESM support & parallel execution", | ||
@@ -17,3 +17,3 @@ "type": "module", | ||
"format": "npx prettier --write index.ts test", | ||
"test": "node test/basic.test.js; node test/example.test.js; node test/parallel.test.js" | ||
"test": "node test/example.test.js" | ||
}, | ||
@@ -39,3 +39,3 @@ "homepage": "https://github.com/paulmillr/micro-should", | ||
"devDependencies": { | ||
"@paulmillr/jsbt": "0.2.1", | ||
"@paulmillr/jsbt": "0.3.0", | ||
"prettier": "3.3.2", | ||
@@ -42,0 +42,0 @@ "typescript": "5.5.2" |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
38323
908
0