Skip to content

Commit 13cb286

Browse files
committed
test: cursor-rule
1 parent 768be3d commit 13cb286

1 file changed

Lines changed: 163 additions & 0 deletions

File tree

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import checkIsVscodeProject from 'lib/check-is-vscode-project.ts';
2+
import makeCursorFolder from 'lib/make-cursor-folder.ts';
3+
import { cursorRuleCli } from 'src/commands/cursor-rule.ts';
4+
5+
jest.mock('lib/check-is-vscode-project.ts');
6+
jest.mock('lib/make-cursor-folder.ts');
7+
8+
const mockCheckIsVscodeProject = checkIsVscodeProject as jest.MockedFunction<typeof checkIsVscodeProject>;
9+
const mockMakeCursorFolder = makeCursorFolder as jest.MockedFunction<typeof makeCursorFolder>;
10+
11+
describe('cursorRuleCli', () => {
12+
let consoleSpy: jest.SpyInstance;
13+
14+
beforeEach(() => {
15+
jest.clearAllMocks();
16+
17+
consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
18+
});
19+
20+
afterEach(() => {
21+
consoleSpy.mockRestore();
22+
});
23+
24+
describe('Command Configuration', () => {
25+
it('should have correct command name', () => {
26+
expect(cursorRuleCli.name()).toBe('cursor-rule');
27+
});
28+
29+
it('should have correct alias', () => {
30+
expect(cursorRuleCli.alias()).toBe('cr');
31+
});
32+
33+
it('should have correct description', () => {
34+
expect(cursorRuleCli.description()).toBe('Setup Cursor AI rules configuration');
35+
});
36+
});
37+
38+
describe('Command Execution', () => {
39+
it('should exit early when not in a VSCode project', async () => {
40+
mockCheckIsVscodeProject.mockReturnValue(false);
41+
42+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
43+
44+
expect(mockCheckIsVscodeProject).toHaveBeenCalledTimes(1);
45+
expect(mockMakeCursorFolder).not.toHaveBeenCalled();
46+
47+
expect(consoleSpy).toHaveBeenCalledWith('🎯 Setting up Cursor AI rules...\n');
48+
expect(consoleSpy).toHaveBeenCalledWith('🥲 .vscode directory not found\n');
49+
expect(consoleSpy).toHaveBeenCalledWith('Is this a cursor project?\n');
50+
expect(consoleSpy).toHaveBeenCalledWith('Please run `ics cursor-rule` in a cursor project\n');
51+
});
52+
53+
it('should exit early when cursor folder creation fails', async () => {
54+
mockCheckIsVscodeProject.mockReturnValue(true);
55+
mockMakeCursorFolder.mockResolvedValue(false);
56+
57+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
58+
59+
expect(mockCheckIsVscodeProject).toHaveBeenCalledTimes(1);
60+
expect(mockMakeCursorFolder).toHaveBeenCalledWith('.cursor/rules');
61+
62+
expect(consoleSpy).toHaveBeenCalledWith('🎯 Setting up Cursor AI rules...\n');
63+
expect(consoleSpy).toHaveBeenCalledWith('🥲 Cursor folder not created\n');
64+
});
65+
66+
it('should complete successfully when all conditions are met', async () => {
67+
mockCheckIsVscodeProject.mockReturnValue(true);
68+
mockMakeCursorFolder.mockResolvedValue(true);
69+
70+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
71+
72+
expect(mockCheckIsVscodeProject).toHaveBeenCalledTimes(1);
73+
expect(mockMakeCursorFolder).toHaveBeenCalledWith('.cursor/rules');
74+
75+
expect(consoleSpy).toHaveBeenCalledWith('🎯 Setting up Cursor AI rules...\n');
76+
expect(consoleSpy).not.toHaveBeenCalledWith('🥲 .vscode directory not found\n');
77+
expect(consoleSpy).not.toHaveBeenCalledWith('🥲 Cursor folder not created\n');
78+
});
79+
});
80+
81+
describe('Error Handling', () => {
82+
it('should handle checkIsVscodeProject throwing an error', async () => {
83+
const error = new Error('File system error');
84+
mockCheckIsVscodeProject.mockImplementation(() => {
85+
throw error;
86+
});
87+
88+
await expect(cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule'])).rejects.toThrow('File system error');
89+
90+
expect(mockCheckIsVscodeProject).toHaveBeenCalledTimes(1);
91+
expect(mockMakeCursorFolder).not.toHaveBeenCalled();
92+
});
93+
94+
it('should handle makeCursorFolder throwing an error', async () => {
95+
mockCheckIsVscodeProject.mockReturnValue(true);
96+
const error = new Error('Permission denied');
97+
mockMakeCursorFolder.mockRejectedValue(error);
98+
99+
await expect(cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule'])).rejects.toThrow('Permission denied');
100+
101+
expect(mockCheckIsVscodeProject).toHaveBeenCalledTimes(1);
102+
expect(mockMakeCursorFolder).toHaveBeenCalledWith('.cursor/rules');
103+
});
104+
});
105+
106+
describe('Integration with Dependencies', () => {
107+
it('should call checkIsVscodeProject before makeCursorFolder', async () => {
108+
const callOrder: string[] = [];
109+
110+
mockCheckIsVscodeProject.mockImplementation(() => {
111+
callOrder.push('checkIsVscodeProject');
112+
return true;
113+
});
114+
115+
mockMakeCursorFolder.mockImplementation(async () => {
116+
callOrder.push('makeCursorFolder');
117+
return true;
118+
});
119+
120+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
121+
122+
expect(callOrder).toEqual(['checkIsVscodeProject', 'makeCursorFolder']);
123+
});
124+
125+
it('should pass correct directory path to makeCursorFolder', async () => {
126+
mockCheckIsVscodeProject.mockReturnValue(true);
127+
mockMakeCursorFolder.mockResolvedValue(true);
128+
129+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
130+
131+
expect(mockMakeCursorFolder).toHaveBeenCalledWith('.cursor/rules');
132+
expect(mockMakeCursorFolder).toHaveBeenCalledTimes(1);
133+
});
134+
});
135+
136+
describe('Console Output', () => {
137+
it('should always show initial setup message', async () => {
138+
mockCheckIsVscodeProject.mockReturnValue(false);
139+
140+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
141+
142+
expect(consoleSpy).toHaveBeenNthCalledWith(1, '🎯 Setting up Cursor AI rules...\n');
143+
});
144+
145+
it('should show appropriate messages for each failure scenario', async () => {
146+
mockCheckIsVscodeProject.mockReturnValue(false);
147+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
148+
149+
expect(consoleSpy).toHaveBeenCalledWith('🥲 .vscode directory not found\n');
150+
expect(consoleSpy).toHaveBeenCalledWith('Is this a cursor project?\n');
151+
expect(consoleSpy).toHaveBeenCalledWith('Please run `ics cursor-rule` in a cursor project\n');
152+
153+
jest.clearAllMocks();
154+
consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
155+
156+
mockCheckIsVscodeProject.mockReturnValue(true);
157+
mockMakeCursorFolder.mockResolvedValue(false);
158+
await cursorRuleCli.parseAsync(['node', 'test', 'cursor-rule']);
159+
160+
expect(consoleSpy).toHaveBeenCalledWith('🥲 Cursor folder not created\n');
161+
});
162+
});
163+
});

0 commit comments

Comments
 (0)