init.test.ts86 lines · main
1import assert from 'node:assert/strict';
2import { describe, test } from 'node:test';
3
4import { parseInitArgs, TEMPLATES } from './init.js';
5
6describe('parseInitArgs', () => {
7 test('defaults to blank template + no name + no force', () => {
8 const args = parseInitArgs([]);
9 assert.equal(args.template, 'blank');
10 assert.equal(args.name, undefined);
11 assert.equal(args.force, false);
12 });
13
14 test('positional name', () => {
15 assert.equal(parseInitArgs(['my-project']).name, 'my-project');
16 });
17
18 test('--name overrides positional', () => {
19 assert.equal(parseInitArgs(['ignored', '--name', 'real']).name, 'real');
20 });
21
22 test('--template <name> picks a known template', () => {
23 assert.equal(parseInitArgs(['--template', 'todo-app']).template, 'todo-app');
24 assert.equal(parseInitArgs(['--template', 'chat']).template, 'chat');
25 });
26
27 test('--template=<name> shorthand', () => {
28 assert.equal(parseInitArgs(['--template=todo-app']).template, 'todo-app');
29 });
30
31 test('--template carries unknown names through (rejected at runtime)', () => {
32 // Defer reject to runInit so the error message can list available
33 // templates. parseInitArgs returns the literal so the caller can
34 // detect the mismatch.
35 assert.equal(parseInitArgs(['--template', 'mystery']).template, 'mystery');
36 });
37
38 test('--force flag', () => {
39 assert.equal(parseInitArgs(['--force']).force, true);
40 });
41
42 test('--list-templates', () => {
43 assert.equal(parseInitArgs(['--list-templates']).list, true);
44 });
45});
46
47describe('TEMPLATES', () => {
48 test('every template has a briven/schema.ts and at least one function', () => {
49 for (const [name, tpl] of Object.entries(TEMPLATES)) {
50 assert.match(tpl.description, /.+/);
51 assert.ok(tpl.files['briven/schema.ts'], `${name} should have briven/schema.ts`);
52 const fnFiles = Object.keys(tpl.files).filter((p) => p.startsWith('briven/functions/'));
53 assert.ok(fnFiles.length >= 1, `${name} should have functions`);
54 }
55 });
56
57 test('todo-app template ships the expected four mutations + listing', () => {
58 const t = TEMPLATES['todo-app'];
59 assert.ok(t.files['briven/functions/listTodos.ts']);
60 assert.ok(t.files['briven/functions/createTodo.ts']);
61 assert.ok(t.files['briven/functions/toggleTodo.ts']);
62 assert.ok(t.files['briven/functions/deleteTodo.ts']);
63 });
64
65 test('chat template ships rooms + messages + the four functions', () => {
66 const t = TEMPLATES.chat;
67 const schema = t.files['briven/schema.ts'];
68 assert.ok(schema);
69 assert.match(schema, /rooms/);
70 assert.match(schema, /messages/);
71 assert.ok(t.files['briven/functions/listRooms.ts']);
72 assert.ok(t.files['briven/functions/listMessages.ts']);
73 assert.ok(t.files['briven/functions/createRoom.ts']);
74 assert.ok(t.files['briven/functions/sendMessage.ts']);
75 });
76
77 test('every function source imports from @briven/cli/server', () => {
78 for (const tpl of Object.values(TEMPLATES)) {
79 for (const [path, src] of Object.entries(tpl.files)) {
80 if (path.startsWith('briven/functions/') && src) {
81 assert.match(src, /@briven\/cli\/server/, `${path} should import @briven/cli/server`);
82 }
83 }
84 }
85 });
86});