projax 3.3.36 → 3.3.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,405 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs"));
37
+ const child_process_1 = require("child_process");
38
+ const scanner_1 = require("../scanner");
39
+ // Mock modules
40
+ jest.mock('fs');
41
+ jest.mock('child_process');
42
+ const mockedFs = fs;
43
+ const mockedExecSync = child_process_1.execSync;
44
+ describe('scanner', () => {
45
+ beforeEach(() => {
46
+ jest.clearAllMocks();
47
+ mockedFs.existsSync.mockReturnValue(false);
48
+ // Reset the singleton
49
+ require('../database').dbManager = null;
50
+ });
51
+ describe('scanProject', () => {
52
+ it('should scan a project and return results', () => {
53
+ const mockScanResponse = {
54
+ project: {
55
+ id: 1,
56
+ name: 'Test Project',
57
+ path: '/test/path',
58
+ description: null,
59
+ framework: 'jest',
60
+ last_scanned: Date.now(),
61
+ created_at: Date.now() - 10000,
62
+ },
63
+ testsFound: 3,
64
+ tests: [
65
+ {
66
+ id: 1,
67
+ project_id: 1,
68
+ file_path: '/test/path/src/__tests__/file1.test.ts',
69
+ framework: 'jest',
70
+ status: null,
71
+ last_run: null,
72
+ created_at: Date.now(),
73
+ },
74
+ {
75
+ id: 2,
76
+ project_id: 1,
77
+ file_path: '/test/path/src/__tests__/file2.test.ts',
78
+ framework: 'jest',
79
+ status: null,
80
+ last_run: null,
81
+ created_at: Date.now(),
82
+ },
83
+ {
84
+ id: 3,
85
+ project_id: 1,
86
+ file_path: '/test/path/src/utils/helper.spec.ts',
87
+ framework: 'jest',
88
+ status: null,
89
+ last_run: null,
90
+ created_at: Date.now(),
91
+ },
92
+ ],
93
+ };
94
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResponse));
95
+ const result = (0, scanner_1.scanProject)(1);
96
+ expect(result.project.id).toBe(1);
97
+ expect(result.testsFound).toBe(3);
98
+ expect(result.tests.length).toBe(3);
99
+ expect(result.project.framework).toBe('jest');
100
+ });
101
+ it('should handle project with no tests found', () => {
102
+ const mockScanResponse = {
103
+ project: {
104
+ id: 1,
105
+ name: 'Empty Project',
106
+ path: '/test/empty',
107
+ description: null,
108
+ framework: null,
109
+ last_scanned: Date.now(),
110
+ created_at: Date.now(),
111
+ },
112
+ testsFound: 0,
113
+ tests: [],
114
+ };
115
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResponse));
116
+ const result = (0, scanner_1.scanProject)(1);
117
+ expect(result.testsFound).toBe(0);
118
+ expect(result.tests).toEqual([]);
119
+ });
120
+ it('should update last_scanned timestamp', () => {
121
+ const mockScanResponse = {
122
+ project: {
123
+ id: 1,
124
+ name: 'Test Project',
125
+ path: '/test/path',
126
+ description: null,
127
+ framework: 'vitest',
128
+ last_scanned: Date.now(),
129
+ created_at: Date.now() - 100000,
130
+ },
131
+ testsFound: 1,
132
+ tests: [],
133
+ };
134
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResponse));
135
+ const result = (0, scanner_1.scanProject)(1);
136
+ expect(result.project.last_scanned).not.toBeNull();
137
+ expect(result.project.last_scanned).toBeGreaterThan(Date.now() - 1000);
138
+ });
139
+ it('should detect and set framework during scan', () => {
140
+ const mockScanResponse = {
141
+ project: {
142
+ id: 1,
143
+ name: 'Test Project',
144
+ path: '/test/path',
145
+ description: null,
146
+ framework: 'mocha',
147
+ last_scanned: Date.now(),
148
+ created_at: Date.now(),
149
+ },
150
+ testsFound: 1,
151
+ tests: [
152
+ {
153
+ id: 1,
154
+ project_id: 1,
155
+ file_path: '/test/path/test/file.spec.js',
156
+ framework: 'mocha',
157
+ status: null,
158
+ last_run: null,
159
+ created_at: Date.now(),
160
+ },
161
+ ],
162
+ };
163
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResponse));
164
+ const result = (0, scanner_1.scanProject)(1);
165
+ expect(result.project.framework).toBe('mocha');
166
+ expect(result.tests[0].framework).toBe('mocha');
167
+ });
168
+ it('should handle API errors', () => {
169
+ mockedExecSync.mockImplementation(() => {
170
+ throw new Error('API request failed');
171
+ });
172
+ expect(() => (0, scanner_1.scanProject)(1)).toThrow('API request failed');
173
+ });
174
+ it('should handle non-existent project', () => {
175
+ mockedExecSync.mockImplementation(() => {
176
+ const error = new Error('Command failed: curl');
177
+ error.message = 'Command failed: curl ... 404';
178
+ throw error;
179
+ });
180
+ expect(() => (0, scanner_1.scanProject)(999)).toThrow();
181
+ });
182
+ });
183
+ describe('scanAllProjects', () => {
184
+ it('should scan all projects and return results', () => {
185
+ const mockScanResults = [
186
+ {
187
+ project: {
188
+ id: 1,
189
+ name: 'Project 1',
190
+ path: '/path/1',
191
+ description: null,
192
+ framework: 'jest',
193
+ last_scanned: Date.now(),
194
+ created_at: Date.now(),
195
+ },
196
+ testsFound: 2,
197
+ tests: [
198
+ {
199
+ id: 1,
200
+ project_id: 1,
201
+ file_path: '/path/1/test1.test.ts',
202
+ framework: 'jest',
203
+ status: null,
204
+ last_run: null,
205
+ created_at: Date.now(),
206
+ },
207
+ {
208
+ id: 2,
209
+ project_id: 1,
210
+ file_path: '/path/1/test2.test.ts',
211
+ framework: 'jest',
212
+ status: null,
213
+ last_run: null,
214
+ created_at: Date.now(),
215
+ },
216
+ ],
217
+ },
218
+ {
219
+ project: {
220
+ id: 2,
221
+ name: 'Project 2',
222
+ path: '/path/2',
223
+ description: null,
224
+ framework: 'vitest',
225
+ last_scanned: Date.now(),
226
+ created_at: Date.now(),
227
+ },
228
+ testsFound: 1,
229
+ tests: [
230
+ {
231
+ id: 3,
232
+ project_id: 2,
233
+ file_path: '/path/2/test.spec.ts',
234
+ framework: 'vitest',
235
+ status: null,
236
+ last_run: null,
237
+ created_at: Date.now(),
238
+ },
239
+ ],
240
+ },
241
+ ];
242
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResults));
243
+ const results = (0, scanner_1.scanAllProjects)();
244
+ expect(results.length).toBe(2);
245
+ expect(results[0].project.name).toBe('Project 1');
246
+ expect(results[0].testsFound).toBe(2);
247
+ expect(results[1].project.name).toBe('Project 2');
248
+ expect(results[1].testsFound).toBe(1);
249
+ });
250
+ it('should handle empty project list', () => {
251
+ mockedExecSync.mockReturnValue(JSON.stringify([]));
252
+ const results = (0, scanner_1.scanAllProjects)();
253
+ expect(results).toEqual([]);
254
+ });
255
+ it('should handle projects with different test frameworks', () => {
256
+ const mockScanResults = [
257
+ {
258
+ project: {
259
+ id: 1,
260
+ name: 'Jest Project',
261
+ path: '/jest',
262
+ description: null,
263
+ framework: 'jest',
264
+ last_scanned: Date.now(),
265
+ created_at: Date.now(),
266
+ },
267
+ testsFound: 1,
268
+ tests: [],
269
+ },
270
+ {
271
+ project: {
272
+ id: 2,
273
+ name: 'Vitest Project',
274
+ path: '/vitest',
275
+ description: null,
276
+ framework: 'vitest',
277
+ last_scanned: Date.now(),
278
+ created_at: Date.now(),
279
+ },
280
+ testsFound: 1,
281
+ tests: [],
282
+ },
283
+ {
284
+ project: {
285
+ id: 3,
286
+ name: 'Mocha Project',
287
+ path: '/mocha',
288
+ description: null,
289
+ framework: 'mocha',
290
+ last_scanned: Date.now(),
291
+ created_at: Date.now(),
292
+ },
293
+ testsFound: 1,
294
+ tests: [],
295
+ },
296
+ ];
297
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResults));
298
+ const results = (0, scanner_1.scanAllProjects)();
299
+ expect(results.length).toBe(3);
300
+ expect(results[0].project.framework).toBe('jest');
301
+ expect(results[1].project.framework).toBe('vitest');
302
+ expect(results[2].project.framework).toBe('mocha');
303
+ });
304
+ it('should handle some projects with no tests', () => {
305
+ const mockScanResults = [
306
+ {
307
+ project: {
308
+ id: 1,
309
+ name: 'Project with tests',
310
+ path: '/path/1',
311
+ description: null,
312
+ framework: 'jest',
313
+ last_scanned: Date.now(),
314
+ created_at: Date.now(),
315
+ },
316
+ testsFound: 2,
317
+ tests: [],
318
+ },
319
+ {
320
+ project: {
321
+ id: 2,
322
+ name: 'Project without tests',
323
+ path: '/path/2',
324
+ description: null,
325
+ framework: null,
326
+ last_scanned: Date.now(),
327
+ created_at: Date.now(),
328
+ },
329
+ testsFound: 0,
330
+ tests: [],
331
+ },
332
+ ];
333
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResults));
334
+ const results = (0, scanner_1.scanAllProjects)();
335
+ expect(results.length).toBe(2);
336
+ expect(results[0].testsFound).toBe(2);
337
+ expect(results[1].testsFound).toBe(0);
338
+ });
339
+ it('should update all projects last_scanned timestamp', () => {
340
+ const mockScanResults = [
341
+ {
342
+ project: {
343
+ id: 1,
344
+ name: 'Project 1',
345
+ path: '/path/1',
346
+ description: null,
347
+ framework: null,
348
+ last_scanned: Date.now(),
349
+ created_at: Date.now() - 100000,
350
+ },
351
+ testsFound: 0,
352
+ tests: [],
353
+ },
354
+ {
355
+ project: {
356
+ id: 2,
357
+ name: 'Project 2',
358
+ path: '/path/2',
359
+ description: null,
360
+ framework: null,
361
+ last_scanned: Date.now(),
362
+ created_at: Date.now() - 100000,
363
+ },
364
+ testsFound: 0,
365
+ tests: [],
366
+ },
367
+ ];
368
+ mockedExecSync.mockReturnValue(JSON.stringify(mockScanResults));
369
+ const results = (0, scanner_1.scanAllProjects)();
370
+ results.forEach(result => {
371
+ expect(result.project.last_scanned).not.toBeNull();
372
+ expect(result.project.last_scanned).toBeGreaterThan(Date.now() - 1000);
373
+ });
374
+ });
375
+ it('should handle API errors', () => {
376
+ mockedExecSync.mockImplementation(() => {
377
+ throw new Error('API request failed');
378
+ });
379
+ expect(() => (0, scanner_1.scanAllProjects)()).toThrow('API request failed');
380
+ });
381
+ });
382
+ describe('ScanResult type', () => {
383
+ it('should have correct structure', () => {
384
+ const scanResult = {
385
+ project: {
386
+ id: 1,
387
+ name: 'Test',
388
+ path: '/test',
389
+ description: null,
390
+ framework: null,
391
+ last_scanned: null,
392
+ created_at: Date.now(),
393
+ },
394
+ testsFound: 0,
395
+ tests: [],
396
+ };
397
+ expect(scanResult).toHaveProperty('project');
398
+ expect(scanResult).toHaveProperty('testsFound');
399
+ expect(scanResult).toHaveProperty('tests');
400
+ expect(scanResult.project).toHaveProperty('id');
401
+ expect(scanResult.project).toHaveProperty('name');
402
+ expect(scanResult.project).toHaveProperty('path');
403
+ });
404
+ });
405
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs"));
37
+ const child_process_1 = require("child_process");
38
+ const settings_1 = require("../settings");
39
+ // Mock modules
40
+ jest.mock('fs');
41
+ jest.mock('child_process');
42
+ const mockedFs = fs;
43
+ const mockedExecSync = child_process_1.execSync;
44
+ describe('settings', () => {
45
+ beforeEach(() => {
46
+ jest.clearAllMocks();
47
+ mockedFs.existsSync.mockReturnValue(false);
48
+ // Reset the singleton
49
+ require('../database').dbManager = null;
50
+ });
51
+ describe('getSetting', () => {
52
+ it('should get a setting value', () => {
53
+ const settings = {
54
+ 'editor.type': 'vscode',
55
+ 'browser.type': 'chrome',
56
+ };
57
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
58
+ const result = (0, settings_1.getSetting)('editor.type');
59
+ expect(result).toBe('vscode');
60
+ });
61
+ it('should return null for non-existent setting', () => {
62
+ mockedExecSync.mockReturnValue(JSON.stringify({}));
63
+ const result = (0, settings_1.getSetting)('nonexistent');
64
+ expect(result).toBeNull();
65
+ });
66
+ });
67
+ describe('setSetting', () => {
68
+ it('should set a setting value', () => {
69
+ mockedExecSync.mockReturnValue('');
70
+ expect(() => (0, settings_1.setSetting)('editor.type', 'cursor')).not.toThrow();
71
+ expect(mockedExecSync).toHaveBeenCalled();
72
+ });
73
+ });
74
+ describe('getAllSettings', () => {
75
+ it('should get all settings', () => {
76
+ const settings = {
77
+ 'editor.type': 'vscode',
78
+ 'browser.type': 'chrome',
79
+ 'editor.customPath': '/path/to/editor',
80
+ };
81
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
82
+ const result = (0, settings_1.getAllSettings)();
83
+ expect(result).toEqual(settings);
84
+ expect(Object.keys(result).length).toBe(3);
85
+ });
86
+ it('should return empty object when no settings exist', () => {
87
+ mockedExecSync.mockReturnValue(JSON.stringify({}));
88
+ const result = (0, settings_1.getAllSettings)();
89
+ expect(result).toEqual({});
90
+ });
91
+ });
92
+ describe('getEditorSettings', () => {
93
+ it('should get editor settings with default values', () => {
94
+ mockedExecSync.mockReturnValue(JSON.stringify({}));
95
+ const result = (0, settings_1.getEditorSettings)();
96
+ expect(result.type).toBe('vscode');
97
+ expect(result.customPath).toBeUndefined();
98
+ });
99
+ it('should get editor settings with custom values', () => {
100
+ const settings = {
101
+ 'editor.type': 'cursor',
102
+ 'editor.customPath': '/path/to/cursor',
103
+ };
104
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
105
+ const result = (0, settings_1.getEditorSettings)();
106
+ expect(result.type).toBe('cursor');
107
+ expect(result.customPath).toBe('/path/to/cursor');
108
+ });
109
+ it('should handle only type being set', () => {
110
+ const settings = {
111
+ 'editor.type': 'zed',
112
+ };
113
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
114
+ const result = (0, settings_1.getEditorSettings)();
115
+ expect(result.type).toBe('zed');
116
+ expect(result.customPath).toBeUndefined();
117
+ });
118
+ it('should support all editor types', () => {
119
+ const editorTypes = ['vscode', 'cursor', 'windsurf', 'zed', 'custom'];
120
+ editorTypes.forEach(type => {
121
+ const settings = { 'editor.type': type };
122
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
123
+ const result = (0, settings_1.getEditorSettings)();
124
+ expect(result.type).toBe(type);
125
+ });
126
+ });
127
+ });
128
+ describe('setEditorSettings', () => {
129
+ it('should set editor type', () => {
130
+ mockedExecSync.mockReturnValue('');
131
+ const settings = { type: 'cursor' };
132
+ expect(() => (0, settings_1.setEditorSettings)(settings)).not.toThrow();
133
+ expect(mockedExecSync).toHaveBeenCalled();
134
+ });
135
+ it('should set editor type and custom path', () => {
136
+ mockedExecSync.mockReturnValue('');
137
+ const settings = {
138
+ type: 'custom',
139
+ customPath: '/usr/local/bin/myeditor',
140
+ };
141
+ expect(() => (0, settings_1.setEditorSettings)(settings)).not.toThrow();
142
+ expect(mockedExecSync).toHaveBeenCalledTimes(2);
143
+ });
144
+ it('should handle setting without custom path', () => {
145
+ mockedExecSync.mockReturnValue('');
146
+ const settings = { type: 'vscode' };
147
+ expect(() => (0, settings_1.setEditorSettings)(settings)).not.toThrow();
148
+ expect(mockedExecSync).toHaveBeenCalledTimes(1);
149
+ });
150
+ });
151
+ describe('getBrowserSettings', () => {
152
+ it('should get browser settings with default values', () => {
153
+ mockedExecSync.mockReturnValue(JSON.stringify({}));
154
+ const result = (0, settings_1.getBrowserSettings)();
155
+ expect(result.type).toBe('chrome');
156
+ expect(result.customPath).toBeUndefined();
157
+ });
158
+ it('should get browser settings with custom values', () => {
159
+ const settings = {
160
+ 'browser.type': 'firefox',
161
+ 'browser.customPath': '/path/to/firefox',
162
+ };
163
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
164
+ const result = (0, settings_1.getBrowserSettings)();
165
+ expect(result.type).toBe('firefox');
166
+ expect(result.customPath).toBe('/path/to/firefox');
167
+ });
168
+ it('should support all browser types', () => {
169
+ const browserTypes = ['chrome', 'firefox', 'safari', 'edge', 'custom'];
170
+ browserTypes.forEach(type => {
171
+ const settings = { 'browser.type': type };
172
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
173
+ const result = (0, settings_1.getBrowserSettings)();
174
+ expect(result.type).toBe(type);
175
+ });
176
+ });
177
+ });
178
+ describe('setBrowserSettings', () => {
179
+ it('should set browser type', () => {
180
+ mockedExecSync.mockReturnValue('');
181
+ const settings = { type: 'firefox' };
182
+ expect(() => (0, settings_1.setBrowserSettings)(settings)).not.toThrow();
183
+ expect(mockedExecSync).toHaveBeenCalled();
184
+ });
185
+ it('should set browser type and custom path', () => {
186
+ mockedExecSync.mockReturnValue('');
187
+ const settings = {
188
+ type: 'custom',
189
+ customPath: '/usr/local/bin/mybrowser',
190
+ };
191
+ expect(() => (0, settings_1.setBrowserSettings)(settings)).not.toThrow();
192
+ expect(mockedExecSync).toHaveBeenCalledTimes(2);
193
+ });
194
+ });
195
+ describe('getAppSettings', () => {
196
+ it('should get all app settings with defaults', () => {
197
+ mockedExecSync.mockReturnValue(JSON.stringify({}));
198
+ const result = (0, settings_1.getAppSettings)();
199
+ expect(result.editor.type).toBe('vscode');
200
+ expect(result.browser.type).toBe('chrome');
201
+ });
202
+ it('should get all app settings with custom values', () => {
203
+ const settings = {
204
+ 'editor.type': 'cursor',
205
+ 'editor.customPath': '/path/to/cursor',
206
+ 'browser.type': 'firefox',
207
+ 'browser.customPath': '/path/to/firefox',
208
+ };
209
+ mockedExecSync.mockReturnValue(JSON.stringify(settings));
210
+ const result = (0, settings_1.getAppSettings)();
211
+ expect(result.editor.type).toBe('cursor');
212
+ expect(result.editor.customPath).toBe('/path/to/cursor');
213
+ expect(result.browser.type).toBe('firefox');
214
+ expect(result.browser.customPath).toBe('/path/to/firefox');
215
+ });
216
+ it('should return complete app settings structure', () => {
217
+ mockedExecSync.mockReturnValue(JSON.stringify({}));
218
+ const result = (0, settings_1.getAppSettings)();
219
+ expect(result).toHaveProperty('editor');
220
+ expect(result).toHaveProperty('browser');
221
+ expect(result.editor).toHaveProperty('type');
222
+ expect(result.browser).toHaveProperty('type');
223
+ });
224
+ });
225
+ describe('setAppSettings', () => {
226
+ it('should set both editor and browser settings', () => {
227
+ mockedExecSync.mockReturnValue('');
228
+ const settings = {
229
+ editor: { type: 'cursor' },
230
+ browser: { type: 'firefox' },
231
+ };
232
+ expect(() => (0, settings_1.setAppSettings)(settings)).not.toThrow();
233
+ expect(mockedExecSync).toHaveBeenCalledTimes(2);
234
+ });
235
+ it('should set all settings including custom paths', () => {
236
+ mockedExecSync.mockReturnValue('');
237
+ const settings = {
238
+ editor: {
239
+ type: 'custom',
240
+ customPath: '/path/to/editor',
241
+ },
242
+ browser: {
243
+ type: 'custom',
244
+ customPath: '/path/to/browser',
245
+ },
246
+ };
247
+ expect(() => (0, settings_1.setAppSettings)(settings)).not.toThrow();
248
+ expect(mockedExecSync).toHaveBeenCalledTimes(4);
249
+ });
250
+ });
251
+ describe('type definitions', () => {
252
+ it('should allow valid editor types', () => {
253
+ const validTypes = [
254
+ 'vscode',
255
+ 'cursor',
256
+ 'windsurf',
257
+ 'zed',
258
+ 'custom',
259
+ ];
260
+ validTypes.forEach(type => {
261
+ const settings = { type };
262
+ expect(settings.type).toBe(type);
263
+ });
264
+ });
265
+ it('should allow valid browser types', () => {
266
+ const validTypes = [
267
+ 'chrome',
268
+ 'firefox',
269
+ 'safari',
270
+ 'edge',
271
+ 'custom',
272
+ ];
273
+ validTypes.forEach(type => {
274
+ const settings = { type };
275
+ expect(settings.type).toBe(type);
276
+ });
277
+ });
278
+ });
279
+ });