1import { spawnPromisified } from '../common/index.mjs';
2import * as fixtures from '../common/fixtures.mjs';
3import assert from 'node:assert';
4import { execPath } from 'node:process';
5import { describe, it, test } from 'node:test';
6
7import { mkdir, rm, writeFile } from 'node:fs/promises';
8import * as tmpdir from '../common/tmpdir.js';
9
10import secret from '../fixtures/experimental.json' with { type: 'json' };
11
12describe('ESM: importing JSON', () => {
13  it('should load JSON', () => {
14    assert.strictEqual(secret.ofLife, 42);
15  });
16
17  it('should print an experimental warning', async () => {
18    const { code, signal, stderr } = await spawnPromisified(execPath, [
19      fixtures.path('/es-modules/json-modules.mjs'),
20    ]);
21
22    assert.match(stderr, /ExperimentalWarning: Importing JSON modules/);
23    assert.strictEqual(code, 0);
24    assert.strictEqual(signal, null);
25  });
26
27  test('should load different modules when the URL is different', async (t) => {
28    const root = tmpdir.fileURL(`./test-esm-json-${Math.random()}/`);
29    try {
30      await mkdir(root, { recursive: true });
31
32      await t.test('json', async () => {
33        let i = 0;
34        const url = new URL('./foo.json', root);
35        await writeFile(url, JSON.stringify({ id: i++ }));
36        const absoluteURL = await import(`${url}`, {
37          with: { type: 'json' },
38        });
39        await writeFile(url, JSON.stringify({ id: i++ }));
40        const queryString = await import(`${url}?a=2`, {
41          with: { type: 'json' },
42        });
43        await writeFile(url, JSON.stringify({ id: i++ }));
44        const hash = await import(`${url}#a=2`, {
45          with: { type: 'json' },
46        });
47        await writeFile(url, JSON.stringify({ id: i++ }));
48        const queryStringAndHash = await import(`${url}?a=2#a=2`, {
49          with: { type: 'json' },
50        });
51
52        assert.notDeepStrictEqual(absoluteURL, queryString);
53        assert.notDeepStrictEqual(absoluteURL, hash);
54        assert.notDeepStrictEqual(queryString, hash);
55        assert.notDeepStrictEqual(absoluteURL, queryStringAndHash);
56        assert.notDeepStrictEqual(queryString, queryStringAndHash);
57        assert.notDeepStrictEqual(hash, queryStringAndHash);
58      });
59
60      await t.test('js', async () => {
61        let i = 0;
62        const url = new URL('./foo.mjs', root);
63        await writeFile(url, `export default ${JSON.stringify({ id: i++ })}\n`);
64        const absoluteURL = await import(`${url}`);
65        await writeFile(url, `export default ${JSON.stringify({ id: i++ })}\n`);
66        const queryString = await import(`${url}?a=1`);
67        await writeFile(url, `export default ${JSON.stringify({ id: i++ })}\n`);
68        const hash = await import(`${url}#a=1`);
69        await writeFile(url, `export default ${JSON.stringify({ id: i++ })}\n`);
70        const queryStringAndHash = await import(`${url}?a=1#a=1`);
71
72        assert.notDeepStrictEqual(absoluteURL, queryString);
73        assert.notDeepStrictEqual(absoluteURL, hash);
74        assert.notDeepStrictEqual(queryString, hash);
75        assert.notDeepStrictEqual(absoluteURL, queryStringAndHash);
76        assert.notDeepStrictEqual(queryString, queryStringAndHash);
77        assert.notDeepStrictEqual(hash, queryStringAndHash);
78      });
79    } finally {
80      await rm(root, { force: true, recursive: true });
81    }
82  });
83});
84