ava 6.1.3 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/assert.js CHANGED
@@ -423,7 +423,7 @@ export class Assertions {
423
423
  retval = fn();
424
424
  if (isPromise(retval)) {
425
425
  // Here isPromise() checks if something is "promise like". Cast to an actual promise.
426
- Promise.resolve(retval).catch(noop);
426
+ Promise.resolve(retval).catch(noop); // eslint-disable-line promise/prefer-await-to-then
427
427
  throw fail(new AssertionError(message, {
428
428
  assertion: 't.throws()',
429
429
  formattedDetails: [formatWithLabel('Function returned a promise. Use `t.throwsAsync()` instead:', retval)],
@@ -462,7 +462,10 @@ export class Assertions {
462
462
  try {
463
463
  assertMessage(message, 't.throwsAsync()');
464
464
  } catch (error) {
465
- Promise.resolve(thrower).catch(noop);
465
+ try {
466
+ await thrower;
467
+ } catch {}
468
+
466
469
  throw error;
467
470
  }
468
471
 
@@ -476,7 +479,10 @@ export class Assertions {
476
479
  try {
477
480
  expectations = validateExpectations('t.throwsAsync()', expectations, args.length, experiments);
478
481
  } catch (error) {
479
- Promise.resolve(thrower).catch(noop);
482
+ try {
483
+ await thrower;
484
+ } catch {}
485
+
480
486
  throw fail(error);
481
487
  }
482
488
 
@@ -484,7 +490,7 @@ export class Assertions {
484
490
  // Record the stack before it gets lost in the promise chain.
485
491
  const assertionStack = getAssertionStack();
486
492
  // Handle "promise like" objects by casting to a real Promise.
487
- const intermediate = Promise.resolve(promise).then(value => {
493
+ const intermediate = Promise.resolve(promise).then(value => { // eslint-disable-line promise/prefer-await-to-then
488
494
  throw failPending(new AssertionError(message, {
489
495
  assertion: 't.throwsAsync()',
490
496
  assertionStack,
@@ -568,7 +574,10 @@ export class Assertions {
568
574
  try {
569
575
  assertMessage(message, 't.notThrowsAsync()');
570
576
  } catch (error) {
571
- Promise.resolve(nonThrower).catch(noop);
577
+ try {
578
+ await nonThrower;
579
+ } catch {}
580
+
572
581
  throw error;
573
582
  }
574
583
 
@@ -583,7 +592,7 @@ export class Assertions {
583
592
  // Create an error object to record the stack before it gets lost in the promise chain.
584
593
  const assertionStack = getAssertionStack();
585
594
  // Handle "promise like" objects by casting to a real Promise.
586
- const intermediate = Promise.resolve(promise).then(noop, error => {
595
+ const intermediate = Promise.resolve(promise).then(noop, error => { // eslint-disable-line promise/prefer-await-to-then
587
596
  throw failPending(new AssertionError(message, {
588
597
  assertion: 't.notThrowsAsync()',
589
598
  assertionStack,
package/lib/cli.js CHANGED
@@ -388,9 +388,15 @@ export default async function loadCli() { // eslint-disable-line complexity
388
388
  exit(error.message);
389
389
  }
390
390
 
391
+ const workerThreads = combined.workerThreads !== false;
392
+
391
393
  let nodeArguments;
392
394
  try {
393
395
  nodeArguments = normalizeNodeArguments(conf.nodeArguments, argv['node-arguments']);
396
+ if (workerThreads && 'filterNodeArgumentsForWorkerThreads' in conf) {
397
+ const {filterNodeArgumentsForWorkerThreads: filter} = conf;
398
+ nodeArguments = nodeArguments.filter(argument => filter(argument));
399
+ }
394
400
  } catch (error) {
395
401
  exit(error.message);
396
402
  }
@@ -41,10 +41,9 @@ const buildGlobs = ({conf, providers, projectDir, overrideExtensions, overrideFi
41
41
 
42
42
  const resolveGlobs = async (projectDir, overrideExtensions, overrideFiles) => {
43
43
  if (!configCache.has(projectDir)) {
44
- configCache.set(projectDir, loadConfig({resolveFrom: projectDir}).then(async ({config: conf}) => {
45
- const providers = await collectProviders({conf, projectDir});
46
- return {conf, providers};
47
- }));
44
+ const {config: conf} = await loadConfig({resolveFrom: projectDir});
45
+ const providers = await collectProviders({conf, projectDir});
46
+ configCache.set(projectDir, {conf, providers});
48
47
  }
49
48
 
50
49
  const {conf, providers} = await configCache.get(projectDir);
@@ -157,6 +157,13 @@ export async function loadConfig({configFile, resolveFrom = process.cwd(), defau
157
157
  ...defaults, nonSemVerExperiments: {}, ...fileConf, ...packageConf, projectDir, configFile,
158
158
  };
159
159
 
160
+ if (
161
+ 'filterNodeArgumentsForWorkerThreads' in config
162
+ && typeof config.filterNodeArgumentsForWorkerThreads !== 'function'
163
+ ) {
164
+ throw new Error(`filterNodeArgumentsForWorkerThreads from ${fileForErrorMessage} must be a function`);
165
+ }
166
+
160
167
  const {nonSemVerExperiments: experiments} = config;
161
168
  if (!isPlainObject(experiments)) {
162
169
  throw new Error(`nonSemVerExperiments from ${fileForErrorMessage} must be an object`);
@@ -16,6 +16,11 @@ const waitForAvailable = async worker => {
16
16
  }
17
17
  };
18
18
 
19
+ const waitForError = async worker => {
20
+ const [error] = await events.once(worker, 'error');
21
+ return tagWorkerError(error);
22
+ };
23
+
19
24
  function launchWorker(filename, initialData) {
20
25
  if (launchedWorkers.has(filename)) {
21
26
  return launchedWorkers.get(filename);
@@ -34,7 +39,7 @@ function launchWorker(filename, initialData) {
34
39
  const launched = {
35
40
  statePromises: {
36
41
  available: waitForAvailable(worker),
37
- error: events.once(worker, 'error').then(([error]) => tagWorkerError(error)),
42
+ error: waitForError(worker),
38
43
  },
39
44
  exited: false,
40
45
  worker,
@@ -79,7 +84,7 @@ export async function observeWorkerProcess(fork, runStatus) {
79
84
  }
80
85
  };
81
86
 
82
- fork.promise.finally(() => {
87
+ fork.promise.finally(() => { // eslint-disable-line promise/prefer-await-to-then
83
88
  removeAllInstances();
84
89
  });
85
90
 
@@ -94,7 +99,7 @@ export async function observeWorkerProcess(fork, runStatus) {
94
99
  }
95
100
  };
96
101
 
97
- launched.statePromises.error.then(error => {
102
+ launched.statePromises.error.then(error => { // eslint-disable-line promise/prefer-await-to-then
98
103
  launched.worker.off('message', handleWorkerMessage);
99
104
  removeAllInstances();
100
105
  runStatus.emitStateChange({type: 'shared-worker-error', err: serializeError(error)});
@@ -113,7 +118,7 @@ export async function observeWorkerProcess(fork, runStatus) {
113
118
  port,
114
119
  }, [port]);
115
120
 
116
- fork.promise.finally(() => {
121
+ fork.promise.finally(() => { // eslint-disable-line promise/prefer-await-to-then
117
122
  launched.worker.postMessage({
118
123
  type: 'deregister-test-worker',
119
124
  id: fork.threadId,
package/lib/runner.js CHANGED
@@ -489,7 +489,7 @@ export default class Runner extends Emittery {
489
489
 
490
490
  // Note that the hooks and tests always begin running asynchronously.
491
491
  const beforePromise = this.runHooks(this.tasks.before, contextRef);
492
- const serialPromise = beforePromise.then(beforeHooksOk => {
492
+ const serialPromise = beforePromise.then(beforeHooksOk => { // eslint-disable-line promise/prefer-await-to-then
493
493
  // Don't run tests if a `before` hook failed.
494
494
  if (!beforeHooksOk) {
495
495
  return false;
@@ -511,7 +511,7 @@ export default class Runner extends Emittery {
511
511
  return this.runTest(task, contextRef.copy());
512
512
  }, true);
513
513
  });
514
- const concurrentPromise = Promise.all([beforePromise, serialPromise]).then(async ([beforeHooksOk, serialOk]) => {
514
+ const concurrentPromise = Promise.all([beforePromise, serialPromise]).then(async ([beforeHooksOk, serialOk]) => { // eslint-disable-line promise/prefer-await-to-then
515
515
  // Don't run tests if a `before` hook failed, or if `failFast` is enabled
516
516
  // and a previous serial test failed.
517
517
  if (!beforeHooksOk || (!serialOk && this.failFast)) {
package/lib/test.js CHANGED
@@ -590,7 +590,7 @@ export default class Test {
590
590
  };
591
591
 
592
592
  promise
593
- .catch(error => {
593
+ .catch(error => { // eslint-disable-line promise/prefer-await-to-then
594
594
  if (this.testFailure !== null && error === this.testFailure) {
595
595
  return;
596
596
  }
@@ -607,7 +607,7 @@ export default class Test {
607
607
  }));
608
608
  }
609
609
  })
610
- .then(() => resolve(this.finish()));
610
+ .then(() => resolve(this.finish())); // eslint-disable-line promise/prefer-await-to-then
611
611
  });
612
612
  }
613
613
 
package/lib/watcher.js CHANGED
@@ -72,7 +72,7 @@ async function * plan({api, filter, globs, projectDir, providers, stdin, abortSi
72
72
  };
73
73
 
74
74
  // Begin a file trace in the background.
75
- fileTracer.update(findTests(cwdAndGlobs).then(testFiles => testFiles.map(path => ({
75
+ fileTracer.update(findTests(cwdAndGlobs).then(testFiles => testFiles.map(path => ({ // eslint-disable-line promise/prefer-await-to-then
76
76
  path: nodePath.relative(projectDir, path),
77
77
  isTest: true,
78
78
  exists: true,
@@ -187,7 +187,7 @@ async function * plan({api, filter, globs, projectDir, providers, stdin, abortSi
187
187
  // If the file tracer is still analyzing dependencies, wait for that to
188
188
  // complete.
189
189
  if (fileTracer.busy !== null) {
190
- fileTracer.busy.then(() => debounce.refresh());
190
+ fileTracer.busy.then(() => debounce.refresh()); // eslint-disable-line promise/prefer-await-to-then
191
191
  takeCoverageForSelfTests?.();
192
192
  return;
193
193
  }
@@ -526,7 +526,7 @@ class FileTracer {
526
526
  }
527
527
 
528
528
  update(changes) {
529
- const current = this.#update(changes).finally(() => {
529
+ const current = this.#update(changes).finally(() => { // eslint-disable-line promise/prefer-await-to-then
530
530
  if (this.#pendingTrace === current) {
531
531
  this.#pendingTrace = null;
532
532
  this.#updateRunning = new Promise(resolve => {
@@ -1,6 +1,6 @@
1
1
  import {mkdir} from 'node:fs/promises';
2
2
  import {createRequire} from 'node:module';
3
- import {join as joinPath, resolve as resolvePath} from 'node:path';
3
+ import path from 'node:path';
4
4
  import process from 'node:process';
5
5
  import {pathToFileURL} from 'node:url';
6
6
  import {workerData} from 'node:worker_threads';
@@ -89,7 +89,7 @@ const run = async options => {
89
89
 
90
90
  refs.runnerChain = runner.chain;
91
91
 
92
- channel.peerFailed.then(() => {
92
+ channel.peerFailed.then(() => { // eslint-disable-line promise/prefer-await-to-then
93
93
  runner.interrupt();
94
94
  });
95
95
 
@@ -187,7 +187,7 @@ const run = async options => {
187
187
 
188
188
  // Try to load the module as a file, relative to the project directory.
189
189
  // Match load() behavior.
190
- const fullPath = resolvePath(projectDir, ref);
190
+ const fullPath = path.resolve(projectDir, ref);
191
191
  try {
192
192
  for (const extension of extensionsToLoadAsModules) {
193
193
  if (fullPath.endsWith(`.${extension}`)) {
@@ -208,9 +208,9 @@ const run = async options => {
208
208
 
209
209
  let importFromProject = async ref => {
210
210
  // Do not use the cacheDir since it's not guaranteed to be inside node_modules.
211
- const avaCacheDir = joinPath(projectDir, 'node_modules', '.cache', 'ava');
211
+ const avaCacheDir = path.join(projectDir, 'node_modules', '.cache', 'ava');
212
212
  await mkdir(avaCacheDir, {recursive: true});
213
- const stubPath = joinPath(avaCacheDir, 'import-from-project.mjs');
213
+ const stubPath = path.join(avaCacheDir, 'import-from-project.mjs');
214
214
  await writeFileAtomic(stubPath, 'export const importFromProject = ref => import(ref);\n');
215
215
  ({importFromProject} = await import(pathToFileURL(stubPath)));
216
216
  return importFromProject(ref);
@@ -158,9 +158,9 @@ function registerSharedWorker(filename, initialData) {
158
158
  // The attaching of message listeners will cause the port to be referenced by
159
159
  // Node.js. In order to keep track, explicitly reference before attaching.
160
160
  sharedWorkerHandle.ref();
161
- const ready = selectAvaMessage(ourPort, 'ready').then(() => {
161
+ const ready = selectAvaMessage(ourPort, 'ready').then(() => { // eslint-disable-line promise/prefer-await-to-then
162
162
  currentlyAvailable = error === null;
163
- }).finally(() => {
163
+ }).finally(() => { // eslint-disable-line promise/prefer-await-to-then
164
164
  // Once ready, it's up to user code to subscribe to messages, which (see
165
165
  // below) causes us to reference the port.
166
166
  sharedWorkerHandle.unref();
@@ -170,7 +170,7 @@ function registerSharedWorker(filename, initialData) {
170
170
 
171
171
  // Errors are received over the test worker channel, not the message port
172
172
  // dedicated to the shared worker.
173
- events.once(channelEmitter, 'shared-worker-error').then(() => {
173
+ events.once(channelEmitter, 'shared-worker-error').then(() => { // eslint-disable-line promise/prefer-await-to-then
174
174
  unsubscribe();
175
175
  sharedWorkerHandle.forceUnref();
176
176
  error = new Error('The shared worker is no longer available');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ava",
3
- "version": "6.1.3",
3
+ "version": "6.2.0",
4
4
  "description": "Node.js test runner that lets you develop with confidence.",
5
5
  "license": "MIT",
6
6
  "repository": "avajs/ava",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "type": "module",
38
38
  "engines": {
39
- "node": "^18.18 || ^20.8 || ^21 || ^22"
39
+ "node": "^18.18 || ^20.8 || ^22 || >=23"
40
40
  },
41
41
  "scripts": {
42
42
  "test": "./scripts/test.sh"
@@ -83,14 +83,14 @@
83
83
  "typescript"
84
84
  ],
85
85
  "dependencies": {
86
- "@vercel/nft": "^0.26.2",
87
- "acorn": "^8.11.3",
88
- "acorn-walk": "^8.3.2",
86
+ "@vercel/nft": "^0.27.5",
87
+ "acorn": "^8.13.0",
88
+ "acorn-walk": "^8.3.4",
89
89
  "ansi-styles": "^6.2.1",
90
90
  "arrgv": "^1.0.2",
91
91
  "arrify": "^3.0.0",
92
- "callsites": "^4.1.0",
93
- "cbor": "^9.0.1",
92
+ "callsites": "^4.2.0",
93
+ "cbor": "^9.0.2",
94
94
  "chalk": "^5.3.0",
95
95
  "chunkd": "^2.0.1",
96
96
  "ci-info": "^4.0.0",
@@ -100,10 +100,10 @@
100
100
  "common-path-prefix": "^3.0.0",
101
101
  "concordance": "^5.0.4",
102
102
  "currently-unhandled": "^0.4.1",
103
- "debug": "^4.3.4",
104
- "emittery": "^1.0.1",
105
- "figures": "^6.0.1",
106
- "globby": "^14.0.0",
103
+ "debug": "^4.3.7",
104
+ "emittery": "^1.0.3",
105
+ "figures": "^6.1.0",
106
+ "globby": "^14.0.2",
107
107
  "ignore-by-default": "^2.1.0",
108
108
  "indent-string": "^5.0.0",
109
109
  "is-plain-object": "^5.0.0",
@@ -111,34 +111,34 @@
111
111
  "matcher": "^5.0.0",
112
112
  "memoize": "^10.0.0",
113
113
  "ms": "^2.1.3",
114
- "p-map": "^7.0.1",
114
+ "p-map": "^7.0.2",
115
115
  "package-config": "^5.0.0",
116
- "picomatch": "^3.0.1",
116
+ "picomatch": "^4.0.2",
117
117
  "plur": "^5.1.0",
118
- "pretty-ms": "^9.0.0",
118
+ "pretty-ms": "^9.1.0",
119
119
  "resolve-cwd": "^3.0.0",
120
120
  "stack-utils": "^2.0.6",
121
121
  "strip-ansi": "^7.1.0",
122
122
  "supertap": "^3.0.1",
123
123
  "temp-dir": "^3.0.0",
124
- "write-file-atomic": "^5.0.1",
124
+ "write-file-atomic": "^6.0.0",
125
125
  "yargs": "^17.7.2"
126
126
  },
127
127
  "devDependencies": {
128
128
  "@ava/test": "github:avajs/test",
129
- "@ava/typescript": "^4.1.0",
130
- "@sindresorhus/tsconfig": "^5.0.0",
131
- "@types/node": "^20.11.10",
132
- "ansi-escapes": "^6.2.0",
133
- "c8": "^9.1.0",
134
- "execa": "^8.0.1",
129
+ "@ava/typescript": "^5.0.0",
130
+ "@sindresorhus/tsconfig": "^5.1.1",
131
+ "@types/node": "^22.8.1",
132
+ "ansi-escapes": "^7.0.0",
133
+ "c8": "^10.1.2",
134
+ "execa": "^9.5.0",
135
135
  "expect": "^29.7.0",
136
- "sinon": "^17.0.1",
137
- "tap": "^18.7.0",
136
+ "sinon": "^19.0.2",
137
+ "tap": "^20.0.3",
138
138
  "tempy": "^3.1.0",
139
- "tsd": "^0.30.4",
140
- "typescript": "~5.3.3",
141
- "xo": "^0.57.0",
139
+ "tsd": "^0.31.2",
140
+ "typescript": "~5.6.3",
141
+ "xo": "^0.59.3",
142
142
  "zen-observable": "^0.10.0"
143
143
  },
144
144
  "peerDependencies": {
@@ -150,6 +150,6 @@
150
150
  }
151
151
  },
152
152
  "volta": {
153
- "node": "20.10.0"
153
+ "node": "22.10.0"
154
154
  }
155
155
  }