a reactive (signals based) hypermedia web framework (wip)
stormlightlabs.github.io/volt/
hypermedia
frontend
signals
1import { describe, it, expect } from "vitest";
2import {
3 generateMinimalHTML,
4 generateMinimalCSS,
5 generateMinimalPackageJSON,
6 generateMinimalREADME,
7} from "$templates/minimal.js";
8import {
9 generateStylesHTML,
10 generateStylesCSS,
11 generateStylesPackageJSON,
12 generateStylesREADME,
13} from "$templates/styles.js";
14import {
15 generateRouterHTML,
16 generateRouterCSS,
17 generateRouterPackageJSON,
18 generateRouterREADME,
19} from "$templates/with-router.js";
20import {
21 generatePluginsHTML,
22 generatePluginsCSS,
23 generatePluginsPackageJSON,
24 generatePluginsREADME,
25} from "$templates/with-plugins.js";
26
27describe("template generators", () => {
28 const projectName = "test-project";
29
30 describe("minimal template", () => {
31 it("should generate HTML with project name", () => {
32 const html = generateMinimalHTML(projectName);
33 expect(html).toContain(projectName);
34 expect(html).toContain("data-volt");
35 expect(html).toContain("voltx.min.js");
36 });
37
38 it("should generate CSS", () => {
39 const css = generateMinimalCSS();
40 expect(css).toContain(".container");
41 expect(css).toContain(".counter");
42 });
43
44 it("should generate valid package.json", () => {
45 const packageJson = generateMinimalPackageJSON(projectName);
46 const parsed = JSON.parse(packageJson);
47 expect(parsed.name).toBe(projectName);
48 expect(parsed.scripts.dev).toBe("voltx dev");
49 expect(parsed.scripts.build).toBe("voltx build");
50 });
51
52 it("should generate README with project name", () => {
53 const readme = generateMinimalREADME(projectName);
54 expect(readme).toContain(projectName);
55 expect(readme).toContain("pnpm dev");
56 });
57 });
58
59 describe("styles template", () => {
60 it("should generate HTML without VoltX.js framework", () => {
61 const html = generateStylesHTML(projectName);
62 expect(html).toContain(projectName);
63 expect(html).toContain("voltx.min.css");
64 expect(html).not.toContain("voltx.min.js");
65 expect(html).not.toContain("data-volt");
66 });
67
68 it("should generate CSS", () => {
69 const css = generateStylesCSS();
70 expect(css).toContain(".container");
71 expect(css).toContain(".card");
72 });
73
74 it("should generate valid package.json", () => {
75 const packageJson = generateStylesPackageJSON(projectName);
76 const parsed = JSON.parse(packageJson);
77 expect(parsed.name).toBe(projectName);
78 });
79
80 it("should generate README explaining styles-only approach", () => {
81 const readme = generateStylesREADME(projectName);
82 expect(readme).toContain(projectName);
83 expect(readme).toContain("styles-only");
84 });
85 });
86
87 describe("router template", () => {
88 it("should generate HTML with routing", () => {
89 const html = generateRouterHTML(projectName);
90 expect(html).toContain(projectName);
91 expect(html).toContain("data-volt-navigate");
92 expect(html).toContain("data-volt-url");
93 expect(html).toContain("navigatePlugin");
94 });
95
96 it("should generate CSS with navigation styles", () => {
97 const css = generateRouterCSS();
98 expect(css).toContain(".nav");
99 });
100
101 it("should generate valid package.json", () => {
102 const packageJson = generateRouterPackageJSON(projectName);
103 const parsed = JSON.parse(packageJson);
104 expect(parsed.name).toBe(projectName);
105 });
106
107 it("should generate README explaining routing", () => {
108 const readme = generateRouterREADME(projectName);
109 expect(readme).toContain(projectName);
110 expect(readme).toContain("routing");
111 });
112 });
113
114 describe("plugins template", () => {
115 it("should generate HTML with all plugins", () => {
116 const html = generatePluginsHTML(projectName);
117 expect(html).toContain(projectName);
118 expect(html).toContain("persistPlugin");
119 expect(html).toContain("scrollPlugin");
120 expect(html).toContain("urlPlugin");
121 expect(html).toContain("surgePlugin");
122 expect(html).toContain("navigatePlugin");
123 });
124
125 it("should generate CSS for plugin demos", () => {
126 const css = generatePluginsCSS();
127 expect(css).toContain(".card");
128 expect(css).toContain(".counter");
129 expect(css).toContain(".animated-box");
130 });
131
132 it("should generate valid package.json", () => {
133 const packageJson = generatePluginsPackageJSON(projectName);
134 const parsed = JSON.parse(packageJson);
135 expect(parsed.name).toBe(projectName);
136 });
137
138 it("should generate README listing all plugins", () => {
139 const readme = generatePluginsREADME(projectName);
140 expect(readme).toContain(projectName);
141 expect(readme).toContain("Persist Plugin");
142 expect(readme).toContain("Scroll Plugin");
143 expect(readme).toContain("URL Plugin");
144 });
145 });
146});