| 1 | import { describe, expect, it } from "vitest"; |
| 2 | import { |
| 3 | findPresetConflict, |
| 4 | hasForeignNitroPlugin, |
| 5 | isSamePreset, |
| 6 | markInjectedPlugins, |
| 7 | NITRO_PLUGIN_NAME, |
| 8 | normalizePresetName, |
| 9 | resolveNitroConfig, |
| 10 | resolveNitroOutputDirs, |
| 11 | type NitroConfigSlice, |
| 12 | } from "../UserConfig.ts"; |
| 13 | |
| 14 | const resolve = (...segments: Array<string>): string => |
| 15 | segments.reduce((acc, segment) => |
| 16 | segment.startsWith("/") ? segment : `${acc}/${segment}`, |
| 17 | ); |
| 18 | |
| 19 | describe("normalizePresetName / isSamePreset", () => { |
| 20 | it("treats kebab, snake, and camel spellings as the same preset", () => { |
| 21 | expect(normalizePresetName("awsLambda")).toBe("aws-lambda"); |
| 22 | expect(normalizePresetName("aws_lambda")).toBe("aws-lambda"); |
| 23 | expect(isSamePreset("aws-lambda", "awsLambda")).toBe(true); |
| 24 | expect(isSamePreset("aws-lambda", "node-server")).toBe(false); |
| 25 | }); |
| 26 | }); |
| 27 | |
| 28 | describe("findPresetConflict", () => { |
| 29 | it("returns undefined when no preset is given or it matches the target", () => { |
| 30 | expect(findPresetConflict(undefined, "aws-lambda")).toBeUndefined(); |
| 31 | expect(findPresetConflict({}, "aws-lambda")).toBeUndefined(); |
| 32 | expect( |
| 33 | findPresetConflict({ preset: "aws_lambda" }, "aws-lambda"), |
| 34 | ).toBeUndefined(); |
| 35 | }); |
| 36 | |
| 37 | it("surfaces a foreign preset so the build can fail actionably", () => { |
| 38 | expect(findPresetConflict({ preset: "netlify" }, "aws-lambda")).toBe( |
| 39 | "netlify", |
| 40 | ); |
| 41 | }); |
| 42 | }); |
| 43 | |
| 44 | describe("resolveNitroConfig", () => { |
| 45 | it("enforces the target's preset and rootDir over the caller's overrides", () => { |
| 46 | const config = resolveNitroConfig({ |
| 47 | preset: "aws-lambda", |
| 48 | rootDir: "/project", |
| 49 | nitro: { |
| 50 | preset: "node-server", |
| 51 | rootDir: "/elsewhere", |
| 52 | prerender: { crawlLinks: true }, |
| 53 | }, |
| 54 | }); |
| 55 | expect(config.preset).toBe("aws-lambda"); |
| 56 | expect(config.rootDir).toBe("/project"); |
| 57 | expect(config.buildDir).toBe("/project/.nitro"); |
| 58 | // Everything the integration does not own is preserved. |
| 59 | expect(config["prerender"]).toEqual({ crawlLinks: true }); |
| 60 | }); |
| 61 | |
| 62 | it("runs the target's configure pass after the preset is enforced", () => { |
| 63 | const config = resolveNitroConfig({ |
| 64 | preset: "aws-lambda", |
| 65 | rootDir: "/project", |
| 66 | nitro: { awsLambda: { foo: 1 } }, |
| 67 | configure: (nitroConfig: NitroConfigSlice) => { |
| 68 | nitroConfig.awsLambda = { |
| 69 | ...(nitroConfig.awsLambda as Record<string, unknown>), |
| 70 | streaming: true, |
| 71 | }; |
| 72 | }, |
| 73 | }); |
| 74 | expect(config.awsLambda).toEqual({ foo: 1, streaming: true }); |
| 75 | }); |
| 76 | }); |
| 77 | |
| 78 | describe("resolveNitroOutputDirs", () => { |
| 79 | it("mirrors nitro's defaults", () => { |
| 80 | expect(resolveNitroOutputDirs({}, "/project", resolve)).toEqual({ |
| 81 | dir: "/project/.output", |
| 82 | serverDir: "/project/.output/server", |
| 83 | publicDir: "/project/.output/public", |
| 84 | }); |
| 85 | }); |
| 86 | |
| 87 | it("honors an output override on the nitro config", () => { |
| 88 | expect( |
| 89 | resolveNitroOutputDirs( |
| 90 | { output: { dir: "build", serverDir: "fn", publicDir: "static" } }, |
| 91 | "/project", |
| 92 | resolve, |
| 93 | ), |
| 94 | ).toEqual({ |
| 95 | dir: "/project/build", |
| 96 | serverDir: "/project/build/fn", |
| 97 | publicDir: "/project/build/static", |
| 98 | }); |
| 99 | }); |
| 100 | }); |
| 101 | |
| 102 | describe("hasForeignNitroPlugin", () => { |
| 103 | it("ignores the plugin instances this integration created", () => { |
| 104 | const injected = markInjectedPlugins([ |
| 105 | { name: "alchemy:solidstart-nitro-conflict" }, |
| 106 | [{ name: NITRO_PLUGIN_NAME }, false], |
| 107 | ]); |
| 108 | expect(hasForeignNitroPlugin(injected)).toBe(false); |
| 109 | }); |
| 110 | |
| 111 | it("detects a project-registered nitro plugin, however nested", () => { |
| 112 | const injected = markInjectedPlugins([{ name: NITRO_PLUGIN_NAME }]); |
| 113 | expect( |
| 114 | hasForeignNitroPlugin([ |
| 115 | [{ name: "solid-start:config" }, [{ name: NITRO_PLUGIN_NAME }]], |
| 116 | injected, |
| 117 | ]), |
| 118 | ).toBe(true); |
| 119 | }); |
| 120 | |
| 121 | it("tolerates falsy and non-plugin entries", () => { |
| 122 | expect(hasForeignNitroPlugin([false, null, undefined, "x"])).toBe(false); |
| 123 | expect(hasForeignNitroPlugin(undefined)).toBe(false); |
| 124 | }); |
| 125 | }); |