ava 3.15.0 → 4.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 (72) hide show
  1. package/entrypoints/cli.mjs +4 -0
  2. package/entrypoints/eslint-plugin-helper.cjs +109 -0
  3. package/entrypoints/main.cjs +2 -0
  4. package/entrypoints/main.mjs +1 -0
  5. package/entrypoints/plugin.cjs +2 -0
  6. package/entrypoints/plugin.mjs +4 -0
  7. package/index.d.ts +6 -816
  8. package/lib/api.js +108 -49
  9. package/lib/assert.js +255 -270
  10. package/lib/chalk.js +9 -14
  11. package/lib/cli.js +118 -112
  12. package/lib/code-excerpt.js +12 -17
  13. package/lib/concordance-options.js +29 -65
  14. package/lib/context-ref.js +3 -6
  15. package/lib/create-chain.js +32 -20
  16. package/lib/environment-variables.js +1 -4
  17. package/lib/eslint-plugin-helper-worker.js +73 -0
  18. package/lib/extensions.js +2 -2
  19. package/lib/fork.js +81 -84
  20. package/lib/glob-helpers.cjs +140 -0
  21. package/lib/globs.js +136 -163
  22. package/lib/{ipc-flow-control.js → ipc-flow-control.cjs} +1 -0
  23. package/lib/is-ci.js +4 -2
  24. package/lib/like-selector.js +7 -13
  25. package/lib/line-numbers.js +11 -18
  26. package/lib/load-config.js +56 -180
  27. package/lib/module-types.js +3 -7
  28. package/lib/node-arguments.js +4 -5
  29. package/lib/{now-and-timers.js → now-and-timers.cjs} +0 -0
  30. package/lib/parse-test-args.js +22 -11
  31. package/lib/pkg.cjs +2 -0
  32. package/lib/plugin-support/shared-worker-loader.js +45 -48
  33. package/lib/plugin-support/shared-workers.js +24 -46
  34. package/lib/provider-manager.js +20 -14
  35. package/lib/reporters/beautify-stack.js +6 -12
  36. package/lib/reporters/colors.js +40 -15
  37. package/lib/reporters/default.js +114 -364
  38. package/lib/reporters/format-serialized-error.js +7 -18
  39. package/lib/reporters/improper-usage-messages.js +8 -9
  40. package/lib/reporters/prefix-title.js +17 -15
  41. package/lib/reporters/tap.js +18 -25
  42. package/lib/run-status.js +29 -23
  43. package/lib/runner.js +157 -172
  44. package/lib/scheduler.js +53 -0
  45. package/lib/serialize-error.js +61 -64
  46. package/lib/snapshot-manager.js +271 -289
  47. package/lib/test.js +135 -291
  48. package/lib/watcher.js +69 -44
  49. package/lib/worker/base.js +208 -0
  50. package/lib/worker/channel.cjs +290 -0
  51. package/lib/worker/dependency-tracker.js +24 -23
  52. package/lib/worker/{ensure-forked.js → guard-environment.cjs} +5 -4
  53. package/lib/worker/line-numbers.js +58 -20
  54. package/lib/worker/main.cjs +12 -0
  55. package/lib/worker/{options.js → options.cjs} +0 -0
  56. package/lib/worker/{plugin.js → plugin.cjs} +30 -21
  57. package/lib/worker/state.cjs +5 -0
  58. package/lib/worker/utils.cjs +6 -0
  59. package/package.json +71 -68
  60. package/plugin.d.ts +51 -53
  61. package/readme.md +5 -13
  62. package/types/assertions.d.ts +327 -0
  63. package/types/subscribable.ts +6 -0
  64. package/types/test-fn.d.ts +231 -0
  65. package/types/try-fn.d.ts +58 -0
  66. package/cli.js +0 -11
  67. package/eslint-plugin-helper.js +0 -201
  68. package/index.js +0 -8
  69. package/lib/worker/ipc.js +0 -201
  70. package/lib/worker/main.js +0 -21
  71. package/lib/worker/subprocess.js +0 -266
  72. package/plugin.js +0 -9
@@ -0,0 +1,140 @@
1
+ 'use strict';
2
+ const path = require('path');
3
+ const process = require('process');
4
+
5
+ const ignoreByDefault = require('ignore-by-default');
6
+ const picomatch = require('picomatch');
7
+ const slash = require('slash');
8
+
9
+ const defaultIgnorePatterns = [...ignoreByDefault.directories(), '**/node_modules'];
10
+ exports.defaultIgnorePatterns = defaultIgnorePatterns;
11
+
12
+ const defaultPicomatchIgnorePatterns = [
13
+ ...defaultIgnorePatterns,
14
+ // Unlike globby(), picomatch needs a complete pattern when ignoring directories.
15
+ ...defaultIgnorePatterns.map(pattern => `${pattern}/**/*`),
16
+ ];
17
+
18
+ const defaultMatchNoIgnore = picomatch(defaultPicomatchIgnorePatterns);
19
+
20
+ const matchingCache = new WeakMap();
21
+ const processMatchingPatterns = input => {
22
+ let result = matchingCache.get(input);
23
+ if (!result) {
24
+ const ignore = [...defaultPicomatchIgnorePatterns];
25
+ const patterns = input.filter(pattern => {
26
+ if (pattern.startsWith('!')) {
27
+ // Unlike globby(), picomatch needs a complete pattern when ignoring directories.
28
+ ignore.push(pattern.slice(1), `${pattern.slice(1)}/**/*`);
29
+ return false;
30
+ }
31
+
32
+ return true;
33
+ });
34
+
35
+ result = {
36
+ match: picomatch(patterns, {ignore}),
37
+ matchNoIgnore: picomatch(patterns),
38
+ individualMatchers: patterns.map(pattern => ({pattern, match: picomatch(pattern, {ignore})})),
39
+ };
40
+ matchingCache.set(input, result);
41
+ }
42
+
43
+ return result;
44
+ };
45
+
46
+ exports.processMatchingPatterns = processMatchingPatterns;
47
+
48
+ const matchesIgnorePatterns = (file, patterns) => {
49
+ const {matchNoIgnore} = processMatchingPatterns(patterns);
50
+ return matchNoIgnore(file) || defaultMatchNoIgnore(file);
51
+ };
52
+
53
+ function classify(file, {cwd, extensions, filePatterns, ignoredByWatcherPatterns}) {
54
+ file = normalizeFileForMatching(cwd, file);
55
+ return {
56
+ isIgnoredByWatcher: matchesIgnorePatterns(file, ignoredByWatcherPatterns),
57
+ isTest: hasExtension(extensions, file) && !isHelperish(file) && filePatterns.length > 0 && matches(file, filePatterns),
58
+ };
59
+ }
60
+
61
+ exports.classify = classify;
62
+
63
+ const hasExtension = (extensions, file) => extensions.includes(path.extname(file).slice(1));
64
+
65
+ exports.hasExtension = hasExtension;
66
+
67
+ function isHelperish(file) { // Assume file has been normalized already.
68
+ // File names starting with an underscore are deemed "helpers".
69
+ if (path.basename(file).startsWith('_')) {
70
+ return true;
71
+ }
72
+
73
+ // This function assumes the file has been normalized. If it couldn't be,
74
+ // don't check if it's got a parent directory that starts with an underscore.
75
+ // Deem it not a "helper".
76
+ if (path.isAbsolute(file)) {
77
+ return false;
78
+ }
79
+
80
+ // If the file has a parent directory that starts with only a single
81
+ // underscore, it's deemed a "helper".
82
+ return path.dirname(file).split('/').some(dir => /^_(?:$|[^_])/.test(dir));
83
+ }
84
+
85
+ exports.isHelperish = isHelperish;
86
+
87
+ function matches(file, patterns) {
88
+ const {match} = processMatchingPatterns(patterns);
89
+ return match(file);
90
+ }
91
+
92
+ exports.matches = matches;
93
+
94
+ function normalizeFileForMatching(cwd, file) {
95
+ if (process.platform === 'win32') {
96
+ cwd = slash(cwd);
97
+ file = slash(file);
98
+ }
99
+
100
+ // Note that if `file` is outside `cwd` we can't normalize it. If this turns
101
+ // out to be a real-world scenario we may have to make changes in calling code
102
+ // to make sure the file isn't even selected for matching.
103
+ if (!file.startsWith(cwd)) {
104
+ return file;
105
+ }
106
+
107
+ // Assume `cwd` does *not* end in a slash.
108
+ return file.slice(cwd.length + 1);
109
+ }
110
+
111
+ exports.normalizeFileForMatching = normalizeFileForMatching;
112
+
113
+ function normalizePattern(pattern) {
114
+ // Always use `/` in patterns, harmonizing matching across platforms
115
+ if (process.platform === 'win32') {
116
+ pattern = slash(pattern);
117
+ }
118
+
119
+ if (pattern.endsWith('/')) {
120
+ pattern = pattern.slice(0, -1);
121
+ }
122
+
123
+ if (pattern.startsWith('./')) {
124
+ return pattern.slice(2);
125
+ }
126
+
127
+ if (pattern.startsWith('!./')) {
128
+ return `!${pattern.slice(3)}`;
129
+ }
130
+
131
+ return pattern;
132
+ }
133
+
134
+ exports.normalizePattern = normalizePattern;
135
+
136
+ function normalizePatterns(patterns) {
137
+ return patterns.map(pattern => normalizePattern(pattern));
138
+ }
139
+
140
+ exports.normalizePatterns = normalizePatterns;
package/lib/globs.js CHANGED
@@ -1,54 +1,36 @@
1
- 'use strict';
2
- const path = require('path');
3
- const globby = require('globby');
4
- const ignoreByDefault = require('ignore-by-default');
5
- const picomatch = require('picomatch');
6
- const slash = require('slash');
7
- const providerManager = require('./provider-manager');
8
-
9
- const defaultIgnorePatterns = [...ignoreByDefault.directories(), '**/node_modules'];
10
- const defaultPicomatchIgnorePatterns = [
11
- ...defaultIgnorePatterns,
12
- // Unlike globby(), picomatch needs a complete pattern when ignoring directories.
13
- ...defaultIgnorePatterns.map(pattern => `${pattern}/**/*`)
14
- ];
15
-
16
- const defaultMatchNoIgnore = picomatch(defaultPicomatchIgnorePatterns);
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import {globby, globbySync} from 'globby';
5
+
6
+ import {
7
+ defaultIgnorePatterns,
8
+ hasExtension,
9
+ normalizeFileForMatching,
10
+ normalizePatterns,
11
+ processMatchingPatterns,
12
+ } from './glob-helpers.cjs';
13
+
14
+ export {
15
+ classify,
16
+ isHelperish,
17
+ matches,
18
+ normalizePattern,
19
+ defaultIgnorePatterns,
20
+ hasExtension,
21
+ normalizeFileForMatching,
22
+ normalizePatterns,
23
+ } from './glob-helpers.cjs';
17
24
 
18
25
  const defaultIgnoredByWatcherPatterns = [
19
26
  '**/*.snap.md', // No need to rerun tests when the Markdown files change.
20
27
  'ava.config.js', // Config is not reloaded so avoid rerunning tests when it changes.
21
- 'ava.config.cjs' // Config is not reloaded so avoid rerunning tests when it changes.
28
+ 'ava.config.cjs', // Config is not reloaded so avoid rerunning tests when it changes.
22
29
  ];
23
30
 
24
31
  const buildExtensionPattern = extensions => extensions.length === 1 ? extensions[0] : `{${extensions.join(',')}}`;
25
32
 
26
- function normalizePattern(pattern) {
27
- // Always use `/` in patterns, harmonizing matching across platforms
28
- if (process.platform === 'win32') {
29
- pattern = slash(pattern);
30
- }
31
-
32
- if (pattern.startsWith('./')) {
33
- return pattern.slice(2);
34
- }
35
-
36
- if (pattern.startsWith('!./')) {
37
- return `!${pattern.slice(3)}`;
38
- }
39
-
40
- return pattern;
41
- }
42
-
43
- exports.normalizePattern = normalizePattern;
44
-
45
- function normalizePatterns(patterns) {
46
- return patterns.map(pattern => normalizePattern(pattern));
47
- }
48
-
49
- exports.normalizePatterns = normalizePatterns;
50
-
51
- function normalizeGlobs({extensions, files: filePatterns, ignoredByWatcher: ignoredByWatcherPatterns, providers}) {
33
+ export function normalizeGlobs({extensions, files: filePatterns, ignoredByWatcher: ignoredByWatcherPatterns, providers}) {
52
34
  if (filePatterns !== undefined && (!Array.isArray(filePatterns) || filePatterns.length === 0)) {
53
35
  throw new Error('The ’files’ configuration must be an array containing glob patterns.');
54
36
  }
@@ -68,7 +50,7 @@ function normalizeGlobs({extensions, files: filePatterns, ignoredByWatcher: igno
68
50
  `**/test/**/*.${extensionPattern}`,
69
51
  `**/tests/**/*.${extensionPattern}`,
70
52
  '!**/__tests__/**/__{helper,fixture}?(s)__/**/*',
71
- '!**/test?(s)/**/{helper,fixture}?(s)/**/*'
53
+ '!**/test?(s)/**/{helper,fixture}?(s)/**/*',
72
54
  ];
73
55
 
74
56
  if (filePatterns) {
@@ -84,40 +66,36 @@ function normalizeGlobs({extensions, files: filePatterns, ignoredByWatcher: igno
84
66
 
85
67
  ignoredByWatcherPatterns = ignoredByWatcherPatterns ? [...defaultIgnoredByWatcherPatterns, ...normalizePatterns(ignoredByWatcherPatterns)] : [...defaultIgnoredByWatcherPatterns];
86
68
 
87
- for (const {level, main} of providers) {
88
- if (level >= providerManager.levels.pathRewrites) {
89
- ({filePatterns, ignoredByWatcherPatterns} = main.updateGlobs({filePatterns, ignoredByWatcherPatterns}));
90
- }
69
+ for (const {main} of providers) {
70
+ ({filePatterns, ignoredByWatcherPatterns} = main.updateGlobs({filePatterns, ignoredByWatcherPatterns}));
91
71
  }
92
72
 
93
73
  return {extensions, filePatterns, ignoredByWatcherPatterns};
94
74
  }
95
75
 
96
- exports.normalizeGlobs = normalizeGlobs;
97
-
98
- const hasExtension = (extensions, file) => extensions.includes(path.extname(file).slice(1));
99
-
100
- exports.hasExtension = hasExtension;
76
+ const globOptions = {
77
+ // Globs should work relative to the cwd value only (this should be the
78
+ // project directory that AVA is run in).
79
+ absolute: false,
80
+ braceExpansion: true,
81
+ caseSensitiveMatch: false,
82
+ dot: false,
83
+ expandDirectories: false,
84
+ extglob: true,
85
+ followSymbolicLinks: true,
86
+ gitignore: false,
87
+ globstar: true,
88
+ ignore: defaultIgnorePatterns,
89
+ baseNameMatch: false,
90
+ stats: false,
91
+ unique: true,
92
+ };
101
93
 
102
94
  const globFiles = async (cwd, patterns) => {
103
95
  const files = await globby(patterns, {
104
- // Globs should work relative to the cwd value only (this should be the
105
- // project directory that AVA is run in).
106
- absolute: false,
107
- braceExpansion: true,
108
- caseSensitiveMatch: false,
96
+ ...globOptions,
109
97
  cwd,
110
- dot: false,
111
- expandDirectories: false,
112
- extglob: true,
113
- followSymbolicLinks: true,
114
- gitignore: false,
115
- globstar: true,
116
- ignore: defaultIgnorePatterns,
117
- baseNameMatch: false,
118
98
  onlyFiles: true,
119
- stats: false,
120
- unique: true
121
99
  });
122
100
 
123
101
  // Return absolute file paths. This has the side-effect of normalizing paths
@@ -125,119 +103,114 @@ const globFiles = async (cwd, patterns) => {
125
103
  return files.map(file => path.join(cwd, file));
126
104
  };
127
105
 
128
- async function findFiles({cwd, extensions, filePatterns}) {
129
- return (await globFiles(cwd, filePatterns)).filter(file => hasExtension(extensions, file));
130
- }
106
+ const globDirectoriesSync = (cwd, patterns) => {
107
+ const files = globbySync(patterns, {
108
+ ...globOptions,
109
+ cwd,
110
+ onlyDirectories: true,
111
+ });
131
112
 
132
- exports.findFiles = findFiles;
113
+ // Return absolute file paths. This has the side-effect of normalizing paths
114
+ // on Windows.
115
+ return files.map(file => path.join(cwd, file));
116
+ };
133
117
 
134
- async function findTests({cwd, extensions, filePatterns}) {
135
- return (await findFiles({cwd, extensions, filePatterns})).filter(file => !path.basename(file).startsWith('_'));
118
+ export async function findFiles({cwd, extensions, filePatterns}) {
119
+ const files = await globFiles(cwd, filePatterns);
120
+ return files.filter(file => hasExtension(extensions, file));
136
121
  }
137
122
 
138
- exports.findTests = findTests;
123
+ export async function findTests({cwd, extensions, filePatterns}) {
124
+ const files = await findFiles({cwd, extensions, filePatterns});
125
+ return files.filter(file => !path.basename(file).startsWith('_'));
126
+ }
139
127
 
140
- function getChokidarIgnorePatterns({ignoredByWatcherPatterns}) {
128
+ export function getChokidarIgnorePatterns({ignoredByWatcherPatterns}) {
141
129
  return [
142
130
  ...defaultIgnorePatterns.map(pattern => `${pattern}/**/*`),
143
- ...ignoredByWatcherPatterns.filter(pattern => !pattern.startsWith('!'))
131
+ ...ignoredByWatcherPatterns.filter(pattern => !pattern.startsWith('!')),
144
132
  ];
145
133
  }
146
134
 
147
- exports.getChokidarIgnorePatterns = getChokidarIgnorePatterns;
148
-
149
- const matchingCache = new WeakMap();
150
- const processMatchingPatterns = input => {
151
- let result = matchingCache.get(input);
152
- if (!result) {
153
- const ignore = [...defaultPicomatchIgnorePatterns];
154
- const patterns = input.filter(pattern => {
155
- if (pattern.startsWith('!')) {
156
- // Unlike globby(), picomatch needs a complete pattern when ignoring directories.
157
- ignore.push(pattern.slice(1), `${pattern.slice(1)}/**/*`);
158
- return false;
135
+ export function applyTestFileFilter({ // eslint-disable-line complexity
136
+ cwd,
137
+ expandDirectories = true,
138
+ filter,
139
+ providers = [],
140
+ testFiles,
141
+ treatFilterPatternsAsFiles = true,
142
+ }) {
143
+ const {individualMatchers} = processMatchingPatterns(filter);
144
+ const normalizedFiles = testFiles.map(file => ({file, matcheable: normalizeFileForMatching(cwd, file)}));
145
+
146
+ const selected = new Set();
147
+ const unmatchedPatterns = new Set(individualMatchers.map(({pattern}) => pattern));
148
+
149
+ for (const {pattern, match} of individualMatchers) {
150
+ for (const {file, matcheable} of normalizedFiles) {
151
+ if (match(matcheable)) {
152
+ unmatchedPatterns.delete(pattern);
153
+ selected.add(file);
159
154
  }
160
-
161
- return true;
162
- });
163
-
164
- result = {
165
- match: picomatch(patterns, {ignore}),
166
- matchNoIgnore: picomatch(patterns)
167
- };
168
- matchingCache.set(input, result);
169
- }
170
-
171
- return result;
172
- };
173
-
174
- function matches(file, patterns) {
175
- const {match} = processMatchingPatterns(patterns);
176
- return match(file);
177
- }
178
-
179
- exports.matches = matches;
180
-
181
- const matchesIgnorePatterns = (file, patterns) => {
182
- const {matchNoIgnore} = processMatchingPatterns(patterns);
183
- return matchNoIgnore(file) || defaultMatchNoIgnore(file);
184
- };
185
-
186
- function normalizeFileForMatching(cwd, file) {
187
- if (process.platform === 'win32') {
188
- cwd = slash(cwd);
189
- file = slash(file);
155
+ }
190
156
  }
191
157
 
192
- if (!cwd) { // TODO: Ensure tests provide an actual value.
193
- return file;
194
- }
158
+ if (expandDirectories && unmatchedPatterns.size > 0) {
159
+ const expansion = [];
160
+ for (const pattern of unmatchedPatterns) {
161
+ const directories = globDirectoriesSync(cwd, pattern);
162
+ if (directories.length > 0) {
163
+ unmatchedPatterns.delete(pattern);
164
+ expansion.push(directories);
165
+ }
166
+ }
195
167
 
196
- // TODO: If `file` is outside `cwd` we can't normalize it. Need to figure
197
- // out if that's a real-world scenario, but we may have to ensure the file
198
- // isn't even selected.
199
- if (!file.startsWith(cwd)) {
200
- return file;
168
+ const directories = expansion.flat();
169
+ if (directories.length > 0) {
170
+ for (const file of testFiles) {
171
+ if (selected.has(file)) {
172
+ continue;
173
+ }
174
+
175
+ for (const dir of directories) {
176
+ if (file.startsWith(dir + path.sep)) { // eslint-disable-line max-depth
177
+ selected.add(file);
178
+ }
179
+ }
180
+ }
181
+ }
201
182
  }
202
183
 
203
- // Assume `cwd` does *not* end in a slash.
204
- return file.slice(cwd.length + 1);
205
- }
206
-
207
- exports.normalizeFileForMatching = normalizeFileForMatching;
184
+ const ignoredFilterPatternFiles = [];
185
+ if (treatFilterPatternsAsFiles && unmatchedPatterns.size > 0) {
186
+ const providerExtensions = new Set(providers.flatMap(({main}) => main.extensions));
187
+ for (const pattern of unmatchedPatterns) {
188
+ const file = path.join(cwd, pattern);
189
+ try {
190
+ const stats = fs.statSync(file);
191
+ if (!stats.isFile()) {
192
+ continue;
193
+ }
194
+ } catch (error) {
195
+ if (error.code === 'ENOENT') {
196
+ continue;
197
+ }
198
+
199
+ throw error;
200
+ }
208
201
 
209
- function isHelperish(file) { // Assume file has been normalized already.
210
- // File names starting with an underscore are deemed "helpers".
211
- if (path.basename(file).startsWith('_')) {
212
- return true;
213
- }
202
+ if (
203
+ path.basename(file).startsWith('_')
204
+ || providerExtensions.has(path.extname(file).slice(1))
205
+ || file.split(path.sep).includes('node_modules')
206
+ ) {
207
+ ignoredFilterPatternFiles.push(pattern);
208
+ continue;
209
+ }
214
210
 
215
- // This function assumes the file has been normalized. If it couldn't be,
216
- // don't check if it's got a parent directory that starts with an underscore.
217
- // Deem it not a "helper".
218
- if (path.isAbsolute(file)) {
219
- return false;
211
+ selected.add(file);
212
+ }
220
213
  }
221
214
 
222
- // If the file has a parent directory that starts with only a single
223
- // underscore, it's deemed a "helper".
224
- return path.dirname(file).split('/').some(dir => /^_(?:$|[^_])/.test(dir));
215
+ return Object.assign([...selected], {ignoredFilterPatternFiles});
225
216
  }
226
-
227
- exports.isHelperish = isHelperish;
228
-
229
- function classify(file, {cwd, extensions, filePatterns, ignoredByWatcherPatterns}) {
230
- file = normalizeFileForMatching(cwd, file);
231
- return {
232
- isIgnoredByWatcher: matchesIgnorePatterns(file, ignoredByWatcherPatterns),
233
- isTest: hasExtension(extensions, file) && !isHelperish(file) && filePatterns.length > 0 && matches(file, filePatterns)
234
- };
235
- }
236
-
237
- exports.classify = classify;
238
-
239
- function applyTestFileFilter({cwd, filter, testFiles}) {
240
- return testFiles.filter(file => matches(normalizeFileForMatching(cwd, file), filter));
241
- }
242
-
243
- exports.applyTestFileFilter = applyTestFileFilter;
@@ -1,3 +1,4 @@
1
+ 'use strict';
1
2
  function controlFlow(channel) {
2
3
  let errored = false;
3
4
  let deliverImmediately = true;
package/lib/is-ci.js CHANGED
@@ -1,5 +1,7 @@
1
- const info = require('ci-info');
1
+ import process from 'node:process';
2
+
3
+ import info from 'ci-info';
2
4
 
3
5
  const {AVA_FORCE_CI} = process.env;
4
6
 
5
- module.exports = AVA_FORCE_CI === 'not-ci' ? false : AVA_FORCE_CI === 'ci' || info.isCI;
7
+ export default AVA_FORCE_CI === 'not-ci' ? false : AVA_FORCE_CI === 'ci' || info.isCI;
@@ -1,17 +1,13 @@
1
- 'use strict';
2
- function isLikeSelector(selector) {
3
- return selector !== null &&
4
- typeof selector === 'object' &&
5
- Reflect.getPrototypeOf(selector) === Object.prototype &&
6
- Reflect.ownKeys(selector).length > 0;
1
+ export function isLikeSelector(selector) {
2
+ return selector !== null
3
+ && typeof selector === 'object'
4
+ && Reflect.getPrototypeOf(selector) === Object.prototype
5
+ && Reflect.ownKeys(selector).length > 0;
7
6
  }
8
7
 
9
- exports.isLikeSelector = isLikeSelector;
8
+ export const CIRCULAR_SELECTOR = new Error('Encountered a circular selector');
10
9
 
11
- const CIRCULAR_SELECTOR = new Error('Encountered a circular selector');
12
- exports.CIRCULAR_SELECTOR = CIRCULAR_SELECTOR;
13
-
14
- function selectComparable(lhs, selector, circular = new Set()) {
10
+ export function selectComparable(lhs, selector, circular = new Set()) {
15
11
  if (circular.has(selector)) {
16
12
  throw CIRCULAR_SELECTOR;
17
13
  }
@@ -33,5 +29,3 @@ function selectComparable(lhs, selector, circular = new Set()) {
33
29
 
34
30
  return comparable;
35
31
  }
36
-
37
- exports.selectComparable = selectComparable;
@@ -1,7 +1,4 @@
1
- 'use strict';
2
-
3
- const picomatch = require('picomatch');
4
- const flatten = require('lodash/flatten');
1
+ import picomatch from 'picomatch';
5
2
 
6
3
  const NUMBER_REGEX = /^\d+$/;
7
4
  const RANGE_REGEX = /^(?<startGroup>\d+)-(?<endGroup>\d+)$/;
@@ -17,10 +14,10 @@ const sortNumbersAscending = array => {
17
14
 
18
15
  const parseNumber = string => Number.parseInt(string, 10);
19
16
  const removeAllWhitespace = string => string.replace(/\s/g, '');
20
- const range = (start, end) => new Array(end - start + 1).fill(start).map((element, index) => element + index);
17
+ const range = (start, end) => Array.from({length: end - start + 1}).fill(start).map((element, index) => element + index);
21
18
 
22
- const parseLineNumbers = suffix => sortNumbersAscending(distinctArray(flatten(
23
- suffix.split(',').map(part => {
19
+ const parseLineNumbers = suffix => sortNumbersAscending(distinctArray(
20
+ suffix.split(',').flatMap(part => {
24
21
  if (NUMBER_REGEX.test(part)) {
25
22
  return parseNumber(part);
26
23
  }
@@ -34,10 +31,10 @@ const parseLineNumbers = suffix => sortNumbersAscending(distinctArray(flatten(
34
31
  }
35
32
 
36
33
  return range(start, end);
37
- })
38
- )));
34
+ }),
35
+ ));
39
36
 
40
- function splitPatternAndLineNumbers(pattern) {
37
+ export function splitPatternAndLineNumbers(pattern) {
41
38
  const parts = pattern.split(DELIMITER);
42
39
  if (parts.length === 1) {
43
40
  return {pattern, lineNumbers: null};
@@ -51,14 +48,10 @@ function splitPatternAndLineNumbers(pattern) {
51
48
  return {pattern: parts.join(DELIMITER), lineNumbers: parseLineNumbers(suffix)};
52
49
  }
53
50
 
54
- exports.splitPatternAndLineNumbers = splitPatternAndLineNumbers;
55
-
56
- function getApplicableLineNumbers(normalizedFilePath, filter) {
57
- return sortNumbersAscending(distinctArray(flatten(
51
+ export function getApplicableLineNumbers(normalizedFilePath, filter) {
52
+ return sortNumbersAscending(distinctArray(
58
53
  filter
59
54
  .filter(({pattern, lineNumbers}) => lineNumbers && picomatch.isMatch(normalizedFilePath, pattern))
60
- .map(({lineNumbers}) => lineNumbers)
61
- )));
55
+ .flatMap(({lineNumbers}) => lineNumbers),
56
+ ));
62
57
  }
63
-
64
- exports.getApplicableLineNumbers = getApplicableLineNumbers;