apify-test-tools 0.10.2-beta.19 → 0.10.2-beta.20
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/.github/cli/apify-test-tools.mjs +114 -114
- package/.github/scripts/run-with-apify-tokens.mjs +6 -6
- package/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml +1 -1
- package/.github/workflows/public_platform-tests.yaml +6 -8
- package/.github/workflows/public_pr-build-test.yaml +11 -11
- package/.github/workflows/public_push-build-latest.yaml +1 -0
- package/CHANGELOG.md +1 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +10 -6
- package/bin/affected-actors.ts +20 -7
- package/bin/diff-changes.ts +40 -16
- package/bin/main.ts +12 -19
- package/bin/run-tests.ts +29 -4
- package/bin/test-files-glob.ts +126 -0
- package/bin/utils/config/load-config.ts +4 -1
- package/bin/utils/config/parser.ts +24 -1
- package/dist/bin/affected-actors.d.ts +13 -4
- package/dist/bin/affected-actors.d.ts.map +1 -1
- package/dist/bin/affected-actors.js +11 -4
- package/dist/bin/affected-actors.js.map +1 -1
- package/dist/bin/diff-changes.d.ts +12 -3
- package/dist/bin/diff-changes.d.ts.map +1 -1
- package/dist/bin/diff-changes.js +25 -12
- package/dist/bin/diff-changes.js.map +1 -1
- package/dist/bin/main.js +11 -17
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/run-tests.d.ts +3 -3
- package/dist/bin/run-tests.d.ts.map +1 -1
- package/dist/bin/run-tests.js +24 -2
- package/dist/bin/run-tests.js.map +1 -1
- package/dist/bin/test-files-glob.d.ts +18 -0
- package/dist/bin/test-files-glob.d.ts.map +1 -0
- package/dist/bin/test-files-glob.js +108 -0
- package/dist/bin/test-files-glob.js.map +1 -0
- package/dist/bin/utils/config/load-config.d.ts +3 -0
- package/dist/bin/utils/config/load-config.d.ts.map +1 -1
- package/dist/bin/utils/config/load-config.js +3 -1
- package/dist/bin/utils/config/load-config.js.map +1 -1
- package/dist/bin/utils/config/parser.d.ts +9 -0
- package/dist/bin/utils/config/parser.d.ts.map +1 -1
- package/dist/bin/utils/config/parser.js +13 -1
- package/dist/bin/utils/config/parser.js.map +1 -1
- package/dist/test/bundle/cli-bundle.test.js +1 -1
- package/dist/test/bundle/cli-bundle.test.js.map +1 -1
- package/dist/test/e2e/cli-bundle.e2e.test.js +1 -1
- package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -1
- package/dist/test/unit/bin/actor-filtering.test.js +7 -0
- package/dist/test/unit/bin/actor-filtering.test.js.map +1 -1
- package/dist/test/unit/bin/affected-actors-cli.test.js +59 -2
- package/dist/test/unit/bin/affected-actors-cli.test.js.map +1 -1
- package/dist/test/unit/bin/affected-actors.test.js +18 -6
- package/dist/test/unit/bin/affected-actors.test.js.map +1 -1
- package/dist/test/unit/bin/diff-changes.test.js +44 -19
- package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
- package/dist/test/unit/bin/test-cli.test.js +34 -3
- package/dist/test/unit/bin/test-cli.test.js.map +1 -1
- package/dist/test/unit/bin/test-files-glob.test.d.ts +2 -0
- package/dist/test/unit/bin/test-files-glob.test.d.ts.map +1 -0
- package/dist/test/unit/bin/test-files-glob.test.js +102 -0
- package/dist/test/unit/bin/test-files-glob.test.js.map +1 -0
- package/dist/test/unit/bin/utils/config/parser.test.js +16 -1
- package/dist/test/unit/bin/utils/config/parser.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/cli.md +46 -29
- package/docs/workflows.md +53 -20
- package/package.json +1 -1
- package/test/bundle/cli-bundle.test.ts +1 -1
- package/test/e2e/cli-bundle.e2e.test.ts +9 -5
- package/test/unit/bin/actor-filtering.test.ts +8 -0
- package/test/unit/bin/affected-actors-cli.test.ts +73 -3
- package/test/unit/bin/affected-actors.test.ts +49 -10
- package/test/unit/bin/diff-changes.test.ts +48 -19
- package/test/unit/bin/test-cli.test.ts +41 -3
- package/test/unit/bin/test-files-glob.test.ts +118 -0
- package/test/unit/bin/utils/config/parser.test.ts +24 -1
|
@@ -71,6 +71,10 @@ const changedActorsFor = async ({
|
|
|
71
71
|
return options.actorConfigs.filter((config) => changed.includes(config));
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
+
// The Actors whose platform tests run because of a test change
|
|
75
|
+
const testChangedActorsFor = async (options: Parameters<typeof getChangedActors>[0]): Promise<ActorConfig[]> =>
|
|
76
|
+
(await getChangedActors(options)).test;
|
|
77
|
+
|
|
74
78
|
describe('getChangedActors', () => {
|
|
75
79
|
beforeEach(() => {
|
|
76
80
|
vi.restoreAllMocks();
|
|
@@ -404,34 +408,58 @@ describe('getChangedActors', () => {
|
|
|
404
408
|
expect(result).toEqual([miniActor]);
|
|
405
409
|
});
|
|
406
410
|
|
|
407
|
-
it('test file listed in .dockerignore
|
|
411
|
+
it('test file listed in .dockerignore is a test change when it matches the platform tests glob', async () => {
|
|
408
412
|
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.startsWith('test/'));
|
|
409
|
-
const
|
|
413
|
+
const options = {
|
|
410
414
|
filepathsChanged: ['test/platform/daily/foo.test.ts'],
|
|
411
415
|
actorConfigs: [miniActor],
|
|
412
416
|
range,
|
|
413
|
-
|
|
417
|
+
platformTestsGlob: 'test/platform/**',
|
|
418
|
+
};
|
|
419
|
+
expect(await testChangedActorsFor(options)).toEqual([miniActor]);
|
|
420
|
+
// A test change needs no build of its own, neither for a PR nor for a release
|
|
421
|
+
expect(await changedActorsFor({ ...options, isLatest: true })).toEqual([]);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it('a test change that is not listed in .dockerignore is still only a test change', async () => {
|
|
425
|
+
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => false);
|
|
426
|
+
const options = {
|
|
427
|
+
filepathsChanged: ['test/platform/utils.ts'],
|
|
428
|
+
actorConfigs: [miniActor],
|
|
429
|
+
range,
|
|
430
|
+
platformTestsGlob: 'test/platform/**',
|
|
431
|
+
};
|
|
432
|
+
expect(await testChangedActorsFor(options)).toEqual([miniActor]);
|
|
433
|
+
expect(await changedActorsFor({ ...options, isLatest: true })).toEqual([]);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('lists an Actor with both source and test changes as functional and as test changed', async () => {
|
|
437
|
+
const result = await getChangedActors({
|
|
438
|
+
filepathsChanged: ['test/platform/daily/foo.test.ts', 'actors/foo_bar/src/main.ts'],
|
|
439
|
+
actorConfigs: [miniActor],
|
|
440
|
+
range,
|
|
441
|
+
platformTestsGlob: 'test/platform/**',
|
|
414
442
|
});
|
|
415
|
-
expect(result).
|
|
443
|
+
expect(result).toStrictEqual({ functional: [miniActor], cosmetic: [], test: [miniActor] });
|
|
416
444
|
});
|
|
417
445
|
|
|
418
|
-
it('test file listed in .dockerignore stays ignored without a
|
|
446
|
+
it('test file listed in .dockerignore stays ignored without a platform tests glob', async () => {
|
|
419
447
|
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.startsWith('test/'));
|
|
420
|
-
const result = await
|
|
448
|
+
const result = await getChangedActors({
|
|
421
449
|
filepathsChanged: ['test/platform/daily/foo.test.ts'],
|
|
422
450
|
actorConfigs: [miniActor],
|
|
423
451
|
range,
|
|
424
452
|
});
|
|
425
|
-
expect(result).
|
|
453
|
+
expect(result).toStrictEqual({ functional: [], cosmetic: [], test: [] });
|
|
426
454
|
});
|
|
427
455
|
|
|
428
|
-
it('
|
|
456
|
+
it('platform tests glob matches case-insensitively and does not bypass .dockerignore for other files', async () => {
|
|
429
457
|
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => true);
|
|
430
|
-
const result = await
|
|
458
|
+
const result = await testChangedActorsFor({
|
|
431
459
|
filepathsChanged: ['Test/Platform/Foo.test.ts'],
|
|
432
460
|
actorConfigs: [miniActor],
|
|
433
461
|
range,
|
|
434
|
-
|
|
462
|
+
platformTestsGlob: 'test/platform/**',
|
|
435
463
|
});
|
|
436
464
|
expect(result).toEqual([miniActor]);
|
|
437
465
|
expect(
|
|
@@ -439,7 +467,7 @@ describe('getChangedActors', () => {
|
|
|
439
467
|
filepathsChanged: ['actors/foo_bar/node_modules/foo.js'],
|
|
440
468
|
actorConfigs: [miniActor],
|
|
441
469
|
range,
|
|
442
|
-
|
|
470
|
+
platformTestsGlob: 'test/platform/**',
|
|
443
471
|
}),
|
|
444
472
|
).toEqual([]);
|
|
445
473
|
});
|
|
@@ -450,7 +478,7 @@ describe('getChangedActors', () => {
|
|
|
450
478
|
filepathsChanged: ['test/platform/daily/foo.test.ts'],
|
|
451
479
|
actorConfigs: [standaloneActor],
|
|
452
480
|
range,
|
|
453
|
-
|
|
481
|
+
platformTestsGlob: 'test/platform/**',
|
|
454
482
|
});
|
|
455
483
|
expect(result).toEqual([]);
|
|
456
484
|
});
|
|
@@ -461,11 +489,11 @@ describe('getChangedActors', () => {
|
|
|
461
489
|
...standaloneActor,
|
|
462
490
|
contextPaths: [...standaloneActor.contextPaths, new RelativeDir('test')],
|
|
463
491
|
};
|
|
464
|
-
const result = await
|
|
492
|
+
const result = await testChangedActorsFor({
|
|
465
493
|
filepathsChanged: ['test/platform/standalone.test.ts'],
|
|
466
494
|
actorConfigs: [actorWithTests],
|
|
467
495
|
range,
|
|
468
|
-
|
|
496
|
+
platformTestsGlob: 'test/platform/**',
|
|
469
497
|
});
|
|
470
498
|
expect(result).toEqual([actorWithTests]);
|
|
471
499
|
});
|
|
@@ -602,6 +630,7 @@ describe('getChangedActors logging', () => {
|
|
|
602
630
|
'[DIFF]: Changes specific to actor team/actor-b: actors/b/b-only.ts',
|
|
603
631
|
'[DIFF]: Actors with functional changes: team/actor-a, team/actor-b',
|
|
604
632
|
'[DIFF]: Actors with only cosmetic changes: none',
|
|
633
|
+
'[DIFF]: Actors with platform test changes: none',
|
|
605
634
|
]);
|
|
606
635
|
});
|
|
607
636
|
|
|
@@ -614,7 +643,7 @@ describe('getChangedActors logging', () => {
|
|
|
614
643
|
filepathsChanged: ['test/platform/standalone.test.ts'],
|
|
615
644
|
actorConfigs: [standaloneActor],
|
|
616
645
|
range,
|
|
617
|
-
|
|
646
|
+
platformTestsGlob: 'test/platform/**',
|
|
618
647
|
});
|
|
619
648
|
|
|
620
649
|
expect(logger.warn).toHaveBeenCalledWith(outsideContextWarning('test/platform/standalone.test.ts'));
|
|
@@ -625,7 +654,7 @@ describe('getChangedActors logging', () => {
|
|
|
625
654
|
filepathsChanged: ['test/platform/standalone.test.ts', 'standalone-actors/standalone/src/main.ts'],
|
|
626
655
|
actorConfigs: [standaloneActor],
|
|
627
656
|
range,
|
|
628
|
-
|
|
657
|
+
platformTestsGlob: 'test/platform/**',
|
|
629
658
|
});
|
|
630
659
|
|
|
631
660
|
expect(result).toEqual([standaloneActor]);
|
|
@@ -637,7 +666,7 @@ describe('getChangedActors logging', () => {
|
|
|
637
666
|
filepathsChanged: ['test/platform/foo.test.ts', 'test/platform/README.md', 'test/platform/CHANGELOG.md'],
|
|
638
667
|
actorConfigs: [miniActor],
|
|
639
668
|
range,
|
|
640
|
-
|
|
669
|
+
platformTestsGlob: 'test/platform/**',
|
|
641
670
|
});
|
|
642
671
|
|
|
643
672
|
expect(logger.warn).not.toHaveBeenCalled();
|
|
@@ -672,12 +701,12 @@ describe('getChangedActors split by impact', () => {
|
|
|
672
701
|
actorConfigs,
|
|
673
702
|
range,
|
|
674
703
|
});
|
|
675
|
-
expect(result).toStrictEqual({ functional: [miniActor], cosmetic: [standaloneActor] });
|
|
704
|
+
expect(result).toStrictEqual({ functional: [miniActor], cosmetic: [standaloneActor], test: [] });
|
|
676
705
|
});
|
|
677
706
|
|
|
678
707
|
it('returns empty lists when nothing relevant changed', async () => {
|
|
679
708
|
expect(
|
|
680
709
|
await getChangedActors({ filepathsChanged: ['.vscode/settings.json'], actorConfigs, range }),
|
|
681
|
-
).toStrictEqual({ functional: [], cosmetic: [] });
|
|
710
|
+
).toStrictEqual({ functional: [], cosmetic: [], test: [] });
|
|
682
711
|
});
|
|
683
712
|
});
|
|
@@ -45,6 +45,15 @@ test('owner/a: fails', () => {
|
|
|
45
45
|
});
|
|
46
46
|
`,
|
|
47
47
|
);
|
|
48
|
+
|
|
49
|
+
// Outside test/platform, so the tests that run test/platform don't see them
|
|
50
|
+
for (const folder of ['with-pr', 'without-pr']) {
|
|
51
|
+
await mkdir(path.join(repoDir, 'test/glob', folder), { recursive: true });
|
|
52
|
+
await writeFile(
|
|
53
|
+
path.join(repoDir, 'test/glob', folder, `${folder}.test.ts`),
|
|
54
|
+
`import { test } from 'vitest';\n\ntest('owner/a: ${folder}', () => {});\n`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
48
57
|
});
|
|
49
58
|
|
|
50
59
|
afterAll(async () => {
|
|
@@ -92,17 +101,46 @@ test('owner/a: fails', () => {
|
|
|
92
101
|
expect(JSON.parse(result.stdout)).toMatchObject({ success: false, summary: { passed: 1, failed: 1 } });
|
|
93
102
|
});
|
|
94
103
|
|
|
95
|
-
it('
|
|
104
|
+
it('passes vitest a folder whose files all match as one filter, and adds the reporters it is given', () => {
|
|
96
105
|
const result = run(
|
|
97
|
-
['--log-level', 'debug', 'test', '--reporter', 'dot', '--reporter', 'verbose'
|
|
106
|
+
['--log-level', 'debug', 'test', '--reporter', 'dot', '--reporter', 'verbose'],
|
|
98
107
|
JSON.stringify([build]),
|
|
99
108
|
);
|
|
109
|
+
// The default glob test/platform/** matches every file in test/platform, so vitest gets just that folder
|
|
100
110
|
expect(result.stderr).toMatch(
|
|
101
|
-
/Running vitest: \S+ run test\/platform --reporter=default --reporter=json --reporter=dot --reporter=verbose /,
|
|
111
|
+
/Running vitest: \S+ run \S+\/test\/platform\/ --reporter=default --reporter=json --reporter=dot --reporter=verbose /,
|
|
102
112
|
);
|
|
103
113
|
expect(JSON.parse(result.stdout)).toMatchObject({ summary: { passed: 1, failed: 1 } });
|
|
104
114
|
});
|
|
105
115
|
|
|
116
|
+
it('runs only the test files that --test-files-glob matches from the repo root', () => {
|
|
117
|
+
const result = run(['test', '--test-files-glob', 'test/glob/{with-pr,other}/**'], JSON.stringify([build]));
|
|
118
|
+
expect(result.status, result.stderr).toBe(0);
|
|
119
|
+
expect(result.stderr).toContain('Running the 1 file(s) that match --test-files-glob');
|
|
120
|
+
expect(JSON.parse(result.stdout)).toMatchObject({
|
|
121
|
+
success: true,
|
|
122
|
+
summary: { total: 1, passed: 1 },
|
|
123
|
+
tests: [{ name: 'owner/a: with-pr', file: 'test/glob/with-pr/with-pr.test.ts' }],
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('fails when --test-files-glob matches no file instead of running every test', () => {
|
|
128
|
+
// Relative to test/platform, the way the workflows took it before
|
|
129
|
+
const result = run(['test', '--test-files-glob', 'hourly'], JSON.stringify([build]));
|
|
130
|
+
expect(result.status).toBe(1);
|
|
131
|
+
expect(result.stderr).toContain('No files match --test-files-glob "hourly"');
|
|
132
|
+
expect(result.stdout).toBe('');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('rejects test paths given the old way, as arguments, instead of running every test', () => {
|
|
136
|
+
const result = run(['test', 'test/platform/core'], JSON.stringify([build]));
|
|
137
|
+
expect(result.status).toBe(1);
|
|
138
|
+
// The help that comes with it shows --test-files-glob
|
|
139
|
+
expect(result.stderr).toContain('Unknown command: test/platform/core');
|
|
140
|
+
expect(result.stderr).toContain('--test-files-glob');
|
|
141
|
+
expect(result.stdout).toBe('');
|
|
142
|
+
});
|
|
143
|
+
|
|
106
144
|
it('fails without TESTER_APIFY_TOKEN instead of passing with every test skipped', () => {
|
|
107
145
|
const result = run(['test'], JSON.stringify([build]), repoDir, { ...env, TESTER_APIFY_TOKEN: '' });
|
|
108
146
|
expect(result.status).toBe(1);
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { createTestFilesMatcher, resolveTestFilesGlob } from '../../../bin/test-files-glob.js';
|
|
8
|
+
|
|
9
|
+
describe('createTestFilesMatcher', () => {
|
|
10
|
+
it('matches repo-root-relative paths, ignoring case and including dot files', () => {
|
|
11
|
+
const isMatch = createTestFilesMatcher('test/platform/{daily,hourly}/**');
|
|
12
|
+
expect(isMatch('test/platform/daily/a.test.ts')).toBe(true);
|
|
13
|
+
expect(isMatch('Test/Platform/Hourly/.b.test.ts')).toBe(true);
|
|
14
|
+
expect(isMatch('test/platform/daily-without-pr/a.test.ts')).toBe(false);
|
|
15
|
+
expect(isMatch('test/platform/utils.ts')).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('matches nothing without a glob', () => {
|
|
19
|
+
expect(createTestFilesMatcher(undefined)('test/platform/a.test.ts')).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('rejects an absolute glob', () => {
|
|
23
|
+
expect(() => createTestFilesMatcher('/repo/test/platform/**')).toThrow('must be relative to the repo root');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('resolveTestFilesGlob', () => {
|
|
28
|
+
let repoDir: string;
|
|
29
|
+
|
|
30
|
+
beforeAll(async () => {
|
|
31
|
+
repoDir = await mkdtemp(path.join(os.tmpdir(), 'apify-test-files-glob-'));
|
|
32
|
+
for (const file of [
|
|
33
|
+
'test/platform/utils.ts',
|
|
34
|
+
'test/platform/daily/a.test.ts',
|
|
35
|
+
'test/platform/daily-without-pr/b.test.ts',
|
|
36
|
+
'test/platform/hourly/nested/c.test.ts',
|
|
37
|
+
'test/platform/node_modules/d.test.ts',
|
|
38
|
+
'other/test/platform/daily/e.test.ts',
|
|
39
|
+
]) {
|
|
40
|
+
await mkdir(path.join(repoDir, path.dirname(file)), { recursive: true });
|
|
41
|
+
await writeFile(path.join(repoDir, file), '');
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
afterAll(async () => {
|
|
46
|
+
if (repoDir) await rm(repoDir, { recursive: true, force: true });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const files = async (glob: string) => (await resolveTestFilesGlob(glob, repoDir)).files;
|
|
50
|
+
const paths = async (glob: string) => (await resolveTestFilesGlob(glob, repoDir)).paths;
|
|
51
|
+
|
|
52
|
+
it('lists the matched files from the repo root, sorted, skipping node_modules', async () => {
|
|
53
|
+
expect(await files('test/platform/**')).toEqual([
|
|
54
|
+
'test/platform/daily-without-pr/b.test.ts',
|
|
55
|
+
'test/platform/daily/a.test.ts',
|
|
56
|
+
'test/platform/hourly/nested/c.test.ts',
|
|
57
|
+
'test/platform/utils.ts',
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('selects folders with a brace pattern', async () => {
|
|
62
|
+
expect(await files('test/platform/{daily,hourly}/**')).toEqual([
|
|
63
|
+
'test/platform/daily/a.test.ts',
|
|
64
|
+
'test/platform/hourly/nested/c.test.ts',
|
|
65
|
+
]);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('accepts a leading ./', async () => {
|
|
69
|
+
expect(await files('./test/platform/daily/**')).toEqual(['test/platform/daily/a.test.ts']);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('walks the whole repo when the glob has no static base', async () => {
|
|
73
|
+
expect(await files('**/daily/*.test.ts')).toEqual([
|
|
74
|
+
'other/test/platform/daily/e.test.ts',
|
|
75
|
+
'test/platform/daily/a.test.ts',
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('resolves a glob without wildcards to the file itself', async () => {
|
|
80
|
+
expect(await resolveTestFilesGlob('test/platform/utils.ts', repoDir)).toStrictEqual({
|
|
81
|
+
files: ['test/platform/utils.ts'],
|
|
82
|
+
paths: ['test/platform/utils.ts'],
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('matches no file with a glob relative to test/platform or a folder without **', async () => {
|
|
87
|
+
expect(await files('daily/**')).toEqual([]);
|
|
88
|
+
expect(await files('test/platform/daily')).toEqual([]);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('gives a folder whose files all match as one path, ending with / so it is not a prefix of a sibling', async () => {
|
|
92
|
+
expect(await paths('test/platform/{daily,hourly}/**')).toEqual([
|
|
93
|
+
'test/platform/daily/',
|
|
94
|
+
'test/platform/hourly/',
|
|
95
|
+
]);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('lists the matched files one by one in a folder that also holds files the glob leaves out', async () => {
|
|
99
|
+
// test/platform/utils.ts is left out, so test/platform/ can't be one path
|
|
100
|
+
expect(await paths('test/platform/**/*.test.ts')).toEqual([
|
|
101
|
+
'test/platform/daily-without-pr/',
|
|
102
|
+
'test/platform/daily/',
|
|
103
|
+
'test/platform/hourly/',
|
|
104
|
+
]);
|
|
105
|
+
// other/ holds only the matched file, so it is the highest folder that can be one path
|
|
106
|
+
expect(await paths('**/daily/*.test.ts')).toEqual(['other/', 'test/platform/daily/']);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('never gives a folder that holds a skipped node_modules as one path', async () => {
|
|
110
|
+
// test/platform/node_modules/ is not walked, so test/platform/ might hold files the glob leaves out
|
|
111
|
+
expect(await paths('test/platform/**')).toEqual([
|
|
112
|
+
'test/platform/daily-without-pr/',
|
|
113
|
+
'test/platform/daily/',
|
|
114
|
+
'test/platform/hourly/',
|
|
115
|
+
'test/platform/utils.ts',
|
|
116
|
+
]);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -4,7 +4,12 @@ import path from 'node:path';
|
|
|
4
4
|
|
|
5
5
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
_privates,
|
|
9
|
+
parseConfigFile,
|
|
10
|
+
parseRepoSettings,
|
|
11
|
+
parseResolvedConfigFile,
|
|
12
|
+
} from '../../../../../bin/utils/config/parser.js';
|
|
8
13
|
import { CONFIG_FILE_STRATEGY, type ResolvedActorConfig } from '../../../../../bin/utils/config/structures/base.js';
|
|
9
14
|
import { GROUPED_PARSER } from '../../../../../bin/utils/config/structures/grouped.js';
|
|
10
15
|
import { LEGACY_PARSER } from '../../../../../bin/utils/config/structures/legacy.js';
|
|
@@ -228,3 +233,21 @@ describe('parseConfigFile', () => {
|
|
|
228
233
|
).toThrow('Duplicate folder "test"');
|
|
229
234
|
});
|
|
230
235
|
});
|
|
236
|
+
|
|
237
|
+
describe('parseRepoSettings', () => {
|
|
238
|
+
it('defaults platformTestsGlob to test/platform/**', () => {
|
|
239
|
+
expect(parseRepoSettings({ actors: [actor()] })).toStrictEqual({ platformTestsGlob: 'test/platform/**' });
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('reads platformTestsGlob next to the Actor entries, in any mode', () => {
|
|
243
|
+
expect(parseRepoSettings({ platformTestsGlob: 'e2e/**', actors: [actor()] })).toStrictEqual({
|
|
244
|
+
platformTestsGlob: 'e2e/**',
|
|
245
|
+
});
|
|
246
|
+
expect(parseConfigFile({ platformTestsGlob: 'e2e/**', actors: [actor({ folder: 'bin' })] })).toHaveLength(1);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('rejects an empty or non-string platformTestsGlob', () => {
|
|
250
|
+
expect(() => parseRepoSettings({ platformTestsGlob: '' })).toThrow(/platformTestsGlob/);
|
|
251
|
+
expect(() => parseRepoSettings({ platformTestsGlob: ['test/**'] })).toThrow(/platformTestsGlob/);
|
|
252
|
+
});
|
|
253
|
+
});
|