diff options
Diffstat (limited to 'test/bun.js/plugins.test.ts')
-rw-r--r-- | test/bun.js/plugins.test.ts | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/test/bun.js/plugins.test.ts b/test/bun.js/plugins.test.ts new file mode 100644 index 000000000..743790cac --- /dev/null +++ b/test/bun.js/plugins.test.ts @@ -0,0 +1,212 @@ +import { it, expect, describe, afterAll } from "bun:test"; +import { resolve } from "path"; + +Bun.plugin({ + name: "boop beep beep", + setup(builder) { + builder.onResolve({ filter: /boop/, namespace: "beep" }, () => ({ + path: "boop", + namespace: "beep", + })); + + builder.onLoad({ filter: /boop/, namespace: "beep" }, () => ({ + contents: `export default 42;`, + loader: "js", + })); + }, +}); + +var objectModuleResult = { + hello: "world", +}; +Bun.plugin({ + name: "an object module", + setup(builder) { + builder.onResolve({ filter: /.*/, namespace: "obj" }, ({ path }) => ({ + path, + namespace: "obj", + })); + + builder.onLoad({ filter: /.*/, namespace: "obj" }, () => ({ + exports: objectModuleResult, + loader: "object", + })); + }, +}); + +Bun.plugin({ + name: "svelte loader", + setup(builder) { + var { compile } = require("svelte/compiler"); + var { readFileSync } = require("fs"); + builder.onLoad({ filter: /\.svelte$/ }, ({ path }) => ({ + contents: compile(readFileSync(path, "utf8"), { + filename: path, + generate: "ssr", + }).js.code, + loader: "js", + })); + }, +}); + +var failingObject; +Bun.plugin({ + name: "failing loader", + setup(builder) { + builder.onResolve({ filter: /.*/, namespace: "fail" }, ({ path }) => ({ + path, + namespace: "fail", + })); + builder.onLoad({ filter: /.*/, namespace: "fail" }, () => failingObject); + }, +}); + +var laterCode = ""; + +Bun.plugin({ + name: "delayed loader", + setup(builder) { + builder.onResolve({ filter: /.*/, namespace: "delay" }, ({ path }) => ({ + namespace: "delay", + path, + })); + + builder.onLoad({ filter: /.*/, namespace: "delay" }, ({ path }) => ({ + contents: laterCode, + loader: "js", + })); + }, +}); + +describe("require", () => { + it("SSRs `<h1>Hello world!</h1>` with Svelte", () => { + const { default: App } = require("./hello.svelte"); + const { html } = App.render(); + + expect(html).toBe("<h1>Hello world!</h1>"); + }); + + it("beep:boop returns 42", () => { + const result = require("beep:boop"); + expect(result.default).toBe(42); + }); + + it("object module works", () => { + const result = require("obj:boop"); + expect(result.hello).toBe(objectModuleResult.hello); + objectModuleResult.there = true; + const result2 = require("obj:boop2"); + expect(result.there).toBe(undefined); + expect(result2.there).toBe(objectModuleResult.there); + expect(result2.there).toBe(true); + }); +}); + +describe("dynamic import", () => { + it("SSRs `<h1>Hello world!</h1>` with Svelte", async () => { + const { default: App } = await import("./hello.svelte"); + const { html } = App.render(); + + expect(html).toBe("<h1>Hello world!</h1>"); + }); + + it("beep:boop returns 42", async () => { + const result = await import("beep:boop"); + expect(result.default).toBe(42); + }); +}); + +describe("import statement", () => { + it("SSRs `<h1>Hello world!</h1>` with Svelte", async () => { + laterCode = ` +import Hello from "${resolve(import.meta.dir, "hello2.svelte")}"; +export default Hello; +`; + const { default: SvelteApp } = await import("delay:hello2.svelte"); + const { html } = SvelteApp.render(); + + expect(html).toBe("<h1>Hello world!</h1>"); + }); +}); + +describe("errors", () => { + it("valid loaders work", () => { + const validLoaders = ["js", "jsx", "ts", "tsx"]; + const inputs = [ + "export default 'hi';", + "export default 'hi';", + "export default 'hi';", + "export default 'hi';", + ]; + for (let i = 0; i < validLoaders.length; i++) { + const loader = validLoaders[i]; + const input = inputs[i]; + failingObject = { contents: input, loader }; + expect(require(`fail:my-file-${loader}`).default).toBe("hi"); + } + }); + + it("invalid loaders throw", () => { + const invalidLoaders = ["blah", "blah2", "blah3", "blah4"]; + const inputs = [ + "body { background: red; }", + "<h1>hi</h1>", + '{"hi": "there"}', + "hi", + ]; + for (let i = 0; i < invalidLoaders.length; i++) { + const loader = invalidLoaders[i]; + const input = inputs[i]; + failingObject = { contents: input, loader }; + try { + require(`fail:my-file-${loader}`); + throw -1; + } catch (e) { + if (e === -1) { + throw new Error("Expected error"); + } + expect(e.message.length > 0).toBe(true); + } + } + }); + + it("transpiler errors work", () => { + const invalidLoaders = ["ts"]; + const inputs = ["const x: string = -NaNAn../!!;"]; + for (let i = 0; i < invalidLoaders.length; i++) { + const loader = invalidLoaders[i]; + const input = inputs[i]; + failingObject = { contents: input, loader }; + try { + require(`fail:my-file-${loader}-3`); + throw -1; + } catch (e) { + if (e === -1) { + throw new Error("Expected error"); + } + expect(e.message.length > 0).toBe(true); + } + } + }); + + it("invalid onLoad objects throw", () => { + const invalidOnLoadObjects = [ + {}, + { contents: -1 }, + { contents: "", loader: -1 }, + { contents: "", loader: "klz", resolveDir: -1 }, + ]; + for (let i = 0; i < invalidOnLoadObjects.length; i++) { + failingObject = invalidOnLoadObjects[i]; + try { + require(`fail:my-file-${i}-2`); + throw -1; + } catch (e) { + if (e === -1) { + throw new Error("Expected error"); + } + expect(e.message.length > 0).toBe(true); + } + } + }); +}); |