Skip to main content
Glama
MIT License
27,120
19,789
  • Linux
  • Apple
defaultActionWorker.test.ts10.7 kB
import path from 'node:path'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import defaultActionWorker, { type DefaultActionTask, type DefaultActionWorkerResult, type PingResult, type PingTask, } from '../../../../src/cli/actions/workers/defaultActionWorker.js'; import type { CliOptions } from '../../../../src/cli/types.js'; import type { RepomixConfigMerged } from '../../../../src/config/configSchema.js'; import { pack } from '../../../../src/core/packager.js'; // Mock dependencies vi.mock('../../../../src/core/packager.js'); vi.mock('../../../../src/shared/logger.js', () => ({ logger: { trace: vi.fn(), }, setLogLevelByWorkerData: vi.fn(), })); vi.mock('../../../../src/cli/cliSpinner.js', () => ({ Spinner: vi.fn().mockImplementation(() => ({ start: vi.fn(), update: vi.fn(), succeed: vi.fn(), fail: vi.fn(), })), })); const mockPack = vi.mocked(pack); describe('defaultActionWorker', () => { const mockConfig: RepomixConfigMerged = { input: { maxFileSize: 50 * 1024 * 1024, }, output: { filePath: 'test-output.txt', style: 'xml', parsableStyle: false, headerText: '', instructionFilePath: '', fileSummary: true, directoryStructure: true, files: true, removeComments: false, removeEmptyLines: false, compress: false, topFilesLength: 10, showLineNumbers: false, truncateBase64: false, copyToClipboard: false, includeEmptyDirectories: false, includeFullDirectoryStructure: false, tokenCountTree: false, git: { sortByChanges: true, sortByChangesMaxCommits: 100, includeDiffs: false, includeLogs: false, includeLogsCount: 50, }, }, include: ['**/*'], ignore: { useGitignore: true, useDefaultPatterns: true, customPatterns: [], }, security: { enableSecurityCheck: true, }, tokenCount: { encoding: 'o200k_base' as const, }, cwd: '/test/project', }; const mockCliOptions: CliOptions = { verbose: false, output: 'test-output.txt', include: undefined, ignore: undefined, 'ignore-file': undefined, config: undefined, style: 'xml', 'output-show-line-numbers': false, 'remove-comments': false, 'remove-empty-lines': false, 'copy-to-clipboard': false, 'include-empty-directories': false, 'git-log-output': false, 'git-log-author': undefined, 'git-log-after': undefined, 'git-log-before': undefined, 'git-log-max-count': undefined, 'git-diff': false, stdin: false, 'top-files-length': 10, version: false, init: false, remote: undefined, 'process-concurrency': 8, 'token-count-tree': false, 'no-progress': false, }; const mockPackResult = { totalFiles: 1, totalCharacters: 12, totalTokens: 3, fileCharCounts: { 'test.txt': 12 }, fileTokenCounts: { 'test.txt': 3 }, gitDiffTokenCount: 0, gitLogTokenCount: 0, suspiciousFilesResults: [], suspiciousGitDiffResults: [], suspiciousGitLogResults: [], processedFiles: [{ path: 'test.txt', content: 'test content' }], safeFilePaths: ['test.txt'], skippedFiles: [], }; beforeEach(() => { vi.clearAllMocks(); }); describe('ping functionality', () => { it('should handle ping requests correctly', async () => { const pingTask: PingTask = { ping: true, }; const result = (await defaultActionWorker(pingTask)) as PingResult; expect(result).toEqual({ ping: true, }); }); }); describe('directory processing', () => { it('should process directories successfully', async () => { const task: DefaultActionTask = { directories: ['src', 'tests'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; mockPack.mockResolvedValueOnce(mockPackResult); const result = (await defaultActionWorker(task)) as DefaultActionWorkerResult; expect(mockPack).toHaveBeenCalledWith( [path.resolve('/test/project', 'src'), path.resolve('/test/project', 'tests')], mockConfig, expect.any(Function), ); expect(result).toEqual({ packResult: mockPackResult, config: mockConfig, }); }); it('should handle single directory', async () => { const task: DefaultActionTask = { directories: ['.'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; mockPack.mockResolvedValueOnce(mockPackResult); const result = (await defaultActionWorker(task)) as DefaultActionWorkerResult; expect(mockPack).toHaveBeenCalledWith([path.resolve('/test/project', '.')], mockConfig, expect.any(Function)); expect(result).toEqual({ packResult: mockPackResult, config: mockConfig, }); }); it('should handle empty directories array', async () => { const task: DefaultActionTask = { directories: [], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; mockPack.mockResolvedValueOnce(mockPackResult); await defaultActionWorker(task); expect(mockPack).toHaveBeenCalledWith([], mockConfig, expect.any(Function)); }); }); describe('stdin processing', () => { it('should process stdin successfully with file paths from main process', async () => { const task: DefaultActionTask = { directories: ['.'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, stdinFilePaths: ['file1.txt', 'file2.txt'], }; mockPack.mockResolvedValueOnce(mockPackResult); const result = (await defaultActionWorker(task)) as DefaultActionWorkerResult; expect(mockPack).toHaveBeenCalledWith(['/test/project'], mockConfig, expect.any(Function), {}, [ 'file1.txt', 'file2.txt', ]); expect(result).toEqual({ packResult: mockPackResult, config: mockConfig, }); }); it('should handle empty directories for stdin', async () => { const task: DefaultActionTask = { directories: [], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, stdinFilePaths: ['file1.txt'], }; mockPack.mockResolvedValueOnce(mockPackResult); await defaultActionWorker(task); expect(mockPack).toHaveBeenCalledWith(['/test/project'], mockConfig, expect.any(Function), {}, ['file1.txt']); }); }); describe('error handling', () => { it('should handle pack errors for directory processing', async () => { const task: DefaultActionTask = { directories: ['src'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; const packError = new Error('Pack failed'); mockPack.mockRejectedValueOnce(packError); await expect(defaultActionWorker(task)).rejects.toThrow('Pack failed'); }); it('should handle pack errors during stdin processing', async () => { const task: DefaultActionTask = { directories: ['.'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, stdinFilePaths: ['file1.txt'], }; const packError = new Error('Pack failed during stdin'); mockPack.mockRejectedValueOnce(packError); await expect(defaultActionWorker(task)).rejects.toThrow('Pack failed during stdin'); }); }); describe('spinner integration', () => { it('should update spinner with progress messages', async () => { const task: DefaultActionTask = { directories: ['src'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; mockPack.mockImplementationOnce(async (_paths, _config, progressCallback) => { if (progressCallback) { progressCallback('Processing files...'); progressCallback('Calculating metrics...'); } return mockPackResult; }); await defaultActionWorker(task); // The spinner mock should be imported and we can verify the calls const { Spinner } = await import('../../../../src/cli/cliSpinner.js'); const mockSpinner = vi.mocked(Spinner).mock.results[0]?.value; expect(mockSpinner.start).toHaveBeenCalled(); expect(mockSpinner.update).toHaveBeenCalledWith('Processing files...'); expect(mockSpinner.update).toHaveBeenCalledWith('Calculating metrics...'); expect(mockSpinner.succeed).toHaveBeenCalledWith('Packing completed successfully!'); }); it('should fail spinner on error', async () => { const task: DefaultActionTask = { directories: ['src'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; mockPack.mockRejectedValueOnce(new Error('Pack failed')); await expect(defaultActionWorker(task)).rejects.toThrow('Pack failed'); const { Spinner } = await import('../../../../src/cli/cliSpinner.js'); const mockSpinner = vi.mocked(Spinner).mock.results[0]?.value; expect(mockSpinner.fail).toHaveBeenCalledWith('Error during packing'); }); }); describe('path resolution', () => { it('should resolve relative paths correctly', async () => { const task: DefaultActionTask = { directories: ['../parent', './current', 'child'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; mockPack.mockResolvedValueOnce(mockPackResult); await defaultActionWorker(task); expect(mockPack).toHaveBeenCalledWith( [ path.resolve('/test/project', '../parent'), path.resolve('/test/project', './current'), path.resolve('/test/project', 'child'), ], mockConfig, expect.any(Function), ); }); it('should handle absolute paths', async () => { const task: DefaultActionTask = { directories: ['/absolute/path1', '/absolute/path2'], cwd: '/test/project', config: mockConfig, cliOptions: mockCliOptions, }; mockPack.mockResolvedValueOnce(mockPackResult); await defaultActionWorker(task); expect(mockPack).toHaveBeenCalledWith( [path.resolve('/test/project', '/absolute/path1'), path.resolve('/test/project', '/absolute/path2')], mockConfig, expect.any(Function), ); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yamadashy/repomix'

If you have feedback or need assistance with the MCP directory API, please join our Discord server