aboutsummaryrefslogtreecommitdiff
path: root/test/bun.js/install/bun-install.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'test/bun.js/install/bun-install.test.ts')
-rw-r--r--test/bun.js/install/bun-install.test.ts435
1 files changed, 401 insertions, 34 deletions
diff --git a/test/bun.js/install/bun-install.test.ts b/test/bun.js/install/bun-install.test.ts
index cf6d3a1ca..d176f5dbe 100644
--- a/test/bun.js/install/bun-install.test.ts
+++ b/test/bun.js/install/bun-install.test.ts
@@ -82,10 +82,10 @@ it("should handle missing package", async () => {
);
expect(stdout).toBeDefined();
expect(await new Response(stdout).text()).toBe("");
+ expect(await exited).toBe(1);
expect(urls).toEqual([
"http://localhost:54321/foo",
]);
- expect(await exited).toBe(1);
expect(requested).toBe(1);
try {
await access(join(package_dir, "bun.lockb"));
@@ -134,11 +134,11 @@ it("should handle @scoped authentication", async () => {
expect(err.split(/\r?\n/)).toContain(`GET ${url} - 555`);
expect(stdout).toBeDefined();
expect(await new Response(stdout).text()).toBe("");
+ expect(await exited).toBe(1);
expect(urls).toEqual([
url,
]);
expect(seen_token).toBe(true);
- expect(await exited).toBe(1);
expect(requested).toBe(1);
try {
await access(join(package_dir, "bun.lockb"));
@@ -150,16 +150,7 @@ it("should handle @scoped authentication", async () => {
it("should handle empty string in dependencies", async () => {
const urls: string[] = [];
- handler = async (request) => {
- expect(request.method).toBe("GET");
- expect(request.headers.get("accept")).toBe(
- "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*",
- );
- expect(request.headers.get("npm-auth-type")).toBe(null);
- expect(await request.text()).toBe("");
- urls.push(request.url);
- return new Response("not to be found", { status: 404 });
- };
+ handler = dummyRegistry(urls);
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
@@ -180,22 +171,31 @@ it("should handle empty string in dependencies", async () => {
});
expect(stderr).toBeDefined();
const err = await new Response(stderr).text();
- expect(err).toContain('error: package "bar" not found localhost/bar 404');
- expect(err).toContain("error: bar@ failed to resolve");
+ expect(err).toContain("Saved lockfile");
expect(stdout).toBeDefined();
const out = await new Response(stdout).text();
- expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([""]);
+ expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
+ " + bar@0.0.2", "",
+ " 1 packages installed",
+ ]);
+ expect(await exited).toBe(0);
expect(urls).toEqual([
"http://localhost:54321/bar",
+ "http://localhost:54321/bar.tgz",
]);
- expect(await exited).toBe(1);
- expect(requested).toBe(1);
- try {
- await access(join(package_dir, "bun.lockb"));
- expect(() => {}).toThrow();
- } catch (err: any) {
- expect(err.code).toBe("ENOENT");
- }
+ expect(requested).toBe(2);
+ expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
+ ".cache",
+ "bar",
+ ]);
+ expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual([
+ "package.json",
+ ]);
+ expect(await file(join(package_dir, "node_modules", "bar", "package.json")).json()).toEqual({
+ name: "baz",
+ version: "0.0.2",
+ });
+ await access(join(package_dir, "bun.lockb"));
});
it("should handle workspaces", async () => {
@@ -559,7 +559,7 @@ it("should handle life-cycle scripts within workspaces", async () => {
await access(join(package_dir, "bun.lockb"));
});
-function dummyRegistry(urls) {
+function dummyRegistry(urls, version = "0.0.2") {
return async (request) => {
urls.push(request.url);
expect(request.method).toBe("GET");
@@ -573,23 +573,390 @@ function dummyRegistry(urls) {
expect(await request.text()).toBe("");
const name = request.url.slice(request.url.lastIndexOf("/") + 1);
return new Response(JSON.stringify({
- name: name,
+ name,
versions: {
- "0.0.2": {
- name: name,
- version: "0.0.2",
+ [version]: {
+ name,
+ version,
dist: {
tarball: `${request.url}.tgz`,
},
},
},
"dist-tags": {
- latest: "0.0.2",
+ latest: version,
},
}));
};
}
+it("should handle ^0 in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls);
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^0",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain("Saved lockfile");
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
+ " + bar@0.0.2", "",
+ " 1 packages installed",
+ ]);
+ expect(await exited).toBe(0);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ "http://localhost:54321/bar.tgz",
+ ]);
+ expect(requested).toBe(2);
+ expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
+ ".cache",
+ "bar",
+ ]);
+ expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual([
+ "package.json",
+ ]);
+ expect(await file(join(package_dir, "node_modules", "bar", "package.json")).json()).toEqual({
+ name: "baz",
+ version: "0.0.2",
+ });
+ await access(join(package_dir, "bun.lockb"));
+});
+
+it("should handle ^1 in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls);
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^1",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain('error: No version matching "^1" found for specifier "bar" (but package exists)');
+ expect(stdout).toBeDefined();
+ expect(await new Response(stdout).text()).toBe("");
+ expect(await exited).toBe(1);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ ]);
+ expect(requested).toBe(1);
+ try {
+ await access(join(package_dir, "bun.lockb"));
+ expect(() => {}).toThrow();
+ } catch (err: any) {
+ expect(err.code).toBe("ENOENT");
+ }
+});
+
+it("should handle ^0.0 in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls);
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^0.0",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain("Saved lockfile");
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
+ " + bar@0.0.2", "",
+ " 1 packages installed",
+ ]);
+ expect(await exited).toBe(0);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ "http://localhost:54321/bar.tgz",
+ ]);
+ expect(requested).toBe(2);
+ expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
+ ".cache",
+ "bar",
+ ]);
+ expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual([
+ "package.json",
+ ]);
+ expect(await file(join(package_dir, "node_modules", "bar", "package.json")).json()).toEqual({
+ name: "baz",
+ version: "0.0.2",
+ });
+ await access(join(package_dir, "bun.lockb"));
+});
+
+it("should handle ^0.1 in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls);
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^0.1",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain('error: No version matching "^0.1" found for specifier "bar" (but package exists)');
+ expect(stdout).toBeDefined();
+ expect(await new Response(stdout).text()).toBe("");
+ expect(await exited).toBe(1);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ ]);
+ expect(requested).toBe(1);
+ try {
+ await access(join(package_dir, "bun.lockb"));
+ expect(() => {}).toThrow();
+ } catch (err: any) {
+ expect(err.code).toBe("ENOENT");
+ }
+});
+
+it("should handle ^0.0.0 in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls);
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^0.0.0",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain('error: No version matching "^0.0.0" found for specifier "bar" (but package exists)');
+ expect(stdout).toBeDefined();
+ expect(await new Response(stdout).text()).toBe("");
+ expect(await exited).toBe(1);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ ]);
+ expect(requested).toBe(1);
+ try {
+ await access(join(package_dir, "bun.lockb"));
+ expect(() => {}).toThrow();
+ } catch (err: any) {
+ expect(err.code).toBe("ENOENT");
+ }
+});
+
+it("should handle ^0.0.2 in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls);
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^0.0.2",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain("Saved lockfile");
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
+ " + bar@0.0.2", "",
+ " 1 packages installed",
+ ]);
+ expect(await exited).toBe(0);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ "http://localhost:54321/bar.tgz",
+ ]);
+ expect(requested).toBe(2);
+ expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
+ ".cache",
+ "bar",
+ ]);
+ expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual([
+ "package.json",
+ ]);
+ expect(await file(join(package_dir, "node_modules", "bar", "package.json")).json()).toEqual({
+ name: "baz",
+ version: "0.0.2",
+ });
+ await access(join(package_dir, "bun.lockb"));
+});
+
+it("should handle ^0.0.2-rc in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls, "0.0.2-rc");
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^0.0.2-rc",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain("Saved lockfile");
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
+ " + bar@0.0.2-rc", "",
+ " 1 packages installed",
+ ]);
+ expect(await exited).toBe(0);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ "http://localhost:54321/bar.tgz",
+ ]);
+ expect(requested).toBe(2);
+ expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
+ ".cache",
+ "bar",
+ ]);
+ expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual([
+ "package.json",
+ ]);
+ expect(await file(join(package_dir, "node_modules", "bar", "package.json")).json()).toEqual({
+ name: "baz",
+ version: "0.0.2",
+ });
+ await access(join(package_dir, "bun.lockb"));
+});
+
+it("should handle ^0.0.2-alpha.3+b4d in dependencies", async () => {
+ const urls: string[] = [];
+ handler = dummyRegistry(urls, "0.0.2-alpha.3");
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "foo",
+ version: "0.0.1",
+ dependencies: {
+ "bar": "^0.0.2-alpha.3+b4d",
+ },
+ }),
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain("Saved lockfile");
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
+ " + bar@0.0.2-alpha.3", "",
+ " 1 packages installed",
+ ]);
+ expect(await exited).toBe(0);
+ expect(urls).toEqual([
+ "http://localhost:54321/bar",
+ "http://localhost:54321/bar.tgz",
+ ]);
+ expect(requested).toBe(2);
+ expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
+ ".cache",
+ "bar",
+ ]);
+ expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual([
+ "package.json",
+ ]);
+ expect(await file(join(package_dir, "node_modules", "bar", "package.json")).json()).toEqual({
+ name: "baz",
+ version: "0.0.2",
+ });
+ await access(join(package_dir, "bun.lockb"));
+});
+
it("should handle dependency aliasing", async () => {
const urls = [];
handler = dummyRegistry(urls);
@@ -637,7 +1004,7 @@ it("should handle dependency aliasing", async () => {
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
name: "baz",
version: "0.0.2",
- })
+ });
await access(join(package_dir, "bun.lockb"));
});
@@ -688,7 +1055,7 @@ it("should handle dependency aliasing (versioned)", async () => {
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
name: "baz",
version: "0.0.2",
- })
+ });
await access(join(package_dir, "bun.lockb"));
});
@@ -739,7 +1106,7 @@ it("should handle dependency aliasing (dist-tagged)", async () => {
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
name: "baz",
version: "0.0.2",
- })
+ });
await access(join(package_dir, "bun.lockb"));
});
@@ -790,7 +1157,7 @@ it("should not reinstall aliased dependencies", async () => {
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
name: "baz",
version: "0.0.2",
- })
+ });
await access(join(package_dir, "bun.lockb"));
// Performs `bun install` again, expects no-op
urls.length = 0;
@@ -824,6 +1191,6 @@ it("should not reinstall aliased dependencies", async () => {
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
name: "baz",
version: "0.0.2",
- })
+ });
await access(join(package_dir, "bun.lockb"));
});