aboutsummaryrefslogtreecommitdiff
path: root/test/bun.js/plugins.test.ts
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-09-03 03:57:43 -0700
committerGravatar GitHub <noreply@github.com> 2022-09-03 03:57:43 -0700
commit0ca42e81f31d31270c44f81d88fff33361817720 (patch)
tree27e27b32d1850a1fada1a002207e3254cbc597e8 /test/bun.js/plugins.test.ts
parent8b2d07e82ee6249e0886109585b63429ccf3ab3a (diff)
downloadbun-0ca42e81f31d31270c44f81d88fff33361817720.tar.gz
bun-0ca42e81f31d31270c44f81d88fff33361817720.tar.zst
bun-0ca42e81f31d31270c44f81d88fff33361817720.zip
Plugin API (#1199)
* Plugin API * Fix the bugs * Implement `"object"` loader Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'test/bun.js/plugins.test.ts')
-rw-r--r--test/bun.js/plugins.test.ts212
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);
+ }
+ }
+ });
+});