import { spawnSync, which } from "bun"; import { describe, expect, it } from "bun:test"; import { existsSync, readFileSync } from "fs"; import { bunEnv, bunExe } from "harness"; import { basename, join, resolve } from "path"; it("process", () => { // this property isn't implemented yet but it should at least return a string const isNode = !process.isBun; if (!isNode && process.title !== "bun") throw new Error("process.title is not 'bun'"); if (typeof process.env.USER !== "string") throw new Error("process.env is not an object"); if (process.env.USER.length === 0) throw new Error("process.env is missing a USER property"); if (process.platform !== "darwin" && process.platform !== "linux") throw new Error("process.platform is invalid"); if (isNode) throw new Error("process.isBun is invalid"); // partially to test it doesn't crash due to various strange types process.env.BACON = "yummy"; if (process.env.BACON !== "yummy") { throw new Error("process.env is not writable"); } delete process.env.BACON; if (typeof process.env.BACON !== "undefined") { throw new Error("process.env is not deletable"); } process.env.BACON = "yummy"; if (process.env.BACON !== "yummy") { throw new Error("process.env is not re-writable"); } if (!JSON.stringify(process.env)) { throw new Error("process.env is not serializable"); } if (typeof JSON.parse(JSON.stringify(process.env)).toJSON !== "undefined") { throw new Error("process.env should call toJSON to hide its internal state"); } // Make sure it doesn't crash expect(Bun.inspect(process).length > 0).toBe(true); let cwd = process.cwd(); process.chdir("../"); expect(process.cwd()).toEqual(resolve(cwd, "../")); process.chdir(cwd); expect(cwd).toEqual(process.cwd()); }); it("process.hrtime()", () => { const start = process.hrtime(); const end = process.hrtime(start); const end2 = process.hrtime(); expect(end[0]).toBe(0); expect(end2[1] > start[1]).toBe(true); }); it("process.hrtime.bigint()", () => { const start = process.hrtime.bigint(); const end = process.hrtime.bigint(); expect(end > start).toBe(true); }); it("process.release", () => { expect(process.release.name).toBe("bun"); expect(process.release.sourceUrl).toContain( `https://github.com/oven-sh/bun/release/bun-v${process.versions.bun}/bun-${process.platform}-${ { arm64: "aarch64", x64: "x64" }[process.arch] || process.arch }`, ); }); it("process.env", () => { process.env["LOL SMILE UTF16 😂"] = "😂"; expect(process.env["LOL SMILE UTF16 😂"]).toBe("😂"); delete process.env["LOL SMILE UTF16 😂"]; expect(process.env["LOL SMILE UTF16 😂"]).toBe(undefined); process.env["LOL SMILE latin1 "] = ""; expect(process.env["LOL SMILE latin1 "]).toBe(""); delete process.env["LOL SMILE latin1 "]; expect(process.env["LOL SMILE latin1 "]).toBe(undefined); }); it("process.env is spreadable and editable", () => { process.env["LOL SMILE UTF16 😂"] = "😂"; const { "LOL SMILE UTF16 😂": lol, ...rest } = process.env; expect(lol).toBe("😂"); delete process.env["LOL SMILE UTF16 😂"]; expect(rest).toEqual(process.env); const orig = (getter => process.env[getter])("USER"); expect(process.env).toEqual(process.env); eval(`globalThis.process.env.USER = 'bun';`); expect(eval(`globalThis.process.env.USER`)).toBe("bun"); expect(eval(`globalThis.process.env.USER = "${orig}"`)).toBe(orig); }); it("process.env.TZ", () => { var origTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; // the default timezone is Etc/UTC if (!"TZ" in process.env) { expect(origTimezone).toBe("Etc/UTC"); } const realOrigTimezone = origTimezone; if (origTimezone === "America/Anchorage") { origTimezone = "America/New_York"; } const target = "America/Anchorage"; const tzKey = String("TZ" + " ").substring(0, 2); process.env[tzKey] = target; expect(process.env[tzKey]).toBe(target); expect(Intl.DateTimeFormat().resolvedOptions().timeZone).toBe(target); process.env[tzKey] = origTimezone; expect(Intl.DateTimeFormat().resolvedOptions().timeZone).toBe(realOrigTimezone); }); it("process.version starts with v", () => { expect(process.version.startsWith("v")).toBeTruthy(); }); it.todo("process.argv0", () => { expect(basename(process.argv0)).toBe(basename(process.argv[0])); }); it("process.execPath", () => { expect(process.execPath).not.toBe(basename(process.argv0)); expect(which(process.execPath)).not.toBeNull(); }); it("process.uptime()", () => { expect(process.uptime()).toBeGreaterThan(0); expect(Math.floor(process.uptime())).toBe(Math.floor(performance.now() / 1000)); }); it("process.umask()", () => { let notNumbers = [265n, "string", true, false, null, {}, [], () => {}, Symbol("symbol"), BigInt(1)]; for (let notNumber of notNumbers) { expect(() => { process.umask(notNumber); }).toThrow('The "mask" argument must be a number'); } let rangeErrors = [NaN, -1.4, Infinity, -Infinity, -1, 1.3, 4294967296]; for (let rangeError of rangeErrors) { expect(() => { process.umask(rangeError); }).toThrow(RangeError); } const orig = process.umask(0o777); expect(orig).toBeGreaterThan(0); expect(process.umask()).toBe(0o777); expect(process.umask(undefined)).toBe(0o777); expect(process.umask(Number(orig))).toBe(0o777); expect(process.umask()).toBe(orig); }); const generated_versions_list = join(import.meta.dir, "../../../../src/generated_versions_list.zig"); const versions = existsSync(generated_versions_list); (versions ? it : it.skip)("process.versions", () => { // Generate a list of all the versions in the versions object // example: // pub const boringssl = "b275c5ce1c88bc06f5a967026d3c0ce1df2be815"; // pub const libarchive = "dc321febde83dd0f31158e1be61a7aedda65e7a2"; // pub const mimalloc = "3c7079967a269027e438a2aac83197076d9fe09d"; // pub const picohttpparser = "066d2b1e9ab820703db0837a7255d92d30f0c9f5"; // pub const uws = "70b1b9fc1341e8b791b42c5447f90505c2abe156"; // pub const webkit = "60d11703a533fd694cd1d6ddda04813eecb5d69f"; // pub const zlib = "885674026394870b7e7a05b7bf1ec5eb7bd8a9c0"; // pub const tinycc = "2d3ad9e0d32194ad7fd867b66ebe218dcc8cb5cd"; // pub const lolhtml = "2eed349dcdfa4ff5c19fe7c6e501cfd687601033"; // pub const c_ares = "0e7a5dee0fbb04080750cf6eabbe89d8bae87faa"; // pub const usockets = "fafc241e8664243fc0c51d69684d5d02b9805134"; const versions = Object.fromEntries( readFileSync(generated_versions_list, "utf8") .split("\n") .filter(line => line.startsWith("pub const") && !line.includes("zig") && line.includes(' = "')) .map(line => line.split(" = ")) .map(([name, hash]) => [name.slice(9).trim(), hash.slice(1, -2)]), ); versions.uwebsockets = versions.uws; delete versions.uws; versions["ares"] = versions.c_ares; delete versions.c_ares; for (const name in versions) { expect(process.versions).toHaveProperty(name); expect(process.versions[name]).toBe(versions[name]); } }); it("process.config", () => { expect(process.config).toEqual({ variables: { v8_enable_i8n_support: 1, }, target_defaults: {}, }); }); it("process.emitWarning", () => { process.emitWarning("-- Testing process.emitWarning --"); var called = 0; process.on("warning", err => { called++; expect(err.message).toBe("-- Testing process.on('warning') --"); }); process.emitWarning("-- Testing process.on('warning') --"); expect(called).toBe(1); expect(process.off("warning")).toBe(process); process.emitWarning("-- Testing process.on('warning') --"); expect(called).toBe(1); }); it("process.execArgv", () => { expect(process.execArgv instanceof Array).toBe(true); }); it("process.binding", () => { expect(() => process.binding("buffer")).toThrow(); }); it("process.argv in testing", () => { expect(process.argv).toBeInstanceOf(Array); expect(process.argv[0]).toBe(bunExe()); // assert we aren't creating a new process.argv each call expect(process.argv).toBe(process.argv); }); describe("process.exitCode", () => { it("validates int", () => { expect(() => (process.exitCode = "potato")).toThrow("exitCode must be a number"); expect(() => (process.exitCode = 1.2)).toThrow('The "code" argument must be an integer'); expect(() => (process.exitCode = NaN)).toThrow('The "code" argument must be an integer'); expect(() => (process.exitCode = Infinity)).toThrow('The "code" argument must be an integer'); expect(() => (process.exitCode = -Infinity)).toThrow('The "code" argument must be an integer'); expect(() => (process.exitCode = -1)).toThrow("exitCode must be between 0 and 127"); }); it("works with implicit process.exit", () => { const { exitCode, stdout } = spawnSync({ cmd: [bunExe(), join(import.meta.dir, "process-exitCode-with-exit.js"), "42"], env: bunEnv, }); expect(exitCode).toBe(42); expect(stdout.toString().trim()).toBe("PASS"); }); it("works with explicit process.exit", () => { const { exitCode, stdout } = spawnSync({ cmd: [bunExe(), join(import.meta.dir, "process-exitCode-fixture.js"), "42"], env: bunEnv, }); expect(exitCode).toBe(42); expect(stdout.toString().trim()).toBe("PASS"); }); }); it("process.exit", () => { const { exitCode, stdout } = spawnSync({ cmd: [bunExe(), join(import.meta.dir, "process-exit-fixture.js")], env: bunEnv, }); expect(exitCode).toBe(0); expect(stdout.toString().trim()).toBe("PASS"); }); describe("process.onBeforeExit", () => { it("emitted", () => { const { exitCode, stdout } = spawnSync({ cmd: [bunExe(), join(import.meta.dir, "process-onBeforeExit-fixture.js")], env: bunEnv, }); expect(exitCode).toBe(0); expect(stdout.toString().trim()).toBe("beforeExit\nexit"); }); it("works with explicit process.exit", () => { const { exitCode, stdout } = spawnSync({ cmd: [bunExe(), join(import.meta.dir, "process-onBeforeExit-keepAlive.js")], env: bunEnv, }); expect(exitCode).toBe(0); expect(stdout.toString().trim()).toBe("beforeExit: 0\nbeforeExit: 1\nexit: 2"); }); }); it("process.memoryUsage", () => { expect(process.memoryUsage()).toEqual({ rss: expect.any(Number), heapTotal: expect.any(Number), heapUsed: expect.any(Number), external: expect.any(Number), arrayBuffers: expect.any(Number), }); }); it("process.memoryUsage.rss", () => { expect(process.memoryUsage.rss()).toEqual(expect.any(Number)); }); describe("process.cpuUsage", () => { it("works", () => { expect(process.cpuUsage()).toEqual({ user: expect.any(Number), system: expect.any(Number), }); }); it("works with diff", () => { const init = process.cpuUsage(); for (let i = 0; i < 1000; i++) {} const delta = process.cpuUsage(init); expect(delta.user).toBeGreaterThan(0); expect(delta.system).toBeGreaterThan(0); }); it("works with diff of different structure", () => { const init = { user: 0, system: 0, }; for (let i = 0; i < 1000; i++) {} const delta = process.cpuUsage(init); expect(delta.user).toBeGreaterThan(0); expect(delta.system).toBeGreaterThan(0); }); it("throws on invalid property", () => { const fixtures = [ {}, { user: null }, { user: {} }, { user: "potato" }, { user: 123 }, { user: 123, system: null }, { user: 123, system: "potato" }, ]; for (const fixture of fixtures) { expect(() => process.cpuUsage(fixture)).toThrow(); } }); // Skipped on Linux because it seems to not change as often as on macOS it.skipIf(process.platform === "linux")("increases monotonically", () => { const init = process.cpuUsage(); for (let i = 0; i < 10000; i++) {} const another = process.cpuUsage(); expect(another.user).toBeGreaterThan(init.user); expect(another.system).toBeGreaterThan(init.system); }); }); it("process.getegid", () => { expect(typeof process.getegid()).toBe("number"); }); it("process.geteuid", () => { expect(typeof process.geteuid()).toBe("number"); }); it("process.getgid", () => { expect(typeof process.getgid()).toBe("number"); }); it("process.getgroups", () => { expect(process.getgroups()).toBeInstanceOf(Array); expect(process.getgroups().length).toBeGreaterThan(0); }); it("process.getuid", () => { expect(typeof process.getuid()).toBe("number"); }); it("process.getuid", () => { expect(typeof process.getuid()).toBe("number"); }); describe("signal", () => { const fixture = join(import.meta.dir, "./process-signal-handler.fixture.js"); it("simple case works", async () => { const child = Bun.spawn({ cmd: [bunExe(), fixture, "SIGUSR1"], env: bunEnv, }); expect(await child.exited).toBe(0); expect(await new Response(child.stdout).text()).toBe("PASS\n"); }); it("process.emit will call signal events", async () => { const child = Bun.spawn({ cmd: [bunExe(), fixture, "SIGUSR2"], env: bunEnv, }); expect(await child.exited).toBe(0); expect(await new Response(child.stdout).text()).toBe("PASS\n"); }); it("process.kill(2) works", async () => { const child = Bun.spawn({ cmd: ["bash", "-c", "sleep 1000000"], stdout: "pipe", }); const prom = child.exited; process.kill(child.pid, "SIGTERM"); await prom; expect(child.signalCode).toBe("SIGTERM"); }); it("process._kill(2) works", async () => { const child = Bun.spawn({ cmd: ["bash", "-c", "sleep 1000000"], stdout: "pipe", }); const prom = child.exited; process.kill(child.pid, 9); await prom; expect(child.signalCode).toBe("SIGKILL"); }); it("process.kill(2) throws on invalid input", async () => { expect(() => process.kill(0, "SIGPOOP")).toThrow(); expect(() => process.kill(0, 456)).toThrow(); }); }); const undefinedStubs = [ "_debugEnd", "_debugProcess", "_fatalException", "_linkedBinding", "_rawDebug", "_startProfilerIdleNotifier", "_stopProfilerIdleNotifier", "_tickCallback", ]; for (const stub of undefinedStubs) { it(`process.${stub}`, () => { expect(process[stub]()).toBeUndefined(); }); } const arrayStubs = ["getActiveResourcesInfo", "_getActiveRequests", "_getActiveHandles"]; for (const stub of arrayStubs) { it(`process.${stub}`, () => { expect(process[stub]()).toBeInstanceOf(Array); }); } const emptyObjectStubs = ["_preload_modules"]; const emptySetStubs = ["allowedNodeEnvironmentFlags"]; const emptyArrayStubs = ["moduleLoadList"]; for (const stub of emptyObjectStubs) { it(`process.${stub}`, () => { expect(process[stub]).toEqual({}); }); } for (const stub of emptySetStubs) { it(`process.${stub}`, () => { expect(process[stub]).toBeInstanceOf(Set); expect(process[stub].size).toBe(0); }); } for (const stub of emptyArrayStubs) { it(`process.${stub}`, () => { expect(process[stub]).toBeInstanceOf(Array); expect(process[stub]).toHaveLength(0); }); } ion value='mt/lit-DSD'>mt/lit-DSD Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2023-11-29Add new preferences module (#9115)Gravatar Nate Moore 15-4/+507
2023-11-29feat: unflag dev overlay (#9232)Gravatar Erika 15-33/+88
* feat: unflag dev overlay * fix: oops * fix: check for both config existing * fix: don't use flag in e2e tests * Disable view transition tests * Disable more * even more --------- Co-authored-by: Matthew Phillips <matthew@skypack.dev>
2023-11-29update error logging (#9129)Gravatar Fred K. Schott 7-46/+68
Co-authored-by: Matthew Phillips <matthew@skypack.dev>
2023-11-29Fix dev overlay style leak (#9220)Gravatar Nate Moore 1-4/+6
Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com>
2023-11-29Improve high contrast mode with the dev overlay (#9218)Gravatar Matthew Phillips 6-1/+57
* Improve high contrast mode with the dev overlay * Update packages/astro/src/runtime/client/dev-overlay/overlay.ts --------- Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
2023-11-29Ensure dev-overlay-window is anchored to the bottom (#9222)Gravatar Matthew Phillips 2-1/+7
2023-11-29Switch `app.render` signature (#9199)Gravatar Arsh 8-10/+80
* feat(app): app.render optional object * tests * update vercel and node * update changeset * deprecation notice and loggin * clarify changeset * add node, vercel changeset * deduplicate code
2023-11-29Unflag view transitions form handling (#9225)Gravatar Nate Moore 2-27/+33
2023-11-29Ensure dev overlay x-ray highlight goes over the island (#9227)Gravatar Matthew Phillips 3-1/+23
* Ensure dev overlay x-ray highlight goes over the island * oops
2023-11-29Small polish to the overlay (#9214)Gravatar Erika 2-5/+14
2023-11-29chore: remove deprecated `matchNotFound` options (#9212)Gravatar Alexander Niebuhr 5-10/+12
Co-authored-by: Matthew Phillips <matthew@skypack.dev>
2023-11-28[ci] release (beta) (#9211)astro@4.0.0-beta.1@astrojs/upgrade@0.1.0-beta.0Gravatar Houston (Bot) 36-68/+118
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-11-28feat: implement overlay main screen redesign (#9118)Gravatar Erika 50-217/+3638
* feat: implement redesign * fix: make it build * feat: visual tweaks * feat(overlay): update styling, integration endpoint * feat: add fallback icons * Clean up tests (#9183) * Add `@astrojs/upgrade` package for automatic package upgrades (#8525) Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * [ci] format * fix: links with same path but different search params not prefetched (#9189) Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * fix: discord icon * chore: changeset --------- Co-authored-by: Nate Moore <nate@astro.build> Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com> Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> Co-authored-by: Spencer Whitehead <35475068+SpencerWhitehead7@users.noreply.github.com> Co-authored-by: Matthew Phillips <matthew@skypack.dev>
2023-11-27[ci] release (beta) (#9114)create-astro@4.5.2-beta.0astro@4.0.0-beta.0@astrojs/vue@4.0.0-beta.0@astrojs/vercel@6.0.0-beta.0@astrojs/tailwind@6.0.0-beta.0@astrojs/svelte@5.0.0-beta.0@astrojs/rss@4.0.0-beta.0@astrojs/react@3.0.7-beta.0@astrojs/node@7.0.0-beta.0@astrojs/mdx@2.0.0-beta.0@astrojs/markdown-remark@4.0.0-beta.0Gravatar Houston (Bot) 66-154/+330
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-11-27Remove support for simple objects in endpoints (#9181)Gravatar Bjorn Lu 56-529/+206
* Deprecate simple object from endpoints * Update changeset * Add missing Response return Co-authored-by: Happydev <81974850+MoustaphaDev@users.noreply.github.com> * Update .changeset/clever-beds-notice.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --------- Co-authored-by: Happydev <81974850+MoustaphaDev@users.noreply.github.com> Co-authored-by: Matthew Phillips <matthew@skypack.dev> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-11-28Remove shiki lang path property support (#9196)Gravatar Bjorn Lu 7-427/+22
2023-11-28Remove deprecated features from Astro 3.0 (#9168)Gravatar Bjorn Lu 47-398/+95
2023-11-28Remove deprecated markdown-remark APIs (#9182)Gravatar Bjorn Lu 4-59/+7
2023-11-27[ci] release (#9180)astro@3.6.1Gravatar Houston (Bot) 32-65/+63
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-11-24Remove vercel deprecated analytics option (#9184)Gravatar Bjorn Lu 3-30/+12
2023-11-24[ci] formatGravatar Guspan Tanadi 1-2/+1
2023-11-24style: highlight markdown Tip Note section CONTRIBUTING (#9123)Gravatar Guspan Tanadi 1-5/+7
2023-11-23fix scroll restoration issue on webKit browsers (#9186)Gravatar Martin Trapp 2-1/+7
* fix scroll restoration issue on webKit browsers * add changeset * Update .changeset/shaggy-socks-glow.md * Update .changeset/shaggy-socks-glow.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --------- Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-11-23fix(middleware): rename internal middleware id (#9173)Gravatar Arsh 2-1/+6
* rename internal middleware id * add changeset
2023-11-23fix: Changelog formatting for 3.6.0 View Transition events (#9176)Gravatar Martin Trapp 1-3/+3
Co-authored-by: Eva Decker <itsevadecker@gmail.com>
2023-11-22[ci] formatGravatar Eva Decker 1-3/+3
2023-11-22Fix View Transitions code block formatting (#9174)Gravatar Eva Decker 1-3/+3
2023-11-22Rename entryPoint to entrypoint (#9161)Gravatar Bjorn Lu 14-26/+38
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-11-22Fix esbuild warning for local dev (#9160)Gravatar Bjorn Lu 1-1/+1
2023-11-22[ci] release (#9165)astro@3.6.0Gravatar Houston (Bot) 34-90/+83
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>