diff options
| author | Shreya Keshive <[email protected]> | 2025-07-28 11:03:22 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-28 15:03:22 +0000 |
| commit | e2754416516edb8c27e63cee5b249f41c3e0fffc (patch) | |
| tree | e00ee188509ce7f0b4f353cf6e08d0422490fe72 /packages/core/src/ide/ideContext.test.ts | |
| parent | f2e006179d27af34c35b58b1df3032e351e61eaf (diff) | |
Updates schema, UX and prompt for IDE context (#5046)
Diffstat (limited to 'packages/core/src/ide/ideContext.test.ts')
| -rw-r--r-- | packages/core/src/ide/ideContext.test.ts | 360 |
1 files changed, 262 insertions, 98 deletions
diff --git a/packages/core/src/ide/ideContext.test.ts b/packages/core/src/ide/ideContext.test.ts index 1cb09c53..7e01d3aa 100644 --- a/packages/core/src/ide/ideContext.test.ts +++ b/packages/core/src/ide/ideContext.test.ts @@ -5,136 +5,300 @@ */ import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { createIdeContextStore } from './ideContext.js'; +import { + createIdeContextStore, + FileSchema, + IdeContextSchema, +} from './ideContext.js'; -describe('ideContext - Active File', () => { - let ideContext: ReturnType<typeof createIdeContextStore>; +describe('ideContext', () => { + describe('createIdeContextStore', () => { + let ideContext: ReturnType<typeof createIdeContextStore>; - beforeEach(() => { - // Create a fresh, isolated instance for each test - ideContext = createIdeContextStore(); - }); + beforeEach(() => { + // Create a fresh, isolated instance for each test + ideContext = createIdeContextStore(); + }); - it('should return undefined initially for active file context', () => { - expect(ideContext.getOpenFilesContext()).toBeUndefined(); - }); + it('should return undefined initially for ide context', () => { + expect(ideContext.getIdeContext()).toBeUndefined(); + }); - it('should set and retrieve the active file context', () => { - const testFile = { - activeFile: '/path/to/test/file.ts', - selectedText: '1234', - }; + it('should set and retrieve the ide context', () => { + const testFile = { + workspaceState: { + openFiles: [ + { + path: '/path/to/test/file.ts', + isActive: true, + selectedText: '1234', + timestamp: 0, + }, + ], + }, + }; - ideContext.setOpenFilesContext(testFile); + ideContext.setIdeContext(testFile); - const activeFile = ideContext.getOpenFilesContext(); - expect(activeFile).toEqual(testFile); - }); + const activeFile = ideContext.getIdeContext(); + expect(activeFile).toEqual(testFile); + }); - it('should update the active file context when called multiple times', () => { - const firstFile = { - activeFile: '/path/to/first.js', - selectedText: '1234', - }; - ideContext.setOpenFilesContext(firstFile); + it('should update the ide context when called multiple times', () => { + const firstFile = { + workspaceState: { + openFiles: [ + { + path: '/path/to/first.js', + isActive: true, + selectedText: '1234', + timestamp: 0, + }, + ], + }, + }; + ideContext.setIdeContext(firstFile); - const secondFile = { - activeFile: '/path/to/second.py', - cursor: { line: 20, character: 30 }, - }; - ideContext.setOpenFilesContext(secondFile); + const secondFile = { + workspaceState: { + openFiles: [ + { + path: '/path/to/second.py', + isActive: true, + cursor: { line: 20, character: 30 }, + timestamp: 0, + }, + ], + }, + }; + ideContext.setIdeContext(secondFile); - const activeFile = ideContext.getOpenFilesContext(); - expect(activeFile).toEqual(secondFile); - }); + const activeFile = ideContext.getIdeContext(); + expect(activeFile).toEqual(secondFile); + }); - it('should handle empty string for file path', () => { - const testFile = { - activeFile: '', - selectedText: '1234', - }; - ideContext.setOpenFilesContext(testFile); - expect(ideContext.getOpenFilesContext()).toEqual(testFile); - }); + it('should handle empty string for file path', () => { + const testFile = { + workspaceState: { + openFiles: [ + { + path: '', + isActive: true, + selectedText: '1234', + timestamp: 0, + }, + ], + }, + }; + ideContext.setIdeContext(testFile); + expect(ideContext.getIdeContext()).toEqual(testFile); + }); - it('should notify subscribers when active file context changes', () => { - const subscriber1 = vi.fn(); - const subscriber2 = vi.fn(); + it('should notify subscribers when ide context changes', () => { + const subscriber1 = vi.fn(); + const subscriber2 = vi.fn(); - ideContext.subscribeToOpenFiles(subscriber1); - ideContext.subscribeToOpenFiles(subscriber2); + ideContext.subscribeToIdeContext(subscriber1); + ideContext.subscribeToIdeContext(subscriber2); - const testFile = { - activeFile: '/path/to/subscribed.ts', - cursor: { line: 15, character: 25 }, - }; - ideContext.setOpenFilesContext(testFile); + const testFile = { + workspaceState: { + openFiles: [ + { + path: '/path/to/subscribed.ts', + isActive: true, + cursor: { line: 15, character: 25 }, + timestamp: 0, + }, + ], + }, + }; + ideContext.setIdeContext(testFile); - expect(subscriber1).toHaveBeenCalledTimes(1); - expect(subscriber1).toHaveBeenCalledWith(testFile); - expect(subscriber2).toHaveBeenCalledTimes(1); - expect(subscriber2).toHaveBeenCalledWith(testFile); + expect(subscriber1).toHaveBeenCalledTimes(1); + expect(subscriber1).toHaveBeenCalledWith(testFile); + expect(subscriber2).toHaveBeenCalledTimes(1); + expect(subscriber2).toHaveBeenCalledWith(testFile); - // Test with another update - const newFile = { - activeFile: '/path/to/new.js', - selectedText: '1234', - }; - ideContext.setOpenFilesContext(newFile); + // Test with another update + const newFile = { + workspaceState: { + openFiles: [ + { + path: '/path/to/new.js', + isActive: true, + selectedText: '1234', + timestamp: 0, + }, + ], + }, + }; + ideContext.setIdeContext(newFile); - expect(subscriber1).toHaveBeenCalledTimes(2); - expect(subscriber1).toHaveBeenCalledWith(newFile); - expect(subscriber2).toHaveBeenCalledTimes(2); - expect(subscriber2).toHaveBeenCalledWith(newFile); - }); + expect(subscriber1).toHaveBeenCalledTimes(2); + expect(subscriber1).toHaveBeenCalledWith(newFile); + expect(subscriber2).toHaveBeenCalledTimes(2); + expect(subscriber2).toHaveBeenCalledWith(newFile); + }); + + it('should stop notifying a subscriber after unsubscribe', () => { + const subscriber1 = vi.fn(); + const subscriber2 = vi.fn(); + + const unsubscribe1 = ideContext.subscribeToIdeContext(subscriber1); + ideContext.subscribeToIdeContext(subscriber2); - it('should stop notifying a subscriber after unsubscribe', () => { - const subscriber1 = vi.fn(); - const subscriber2 = vi.fn(); + ideContext.setIdeContext({ + workspaceState: { + openFiles: [ + { + path: '/path/to/file1.txt', + isActive: true, + selectedText: '1234', + timestamp: 0, + }, + ], + }, + }); + expect(subscriber1).toHaveBeenCalledTimes(1); + expect(subscriber2).toHaveBeenCalledTimes(1); - const unsubscribe1 = ideContext.subscribeToOpenFiles(subscriber1); - ideContext.subscribeToOpenFiles(subscriber2); + unsubscribe1(); - ideContext.setOpenFilesContext({ - activeFile: '/path/to/file1.txt', - selectedText: '1234', + ideContext.setIdeContext({ + workspaceState: { + openFiles: [ + { + path: '/path/to/file2.txt', + isActive: true, + selectedText: '1234', + timestamp: 0, + }, + ], + }, + }); + expect(subscriber1).toHaveBeenCalledTimes(1); // Should not be called again + expect(subscriber2).toHaveBeenCalledTimes(2); }); - expect(subscriber1).toHaveBeenCalledTimes(1); - expect(subscriber2).toHaveBeenCalledTimes(1); - unsubscribe1(); + it('should clear the ide context', () => { + const testFile = { + workspaceState: { + openFiles: [ + { + path: '/path/to/test/file.ts', + isActive: true, + selectedText: '1234', + timestamp: 0, + }, + ], + }, + }; - ideContext.setOpenFilesContext({ - activeFile: '/path/to/file2.txt', - selectedText: '1234', + ideContext.setIdeContext(testFile); + + expect(ideContext.getIdeContext()).toEqual(testFile); + + ideContext.clearIdeContext(); + + expect(ideContext.getIdeContext()).toBeUndefined(); }); - expect(subscriber1).toHaveBeenCalledTimes(1); // Should not be called again - expect(subscriber2).toHaveBeenCalledTimes(2); }); - it('should allow the cursor to be optional', () => { - const testFile = { - activeFile: '/path/to/test/file.ts', - }; + describe('FileSchema', () => { + it('should validate a file with only required fields', () => { + const file = { + path: '/path/to/file.ts', + timestamp: 12345, + }; + const result = FileSchema.safeParse(file); + expect(result.success).toBe(true); + }); - ideContext.setOpenFilesContext(testFile); + it('should validate a file with all fields', () => { + const file = { + path: '/path/to/file.ts', + timestamp: 12345, + isActive: true, + selectedText: 'const x = 1;', + cursor: { + line: 10, + character: 20, + }, + }; + const result = FileSchema.safeParse(file); + expect(result.success).toBe(true); + }); + + it('should fail validation if path is missing', () => { + const file = { + timestamp: 12345, + }; + const result = FileSchema.safeParse(file); + expect(result.success).toBe(false); + }); - const activeFile = ideContext.getOpenFilesContext(); - expect(activeFile).toEqual(testFile); + it('should fail validation if timestamp is missing', () => { + const file = { + path: '/path/to/file.ts', + }; + const result = FileSchema.safeParse(file); + expect(result.success).toBe(false); + }); }); - it('should clear the active file context', () => { - const testFile = { - activeFile: '/path/to/test/file.ts', - selectedText: '1234', - }; + describe('IdeContextSchema', () => { + it('should validate an empty context', () => { + const context = {}; + const result = IdeContextSchema.safeParse(context); + expect(result.success).toBe(true); + }); - ideContext.setOpenFilesContext(testFile); + it('should validate a context with an empty workspaceState', () => { + const context = { + workspaceState: {}, + }; + const result = IdeContextSchema.safeParse(context); + expect(result.success).toBe(true); + }); - expect(ideContext.getOpenFilesContext()).toEqual(testFile); + it('should validate a context with an empty openFiles array', () => { + const context = { + workspaceState: { + openFiles: [], + }, + }; + const result = IdeContextSchema.safeParse(context); + expect(result.success).toBe(true); + }); - ideContext.clearOpenFilesContext(); + it('should validate a context with a valid file', () => { + const context = { + workspaceState: { + openFiles: [ + { + path: '/path/to/file.ts', + timestamp: 12345, + }, + ], + }, + }; + const result = IdeContextSchema.safeParse(context); + expect(result.success).toBe(true); + }); - expect(ideContext.getOpenFilesContext()).toBeUndefined(); + it('should fail validation with an invalid file', () => { + const context = { + workspaceState: { + openFiles: [ + { + timestamp: 12345, // path is missing + }, + ], + }, + }; + const result = IdeContextSchema.safeParse(context); + expect(result.success).toBe(false); + }); }); }); |
