alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
56 lines (50 loc) • 1.87 kB
text/typescript
import { $inject, z } from "alepha";
import { $command } from "alepha/command";
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
import { ProjectScaffolder } from "../services/ProjectScaffolder.ts";
export class TestCommand {
protected readonly utils = $inject(AlephaCliUtils);
protected readonly scaffolder = $inject(ProjectScaffolder);
public readonly test = $command({
name: "test",
description:
"Run tests using Vitest. Pass a filter to run only matching specs, e.g. `alepha test user` or `alepha test test/auth.spec.ts`",
args: z
.text({
title: "filter",
description: "Only run spec files whose path matches this string",
})
.optional(),
flags: z.object({
config: z
.string()
.meta({ alias: "c" })
.describe("Path to Vitest config file")
.optional(),
}),
env: z.object({
VITEST_ARGS: z
.string()
.describe("Additional arguments to pass to Vitest. E.g., --coverage")
.default("")
.optional(),
}),
handler: async ({ run, root, flags, env, args }) => {
await this.scaffolder.ensureConfig(root, {
tsconfigJson: true,
});
const config = flags.config ? `--config=${flags.config}` : "";
// The positional arg is forwarded to Vitest as a filename filter —
// `alepha test user` runs only specs whose path matches "user".
const filter = args ? JSON.stringify(args) : "";
// Vitest ships embedded in `alepha` (paired with vite) — resolve and
// run it from alepha's own install, so the project never declares it.
const vitest = this.utils.resolveBin("vitest", "vitest");
await run(
`node "${vitest}" run ${config} ${filter} ${env.VITEST_ARGS}`
.replace(/\s+/g, " ")
.trim(),
);
},
});
}