ava 7.0.0 → 8.0.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.
Files changed (61) hide show
  1. package/entrypoints/{eslint-plugin-helper.cjs → eslint-plugin-helper.js} +10 -13
  2. package/entrypoints/{internal.d.mts → internal.d.ts} +1 -1
  3. package/entrypoints/{main.d.mts → main.d.ts} +5 -5
  4. package/entrypoints/{main.mjs → main.js} +1 -1
  5. package/entrypoints/{plugin.d.cts → plugin.d.ts} +2 -2
  6. package/entrypoints/plugin.js +1 -0
  7. package/index.d.ts +2 -2
  8. package/lib/api-event-iterator.js +2 -2
  9. package/lib/api.js +6 -6
  10. package/lib/assert.js +6 -5
  11. package/lib/cli.js +7 -27
  12. package/lib/create-chain.js +68 -25
  13. package/lib/extensions.js +5 -7
  14. package/lib/fork.js +3 -3
  15. package/lib/{glob-helpers.cjs → glob-helpers.js} +16 -30
  16. package/lib/globs.js +3 -3
  17. package/lib/{ipc-flow-control.cjs → ipc-flow-control.js} +1 -4
  18. package/lib/load-config.js +2 -3
  19. package/lib/{now-and-timers.cjs → now-and-timers.js} +11 -8
  20. package/lib/pkg.js +1 -0
  21. package/lib/plugin-support/shared-worker-loader.js +2 -2
  22. package/lib/plugin-support/shared-workers.js +3 -3
  23. package/lib/provider-manager.js +6 -5
  24. package/lib/reporters/default.js +1 -1
  25. package/lib/reporters/improper-usage-messages.js +1 -1
  26. package/lib/reporters/tap.js +10 -4
  27. package/lib/runner.js +5 -5
  28. package/lib/scheduler.js +1 -1
  29. package/lib/snapshot-manager.js +2 -2
  30. package/lib/test.js +15 -8
  31. package/lib/watcher.js +10 -18
  32. package/lib/worker/base.js +17 -41
  33. package/lib/worker/{channel.cjs → channel.js} +21 -25
  34. package/lib/worker/completion-handlers.js +3 -3
  35. package/lib/worker/{guard-environment.cjs → guard-environment.js} +4 -5
  36. package/lib/worker/line-numbers.js +3 -7
  37. package/lib/worker/main.js +11 -0
  38. package/lib/worker/{options.cjs → options.js} +4 -5
  39. package/lib/worker/{plugin.cjs → plugin.js} +8 -10
  40. package/lib/worker/state.js +5 -0
  41. package/lib/worker/utils.js +5 -0
  42. package/package.json +28 -36
  43. package/plugin.d.ts +1 -1
  44. package/types/{test-fn.d.cts → test-fn.d.ts} +24 -3
  45. package/types/{try-fn.d.cts → try-fn.d.ts} +1 -2
  46. package/entrypoints/main.cjs +0 -2
  47. package/entrypoints/main.d.cts +0 -12
  48. package/entrypoints/plugin.cjs +0 -2
  49. package/entrypoints/plugin.d.mts +0 -6
  50. package/entrypoints/plugin.mjs +0 -4
  51. package/lib/module-types.js +0 -85
  52. package/lib/pkg.cjs +0 -2
  53. package/lib/slash.cjs +0 -36
  54. package/lib/worker/main.cjs +0 -12
  55. package/lib/worker/state.cjs +0 -6
  56. package/lib/worker/utils.cjs +0 -6
  57. /package/entrypoints/{cli.mjs → cli.js} +0 -0
  58. /package/types/{assertions.d.cts → assertions.d.ts} +0 -0
  59. /package/types/{shared-worker.d.cts → shared-worker.d.ts} +0 -0
  60. /package/types/{state-change-events.d.cts → state-change-events.d.ts} +0 -0
  61. /package/types/{subscribable.d.cts → subscribable.d.ts} +0 -0
@@ -1,17 +1,16 @@
1
- 'use strict';
2
- const path = require('node:path');
3
- const url = require('node:url');
4
- const v8 = require('node:v8');
5
- const {Worker} = require('node:worker_threads');
1
+ import path from 'node:path';
2
+ import {pathToFileURL} from 'node:url';
3
+ import v8 from 'node:v8';
4
+ import {Worker} from 'node:worker_threads';
6
5
 
7
- const {
6
+ import {
8
7
  classify,
9
8
  hasExtension,
10
9
  isHelperish,
11
10
  matches,
12
11
  normalizeFileForMatching,
13
12
  normalizePatterns,
14
- } = require('../lib/glob-helpers.cjs');
13
+ } from '../lib/glob-helpers.js';
15
14
 
16
15
  const MAX_DATA_LENGTH_EXCLUSIVE = 100 * 1024; // Allocate 100 KiB to exchange globs.
17
16
 
@@ -27,8 +26,8 @@ const resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => {
27
26
  const syncBuffer = new SharedArrayBuffer(4);
28
27
  sync = new Int32Array(syncBuffer);
29
28
 
30
- const filename = path.join(__dirname, '../lib/eslint-plugin-helper-worker.js');
31
- worker = new Worker(url.pathToFileURL(filename), {
29
+ const filename = path.join(import.meta.dirname, '../lib/eslint-plugin-helper-worker.js');
30
+ worker = new Worker(pathToFileURL(filename), {
32
31
  workerData: {
33
32
  dataBuffer,
34
33
  syncBuffer,
@@ -60,7 +59,7 @@ const resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => {
60
59
 
61
60
  const helperCache = new Map();
62
61
 
63
- function load(projectDir, overrides) {
62
+ export function load(projectDir, overrides) {
64
63
  const cacheKey = `${JSON.stringify(overrides)}\n${projectDir}`;
65
64
  if (helperCache.has(cacheKey)) {
66
65
  return helperCache.get(cacheKey);
@@ -69,7 +68,7 @@ function load(projectDir, overrides) {
69
68
  let helperPatterns = [];
70
69
  if (overrides && overrides.helpers !== undefined) {
71
70
  if (!Array.isArray(overrides.helpers) || overrides.helpers.length === 0) {
72
- throw new Error('The ’helpers’ override must be an array containing glob patterns.');
71
+ throw new Error('The \u2018helpers\u2019 override must be an array containing glob patterns.');
73
72
  }
74
73
 
75
74
  helperPatterns = normalizePatterns(overrides.helpers);
@@ -105,5 +104,3 @@ function load(projectDir, overrides) {
105
104
  helperCache.set(cacheKey, helper);
106
105
  return helper;
107
106
  }
108
-
109
- exports.load = load;
@@ -1,4 +1,4 @@
1
- import type {StateChangeEvent} from '../types/state-change-events.d.cts';
1
+ import type {StateChangeEvent} from '../types/state-change-events.js';
2
2
 
3
3
  export type Event = StateChangeEvent;
4
4
 
@@ -1,9 +1,9 @@
1
- import type {TestFn} from '../types/test-fn.cjs';
1
+ import type {TestFn} from '../types/test-fn.js';
2
2
 
3
- export type * from '../types/assertions.cjs';
4
- export type * from '../types/try-fn.cjs';
5
- export type * from '../types/test-fn.cjs';
6
- export type * from '../types/subscribable.cjs';
3
+ export type * from '../types/assertions.js';
4
+ export type * from '../types/try-fn.js';
5
+ export type * from '../types/test-fn.js';
6
+ export type * from '../types/subscribable.js';
7
7
 
8
8
  /** Call to declare a test, or chain to declare hooks or test modifiers */
9
9
  declare const test: TestFn;
@@ -1,2 +1,2 @@
1
- export {default} from '../lib/worker/main.cjs';
1
+ export {default} from '../lib/worker/main.js';
2
2
  export {registerCompletionHandler} from '../lib/worker/completion-handlers.js';
@@ -1,6 +1,6 @@
1
- import type {SharedWorker} from '../types/shared-worker.cjs';
1
+ import type {SharedWorker} from '../types/shared-worker.js';
2
2
 
3
3
  export function registerSharedWorker<Data = unknown>(options: SharedWorker.Plugin.RegistrationOptions<'ava-4', Data>): SharedWorker.Plugin.Protocol<Data>;
4
4
  // Add overloads for additional protocols.
5
5
 
6
- export type {SharedWorker} from '../types/shared-worker.cjs';
6
+ export type {SharedWorker} from '../types/shared-worker.js';
@@ -0,0 +1 @@
1
+ export {registerSharedWorker} from '../lib/worker/plugin.js';
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  // For compatibility with resolution algorithms other than Node16.
2
2
 
3
- export * from './entrypoints/main.cjs';
4
- export {default} from './entrypoints/main.cjs';
3
+ export * from './entrypoints/main.js';
4
+ export {default} from './entrypoints/main.js';
@@ -1,8 +1,8 @@
1
1
  export async function * asyncEventIteratorFromApi(api) {
2
2
  // TODO: support multiple runs (watch mode)
3
- const {value: plan} = await api.events('run').next();
3
+ const {value: {data: plan}} = await api.events('run').next();
4
4
 
5
- for await (const stateChange of plan.status.events('stateChange')) {
5
+ for await (const {data: stateChange} of plan.status.events('stateChange')) {
6
6
  yield stateChange;
7
7
 
8
8
  if (stateChange.type === 'end' || stateChange.type === 'interrupt') {
package/lib/api.js CHANGED
@@ -15,7 +15,7 @@ import fork from './fork.js';
15
15
  import * as globs from './globs.js';
16
16
  import isCi from './is-ci.js';
17
17
  import {getApplicableLineNumbers} from './line-numbers.js';
18
- import {setCappedTimeout} from './now-and-timers.cjs';
18
+ import {setCappedTimeout} from './now-and-timers.js';
19
19
  import {observeWorkerProcess} from './plugin-support/shared-workers.js';
20
20
  import RunStatus from './run-status.js';
21
21
  import scheduler from './scheduler.js';
@@ -77,7 +77,7 @@ export default class Api extends Emittery {
77
77
  constructor(options) {
78
78
  super();
79
79
 
80
- this.options = {match: [], moduleTypes: {}, ...options};
80
+ this.options = {match: [], ...options};
81
81
  this.options.require = normalizeRequireOption(this.options.require);
82
82
 
83
83
  this._cacheDir = null;
@@ -180,7 +180,7 @@ export default class Api extends Emittery {
180
180
 
181
181
  // The files must be in the same order across all runs, so sort them.
182
182
  const defaultComparator = (a, b) => a.localeCompare(b, [], {numeric: true});
183
- selectedFiles = selectedFiles.sort(this.options.sortTestFiles ?? defaultComparator);
183
+ selectedFiles = selectedFiles.toSorted(this.options.sortTestFiles ?? defaultComparator);
184
184
  selectedFiles = chunkd(selectedFiles, currentIndex, totalRuns);
185
185
 
186
186
  const currentFileCount = selectedFiles.length;
@@ -189,7 +189,7 @@ export default class Api extends Emittery {
189
189
  } else {
190
190
  // If a custom sorter was configured, use it.
191
191
  if (this.options.sortTestFiles) {
192
- selectedFiles = selectedFiles.sort(this.options.sortTestFiles);
192
+ selectedFiles = selectedFiles.toSorted(this.options.sortTestFiles);
193
193
  }
194
194
 
195
195
  runStatus = new RunStatus(selectedFiles.length, null, selectionInsights);
@@ -220,7 +220,7 @@ export default class Api extends Emittery {
220
220
  return runStatus;
221
221
  }
222
222
 
223
- runStatus.on('stateChange', record => {
223
+ runStatus.on('stateChange', ({data: record}) => {
224
224
  if (record.testFile && !timedOutWorkerFiles.has(record.testFile) && record.type !== 'worker-stderr' && record.type !== 'worker-stdout') {
225
225
  // Debounce the timer whenever there is test-related activity from workers that haven't already timed out.
226
226
  timeoutTrigger.debounce();
@@ -293,7 +293,7 @@ export default class Api extends Emittery {
293
293
  deregisteredSharedWorkers.push(observeWorkerProcess(worker, runStatus));
294
294
 
295
295
  pendingWorkers.add(worker);
296
- worker.promise.then(() => { // eslint-disable-line promise/prefer-await-to-then
296
+ worker.promise.then(() => {
297
297
  pendingWorkers.delete(worker);
298
298
  });
299
299
  timeoutTrigger.debounce();
package/lib/assert.js CHANGED
@@ -29,6 +29,7 @@ function formatWithLabel(label, value) {
29
29
  }
30
30
 
31
31
  const noop = () => {};
32
+
32
33
  const notImplemented = () => {
33
34
  throw new Error('not implemented');
34
35
  };
@@ -423,7 +424,7 @@ export class Assertions {
423
424
  retval = fn();
424
425
  if (isPromise(retval)) {
425
426
  // Here isPromise() checks if something is "promise like". Cast to an actual promise.
426
- Promise.resolve(retval).catch(noop); // eslint-disable-line promise/prefer-await-to-then
427
+ Promise.resolve(retval).catch(noop);
427
428
  throw fail(new AssertionError(message, {
428
429
  assertion: 't.throws()',
429
430
  formattedDetails: [formatWithLabel('Function returned a promise. Use `t.throwsAsync()` instead:', retval)],
@@ -490,7 +491,7 @@ export class Assertions {
490
491
  // Record the stack before it gets lost in the promise chain.
491
492
  const assertionStack = getAssertionStack();
492
493
  // Handle "promise like" objects by casting to a real Promise.
493
- const intermediate = Promise.resolve(promise).then(value => { // eslint-disable-line promise/prefer-catch, promise/prefer-await-to-then
494
+ const intermediate = Promise.resolve(promise).then(value => {
494
495
  throw failPending(new AssertionError(message, {
495
496
  assertion: 't.throwsAsync()',
496
497
  assertionStack,
@@ -512,7 +513,7 @@ export class Assertions {
512
513
  }
513
514
  });
514
515
 
515
- pending(intermediate);
516
+ pending(intermediate, assertionStack);
516
517
  return intermediate;
517
518
  };
518
519
 
@@ -592,14 +593,14 @@ export class Assertions {
592
593
  // Create an error object to record the stack before it gets lost in the promise chain.
593
594
  const assertionStack = getAssertionStack();
594
595
  // Handle "promise like" objects by casting to a real Promise.
595
- const intermediate = Promise.resolve(promise).then(noop, error => { // eslint-disable-line promise/prefer-catch, promise/prefer-await-to-then
596
+ const intermediate = Promise.resolve(promise).then(noop, error => {
596
597
  throw failPending(new AssertionError(message, {
597
598
  assertion: 't.notThrowsAsync()',
598
599
  assertionStack,
599
600
  formattedDetails: [formatWithLabel(`${wasReturned ? 'Returned promise' : 'Promise'} rejected with:`, error)],
600
601
  }));
601
602
  });
602
- pending(intermediate);
603
+ pending(intermediate, assertionStack);
603
604
 
604
605
  await intermediate;
605
606
  return true;
package/lib/cli.js CHANGED
@@ -17,9 +17,8 @@ import {normalizeGlobs, normalizePattern} from './globs.js';
17
17
  import isCi from './is-ci.js';
18
18
  import {splitPatternAndLineNumbers} from './line-numbers.js';
19
19
  import {loadConfig} from './load-config.js';
20
- import normalizeModuleTypes from './module-types.js';
21
20
  import normalizeNodeArguments from './node-arguments.js';
22
- import pkg from './pkg.cjs';
21
+ import pkg from './pkg.js';
23
22
 
24
23
  function exit(message) {
25
24
  console.error(`\n ${chalk.red(figures.cross)} ${message}`);
@@ -334,17 +333,6 @@ export default async function loadCli() { // eslint-disable-line complexity
334
333
  console.log(chalk.magenta(` ${figures.warning} Experiments are enabled. These are unsupported and may change or be removed at any time.`));
335
334
  }
336
335
 
337
- let projectPackageObject;
338
- try {
339
- projectPackageObject = JSON.parse(fs.readFileSync(path.resolve(projectDir, 'package.json')));
340
- } catch (error) {
341
- if (error.code !== 'ENOENT') {
342
- throw error;
343
- }
344
- }
345
-
346
- const {type: defaultModuleType = 'commonjs'} = projectPackageObject ?? {};
347
-
348
336
  const providers = [];
349
337
  if (Object.hasOwn(conf, 'typescript')) {
350
338
  const {default: providerManager} = await import('./provider-manager.js');
@@ -375,13 +363,6 @@ export default async function loadCli() { // eslint-disable-line complexity
375
363
  exit(error.message);
376
364
  }
377
365
 
378
- let moduleTypes;
379
- try {
380
- moduleTypes = normalizeModuleTypes(conf.extensions, defaultModuleType, experiments);
381
- } catch (error) {
382
- exit(error.message);
383
- }
384
-
385
366
  let globs;
386
367
  try {
387
368
  globs = normalizeGlobs({
@@ -436,7 +417,6 @@ export default async function loadCli() { // eslint-disable-line complexity
436
417
  failWithoutAssertions: combined.failWithoutAssertions !== false,
437
418
  globs,
438
419
  match,
439
- moduleTypes,
440
420
  nodeArguments,
441
421
  parallelRuns,
442
422
  sortTestFiles: conf.sortTestFiles,
@@ -472,11 +452,11 @@ export default async function loadCli() { // eslint-disable-line complexity
472
452
  }
473
453
 
474
454
  if (process.env.TEST_AVA) {
475
- const {controlFlow} = await import('./ipc-flow-control.cjs');
455
+ const {controlFlow} = await import('./ipc-flow-control.js');
476
456
  const bufferedSend = controlFlow(process);
477
457
 
478
- api.on('run', plan => {
479
- plan.status.on('stateChange', evt => {
458
+ api.on('run', ({data: plan}) => {
459
+ plan.status.on('stateChange', ({data: evt}) => {
480
460
  bufferedSend(evt);
481
461
  });
482
462
  });
@@ -488,10 +468,10 @@ export default async function loadCli() { // eslint-disable-line complexity
488
468
  });
489
469
  }
490
470
 
491
- api.on('run', plan => {
471
+ api.on('run', ({data: plan}) => {
492
472
  reporter.startRun(plan);
493
473
 
494
- plan.status.on('stateChange', evt => {
474
+ plan.status.on('stateChange', ({data: evt}) => {
495
475
  if (evt.type === 'end' || evt.type === 'interrupt') {
496
476
  // Write out code coverage data when the run ends, lest a process
497
477
  // interrupt causes it to be lost.
@@ -537,7 +517,7 @@ export default async function loadCli() { // eslint-disable-line complexity
537
517
  });
538
518
  } else {
539
519
  let debugWithoutSpecificFile = false;
540
- api.on('run', plan => {
520
+ api.on('run', ({data: plan}) => {
541
521
  if (debug !== null && plan.files.length !== 1) {
542
522
  debugWithoutSpecificFile = true;
543
523
  }
@@ -39,6 +39,70 @@ function callWithFlag(previous, flag, args) {
39
39
  } while (previous);
40
40
  }
41
41
 
42
+ function getSkippedTarget(target) {
43
+ let current = target;
44
+ while (current) {
45
+ if (current.skip) {
46
+ return current.skip;
47
+ }
48
+
49
+ current = chainRegistry.get(current)?.prev;
50
+ }
51
+
52
+ return target;
53
+ }
54
+
55
+ function createConditionalChain(node, shouldSkip) {
56
+ return new Proxy(node, {
57
+ apply(target, thisArg, argumentsList) {
58
+ return (shouldSkip ? getSkippedTarget(target) : target).apply(thisArg, argumentsList);
59
+ },
60
+ get(target, prop, receiver) {
61
+ // Proxy invariant: non-configurable properties must return invariant-safe values.
62
+ const descriptor = Object.getOwnPropertyDescriptor(target, prop);
63
+ if (descriptor && !descriptor.configurable) {
64
+ if ('value' in descriptor && !descriptor.writable) {
65
+ return descriptor.value;
66
+ }
67
+
68
+ if ('get' in descriptor && descriptor.get === undefined) {
69
+ return undefined;
70
+ }
71
+ }
72
+
73
+ if (prop === 'skipIf' || prop === 'runIf') {
74
+ return typeof target[prop] === 'function'
75
+ ? condition => createConditionalChain(target, shouldSkip || (prop === 'skipIf' ? condition : !condition))
76
+ : undefined;
77
+ }
78
+
79
+ const value = Reflect.get(target, prop, receiver);
80
+ if (chainRegistry.has(value)) {
81
+ const {call, defaults} = chainRegistry.get(value);
82
+ if (!call || (defaults.type === 'test' && !defaults.todo)) {
83
+ return createConditionalChain(value, shouldSkip);
84
+ }
85
+
86
+ return value;
87
+ }
88
+
89
+ if (
90
+ shouldSkip
91
+ && value === undefined
92
+ ) {
93
+ return Reflect.get(getSkippedTarget(target), prop);
94
+ }
95
+
96
+ return value;
97
+ },
98
+ });
99
+ }
100
+
101
+ function addConditionalModifiers(node) {
102
+ node.skipIf = condition => createConditionalChain(node, condition);
103
+ node.runIf = condition => createConditionalChain(node, !condition);
104
+ }
105
+
42
106
  function createHookChain(hook, isAfterHook) {
43
107
  // Hook chaining rules:
44
108
  // * `always` comes immediately after "after hooks"
@@ -74,6 +138,10 @@ export default function createChain(fn, defaults, meta) {
74
138
  extendChain(root.serial.failing, 'only', 'exclusive');
75
139
  extendChain(root.serial.failing, 'skip', 'skipped');
76
140
 
141
+ for (const node of [root, root.serial, root.failing, root.serial.failing]) {
142
+ addConditionalModifiers(node);
143
+ }
144
+
77
145
  root.after = createHookChain(startChain('test.after', fn, {...defaults, type: 'after'}), true);
78
146
  root.afterEach = createHookChain(startChain('test.afterEach', fn, {...defaults, type: 'afterEach'}), true);
79
147
  root.before = createHookChain(startChain('test.before', fn, {...defaults, type: 'before'}), false);
@@ -101,30 +169,5 @@ export default function createChain(fn, defaults, meta) {
101
169
 
102
170
  root.meta = meta;
103
171
 
104
- // The ESM and CJS type definitions export the chain (`test()` function) as
105
- // the default. TypeScript's CJS output (when `esModuleInterop` is disabled)
106
- // assume `require('ava').default` is available. The same goes for `import ava
107
- // = require('ava')` syntax.
108
- //
109
- // Add `test.default` to make this work. Use a proxy to avoid
110
- // `test.default.default` chains.
111
- Object.defineProperty(root, 'default', {
112
- configurable: false,
113
- enumerable: false,
114
- writable: false,
115
- value: new Proxy(root, {
116
- apply(target, thisArg, argumentsList) {
117
- target.apply(thisArg, argumentsList);
118
- },
119
- get(target, prop) {
120
- if (prop === 'default') {
121
- throw new TypeError('Cannot access default.default');
122
- }
123
-
124
- return target[prop];
125
- },
126
- }),
127
- });
128
-
129
172
  return root;
130
173
  }
package/lib/extensions.js CHANGED
@@ -3,10 +3,8 @@ export default function resolveExtensions(configuredExtensions, providers = [])
3
3
  const duplicates = new Set();
4
4
  const seen = new Set();
5
5
 
6
- const normalize = extensions => Array.isArray(extensions) ? extensions : Object.keys(extensions);
7
-
8
6
  const combine = extensions => {
9
- for (const ext of normalize(extensions)) {
7
+ for (const ext of extensions) {
10
8
  if (seen.has(ext)) {
11
9
  duplicates.add(ext);
12
10
  } else {
@@ -16,6 +14,10 @@ export default function resolveExtensions(configuredExtensions, providers = [])
16
14
  };
17
15
 
18
16
  if (configuredExtensions !== undefined) {
17
+ if (!Array.isArray(configuredExtensions)) {
18
+ throw new TypeError('The extensions option must be an array');
19
+ }
20
+
19
21
  combine(configuredExtensions);
20
22
  }
21
23
 
@@ -29,10 +31,6 @@ export default function resolveExtensions(configuredExtensions, providers = [])
29
31
 
30
32
  // Unless the default was used by providers, as long as the extensions aren't explicitly set, set the default.
31
33
  if (configuredExtensions === undefined) {
32
- if (!seen.has('cjs')) {
33
- seen.add('cjs');
34
- }
35
-
36
34
  if (!seen.has('mjs')) {
37
35
  seen.add('mjs');
38
36
  }
package/lib/fork.js CHANGED
@@ -5,7 +5,7 @@ import {Worker} from 'node:worker_threads';
5
5
 
6
6
  import Emittery from 'emittery';
7
7
 
8
- import {controlFlow} from './ipc-flow-control.cjs';
8
+ import {controlFlow} from './ipc-flow-control.js';
9
9
  import serializeError, {tagWorkerError} from './serialize-error.js';
10
10
 
11
11
  let workerPath = new URL('worker/base.js', import.meta.url);
@@ -168,11 +168,11 @@ export default function loadFork(file, options, execArgv = process.execArgv) {
168
168
  },
169
169
 
170
170
  onConnectSharedWorker(listener) {
171
- return emitter.on('connectSharedWorker', listener);
171
+ return emitter.on('connectSharedWorker', ({data}) => listener(data));
172
172
  },
173
173
 
174
174
  onStateChange(listener) {
175
- return emitter.on('stateChange', listener);
175
+ return emitter.on('stateChange', ({data}) => listener(data));
176
176
  },
177
177
  };
178
178
  }
@@ -1,14 +1,12 @@
1
- 'use strict';
2
- const path = require('node:path');
3
- const process = require('node:process');
1
+ import path from 'node:path';
2
+ import process from 'node:process';
4
3
 
5
- const ignoreByDefault = require('ignore-by-default');
6
- const picomatch = require('picomatch');
7
-
8
- const slash = require('./slash.cjs');
4
+ import ignoreByDefault from 'ignore-by-default';
5
+ import picomatch from 'picomatch';
6
+ import slash from 'slash';
9
7
 
10
8
  const defaultIgnorePatterns = [...ignoreByDefault.directories(), '**/node_modules'];
11
- exports.defaultIgnorePatterns = defaultIgnorePatterns;
9
+ export {defaultIgnorePatterns};
12
10
 
13
11
  const defaultPicomatchIgnorePatterns = [
14
12
  ...defaultIgnorePatterns,
@@ -42,22 +40,20 @@ const processMatchingPatterns = input => {
42
40
  return result;
43
41
  };
44
42
 
45
- exports.processMatchingPatterns = processMatchingPatterns;
43
+ export {processMatchingPatterns};
46
44
 
47
- function classify(file, {cwd, extensions, filePatterns}) {
45
+ export function classify(file, {cwd, extensions, filePatterns}) {
48
46
  file = normalizeFileForMatching(cwd, file);
49
47
  return {
50
48
  isTest: hasExtension(extensions, file) && !isHelperish(file) && filePatterns.length > 0 && matches(file, filePatterns),
51
49
  };
52
50
  }
53
51
 
54
- exports.classify = classify;
55
-
56
- const hasExtension = (extensions, file) => extensions.includes(path.extname(file).slice(1));
57
-
58
- exports.hasExtension = hasExtension;
52
+ export function hasExtension(extensions, file) {
53
+ return extensions.includes(path.extname(file).slice(1));
54
+ }
59
55
 
60
- function isHelperish(file) { // Assume file has been normalized already.
56
+ export function isHelperish(file) { // Assume file has been normalized already.
61
57
  // File names starting with an underscore are deemed "helpers".
62
58
  if (path.basename(file).startsWith('_')) {
63
59
  return true;
@@ -75,16 +71,12 @@ function isHelperish(file) { // Assume file has been normalized already.
75
71
  return path.dirname(file).split('/').some(dir => /^_(?:$|[^_])/.test(dir));
76
72
  }
77
73
 
78
- exports.isHelperish = isHelperish;
79
-
80
- function matches(file, patterns) {
74
+ export function matches(file, patterns) {
81
75
  const {match} = processMatchingPatterns(patterns);
82
76
  return match(file);
83
77
  }
84
78
 
85
- exports.matches = matches;
86
-
87
- function normalizeFileForMatching(cwd, file) {
79
+ export function normalizeFileForMatching(cwd, file) {
88
80
  if (process.platform === 'win32') {
89
81
  cwd = slash(cwd);
90
82
  file = slash(file);
@@ -101,9 +93,7 @@ function normalizeFileForMatching(cwd, file) {
101
93
  return file.slice(cwd.length + 1);
102
94
  }
103
95
 
104
- exports.normalizeFileForMatching = normalizeFileForMatching;
105
-
106
- function normalizePattern(pattern) {
96
+ export function normalizePattern(pattern) {
107
97
  // Always use `/` in patterns, harmonizing matching across platforms
108
98
  if (process.platform === 'win32') {
109
99
  pattern = slash(pattern);
@@ -124,10 +114,6 @@ function normalizePattern(pattern) {
124
114
  return pattern;
125
115
  }
126
116
 
127
- exports.normalizePattern = normalizePattern;
128
-
129
- function normalizePatterns(patterns) {
117
+ export function normalizePatterns(patterns) {
130
118
  return patterns.map(pattern => normalizePattern(pattern));
131
119
  }
132
-
133
- exports.normalizePatterns = normalizePatterns;
package/lib/globs.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  normalizeFileForMatching,
11
11
  normalizePatterns,
12
12
  processMatchingPatterns,
13
- } from './glob-helpers.cjs';
13
+ } from './glob-helpers.js';
14
14
 
15
15
  export {
16
16
  classify,
@@ -21,12 +21,12 @@ export {
21
21
  hasExtension,
22
22
  normalizeFileForMatching,
23
23
  normalizePatterns,
24
- } from './glob-helpers.cjs';
24
+ } from './glob-helpers.js';
25
25
 
26
26
  const defaultIgnoredByWatcherPatterns = [
27
27
  '**/*.snap.md', // No need to rerun tests when the Markdown files change.
28
+ '**/*.tsbuildinfo', // No need to rerun tests when TypeScript build info files change.
28
29
  'ava.config.js', // Config is not reloaded so avoid rerunning tests when it changes.
29
- 'ava.config.cjs', // Config is not reloaded so avoid rerunning tests when it changes.
30
30
  'ava.config.mjs', // Config is not reloaded so avoid rerunning tests when it changes.
31
31
  ];
32
32
 
@@ -1,5 +1,4 @@
1
- 'use strict';
2
- function controlFlow(channel) {
1
+ export function controlFlow(channel) {
3
2
  let errored = false;
4
3
  let deliverImmediately = true;
5
4
 
@@ -36,5 +35,3 @@ function controlFlow(channel) {
36
35
  }
37
36
  };
38
37
  }
39
-
40
- exports.controlFlow = controlFlow;
@@ -94,8 +94,8 @@ export async function loadConfig({configFile, resolveFrom = process.cwd(), defau
94
94
  try {
95
95
  loaded = await loadConfigFile({projectDir, configFile});
96
96
  } catch (error) {
97
- if (!configFile.endsWith('.js') && !configFile.endsWith('.cjs') && !configFile.endsWith('.mjs')) {
98
- throw Object.assign(new Error('Could not load config file; it should have .js, .cjs or .mjs extension'), {cause: error});
97
+ if (!configFile.endsWith('.js') && !configFile.endsWith('.mjs')) {
98
+ throw Object.assign(new Error('Could not load config file; it should have .js or .mjs extension'), {cause: error});
99
99
  }
100
100
 
101
101
  throw error;
@@ -111,7 +111,6 @@ export async function loadConfig({configFile, resolveFrom = process.cwd(), defau
111
111
  const [jsonFile, ...results] = await Promise.all([ // eslint-disable-line no-await-in-loop
112
112
  checkJsonFile(searchDir),
113
113
  loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.js')}),
114
- loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.cjs')}),
115
114
  loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.mjs')}),
116
115
  ]);
117
116
 
@@ -1,16 +1,19 @@
1
- 'use strict';
2
- const timers = require('node:timers');
1
+ export {
2
+ setTimeout,
3
+ clearTimeout,
4
+ setImmediate,
5
+ setInterval,
6
+ clearInterval,
7
+ clearImmediate,
8
+ } from 'node:timers';
3
9
 
4
- Object.assign(exports, timers);
5
- exports.now = Date.now;
10
+ export const {now} = Date;
6
11
 
7
12
  // Any delay larger than this value is ignored by Node.js, with a delay of `1`
8
13
  // used instead. See <https://nodejs.org/api/timers.html#settimeoutcallback-delay-args>.
9
14
  const MAX_DELAY = (2 ** 31) - 1;
10
15
 
11
- function setCappedTimeout(callback, delay) {
16
+ export function setCappedTimeout(callback, delay) {
12
17
  const safeDelay = Math.min(delay, MAX_DELAY);
13
- return timers.setTimeout(callback, safeDelay);
18
+ return globalThis.setTimeout(callback, safeDelay);
14
19
  }
15
-
16
- exports.setCappedTimeout = setCappedTimeout;
package/lib/pkg.js ADDED
@@ -0,0 +1 @@
1
+ export {default} from '../package.json' with {type: 'json'};