UNPKG

@beparallel/langchain-ts

Version:

Extracts Langchain prompts and generates TypeScript types.

149 lines (148 loc) 6.41 kB
import { pull } from 'langchain/hub'; import { Client } from 'langsmith'; import { extractPrompts } from './parser.js'; // Mock the external dependencies jest.mock('langchain/hub'); jest.mock('langsmith'); const mockPull = jest.mocked(pull); const MockClient = jest.mocked(Client); describe('Parser Module', () => { describe('extractPrompts', () => { const mockApiKey = 'test-api-key'; const mockTag = 'test-tag'; let mockClientInstance; beforeEach(() => { jest.clearAllMocks(); // Create mock client instance mockClientInstance = { listPrompts: jest.fn(), }; // Mock the Client constructor MockClient.mockImplementation(() => mockClientInstance); // Mock console methods jest.spyOn(console, 'debug').mockImplementation(() => { }); jest.spyOn(console, 'error').mockImplementation(() => { }); }); afterEach(() => { jest.restoreAllMocks(); }); test('should extract prompts successfully', async () => { // Arrange const mockPrompts = [{ repo_handle: 'prompt1' }, { repo_handle: 'prompt2' }]; const mockTemplate1 = {}; const mockTemplate2 = {}; mockClientInstance.listPrompts.mockResolvedValue(mockPrompts); mockPull.mockResolvedValueOnce(mockTemplate1).mockResolvedValueOnce(mockTemplate2); // Act const result = await extractPrompts({ langchainApiKey: mockApiKey, langchainTag: mockTag, }); // Assert expect(MockClient).toHaveBeenCalledWith({ apiKey: mockApiKey }); expect(mockClientInstance.listPrompts).toHaveBeenCalledWith({ isPublic: false, isArchived: false, sortField: 'updated_at', }); expect(mockPull).toHaveBeenCalledTimes(2); expect(mockPull).toHaveBeenNthCalledWith(1, 'prompt1:test-tag'); expect(mockPull).toHaveBeenNthCalledWith(2, 'prompt2:test-tag'); expect(result).toEqual([mockTemplate1, mockTemplate2]); }); test('should handle empty prompts list', async () => { // Arrange mockClientInstance.listPrompts.mockResolvedValue([]); // Act const result = await extractPrompts({ langchainApiKey: mockApiKey, langchainTag: mockTag, }); // Assert expect(result).toEqual([]); expect(mockPull).not.toHaveBeenCalled(); }); test('should handle hub.pull errors gracefully', async () => { // Arrange const mockPrompts = [{ repo_handle: 'prompt1' }, { repo_handle: 'prompt2' }, { repo_handle: 'prompt3' }]; const mockTemplate1 = {}; const mockTemplate3 = {}; mockClientInstance.listPrompts.mockResolvedValue(mockPrompts); mockPull .mockResolvedValueOnce(mockTemplate1) .mockRejectedValueOnce(new Error('Failed to pull prompt2')) .mockResolvedValueOnce(mockTemplate3); // Act const result = await extractPrompts({ langchainApiKey: mockApiKey, langchainTag: mockTag, }); // Assert expect(result).toEqual([mockTemplate1, mockTemplate3]); expect(console.error).toHaveBeenCalledWith(new Error('Failed to pull prompt2')); }); test('should handle Client.listPrompts error', async () => { // Arrange const error = new Error('API Error'); mockClientInstance.listPrompts.mockRejectedValue(error); // Act & Assert await expect(extractPrompts({ langchainApiKey: mockApiKey, langchainTag: mockTag, })).rejects.toThrow('API Error'); }); test('should use correct parameters for Client initialization', async () => { // Arrange mockClientInstance.listPrompts.mockResolvedValue([]); // Act await extractPrompts({ langchainApiKey: 'custom-key', langchainTag: mockTag, }); // Assert expect(MockClient).toHaveBeenCalledWith({ apiKey: 'custom-key' }); }); test('should use correct tag in hub.pull calls', async () => { // Arrange const mockPrompts = [{ repo_handle: 'test-prompt' }]; const mockTemplate = {}; mockClientInstance.listPrompts.mockResolvedValue(mockPrompts); mockPull.mockResolvedValue(mockTemplate); // Act await extractPrompts({ langchainApiKey: mockApiKey, langchainTag: 'custom-tag', }); // Assert expect(mockPull).toHaveBeenCalledWith('test-prompt:custom-tag'); }); test('should log debug messages for each prompt', async () => { // Arrange const mockPrompts = [{ repo_handle: 'prompt1' }, { repo_handle: 'prompt2' }]; mockClientInstance.listPrompts.mockResolvedValue(mockPrompts); mockPull.mockResolvedValue({}); // Act await extractPrompts({ langchainApiKey: mockApiKey, langchainTag: mockTag, }); // Assert expect(console.debug).toHaveBeenCalledWith('Generating prompt prompt1'); expect(console.debug).toHaveBeenCalledWith('Generating prompt prompt2'); }); test('should handle all prompts failing to pull', async () => { // Arrange const mockPrompts = [{ repo_handle: 'prompt1' }, { repo_handle: 'prompt2' }]; mockClientInstance.listPrompts.mockResolvedValue(mockPrompts); mockPull.mockRejectedValueOnce(new Error('Error 1')).mockRejectedValueOnce(new Error('Error 2')); // Act const result = await extractPrompts({ langchainApiKey: mockApiKey, langchainTag: mockTag, }); // Assert expect(result).toEqual([]); expect(console.error).toHaveBeenCalledTimes(2); }); }); });