11cb0ef41Sopenharmony_ciimport * as common from '../common/index.mjs'; 21cb0ef41Sopenharmony_ciimport * as fixtures from '../common/fixtures.mjs'; 31cb0ef41Sopenharmony_ciimport { join } from 'node:path'; 41cb0ef41Sopenharmony_ciimport { describe, it, run } from 'node:test'; 51cb0ef41Sopenharmony_ciimport { dot, spec, tap } from 'node:test/reporters'; 61cb0ef41Sopenharmony_ciimport assert from 'node:assert'; 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst testFixtures = fixtures.path('test-runner'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cidescribe('require(\'node:test\').run', { concurrency: true }, () => { 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci it('should run with no tests', async () => { 131cb0ef41Sopenharmony_ci const stream = run({ files: [] }); 141cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustNotCall()); 151cb0ef41Sopenharmony_ci stream.on('test:pass', common.mustNotCall()); 161cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 171cb0ef41Sopenharmony_ci for await (const _ of stream); 181cb0ef41Sopenharmony_ci }); 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci it('should fail with non existing file', async () => { 211cb0ef41Sopenharmony_ci const stream = run({ files: ['a-random-file-that-does-not-exist.js'] }); 221cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustCall(1)); 231cb0ef41Sopenharmony_ci stream.on('test:pass', common.mustNotCall()); 241cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 251cb0ef41Sopenharmony_ci for await (const _ of stream); 261cb0ef41Sopenharmony_ci }); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci it('should succeed with a file', async () => { 291cb0ef41Sopenharmony_ci const stream = run({ files: [join(testFixtures, 'default-behavior/test/random.cjs')] }); 301cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustNotCall()); 311cb0ef41Sopenharmony_ci stream.on('test:pass', common.mustCall(1)); 321cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 331cb0ef41Sopenharmony_ci for await (const _ of stream); 341cb0ef41Sopenharmony_ci }); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci it('should run same file twice', async () => { 371cb0ef41Sopenharmony_ci const stream = run({ 381cb0ef41Sopenharmony_ci files: [ 391cb0ef41Sopenharmony_ci join(testFixtures, 'default-behavior/test/random.cjs'), 401cb0ef41Sopenharmony_ci join(testFixtures, 'default-behavior/test/random.cjs'), 411cb0ef41Sopenharmony_ci ] 421cb0ef41Sopenharmony_ci }); 431cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustNotCall()); 441cb0ef41Sopenharmony_ci stream.on('test:pass', common.mustCall(2)); 451cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 461cb0ef41Sopenharmony_ci for await (const _ of stream); 471cb0ef41Sopenharmony_ci }); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci it('should run a failed test', async () => { 501cb0ef41Sopenharmony_ci const stream = run({ files: [testFixtures] }); 511cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustCall(1)); 521cb0ef41Sopenharmony_ci stream.on('test:pass', common.mustNotCall()); 531cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 541cb0ef41Sopenharmony_ci for await (const _ of stream); 551cb0ef41Sopenharmony_ci }); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci it('should support timeout', async () => { 581cb0ef41Sopenharmony_ci const stream = run({ timeout: 50, files: [ 591cb0ef41Sopenharmony_ci fixtures.path('test-runner', 'never_ending_sync.js'), 601cb0ef41Sopenharmony_ci fixtures.path('test-runner', 'never_ending_async.js'), 611cb0ef41Sopenharmony_ci ] }); 621cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustCall(2)); 631cb0ef41Sopenharmony_ci stream.on('test:pass', common.mustNotCall()); 641cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 651cb0ef41Sopenharmony_ci for await (const _ of stream); 661cb0ef41Sopenharmony_ci }); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci it('should validate files', async () => { 691cb0ef41Sopenharmony_ci [Symbol(), {}, () => {}, 0, 1, 0n, 1n, '', '1', Promise.resolve([]), true, false] 701cb0ef41Sopenharmony_ci .forEach((files) => assert.throws(() => run({ files }), { 711cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE' 721cb0ef41Sopenharmony_ci })); 731cb0ef41Sopenharmony_ci }); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci it('should be piped with dot', async () => { 761cb0ef41Sopenharmony_ci const result = await run({ 771cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/random.cjs')] 781cb0ef41Sopenharmony_ci }).compose(dot).toArray(); 791cb0ef41Sopenharmony_ci assert.deepStrictEqual(result, [ 801cb0ef41Sopenharmony_ci '.', 811cb0ef41Sopenharmony_ci '\n', 821cb0ef41Sopenharmony_ci ]); 831cb0ef41Sopenharmony_ci }); 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci describe('should be piped with spec reporter', () => { 861cb0ef41Sopenharmony_ci it('new spec', async () => { 871cb0ef41Sopenharmony_ci const specReporter = new spec(); 881cb0ef41Sopenharmony_ci const result = await run({ 891cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/random.cjs')] 901cb0ef41Sopenharmony_ci }).compose(specReporter).toArray(); 911cb0ef41Sopenharmony_ci const stringResults = result.map((bfr) => bfr.toString()); 921cb0ef41Sopenharmony_ci assert.match(stringResults[0], /this should pass/); 931cb0ef41Sopenharmony_ci assert.match(stringResults[1], /tests 1/); 941cb0ef41Sopenharmony_ci assert.match(stringResults[1], /pass 1/); 951cb0ef41Sopenharmony_ci }); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci it('spec()', async () => { 981cb0ef41Sopenharmony_ci const specReporter = spec(); 991cb0ef41Sopenharmony_ci const result = await run({ 1001cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/random.cjs')] 1011cb0ef41Sopenharmony_ci }).compose(specReporter).toArray(); 1021cb0ef41Sopenharmony_ci const stringResults = result.map((bfr) => bfr.toString()); 1031cb0ef41Sopenharmony_ci assert.match(stringResults[0], /this should pass/); 1041cb0ef41Sopenharmony_ci assert.match(stringResults[1], /tests 1/); 1051cb0ef41Sopenharmony_ci assert.match(stringResults[1], /pass 1/); 1061cb0ef41Sopenharmony_ci }); 1071cb0ef41Sopenharmony_ci }); 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci it('should be piped with tap', async () => { 1101cb0ef41Sopenharmony_ci const result = await run({ 1111cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/random.cjs')] 1121cb0ef41Sopenharmony_ci }).compose(tap).toArray(); 1131cb0ef41Sopenharmony_ci assert.strictEqual(result.length, 13); 1141cb0ef41Sopenharmony_ci assert.strictEqual(result[0], 'TAP version 13\n'); 1151cb0ef41Sopenharmony_ci assert.strictEqual(result[1], '# Subtest: this should pass\n'); 1161cb0ef41Sopenharmony_ci assert.strictEqual(result[2], 'ok 1 - this should pass\n'); 1171cb0ef41Sopenharmony_ci assert.match(result[3], /duration_ms: \d+\.?\d*/); 1181cb0ef41Sopenharmony_ci assert.strictEqual(result[4], '1..1\n'); 1191cb0ef41Sopenharmony_ci assert.strictEqual(result[5], '# tests 1\n'); 1201cb0ef41Sopenharmony_ci assert.strictEqual(result[6], '# suites 0\n'); 1211cb0ef41Sopenharmony_ci assert.strictEqual(result[7], '# pass 1\n'); 1221cb0ef41Sopenharmony_ci assert.strictEqual(result[8], '# fail 0\n'); 1231cb0ef41Sopenharmony_ci assert.strictEqual(result[9], '# cancelled 0\n'); 1241cb0ef41Sopenharmony_ci assert.strictEqual(result[10], '# skipped 0\n'); 1251cb0ef41Sopenharmony_ci assert.strictEqual(result[11], '# todo 0\n'); 1261cb0ef41Sopenharmony_ci assert.match(result[12], /# duration_ms \d+\.?\d*/); 1271cb0ef41Sopenharmony_ci }); 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci it('should skip tests not matching testNamePatterns - RegExp', async () => { 1301cb0ef41Sopenharmony_ci const result = await run({ 1311cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/skip_by_name.cjs')], 1321cb0ef41Sopenharmony_ci testNamePatterns: [/executed/] 1331cb0ef41Sopenharmony_ci }) 1341cb0ef41Sopenharmony_ci .compose(tap) 1351cb0ef41Sopenharmony_ci .toArray(); 1361cb0ef41Sopenharmony_ci assert.strictEqual(result[2], 'ok 1 - this should be skipped # SKIP test name does not match pattern\n'); 1371cb0ef41Sopenharmony_ci assert.strictEqual(result[5], 'ok 2 - this should be executed\n'); 1381cb0ef41Sopenharmony_ci }); 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci it('should skip tests not matching testNamePatterns - string', async () => { 1411cb0ef41Sopenharmony_ci const result = await run({ 1421cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/skip_by_name.cjs')], 1431cb0ef41Sopenharmony_ci testNamePatterns: ['executed'] 1441cb0ef41Sopenharmony_ci }) 1451cb0ef41Sopenharmony_ci .compose(tap) 1461cb0ef41Sopenharmony_ci .toArray(); 1471cb0ef41Sopenharmony_ci assert.strictEqual(result[2], 'ok 1 - this should be skipped # SKIP test name does not match pattern\n'); 1481cb0ef41Sopenharmony_ci assert.strictEqual(result[5], 'ok 2 - this should be executed\n'); 1491cb0ef41Sopenharmony_ci }); 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci it('should pass only to children', async () => { 1521cb0ef41Sopenharmony_ci const result = await run({ 1531cb0ef41Sopenharmony_ci files: [join(testFixtures, 'test_only.js')], 1541cb0ef41Sopenharmony_ci only: true 1551cb0ef41Sopenharmony_ci }) 1561cb0ef41Sopenharmony_ci .compose(tap) 1571cb0ef41Sopenharmony_ci .toArray(); 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci assert.strictEqual(result[2], 'ok 1 - this should be skipped # SKIP \'only\' option not set\n'); 1601cb0ef41Sopenharmony_ci assert.strictEqual(result[5], 'ok 2 - this should be executed\n'); 1611cb0ef41Sopenharmony_ci }); 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci it('should emit "test:watch:drained" event on watch mode', async () => { 1641cb0ef41Sopenharmony_ci const controller = new AbortController(); 1651cb0ef41Sopenharmony_ci await run({ 1661cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/random.cjs')], 1671cb0ef41Sopenharmony_ci watch: true, 1681cb0ef41Sopenharmony_ci signal: controller.signal, 1691cb0ef41Sopenharmony_ci }).on('data', function({ type }) { 1701cb0ef41Sopenharmony_ci if (type === 'test:watch:drained') { 1711cb0ef41Sopenharmony_ci controller.abort(); 1721cb0ef41Sopenharmony_ci } 1731cb0ef41Sopenharmony_ci }); 1741cb0ef41Sopenharmony_ci }); 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci describe('AbortSignal', () => { 1771cb0ef41Sopenharmony_ci it('should stop watch mode when abortSignal aborts', async () => { 1781cb0ef41Sopenharmony_ci const controller = new AbortController(); 1791cb0ef41Sopenharmony_ci const result = await run({ 1801cb0ef41Sopenharmony_ci files: [join(testFixtures, 'default-behavior/test/random.cjs')], 1811cb0ef41Sopenharmony_ci watch: true, 1821cb0ef41Sopenharmony_ci signal: controller.signal, 1831cb0ef41Sopenharmony_ci }) 1841cb0ef41Sopenharmony_ci .compose(async function* (source) { 1851cb0ef41Sopenharmony_ci for await (const chunk of source) { 1861cb0ef41Sopenharmony_ci if (chunk.type === 'test:pass') { 1871cb0ef41Sopenharmony_ci controller.abort(); 1881cb0ef41Sopenharmony_ci yield chunk.data.name; 1891cb0ef41Sopenharmony_ci } 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci }) 1921cb0ef41Sopenharmony_ci .toArray(); 1931cb0ef41Sopenharmony_ci assert.deepStrictEqual(result, ['this should pass']); 1941cb0ef41Sopenharmony_ci }); 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci it('should abort when test succeeded', async () => { 1971cb0ef41Sopenharmony_ci const stream = run({ 1981cb0ef41Sopenharmony_ci files: [ 1991cb0ef41Sopenharmony_ci fixtures.path( 2001cb0ef41Sopenharmony_ci 'test-runner', 2011cb0ef41Sopenharmony_ci 'aborts', 2021cb0ef41Sopenharmony_ci 'successful-test-still-call-abort.js' 2031cb0ef41Sopenharmony_ci ), 2041cb0ef41Sopenharmony_ci ], 2051cb0ef41Sopenharmony_ci }); 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci let passedTestCount = 0; 2081cb0ef41Sopenharmony_ci let failedTestCount = 0; 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci let output = ''; 2111cb0ef41Sopenharmony_ci for await (const data of stream) { 2121cb0ef41Sopenharmony_ci if (data.type === 'test:stdout') { 2131cb0ef41Sopenharmony_ci output += data.data.message.toString(); 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci if (data.type === 'test:fail') { 2161cb0ef41Sopenharmony_ci failedTestCount++; 2171cb0ef41Sopenharmony_ci } 2181cb0ef41Sopenharmony_ci if (data.type === 'test:pass') { 2191cb0ef41Sopenharmony_ci passedTestCount++; 2201cb0ef41Sopenharmony_ci } 2211cb0ef41Sopenharmony_ci } 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci assert.match(output, /abort called for test 1/); 2241cb0ef41Sopenharmony_ci assert.match(output, /abort called for test 2/); 2251cb0ef41Sopenharmony_ci assert.strictEqual(failedTestCount, 0, new Error('no tests should fail')); 2261cb0ef41Sopenharmony_ci assert.strictEqual(passedTestCount, 2); 2271cb0ef41Sopenharmony_ci }); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci it('should abort when test failed', async () => { 2301cb0ef41Sopenharmony_ci const stream = run({ 2311cb0ef41Sopenharmony_ci files: [ 2321cb0ef41Sopenharmony_ci fixtures.path( 2331cb0ef41Sopenharmony_ci 'test-runner', 2341cb0ef41Sopenharmony_ci 'aborts', 2351cb0ef41Sopenharmony_ci 'failed-test-still-call-abort.js' 2361cb0ef41Sopenharmony_ci ), 2371cb0ef41Sopenharmony_ci ], 2381cb0ef41Sopenharmony_ci }); 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci let passedTestCount = 0; 2411cb0ef41Sopenharmony_ci let failedTestCount = 0; 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci let output = ''; 2441cb0ef41Sopenharmony_ci for await (const data of stream) { 2451cb0ef41Sopenharmony_ci if (data.type === 'test:stdout') { 2461cb0ef41Sopenharmony_ci output += data.data.message.toString(); 2471cb0ef41Sopenharmony_ci } 2481cb0ef41Sopenharmony_ci if (data.type === 'test:fail') { 2491cb0ef41Sopenharmony_ci failedTestCount++; 2501cb0ef41Sopenharmony_ci } 2511cb0ef41Sopenharmony_ci if (data.type === 'test:pass') { 2521cb0ef41Sopenharmony_ci passedTestCount++; 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci } 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci assert.match(output, /abort called for test 1/); 2571cb0ef41Sopenharmony_ci assert.match(output, /abort called for test 2/); 2581cb0ef41Sopenharmony_ci assert.strictEqual(passedTestCount, 0, new Error('no tests should pass')); 2591cb0ef41Sopenharmony_ci assert.strictEqual(failedTestCount, 2); 2601cb0ef41Sopenharmony_ci }); 2611cb0ef41Sopenharmony_ci }); 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ci describe('sharding', () => { 2641cb0ef41Sopenharmony_ci const shardsTestsFixtures = fixtures.path('test-runner', 'shards'); 2651cb0ef41Sopenharmony_ci const shardsTestsFiles = [ 2661cb0ef41Sopenharmony_ci 'a.cjs', 2671cb0ef41Sopenharmony_ci 'b.cjs', 2681cb0ef41Sopenharmony_ci 'c.cjs', 2691cb0ef41Sopenharmony_ci 'd.cjs', 2701cb0ef41Sopenharmony_ci 'e.cjs', 2711cb0ef41Sopenharmony_ci 'f.cjs', 2721cb0ef41Sopenharmony_ci 'g.cjs', 2731cb0ef41Sopenharmony_ci 'h.cjs', 2741cb0ef41Sopenharmony_ci 'i.cjs', 2751cb0ef41Sopenharmony_ci 'j.cjs', 2761cb0ef41Sopenharmony_ci ].map((file) => join(shardsTestsFixtures, file)); 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci describe('validation', () => { 2791cb0ef41Sopenharmony_ci it('should require shard.total when having shard option', () => { 2801cb0ef41Sopenharmony_ci assert.throws(() => run({ files: shardsTestsFiles, shard: {} }), { 2811cb0ef41Sopenharmony_ci name: 'TypeError', 2821cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 2831cb0ef41Sopenharmony_ci message: 'The "options.shard.total" property must be of type number. Received undefined' 2841cb0ef41Sopenharmony_ci }); 2851cb0ef41Sopenharmony_ci }); 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci it('should require shard.index when having shards option', () => { 2881cb0ef41Sopenharmony_ci assert.throws(() => run({ 2891cb0ef41Sopenharmony_ci files: shardsTestsFiles, 2901cb0ef41Sopenharmony_ci shard: { 2911cb0ef41Sopenharmony_ci total: 5 2921cb0ef41Sopenharmony_ci } 2931cb0ef41Sopenharmony_ci }), { 2941cb0ef41Sopenharmony_ci name: 'TypeError', 2951cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 2961cb0ef41Sopenharmony_ci message: 'The "options.shard.index" property must be of type number. Received undefined' 2971cb0ef41Sopenharmony_ci }); 2981cb0ef41Sopenharmony_ci }); 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci it('should require shard.total to be greater than 0 when having shard option', () => { 3011cb0ef41Sopenharmony_ci assert.throws(() => run({ 3021cb0ef41Sopenharmony_ci files: shardsTestsFiles, 3031cb0ef41Sopenharmony_ci shard: { 3041cb0ef41Sopenharmony_ci total: 0, 3051cb0ef41Sopenharmony_ci index: 1 3061cb0ef41Sopenharmony_ci } 3071cb0ef41Sopenharmony_ci }), { 3081cb0ef41Sopenharmony_ci name: 'RangeError', 3091cb0ef41Sopenharmony_ci code: 'ERR_OUT_OF_RANGE', 3101cb0ef41Sopenharmony_ci message: 3111cb0ef41Sopenharmony_ci 'The value of "options.shard.total" is out of range. It must be >= 1 && <= 9007199254740991. Received 0' 3121cb0ef41Sopenharmony_ci }); 3131cb0ef41Sopenharmony_ci }); 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci it('should require shard.index to be greater than 0 when having shard option', () => { 3161cb0ef41Sopenharmony_ci assert.throws(() => run({ 3171cb0ef41Sopenharmony_ci files: shardsTestsFiles, 3181cb0ef41Sopenharmony_ci shard: { 3191cb0ef41Sopenharmony_ci total: 6, 3201cb0ef41Sopenharmony_ci index: 0 3211cb0ef41Sopenharmony_ci } 3221cb0ef41Sopenharmony_ci }), { 3231cb0ef41Sopenharmony_ci name: 'RangeError', 3241cb0ef41Sopenharmony_ci code: 'ERR_OUT_OF_RANGE', 3251cb0ef41Sopenharmony_ci // eslint-disable-next-line max-len 3261cb0ef41Sopenharmony_ci message: 'The value of "options.shard.index" is out of range. It must be >= 1 && <= 6 ("options.shard.total"). Received 0' 3271cb0ef41Sopenharmony_ci }); 3281cb0ef41Sopenharmony_ci }); 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_ci it('should require shard.index to not be greater than the shards total when having shard option', () => { 3311cb0ef41Sopenharmony_ci assert.throws(() => run({ 3321cb0ef41Sopenharmony_ci files: shardsTestsFiles, 3331cb0ef41Sopenharmony_ci shard: { 3341cb0ef41Sopenharmony_ci total: 6, 3351cb0ef41Sopenharmony_ci index: 7 3361cb0ef41Sopenharmony_ci } 3371cb0ef41Sopenharmony_ci }), { 3381cb0ef41Sopenharmony_ci name: 'RangeError', 3391cb0ef41Sopenharmony_ci code: 'ERR_OUT_OF_RANGE', 3401cb0ef41Sopenharmony_ci // eslint-disable-next-line max-len 3411cb0ef41Sopenharmony_ci message: 'The value of "options.shard.index" is out of range. It must be >= 1 && <= 6 ("options.shard.total"). Received 7' 3421cb0ef41Sopenharmony_ci }); 3431cb0ef41Sopenharmony_ci }); 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci it('should require watch mode to be disabled when having shard option', () => { 3461cb0ef41Sopenharmony_ci assert.throws(() => run({ 3471cb0ef41Sopenharmony_ci files: shardsTestsFiles, 3481cb0ef41Sopenharmony_ci watch: true, 3491cb0ef41Sopenharmony_ci shard: { 3501cb0ef41Sopenharmony_ci total: 6, 3511cb0ef41Sopenharmony_ci index: 1 3521cb0ef41Sopenharmony_ci } 3531cb0ef41Sopenharmony_ci }), { 3541cb0ef41Sopenharmony_ci name: 'TypeError', 3551cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_VALUE', 3561cb0ef41Sopenharmony_ci message: 'The property \'options.shard\' shards not supported with watch mode. Received true' 3571cb0ef41Sopenharmony_ci }); 3581cb0ef41Sopenharmony_ci }); 3591cb0ef41Sopenharmony_ci }); 3601cb0ef41Sopenharmony_ci 3611cb0ef41Sopenharmony_ci it('should run only the tests files matching the shard index', async () => { 3621cb0ef41Sopenharmony_ci const stream = run({ 3631cb0ef41Sopenharmony_ci files: shardsTestsFiles, 3641cb0ef41Sopenharmony_ci shard: { 3651cb0ef41Sopenharmony_ci total: 5, 3661cb0ef41Sopenharmony_ci index: 1 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci }); 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci const executedTestFiles = []; 3711cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustNotCall()); 3721cb0ef41Sopenharmony_ci stream.on('test:pass', (passedTest) => { 3731cb0ef41Sopenharmony_ci executedTestFiles.push(passedTest.file); 3741cb0ef41Sopenharmony_ci }); 3751cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 3761cb0ef41Sopenharmony_ci for await (const _ of stream) ; 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci assert.deepStrictEqual(executedTestFiles, [ 3791cb0ef41Sopenharmony_ci join(shardsTestsFixtures, 'a.cjs'), 3801cb0ef41Sopenharmony_ci join(shardsTestsFixtures, 'f.cjs'), 3811cb0ef41Sopenharmony_ci ]); 3821cb0ef41Sopenharmony_ci }); 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci it('different shards should not run the same file', async () => { 3851cb0ef41Sopenharmony_ci const executedTestFiles = []; 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ci const testStreams = []; 3881cb0ef41Sopenharmony_ci const shards = 5; 3891cb0ef41Sopenharmony_ci for (let i = 1; i <= shards; i++) { 3901cb0ef41Sopenharmony_ci const stream = run({ 3911cb0ef41Sopenharmony_ci files: shardsTestsFiles, 3921cb0ef41Sopenharmony_ci shard: { 3931cb0ef41Sopenharmony_ci total: shards, 3941cb0ef41Sopenharmony_ci index: i 3951cb0ef41Sopenharmony_ci } 3961cb0ef41Sopenharmony_ci }); 3971cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustNotCall()); 3981cb0ef41Sopenharmony_ci stream.on('test:pass', (passedTest) => { 3991cb0ef41Sopenharmony_ci executedTestFiles.push(passedTest.file); 4001cb0ef41Sopenharmony_ci }); 4011cb0ef41Sopenharmony_ci testStreams.push(stream); 4021cb0ef41Sopenharmony_ci } 4031cb0ef41Sopenharmony_ci 4041cb0ef41Sopenharmony_ci await Promise.all(testStreams.map(async (stream) => { 4051cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 4061cb0ef41Sopenharmony_ci for await (const _ of stream) ; 4071cb0ef41Sopenharmony_ci })); 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci assert.deepStrictEqual(executedTestFiles, [...new Set(executedTestFiles)]); 4101cb0ef41Sopenharmony_ci }); 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci it('combination of all shards should be all the tests', async () => { 4131cb0ef41Sopenharmony_ci const executedTestFiles = []; 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_ci const testStreams = []; 4161cb0ef41Sopenharmony_ci const shards = 5; 4171cb0ef41Sopenharmony_ci for (let i = 1; i <= shards; i++) { 4181cb0ef41Sopenharmony_ci const stream = run({ 4191cb0ef41Sopenharmony_ci files: shardsTestsFiles, 4201cb0ef41Sopenharmony_ci shard: { 4211cb0ef41Sopenharmony_ci total: shards, 4221cb0ef41Sopenharmony_ci index: i 4231cb0ef41Sopenharmony_ci } 4241cb0ef41Sopenharmony_ci }); 4251cb0ef41Sopenharmony_ci stream.on('test:fail', common.mustNotCall()); 4261cb0ef41Sopenharmony_ci stream.on('test:pass', (passedTest) => { 4271cb0ef41Sopenharmony_ci executedTestFiles.push(passedTest.file); 4281cb0ef41Sopenharmony_ci }); 4291cb0ef41Sopenharmony_ci testStreams.push(stream); 4301cb0ef41Sopenharmony_ci } 4311cb0ef41Sopenharmony_ci 4321cb0ef41Sopenharmony_ci await Promise.all(testStreams.map(async (stream) => { 4331cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 4341cb0ef41Sopenharmony_ci for await (const _ of stream) ; 4351cb0ef41Sopenharmony_ci })); 4361cb0ef41Sopenharmony_ci 4371cb0ef41Sopenharmony_ci assert.deepStrictEqual(executedTestFiles.sort(), [...shardsTestsFiles].sort()); 4381cb0ef41Sopenharmony_ci }); 4391cb0ef41Sopenharmony_ci }); 4401cb0ef41Sopenharmony_ci}); 441