Files
repomix-mirror/tests/core/packager/diffsFunctionality.test.ts
Claude 4d2bbcf6cc perf(core): Pre-initialize metrics worker pool to overlap tiktoken WASM loading
Pipeline-level optimizations that produce measurable end-to-end improvement:

- Pre-initialize metrics worker pool during file collection phase so tiktoken
  WASM loading overlaps with security checks and file processing. First token
  count task dropped from 381ms to 22ms (worker already warmed).
- Lazy-load Jiti via dynamic import — only loaded when TS/JS config files are
  detected, saving startup time for the common JSON/default config path.
- Fix O(n²) file path re-grouping in packager by using Map + Set for O(1)
  membership checks instead of .find() + .includes().
- Move binary extension check before fs.stat in fileRead to skip unnecessary
  stat syscalls for binary files.
- Parallelize split output file writes with Promise.all instead of sequential
  for-loop.

Benchmark (15 runs each, median ± IQR, packing repomix repo ~1000 files):

  main branch: 3515ms (P25: 3443, P75: 3581)
  perf branch: 3318ms (P25: 3215, P75: 3383)
  Improvement: -197ms (-5.6%)

Pipeline stage breakdown (instrumented):
  - Metrics first-file init: 381ms → 22ms (worker pre-warmed)
  - Total metrics stage: 793ms → ~450ms

All 1096 tests pass. Lint clean.

https://claude.ai/code/session_01JoNjFe7S2roMfHfNcw6bso
2026-03-28 01:15:43 +09:00

154 lines
5.2 KiB
TypeScript

import { beforeEach, describe, expect, test, vi } from 'vitest';
import type { RepomixConfigMerged } from '../../../src/config/configSchema.js';
import type { ProcessedFile } from '../../../src/core/file/fileTypes.js';
import * as gitDiffModule from '../../../src/core/git/gitDiffHandle.js';
import * as gitRepositoryModule from '../../../src/core/git/gitRepositoryHandle.js';
import { pack } from '../../../src/core/packager.js';
import { createMockConfig } from '../../testing/testUtils.js';
// Mock the dependencies
vi.mock('../../../src/core/git/gitDiffHandle.js', () => ({
getWorkTreeDiff: vi.fn(),
getStagedDiff: vi.fn(),
getGitDiffs: vi.fn(),
}));
vi.mock('../../../src/core/git/gitRepositoryHandle.js', () => ({
isGitRepository: vi.fn(),
}));
describe('Git Diffs Functionality', () => {
let mockConfig: RepomixConfigMerged;
const mockRootDir = '/test/repo';
const sampleDiff = `diff --git a/file1.js b/file1.js
index 123..456 100644
--- a/file1.js
+++ b/file1.js
@@ -1,5 +1,5 @@
-old line
+new line
`;
beforeEach(() => {
vi.resetAllMocks();
// Sample minimal config using createMockConfig utility
mockConfig = createMockConfig({
cwd: mockRootDir,
output: {
filePath: 'repomix-output.txt',
style: 'plain',
git: {
includeDiffs: false,
},
},
});
// Set up our mocks
vi.mocked(gitRepositoryModule.isGitRepository).mockResolvedValue(true);
vi.mocked(gitDiffModule.getWorkTreeDiff).mockResolvedValue(sampleDiff);
vi.mocked(gitDiffModule.getStagedDiff).mockResolvedValue('');
});
test('should not fetch diffs when includeDiffs is disabled', async () => {
// Mock the dependencies for pack
const mockSearchFiles = vi.fn().mockResolvedValue({ filePaths: [] });
const mockCollectFiles = vi.fn().mockResolvedValue({ rawFiles: [], skippedFiles: [] });
const mockProcessFiles = vi.fn().mockResolvedValue([]);
const mockValidateFileSafety = vi.fn().mockResolvedValue({
safeFilePaths: [],
safeRawFiles: [],
suspiciousFilesResults: [],
});
const mockProduceOutput = vi.fn().mockResolvedValue({
outputForMetrics: 'mocked output',
});
const mockCalculateMetrics = vi.fn().mockResolvedValue({
totalFiles: 0,
totalCharacters: 0,
totalTokens: 0,
fileCharCounts: {},
fileTokenCounts: {},
});
const mockSortPaths = vi.fn().mockImplementation((paths) => paths);
const mockCreateMetricsTaskRunner = vi.fn().mockReturnValue({
run: vi.fn().mockResolvedValue(0),
cleanup: vi.fn().mockResolvedValue(undefined),
});
// Config with diffs disabled
if (mockConfig.output.git) {
mockConfig.output.git.includeDiffs = false;
}
await pack([mockRootDir], mockConfig, vi.fn(), {
searchFiles: mockSearchFiles,
collectFiles: mockCollectFiles,
processFiles: mockProcessFiles,
validateFileSafety: mockValidateFileSafety,
produceOutput: mockProduceOutput,
calculateMetrics: mockCalculateMetrics,
createMetricsTaskRunner: mockCreateMetricsTaskRunner,
sortPaths: mockSortPaths,
});
// Should not call getWorkTreeDiff
expect(gitDiffModule.getWorkTreeDiff).not.toHaveBeenCalled();
});
test('should calculate diff token count correctly', async () => {
// Create a processed files array with a sample file
const processedFiles: ProcessedFile[] = [
{
path: 'test.js',
content: 'console.log("test");',
},
];
// Mock dependencies
const mockSearchFiles = vi.fn().mockResolvedValue({ filePaths: ['test.js'] });
const mockCollectFiles = vi.fn().mockResolvedValue({ rawFiles: processedFiles, skippedFiles: [] });
const mockProcessFiles = vi.fn().mockResolvedValue(processedFiles);
const mockValidateFileSafety = vi.fn().mockResolvedValue({
safeFilePaths: ['test.js'],
safeRawFiles: processedFiles,
suspiciousFilesResults: [],
});
const mockProduceOutput = vi.fn().mockResolvedValue({
outputForMetrics: 'Generated output with diffs included',
});
const mockCalculateMetrics = vi.fn().mockResolvedValue({
totalFiles: 1,
totalCharacters: 30,
totalTokens: 10,
fileCharCounts: { 'test.js': 10 },
fileTokenCounts: { 'test.js': 5 },
gitDiffTokenCount: 15, // Mock diff token count
});
const mockSortPaths = vi.fn().mockImplementation((paths) => paths);
const mockCreateMetricsTaskRunner = vi.fn().mockReturnValue({
run: vi.fn().mockResolvedValue(0),
cleanup: vi.fn().mockResolvedValue(undefined),
});
// Config with diffs enabled
if (mockConfig.output.git) {
mockConfig.output.git.includeDiffs = true;
}
const result = await pack([mockRootDir], mockConfig, vi.fn(), {
searchFiles: mockSearchFiles,
collectFiles: mockCollectFiles,
processFiles: mockProcessFiles,
validateFileSafety: mockValidateFileSafety,
produceOutput: mockProduceOutput,
calculateMetrics: mockCalculateMetrics,
createMetricsTaskRunner: mockCreateMetricsTaskRunner,
sortPaths: mockSortPaths,
});
// Check gitDiffTokenCount in the result
expect(result.gitDiffTokenCount).toBe(15);
});
});