Files
bun.sh/test/cli/install/bun-upgrade.test.ts
Jarred Sumner 2e02d9de28 Use ReadableStream.prototype.* in tests instead of new Response(...).* (#20937)
Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Alistair Smith <hi@alistair.sh>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-14 00:47:53 -07:00

179 lines
6.0 KiB
TypeScript

import { spawn, spawnSync } from "bun";
import { upgrade_test_helpers } from "bun:internal-for-testing";
import { beforeAll, beforeEach, expect, it, setDefaultTimeout } from "bun:test";
import { bunExe, bunEnv as env, tls, tmpdirSync } from "harness";
import { copyFileSync } from "node:fs";
import { basename, join } from "path";
const { openTempDirWithoutSharingDelete, closeTempDirHandle } = upgrade_test_helpers;
let cwd: string;
let execPath: string;
beforeAll(() => {
setDefaultTimeout(1000 * 60 * 5);
});
beforeEach(async () => {
cwd = tmpdirSync();
execPath = join(cwd, basename(bunExe()));
copyFileSync(bunExe(), execPath);
});
it("two invalid arguments, should display error message and suggest command", async () => {
const { stderr } = spawn({
cmd: [execPath, "upgrade", "bun-types", "--dev"],
cwd,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
const err = await stderr.text();
expect(err.split(/\r?\n/)).toContain("error: This command updates Bun itself, and does not take package names.");
expect(err.split(/\r?\n/)).toContain("note: Use `bun update bun-types --dev` instead.");
});
it("two invalid arguments flipped, should display error message and suggest command", async () => {
const { stderr } = spawn({
cmd: [execPath, "upgrade", "--dev", "bun-types"],
cwd,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
const err = await stderr.text();
expect(err.split(/\r?\n/)).toContain("error: This command updates Bun itself, and does not take package names.");
expect(err.split(/\r?\n/)).toContain("note: Use `bun update --dev bun-types` instead.");
});
it("one invalid argument, should display error message and suggest command", async () => {
const { stderr } = spawn({
cmd: [execPath, "upgrade", "bun-types"],
cwd,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
const err = await stderr.text();
expect(err.split(/\r?\n/)).toContain("error: This command updates Bun itself, and does not take package names.");
expect(err.split(/\r?\n/)).toContain("note: Use `bun update bun-types` instead.");
});
it("one valid argument, should succeed", async () => {
const { stderr } = spawn({
cmd: [execPath, "upgrade", "--help"],
cwd,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
const err = await stderr.text();
// Should not contain error message
expect(err.split(/\r?\n/)).not.toContain("error: This command updates bun itself, and does not take package names.");
expect(err.split(/\r?\n/)).not.toContain("note: Use `bun update --help` instead.");
});
it("two valid argument, should succeed", async () => {
const { stderr } = spawn({
cmd: [execPath, "upgrade", "--stable", "--profile"],
cwd,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
const err = await stderr.text();
// Should not contain error message
expect(err.split(/\r?\n/)).not.toContain("error: This command updates Bun itself, and does not take package names.");
expect(err.split(/\r?\n/)).not.toContain("note: Use `bun update --stable --profile` instead.");
});
it("zero arguments, should succeed", async () => {
const tagName = bunExe().includes("-debug") ? "canary" : `bun-v${Bun.version}`;
using server = Bun.serve({
tls: tls,
port: 0,
async fetch() {
return new Response(
JSON.stringify({
"tag_name": tagName,
"assets": [
{
"url": "foo",
"content_type": "application/zip",
"name": "bun-windows-x64.zip",
"browser_download_url": `https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/${tagName}/bun-windows-x64.zip`,
},
{
"url": "foo",
"content_type": "application/zip",
"name": "bun-windows-x64-baseline.zip",
"browser_download_url": `https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/${tagName}/bun-windows-x64-baseline.zip`,
},
{
"url": "foo",
"content_type": "application/zip",
"name": "bun-linux-x64.zip",
"browser_download_url": `https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/${tagName}/bun-linux-x64.zip`,
},
{
"url": "foo",
"content_type": "application/zip",
"name": "bun-linux-x64-baseline.zip",
"browser_download_url": `https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/${tagName}/bun-linux-x64-baseline.zip`,
},
{
"url": "foo",
"content_type": "application/zip",
"name": "bun-darwin-x64.zip",
"browser_download_url": `https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/${tagName}/bun-darwin-x64.zip`,
},
{
"url": "foo",
"content_type": "application/zip",
"name": "bun-darwin-x64-baseline.zip",
"browser_download_url": `https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/${tagName}/bun-darwin-x64-baseline.zip`,
},
{
"url": "foo",
"content_type": "application/zip",
"name": "bun-darwin-aarch64.zip",
"browser_download_url": `https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/${tagName}/bun-darwin-aarch64.zip`,
},
],
}),
);
},
});
// On windows, open the temporary directory without FILE_SHARE_DELETE before spawning
// the upgrade process. This is to test for EBUSY errors
openTempDirWithoutSharingDelete();
const { stderr } = spawnSync({
cmd: [execPath, "upgrade"],
cwd,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env: {
...env,
NODE_TLS_REJECT_UNAUTHORIZED: "0",
GITHUB_API_DOMAIN: `${server.hostname}:${server.port}`,
},
});
closeTempDirHandle();
// Should not contain error message
expect(stderr.toString()).not.toContain("error:");
});