Merge branch 'main' into ali/piscina

This commit is contained in:
Alistair Smith
2025-05-28 00:19:36 -07:00
committed by GitHub
21 changed files with 412 additions and 71 deletions

View File

@@ -320,4 +320,46 @@ describe("bundler", () => {
expect(contents).toBe("");
},
});
itBundled("browser/AwaitUsingStatement", {
files: {
"/entry.js": `
async function test() {
await using resource = {
async [Symbol.asyncDispose]() {
console.log("The function was called");
await 42;
console.log("and the await finished");
}
};
console.log("Before!");
}
test();
`,
},
target: "browser",
run: {
stdout: "Before!\nThe function was called\nand the await finished\n",
},
});
itBundled("browser/UsingStatement", {
files: {
"/entry.js": `
function test() {
using resource = {
[Symbol.dispose]() {
console.log("The dispose function was called");
}
};
console.log("Before!");
}
test();
`,
},
target: "browser",
run: {
stdout: "Before!\nThe dispose function was called\n",
},
});
});

View File

@@ -57,9 +57,9 @@ describe("bundler", () => {
"../entry.tsx",
],
mappings: [
["react.development.js:524:'getContextName'", "1:5426:Y1"],
["react.development.js:524:'getContextName'", "1:5436:Y1"],
["react.development.js:2495:'actScopeDepth'", "23:4092:GJ++"],
["react.development.js:696:''Component'", '1:7488:\'Component "%s"'],
["react.development.js:696:''Component'", '1:7498:\'Component "%s"'],
["entry.tsx:6:'\"Content-Type\"'", '100:18849:"Content-Type"'],
["entry.tsx:11:'<html>'", "100:19103:void"],
["entry.tsx:23:'await'", "100:19203:await"],
@@ -67,7 +67,7 @@ describe("bundler", () => {
},
},
expectExactFilesize: {
"out/entry.js": 222164,
"out/entry.js": 222174,
},
run: {
stdout: "<!DOCTYPE html><html><body><h1>Hello World</h1><p>This is an example.</p></body></html>",

View File

@@ -1,6 +1,6 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP
exports[`\`bun pm audit\` should exit code 1 when there are vulnerabilities: bun-audit-expect-vulnerabilities-found 1`] = `
exports[`\`bun audit\` should exit code 1 when there are vulnerabilities: bun-audit-expect-vulnerabilities-found 1`] = `
"minimist <0.2.4
express mkdirp minimist
critical: Prototype Pollution in minimist - https://github.com/advisories/GHSA-xvch-5gv4-984h
@@ -78,9 +78,9 @@ To update all dependencies to the latest versions (including breaking changes):
"
`;
exports[`\`bun pm audit\` should print valid JSON and exit 0 when --json is passed and there are no vulnerabilities: bun-audit-expect-valid-json-stdout-report-no-vulnerabilities 1`] = `{}`;
exports[`\`bun audit\` should print valid JSON and exit 0 when --json is passed and there are no vulnerabilities: bun-audit-expect-valid-json-stdout-report-no-vulnerabilities 1`] = `{}`;
exports[`\`bun pm audit\` should print valid JSON and exit 1 when --json is passed and there are vulnerabilities: bun-audit-expect-valid-json-stdout-report-vulnerabilities 1`] = `
exports[`\`bun audit\` should print valid JSON and exit 1 when --json is passed and there are vulnerabilities: bun-audit-expect-valid-json-stdout-report-vulnerabilities 1`] = `
{
"base64-url": [
{
@@ -410,7 +410,7 @@ exports[`\`bun pm audit\` should print valid JSON and exit 1 when --json is pass
}
`;
exports[`\`bun pm audit\` should exit 1 and behave exactly the same when there are vulnerabilities when only devDependencies are specified: bun-audit-expect-vulnerabilities-found 1`] = `
exports[`\`bun audit\` should exit 1 and behave exactly the same when there are vulnerabilities when only devDependencies are specified: bun-audit-expect-vulnerabilities-found 1`] = `
"ms <2.0.0
(direct dependency)
moderate: Vercel ms Inefficient Regular Expression Complexity vulnerability - https://github.com/advisories/GHSA-w9mr-4mfr-499f
@@ -427,7 +427,7 @@ To update all dependencies to the latest versions (including breaking changes):
"
`;
exports[`\`bun pm audit\` when a project has some safe dependencies and some vulnerable dependencies, we should not print the safe dependencies: bun-audit-expect-vulnerabilities-found 1`] = `
exports[`\`bun audit\` when a project has some safe dependencies and some vulnerable dependencies, we should not print the safe dependencies: bun-audit-expect-vulnerabilities-found 1`] = `
"ms <2.0.0
(direct dependency)
moderate: Vercel ms Inefficient Regular Expression Complexity vulnerability - https://github.com/advisories/GHSA-w9mr-4mfr-499f

View File

@@ -47,9 +47,9 @@ function doAuditTest(
},
) {
test(label, async () => {
const dir = tempDirWithFiles("bun-test-pm-audit-" + label.replace(/[^a-zA-Z0-9]/g, "-"), options.files);
const dir = tempDirWithFiles("bun-test-audit-" + label.replace(/[^a-zA-Z0-9]/g, "-"), options.files);
const cmd = [bunExe(), "pm", "audit", ...(options.args ?? [])];
const cmd = [bunExe(), "audit", ...(options.args ?? [])];
const url = server.url.toString().slice(0, -1);
@@ -87,7 +87,7 @@ function doAuditTest(
});
}
describe("`bun pm audit`", () => {
describe("`bun audit`", () => {
doAuditTest("should fail with no package.json", {
exitCode: 1,
files: {

View File

@@ -0,0 +1,9 @@
import { expect, it } from "bun:test";
import { nsExample1, nsExample2, nsExample3, nsExample4 } from "../../snippets/jsx-attributes.tsx";
it("parses namespaced attributes correctly", () => {
expect(nsExample1.props).toEqual({ "ns:bar": "baz", "tag": true });
expect(nsExample2.props).toEqual({ "ns:bar42": "baz", "tag": false });
expect(nsExample3.props).toEqual({ "ns:bar42bar": "baz" });
expect(nsExample4.props).toEqual({ "ns42:bar": "baz" });
});

View File

@@ -34,7 +34,7 @@ const words: Record<string, { reason: string; limit?: number; regex?: boolean }>
[String.raw`: [a-zA-Z0-9_\.\*\?\[\]\(\)]+ = undefined,`]: { reason: "Do not default a struct field to undefined", limit: 241, regex: true },
"usingnamespace": { reason: "Zig 0.15 will remove `usingnamespace`" },
"catch unreachable": { reason: "For out-of-memory, prefer 'catch bun.outOfMemory()'", limit: 1851 },
"catch unreachable": { reason: "For out-of-memory, prefer 'catch bun.outOfMemory()'", limit: 1852 },
"std.fs.Dir": { reason: "Prefer bun.sys + bun.FD instead of std.fs", limit: 180 },
"std.fs.cwd": { reason: "Prefer bun.FD.cwd()", limit: 103 },

View File

@@ -323,7 +323,7 @@ describe("cookie path option", () => {
"/x/y": {
GET(r) {
r.cookies.set("user", "a", { maxAge: 3600, path: "/" });
const cookie = r.cookies.toSetCookieHeaders().at(0);
const cookie = r.cookies.toSetCookieHeaders().at(0)!;
return new Response("ok", {
headers: { "set-cookie": cookie },
});
@@ -371,3 +371,45 @@ test("delete cookie invalid path option", () => {
`"Invalid cookie name: contains invalid characters"`,
);
});
describe("Bun.CookieMap constructor", () => {
test("throws for invalid array", () => {
expect(() => new Bun.CookieMap([["abc defg =fhaingj809读写汉字学中文"]])).toThrowErrorMatchingInlineSnapshot(
`"Expected arrays of exactly two strings"`,
);
});
test("accepts unicode cookie value in object", () => {
const map = new Bun.CookieMap({
"cookie key": "读写汉字学中文",
});
expect(map.get("cookie key")).toBe("读写汉字学中文");
});
test("accepts unicode cookie value in array", () => {
const map = new Bun.CookieMap([["cookie key", "读写汉字学中文"]]);
expect(map.get("cookie key")).toBe("读写汉字学中文");
});
test("accepts unicode cookie value in string", () => {
const map = new Bun.CookieMap("cookie key=读写汉字学中文");
expect(map.get("cookie key")).toBe("读写汉字学中文");
});
test("serializes unicode cookie value", () => {
const map = new Bun.CookieMap();
map.set("cookiekey", "读写汉字学中文");
expect(map.toSetCookieHeaders()).toMatchInlineSnapshot(`
[
"cookiekey=%E8%AF%BB%E5%86%99%E6%B1%89%E5%AD%97%E5%AD%A6%E4%B8%AD%E6%96%87; Path=/; SameSite=Lax",
]
`);
// re-parse
const reparsed = new Bun.CookieMap(map.toSetCookieHeaders()[0].split(";")[0]!);
expect(reparsed.get("cookiekey")).toBe("读写汉字学中文");
});
test("doesn't parse percent encoded value in object or array", () => {
const map = new Bun.CookieMap({
"cookiekey": "%E8%AF%BB%E5%86%99%E6%B1%89%E5%AD%97%E5%AD%A6%E4%B8%AD%E6%96%87",
});
const map2 = new Bun.CookieMap([["cookiekey", "%E8%AF%BB%E5%86%99%E6%B1%89%E5%AD%97%E5%AD%A6%E4%B8%AD%E6%96%87"]]);
expect(map.get("cookiekey")).toBe("%E8%AF%BB%E5%86%99%E6%B1%89%E5%AD%97%E5%AD%A6%E4%B8%AD%E6%96%87");
expect(map2.get("cookiekey")).toBe("%E8%AF%BB%E5%86%99%E6%B1%89%E5%AD%97%E5%AD%A6%E4%B8%AD%E6%96%87");
});
});

View File

@@ -0,0 +1,47 @@
// @ts-nocheck
// Declare a minimally reproducible JSX namespace for testing;
// ensures that no dependencies are required for this test.
export interface JSXIntrinsicElements {
"ns:foo": {
"tag"?: boolean;
"ns:bar"?: string;
"ns:bar42"?: string;
"ns:bar42bar"?: string;
"ns42:bar"?: string;
};
}
// Minimal JSX element implementation.
export class Element<T, P, C> {
constructor(
public readonly tag: T,
public readonly props: P,
public readonly children: C,
) { }
}
export interface JsxElement extends Element<unknown, unknown, unknown> { }
// JSX factory function used when compiling JSX with `jsx` pragma.
// This is what the JSX transpiles to.
export function jsx<T, P, C extends unknown[]>(
tag: T,
props: P,
...children: C
) {
return new Element(tag, props, children);
}
// Define the JSX namespace itself so TypeScript can resolve JSX
// types correctly.
export namespace jsx.JSX {
export interface Element extends JsxElement { }
export type IntrinsicElements = JSXIntrinsicElements;
}
// Examples of namespaced JSX attributes
export const nsExample1 = <ns:foo tag ns:bar="baz" />;
export const nsExample2 = <ns:foo tag={false} ns:bar42="baz" />;
export const nsExample3 = <ns:foo ns:bar42bar="baz" />;
export const nsExample4 = <ns:foo ns42:bar="baz" />;