WIP: A simple cli for daily tangled use cases and AI integration. This is for my personal use right now, but happy if others get mileage from it! :)
at main 92 lines 3.6 kB view raw
1import { beforeEach, describe, expect, it, vi } from 'vitest'; 2import { createContextCommand } from '../../src/commands/context.js'; 3 4// Mock modules 5vi.mock('../../src/lib/context.js'); 6 7// Import mocked modules 8import * as contextModule from '../../src/lib/context.js'; 9 10describe('Context Command', () => { 11 let consoleLogSpy: ReturnType<typeof vi.fn>; 12 let consoleErrorSpy: ReturnType<typeof vi.fn>; 13 14 beforeEach(() => { 15 vi.clearAllMocks(); 16 17 // Mock console methods 18 consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) as never; 19 consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) as never; 20 21 // Mock process.exit to throw so tests don't actually exit 22 vi.spyOn(process, 'exit').mockImplementation((code) => { 23 throw new Error(`process.exit(${code})`); 24 }) as never; 25 }); 26 27 it('should display repository context when in tangled repo', async () => { 28 vi.mocked(contextModule.getCurrentRepoContext).mockResolvedValue({ 29 owner: 'did:plc:b2mcbcamkwyznc5fkplwlxbf', 30 ownerType: 'did', 31 name: 'tangled-cli', 32 remoteName: 'origin', 33 remoteUrl: 'git@tangled.org:did:plc:b2mcbcamkwyznc5fkplwlxbf/tangled-cli.git', 34 protocol: 'ssh', 35 }); 36 37 const context = createContextCommand(); 38 await context.parseAsync(['node', 'test']); 39 40 expect(consoleLogSpy).toHaveBeenCalledWith('✓ Repository context resolved:\n'); 41 expect(consoleLogSpy).toHaveBeenCalledWith(' Owner: did:plc:b2mcbcamkwyznc5fkplwlxbf (did)'); 42 expect(consoleLogSpy).toHaveBeenCalledWith(' Repository: tangled-cli'); 43 expect(consoleLogSpy).toHaveBeenCalledWith(' Protocol: ssh'); 44 expect(consoleLogSpy).toHaveBeenCalledWith( 45 ' Remote: origin (git@tangled.org:did:plc:b2mcbcamkwyznc5fkplwlxbf/tangled-cli.git)' 46 ); 47 }); 48 49 it('should display context for HTTPS remote with handle', async () => { 50 vi.mocked(contextModule.getCurrentRepoContext).mockResolvedValue({ 51 owner: 'markbennett.ca', 52 ownerType: 'handle', 53 name: 'tangled-cli', 54 remoteName: 'origin', 55 remoteUrl: 'https://tangled.org/markbennett.ca/tangled-cli', 56 protocol: 'https', 57 }); 58 59 const context = createContextCommand(); 60 await context.parseAsync(['node', 'test']); 61 62 expect(consoleLogSpy).toHaveBeenCalledWith(' Owner: markbennett.ca (handle)'); 63 expect(consoleLogSpy).toHaveBeenCalledWith(' Protocol: https'); 64 }); 65 66 it('should show error when not in tangled repository', async () => { 67 vi.mocked(contextModule.getCurrentRepoContext).mockResolvedValue(null); 68 69 const context = createContextCommand(); 70 await expect(context.parseAsync(['node', 'test'])).rejects.toThrow('process.exit(1)'); 71 72 expect(consoleLogSpy).toHaveBeenCalledWith('✗ Not in a Tangled repository'); 73 expect(consoleLogSpy).toHaveBeenCalledWith( 74 expect.stringContaining('To use this repository with Tangled') 75 ); 76 expect(consoleLogSpy).toHaveBeenCalledWith( 77 expect.stringContaining('git remote add origin git@tangled.org:') 78 ); 79 }); 80 81 it('should handle errors gracefully', async () => { 82 vi.mocked(contextModule.getCurrentRepoContext).mockRejectedValue(new Error('Git error')); 83 84 const context = createContextCommand(); 85 await expect(context.parseAsync(['node', 'test'])).rejects.toThrow('process.exit(1)'); 86 87 expect(consoleErrorSpy).toHaveBeenCalledWith( 88 expect.stringContaining('Failed to resolve context') 89 ); 90 expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Git error')); 91 }); 92});