mirror of
https://github.com/oven-sh/bun
synced 2026-02-18 14:51:52 +00:00
Merge branch 'main' into ali/piscina
This commit is contained in:
@@ -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",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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>",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: {
|
||||
|
||||
9
test/cli/run/jsx-namespaced-attributes.test.ts
Normal file
9
test/cli/run/jsx-namespaced-attributes.test.ts
Normal 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" });
|
||||
});
|
||||
@@ -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 },
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
|
||||
47
test/snippets/jsx-attributes.tsx
Normal file
47
test/snippets/jsx-attributes.tsx
Normal 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" />;
|
||||
Reference in New Issue
Block a user