diff options
author | 2023-01-30 23:12:41 -0800 | |
---|---|---|
committer | 2023-01-30 23:12:41 -0800 | |
commit | ad3295668f18424846aaebb114f5272ce77c7f73 (patch) | |
tree | f6e078e6dd5dfeac3c90ddba7a366c8c951d2724 /test | |
parent | f9fd7e9d0895f9141667712e945118ab5c57b93d (diff) | |
download | bun-ad3295668f18424846aaebb114f5272ce77c7f73.tar.gz bun-ad3295668f18424846aaebb114f5272ce77c7f73.tar.zst bun-ad3295668f18424846aaebb114f5272ce77c7f73.zip |
Fix crash in `bun install <package-name>` (#1947)
* Fix crash in `bun install <package-name>` when <package-name> already exists
* Prettier
* Add test
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/bun.js/install/bun-install.test.ts | 484 |
1 files changed, 355 insertions, 129 deletions
diff --git a/test/bun.js/install/bun-install.test.ts b/test/bun.js/install/bun-install.test.ts index 7d127d4ed..33a662dc2 100644 --- a/test/bun.js/install/bun-install.test.ts +++ b/test/bun.js/install/bun-install.test.ts @@ -9,12 +9,7 @@ import { } from "bun:test"; import { bunExe } from "bunExe"; import { bunEnv as env } from "bunEnv"; -import { - access, - mkdir, - readlink, - writeFile, -} from "fs/promises"; +import { access, mkdir, readlink, writeFile } from "fs/promises"; import { join } from "path"; import { dummyAfterAll, @@ -28,6 +23,7 @@ import { root_url, setHandler, } from "./dummy.registry"; +import { rmSync } from "fs"; beforeAll(dummyBeforeAll); afterAll(dummyAfterAll); @@ -161,10 +157,7 @@ it("should handle empty string in dependencies", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/bar`, - `${root_url}/bar.tgz`, - ]); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".cache", @@ -575,10 +568,7 @@ it("should handle ^0 in dependencies", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/bar`, - `${root_url}/bar.tgz`, - ]); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".cache", @@ -667,10 +657,7 @@ it("should handle ^0.0 in dependencies", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/bar`, - `${root_url}/bar.tgz`, - ]); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".cache", @@ -798,10 +785,7 @@ it("should handle ^0.0.2 in dependencies", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/bar`, - `${root_url}/bar.tgz`, - ]); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".cache", @@ -851,10 +835,7 @@ it("should handle ^0.0.2-rc in dependencies", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/bar`, - `${root_url}/bar.tgz`, - ]); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".cache", @@ -904,10 +885,7 @@ it("should handle ^0.0.2-alpha.3+b4d in dependencies", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/bar`, - `${root_url}/bar.tgz`, - ]); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".cache", @@ -927,11 +905,13 @@ it("should handle ^0.0.2-alpha.3+b4d in dependencies", async () => { it("should handle dependency aliasing", async () => { const urls = []; - setHandler(dummyRegistry(urls, "0.0.3", { - bin: { - "baz-run": "index.js", - }, - })); + setHandler( + dummyRegistry(urls, "0.0.3", { + bin: { + "baz-run": "index.js", + }, + }), + ); await writeFile( join(package_dir, "package.json"), JSON.stringify({ @@ -961,25 +941,25 @@ it("should handle dependency aliasing", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/baz`, - `${root_url}/baz.tgz`, - ]); + expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".bin", ".cache", "Bar", ]); - expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([ - "baz-run", - ]); - expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js")); - expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([ - "index.js", - "package.json", - ]); - expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({ + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["baz-run"]); + expect( + await readlink(join(package_dir, "node_modules", ".bin", "baz-run")), + ).toBe(join("..", "Bar", "index.js")); + expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual( + ["index.js", "package.json"], + ); + expect( + await file(join(package_dir, "node_modules", "Bar", "package.json")).json(), + ).toEqual({ name: "baz", version: "0.0.3", bin: { @@ -991,11 +971,13 @@ it("should handle dependency aliasing", async () => { it("should handle dependency aliasing (versioned)", async () => { const urls: string[] = []; - setHandler(dummyRegistry(urls, "0.0.3", { - bin: { - "baz-run": "index.js", - }, - })); + setHandler( + dummyRegistry(urls, "0.0.3", { + bin: { + "baz-run": "index.js", + }, + }), + ); await writeFile( join(package_dir, "package.json"), JSON.stringify({ @@ -1025,25 +1007,25 @@ it("should handle dependency aliasing (versioned)", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/baz`, - `${root_url}/baz.tgz`, - ]); + expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".bin", ".cache", "Bar", ]); - expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([ - "baz-run", - ]); - expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js")); - expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([ - "index.js", - "package.json", - ]); - expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({ + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["baz-run"]); + expect( + await readlink(join(package_dir, "node_modules", ".bin", "baz-run")), + ).toBe(join("..", "Bar", "index.js")); + expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual( + ["index.js", "package.json"], + ); + expect( + await file(join(package_dir, "node_modules", "Bar", "package.json")).json(), + ).toEqual({ name: "baz", version: "0.0.3", bin: { @@ -1053,13 +1035,241 @@ it("should handle dependency aliasing (versioned)", async () => { await access(join(package_dir, "bun.lockb")); }); -it("should handle dependency aliasing (dist-tagged)", async () => { +it("should handle ^0.0.2-rc in dependencies", async () => { + const urls: string[] = []; + setHandler(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\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([ + " + bar@0.0.2-rc", + "", + " 1 packages installed", + ]); + expect(await exited).toBe(0); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/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: "bar", + 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[] = []; - setHandler(dummyRegistry(urls, "0.0.3", { + setHandler(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\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([ + " + bar@0.0.2-alpha.3", + "", + " 1 packages installed", + ]); + expect(await exited).toBe(0); + expect(urls).toEqual([`${root_url}/bar`, `${root_url}/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: "bar", + version: "0.0.2", + }); + await access(join(package_dir, "bun.lockb")); +}); + +it("should handle dependency aliasing", async () => { + const urls = []; + setHandler( + dummyRegistry(urls, "0.0.3", { + bin: { + "baz-run": "index.js", + }, + }), + ); + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ + name: "Foo", + version: "0.0.1", + dependencies: { + Bar: "npm:baz", + }, + }), + ); + 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\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([ + " + Bar@0.0.3", + "", + " 1 packages installed", + ]); + expect(await exited).toBe(0); + expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]); + expect(requested).toBe(2); + expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ + ".bin", + ".cache", + "Bar", + ]); + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["baz-run"]); + expect( + await readlink(join(package_dir, "node_modules", ".bin", "baz-run")), + ).toBe(join("..", "Bar", "index.js")); + expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual( + ["index.js", "package.json"], + ); + expect( + await file(join(package_dir, "node_modules", "Bar", "package.json")).json(), + ).toEqual({ + name: "baz", + version: "0.0.3", bin: { "baz-run": "index.js", }, - })); + }); + await access(join(package_dir, "bun.lockb")); +}); + +it("should let you add the same package twice", async () => { + const urls: string[] = []; + setHandler(dummyRegistry(urls, "0.0.3", {})); + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ + name: "Foo", + version: "0.0.1", + dependencies: {}, + }), + ); + rmSync(`${root_url}/baz`, { recursive: true, force: true }); + for (let i = 0; i < 2; i++) { + const { stdout, stderr, exited } = spawn({ + cmd: [ + bunExe(), + "install", + "baz@0.0.3", + "--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).toContain("installed baz@0.0.3"); + if (i === 0) { + expect(out).toContain("1 packages installed"); + } else { + expect(out).not.toContain("1 packages installed"); + } + expect(await exited).toBe(0); + expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]); + expect(requested).toBe(2); + expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ + ".cache", + "baz", + ]); + expect( + await file( + join(package_dir, "node_modules", "baz", "package.json"), + ).json(), + ).toEqual({ + name: "baz", + version: "0.0.3", + bin: { + "baz-run": "index.js", + }, + }); + await access(join(package_dir, "bun.lockb")); + } +}); + +it("should handle dependency aliasing (dist-tagged)", async () => { + const urls: string[] = []; + setHandler( + dummyRegistry(urls, "0.0.3", { + bin: { + "baz-run": "index.js", + }, + }), + ); await writeFile( join(package_dir, "package.json"), JSON.stringify({ @@ -1089,25 +1299,25 @@ it("should handle dependency aliasing (dist-tagged)", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls).toEqual([ - `${root_url}/baz`, - `${root_url}/baz.tgz`, - ]); + expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".bin", ".cache", "Bar", ]); - expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([ - "baz-run", - ]); - expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js")); - expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([ - "index.js", - "package.json", - ]); - expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({ + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["baz-run"]); + expect( + await readlink(join(package_dir, "node_modules", ".bin", "baz-run")), + ).toBe(join("..", "Bar", "index.js")); + expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual( + ["index.js", "package.json"], + ); + expect( + await file(join(package_dir, "node_modules", "Bar", "package.json")).json(), + ).toEqual({ name: "baz", version: "0.0.3", bin: { @@ -1119,11 +1329,13 @@ it("should handle dependency aliasing (dist-tagged)", async () => { it("should not reinstall aliased dependencies", async () => { const urls = []; - setHandler(dummyRegistry(urls, "0.0.3", { - bin: { - "baz-run": "index.js", - }, - })); + setHandler( + dummyRegistry(urls, "0.0.3", { + bin: { + "baz-run": "index.js", + }, + }), + ); await writeFile( join(package_dir, "package.json"), JSON.stringify({ @@ -1157,25 +1369,25 @@ it("should not reinstall aliased dependencies", async () => { " 1 packages installed", ]); expect(await exited1).toBe(0); - expect(urls).toEqual([ - `${root_url}/baz`, - `${root_url}/baz.tgz`, - ]); + expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([ ".bin", ".cache", "Bar", ]); - expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([ - "baz-run", - ]); - expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js")); - expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([ - "index.js", - "package.json", - ]); - expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({ + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["baz-run"]); + expect( + await readlink(join(package_dir, "node_modules", ".bin", "baz-run")), + ).toBe(join("..", "Bar", "index.js")); + expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual( + ["index.js", "package.json"], + ); + expect( + await file(join(package_dir, "node_modules", "Bar", "package.json")).json(), + ).toEqual({ name: "baz", version: "0.0.3", bin: { @@ -1214,15 +1426,18 @@ it("should not reinstall aliased dependencies", async () => { ".cache", "Bar", ]); - expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([ - "baz-run", - ]); - expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js")); - expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([ - "index.js", - "package.json", - ]); - expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({ + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["baz-run"]); + expect( + await readlink(join(package_dir, "node_modules", ".bin", "baz-run")), + ).toBe(join("..", "Bar", "index.js")); + expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual( + ["index.js", "package.json"], + ); + expect( + await file(join(package_dir, "node_modules", "Bar", "package.json")).json(), + ).toEqual({ name: "baz", version: "0.0.3", bin: { @@ -1511,25 +1726,28 @@ it("should handle GitHub URL in dependencies (github:user/repo#tag)", async () = expect( await readdirSorted(join(package_dir, "node_modules", ".bin")), ).toEqual(["uglifyjs"]); - expect(await readlink(join(package_dir, "node_modules", ".bin", "uglifyjs"))).toBe(join( - "..", - "uglify", - "bin", - "uglifyjs", - )); + expect( + await readlink(join(package_dir, "node_modules", ".bin", "uglifyjs")), + ).toBe(join("..", "uglify", "bin", "uglifyjs")); expect( await readdirSorted(join(package_dir, "node_modules", ".cache")), ).toEqual(["@GH@mishoo-UglifyJS-e219a9a", "uglify"]); - expect(await readdirSorted(join(package_dir, "node_modules", ".cache", "uglify"))).toEqual([ - "mishoo-UglifyJS-e219a9a", - ]); - expect(await readlink(join( - package_dir, - "node_modules", - ".cache", - "uglify", - "mishoo-UglifyJS-e219a9a", - ))).toBe(join(package_dir, "node_modules", ".cache", "@GH@mishoo-UglifyJS-e219a9a")); + expect( + await readdirSorted(join(package_dir, "node_modules", ".cache", "uglify")), + ).toEqual(["mishoo-UglifyJS-e219a9a"]); + expect( + await readlink( + join( + package_dir, + "node_modules", + ".cache", + "uglify", + "mishoo-UglifyJS-e219a9a", + ), + ), + ).toBe( + join(package_dir, "node_modules", ".cache", "@GH@mishoo-UglifyJS-e219a9a"), + ); expect( await readdirSorted(join(package_dir, "node_modules", "uglify")), ).toEqual([ @@ -1595,8 +1813,12 @@ it("should handle GitHub URL in dependencies (https://github.com/user/repo.git)" ".cache", "uglify", ]); - expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["uglifyjs"]); - expect(await readdirSorted(join(package_dir, "node_modules", "uglify"))).toEqual([ + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["uglifyjs"]); + expect( + await readdirSorted(join(package_dir, "node_modules", "uglify")), + ).toEqual([ ".bun-tag", ".gitattributes", ".github", @@ -1658,8 +1880,12 @@ it("should handle GitHub URL in dependencies (git+https://github.com/user/repo.g ".cache", "uglify", ]); - expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["uglifyjs"]); - expect(await readdirSorted(join(package_dir, "node_modules", "uglify"))).toEqual([ + expect( + await readdirSorted(join(package_dir, "node_modules", ".bin")), + ).toEqual(["uglifyjs"]); + expect( + await readdirSorted(join(package_dir, "node_modules", "uglify")), + ).toEqual([ ".bun-tag", ".gitattributes", ".github", |