11cb0ef41Sopenharmony_ciimport { spawnPromisified } from '../common/index.mjs';
21cb0ef41Sopenharmony_ciimport * as fixtures from '../common/fixtures.mjs';
31cb0ef41Sopenharmony_ciimport assert from 'node:assert';
41cb0ef41Sopenharmony_ciimport { execPath } from 'node:process';
51cb0ef41Sopenharmony_ciimport { describe, it } from 'node:test';
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst setupArgs = [
81cb0ef41Sopenharmony_ci  '--no-warnings',
91cb0ef41Sopenharmony_ci  '--input-type=module',
101cb0ef41Sopenharmony_ci  '--eval',
111cb0ef41Sopenharmony_ci];
121cb0ef41Sopenharmony_ciconst commonInput = 'import os from "node:os"; console.log(os)';
131cb0ef41Sopenharmony_ciconst commonArgs = [
141cb0ef41Sopenharmony_ci  ...setupArgs,
151cb0ef41Sopenharmony_ci  commonInput,
161cb0ef41Sopenharmony_ci];
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cidescribe('ESM: loader chaining', { concurrency: true }, () => {
191cb0ef41Sopenharmony_ci  it('should load unadulterated source when there are no loaders', async () => {
201cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
211cb0ef41Sopenharmony_ci      execPath,
221cb0ef41Sopenharmony_ci      [
231cb0ef41Sopenharmony_ci        ...setupArgs,
241cb0ef41Sopenharmony_ci        'import fs from "node:fs"; console.log(typeof fs?.constants?.F_OK )',
251cb0ef41Sopenharmony_ci      ],
261cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
271cb0ef41Sopenharmony_ci    );
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
301cb0ef41Sopenharmony_ci    assert.match(stdout, /number/); // node:fs is an object
311cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
321cb0ef41Sopenharmony_ci  });
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  it('should load properly different source when only load changes something', async () => {
351cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
361cb0ef41Sopenharmony_ci      execPath,
371cb0ef41Sopenharmony_ci      [
381cb0ef41Sopenharmony_ci        '--loader',
391cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
401cb0ef41Sopenharmony_ci        '--loader',
411cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
421cb0ef41Sopenharmony_ci        '--loader',
431cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passthru.mjs'),
441cb0ef41Sopenharmony_ci        ...commonArgs,
451cb0ef41Sopenharmony_ci      ],
461cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
471cb0ef41Sopenharmony_ci    );
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
501cb0ef41Sopenharmony_ci    assert.match(stdout, /load passthru/);
511cb0ef41Sopenharmony_ci    assert.match(stdout, /resolve passthru/);
521cb0ef41Sopenharmony_ci    assert.match(stdout, /foo/);
531cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
541cb0ef41Sopenharmony_ci  });
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  it('should result in proper output from multiple changes in resolve hooks', async () => {
571cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
581cb0ef41Sopenharmony_ci      execPath,
591cb0ef41Sopenharmony_ci      [
601cb0ef41Sopenharmony_ci        '--loader',
611cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-shortcircuit.mjs'),
621cb0ef41Sopenharmony_ci        '--loader',
631cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-foo.mjs'),
641cb0ef41Sopenharmony_ci        '--loader',
651cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-42.mjs'),
661cb0ef41Sopenharmony_ci        '--loader',
671cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
681cb0ef41Sopenharmony_ci        ...commonArgs,
691cb0ef41Sopenharmony_ci      ],
701cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
711cb0ef41Sopenharmony_ci    );
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
741cb0ef41Sopenharmony_ci    assert.match(stdout, /resolve 42/); // It did go thru resolve-42
751cb0ef41Sopenharmony_ci    assert.match(stdout, /foo/); // LIFO, so resolve-foo won
761cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
771cb0ef41Sopenharmony_ci  });
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  it('should respect modified context within resolve chain', async () => {
801cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
811cb0ef41Sopenharmony_ci      execPath,
821cb0ef41Sopenharmony_ci      [
831cb0ef41Sopenharmony_ci        '--loader',
841cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-shortcircuit.mjs'),
851cb0ef41Sopenharmony_ci        '--loader',
861cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-42.mjs'),
871cb0ef41Sopenharmony_ci        '--loader',
881cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
891cb0ef41Sopenharmony_ci        '--loader',
901cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-receiving-modified-context.mjs'),
911cb0ef41Sopenharmony_ci        '--loader',
921cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passing-modified-context.mjs'),
931cb0ef41Sopenharmony_ci        ...commonArgs,
941cb0ef41Sopenharmony_ci      ],
951cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
961cb0ef41Sopenharmony_ci    );
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
991cb0ef41Sopenharmony_ci    assert.match(stdout, /bar/);
1001cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
1011cb0ef41Sopenharmony_ci  });
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  it('should accept only the correct arguments', async () => {
1041cb0ef41Sopenharmony_ci    const { stdout } = await spawnPromisified(
1051cb0ef41Sopenharmony_ci      execPath,
1061cb0ef41Sopenharmony_ci      [
1071cb0ef41Sopenharmony_ci        '--loader',
1081cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-log-args.mjs'),
1091cb0ef41Sopenharmony_ci        '--loader',
1101cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-with-too-many-args.mjs'),
1111cb0ef41Sopenharmony_ci        ...commonArgs,
1121cb0ef41Sopenharmony_ci      ],
1131cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
1141cb0ef41Sopenharmony_ci    );
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci    assert.match(stdout, /^resolve arg count: 3$/m);
1171cb0ef41Sopenharmony_ci    assert.match(stdout, /specifier: 'node:os'/);
1181cb0ef41Sopenharmony_ci    assert.match(stdout, /next: \[AsyncFunction: nextResolve\]/);
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci    assert.match(stdout, /^load arg count: 3$/m);
1211cb0ef41Sopenharmony_ci    assert.match(stdout, /url: 'node:os'/);
1221cb0ef41Sopenharmony_ci    assert.match(stdout, /next: \[AsyncFunction: nextLoad\]/);
1231cb0ef41Sopenharmony_ci  });
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  it('should result in proper output from multiple changes in resolve hooks', async () => {
1261cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
1271cb0ef41Sopenharmony_ci      execPath,
1281cb0ef41Sopenharmony_ci      [
1291cb0ef41Sopenharmony_ci        '--loader',
1301cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-shortcircuit.mjs'),
1311cb0ef41Sopenharmony_ci        '--loader',
1321cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-42.mjs'),
1331cb0ef41Sopenharmony_ci        '--loader',
1341cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-foo.mjs'),
1351cb0ef41Sopenharmony_ci        '--loader',
1361cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
1371cb0ef41Sopenharmony_ci        ...commonArgs,
1381cb0ef41Sopenharmony_ci      ],
1391cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
1401cb0ef41Sopenharmony_ci    );
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
1431cb0ef41Sopenharmony_ci    assert.match(stdout, /resolve foo/); // It did go thru resolve-foo
1441cb0ef41Sopenharmony_ci    assert.match(stdout, /42/); // LIFO, so resolve-42 won
1451cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
1461cb0ef41Sopenharmony_ci  });
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  it('should provide the correct "next" fn when multiple calls to next within same loader', async () => {
1491cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
1501cb0ef41Sopenharmony_ci      execPath,
1511cb0ef41Sopenharmony_ci      [
1521cb0ef41Sopenharmony_ci        '--loader',
1531cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-shortcircuit.mjs'),
1541cb0ef41Sopenharmony_ci        '--loader',
1551cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-foo.mjs'),
1561cb0ef41Sopenharmony_ci        '--loader',
1571cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-multiple-next-calls.mjs'),
1581cb0ef41Sopenharmony_ci        '--loader',
1591cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
1601cb0ef41Sopenharmony_ci        ...commonArgs,
1611cb0ef41Sopenharmony_ci      ],
1621cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
1631cb0ef41Sopenharmony_ci    );
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci    const countFoos = stdout.match(/resolve foo/g)?.length;
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
1681cb0ef41Sopenharmony_ci    assert.strictEqual(countFoos, 2);
1691cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
1701cb0ef41Sopenharmony_ci  });
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  it('should use the correct `name` for next<HookName>\'s function', async () => {
1731cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
1741cb0ef41Sopenharmony_ci      execPath,
1751cb0ef41Sopenharmony_ci      [
1761cb0ef41Sopenharmony_ci        '--loader',
1771cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-shortcircuit.mjs'),
1781cb0ef41Sopenharmony_ci        '--loader',
1791cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-42.mjs'),
1801cb0ef41Sopenharmony_ci        '--loader',
1811cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
1821cb0ef41Sopenharmony_ci        ...commonArgs,
1831cb0ef41Sopenharmony_ci      ],
1841cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
1851cb0ef41Sopenharmony_ci    );
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
1881cb0ef41Sopenharmony_ci    assert.match(stdout, /next<HookName>: nextResolve/);
1891cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
1901cb0ef41Sopenharmony_ci  });
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci  it('should throw for incomplete resolve chain, citing errant loader & hook', async () => {
1931cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
1941cb0ef41Sopenharmony_ci      execPath,
1951cb0ef41Sopenharmony_ci      [
1961cb0ef41Sopenharmony_ci        '--loader',
1971cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-incomplete.mjs'),
1981cb0ef41Sopenharmony_ci        '--loader',
1991cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
2001cb0ef41Sopenharmony_ci        '--loader',
2011cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
2021cb0ef41Sopenharmony_ci        ...commonArgs,
2031cb0ef41Sopenharmony_ci      ],
2041cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
2051cb0ef41Sopenharmony_ci    );
2061cb0ef41Sopenharmony_ci    assert.match(stdout, /resolve passthru/);
2071cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_LOADER_CHAIN_INCOMPLETE/);
2081cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-resolve-incomplete\.mjs/);
2091cb0ef41Sopenharmony_ci    assert.match(stderr, /'resolve'/);
2101cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
2111cb0ef41Sopenharmony_ci  });
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci  it('should NOT throw when nested resolve hook signaled a short circuit', async () => {
2141cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
2151cb0ef41Sopenharmony_ci      execPath,
2161cb0ef41Sopenharmony_ci      [
2171cb0ef41Sopenharmony_ci        '--loader',
2181cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-shortcircuit.mjs'),
2191cb0ef41Sopenharmony_ci        '--loader',
2201cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-next-modified.mjs'),
2211cb0ef41Sopenharmony_ci        '--loader',
2221cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
2231cb0ef41Sopenharmony_ci        ...commonArgs,
2241cb0ef41Sopenharmony_ci      ],
2251cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
2261cb0ef41Sopenharmony_ci    );
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
2291cb0ef41Sopenharmony_ci    assert.strictEqual(stdout.trim(), 'foo');
2301cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
2311cb0ef41Sopenharmony_ci  });
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci  it('should NOT throw when nested load hook signaled a short circuit', async () => {
2341cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
2351cb0ef41Sopenharmony_ci      execPath,
2361cb0ef41Sopenharmony_ci      [
2371cb0ef41Sopenharmony_ci        '--loader',
2381cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-shortcircuit.mjs'),
2391cb0ef41Sopenharmony_ci        '--loader',
2401cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-42.mjs'),
2411cb0ef41Sopenharmony_ci        '--loader',
2421cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
2431cb0ef41Sopenharmony_ci        '--loader',
2441cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-next-modified.mjs'),
2451cb0ef41Sopenharmony_ci        ...commonArgs,
2461cb0ef41Sopenharmony_ci      ],
2471cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
2481cb0ef41Sopenharmony_ci    );
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
2511cb0ef41Sopenharmony_ci    assert.match(stdout, /421/);
2521cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
2531cb0ef41Sopenharmony_ci  });
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci  it('should allow loaders to influence subsequent loader resolutions', async () => {
2561cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
2571cb0ef41Sopenharmony_ci      execPath,
2581cb0ef41Sopenharmony_ci      [
2591cb0ef41Sopenharmony_ci        '--loader',
2601cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-strip-xxx.mjs'),
2611cb0ef41Sopenharmony_ci        '--loader',
2621cb0ef41Sopenharmony_ci        'xxx/loader-resolve-strip-yyy.mjs',
2631cb0ef41Sopenharmony_ci        ...commonArgs,
2641cb0ef41Sopenharmony_ci      ],
2651cb0ef41Sopenharmony_ci      { encoding: 'utf8', cwd: fixtures.path('es-module-loaders') },
2661cb0ef41Sopenharmony_ci    );
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
2691cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
2701cb0ef41Sopenharmony_ci  });
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci  it('should throw when the resolve chain is broken', async () => {
2731cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
2741cb0ef41Sopenharmony_ci      execPath,
2751cb0ef41Sopenharmony_ci      [
2761cb0ef41Sopenharmony_ci        '--loader',
2771cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
2781cb0ef41Sopenharmony_ci        '--loader',
2791cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-incomplete.mjs'),
2801cb0ef41Sopenharmony_ci        '--loader',
2811cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-foo-or-42.mjs'),
2821cb0ef41Sopenharmony_ci        ...commonArgs,
2831cb0ef41Sopenharmony_ci      ],
2841cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
2851cb0ef41Sopenharmony_ci    );
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ci    assert.doesNotMatch(stdout, /resolve passthru/);
2881cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_LOADER_CHAIN_INCOMPLETE/);
2891cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-resolve-incomplete\.mjs/);
2901cb0ef41Sopenharmony_ci    assert.match(stderr, /'resolve'/);
2911cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
2921cb0ef41Sopenharmony_ci  });
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_ci  it('should throw for incomplete load chain, citing errant loader & hook', async () => {
2951cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
2961cb0ef41Sopenharmony_ci      execPath,
2971cb0ef41Sopenharmony_ci      [
2981cb0ef41Sopenharmony_ci        '--loader',
2991cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
3001cb0ef41Sopenharmony_ci        '--loader',
3011cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-incomplete.mjs'),
3021cb0ef41Sopenharmony_ci        '--loader',
3031cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passthru.mjs'),
3041cb0ef41Sopenharmony_ci        ...commonArgs,
3051cb0ef41Sopenharmony_ci      ],
3061cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
3071cb0ef41Sopenharmony_ci    );
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci    assert.match(stdout, /load passthru/);
3101cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_LOADER_CHAIN_INCOMPLETE/);
3111cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-load-incomplete\.mjs/);
3121cb0ef41Sopenharmony_ci    assert.match(stderr, /'load'/);
3131cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
3141cb0ef41Sopenharmony_ci  });
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci  it('should throw when the load chain is broken', async () => {
3171cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
3181cb0ef41Sopenharmony_ci      execPath,
3191cb0ef41Sopenharmony_ci      [
3201cb0ef41Sopenharmony_ci        '--loader',
3211cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
3221cb0ef41Sopenharmony_ci        '--loader',
3231cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passthru.mjs'),
3241cb0ef41Sopenharmony_ci        '--loader',
3251cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-incomplete.mjs'),
3261cb0ef41Sopenharmony_ci        ...commonArgs,
3271cb0ef41Sopenharmony_ci      ],
3281cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
3291cb0ef41Sopenharmony_ci    );
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci    assert.doesNotMatch(stdout, /load passthru/);
3321cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_LOADER_CHAIN_INCOMPLETE/);
3331cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-load-incomplete\.mjs/);
3341cb0ef41Sopenharmony_ci    assert.match(stderr, /'load'/);
3351cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
3361cb0ef41Sopenharmony_ci  });
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci  it('should throw when invalid `specifier` argument passed to `nextResolve`', async () => {
3391cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
3401cb0ef41Sopenharmony_ci      execPath,
3411cb0ef41Sopenharmony_ci      [
3421cb0ef41Sopenharmony_ci        '--loader',
3431cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
3441cb0ef41Sopenharmony_ci        '--loader',
3451cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-bad-next-specifier.mjs'),
3461cb0ef41Sopenharmony_ci        ...commonArgs,
3471cb0ef41Sopenharmony_ci      ],
3481cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
3491cb0ef41Sopenharmony_ci    );
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
3521cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_INVALID_ARG_TYPE/);
3531cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-resolve-bad-next-specifier\.mjs/);
3541cb0ef41Sopenharmony_ci    assert.match(stderr, /'resolve' hook's nextResolve\(\) specifier/);
3551cb0ef41Sopenharmony_ci  });
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci  it('should throw when resolve hook is invalid', async () => {
3581cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
3591cb0ef41Sopenharmony_ci      execPath,
3601cb0ef41Sopenharmony_ci      [
3611cb0ef41Sopenharmony_ci        '--loader',
3621cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
3631cb0ef41Sopenharmony_ci        '--loader',
3641cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-null-return.mjs'),
3651cb0ef41Sopenharmony_ci        ...commonArgs,
3661cb0ef41Sopenharmony_ci      ],
3671cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
3681cb0ef41Sopenharmony_ci    );
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
3711cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_INVALID_RETURN_VALUE/);
3721cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-resolve-null-return\.mjs/);
3731cb0ef41Sopenharmony_ci    assert.match(stderr, /'resolve' hook's nextResolve\(\)/);
3741cb0ef41Sopenharmony_ci    assert.match(stderr, /an object/);
3751cb0ef41Sopenharmony_ci    assert.match(stderr, /got null/);
3761cb0ef41Sopenharmony_ci  });
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci  it('should throw when invalid `context` argument passed to `nextResolve`', async () => {
3791cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
3801cb0ef41Sopenharmony_ci      execPath,
3811cb0ef41Sopenharmony_ci      [
3821cb0ef41Sopenharmony_ci        '--loader',
3831cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
3841cb0ef41Sopenharmony_ci        '--loader',
3851cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-bad-next-context.mjs'),
3861cb0ef41Sopenharmony_ci        ...commonArgs,
3871cb0ef41Sopenharmony_ci      ],
3881cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
3891cb0ef41Sopenharmony_ci    );
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_INVALID_ARG_TYPE/);
3921cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-resolve-bad-next-context\.mjs/);
3931cb0ef41Sopenharmony_ci    assert.match(stderr, /'resolve' hook's nextResolve\(\) context/);
3941cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
3951cb0ef41Sopenharmony_ci  });
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci  it('should throw when load hook is invalid', async () => {
3981cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
3991cb0ef41Sopenharmony_ci      execPath,
4001cb0ef41Sopenharmony_ci      [
4011cb0ef41Sopenharmony_ci        '--loader',
4021cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passthru.mjs'),
4031cb0ef41Sopenharmony_ci        '--loader',
4041cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-null-return.mjs'),
4051cb0ef41Sopenharmony_ci        ...commonArgs,
4061cb0ef41Sopenharmony_ci      ],
4071cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
4081cb0ef41Sopenharmony_ci    );
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
4111cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_INVALID_RETURN_VALUE/);
4121cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-load-null-return\.mjs/);
4131cb0ef41Sopenharmony_ci    assert.match(stderr, /'load' hook's nextLoad\(\)/);
4141cb0ef41Sopenharmony_ci    assert.match(stderr, /an object/);
4151cb0ef41Sopenharmony_ci    assert.match(stderr, /got null/);
4161cb0ef41Sopenharmony_ci  });
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci  it('should throw when invalid `url` argument passed to `nextLoad`', async () => {
4191cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
4201cb0ef41Sopenharmony_ci      execPath,
4211cb0ef41Sopenharmony_ci      [
4221cb0ef41Sopenharmony_ci        '--loader',
4231cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passthru.mjs'),
4241cb0ef41Sopenharmony_ci        '--loader',
4251cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-bad-next-url.mjs'),
4261cb0ef41Sopenharmony_ci        ...commonArgs,
4271cb0ef41Sopenharmony_ci      ],
4281cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
4291cb0ef41Sopenharmony_ci    );
4301cb0ef41Sopenharmony_ci
4311cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_INVALID_ARG_TYPE/);
4321cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-load-bad-next-url\.mjs/);
4331cb0ef41Sopenharmony_ci    assert.match(stderr, /'load' hook's nextLoad\(\) url/);
4341cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
4351cb0ef41Sopenharmony_ci  });
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_ci  it('should throw when invalid `url` argument passed to `nextLoad`', async () => {
4381cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
4391cb0ef41Sopenharmony_ci      execPath,
4401cb0ef41Sopenharmony_ci      [
4411cb0ef41Sopenharmony_ci        '--loader',
4421cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passthru.mjs'),
4431cb0ef41Sopenharmony_ci        '--loader',
4441cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-impersonating-next-url.mjs'),
4451cb0ef41Sopenharmony_ci        ...commonArgs,
4461cb0ef41Sopenharmony_ci      ],
4471cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
4481cb0ef41Sopenharmony_ci    );
4491cb0ef41Sopenharmony_ci
4501cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_INVALID_ARG_VALUE/);
4511cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-load-impersonating-next-url\.mjs/);
4521cb0ef41Sopenharmony_ci    assert.match(stderr, /'load' hook's nextLoad\(\) url/);
4531cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
4541cb0ef41Sopenharmony_ci  });
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_ci  it('should throw when invalid `context` argument passed to `nextLoad`', async () => {
4571cb0ef41Sopenharmony_ci    const { code, stderr } = await spawnPromisified(
4581cb0ef41Sopenharmony_ci      execPath,
4591cb0ef41Sopenharmony_ci      [
4601cb0ef41Sopenharmony_ci        '--loader',
4611cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-passthru.mjs'),
4621cb0ef41Sopenharmony_ci        '--loader',
4631cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-bad-next-context.mjs'),
4641cb0ef41Sopenharmony_ci        ...commonArgs,
4651cb0ef41Sopenharmony_ci      ],
4661cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
4671cb0ef41Sopenharmony_ci    );
4681cb0ef41Sopenharmony_ci    assert.match(stderr, /ERR_INVALID_ARG_TYPE/);
4691cb0ef41Sopenharmony_ci    assert.match(stderr, /loader-load-bad-next-context\.mjs/);
4701cb0ef41Sopenharmony_ci    assert.match(stderr, /'load' hook's nextLoad\(\) context/);
4711cb0ef41Sopenharmony_ci    assert.strictEqual(code, 1);
4721cb0ef41Sopenharmony_ci  });
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci  it('should allow loaders to influence subsequent loader `import()` calls in `resolve`', async () => {
4751cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
4761cb0ef41Sopenharmony_ci      execPath,
4771cb0ef41Sopenharmony_ci      [
4781cb0ef41Sopenharmony_ci        '--loader',
4791cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-strip-xxx.mjs'),
4801cb0ef41Sopenharmony_ci        '--loader',
4811cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-dynamic-import.mjs'),
4821cb0ef41Sopenharmony_ci        ...commonArgs,
4831cb0ef41Sopenharmony_ci      ],
4841cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
4851cb0ef41Sopenharmony_ci    );
4861cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
4871cb0ef41Sopenharmony_ci    assert.match(stdout, /resolve dynamic import/); // It did go thru resolve-dynamic
4881cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
4891cb0ef41Sopenharmony_ci  });
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci  it('should allow loaders to influence subsequent loader `import()` calls in `load`', async () => {
4921cb0ef41Sopenharmony_ci    const { code, stderr, stdout } = await spawnPromisified(
4931cb0ef41Sopenharmony_ci      execPath,
4941cb0ef41Sopenharmony_ci      [
4951cb0ef41Sopenharmony_ci        '--loader',
4961cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-resolve-strip-xxx.mjs'),
4971cb0ef41Sopenharmony_ci        '--loader',
4981cb0ef41Sopenharmony_ci        fixtures.fileURL('es-module-loaders', 'loader-load-dynamic-import.mjs'),
4991cb0ef41Sopenharmony_ci        ...commonArgs,
5001cb0ef41Sopenharmony_ci      ],
5011cb0ef41Sopenharmony_ci      { encoding: 'utf8' },
5021cb0ef41Sopenharmony_ci    );
5031cb0ef41Sopenharmony_ci    assert.strictEqual(stderr, '');
5041cb0ef41Sopenharmony_ci    assert.match(stdout, /load dynamic import/); // It did go thru load-dynamic
5051cb0ef41Sopenharmony_ci    assert.strictEqual(code, 0);
5061cb0ef41Sopenharmony_ci  });
5071cb0ef41Sopenharmony_ci});
508