Skip to content

Commit 1c63fa1

Browse files
committed
Fixing an error message for the config file.
1 parent 69d55a4 commit 1c63fa1

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

src/BaseCommand.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export abstract class BaseCommand implements CommandInterface {
3535
const requiresProject = (this.constructor as any).requiresProject;
3636

3737
if (requiresProject && !this.projectRoot) {
38-
this.error('This command requires to be run within an app project (app.yml not found).', 1);
38+
this.error(`This command requires to be run within an app project (${this.cli.name}.yml not found).`, 1);
3939
return; // TS doesn't know error exits
4040
}
4141

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3+
import { CLI } from '../../../src/CLI.js';
4+
import { BaseCommand } from '../../../src/BaseCommand.js';
5+
import * as ConfigUtils from '../../../src/utils/config.js';
6+
import pc from 'picocolors';
7+
import process from 'node:process';
8+
9+
vi.mock('../../../src/utils/config.js');
10+
11+
class TestProjectRequiredCommand extends BaseCommand {
12+
static requiresProject = true;
13+
async run() { }
14+
}
15+
16+
describe('Config Loading & Error Messaging', () => {
17+
let processExitSpy: any;
18+
let consoleLogSpy: any;
19+
20+
beforeEach(() => {
21+
vi.clearAllMocks();
22+
processExitSpy = vi.spyOn(process, 'exit').mockImplementation((() => { }) as any);
23+
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
24+
});
25+
26+
afterEach(() => {
27+
processExitSpy.mockRestore();
28+
consoleLogSpy.mockRestore();
29+
});
30+
31+
it('should propagate command name to config loading', async () => {
32+
const cli = new CLI({ commandName: 'astrical' });
33+
const command = new TestProjectRequiredCommand(cli);
34+
35+
// Mock finding root so we don't error out immediately on missing root check logic if we want to proceed,
36+
// but wait, we want to verify findProjectRoot call.
37+
(ConfigUtils.findProjectRoot as any).mockResolvedValue('/some/path');
38+
(ConfigUtils.loadConfig as any).mockResolvedValue({});
39+
40+
await command.init();
41+
42+
expect(ConfigUtils.findProjectRoot).toHaveBeenCalledWith('astrical', expect.any(String));
43+
expect(ConfigUtils.loadConfig).toHaveBeenCalledWith('astrical', '/some/path');
44+
});
45+
46+
it('should show correct error message when project root is missing for named command', async () => {
47+
const cli = new CLI({ commandName: 'astrical' });
48+
const command = new TestProjectRequiredCommand(cli);
49+
50+
(ConfigUtils.findProjectRoot as any).mockResolvedValue(null);
51+
52+
await command.init();
53+
54+
expect(consoleLogSpy).toHaveBeenCalledWith(
55+
expect.stringContaining(pc.red('✖ This command requires to be run within an app project (astrical.yml not found).'))
56+
);
57+
expect(process.exit).toHaveBeenCalledWith(1);
58+
});
59+
60+
it('should show default error message when using default name', async () => {
61+
const cli = new CLI(); // default 'app'
62+
const command = new TestProjectRequiredCommand(cli);
63+
64+
(ConfigUtils.findProjectRoot as any).mockResolvedValue(null);
65+
66+
await command.init();
67+
68+
expect(consoleLogSpy).toHaveBeenCalledWith(
69+
expect.stringContaining(pc.red('✖ This command requires to be run within an app project (app.yml not found).'))
70+
);
71+
});
72+
});

0 commit comments

Comments
 (0)