diff options
Diffstat (limited to 'test/bun.js/install/bun-install.test.ts')
-rw-r--r-- | test/bun.js/install/bun-install.test.ts | 435 |
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")); }); |