diff options
Diffstat (limited to '')
| -rw-r--r-- | test/bun.js/install/bun-install.test.ts | 344 | 
1 files changed, 300 insertions, 44 deletions
| diff --git a/test/bun.js/install/bun-install.test.ts b/test/bun.js/install/bun-install.test.ts index 58bd4918e..78b1c12b8 100644 --- a/test/bun.js/install/bun-install.test.ts +++ b/test/bun.js/install/bun-install.test.ts @@ -1,26 +1,53 @@ -import { spawn, spawnSync } from "bun"; -import { describe, expect, it, test } from "bun:test"; +import { spawn } from "bun"; +import { afterAll, afterEach, beforeAll, beforeEach, expect, it } from "bun:test";  import { bunExe } from "bunExe"; +import { mkdir, mkdtemp, readdir, readlink, rm, writeFile } from "fs/promises"; +import { join } from "path"; +import { tmpdir } from "os"; -test("bun install", async () => { -  const urls = []; -  const server = Bun.serve({ +let handler, package_dir, requested, server; + +function resetHanlder() { +  handler = function() { +    return new Response("Tea Break~", { status: 418 }); +  }; +} + +beforeAll(() => { +  server = Bun.serve({      async fetch(request) { -      try { -        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("bar", { status: 404 }); -      } finally { -        server.stop(); -      } +      requested++; +      return await handler(request);      },      port: 54321,    }); +}); +afterAll(() => { +  server.stop(); +}); +beforeEach(async () => { +  resetHanlder(); +  requested = 0; +  package_dir = await mkdtemp(join(tmpdir(), "bun-install.test")); +}); +afterEach(async () => { +  resetHanlder(); +  await rm(package_dir, { force: true, recursive: true }); +}); + +it("should handle missing package", 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("bar", { status: 404 }); +  };    const { stdout, stderr, exited } = spawn({      cmd: [bunExe(), "install", "foo", "--config", import.meta.dir + "/basic.toml"], +    cwd: package_dir,      stdout: null,      stdin: "pipe",      stderr: "pipe", @@ -29,42 +56,37 @@ test("bun install", async () => {        BUN_DEBUG_QUIET_LOGS: "1",      },    }); -  expect(stdout).toBeDefined();    expect(stderr).toBeDefined(); -  expect(await new Response(stdout).text()).toBe("");    var err = await new Response(stderr).text(); -  expect(err.split(/\n/)).toContain('error: package "foo" not found localhost/foo 404'); +  expect(err.split(/\r?\n/)).toContain('error: package "foo" not found localhost/foo 404'); +  expect(stdout).toBeDefined(); +  expect(await new Response(stdout).text()).toBe("");    expect(urls).toContain("http://localhost:54321/foo");    expect(await exited).toBe(1); +  expect(requested).toBe(1);  }); -test("bun install @scoped", async () => { +it("should handle @scoped authentication", async () => {    let seen_token = false;    const url = "http://localhost:54321/@foo/bar"; -  const urls = []; -  const server = Bun.serve({ -    async fetch(request) { -      try { -        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, */*"); -        if (request.url === url) { -          expect(request.headers.get("authorization")).toBe("Bearer bar"); -          expect(request.headers.get("npm-auth-type")).toBe("legacy"); -          seen_token = true; -        } else { -          expect(request.headers.get("npm-auth-type")).toBe(null); -        } -        expect(await request.text()).toBe(""); -        urls.push(request.url); -        return new Response("Tea?", { status: 418 }); -      } finally { -        server.stop(); -      } -    }, -    port: 54321, -  }); +  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, */*"); +    if (request.url === url) { +      expect(request.headers.get("authorization")).toBe("Bearer bar"); +      expect(request.headers.get("npm-auth-type")).toBe("legacy"); +      seen_token = true; +    } else { +      expect(request.headers.get("npm-auth-type")).toBe(null); +    } +    expect(await request.text()).toBe(""); +    urls.push(request.url); +    return new Response("Feeling lucky?", { status: 555 }); +  };    const { stdout, stderr, exited } = spawn({      cmd: [bunExe(), "install", "@foo/bar", "--config", import.meta.dir + "/basic.toml"], +    cwd: package_dir,      stdout: null,      stdin: "pipe",      stderr: "pipe", @@ -73,12 +95,246 @@ test("bun install @scoped", async () => {        BUN_DEBUG_QUIET_LOGS: "1",      },    }); -  expect(stdout).toBeDefined();    expect(stderr).toBeDefined(); -  expect(await new Response(stdout).text()).toBe("");    var err = await new Response(stderr).text(); -  expect(err.split(/\n/)).toContain(`GET ${url} - 418`); +  expect(err.split(/\r?\n/)).toContain(`GET ${url} - 555`); +  expect(stdout).toBeDefined(); +  expect(await new Response(stdout).text()).toBe("");    expect(urls).toContain(url);    expect(seen_token).toBe(true);    expect(await exited).toBe(1); +  expect(requested).toBe(1); +}); + +it("should handle workspaces", async () => { +  await writeFile(join(package_dir, "package.json"), JSON.stringify({ +    name: "Foo", +    version: "0.0.1", +    workspaces: [ +      "bar", +    ], +  })); +  await mkdir(join(package_dir, "bar")); +  await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({ +    name: "Bar", +    version: "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: { +      ...process.env, +      BUN_DEBUG_QUIET_LOGS: "1", +    }, +  }); +  expect(stderr).toBeDefined(); +  var err = await new Response(stderr).text(); +  expect(err).toContain("Saved lockfile"); +  expect(stdout).toBeDefined(); +  var out = await new Response(stdout).text(); +  expect(out).toContain("+ Bar@workspace://bar"); +  expect(out).toContain("1 packages installed"); +  expect(await exited).toBe(0); +  expect(requested).toBe(0); +  expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar"]); +  expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar")); +}); + +it("should handle inter-dependency between workspaces", async () => { +  await writeFile(join(package_dir, "package.json"), JSON.stringify({ +    name: "Foo", +    version: "0.0.1", +    workspaces: [ +      "bar", +      "packages/baz", +    ], +  })); +  await mkdir(join(package_dir, "bar")); +  await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({ +    name: "Bar", +    version: "0.0.2", +    dependencies: { +      "Baz": "0.0.3", +    }, +  })); +  await mkdir(join(package_dir, "packages", "baz"), { recursive: true }); +  await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({ +    name: "Baz", +    version: "0.0.3", +    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: { +      ...process.env, +      BUN_DEBUG_QUIET_LOGS: "1", +    }, +  }); +  expect(stderr).toBeDefined(); +  var err = await new Response(stderr).text(); +  expect(err).toContain("Saved lockfile"); +  expect(stdout).toBeDefined(); +  var out = await new Response(stdout).text(); +  expect(out).toContain("+ Bar@workspace://bar"); +  expect(out).toContain("+ Baz@workspace://packages/baz"); +  expect(out).toContain("2 packages installed"); +  expect(await exited).toBe(0); +  expect(requested).toBe(0); +  expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar", "Baz"]); +  expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar")); +  expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz")); +}); + +it("should handle inter-dependency between workspaces (devDependencies)", async () => { +  await writeFile(join(package_dir, "package.json"), JSON.stringify({ +    name: "Foo", +    version: "0.0.1", +    workspaces: [ +      "bar", +      "packages/baz", +    ], +  })); +  await mkdir(join(package_dir, "bar")); +  await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({ +    name: "Bar", +    version: "0.0.2", +    devDependencies: { +      "Baz": "0.0.3", +    }, +  })); +  await mkdir(join(package_dir, "packages", "baz"), { recursive: true }); +  await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({ +    name: "Baz", +    version: "0.0.3", +    devDependencies: { +      "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: { +      ...process.env, +      BUN_DEBUG_QUIET_LOGS: "1", +    }, +  }); +  expect(stderr).toBeDefined(); +  var err = await new Response(stderr).text(); +  expect(err).toContain("Saved lockfile"); +  expect(stdout).toBeDefined(); +  var out = await new Response(stdout).text(); +  expect(out).toContain("+ Bar@workspace://bar"); +  expect(out).toContain("+ Baz@workspace://packages/baz"); +  expect(out).toContain("2 packages installed"); +  expect(await exited).toBe(0); +  expect(requested).toBe(0); +  expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar", "Baz"]); +  expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar")); +  expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz")); +}); + +it("should handle inter-dependency between workspaces (optionalDependencies)", async () => { +  await writeFile(join(package_dir, "package.json"), JSON.stringify({ +    name: "Foo", +    version: "0.0.1", +    workspaces: [ +      "bar", +      "packages/baz", +    ], +  })); +  await mkdir(join(package_dir, "bar")); +  await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({ +    name: "Bar", +    version: "0.0.2", +    optionalDependencies: { +      "Baz": "0.0.3", +    }, +  })); +  await mkdir(join(package_dir, "packages", "baz"), { recursive: true }); +  await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({ +    name: "Baz", +    version: "0.0.3", +    optionalDependencies: { +      "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: { +      ...process.env, +      BUN_DEBUG_QUIET_LOGS: "1", +    }, +  }); +  expect(stderr).toBeDefined(); +  var err = await new Response(stderr).text(); +  expect(err).toContain("Saved lockfile"); +  expect(stdout).toBeDefined(); +  var out = await new Response(stdout).text(); +  expect(out).toContain("+ Bar@workspace://bar"); +  expect(out).toContain("+ Baz@workspace://packages/baz"); +  expect(out).toContain("2 packages installed"); +  expect(await exited).toBe(0); +  expect(requested).toBe(0); +  expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar", "Baz"]); +  expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar")); +  expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz")); +}); + +it("should ignore peerDependencies within workspaces", async () => { +  await writeFile(join(package_dir, "package.json"), JSON.stringify({ +    name: "Foo", +    version: "0.0.1", +    workspaces: [ +      "packages/baz", +    ], +    peerDependencies: { +      "Bar": ">=0.0.2", +    }, +  })); +  await mkdir(join(package_dir, "packages", "baz"), { recursive: true }); +  await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({ +    name: "Baz", +    version: "0.0.3", +    peerDependencies: { +      "Moo": ">=0.0.4", +    }, +  })); +  const { stdout, stderr, exited } = spawn({ +    cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"], +    cwd: package_dir, +    stdout: null, +    stdin: "pipe", +    stderr: "pipe", +    env: { +      ...process.env, +      BUN_DEBUG_QUIET_LOGS: "1", +    }, +  }); +  expect(stderr).toBeDefined(); +  var err = await new Response(stderr).text(); +  expect(err).toContain("Saved lockfile"); +  expect(stdout).toBeDefined(); +  var out = await new Response(stdout).text(); +  expect(out).toContain("+ Baz@workspace://packages/baz"); +  expect(out).toContain("1 packages installed"); +  expect(await exited).toBe(0); +  expect(requested).toBe(0); +  expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Baz"]); +  expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz"));  }); | 
