mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
334 lines
10 KiB
TypeScript
334 lines
10 KiB
TypeScript
import { it, expect } from "bun:test";
|
||
import { mkdirSync, writeFileSync } from "fs";
|
||
import { join, sep } from "path";
|
||
import { bunExe, bunEnv, tempDirWithFiles, isWindows } from "harness";
|
||
import { pathToFileURL } from "bun";
|
||
|
||
it("spawn test file", () => {
|
||
writePackageJSONImportsFixture();
|
||
writePackageJSONExportsFixture();
|
||
|
||
const { exitCode } = Bun.spawnSync({
|
||
cmd: [bunExe(), "test", "./resolve-test.js"],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
stdio: ["inherit", "inherit", "inherit"],
|
||
});
|
||
|
||
expect(exitCode).toBe(0);
|
||
});
|
||
|
||
function writePackageJSONExportsFixture() {
|
||
try {
|
||
mkdirSync(join(import.meta.dir, "./node_modules/package-json-exports/foo"), {
|
||
recursive: true,
|
||
});
|
||
} catch (exception) {}
|
||
writeFileSync(join(import.meta.dir, "./node_modules/package-json-exports/foo/bar.js"), "export const bar = 1;");
|
||
writeFileSync(
|
||
join(import.meta.dir, "./node_modules/package-json-exports/foo/references-baz.js"),
|
||
"export {bar} from 'package-json-exports/baz';",
|
||
);
|
||
writeFileSync(
|
||
join(import.meta.dir, "./node_modules/package-json-exports/package.json"),
|
||
JSON.stringify(
|
||
{
|
||
name: "package-json-exports",
|
||
exports: {
|
||
"./baz": "./foo/bar.js",
|
||
"./references-baz": "./foo/references-baz.js",
|
||
},
|
||
},
|
||
null,
|
||
2,
|
||
),
|
||
);
|
||
}
|
||
|
||
function writePackageJSONImportsFixture() {
|
||
try {
|
||
mkdirSync(join(import.meta.dir, "./node_modules/package-json-imports/foo"), {
|
||
recursive: true,
|
||
});
|
||
} catch (exception) {}
|
||
writeFileSync(join(import.meta.dir, "./node_modules/package-json-imports/foo/bar.js"), "export const bar = 1;");
|
||
writeFileSync(
|
||
join(import.meta.dir, "./node_modules/package-json-imports/foo/wildcard.js"),
|
||
"export const wildcard = 1;",
|
||
);
|
||
writeFileSync(
|
||
join(import.meta.dir, "./node_modules/package-json-imports/foo/private-foo.js"),
|
||
"export {bar} from 'package-json-imports/#foo';",
|
||
);
|
||
writeFileSync(
|
||
join(import.meta.dir, "./node_modules/package-json-imports/package.json"),
|
||
JSON.stringify(
|
||
{
|
||
name: "package-json-imports",
|
||
exports: {
|
||
"./baz": "./foo/bar.js",
|
||
},
|
||
imports: {
|
||
"#foo/bar": "./foo/private-foo.js",
|
||
"#foo/*.js": "./foo/*.js",
|
||
"#foo/extensionless/*": "./foo/*.js",
|
||
"#foo": "./foo/private-foo.js",
|
||
|
||
"#internal-react": "react",
|
||
|
||
"#to_node_module": "async_hooks",
|
||
},
|
||
},
|
||
null,
|
||
2,
|
||
),
|
||
);
|
||
}
|
||
|
||
it("file url in import resolves", async () => {
|
||
const dir = tempDirWithFiles("fileurl", {
|
||
"index.js": "export const foo = 1;",
|
||
});
|
||
writeFileSync(`${dir}/test.js`, `import {foo} from '${pathToFileURL(dir)}/index.js';\nconsole.log(foo);`);
|
||
|
||
console.log(dir);
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
try {
|
||
expect(exitCode).toBe(0);
|
||
} catch (e) {
|
||
console.log(stdout.toString("utf8"));
|
||
throw e;
|
||
}
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("invalid file url in import throws error", async () => {
|
||
const dir = tempDirWithFiles("fileurl", {});
|
||
writeFileSync(`${dir}/test.js`, `import {foo} from 'file://\0invalid url';\nconsole.log(foo);`);
|
||
|
||
const { exitCode, stdout, stderr } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).not.toBe(0);
|
||
expect(stderr.toString("utf8")).toContain("file://\0invalid url");
|
||
});
|
||
|
||
it("file url in await import resolves", async () => {
|
||
const dir = tempDirWithFiles("fileurl", {
|
||
"index.js": "export const foo = 1;",
|
||
});
|
||
writeFileSync(`${dir}/test.js`, `const {foo} = await import('${pathToFileURL(dir)}/index.js');\nconsole.log(foo);`);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("file url with special characters in await import resolves", async () => {
|
||
const filename = "🅱️ndex.js";
|
||
const dir = tempDirWithFiles("file url", {
|
||
[filename]: "export const foo = 1;",
|
||
});
|
||
console.log(dir);
|
||
writeFileSync(
|
||
`${dir}/test.js`,
|
||
`const {foo} = await import('${pathToFileURL(dir)}/${encodeURIComponent(filename)}');\nconsole.log(foo);`,
|
||
);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("file url with special characters not encoded in await import resolves", async () => {
|
||
const filename = "🅱️ndex.js";
|
||
const dir = tempDirWithFiles("file url", {
|
||
[filename]: "export const foo = 1;",
|
||
});
|
||
writeFileSync(
|
||
`${dir}/test.js`,
|
||
`const {foo} = await import('${pathToFileURL(dir)}/${filename}');\nconsole.log(foo);`,
|
||
);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("file url with special characters in import statement resolves", async () => {
|
||
const filename = "🅱️ndex.js";
|
||
const dir = tempDirWithFiles("file url", {
|
||
[filename]: "export const foo = 1;",
|
||
});
|
||
writeFileSync(
|
||
`${dir}/test.js`,
|
||
`import {foo} from '${pathToFileURL(dir)}/${encodeURIComponent(filename)}';\nconsole.log(foo);`,
|
||
);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("file url with special characters not encoded in import statement resolves", async () => {
|
||
const filename = "🅱️ndex.js";
|
||
const dir = tempDirWithFiles("file url", {
|
||
[filename]: "export const foo = 1;",
|
||
});
|
||
writeFileSync(`${dir}/test.js`, `import {foo} from '${pathToFileURL(dir)}/${filename}';\nconsole.log(foo);`);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("file url in require resolves", async () => {
|
||
const dir = tempDirWithFiles("fileurl", {
|
||
"index.js": "export const foo = 1;",
|
||
});
|
||
writeFileSync(`${dir}/test.js`, `const {foo} = require('${pathToFileURL(dir)}/index.js');\nconsole.log(foo);`);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("file url with special characters in require resolves", async () => {
|
||
const filename = "🅱️ndex.js";
|
||
const dir = tempDirWithFiles("file url", {
|
||
[filename]: "export const foo = 1;",
|
||
});
|
||
writeFileSync(
|
||
`${dir}/test.js`,
|
||
`const {foo} = require('${pathToFileURL(dir)}/${encodeURIComponent(filename)}');\nconsole.log(foo);`,
|
||
);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe("1\n");
|
||
});
|
||
|
||
it("file url in require.resolve resolves", async () => {
|
||
const dir = tempDirWithFiles("fileurl", {
|
||
"index.js": "export const foo = 1;",
|
||
});
|
||
writeFileSync(`${dir}/test.js`, `const to = require.resolve('${pathToFileURL(dir)}/index.js');\nconsole.log(to);`);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe(`${dir}${sep}index.js\n`);
|
||
});
|
||
|
||
it("file url with special characters in require resolves", async () => {
|
||
const filename = "🅱️ndex.js";
|
||
const dir = tempDirWithFiles("file url", {
|
||
[filename]: "export const foo = 1;",
|
||
});
|
||
writeFileSync(
|
||
`${dir}/test.js`,
|
||
`const to = require.resolve('${pathToFileURL(dir)}/${encodeURIComponent(filename)}');\nconsole.log(to);`,
|
||
);
|
||
|
||
const { exitCode, stdout } = Bun.spawnSync({
|
||
cmd: [bunExe(), `${dir}/test.js`],
|
||
env: bunEnv,
|
||
cwd: import.meta.dir,
|
||
});
|
||
expect(exitCode).toBe(0);
|
||
expect(stdout.toString("utf8")).toBe(`${dir}${sep}${filename}\n`);
|
||
});
|
||
|
||
it("import long string should not segfault", async () => {
|
||
try {
|
||
await import("a".repeat(10000));
|
||
} catch {}
|
||
});
|
||
it("import long string should not segfault", async () => {
|
||
try {
|
||
import.meta.require("a".repeat(10000));
|
||
} catch {}
|
||
});
|
||
it("import long string should not segfault", async () => {
|
||
try {
|
||
await import.meta.resolve!("a".repeat(10000));
|
||
} catch {}
|
||
});
|
||
it("import long string should not segfault", async () => {
|
||
try {
|
||
await import.meta.require.resolve("a".repeat(10000));
|
||
} catch {}
|
||
});
|
||
|
||
it("import override to node builtin", async () => {
|
||
// @ts-expect-error
|
||
expect(await import("#async_hooks")).toBeDefined();
|
||
});
|
||
|
||
it("import override to bun", async () => {
|
||
// @ts-expect-error
|
||
expect(await import("#bun")).toBeDefined();
|
||
});
|
||
|
||
it.todo("import override to bun:test", async () => {
|
||
// @ts-expect-error
|
||
expect(await import("#bun_test")).toBeDefined();
|
||
});
|
||
|
||
it.if(isWindows)("directory cache key computation", () => {
|
||
expect(import(`${process.cwd()}\\\\doesnotexist.ts`)).rejects.toThrow();
|
||
expect(import(`${process.cwd()}\\\\\\doesnotexist.ts`)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\doesnotexist.ts\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\doesnotexist.ts\\\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\doesnotexist.ts\\\\\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\\\doesnotexist.ts` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\\\\\doesnotexist.ts` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\doesnotexist.ts` as any)).rejects.toThrow();
|
||
expect(import(`\\\\\\Test\\doesnotexist.ts` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\\\doesnotexist.ts\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\\\\\doesnotexist.ts\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\doesnotexist.ts\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\\\Test\\doesnotexist.ts\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\\\doesnotexist.ts\\\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\\\\\\\doesnotexist.ts\\\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\Test\\doesnotexist.ts\\\\` as any)).rejects.toThrow();
|
||
expect(import(`\\\\\\Test\\doesnotexist.ts\\\\` as any)).rejects.toThrow();
|
||
});
|