| 1 | import { createMiniflareFromRolldown } from "../../../../cloudflare-test-tools/src/miniflare/miniflare.ts"; |
| 2 | import { describe, expect, it } from "vitest"; |
| 3 | import { buildFixture } from "./utils/build-fixture.ts"; |
| 4 | import { |
| 5 | getAsset, |
| 6 | getEntryChunk, |
| 7 | hasCloudflareModuleReferences, |
| 8 | } from "./utils/output.ts"; |
| 9 | |
| 10 | describe("additional modules", async () => { |
| 11 | const built = await buildFixture({ |
| 12 | fixture: "additional-modules/index.ts", |
| 13 | }); |
| 14 | |
| 15 | it("supports Data modules with a .bin extension", async () => { |
| 16 | await using miniflare = await createMiniflareFromRolldown(built.output, { |
| 17 | compatibilityDate: "2025-07-01", |
| 18 | }); |
| 19 | |
| 20 | expect(await miniflare.fetchJson<{ byteLength: number }>("/bin")).toEqual({ |
| 21 | byteLength: 342_936, |
| 22 | }); |
| 23 | }); |
| 24 | |
| 25 | it("supports Text modules with .html, .txt, and .sql extensions", async () => { |
| 26 | await using miniflare = await createMiniflareFromRolldown(built.output, { |
| 27 | compatibilityDate: "2025-07-01", |
| 28 | }); |
| 29 | |
| 30 | expect(await miniflare.fetchText("/html")).toBe("<h1>Hello world</h1>\n"); |
| 31 | expect(await miniflare.fetchText("/text")).toBe("Example text content.\n"); |
| 32 | expect(await miniflare.fetchText("/sql")).toBe("SELECT * FROM users;\n"); |
| 33 | }); |
| 34 | |
| 35 | it("supports text filenames containing double underscores", async () => { |
| 36 | await using miniflare = await createMiniflareFromRolldown(built.output, { |
| 37 | compatibilityDate: "2025-07-01", |
| 38 | }); |
| 39 | |
| 40 | expect(await miniflare.fetchText("/text2")).toBe( |
| 41 | "Example text content 2\n", |
| 42 | ); |
| 43 | }); |
| 44 | |
| 45 | it("supports subpath imports for text modules", async () => { |
| 46 | await using miniflare = await createMiniflareFromRolldown(built.output, { |
| 47 | compatibilityDate: "2025-07-01", |
| 48 | }); |
| 49 | |
| 50 | // Removed - see fixtures/additional-modules/index.ts for more details. |
| 51 | // expect(await miniflare.fetchText("/subpath-html")).toBe("<h1>Hello world</h1>\n"); |
| 52 | expect(await miniflare.fetchText("/subpath-html-with-ext")).toBe( |
| 53 | "<h1>Hello world</h1>\n", |
| 54 | ); |
| 55 | }); |
| 56 | |
| 57 | it("supports .wasm, .wasm?module, and .wasm?init imports", async () => { |
| 58 | await using miniflare = await createMiniflareFromRolldown(built.output, { |
| 59 | compatibilityDate: "2025-07-01", |
| 60 | }); |
| 61 | |
| 62 | expect(await miniflare.fetchJson<{ result: number }>("/wasm")).toEqual({ |
| 63 | result: 7, |
| 64 | }); |
| 65 | expect( |
| 66 | await miniflare.fetchJson<{ result: number }>("/wasm-with-module-param"), |
| 67 | ).toEqual({ |
| 68 | result: 11, |
| 69 | }); |
| 70 | expect( |
| 71 | await miniflare.fetchJson<{ result: number }>("/wasm-with-init-param"), |
| 72 | ).toEqual({ |
| 73 | result: 15, |
| 74 | }); |
| 75 | }); |
| 76 | |
| 77 | it("rewrites Cloudflare module sentinels into emitted asset paths", () => { |
| 78 | const entry = getEntryChunk(built.output); |
| 79 | |
| 80 | expect(hasCloudflareModuleReferences(entry.code)).toBe(false); |
| 81 | |
| 82 | const binAsset = getAsset(built.output, /bin-example.*\.bin$/); |
| 83 | const htmlAsset = getAsset(built.output, /html-example.*\.html$/); |
| 84 | const textAsset = getAsset(built.output, /text-example.*\.txt$/); |
| 85 | const text2Asset = getAsset(built.output, /text__example__2.*\.txt$/); |
| 86 | const sqlAsset = getAsset(built.output, /sql-example.*\.sql$/); |
| 87 | const wasmAsset = getAsset(built.output, /wasm-example.*\.wasm$/); |
| 88 | |
| 89 | expect(entry.code).toContain(binAsset.fileName); |
| 90 | expect(entry.code).toContain(htmlAsset.fileName); |
| 91 | expect(entry.code).toContain(textAsset.fileName); |
| 92 | expect(entry.code).toContain(text2Asset.fileName); |
| 93 | expect(entry.code).toContain(sqlAsset.fileName); |
| 94 | expect(entry.code).toContain(wasmAsset.fileName); |
| 95 | }); |
| 96 | }); |