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