Skip to content

Commit a691543

Browse files
authored
Merge pull request #83 from bertdeblock/test-option
Support generating a corresponding test file via a `--test` option
2 parents d006837 + 94d9896 commit a691543

15 files changed

+234
-9
lines changed

src/cli.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
// type CommandDef,
66
type SubCommandsDef,
77
} from "citty";
8-
import { GemberError, logGemberErrors } from "./errors.js";
8+
import { GemberBugError, GemberError, logGemberErrors } from "./errors.js";
99
import { generators } from "./generators/generators.js";
1010
import { readOwnPackageJsonSync } from "./internal.js";
1111
import { logger } from "./logger.js";
@@ -61,8 +61,8 @@ const main = defineCommand({
6161
);
6262

6363
if (selectedGenerator === undefined) {
64-
throw new GemberError(
65-
`[BUG] Could not find generator \`${selectedGeneratorName}\`.`,
64+
throw new GemberBugError(
65+
`Could not find generator \`${selectedGeneratorName}\`.`,
6666
);
6767
}
6868

@@ -124,6 +124,31 @@ function generatorCommands(deprecated?: boolean): SubCommandsDef {
124124

125125
logGemberErrors(async () => {
126126
await generator.run(context.args);
127+
128+
if (context.args.test) {
129+
if (generator.isTestGenerator) {
130+
logger.warn(
131+
`You passed the \`--test\` option, but the \`${generator.name}\` generator is already a test generator.`,
132+
);
133+
} else if (generator.args.find((arg) => arg.name === "test")) {
134+
const testGeneratorName = `${generator.name}-test`;
135+
const testGenerator = generators.find(
136+
(g) => g.name === testGeneratorName,
137+
);
138+
139+
if (testGenerator) {
140+
await testGenerator.run(context.args);
141+
} else {
142+
throw new GemberBugError(
143+
`Could not find generator \`${testGeneratorName}\`.`,
144+
);
145+
}
146+
} else {
147+
logger.warn(
148+
`You passed the \`--test\` option, but the \`${generator.name}\` generator does not have a corresponding test generator.`,
149+
);
150+
}
151+
}
127152
});
128153
},
129154
};

src/errors.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import process from "node:process";
22
import { logger } from "./logger.js";
33

44
export class GemberError extends Error {}
5+
export class GemberBugError extends GemberError {
6+
constructor(message?: string, options?: ErrorOptions) {
7+
super(`[BUG] ${message}`, options);
8+
}
9+
}
510

611
export async function logGemberErrors(
712
func: () => Promise<void>,

src/generators/generator.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
export type Generator = {
2020
args: GeneratorArg[];
2121
description: string;
22+
isTestGenerator: boolean;
2223
name: string;
2324
run: (args: Args) => Promise<void>;
2425
};
@@ -36,6 +37,7 @@ export type GeneratorFile = {
3637
type GeneratorOptions = {
3738
args: GeneratorArgFactory[];
3839
description?: string;
40+
isTestGenerator?: boolean;
3941
modifyTargetFile?: ModifyTargetFile;
4042
modifyTemplateFile?: ModifyTemplateFile;
4143
name: string;
@@ -69,6 +71,7 @@ type Args = Record<string, any>;
6971
export function defineGenerator({
7072
args,
7173
description,
74+
isTestGenerator,
7275
modifyTargetFile,
7376
modifyTemplateFile,
7477
name: generatorName,
@@ -235,6 +238,7 @@ export function defineGenerator({
235238
return {
236239
args: generatorArgs,
237240
description: description ?? `Generate a new ${generatorName}`,
241+
isTestGenerator: isTestGenerator ?? false,
238242
name: generatorName,
239243
run,
240244
};
@@ -245,6 +249,7 @@ export function defineTestGenerator(
245249
): Generator {
246250
return defineGenerator({
247251
...options,
252+
isTestGenerator: true,
248253
modifyTargetFile: (targetFile, args) => {
249254
if (args.path === undefined && env.GEMBER_PATH === undefined) {
250255
targetFile.subDir = join(
@@ -344,6 +349,14 @@ export function path(): GeneratorArgFactory {
344349
});
345350
}
346351

352+
export function test(): GeneratorArgFactory {
353+
return (generatorName) => ({
354+
description: `Generate a corresponding ${generatorName}-test`,
355+
name: "test",
356+
type: "boolean",
357+
});
358+
}
359+
347360
export function typescript({
348361
gts = false,
349362
}: {

src/generators/generators.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
defineGenerator,
44
defineTestGenerator,
55
nested,
6+
test,
67
typescript,
78
type Generator,
89
} from "./generator.js";
@@ -15,6 +16,7 @@ export const generators: Generator[] = [
1516
description:
1617
"Generate a nested colocated component, e.g. `foo/bar/index.gts`",
1718
}),
19+
test(),
1820
typescript({ gts: true }),
1921
],
2022
name: "component",
@@ -27,7 +29,7 @@ export const generators: Generator[] = [
2729
}),
2830

2931
defineGenerator({
30-
args: [classBased(), typescript()],
32+
args: [classBased(), test(), typescript()],
3133
name: "helper",
3234
}),
3335

@@ -38,7 +40,7 @@ export const generators: Generator[] = [
3840
}),
3941

4042
defineGenerator({
41-
args: [classBased(), typescript()],
43+
args: [classBased(), test(), typescript()],
4244
name: "modifier",
4345
}),
4446

@@ -49,7 +51,7 @@ export const generators: Generator[] = [
4951
}),
5052

5153
defineGenerator({
52-
args: [typescript()],
54+
args: [test(), typescript()],
5355
name: "service",
5456
}),
5557

test/generators/acceptance-test.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,19 @@ it("generates a `.ts` acceptance-test at a custom path", async (ctx) => {
4949

5050
ctx.expect(content).toMatchSnapshot();
5151
});
52+
53+
it("destroys an acceptance-test", async (ctx) => {
54+
pkg = await Package.create("v2-addon");
55+
56+
await pkg.gember("acceptance-test", "foo");
57+
58+
ctx
59+
.expect(await pkg.pathExists("tests/acceptance/foo-test.js"))
60+
.to.equal(true);
61+
62+
await pkg.gember("acceptance-test", "foo", "--destroy");
63+
64+
ctx
65+
.expect(await pkg.pathExists("tests/acceptance/foo-test.js"))
66+
.to.equal(false);
67+
});

test/generators/component-test.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,19 @@ it("generates a `.gts` component-test at a custom path", async (ctx) => {
4848

4949
ctx.expect(content).toMatchSnapshot();
5050
});
51+
52+
it("destroys a component-test", async (ctx) => {
53+
pkg = await Package.create("v2-addon");
54+
55+
await pkg.gember("component-test", "foo");
56+
57+
ctx
58+
.expect(await pkg.pathExists("tests/integration/components/foo-test.gjs"))
59+
.to.equal(true);
60+
61+
await pkg.gember("component-test", "foo", "--destroy");
62+
63+
ctx
64+
.expect(await pkg.pathExists("tests/integration/components/foo-test.gjs"))
65+
.to.equal(false);
66+
});

test/generators/component.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,26 @@ it("generates a nested colocated template-only `.gjs` component", async (ctx) =>
8484

8585
ctx.expect(content).toMatchSnapshot();
8686
});
87+
88+
it("generates a corresponding component-test", async (ctx) => {
89+
pkg = await Package.create("v2-addon");
90+
91+
await pkg.gember("component", "foo", "--test");
92+
93+
ctx.expect(await pkg.pathExists("src/components/foo.gjs")).to.equal(true);
94+
ctx
95+
.expect(await pkg.pathExists("tests/integration/components/foo-test.gjs"))
96+
.to.equal(true);
97+
});
98+
99+
it("destroys a component", async (ctx) => {
100+
pkg = await Package.create("v2-addon");
101+
102+
await pkg.gember("component", "foo");
103+
104+
ctx.expect(await pkg.pathExists("src/components/foo.gjs")).to.equal(true);
105+
106+
await pkg.gember("component", "foo", "--destroy");
107+
108+
ctx.expect(await pkg.pathExists("src/components/foo.gjs")).to.equal(false);
109+
});

test/generators/helper-test.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,19 @@ it("generates a `.gts` helper-test at a custom path", async (ctx) => {
4444

4545
ctx.expect(content).toMatchSnapshot();
4646
});
47+
48+
it("destroys a helper-test", async (ctx) => {
49+
pkg = await Package.create("v2-addon");
50+
51+
await pkg.gember("helper-test", "foo");
52+
53+
ctx
54+
.expect(await pkg.pathExists("tests/integration/helpers/foo-test.gjs"))
55+
.to.equal(true);
56+
57+
await pkg.gember("helper-test", "foo", "--destroy");
58+
59+
ctx
60+
.expect(await pkg.pathExists("tests/integration/helpers/foo-test.gjs"))
61+
.to.equal(false);
62+
});

test/generators/helper.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,26 @@ it("generates a nested function-based `.js` helper", async (ctx) => {
7474

7575
ctx.expect(content).toMatchSnapshot();
7676
});
77+
78+
it("generates a corresponding helper-test", async (ctx) => {
79+
pkg = await Package.create("v2-addon");
80+
81+
await pkg.gember("helper", "foo", "--test");
82+
83+
ctx.expect(await pkg.pathExists("src/helpers/foo.js")).to.equal(true);
84+
ctx
85+
.expect(await pkg.pathExists("tests/integration/helpers/foo-test.gjs"))
86+
.to.equal(true);
87+
});
88+
89+
it("destroys a helper", async (ctx) => {
90+
pkg = await Package.create("v2-addon");
91+
92+
await pkg.gember("helper", "foo");
93+
94+
ctx.expect(await pkg.pathExists("src/helpers/foo.js")).to.equal(true);
95+
96+
await pkg.gember("helper", "foo", "--destroy");
97+
98+
ctx.expect(await pkg.pathExists("src/helpers/foo.js")).to.equal(false);
99+
});

0 commit comments

Comments
 (0)