Skip to content

Commit 3475654

Browse files
committed
refactor(bakedInTemplates): use test fixture, return undefined instead of throw
1 parent ba7e988 commit 3475654

File tree

3 files changed

+83
-81
lines changed

3 files changed

+83
-81
lines changed

apps/generator/lib/templates/bakedInTemplates.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,19 @@ module.exports.isCoreTemplate = (templateName) => {
3737
/**
3838
* Retrieve a template by name and validate its path.
3939
* If the path does not exist, fallback to `node_modules/{templateName}`.
40+
* Returns undefined when templateName is invalid (null, undefined, not a string, or empty/whitespace-only) or when no baked-in template exists with the given name.
4041
*
4142
* @async
4243
* @param {string} templateName - The name of the template to retrieve.
43-
* @returns {Promise<{name: string, path: string}|undefined>} An object containing the template's name and path, or undefined if not found.
44+
* @returns {Promise<{name: string, path: string}|undefined>} An object containing the template's name and path, or undefined if templateName is invalid or template is not on the list.
4445
*/
4546
module.exports.getTemplate = async (templateName) => {
4647
if (templateName == null || typeof templateName !== 'string' || templateName.trim() === '') {
47-
throw new Error('Invalid template name');
48+
return undefined;
4849
}
4950
const template = templates.find(t => t.name === templateName);
5051
if (!template) {
51-
throw new Error('Invalid template name');
52+
return undefined;
5253
}
5354
const templatePath = template.path || path.resolve(__dirname, BAKED_IN_TEMPLATES_DIR, template.name);
5455
return {

apps/generator/test/bakedInTemplates.test.js

Lines changed: 56 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,35 @@
22
* @jest-environment node
33
*/
44
const path = require('path');
5+
6+
jest.mock('../lib/templates/BakedInTemplatesList.json', () => require('./fixtures/bakedInTemplatesFixture.json'));
7+
58
const { listBakedInTemplates, isCoreTemplate, getTemplate } = require('../lib/templates/bakedInTemplates');
6-
const templates = require('../lib/templates/BakedInTemplatesList.json');
9+
const fixtureTemplates = require('./fixtures/bakedInTemplatesFixture.json');
710

811
describe('bakedInTemplates', () => {
912
describe('listBakedInTemplates', () => {
1013
it('returns all templates when no filter is provided', () => {
1114
const result = listBakedInTemplates();
12-
expect(result).toHaveLength(templates.length);
13-
expect(result).toEqual(templates);
15+
expect(result).toHaveLength(fixtureTemplates.length);
16+
expect(result).toEqual(fixtureTemplates);
1417
});
1518

1619
it('returns all templates when filter is undefined', () => {
1720
const result = listBakedInTemplates(undefined);
18-
expect(result).toHaveLength(templates.length);
19-
expect(result).toEqual(templates);
21+
expect(result).toHaveLength(fixtureTemplates.length);
22+
expect(result).toEqual(fixtureTemplates);
2023
});
2124

2225
it('returns all templates when filter is empty object', () => {
2326
const result = listBakedInTemplates({});
24-
expect(result).toHaveLength(templates.length);
25-
expect(result).toEqual(templates);
27+
expect(result).toHaveLength(fixtureTemplates.length);
28+
expect(result).toEqual(fixtureTemplates);
2629
});
2730

2831
it('filters by type correctly', () => {
2932
const result = listBakedInTemplates({ type: 'client' });
30-
expect(result.length).toBeGreaterThan(0);
33+
expect(result).toHaveLength(3);
3134
expect(result.every(t => t.type === 'client')).toBe(true);
3235
});
3336

@@ -38,7 +41,7 @@ describe('bakedInTemplates', () => {
3841

3942
it('filters by stack correctly', () => {
4043
const result = listBakedInTemplates({ stack: 'quarkus' });
41-
expect(result.length).toBeGreaterThan(0);
44+
expect(result).toHaveLength(2);
4245
expect(result.every(t => t.stack === 'quarkus')).toBe(true);
4346
});
4447

@@ -49,7 +52,7 @@ describe('bakedInTemplates', () => {
4952

5053
it('filters by protocol correctly', () => {
5154
const result = listBakedInTemplates({ protocol: 'websocket' });
52-
expect(result.length).toBeGreaterThan(0);
55+
expect(result).toHaveLength(2);
5356
expect(result.every(t => t.protocol === 'websocket')).toBe(true);
5457
});
5558

@@ -60,8 +63,8 @@ describe('bakedInTemplates', () => {
6063

6164
it('filters by target correctly', () => {
6265
const result = listBakedInTemplates({ target: 'javascript' });
63-
expect(result.length).toBeGreaterThan(0);
64-
expect(result.every(t => t.target === 'javascript')).toBe(true);
66+
expect(result).toHaveLength(1);
67+
expect(result[0].target).toBe('javascript');
6568
});
6669

6770
it('returns empty array when target filter matches nothing', () => {
@@ -71,62 +74,49 @@ describe('bakedInTemplates', () => {
7174

7275
it('filters by combined type and protocol', () => {
7376
const result = listBakedInTemplates({ type: 'client', protocol: 'websocket' });
74-
expect(result.length).toBeGreaterThan(0);
77+
expect(result).toHaveLength(2);
7578
expect(result.every(t => t.type === 'client' && t.protocol === 'websocket')).toBe(true);
7679
});
7780

7881
it('filters by combined type, protocol, and target', () => {
7982
const result = listBakedInTemplates({ type: 'client', protocol: 'websocket', target: 'javascript' });
80-
expect(result.length).toBeGreaterThan(0);
81-
expect(result.every(t =>
82-
t.type === 'client' &&
83-
t.protocol === 'websocket' &&
84-
t.target === 'javascript'
85-
)).toBe(true);
83+
expect(result).toHaveLength(1);
84+
expect(result[0].name).toBe('fixture-template-client-ws-js');
8685
});
8786

8887
it('filters by combined type, protocol, target, and stack', () => {
89-
const result = listBakedInTemplates({
90-
type: 'client',
91-
protocol: 'websocket',
88+
const result = listBakedInTemplates({
89+
type: 'client',
90+
protocol: 'websocket',
9291
target: 'java',
9392
stack: 'quarkus'
9493
});
95-
expect(result.length).toBeGreaterThan(0);
96-
expect(result.every(t =>
97-
t.type === 'client' &&
98-
t.protocol === 'websocket' &&
99-
t.target === 'java' &&
100-
t.stack === 'quarkus'
101-
)).toBe(true);
94+
expect(result).toHaveLength(1);
95+
expect(result[0].name).toBe('fixture-template-client-ws-java');
10296
});
10397

10498
it('returns empty array when combined filters match nothing', () => {
105-
const result = listBakedInTemplates({
106-
type: 'client',
107-
protocol: 'nonexistent'
99+
const result = listBakedInTemplates({
100+
type: 'client',
101+
protocol: 'nonexistent'
108102
});
109103
expect(result).toEqual([]);
110104
});
111105

112106
it('handles templates without optional stack property', () => {
113-
const templatesWithoutStack = templates.filter(t => !t.stack);
114-
if (templatesWithoutStack.length > 0) {
115-
const result = listBakedInTemplates({ stack: 'quarkus' });
116-
// Should not include templates without stack property
117-
expect(result.every(t => t.stack === 'quarkus')).toBe(true);
118-
}
107+
const result = listBakedInTemplates({ stack: 'quarkus' });
108+
expect(result.every(t => t.stack === 'quarkus')).toBe(true);
109+
expect(result).toHaveLength(2);
119110
});
120111
});
121112

122113
describe('isCoreTemplate', () => {
123114
it('returns true for existing template name', () => {
124-
const existingTemplate = templates[0];
125-
expect(isCoreTemplate(existingTemplate.name)).toBe(true);
115+
expect(isCoreTemplate('fixture-template-client-ws-js')).toBe(true);
126116
});
127117

128118
it('returns true for all templates in the list', () => {
129-
templates.forEach(template => {
119+
fixtureTemplates.forEach(template => {
130120
expect(isCoreTemplate(template.name)).toBe(true);
131121
});
132122
});
@@ -148,48 +138,36 @@ describe('bakedInTemplates', () => {
148138
});
149139

150140
it('is case-sensitive', () => {
151-
const existingTemplate = templates[0];
152-
const caseVariation = existingTemplate.name.toUpperCase();
153-
if (caseVariation !== existingTemplate.name) {
154-
expect(isCoreTemplate(caseVariation)).toBe(false);
155-
}
141+
expect(isCoreTemplate('FIXTURE-TEMPLATE-CLIENT-WS-JS')).toBe(false);
156142
});
157143
});
158144

159145
describe('getTemplate', () => {
160146
it('returns template object with name and path for existing template', async () => {
161-
const existingTemplate = templates[0];
162-
const result = await getTemplate(existingTemplate.name);
163-
147+
const result = await getTemplate('fixture-template-client-ws-js');
164148
expect(result).toBeDefined();
165-
expect(result.name).toBe(existingTemplate.name);
149+
expect(result.name).toBe('fixture-template-client-ws-js');
166150
expect(result.path).toBeDefined();
167151
expect(typeof result.path).toBe('string');
168152
});
169153

170154
it('uses template path when available', async () => {
171-
const templateWithPath = templates.find(t => t.path);
172-
if (templateWithPath) {
173-
const result = await getTemplate(templateWithPath.name);
174-
expect(result.path).toBe(templateWithPath.path);
175-
}
155+
const result = await getTemplate('fixture-template-with-path');
156+
expect(result.path).toBe('/custom/path/to/template');
176157
});
177158

178159
it('falls back to bakedInTemplates directory when path is not provided', async () => {
179-
const templateWithoutPath = templates.find(t => !t.path);
180-
if (templateWithoutPath) {
181-
const result = await getTemplate(templateWithoutPath.name);
182-
const expectedPath = path.resolve(
183-
__dirname,
184-
'../lib/templates/bakedInTemplates',
185-
templateWithoutPath.name
186-
);
187-
expect(result.path).toBe(expectedPath);
188-
}
160+
const result = await getTemplate('fixture-template-client-ws-js');
161+
const expectedPath = path.resolve(
162+
__dirname,
163+
'../lib/templates/bakedInTemplates',
164+
'fixture-template-client-ws-js'
165+
);
166+
expect(result.path).toBe(expectedPath);
189167
});
190168

191169
it('handles all templates in the list', async () => {
192-
for (const template of templates) {
170+
for (const template of fixtureTemplates) {
193171
const result = await getTemplate(template.name);
194172
expect(result).toBeDefined();
195173
expect(result.name).toBe(template.name);
@@ -198,24 +176,24 @@ describe('bakedInTemplates', () => {
198176
}
199177
});
200178

201-
it('throws error for non-existing template', async () => {
202-
// Current implementation throws when template.name is accessed on undefined
203-
await expect(getTemplate('nonexistent-template')).rejects.toThrow();
179+
it('returns undefined for non-existing template', async () => {
180+
const result = await getTemplate('nonexistent-template');
181+
expect(result).toBeUndefined();
204182
});
205183

206-
it('throws error for empty string template name', async () => {
207-
// Current implementation will throw when template is not found
208-
await expect(getTemplate('')).rejects.toThrow();
184+
it('returns undefined for empty string template name', async () => {
185+
const result = await getTemplate('');
186+
expect(result).toBeUndefined();
209187
});
210188

211-
it('throws error for null template name', async () => {
212-
// Current implementation will throw when template is not found
213-
await expect(getTemplate(null)).rejects.toThrow();
189+
it('returns undefined for null template name', async () => {
190+
const result = await getTemplate(null);
191+
expect(result).toBeUndefined();
214192
});
215193

216-
it('throws error for undefined template name', async () => {
217-
// Current implementation will throw when template is not found
218-
await expect(getTemplate(undefined)).rejects.toThrow();
194+
it('returns undefined for undefined template name', async () => {
195+
const result = await getTemplate(undefined);
196+
expect(result).toBeUndefined();
219197
});
220198
});
221199
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[
2+
{
3+
"name": "fixture-template-client-ws-js",
4+
"type": "client",
5+
"protocol": "websocket",
6+
"target": "javascript"
7+
},
8+
{
9+
"name": "fixture-template-client-ws-java",
10+
"type": "client",
11+
"protocol": "websocket",
12+
"target": "java",
13+
"stack": "quarkus"
14+
},
15+
{
16+
"name": "fixture-template-with-path",
17+
"type": "client",
18+
"protocol": "kafka",
19+
"target": "java",
20+
"stack": "quarkus",
21+
"path": "/custom/path/to/template"
22+
}
23+
]

0 commit comments

Comments
 (0)