diff --git a/package.json b/package.json index d5c2fff..7fd1aa6 100644 --- a/package.json +++ b/package.json @@ -38,19 +38,19 @@ }, "dependencies": { "acquerello": "^1.0.0", - "hdr-histogram-js": "^2.0.1", + "hdr-histogram-js": "^3.0.0", "table": "^6.7.1" }, "devDependencies": { - "@cowtech/eslint-config": "^7.14.5", - "@cowtech/esm-package-utils": "^0.9.1", - "@types/node": "^16.6.1", + "@cowtech/eslint-config": "^8.0.1", + "@cowtech/esm-package-utils": "^0.9.3", + "@types/node": "^17.0.2", "@types/sinon": "^10.0.2", "@types/tap": "^15.0.5", "c8": "^7.8.0", "prettier": "^2.3.2", "proxyquire": "^2.1.3", - "sinon": "^11.1.2", + "sinon": "^12.0.1", "tap": "^15.0.9", "ts-node": "^10.2.0", "typescript": "^4.3.5" diff --git a/src/index.ts b/src/index.ts index 3ba38ea..6409c32 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ 'use strict' import { isMainThread, Worker, workerData } from 'worker_threads' -import { Callback, Context, defaultOptions, Options, PrintOptions, Result, Results, runnerPath, Tests } from './models' +import { Callback, Context, defaultOptions, Options, PrintOptions, Results, runnerPath, Tests } from './models' import { printResults } from './print' type PromiseResolver = (value: T) => void @@ -42,7 +42,7 @@ function run(context: Context): void { } }) - worker.on('error', (error: Error) => { + worker.on('error', error => { context.results[name] = { success: false, error, @@ -60,7 +60,7 @@ function run(context: Context): void { scheduleNextTest(context) }) - worker.on('message', (result: Result) => { + worker.on('message', result => { context.results[name] = result context.current++ @@ -96,7 +96,7 @@ export function cronometro( let callback = cb as (err: Error | null, results?: Results) => void if (!callback) { - promise = new Promise((resolve: PromiseResolver, reject: PromiseRejecter) => { + promise = new Promise((resolve, reject) => { promiseResolve = resolve promiseReject = reject }) diff --git a/src/models.ts b/src/models.ts index e9ca9cd..487ab01 100644 --- a/src/models.ts +++ b/src/models.ts @@ -29,7 +29,7 @@ export interface Test { after?: SetupFunction } -export type Callback = ((err: Error | null) => void) | ((err: null, results: Results) => any) +export type Callback = (err: Error | null, results: Results) => any export interface Percentiles { [key: string]: number diff --git a/src/print.ts b/src/print.ts index 559af00..55f1d4c 100644 --- a/src/print.ts +++ b/src/print.ts @@ -1,6 +1,6 @@ import { clean, colorize } from 'acquerello' import { table } from 'table' -import { Result, Results } from './models' +import { Results } from './models' const styles = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'gray'] @@ -29,8 +29,8 @@ export function printResults(results: Results, colors: boolean, compare: boolean let standardErrorPadding = 0 const entries: Array = Object.entries(results) - .sort((a: [string, Result], b: [string, Result]) => (!a[1].success ? -1 : b[1].mean - a[1].mean)) - .map(([name, result]: [string, Result]) => { + .sort((a, b) => (!a[1].success ? -1 : b[1].mean - a[1].mean)) + .map(([name, result]) => { if (!result.success) { return { name, @@ -72,7 +72,7 @@ export function printResults(results: Results, colors: boolean, compare: boolean let currentColor = 0 - const rows: Array> = entries.map((entry: PrintInfo) => { + const rows: Array> = entries.map(entry => { if (entry.error) { const row = [ styler(`{{gray}}${entry.name}{{-}}`), diff --git a/src/runner.ts b/src/runner.ts index b0e8ab5..c4fa336 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -1,10 +1,6 @@ import { isMainThread, parentPort, workerData } from 'worker_threads' import { runWorker } from './worker' -interface TsNodeModule { - register: (options: object) => void -} - if (isMainThread) { throw new Error('Do not run this file as main script.') } @@ -17,7 +13,7 @@ if (workerData.path.endsWith('.ts')) { const instance = Symbol.for('ts-node.register.instance') if (!(instance in process)) { - chain = import('ts-node').then(({ register }: TsNodeModule) => { + chain = import('ts-node').then(({ register }) => { register({ project: process.env.TS_NODE_PROJECT }) }) } @@ -28,7 +24,7 @@ chain .then(() => { return import(workerData.path) }) - .then((module: any) => { + .then(module => { if (typeof module === 'function') { return module() } else if (typeof module.default === 'function') { @@ -37,9 +33,9 @@ chain }) .then(() => { // Run the worker - runWorker(workerData, (value: any) => parentPort!.postMessage(value), process.exit) + runWorker(workerData, value => parentPort!.postMessage(value), process.exit) }) - .catch((e: Error) => { + .catch(e => { process.nextTick(() => { throw e }) diff --git a/src/worker.ts b/src/worker.ts index 95f7ded..cbf7a3f 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -63,7 +63,7 @@ function handleTestIteration(context: TestContext, error?: Error | null): void { max: histogram.maxValue, mean: histogram.mean, stddev: stdDev, - percentiles: percentiles.reduce((accu: Percentiles, percentile: number) => { + percentiles: percentiles.reduce((accu: Percentiles, percentile) => { accu[percentile] = histogram.getValueAtPercentile(percentile) return accu }, {}), diff --git a/test/asyncImport.test.ts b/test/asyncImport.test.ts index 015dcc6..8303e9f 100644 --- a/test/asyncImport.test.ts +++ b/test/asyncImport.test.ts @@ -4,10 +4,8 @@ import t from 'tap' import { isMainThread } from 'worker_threads' import { cronometro, percentiles } from '../src' -type Test = typeof t - async function main(): Promise { - await new Promise((resolve: (value: unknown) => void) => setTimeout(resolve, 100)) + await new Promise(resolve => setTimeout(resolve, 100)) if (!isMainThread) { cronometro( @@ -23,7 +21,7 @@ async function main(): Promise { () => false ) } else { - t.only('Collecting results', async (t: Test) => { + t.only('Collecting results', async t => { const results = await cronometro( { single() { diff --git a/test/errorHandling.test.ts b/test/errorHandling.test.ts index 26a1805..b12c7d5 100644 --- a/test/errorHandling.test.ts +++ b/test/errorHandling.test.ts @@ -4,8 +4,6 @@ import t from 'tap' import { isMainThread } from 'worker_threads' import { cronometro, percentiles } from '../src' -type Test = typeof t - if (!isMainThread) { cronometro( { @@ -19,7 +17,7 @@ if (!isMainThread) { () => false ) } else { - t.test('Errored tests handling', async (t: Test) => { + t.test('Errored tests handling', async t => { const results = await cronometro( { single() { @@ -59,11 +57,11 @@ if (!isMainThread) { t.strictSame(results.multiple.percentiles, {}) }) - t.test('Runner cannot be run in main thread', async (t: Test) => { + t.test('Runner cannot be run in main thread', async t => { await t.rejects(import('../src/runner'), { message: 'Do not run this file as main script.' }) }) - t.only('Runner reports setup errors', async (t: Test) => { + t.only('Runner reports setup errors', async t => { const results = await cronometro( { notDefined() { diff --git a/test/fixture/sample.ts b/test/fixture/sample.ts index e4e8e3d..af7f308 100644 --- a/test/fixture/sample.ts +++ b/test/fixture/sample.ts @@ -1,5 +1,4 @@ import cronometro from '../../dist' -import { Results } from '../../src' const pattern = /[123]/g const replacements: { [key: string]: string } = { 1: 'a', 2: 'b', 3: 'c' } @@ -11,14 +10,14 @@ const subject = cronometro( { single() { - subject.replace(pattern, (m: string) => replacements[m]) + subject.replace(pattern, m => replacements[m]) }, multiple() { subject.replace(/1/g, 'a').replace(/2/g, 'b').replace(/3/g, 'c') } }, { iterations: 5, errorThreshold: 0, print: { compare: true }, warmup: true }, - (_err: Error | null, results: Results) => { + (_, results) => { console.log(JSON.stringify(results, null, 2)) } ) diff --git a/test/genericErrorHandling.test.ts b/test/genericErrorHandling.test.ts index 1f635f3..7bcb66e 100644 --- a/test/genericErrorHandling.test.ts +++ b/test/genericErrorHandling.test.ts @@ -4,12 +4,10 @@ import t from 'tap' import { isMainThread } from 'worker_threads' import { cronometro } from '../src' -type Test = typeof t - if (!isMainThread) { cronometro(undefined as any, () => false) } else { - t.test('Generic error handling', async (t: Test) => { + t.test('Generic error handling', async t => { const results = await cronometro( { single() { diff --git a/test/optionsValidation.test.ts b/test/optionsValidation.test.ts index 90c9f5f..b193eac 100644 --- a/test/optionsValidation.test.ts +++ b/test/optionsValidation.test.ts @@ -3,9 +3,7 @@ import t from 'tap' import { cronometro } from '../src' -type Test = typeof t - -t.test('Options validation', async (t: Test) => { +t.test('Options validation', async t => { await t.rejects( () => cronometro( @@ -34,7 +32,7 @@ t.test('Options validation', async (t: Test) => { } }, { errorThreshold: -1 }, - (err: Error | null) => { + err => { t.type(err, 'Error') t.equal(err!.message, 'The errorThreshold option must be a number between 0 and 100.') } diff --git a/test/print.test.ts b/test/print.test.ts index 34db04b..e695af6 100644 --- a/test/print.test.ts +++ b/test/print.test.ts @@ -3,11 +3,9 @@ import sinon from 'sinon' import t from 'tap' import { isMainThread } from 'worker_threads' -import { cronometro, defaultOptions, percentiles, Results } from '../src' +import { cronometro, defaultOptions, percentiles } from '../src' import { setLogger } from '../src/print' -type Test = typeof t - function removeStyle(source: string): string { // eslint-disable-next-line no-control-regex return source.replace(/\x1b\[\d+m/g, '') @@ -35,7 +33,7 @@ if (!isMainThread) { } else { t.afterEach(() => loggerSpy.resetHistory()) - t.test('Printing - Default options', (t: Test) => { + t.test('Printing - Default options', t => { cronometro( { single() { @@ -48,7 +46,7 @@ if (!isMainThread) { throw new Error('FAILED') } }, - (err: Error | null, results: Results) => { + (err, results) => { t.equal(err, null) t.strictSame(Object.keys(results), ['single', 'multiple', 'error']) @@ -89,7 +87,7 @@ if (!isMainThread) { ) }) - t.test('Printing - No colors', (t: Test) => { + t.test('Printing - No colors', t => { cronometro( { single() { @@ -103,7 +101,7 @@ if (!isMainThread) { } }, { print: { colors: false } }, - (err: Error | null) => { + err => { t.equal(err, null) const output = loggerSpy.getCall(0).args[0] @@ -116,7 +114,7 @@ if (!isMainThread) { ) }) - t.test('Printing - Base compare', (t: Test) => { + t.test('Printing - Base compare', t => { cronometro( { single() { @@ -130,7 +128,7 @@ if (!isMainThread) { } }, { print: { compare: true } }, - (err: Error | null) => { + err => { t.equal(err, null) const output = removeStyle(loggerSpy.getCall(0).args[0]) @@ -147,7 +145,7 @@ if (!isMainThread) { ) }) - t.test('Printing - Previous compare', (t: Test) => { + t.test('Printing - Previous compare', t => { cronometro( { single() { @@ -161,7 +159,7 @@ if (!isMainThread) { } }, { print: { compare: true, compareMode: 'previous' } }, - (err: Error | null) => { + err => { t.equal(err, null) const output = removeStyle(loggerSpy.getCall(0).args[0]) diff --git a/test/success.test.ts b/test/success.test.ts index 1c0cb75..bf7cac4 100644 --- a/test/success.test.ts +++ b/test/success.test.ts @@ -4,8 +4,6 @@ import t from 'tap' import { isMainThread } from 'worker_threads' import { cronometro, percentiles } from '../src' -type Test = typeof t - if (!isMainThread) { cronometro( { @@ -20,7 +18,7 @@ if (!isMainThread) { () => false ) } else { - t.only('Collecting results', async (t: Test) => { + t.only('Collecting results', async t => { const results = await cronometro( { single() { diff --git a/test/unhandledErrorHandling.test.ts b/test/unhandledErrorHandling.test.ts index a1198f7..30fb2b3 100644 --- a/test/unhandledErrorHandling.test.ts +++ b/test/unhandledErrorHandling.test.ts @@ -4,8 +4,6 @@ import t from 'tap' import { isMainThread } from 'worker_threads' import { Callback, cronometro, percentiles } from '../src' -type Test = typeof t - if (!isMainThread) { cronometro( { @@ -23,7 +21,7 @@ if (!isMainThread) { () => false ) } else { - t.test('Unhandled errored tests handling', async (t: Test) => { + t.test('Unhandled errored tests handling', async t => { const results = await cronometro( { single() { diff --git a/test/worker.test.ts b/test/worker.test.ts index f1447b7..f5c7440 100644 --- a/test/worker.test.ts +++ b/test/worker.test.ts @@ -5,9 +5,8 @@ import { percentiles, Test } from '../src' import { runWorker } from '../src/worker' const { spy, stub } = sinon -type TapTest = typeof t -t.test('Worker execution - Handle sync functions that succeed', (t: TapTest) => { +t.test('Worker execution - Handle sync functions that succeed', t => { const main = stub() const notifier = spy() @@ -21,7 +20,7 @@ t.test('Worker execution - Handle sync functions that succeed', (t: TapTest) => errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.ok(main.called) @@ -45,7 +44,7 @@ t.test('Worker execution - Handle sync functions that succeed', (t: TapTest) => ) }) -t.test('Worker execution - Handle sync functions that throw errors', (t: TapTest) => { +t.test('Worker execution - Handle sync functions that throw errors', t => { const main = stub().throws(new Error('FAILED')) const notifier = spy() @@ -59,7 +58,7 @@ t.test('Worker execution - Handle sync functions that throw errors', (t: TapTest errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 1) t.ok(main.called) @@ -81,7 +80,7 @@ t.test('Worker execution - Handle sync functions that throw errors', (t: TapTest ) }) -t.test('Worker execution - Handle callback functions that succeed', (t: TapTest) => { +t.test('Worker execution - Handle callback functions that succeed', t => { function main(cb: (err?: Error) => void): void { cb() } @@ -100,7 +99,7 @@ t.test('Worker execution - Handle callback functions that succeed', (t: TapTest) errorThreshold: 1e-9 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.ok(mainSpy.called) @@ -124,7 +123,7 @@ t.test('Worker execution - Handle callback functions that succeed', (t: TapTest) ) }) -t.test('Worker execution - Handle callback functions that throw errors', (t: TapTest) => { +t.test('Worker execution - Handle callback functions that throw errors', t => { function main(cb: (err?: Error) => void): void { cb(new Error('FAILED')) } @@ -143,7 +142,7 @@ t.test('Worker execution - Handle callback functions that throw errors', (t: Tap errorThreshold: 0 }, notifier, - (code: number) => { + code => { t.equal(code, 1) t.ok(mainSpy.called) @@ -165,7 +164,7 @@ t.test('Worker execution - Handle callback functions that throw errors', (t: Tap ) }) -t.test('Worker execution - Handle promise functions that resolve', (t: TapTest) => { +t.test('Worker execution - Handle promise functions that resolve', t => { const main = stub().resolves() const notifier = spy() @@ -180,7 +179,7 @@ t.test('Worker execution - Handle promise functions that resolve', (t: TapTest) errorThreshold: 0 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.ok(main.called) @@ -204,7 +203,7 @@ t.test('Worker execution - Handle promise functions that resolve', (t: TapTest) ) }) -t.test('Worker execution - Handle promise functions that reject', (t: TapTest) => { +t.test('Worker execution - Handle promise functions that reject', t => { const main = stub().rejects(new Error('FAILED')) const notifier = spy() @@ -219,7 +218,7 @@ t.test('Worker execution - Handle promise functions that reject', (t: TapTest) = errorThreshold: 0 }, notifier, - (code: number) => { + code => { t.equal(code, 1) t.ok(main.called) @@ -241,7 +240,7 @@ t.test('Worker execution - Handle promise functions that reject', (t: TapTest) = ) }) -t.test('Worker execution - Handle warmup mode enabled', (t: TapTest) => { +t.test('Worker execution - Handle warmup mode enabled', t => { const main = stub() const notifier = spy() @@ -256,7 +255,7 @@ t.test('Worker execution - Handle warmup mode enabled', (t: TapTest) => { errorThreshold: 0 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.equal(main.callCount, 10) t.equal(notifier.callCount, 1) @@ -281,7 +280,7 @@ t.test('Worker execution - Handle warmup mode enabled', (t: TapTest) => { ) }) -t.test('Worker execution - Handle warmup mode disabled', (t: TapTest) => { +t.test('Worker execution - Handle warmup mode disabled', t => { const main = stub() const notifier = spy() @@ -296,7 +295,7 @@ t.test('Worker execution - Handle warmup mode disabled', (t: TapTest) => { errorThreshold: 0 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.equal(main.callCount, 5) t.equal(notifier.callCount, 1) @@ -321,7 +320,7 @@ t.test('Worker execution - Handle warmup mode disabled', (t: TapTest) => { ) }) -t.test('Worker setup - Handle callback before functions', (t: TapTest) => { +t.test('Worker setup - Handle callback before functions', t => { const main = stub() const setup = spy() const notifier = spy() @@ -347,7 +346,7 @@ t.test('Worker setup - Handle callback before functions', (t: TapTest) => { errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.equal(setup.callCount, 1) t.ok(main.called) @@ -373,7 +372,7 @@ t.test('Worker setup - Handle callback before functions', (t: TapTest) => { ) }) -t.test('Worker setup - Handle callback before functions that throw errors', (t: TapTest) => { +t.test('Worker setup - Handle callback before functions that throw errors', t => { const main = stub() const notifier = spy() @@ -397,7 +396,7 @@ t.test('Worker setup - Handle callback before functions that throw errors', (t: errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 1) t.notOk(main.called) @@ -419,7 +418,7 @@ t.test('Worker setup - Handle callback before functions that throw errors', (t: ) }) -t.test('Worker setup - Handle promise before functions that resolve', (t: TapTest) => { +t.test('Worker setup - Handle promise before functions that resolve', t => { const main = stub() const setup = spy() const notifier = spy() @@ -432,8 +431,9 @@ t.test('Worker setup - Handle promise before functions that resolve', (t: TapTes 'main', { test: main, - async before(): Promise { + before() { setup() + return Promise.resolve() } } ] @@ -444,7 +444,7 @@ t.test('Worker setup - Handle promise before functions that resolve', (t: TapTes errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.equal(setup.callCount, 1) t.ok(main.called) @@ -470,7 +470,7 @@ t.test('Worker setup - Handle promise before functions that resolve', (t: TapTes ) }) -t.test('Worker setup - Handle promise before functions that reject', (t: TapTest) => { +t.test('Worker setup - Handle promise before functions that reject', t => { const main = stub() const notifier = spy() @@ -482,8 +482,8 @@ t.test('Worker setup - Handle promise before functions that reject', (t: TapTest 'main', { test: main, - async before(): Promise { - throw new Error('FAILED') + before() { + return Promise.reject(new Error('FAILED')) } } ] @@ -494,7 +494,7 @@ t.test('Worker setup - Handle promise before functions that reject', (t: TapTest errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 1) t.notOk(main.called) @@ -516,7 +516,7 @@ t.test('Worker setup - Handle promise before functions that reject', (t: TapTest ) }) -t.test('Worker setup - Handle callback after functions', (t: TapTest) => { +t.test('Worker setup - Handle callback after functions', t => { const main = stub() const setup = spy() const notifier = spy() @@ -542,7 +542,7 @@ t.test('Worker setup - Handle callback after functions', (t: TapTest) => { errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.equal(setup.callCount, 1) t.ok(main.called) @@ -568,7 +568,7 @@ t.test('Worker setup - Handle callback after functions', (t: TapTest) => { ) }) -t.test('Worker setup - Handle callback after functions that throw errors', (t: TapTest) => { +t.test('Worker setup - Handle callback after functions that throw errors', t => { const main = stub() const notifier = spy() @@ -592,7 +592,7 @@ t.test('Worker setup - Handle callback after functions that throw errors', (t: T errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 1) t.ok(main.called) @@ -614,7 +614,7 @@ t.test('Worker setup - Handle callback after functions that throw errors', (t: T ) }) -t.test('Worker setup - Handle promise after functions that resolve', (t: TapTest) => { +t.test('Worker setup - Handle promise after functions that resolve', t => { const main = stub() const setup = spy() const notifier = spy() @@ -627,8 +627,9 @@ t.test('Worker setup - Handle promise after functions that resolve', (t: TapTest 'main', { test: main, - async after(): Promise { + after() { setup() + return Promise.resolve() } } ] @@ -639,7 +640,7 @@ t.test('Worker setup - Handle promise after functions that resolve', (t: TapTest errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 0) t.equal(setup.callCount, 1) t.ok(main.called) @@ -665,7 +666,7 @@ t.test('Worker setup - Handle promise after functions that resolve', (t: TapTest ) }) -t.test('Worker setup - Handle promise after functions that reject', (t: TapTest) => { +t.test('Worker setup - Handle promise after functions that reject', t => { const main = stub() const notifier = spy() @@ -677,8 +678,8 @@ t.test('Worker setup - Handle promise after functions that reject', (t: TapTest) 'main', { test: main, - async after(): Promise { - throw new Error('FAILED') + after() { + return Promise.reject(new Error('FAILED')) } } ] @@ -689,7 +690,7 @@ t.test('Worker setup - Handle promise after functions that reject', (t: TapTest) errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 1) t.ok(main.called) @@ -711,7 +712,7 @@ t.test('Worker setup - Handle promise after functions that reject', (t: TapTest) ) }) -t.test('Worker execution - Handle empty tests', (t: TapTest) => { +t.test('Worker execution - Handle empty tests', t => { const notifier = spy() runWorker( @@ -724,7 +725,7 @@ t.test('Worker execution - Handle empty tests', (t: TapTest) => { errorThreshold: 100 }, notifier, - (code: number) => { + code => { t.equal(code, 0) const result = notifier.getCall(0).args[0]