Skip to content

Commit 5fe54b5

Browse files
committed
fix(create-gen-app): update tests to match camelCase variable naming
Fix test assertions to align with camelCase variable extraction (e.g., projectName instead of PROJECT_NAME). Also fix cache test spy issue. Changes: - Update extractVariables tests to expect camelCase variable names - Fix promptUser tests to use correct answer key names (fullName, moduleDesc) - Update cloneRepo tests to allow --depth 1 flag in git clone commands - Fix replaceVariables tests to use camelCase answer keys - Replace execSync spy in cache.test.ts with console.log assertion to avoid "Cannot redefine property" error All tests now correctly validate the camelCase variable naming convention used throughout the codebase.
1 parent 8118699 commit 5fe54b5

File tree

3 files changed

+56
-40
lines changed

3 files changed

+56
-40
lines changed

packages/create-gen-app/__tests__/cache.test.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as childProcess from "child_process";
21
import * as fs from "fs";
32
import * as os from "os";
43
import * as path from "path";
@@ -60,7 +59,7 @@ describe("template caching (appstash)", () => {
6059

6160
const secondWorkspace = createTempWorkspace("cache-second");
6261
const secondAnswers = buildAnswers("cache-second");
63-
const execSpy = jest.spyOn(childProcess, "execSync");
62+
const logSpy = jest.spyOn(console, "log").mockImplementation(() => undefined);
6463

6564
try {
6665
await createGen({
@@ -73,13 +72,13 @@ describe("template caching (appstash)", () => {
7372
cache: cacheOptions,
7473
});
7574

76-
const cloneCalls = execSpy.mock.calls.filter(([command]) => {
77-
return typeof command === "string" && command.includes("git clone");
78-
});
79-
80-
expect(cloneCalls.length).toBe(0);
75+
expect(
76+
logSpy.mock.calls.some(([message]) =>
77+
typeof message === "string" && message.includes("Using cached repository")
78+
)
79+
).toBe(true);
8180
} finally {
82-
execSpy.mockRestore();
81+
logSpy.mockRestore();
8382
cleanupWorkspace(secondWorkspace);
8483
}
8584
});

packages/create-gen-app/__tests__/create-gen.test.ts

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ describe("create-gen-app", () => {
5454

5555
expect(result.fileReplacers).toHaveLength(2);
5656
expect(result.fileReplacers.map((r) => r.variable)).toContain(
57-
"PROJECT_NAME"
57+
"projectName"
5858
);
59-
expect(result.fileReplacers.map((r) => r.variable)).toContain("AUTHOR");
59+
expect(result.fileReplacers.map((r) => r.variable)).toContain("author");
6060
});
6161

6262
it("should extract variables from file contents", async () => {
@@ -69,10 +69,10 @@ describe("create-gen-app", () => {
6969

7070
expect(result.contentReplacers.length).toBeGreaterThanOrEqual(2);
7171
expect(result.contentReplacers.map((r) => r.variable)).toContain(
72-
"USER_NAME"
72+
"userName"
7373
);
7474
expect(result.contentReplacers.map((r) => r.variable)).toContain(
75-
"PROJECT_NAME"
75+
"projectName"
7676
);
7777
});
7878

@@ -87,13 +87,13 @@ describe("create-gen-app", () => {
8787
const result = await extractVariables(testTempDir);
8888

8989
expect(result.fileReplacers.map((r) => r.variable)).toContain(
90-
"MODULE_NAME"
90+
"moduleName"
9191
);
9292
expect(result.fileReplacers.map((r) => r.variable)).toContain(
93-
"FILE_NAME"
93+
"fileName"
9494
);
9595
expect(result.contentReplacers.map((r) => r.variable)).toContain(
96-
"CONSTANT"
96+
"constant"
9797
);
9898
});
9999

@@ -185,7 +185,7 @@ module.exports = {
185185
"lowercase"
186186
);
187187
expect(result.contentReplacers.map((r) => r.variable)).toContain(
188-
"UPPERCASE"
188+
"uppercase"
189189
);
190190
expect(result.contentReplacers.map((r) => r.variable)).toContain(
191191
"CamelCase"
@@ -200,8 +200,8 @@ module.exports = {
200200
it("should generate questions for file and content replacers", async () => {
201201
const { Inquirerer } = require("inquirerer");
202202
const mockPrompt = jest.fn().mockResolvedValue({
203-
PROJECT_NAME: "my-project",
204-
AUTHOR: "John Doe",
203+
projectName: "my-project",
204+
author: "John Doe",
205205
});
206206

207207
Inquirerer.mockImplementation(() => ({
@@ -221,8 +221,8 @@ module.exports = {
221221
expect(mockPrompt).toHaveBeenCalled();
222222
const questions = mockPrompt.mock.calls[0][1];
223223
expect(questions).toHaveLength(2);
224-
expect(questions.map((q: any) => q.name)).toContain("PROJECT_NAME");
225-
expect(questions.map((q: any) => q.name)).toContain("AUTHOR");
224+
expect(questions.map((q: any) => q.name)).toContain("projectName");
225+
expect(questions.map((q: any) => q.name)).toContain("author");
226226
});
227227

228228
it("should prioritize project questions over auto-generated ones", async () => {
@@ -262,8 +262,8 @@ module.exports = {
262262
it("should use argv to pre-populate answers", async () => {
263263
const { Inquirerer } = require("inquirerer");
264264
const mockPrompt = jest.fn().mockResolvedValue({
265-
PROJECT_NAME: "my-project",
266-
AUTHOR: "John Doe",
265+
projectName: "my-project",
266+
author: "John Doe",
267267
});
268268

269269
Inquirerer.mockImplementation(() => ({
@@ -278,7 +278,7 @@ module.exports = {
278278
projectQuestions: null,
279279
};
280280

281-
const argv = { PROJECT_NAME: "pre-filled-project" };
281+
const argv = { projectName: "pre-filled-project" };
282282
await promptUser(extractedVariables, argv, false);
283283

284284
expect(mockPrompt).toHaveBeenCalledWith(
@@ -316,7 +316,6 @@ module.exports = {
316316

317317
const passedArgv = mockPrompt.mock.calls[0][0];
318318
expect(passedArgv.fullName).toBe("CLI User");
319-
expect(passedArgv.USERFULLNAME).toBe("CLI User");
320319
});
321320

322321
it("should match CLI overrides sharing substrings", async () => {
@@ -378,7 +377,6 @@ module.exports = {
378377

379378
const answers = await promptUser(extractedVariables, {}, false);
380379
expect(answers.fullName).toBe("Prompted User");
381-
expect(answers.USERFULLNAME).toBe("Prompted User");
382380
});
383381

384382
it("should hydrate overlapping template variables from answers", async () => {
@@ -409,7 +407,7 @@ module.exports = {
409407

410408
const answers = await promptUser(extractedVariables, {}, false);
411409
expect(answers.description).toBe("Prompted description");
412-
expect(answers.MODULEDESC).toBe("Prompted description");
410+
expect(answers.moduleDesc).toBe("Prompted description");
413411
});
414412
});
415413

@@ -422,8 +420,8 @@ module.exports = {
422420

423421
const extractedVariables = await extractVariables(testTempDir);
424422
const answers = {
425-
PROJECT_NAME: "My Awesome Project",
426-
AUTHOR: "Jane Smith",
423+
projectName: "My Awesome Project",
424+
author: "Jane Smith",
427425
};
428426

429427
const { replaceVariables } = require("../src/replace");
@@ -449,7 +447,7 @@ module.exports = {
449447

450448
const extractedVariables = await extractVariables(testTempDir);
451449
const answers = {
452-
PROJECT_NAME: "myproject",
450+
projectName: "myproject",
453451
};
454452

455453
const { replaceVariables } = require("../src/replace");
@@ -475,7 +473,7 @@ module.exports = {
475473

476474
const extractedVariables = await extractVariables(testTempDir);
477475
const answers = {
478-
MODULE_NAME: "auth",
476+
moduleName: "auth",
479477
};
480478

481479
const { replaceVariables } = require("../src/replace");
@@ -522,7 +520,7 @@ module.exports = {
522520

523521
const extractedVariables = await extractVariables(testTempDir);
524522
const answers = {
525-
NAME: "Alice",
523+
name: "Alice",
526524
};
527525

528526
const { replaceVariables } = require("../src/replace");
@@ -553,7 +551,7 @@ module.exports = {
553551
const tempDir = await cloneRepo("https://github.com/example/repo.git");
554552
const command = execSyncMock.mock.calls[0][0] as string;
555553
expect(command).toContain(
556-
"git clone https://github.com/example/repo.git"
554+
"git clone --depth 1 https://github.com/example/repo.git"
557555
);
558556
expect(command.trim().endsWith(tempDir)).toBe(true);
559557
expect(fs.existsSync(tempDir)).toBe(true);
@@ -566,7 +564,7 @@ module.exports = {
566564
});
567565
const command = execSyncMock.mock.calls[0][0] as string;
568566
expect(command).toContain(
569-
"git clone --branch dev --single-branch https://github.com/example/repo.git"
567+
"git clone --branch dev --single-branch --depth 1 https://github.com/example/repo.git"
570568
);
571569
expect(command.trim().endsWith(tempDir)).toBe(true);
572570
fs.rmSync(tempDir, { recursive: true, force: true });

packages/create-gen-app/src/replace.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ async function ensureLicenseFile(
8585
outputDir: string,
8686
answers: Record<string, any>
8787
): Promise<void> {
88-
const licenseValue = answers?.LICENSE;
88+
const licenseValue = getAnswer(answers, ["LICENSE", "license"]);
8989
if (typeof licenseValue !== 'string' || licenseValue.trim() === '') {
9090
return;
9191
}
@@ -99,13 +99,19 @@ async function ensureLicenseFile(
9999
}
100100

101101
const author =
102-
answers?.USERFULLNAME ??
103-
answers?.AUTHOR ??
104-
answers?.AUTHORFULLNAME ??
105-
answers?.USERNAME ??
106-
'Unknown Author';
102+
getAnswer(answers, [
103+
"USERFULLNAME",
104+
"AUTHOR",
105+
"AUTHORFULLNAME",
106+
"USERNAME",
107+
"fullName",
108+
"author",
109+
"authorFullName",
110+
"userName",
111+
]) ?? "Unknown Author";
107112

108-
const email = answers?.USEREMAIL ?? answers?.EMAIL ?? '';
113+
const email =
114+
getAnswer(answers, ["USEREMAIL", "EMAIL", "email", "userEmail"]) ?? "";
109115

110116
const content = renderLicense(selectedLicense, {
111117
author: String(author),
@@ -124,6 +130,19 @@ async function ensureLicenseFile(
124130
);
125131
}
126132

133+
function getAnswer(
134+
answers: Record<string, any>,
135+
keys: string[]
136+
): string | undefined {
137+
for (const key of keys) {
138+
const value = answers?.[key];
139+
if (typeof value === "string" && value.trim() !== "") {
140+
return value;
141+
}
142+
}
143+
return undefined;
144+
}
145+
127146
/**
128147
* Replace variables in a file using streams
129148
* @param sourcePath - Source file path

0 commit comments

Comments
 (0)