node:http: allow setting response.statusCode and statusMessage [v2] (#11082)

This commit is contained in:
Meghan Denny
2024-05-15 00:27:55 -07:00
committed by GitHub
parent 5c8c112c4e
commit 86bcc49bef
14 changed files with 124 additions and 156 deletions

View File

@@ -818,12 +818,19 @@ Object.defineProperty(IncomingMessage.prototype, "statusCode", {
get() {
return this[reqSymbol].status;
},
set(v) {
if (!(v in STATUS_CODES)) return;
this[reqSymbol].status = v;
},
});
Object.defineProperty(IncomingMessage.prototype, "statusMessage", {
get() {
return STATUS_CODES[this[reqSymbol].status];
},
set(v) {
//noop
},
});
Object.defineProperty(IncomingMessage.prototype, "httpVersion", {

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,6 +1,6 @@
import { spawn, file } from "bun";
import { afterAll, afterEach, beforeAll, beforeEach, expect, it } from "bun:test";
import { bunExe, bunEnv as env, tmpdirSync, toBeValidBin, toHaveBins } from "harness";
import { bunExe, bunEnv as env, runBunInstall, toBeValidBin, toHaveBins, tmpdirSync } from "harness";
import { access, writeFile, mkdir } from "fs/promises";
import { basename, join } from "path";
import {
@@ -55,19 +55,8 @@ it("should link and unlink workspace package", async () => {
version: "0.0.1",
}),
);
var { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install"],
cwd: link_dir,
stdout: "pipe",
stdin: "pipe",
stderr: "pipe",
env,
});
expect(stderr).toBeDefined();
var err = await new Response(stderr).text();
let { out, err } = await runBunInstall(env, link_dir);
expect(err.replace(/^(.*?) v[^\n]+/, "$1").split(/\r?\n/)).toEqual(["bun install", " Saved lockfile", ""]);
expect(stdout).toBeDefined();
var out = await new Response(stdout).text();
expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
` + boba@workspace:packages/boba`,
@@ -75,16 +64,15 @@ it("should link and unlink workspace package", async () => {
"",
" 2 packages installed",
]);
expect(await exited).toBe(0);
({ stdout, stderr, exited } = spawn({
let { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "link"],
cwd: join(link_dir, "packages", "moo"),
stdout: "pipe",
stdin: "pipe",
stderr: "pipe",
env,
}));
});
expect(stderr).toBeDefined();
err = await new Response(stderr).text();

View File

@@ -1,5 +1,5 @@
import { spawnSync } from "bun";
import { bunExe, bunEnv as env, tmpdirSync, toMatchNodeModulesAt } from "harness";
import { bunExe, bunEnv as env, runBunInstall, tmpdirSync, toMatchNodeModulesAt } from "harness";
import { join } from "path";
import { writeFileSync, mkdirSync, rmSync } from "fs";
import { beforeEach, test, expect } from "bun:test";
@@ -27,7 +27,7 @@ cache = false
);
});
test("dependency on workspace without version in package.json", () => {
test("dependency on workspace without version in package.json", async () => {
writeFileSync(
join(packageDir, "package.json"),
JSON.stringify({
@@ -77,19 +77,10 @@ test("dependency on workspace without version in package.json", () => {
}),
);
const { stdout, exitCode } = spawnSync({
cmd: [bunExe(), "install"],
cwd: packageDir,
stderr: "inherit",
stdout: "pipe",
env,
});
const { out } = await runBunInstall(env, packageDir);
const lockfile = parseLockfile(packageDir);
expect(lockfile).toMatchNodeModulesAt(packageDir);
expect(lockfile).toMatchSnapshot(`version: ${version}`);
const out = stdout.toString();
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
" + bar@workspace:packages/bar",
@@ -97,9 +88,6 @@ test("dependency on workspace without version in package.json", () => {
"",
" 2 packages installed",
]);
expect(exitCode).toBe(0);
rmSync(join(packageDir, "node_modules"), { recursive: true, force: true });
rmSync(join(packageDir, "bun.lockb"), { recursive: true, force: true });
}
@@ -118,19 +106,10 @@ test("dependency on workspace without version in package.json", () => {
}),
);
const { exitCode, stdout } = spawnSync({
cmd: [bunExe(), "install"],
cwd: packageDir,
stderr: "inherit",
stdout: "pipe",
env,
});
const { out } = await runBunInstall(env, packageDir);
const lockfile = parseLockfile(packageDir);
expect(lockfile).toMatchNodeModulesAt(packageDir);
expect(lockfile).toMatchSnapshot(`version: ${version}`);
const out = stdout.toString();
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
" + bar@workspace:packages/bar",
@@ -138,16 +117,13 @@ test("dependency on workspace without version in package.json", () => {
"",
" 3 packages installed",
]);
expect(exitCode).toBe(0);
rmSync(join(packageDir, "node_modules"), { recursive: true, force: true });
rmSync(join(packageDir, "packages", "bar", "node_modules"), { recursive: true, force: true });
rmSync(join(packageDir, "bun.lockb"), { recursive: true, force: true });
}
}, 20_000);
test("dependency on same name as workspace and dist-tag", () => {
test("dependency on same name as workspace and dist-tag", async () => {
writeFileSync(
join(packageDir, "package.json"),
JSON.stringify({
@@ -177,19 +153,10 @@ test("dependency on same name as workspace and dist-tag", () => {
}),
);
const { stdout, exitCode } = spawnSync({
cmd: [bunExe(), "install"],
cwd: packageDir,
stderr: "inherit",
stdout: "pipe",
env,
});
const { out } = await runBunInstall(env, packageDir);
const lockfile = parseLockfile(packageDir);
expect(lockfile).toMatchSnapshot("with version");
expect(lockfile).toMatchNodeModulesAt(packageDir);
const out = stdout.toString();
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
" + bar@workspace:packages/bar",
@@ -197,6 +164,4 @@ test("dependency on same name as workspace and dist-tag", () => {
"",
" 3 packages installed",
]);
expect(exitCode).toBe(0);
});

View File

@@ -763,3 +763,24 @@ export function mergeWindowEnvs(envs: Record<string, string | undefined>[]) {
export function tmpdirSync(pattern: string = "bun.test.") {
return fs.mkdtempSync(join(fs.realpathSync(os.tmpdir()), pattern));
}
export async function runBunInstall(env: NodeJS.ProcessEnv, cwd: string) {
const { stdout, stderr, exited } = Bun.spawn({
cmd: [bunExe(), "install"],
cwd,
stdout: "pipe",
stdin: "ignore",
stderr: "pipe",
env,
});
expect(stdout).toBeDefined();
expect(stderr).toBeDefined();
let err = await new Response(stderr).text();
expect(err).not.toContain("panic:");
expect(err).not.toContain("error:");
expect(err).not.toContain("warn:");
expect(err).toContain("Saved lockfile");
let out = await new Response(stdout).text();
expect(await exited).toBe(0);
return { out, err, exited };
}

View File

@@ -16,7 +16,7 @@ function createTree(basedir: string, paths: string[]) {
}
var count = 0;
function make(files: string[]) {
const dir = tmpdirSync();
const dir = tmpdirSync().replaceAll("\\", "/");
rmSync(dir, {
recursive: true,
force: true,

26
test/js/third_party/_fixtures/msw.ts vendored Normal file
View File

@@ -0,0 +1,26 @@
import axios from "axios";
import { http, passthrough, HttpResponse } from "msw";
import { setupServer } from "msw/node";
const server = setupServer(
...[
http.get("http://localhost/", () => {
// return passthrough()
return HttpResponse.json({ results: [{}, {}] });
}),
],
);
server.listen({
onUnhandledRequest: "warn",
});
axios
.get("http://localhost/?page=2")
.then(function (response) {
// handle success
console.log(response.data.results.length);
})
.catch(function (error) {
// handle error
console.log(error?.message);
});

18
test/js/third_party/_fixtures/st.ts vendored Normal file
View File

@@ -0,0 +1,18 @@
import { createServer } from "node:http";
import st from "st";
function listen(server): Promise<URL> {
return new Promise((resolve, reject) => {
server.listen({ port: 0 }, (err, hostname, port) => {
if (err) {
reject(err);
} else {
resolve(new URL("http://" + hostname + ":" + port));
}
});
});
}
await using server = createServer(st(process.cwd()));
const url = await listen(server);
const res = await fetch(new URL("/st.ts", url));
console.log(await res.text());

View File

@@ -0,0 +1,8 @@
const Stripe = require("stripe");
const stripe = Stripe(process.env.STRIPE_ACCESS_TOKEN);
await stripe.charges
.retrieve(process.env.STRIPE_CHARGE_ID, { stripeAccount: process.env.STRIPE_ACCOUNT_ID })
.then(x => {
console.log(x);
});

7
test/js/third_party/msw.test.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
import "harness";
import { expect, it } from "bun:test";
import * as path from "node:path";
it("works", async () => {
expect([path.join(import.meta.dirname, "_fixtures", "msw.ts")]).toRun("2\n");
});

View File

@@ -1,60 +1,22 @@
import { bunExe } from "bun:harness";
import { bunEnv, tmpdirSync } from "harness";
import { bunEnv } from "harness";
import { expect, it } from "bun:test";
import * as path from "node:path";
it("works", async () => {
const package_dir = tmpdirSync();
const fixture_path = path.join(import.meta.dirname, "_fixtures", "st.ts");
const fixture_data = await Bun.file(fixture_path).text();
let { stdout, stderr, exited } = Bun.spawn({
cmd: [bunExe(), "add", "st@3.0.0"],
cwd: package_dir,
cmd: [bunExe(), "run", fixture_path],
cwd: path.dirname(fixture_path),
stdout: "pipe",
stdin: "ignore",
stderr: "pipe",
env: bunEnv,
});
let err = await new Response(stderr).text();
expect(err).not.toContain("panic:");
expect(err).not.toContain("error:");
expect(err).not.toContain("warn:");
let out = await new Response(stdout).text();
expect(await exited).toBe(0);
const fixture_path = path.join(package_dir, "index.ts");
const fixture_data = `
import { createServer } from "node:http";
import st from "st";
function listen(server): Promise<URL> {
return new Promise((resolve, reject) => {
server.listen({ port: 0 }, (err, hostname, port) => {
if (err) {
reject(err);
} else {
resolve(new URL("http://"+hostname+":"+port));
}
});
});
}
await using server = createServer(st(process.cwd()));
const url = await listen(server);
const res = await fetch(new URL("/index.ts", url));
console.log(await res.text());
`;
await Bun.write(fixture_path, fixture_data);
({ stdout, stderr, exited } = Bun.spawn({
cmd: [bunExe(), "run", fixture_path],
cwd: package_dir,
stdout: "pipe",
stdin: "ignore",
stderr: "pipe",
env: bunEnv,
}));
// err = await new Response(stderr).text();
// expect(err).toBeEmpty();
out = await new Response(stdout).text();
let out = await new Response(stdout).text();
expect(out).toEqual(fixture_data + "\n");
expect(await exited).toBe(0);
});

View File

@@ -1,64 +1,26 @@
import { bunExe } from "bun:harness";
import { bunEnv, tmpdirSync } from "harness";
import { bunEnv, runBunInstall, tmpdirSync } from "harness";
import * as path from "node:path";
import { expect, it } from "bun:test";
it.skipIf(!process.env.TEST_INFO_STRIPE)("should be able to query a charge", async () => {
const package_dir = tmpdirSync();
await Bun.write(
path.join(package_dir, "package.json"),
JSON.stringify({
"dependencies": {
"stripe": "^15.4.0",
},
}),
);
let { stdout, stderr } = Bun.spawn({
cmd: [bunExe(), "install"],
cwd: package_dir,
stdout: "pipe",
stdin: "ignore",
stderr: "pipe",
env: bunEnv,
});
let err = await new Response(stderr).text();
expect(err).not.toContain("panic:");
expect(err).not.toContain("error:");
expect(err).not.toContain("warn:");
let out = await new Response(stdout).text();
// prettier-ignore
const [access_token, charge_id, account_id] = process.env.TEST_INFO_STRIPE?.split(",");
const fixture_path = path.join(package_dir, "index.js");
await Bun.write(
fixture_path,
String.raw`
const Stripe = require("stripe");
const stripe = Stripe("${access_token}");
await stripe.charges
.retrieve("${charge_id}", {
stripeAccount: "${account_id}",
})
.then((x) => {
console.log(x);
});
`,
);
({ stdout, stderr } = Bun.spawn({
cmd: [bunExe(), "run", fixture_path],
cwd: package_dir,
let { stdout, stderr } = Bun.spawn({
cmd: [bunExe(), "run", path.join(import.meta.dirname, "_fixtures", "stripe.ts")],
cwd: import.meta.dirname,
stdout: "pipe",
stdin: "ignore",
stderr: "pipe",
env: bunEnv,
}));
out = await new Response(stdout).text();
env: {
...bunEnv,
STRIPE_ACCESS_TOKEN: access_token,
STRIPE_CHARGE_ID: charge_id,
STRIPE_ACCOUNT_ID: account_id,
},
});
let out = await new Response(stdout).text();
expect(out).toBeEmpty();
err = await new Response(stderr).text();
let err = await new Response(stderr).text();
expect(err).toContain(`error: No such charge: '${charge_id}'\n`);
});

View File

@@ -15,6 +15,7 @@
"@resvg/resvg-js": "2.4.1",
"@swc/core": "1.3.38",
"@types/ws": "8.5.10",
"axios": "1.6.8",
"body-parser": "1.20.2",
"comlink": "4.4.1",
"dedent": "0.7.0",
@@ -29,11 +30,12 @@
"lodash": "4.17.21",
"mongodb": "6.0.0",
"msgpackr-extract": "3.0.2",
"msw": "2.3.0",
"mysql2": "3.7.0",
"node-gyp": "10.0.1",
"nodemailer": "6.9.3",
"pg-connection-string": "2.6.1",
"pg": "8.11.1",
"pg-connection-string": "2.6.1",
"postgres": "3.3.5",
"prisma": "5.1.1",
"prompts": "2.4.2",
@@ -41,17 +43,19 @@
"rollup": "4.4.1",
"sharp": "0.33.0",
"sinon": "6.0.0",
"socket.io-client": "4.7.1",
"socket.io": "4.7.1",
"socket.io-client": "4.7.1",
"st": "3.0.0",
"string-width": "7.0.0",
"stripe": "15.4.0",
"supertest": "6.3.3",
"svelte": "3.55.1",
"typescript": "5.0.2",
"undici": "5.20.0",
"verdaccio": "5.27.0",
"vitest": "0.32.2",
"webpack-cli": "4.7.2",
"webpack": "5.88.0",
"webpack-cli": "4.7.2",
"yargs": "17.7.2"
},
"private": true,