@omg-dev/vite-plugin 0.4.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,79 @@
1
+ // Verifies the build-time injection of the shake-to-report feedback widget
2
+ // (@omg-dev/sdk/feedback/auto) into the app entry. The brand badge bundles
3
+ // feedback when it's on (the default), so the STANDALONE widget only injects
4
+ // when the brand badge is disabled — these tests run with brandBadge:false.
5
+ // Opt-out via vibes({ feedback: false }), build-only, app-entry-only.
6
+
7
+ import { describe, expect, test } from "bun:test"
8
+ import vibes from "./index.ts"
9
+
10
+ const ROOT = "/app"
11
+ const ENTRY = `${ROOT}/src/main.tsx`
12
+ const FEEDBACK_IMPORT = `import "@omg-dev/sdk/feedback/auto";`
13
+
14
+ // Minimal Rollup plugin-context stub: resolve() succeeds for everything,
15
+ // warn() is captured. transform() is a plain async fn we bind `this` onto.
16
+ function ctx() {
17
+ const warnings: string[] = []
18
+ return {
19
+ warnings,
20
+ resolve: async (src: string) => ({ id: src }),
21
+ warn: (msg: string) => warnings.push(msg),
22
+ }
23
+ }
24
+
25
+ async function runTransform(
26
+ plugin: ReturnType<typeof vibes>,
27
+ code: string,
28
+ id: string,
29
+ context: ReturnType<typeof ctx>,
30
+ ) {
31
+ const fn = plugin.transform as (this: unknown, code: string, id: string) => Promise<unknown>
32
+ return fn.call(context, code, id) as Promise<{ code: string } | null>
33
+ }
34
+
35
+ function buildPlugin(opts?: Parameters<typeof vibes>[0]) {
36
+ const plugin = vibes({ root: ROOT, brandBadge: false, ...opts })
37
+ // configResolved sets command + root that transform gates on.
38
+ const configResolved = plugin.configResolved as (cfg: unknown) => void
39
+ configResolved({ command: "build", root: ROOT })
40
+ return plugin
41
+ }
42
+
43
+ describe("feedback widget injection", () => {
44
+ test("default ON: appends the auto-mount import to the app entry", async () => {
45
+ const plugin = buildPlugin()
46
+ const out = await runTransform(plugin, "export default 1", ENTRY, ctx())
47
+ expect(out?.code).toContain(FEEDBACK_IMPORT)
48
+ })
49
+
50
+ test("opt-out via feedback:false omits the import", async () => {
51
+ const plugin = buildPlugin({ feedback: false, pwa: false })
52
+ const out = await runTransform(plugin, "export default 1", ENTRY, ctx())
53
+ // Nothing to inject → transform returns null.
54
+ expect(out).toBeNull()
55
+ })
56
+
57
+ test("injected exactly once across multiple entry transforms", async () => {
58
+ const plugin = buildPlugin({ pwa: false })
59
+ const first = await runTransform(plugin, "export default 1", ENTRY, ctx())
60
+ const second = await runTransform(plugin, "export default 2", ENTRY, ctx())
61
+ expect(first?.code).toContain(FEEDBACK_IMPORT)
62
+ expect(second).toBeNull() // already injected
63
+ })
64
+
65
+ test("non-entry modules are untouched", async () => {
66
+ const plugin = buildPlugin()
67
+ const out = await runTransform(plugin, "export const x = 1", `${ROOT}/src/util.ts`, ctx())
68
+ expect(out).toBeNull()
69
+ })
70
+
71
+ test("warns (and skips) when @omg-dev/sdk cannot be resolved", async () => {
72
+ const plugin = buildPlugin({ pwa: false })
73
+ const context = ctx()
74
+ context.resolve = async () => null // simulate missing dependency
75
+ const out = await runTransform(plugin, "export default 1", ENTRY, context)
76
+ expect(out).toBeNull()
77
+ expect(context.warnings.some((w) => w.includes("shake-to-report skipped"))).toBe(true)
78
+ })
79
+ })