Fixes from linter

This commit is contained in:
Mike Judge
2024-12-24 17:42:55 -08:00
parent c66ed65775
commit 33d9c14650
22 changed files with 308 additions and 469 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "Repomix",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bullseye",
"runArgs": ["--name", "repomix-devcontainer"],
"postCreateCommand": "npm install"
"name": "Repomix",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bullseye",
"runArgs": ["--name", "repomix-devcontainer"],
"postCreateCommand": "npm install"
}

View File

@@ -1,15 +1,12 @@
import fs from "node:fs/promises";
import path from "node:path";
import { globby } from "globby";
import { minimatch } from "minimatch";
import type { RepomixConfigMerged } from "../../config/configSchema.js";
import { defaultIgnoreList } from "../../config/defaultIgnore.js";
import { logger } from "../../shared/logger.js";
import { sortPaths } from "./filePathSort.js";
import {
PermissionError,
checkDirectoryPermissions,
} from "./permissionCheck.js";
import fs from 'node:fs/promises';
import path from 'node:path';
import { globby } from 'globby';
import { minimatch } from 'minimatch';
import type { RepomixConfigMerged } from '../../config/configSchema.js';
import { defaultIgnoreList } from '../../config/defaultIgnore.js';
import { logger } from '../../shared/logger.js';
import { sortPaths } from './filePathSort.js';
import { PermissionError, checkDirectoryPermissions } from './permissionCheck.js';
export interface FileSearchResult {
filePaths: string[];
@@ -19,7 +16,7 @@ export interface FileSearchResult {
const findEmptyDirectories = async (
rootDir: string,
directories: string[],
ignorePatterns: string[]
ignorePatterns: string[],
): Promise<string[]> => {
const emptyDirs: string[] = [];
@@ -27,15 +24,11 @@ const findEmptyDirectories = async (
const fullPath = path.join(rootDir, dir);
try {
const entries = await fs.readdir(fullPath);
const hasVisibleContents = entries.some(
(entry) => !entry.startsWith(".")
);
const hasVisibleContents = entries.some((entry) => !entry.startsWith('.'));
if (!hasVisibleContents) {
// This checks if the directory itself matches any ignore patterns
const shouldIgnore = ignorePatterns.some(
(pattern) => minimatch(dir, pattern) || minimatch(`${dir}/`, pattern)
);
const shouldIgnore = ignorePatterns.some((pattern) => minimatch(dir, pattern) || minimatch(`${dir}/`, pattern));
if (!shouldIgnore) {
emptyDirs.push(dir);
@@ -50,10 +43,7 @@ const findEmptyDirectories = async (
};
// Get all file paths considering the config
export const searchFiles = async (
rootDir: string,
config: RepomixConfigMerged
): Promise<FileSearchResult> => {
export const searchFiles = async (rootDir: string, config: RepomixConfigMerged): Promise<FileSearchResult> => {
// First check directory permissions
const permissionCheck = await checkDirectoryPermissions(rootDir);
@@ -61,12 +51,10 @@ export const searchFiles = async (
if (permissionCheck.error instanceof PermissionError) {
throw permissionCheck.error;
}
throw new Error(
`Cannot access directory ${rootDir}: ${permissionCheck.error?.message}`
);
throw new Error(`Cannot access directory ${rootDir}: ${permissionCheck.error?.message}`);
}
const includePatterns = config.include.length > 0 ? config.include : ["**/*"];
const includePatterns = config.include.length > 0 ? config.include : ['**/*'];
try {
const [ignorePatterns, ignoreFilePatterns] = await Promise.all([
@@ -74,9 +62,9 @@ export const searchFiles = async (
getIgnoreFilePatterns(config),
]);
logger.trace("Include patterns:", includePatterns);
logger.trace("Ignore patterns:", ignorePatterns);
logger.trace("Ignore file patterns:", ignoreFilePatterns);
logger.trace('Include patterns:', includePatterns);
logger.trace('Ignore patterns:', ignorePatterns);
logger.trace('Ignore file patterns:', ignoreFilePatterns);
const filePaths = await globby(includePatterns, {
cwd: rootDir,
@@ -88,10 +76,10 @@ export const searchFiles = async (
followSymbolicLinks: false,
}).catch((error) => {
// Handle EPERM errors specifically
if (error.code === "EPERM" || error.code === "EACCES") {
if (error.code === 'EPERM' || error.code === 'EACCES') {
throw new PermissionError(
"Permission denied while scanning directory. Please check folder access permissions for your terminal app.",
rootDir
'Permission denied while scanning directory. Please check folder access permissions for your terminal app.',
rootDir,
);
}
throw error;
@@ -109,11 +97,7 @@ export const searchFiles = async (
followSymbolicLinks: false,
});
emptyDirPaths = await findEmptyDirectories(
rootDir,
directories,
ignorePatterns
);
emptyDirPaths = await findEmptyDirectories(rootDir, directories, ignorePatterns);
}
logger.trace(`Filtered ${filePaths.length} files`);
@@ -129,52 +113,45 @@ export const searchFiles = async (
}
if (error instanceof Error) {
logger.error("Error filtering files:", error.message);
throw new Error(
`Failed to filter files in directory ${rootDir}. Reason: ${error.message}`
);
logger.error('Error filtering files:', error.message);
throw new Error(`Failed to filter files in directory ${rootDir}. Reason: ${error.message}`);
}
logger.error("An unexpected error occurred:", error);
throw new Error("An unexpected error occurred while filtering files.");
logger.error('An unexpected error occurred:', error);
throw new Error('An unexpected error occurred while filtering files.');
}
};
export const parseIgnoreContent = (content: string): string[] => {
if (!content) return [];
return content.split("\n").reduce<string[]>((acc, line) => {
return content.split('\n').reduce<string[]>((acc, line) => {
const trimmedLine = line.trim();
if (trimmedLine && !trimmedLine.startsWith("#")) {
if (trimmedLine && !trimmedLine.startsWith('#')) {
acc.push(trimmedLine);
}
return acc;
}, []);
};
export const getIgnoreFilePatterns = async (
config: RepomixConfigMerged
): Promise<string[]> => {
export const getIgnoreFilePatterns = async (config: RepomixConfigMerged): Promise<string[]> => {
const ignoreFilePatterns: string[] = [];
if (config.ignore.useGitignore) {
ignoreFilePatterns.push("**/.gitignore");
ignoreFilePatterns.push('**/.gitignore');
}
ignoreFilePatterns.push("**/.repomixignore");
ignoreFilePatterns.push('**/.repomixignore');
return ignoreFilePatterns;
};
export const getIgnorePatterns = async (
rootDir: string,
config: RepomixConfigMerged
): Promise<string[]> => {
export const getIgnorePatterns = async (rootDir: string, config: RepomixConfigMerged): Promise<string[]> => {
const ignorePatterns = new Set<string>();
// Add default ignore patterns
if (config.ignore.useDefaultPatterns) {
logger.trace("Adding default ignore patterns");
logger.trace('Adding default ignore patterns');
for (const pattern of defaultIgnoreList) {
ignorePatterns.add(pattern);
}
@@ -182,19 +159,13 @@ export const getIgnorePatterns = async (
// Add repomix output file
if (config.output.filePath) {
logger.trace(
"Adding output file to ignore patterns:",
config.output.filePath
);
logger.trace('Adding output file to ignore patterns:', config.output.filePath);
ignorePatterns.add(config.output.filePath);
}
// Add custom ignore patterns
if (config.ignore.customPatterns) {
logger.trace(
"Adding custom ignore patterns:",
config.ignore.customPatterns
);
logger.trace('Adding custom ignore patterns:', config.ignore.customPatterns);
for (const pattern of config.ignore.customPatterns) {
ignorePatterns.add(pattern);
}

View File

@@ -1,12 +1,12 @@
import type { ProcessedFile } from "../file/fileTypes.js";
import type { TokenCounter } from "../tokenCount/tokenCount.js";
import type { FileMetrics } from "./calculateIndividualFileMetrics.js";
import type { ProcessedFile } from '../file/fileTypes.js';
import type { TokenCounter } from '../tokenCount/tokenCount.js';
import type { FileMetrics } from './calculateIndividualFileMetrics.js';
export const aggregateMetrics = (
fileMetrics: FileMetrics[],
processedFiles: ProcessedFile[],
output: string,
tokenCounter: TokenCounter
tokenCounter: TokenCounter,
) => {
const totalFiles = processedFiles.length;
const totalCharacters = output.length;

View File

@@ -1,30 +1,20 @@
import pMap from "p-map";
import { getProcessConcurrency } from "../../shared/processConcurrency.js";
import type { RepomixProgressCallback } from "../../shared/types.js";
import type { ProcessedFile } from "../file/fileTypes.js";
import type { TokenCounter } from "../tokenCount/tokenCount.js";
import {
calculateIndividualFileMetrics,
type FileMetrics,
} from "./calculateIndividualFileMetrics.js";
import pMap from 'p-map';
import { getProcessConcurrency } from '../../shared/processConcurrency.js';
import type { RepomixProgressCallback } from '../../shared/types.js';
import type { ProcessedFile } from '../file/fileTypes.js';
import type { TokenCounter } from '../tokenCount/tokenCount.js';
import { type FileMetrics, calculateIndividualFileMetrics } from './calculateIndividualFileMetrics.js';
export const calculateAllFileMetrics = async (
processedFiles: ProcessedFile[],
tokenCounter: TokenCounter,
progressCallback: RepomixProgressCallback
progressCallback: RepomixProgressCallback,
): Promise<FileMetrics[]> => {
return await pMap(
processedFiles,
(file, index) =>
calculateIndividualFileMetrics(
file,
index,
processedFiles.length,
tokenCounter,
progressCallback
),
(file, index) => calculateIndividualFileMetrics(file, index, processedFiles.length, tokenCounter, progressCallback),
{
concurrency: getProcessConcurrency(),
}
},
);
};

View File

@@ -1,8 +1,8 @@
import { setTimeout } from "node:timers/promises";
import pc from "picocolors";
import { RepomixProgressCallback } from "../../shared/types.js";
import type { ProcessedFile } from "../file/fileTypes.js";
import type { TokenCounter } from "../tokenCount/tokenCount.js";
import { setTimeout } from 'node:timers/promises';
import pc from 'picocolors';
import type { RepomixProgressCallback } from '../../shared/types.js';
import type { ProcessedFile } from '../file/fileTypes.js';
import type { TokenCounter } from '../tokenCount/tokenCount.js';
export interface FileMetrics {
path: string;
@@ -15,14 +15,12 @@ export const calculateIndividualFileMetrics = async (
index: number,
totalFiles: number,
tokenCounter: TokenCounter,
progressCallback: RepomixProgressCallback
progressCallback: RepomixProgressCallback,
): Promise<FileMetrics> => {
const charCount = file.content.length;
const tokenCount = tokenCounter.countTokens(file.content, file.path);
progressCallback(
`Calculating metrics... (${index + 1}/${totalFiles}) ${pc.dim(file.path)}`
);
progressCallback(`Calculating metrics... (${index + 1}/${totalFiles}) ${pc.dim(file.path)}`);
// Sleep for a short time to prevent blocking the event loop
await setTimeout(1);

View File

@@ -1,8 +1,8 @@
import { RepomixProgressCallback } from "../../shared/types.js";
import { type ProcessedFile } from "../file/fileTypes.js";
import { TokenCounter } from "../tokenCount/tokenCount.js";
import { aggregateMetrics } from "./aggregateMetrics.js";
import { calculateAllFileMetrics } from "./calculateAllFileMetrics.js";
import type { RepomixProgressCallback } from '../../shared/types.js';
import type { ProcessedFile } from '../file/fileTypes.js';
import { TokenCounter } from '../tokenCount/tokenCount.js';
import { aggregateMetrics } from './aggregateMetrics.js';
import { calculateAllFileMetrics } from './calculateAllFileMetrics.js';
export interface CalculateMetricsResult {
totalFiles: number;
@@ -15,23 +15,14 @@ export interface CalculateMetricsResult {
export const calculateMetrics = async (
processedFiles: ProcessedFile[],
output: string,
progressCallback: RepomixProgressCallback
progressCallback: RepomixProgressCallback,
): Promise<CalculateMetricsResult> => {
const tokenCounter = new TokenCounter();
progressCallback("Calculating metrics...");
const fileMetrics = await calculateAllFileMetrics(
processedFiles,
tokenCounter,
progressCallback
);
progressCallback('Calculating metrics...');
const fileMetrics = await calculateAllFileMetrics(processedFiles, tokenCounter, progressCallback);
const result = aggregateMetrics(
fileMetrics,
processedFiles,
output,
tokenCounter
);
const result = aggregateMetrics(fileMetrics, processedFiles, output, tokenCounter);
tokenCounter.free();

View File

@@ -1,14 +1,14 @@
import type { RepomixConfigMerged } from "../config/configSchema.js";
import type { RepomixProgressCallback } from "../shared/types.js";
import { collectFiles } from "./file/fileCollect.js";
import { processFiles } from "./file/fileProcess.js";
import { searchFiles } from "./file/fileSearch.js";
import { calculateMetrics } from "./metrics/calculateMetrics.js";
import { generateOutput } from "./output/outputGenerate.js";
import { copyToClipboardIfEnabled } from "./packager/copyToClipboardIfEnabled.js";
import { writeOutputToDisk } from "./packager/writeOutputToDisk.js";
import type { SuspiciousFileResult } from "./security/securityCheck.js";
import { validateFileSafety } from "./security/validateFileSafety.js";
import type { RepomixConfigMerged } from '../config/configSchema.js';
import type { RepomixProgressCallback } from '../shared/types.js';
import { collectFiles } from './file/fileCollect.js';
import { processFiles } from './file/fileProcess.js';
import { searchFiles } from './file/fileSearch.js';
import { calculateMetrics } from './metrics/calculateMetrics.js';
import { generateOutput } from './output/outputGenerate.js';
import { copyToClipboardIfEnabled } from './packager/copyToClipboardIfEnabled.js';
import { writeOutputToDisk } from './packager/writeOutputToDisk.js';
import type { SuspiciousFileResult } from './security/securityCheck.js';
import { validateFileSafety } from './security/validateFileSafety.js';
export interface PackResult {
totalFiles: number;
@@ -32,39 +32,33 @@ export const pack = async (
writeOutputToDisk,
copyToClipboardIfEnabled,
calculateMetrics,
}
},
): Promise<PackResult> => {
progressCallback("Searching for files...");
progressCallback('Searching for files...');
const { filePaths } = await deps.searchFiles(rootDir, config);
progressCallback("Collecting files...");
progressCallback('Collecting files...');
const rawFiles = await deps.collectFiles(filePaths, rootDir);
const { safeFilePaths, safeRawFiles, suspiciousFilesResults } =
await deps.validateFileSafety(rawFiles, progressCallback, config);
// Process files (remove comments, etc.)
progressCallback("Processing files...");
const processedFiles = await deps.processFiles(safeRawFiles, config);
progressCallback("Generating output...");
const output = await deps.generateOutput(
rootDir,
const { safeFilePaths, safeRawFiles, suspiciousFilesResults } = await deps.validateFileSafety(
rawFiles,
progressCallback,
config,
processedFiles,
safeFilePaths
);
progressCallback("Writing output file...");
// Process files (remove comments, etc.)
progressCallback('Processing files...');
const processedFiles = await deps.processFiles(safeRawFiles, config);
progressCallback('Generating output...');
const output = await deps.generateOutput(rootDir, config, processedFiles, safeFilePaths);
progressCallback('Writing output file...');
await deps.writeOutputToDisk(output, config);
await deps.copyToClipboardIfEnabled(output, progressCallback, config);
const metrics = await deps.calculateMetrics(
processedFiles,
output,
progressCallback
);
const metrics = await deps.calculateMetrics(processedFiles, output, progressCallback);
return {
...metrics,

View File

@@ -1,17 +1,17 @@
import clipboard from "clipboardy";
import { RepomixConfigMerged } from "../../config/configSchema.js";
import { logger } from "../../shared/logger.js";
import { type RepomixProgressCallback } from "../../shared/types.js";
import clipboard from 'clipboardy';
import type { RepomixConfigMerged } from '../../config/configSchema.js';
import { logger } from '../../shared/logger.js';
import type { RepomixProgressCallback } from '../../shared/types.js';
// Additionally copy to clipboard if flag is raised
export const copyToClipboardIfEnabled = async (
output: string,
progressCallback: RepomixProgressCallback,
config: RepomixConfigMerged
config: RepomixConfigMerged,
): Promise<undefined> => {
if (config.output.copyToClipboard) {
progressCallback("Copying to clipboard...");
logger.trace("Copying output to clipboard");
progressCallback('Copying to clipboard...');
logger.trace('Copying output to clipboard');
await clipboard.write(output);
}
};

View File

@@ -1,13 +1,10 @@
import path from "path";
import fs from "node:fs/promises";
import { RepomixConfigMerged } from "../../config/configSchema.js";
import { logger } from "../../shared/logger.js";
import fs from 'node:fs/promises';
import path from 'path';
import type { RepomixConfigMerged } from '../../config/configSchema.js';
import { logger } from '../../shared/logger.js';
// Write output to file. path is relative to the cwd
export const writeOutputToDisk = async (
output: string,
config: RepomixConfigMerged
): Promise<undefined> => {
export const writeOutputToDisk = async (output: string, config: RepomixConfigMerged): Promise<undefined> => {
const outputPath = path.resolve(config.cwd, config.output.filePath);
logger.trace(`Writing output to: ${outputPath}`);
await fs.writeFile(outputPath, output);

View File

@@ -1,11 +1,8 @@
import { RawFile } from "../file/fileTypes.js";
import { SuspiciousFileResult } from "./securityCheck.js";
import type { RawFile } from '../file/fileTypes.js';
import type { SuspiciousFileResult } from './securityCheck.js';
export const filterOutUntrustedFiles = (
rawFiles: RawFile[],
suspiciousFilesResults: SuspiciousFileResult[]
suspiciousFilesResults: SuspiciousFileResult[],
): RawFile[] =>
rawFiles.filter(
(rawFile) =>
!suspiciousFilesResults.some((result) => result.filePath === rawFile.path)
);
rawFiles.filter((rawFile) => !suspiciousFilesResults.some((result) => result.filePath === rawFile.path));

View File

@@ -1,16 +1,16 @@
import { RepomixConfigMerged } from "../../config/configSchema.js";
import { RepomixProgressCallback } from "../../shared/types.js";
import { RawFile } from "../file/fileTypes.js";
import { runSecurityCheck, SuspiciousFileResult } from "./securityCheck.js";
import type { RepomixConfigMerged } from '../../config/configSchema.js';
import type { RepomixProgressCallback } from '../../shared/types.js';
import type { RawFile } from '../file/fileTypes.js';
import { type SuspiciousFileResult, runSecurityCheck } from './securityCheck.js';
export const runSecurityCheckIfEnabled = async (
rawFiles: RawFile[],
config: RepomixConfigMerged,
progressCallback: RepomixProgressCallback,
checkSecurity = runSecurityCheck
checkSecurity = runSecurityCheck,
): Promise<SuspiciousFileResult[]> => {
if (config.security.enableSecurityCheck) {
progressCallback("Running security check...");
progressCallback('Running security check...');
return await checkSecurity(rawFiles, progressCallback);
}
return [];

View File

@@ -1,9 +1,9 @@
import { type RepomixConfigMerged } from "../../config/configSchema.js";
import { logger } from "../../shared/logger.js";
import { type RepomixProgressCallback } from "../../shared/types.js";
import { type RawFile } from "../file/fileTypes.js";
import { filterOutUntrustedFiles } from "./filterOutUntrustedFiles.js";
import { runSecurityCheckIfEnabled } from "./runSecurityCheckIfEnabled.js";
import type { RepomixConfigMerged } from '../../config/configSchema.js';
import { logger } from '../../shared/logger.js';
import type { RepomixProgressCallback } from '../../shared/types.js';
import type { RawFile } from '../file/fileTypes.js';
import { filterOutUntrustedFiles } from './filterOutUntrustedFiles.js';
import { runSecurityCheckIfEnabled } from './runSecurityCheckIfEnabled.js';
// marks which files are suspicious and which are safe
export const validateFileSafety = async (
@@ -13,19 +13,12 @@ export const validateFileSafety = async (
deps = {
runSecurityCheckIfEnabled,
filterOutUntrustedFiles,
}
},
) => {
const suspiciousFilesResults = await deps.runSecurityCheckIfEnabled(
rawFiles,
config,
progressCallback
);
const safeRawFiles = deps.filterOutUntrustedFiles(
rawFiles,
suspiciousFilesResults
);
const suspiciousFilesResults = await deps.runSecurityCheckIfEnabled(rawFiles, config, progressCallback);
const safeRawFiles = deps.filterOutUntrustedFiles(rawFiles, suspiciousFilesResults);
const safeFilePaths = safeRawFiles.map((file) => file.path);
logger.trace("Safe files count:", safeRawFiles.length);
logger.trace('Safe files count:', safeRawFiles.length);
return {
safeRawFiles,

View File

@@ -1,62 +1,49 @@
import { describe, it, expect } from "vitest";
import {
aggregateMetrics,
type FileMetrics,
} from "../../../src/core/metrics/aggregateMetrics.js";
import type { ProcessedFile } from "../../../src/core/file/fileTypes.js";
import type { TokenCounter } from "../../../src/core/tokenCount/tokenCount.js";
import { describe, expect, it } from 'vitest';
import type { ProcessedFile } from '../../../src/core/file/fileTypes.js';
import { type FileMetrics, aggregateMetrics } from '../../../src/core/metrics/aggregateMetrics.js';
import type { TokenCounter } from '../../../src/core/tokenCount/tokenCount.js';
describe("aggregateMetrics", () => {
it("should aggregate metrics correctly", () => {
describe('aggregateMetrics', () => {
it('should aggregate metrics correctly', () => {
const fileMetrics: FileMetrics[] = [
{ path: "file1.txt", charCount: 100, tokenCount: 10 },
{ path: "file2.txt", charCount: 200, tokenCount: 20 },
{ path: 'file1.txt', charCount: 100, tokenCount: 10 },
{ path: 'file2.txt', charCount: 200, tokenCount: 20 },
];
const processedFiles: ProcessedFile[] = [
{ path: "file1.txt", content: "a" },
{ path: "file2.txt", content: "b".repeat(200) },
{ path: 'file1.txt', content: 'a' },
{ path: 'file2.txt', content: 'b'.repeat(200) },
];
const output = "a".repeat(300);
const output = 'a'.repeat(300);
const tokenCounter = {
countTokens: (content: string) => content.length / 10,
} as TokenCounter;
const result = aggregateMetrics(
fileMetrics,
processedFiles,
output,
tokenCounter
);
const result = aggregateMetrics(fileMetrics, processedFiles, output, tokenCounter);
expect(result).toEqual({
totalFiles: 2,
totalCharacters: 300,
totalTokens: 30,
fileCharCounts: {
"file1.txt": 100,
"file2.txt": 200,
'file1.txt': 100,
'file2.txt': 200,
},
fileTokenCounts: {
"file1.txt": 10,
"file2.txt": 20,
'file1.txt': 10,
'file2.txt': 20,
},
});
});
it("should handle empty file metrics", () => {
it('should handle empty file metrics', () => {
const fileMetrics: FileMetrics[] = [];
const processedFiles: ProcessedFile[] = [];
const output = "";
const output = '';
const tokenCounter = {
countTokens: (content: string) => content.length / 10,
} as TokenCounter;
const result = aggregateMetrics(
fileMetrics,
processedFiles,
output,
tokenCounter
);
const result = aggregateMetrics(fileMetrics, processedFiles, output, tokenCounter);
expect(result).toEqual({
totalFiles: 0,

View File

@@ -1,20 +1,20 @@
import { describe, it, expect, vi, Mock } from "vitest";
import type { ProcessedFile } from "../../../src/core/file/fileTypes.js";
import { calculateAllFileMetrics } from "../../../src/core/metrics/calculateAllFileMetrics.js";
import type { TokenCounter } from "../../../src/core/tokenCount/tokenCount.js";
import type { RepomixProgressCallback } from "../../../src/shared/types.js";
import { calculateIndividualFileMetrics } from "../../../src/core/metrics/calculateIndividualFileMetrics.js";
import { type Mock, describe, expect, it, vi } from 'vitest';
import type { ProcessedFile } from '../../../src/core/file/fileTypes.js';
import { calculateAllFileMetrics } from '../../../src/core/metrics/calculateAllFileMetrics.js';
import { calculateIndividualFileMetrics } from '../../../src/core/metrics/calculateIndividualFileMetrics.js';
import type { TokenCounter } from '../../../src/core/tokenCount/tokenCount.js';
import type { RepomixProgressCallback } from '../../../src/shared/types.js';
vi.mock("../../../src/core/metrics/calculateIndividualFileMetrics.js");
vi.mock("../../shared/processConcurrency", () => ({
vi.mock('../../../src/core/metrics/calculateIndividualFileMetrics.js');
vi.mock('../../shared/processConcurrency', () => ({
getProcessConcurrency: () => 1,
}));
describe("calculateAllFileMetrics", () => {
it("should calculate metrics for all files", async () => {
describe('calculateAllFileMetrics', () => {
it('should calculate metrics for all files', async () => {
const processedFiles: ProcessedFile[] = [
{ path: "file1.txt", content: "a".repeat(100) },
{ path: "file2.txt", content: "b".repeat(200) },
{ path: 'file1.txt', content: 'a'.repeat(100) },
{ path: 'file2.txt', content: 'b'.repeat(200) },
];
const tokenCounter = {} as TokenCounter;
const progressCallback: RepomixProgressCallback = vi.fn();
@@ -26,19 +26,15 @@ describe("calculateAllFileMetrics", () => {
charCount: file.content.length,
tokenCount: file.content.length / 10,
};
}
},
);
const result = await calculateAllFileMetrics(
processedFiles,
tokenCounter,
progressCallback
);
const result = await calculateAllFileMetrics(processedFiles, tokenCounter, progressCallback);
expect(calculateIndividualFileMetrics).toHaveBeenCalledTimes(2);
expect(result).toEqual([
{ path: "file1.txt", charCount: 100, tokenCount: 10 },
{ path: "file2.txt", charCount: 200, tokenCount: 20 },
{ path: 'file1.txt', charCount: 100, tokenCount: 10 },
{ path: 'file2.txt', charCount: 200, tokenCount: 20 },
]);
});
});

View File

@@ -1,13 +1,13 @@
import pc from "picocolors";
import { describe, expect, it, vi } from "vitest";
import type { ProcessedFile } from "../../../src/core/file/fileTypes.js";
import { calculateIndividualFileMetrics } from "../../../src/core/metrics/calculateIndividualFileMetrics.js";
import type { TokenCounter } from "../../../src/core/tokenCount/tokenCount.js";
import type { RepomixProgressCallback } from "../../../src/shared/types.js";
import pc from 'picocolors';
import { describe, expect, it, vi } from 'vitest';
import type { ProcessedFile } from '../../../src/core/file/fileTypes.js';
import { calculateIndividualFileMetrics } from '../../../src/core/metrics/calculateIndividualFileMetrics.js';
import type { TokenCounter } from '../../../src/core/tokenCount/tokenCount.js';
import type { RepomixProgressCallback } from '../../../src/shared/types.js';
describe("calculateIndividualFileMetrics", () => {
it("should calculate file metrics and report progress", async () => {
const file: ProcessedFile = { path: "file1.txt", content: "a".repeat(100) };
describe('calculateIndividualFileMetrics', () => {
it('should calculate file metrics and report progress', async () => {
const file: ProcessedFile = { path: 'file1.txt', content: 'a'.repeat(100) };
const index = 0;
const totalFiles = 1;
const tokenCounter = {
@@ -15,23 +15,12 @@ describe("calculateIndividualFileMetrics", () => {
} as unknown as TokenCounter;
const progressCallback: RepomixProgressCallback = vi.fn();
const result = await calculateIndividualFileMetrics(
file,
index,
totalFiles,
tokenCounter,
progressCallback
);
const result = await calculateIndividualFileMetrics(file, index, totalFiles, tokenCounter, progressCallback);
expect(tokenCounter.countTokens).toHaveBeenCalledWith(
file.content,
file.path
);
expect(progressCallback).toHaveBeenCalledWith(
`Calculating metrics... (1/1) ${pc.dim("file1.txt")}`
);
expect(tokenCounter.countTokens).toHaveBeenCalledWith(file.content, file.path);
expect(progressCallback).toHaveBeenCalledWith(`Calculating metrics... (1/1) ${pc.dim('file1.txt')}`);
expect(result).toEqual({
path: "file1.txt",
path: 'file1.txt',
charCount: 100,
tokenCount: 10,
});

View File

@@ -1,35 +1,33 @@
import { describe, it, expect, vi, Mock } from "vitest";
import { ProcessedFile } from "../../../src/core/file/fileTypes.js";
import { aggregateMetrics } from "../../../src/core/metrics/aggregateMetrics.js";
import { calculateAllFileMetrics } from "../../../src/core/metrics/calculateAllFileMetrics.js";
import { calculateMetrics } from "../../../src/core/metrics/calculateMetrics.js";
import { TokenCounter } from "../../../src/core/tokenCount/tokenCount.js";
import { RepomixProgressCallback } from "../../../src/shared/types.js";
import { type Mock, describe, expect, it, vi } from 'vitest';
import type { ProcessedFile } from '../../../src/core/file/fileTypes.js';
import { aggregateMetrics } from '../../../src/core/metrics/aggregateMetrics.js';
import { calculateAllFileMetrics } from '../../../src/core/metrics/calculateAllFileMetrics.js';
import { calculateMetrics } from '../../../src/core/metrics/calculateMetrics.js';
import { TokenCounter } from '../../../src/core/tokenCount/tokenCount.js';
import type { RepomixProgressCallback } from '../../../src/shared/types.js';
vi.mock("../../../src/core/tokenCount/tokenCount.js");
vi.mock("../../../src/core/metrics/aggregateMetrics.js");
vi.mock("../../../src/core/metrics/calculateAllFileMetrics.js");
vi.mock('../../../src/core/tokenCount/tokenCount.js');
vi.mock('../../../src/core/metrics/aggregateMetrics.js');
vi.mock('../../../src/core/metrics/calculateAllFileMetrics.js');
describe("calculateMetrics", () => {
it("should calculate metrics and return the result", async () => {
describe('calculateMetrics', () => {
it('should calculate metrics and return the result', async () => {
const processedFiles: ProcessedFile[] = [
{ path: "file1.txt", content: "a".repeat(100) },
{ path: "file2.txt", content: "b".repeat(200) },
{ path: 'file1.txt', content: 'a'.repeat(100) },
{ path: 'file2.txt', content: 'b'.repeat(200) },
];
const output = "a".repeat(300);
const output = 'a'.repeat(300);
const progressCallback: RepomixProgressCallback = vi.fn();
const mockTokenCounter = {
countTokens: vi.fn(),
free: vi.fn(),
};
(TokenCounter as unknown as Mock).mockImplementation(
() => mockTokenCounter
);
(TokenCounter as unknown as Mock).mockImplementation(() => mockTokenCounter);
const fileMetrics = [
{ path: "file1.txt", charCount: 100, tokenCount: 10 },
{ path: "file2.txt", charCount: 200, tokenCount: 20 },
{ path: 'file1.txt', charCount: 100, tokenCount: 10 },
{ path: 'file2.txt', charCount: 200, tokenCount: 20 },
];
(calculateAllFileMetrics as unknown as Mock).mockResolvedValue(fileMetrics);
@@ -38,34 +36,21 @@ describe("calculateMetrics", () => {
totalCharacters: 300,
totalTokens: 30,
fileCharCounts: {
"file1.txt": 100,
"file2.txt": 200,
'file1.txt': 100,
'file2.txt': 200,
},
fileTokenCounts: {
"file1.txt": 10,
"file2.txt": 20,
'file1.txt': 10,
'file2.txt': 20,
},
};
(aggregateMetrics as unknown as vi.Mock).mockReturnValue(aggregatedResult);
const result = await calculateMetrics(
processedFiles,
output,
progressCallback
);
const result = await calculateMetrics(processedFiles, output, progressCallback);
expect(progressCallback).toHaveBeenCalledWith("Calculating metrics...");
expect(calculateAllFileMetrics).toHaveBeenCalledWith(
processedFiles,
mockTokenCounter,
progressCallback
);
expect(aggregateMetrics).toHaveBeenCalledWith(
fileMetrics,
processedFiles,
output,
mockTokenCounter
);
expect(progressCallback).toHaveBeenCalledWith('Calculating metrics...');
expect(calculateAllFileMetrics).toHaveBeenCalledWith(processedFiles, mockTokenCounter, progressCallback);
expect(aggregateMetrics).toHaveBeenCalledWith(fileMetrics, processedFiles, output, mockTokenCounter);
expect(mockTokenCounter.free).toHaveBeenCalled();
expect(result).toEqual(aggregatedResult);
});

View File

@@ -1,39 +1,39 @@
import path from "node:path";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { pack } from "../../src/core/packager.js";
import { TokenCounter } from "../../src/core/tokenCount/tokenCount.js";
import { createMockConfig } from "../testing/testUtils.js";
import path from 'node:path';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import { pack } from '../../src/core/packager.js';
import { TokenCounter } from '../../src/core/tokenCount/tokenCount.js';
import { createMockConfig } from '../testing/testUtils.js';
vi.mock("node:fs/promises");
vi.mock("fs/promises");
vi.mock("../../src/core/tokenCount/tokenCount");
vi.mock("clipboardy", () => ({
vi.mock('node:fs/promises');
vi.mock('fs/promises');
vi.mock('../../src/core/tokenCount/tokenCount');
vi.mock('clipboardy', () => ({
default: {
write: vi.fn(),
},
}));
describe("packager", () => {
describe('packager', () => {
beforeEach(() => {
vi.resetAllMocks();
});
test("pack should orchestrate packing files and generating output", async () => {
const file2Path = path.join("dir1", "file2.txt");
test('pack should orchestrate packing files and generating output', async () => {
const file2Path = path.join('dir1', 'file2.txt');
const mockRawFiles = [
{ path: "file1.txt", content: "raw content 1" },
{ path: file2Path, content: "raw content 2" },
{ path: 'file1.txt', content: 'raw content 1' },
{ path: file2Path, content: 'raw content 2' },
];
const mockSafeRawFiles = [
{ path: "file1.txt", content: "safed content 1" },
{ path: file2Path, content: "safed content 2" },
{ path: 'file1.txt', content: 'safed content 1' },
{ path: file2Path, content: 'safed content 2' },
];
const mockProcessedFiles = [
{ path: "file1.txt", content: "processed content 1" },
{ path: file2Path, content: "processed content 2" },
{ path: 'file1.txt', content: 'processed content 1' },
{ path: file2Path, content: 'processed content 2' },
];
const mockOutput = "mock output";
const mockFilePaths = ["file1.txt", file2Path];
const mockOutput = 'mock output';
const mockFilePaths = ['file1.txt', file2Path];
const mockDeps = {
searchFiles: vi.fn().mockResolvedValue({
@@ -55,11 +55,11 @@ describe("packager", () => {
totalCharacters: 11,
totalTokens: 10,
fileCharCounts: {
"file1.txt": 19,
'file1.txt': 19,
[file2Path]: 19,
},
fileTokenCounts: {
"file1.txt": 10,
'file1.txt': 10,
[file2Path]: 10,
},
}),
@@ -69,56 +69,33 @@ describe("packager", () => {
const mockConfig = createMockConfig();
const progressCallback = vi.fn();
const result = await pack("root", mockConfig, progressCallback, mockDeps);
const result = await pack('root', mockConfig, progressCallback, mockDeps);
expect(mockDeps.searchFiles).toHaveBeenCalledWith("root", mockConfig);
expect(mockDeps.collectFiles).toHaveBeenCalledWith(mockFilePaths, "root");
expect(mockDeps.searchFiles).toHaveBeenCalledWith('root', mockConfig);
expect(mockDeps.collectFiles).toHaveBeenCalledWith(mockFilePaths, 'root');
expect(mockDeps.validateFileSafety).toHaveBeenCalled();
expect(mockDeps.processFiles).toHaveBeenCalled();
expect(mockDeps.writeOutputToDisk).toHaveBeenCalled();
expect(mockDeps.generateOutput).toHaveBeenCalled();
expect(mockDeps.calculateMetrics).toHaveBeenCalled();
expect(mockDeps.validateFileSafety).toHaveBeenCalledWith(
mockRawFiles,
progressCallback,
mockConfig
);
expect(mockDeps.processFiles).toHaveBeenCalledWith(
mockSafeRawFiles,
mockConfig
);
expect(mockDeps.generateOutput).toHaveBeenCalledWith(
"root",
mockConfig,
mockProcessedFiles,
mockFilePaths
);
expect(mockDeps.writeOutputToDisk).toHaveBeenCalledWith(
mockOutput,
mockConfig
);
expect(mockDeps.copyToClipboardIfEnabled).toHaveBeenCalledWith(
mockOutput,
progressCallback,
mockConfig
);
expect(mockDeps.calculateMetrics).toHaveBeenCalledWith(
mockProcessedFiles,
mockOutput,
progressCallback
);
expect(mockDeps.validateFileSafety).toHaveBeenCalledWith(mockRawFiles, progressCallback, mockConfig);
expect(mockDeps.processFiles).toHaveBeenCalledWith(mockSafeRawFiles, mockConfig);
expect(mockDeps.generateOutput).toHaveBeenCalledWith('root', mockConfig, mockProcessedFiles, mockFilePaths);
expect(mockDeps.writeOutputToDisk).toHaveBeenCalledWith(mockOutput, mockConfig);
expect(mockDeps.copyToClipboardIfEnabled).toHaveBeenCalledWith(mockOutput, progressCallback, mockConfig);
expect(mockDeps.calculateMetrics).toHaveBeenCalledWith(mockProcessedFiles, mockOutput, progressCallback);
// Check the result of pack function
expect(result.totalFiles).toBe(2);
expect(result.totalCharacters).toBe(11);
expect(result.totalTokens).toBe(10);
expect(result.fileCharCounts).toEqual({
"file1.txt": 19,
'file1.txt': 19,
[file2Path]: 19,
});
expect(result.fileTokenCounts).toEqual({
"file1.txt": 10,
'file1.txt': 10,
[file2Path]: 10,
});
});

View File

@@ -1,20 +1,20 @@
import clipboard from "clipboardy";
import { logger } from "handlebars";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { type RepomixConfigMerged } from "../../../src/config/configSchema.js";
import { copyToClipboardIfEnabled } from "../../../src/core/packager/copyToClipboardIfEnabled.js";
import { type RepomixProgressCallback } from "../../../src/shared/types.js";
import clipboard from 'clipboardy';
import { logger } from 'handlebars';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { RepomixConfigMerged } from '../../../src/config/configSchema.js';
import { copyToClipboardIfEnabled } from '../../../src/core/packager/copyToClipboardIfEnabled.js';
import type { RepomixProgressCallback } from '../../../src/shared/types.js';
vi.mock("clipboardy");
vi.mock("../../shared/logger");
vi.mock('clipboardy');
vi.mock('../../shared/logger');
describe("copyToClipboardIfEnabled", () => {
describe('copyToClipboardIfEnabled', () => {
beforeEach(() => {
vi.resetAllMocks();
});
it("should copy output to clipboard if flag enabled in config", async () => {
const output = "test output";
it('should copy output to clipboard if flag enabled in config', async () => {
const output = 'test output';
const config: RepomixConfigMerged = {
output: { copyToClipboard: true },
} as RepomixConfigMerged;
@@ -22,12 +22,12 @@ describe("copyToClipboardIfEnabled", () => {
await copyToClipboardIfEnabled(output, progressCallback, config);
expect(progressCallback).toHaveBeenCalledWith("Copying to clipboard...");
expect(progressCallback).toHaveBeenCalledWith('Copying to clipboard...');
expect(clipboard.write).toHaveBeenCalledWith(output);
});
it("should not copy output to clipboard if flag disabled in config", async () => {
const output = "test output";
it('should not copy output to clipboard if flag disabled in config', async () => {
const output = 'test output';
const config: RepomixConfigMerged = {
output: { copyToClipboard: false },
} as RepomixConfigMerged;

View File

@@ -1,18 +1,18 @@
import { describe, it, expect, vi } from "vitest";
import path from "path";
import fs from "node:fs/promises";
import { type RepomixConfigMerged } from "../../../src/config/configSchema.js";
import { writeOutputToDisk } from "../../../src/core/packager/writeOutputToDisk.js";
import fs from 'node:fs/promises';
import path from 'path';
import { describe, expect, it, vi } from 'vitest';
import type { RepomixConfigMerged } from '../../../src/config/configSchema.js';
import { writeOutputToDisk } from '../../../src/core/packager/writeOutputToDisk.js';
vi.mock("node:fs/promises");
vi.mock("../../shared/logger");
vi.mock('node:fs/promises');
vi.mock('../../shared/logger');
describe("writeOutputToDisk", () => {
it("should write output to the specified file path", async () => {
const output = "test output";
describe('writeOutputToDisk', () => {
it('should write output to the specified file path', async () => {
const output = 'test output';
const config: RepomixConfigMerged = {
cwd: "/test/directory",
output: { filePath: "output.txt" },
cwd: '/test/directory',
output: { filePath: 'output.txt' },
} as RepomixConfigMerged;
const outputPath = path.resolve(config.cwd, config.output.filePath);

View File

@@ -1,17 +1,17 @@
import { describe, expect, it } from "vitest";
import { RawFile } from "../../../src/core/file/fileTypes.js";
import { filterOutUntrustedFiles } from "../../../src/core/security/filterOutUntrustedFiles.js";
import { SuspiciousFileResult } from "../../../src/core/security/securityCheck.js";
import { describe, expect, it } from 'vitest';
import type { RawFile } from '../../../src/core/file/fileTypes.js';
import { filterOutUntrustedFiles } from '../../../src/core/security/filterOutUntrustedFiles.js';
import type { SuspiciousFileResult } from '../../../src/core/security/securityCheck.js';
describe("filterOutUntrustedFiles", () => {
it("should filter out untrusted files", () => {
describe('filterOutUntrustedFiles', () => {
it('should filter out untrusted files', () => {
const rawFiles: RawFile[] = [
{ path: "file1.txt", content: "content 1" },
{ path: "file2.txt", content: "content 2" },
{ path: "file3.txt", content: "content 3" },
{ path: 'file1.txt', content: 'content 1' },
{ path: 'file2.txt', content: 'content 2' },
{ path: 'file3.txt', content: 'content 3' },
];
const suspiciousFilesResults: SuspiciousFileResult[] = [
{ filePath: "file2.txt", messages: ["something suspicious."] },
{ filePath: 'file2.txt', messages: ['something suspicious.'] },
];
const expectedGoodFiles = [rawFiles[0], rawFiles[2]];
@@ -20,11 +20,11 @@ describe("filterOutUntrustedFiles", () => {
expect(result).toEqual(expectedGoodFiles);
});
it("should return all files if no suspicious files", () => {
it('should return all files if no suspicious files', () => {
const rawFiles: RawFile[] = [
{ path: "file1.txt", content: "content 1" },
{ path: "file2.txt", content: "content 2" },
{ path: "file3.txt", content: "content 3" },
{ path: 'file1.txt', content: 'content 1' },
{ path: 'file2.txt', content: 'content 2' },
{ path: 'file3.txt', content: 'content 3' },
];
const suspiciousFilesResults: SuspiciousFileResult[] = [];

View File

@@ -1,40 +1,33 @@
import { describe, it, expect, vi } from "vitest";
import { RepomixConfigMerged } from "../../../src/config/configSchema.js";
import { RawFile } from "../../../src/core/file/fileTypes.js";
import { runSecurityCheckIfEnabled } from "../../../src/core/security/runSecurityCheckIfEnabled.js";
import { SuspiciousFileResult } from "../../../src/core/security/securityCheck.js";
import { RepomixProgressCallback } from "../../../src/shared/types.js";
import { describe, expect, it, vi } from 'vitest';
import type { RepomixConfigMerged } from '../../../src/config/configSchema.js';
import type { RawFile } from '../../../src/core/file/fileTypes.js';
import { runSecurityCheckIfEnabled } from '../../../src/core/security/runSecurityCheckIfEnabled.js';
import type { SuspiciousFileResult } from '../../../src/core/security/securityCheck.js';
import type { RepomixProgressCallback } from '../../../src/shared/types.js';
describe("runSecurityCheckIfEnabled", () => {
it("should run security check if enabled in config", async () => {
describe('runSecurityCheckIfEnabled', () => {
it('should run security check if enabled in config', async () => {
const rawFiles: RawFile[] = [
{ path: "file1.txt", content: "contents1" },
{ path: "file2.txt", content: "contents2" },
{ path: 'file1.txt', content: 'contents1' },
{ path: 'file2.txt', content: 'contents2' },
];
const config: RepomixConfigMerged = {
security: { enableSecurityCheck: true },
} as RepomixConfigMerged;
const progressCallback: RepomixProgressCallback = vi.fn();
const checkSecurity = vi
.fn()
.mockResolvedValue([{ filePath: "file1.txt" }] as SuspiciousFileResult[]);
const checkSecurity = vi.fn().mockResolvedValue([{ filePath: 'file1.txt' }] as SuspiciousFileResult[]);
const result = await runSecurityCheckIfEnabled(
rawFiles,
config,
progressCallback,
checkSecurity
);
const result = await runSecurityCheckIfEnabled(rawFiles, config, progressCallback, checkSecurity);
expect(progressCallback).toHaveBeenCalledWith("Running security check...");
expect(progressCallback).toHaveBeenCalledWith('Running security check...');
expect(checkSecurity).toHaveBeenCalledWith(rawFiles, progressCallback);
expect(result).toEqual([{ filePath: "file1.txt" }]);
expect(result).toEqual([{ filePath: 'file1.txt' }]);
});
it("should not run security check if disabled in config", async () => {
it('should not run security check if disabled in config', async () => {
const rawFiles: RawFile[] = [
{ path: "file1.txt", content: "contents1" },
{ path: "file2.txt", content: "contents2" },
{ path: 'file1.txt', content: 'contents1' },
{ path: 'file2.txt', content: 'contents2' },
];
const config: RepomixConfigMerged = {
security: { enableSecurityCheck: false },
@@ -42,12 +35,7 @@ describe("runSecurityCheckIfEnabled", () => {
const progressCallback: RepomixProgressCallback = vi.fn();
const checkSecurity = vi.fn();
const result = await runSecurityCheckIfEnabled(
rawFiles,
config,
progressCallback,
checkSecurity
);
const result = await runSecurityCheckIfEnabled(rawFiles, config, progressCallback, checkSecurity);
expect(progressCallback).not.toHaveBeenCalled();
expect(checkSecurity).not.toHaveBeenCalled();

View File

@@ -1,16 +1,16 @@
import { describe, it, expect, vi } from "vitest";
import { type RepomixConfigMerged } from "../../../src/config/configSchema.js";
import { type RawFile } from "../../../src/core/file/fileTypes.js";
import { type SuspiciousFileResult } from "../../../src/core/security/securityCheck.js";
import { validateFileSafety } from "../../../src/core/security/validateFileSafety.js";
import { type RepomixProgressCallback } from "../../../src/shared/types.js";
import { describe, expect, it, vi } from 'vitest';
import type { RepomixConfigMerged } from '../../../src/config/configSchema.js';
import type { RawFile } from '../../../src/core/file/fileTypes.js';
import type { SuspiciousFileResult } from '../../../src/core/security/securityCheck.js';
import { validateFileSafety } from '../../../src/core/security/validateFileSafety.js';
import type { RepomixProgressCallback } from '../../../src/shared/types.js';
describe("validateFileSafety", () => {
it("should validate file safety and return safe files and paths", async () => {
describe('validateFileSafety', () => {
it('should validate file safety and return safe files and paths', async () => {
const rawFiles: RawFile[] = [
{ path: "file1.txt", content: "content1" },
{ path: "file2.txt", content: "content2" },
{ path: "file3.txt", content: "content3" },
{ path: 'file1.txt', content: 'content1' },
{ path: 'file2.txt', content: 'content2' },
{ path: 'file3.txt', content: 'content3' },
];
const safeRawFiles = [rawFiles[0], rawFiles[1]];
const config: RepomixConfigMerged = {
@@ -18,34 +18,20 @@ describe("validateFileSafety", () => {
} as RepomixConfigMerged;
const progressCallback: RepomixProgressCallback = vi.fn();
const suspiciousFilesResults: SuspiciousFileResult[] = [
{ filePath: "file2.txt", messages: ["something suspicious."] },
{ filePath: 'file2.txt', messages: ['something suspicious.'] },
];
const deps = {
runSecurityCheckIfEnabled: vi
.fn()
.mockResolvedValue(suspiciousFilesResults),
runSecurityCheckIfEnabled: vi.fn().mockResolvedValue(suspiciousFilesResults),
filterOutUntrustedFiles: vi.fn().mockReturnValue(safeRawFiles),
};
const result = await validateFileSafety(
rawFiles,
progressCallback,
config,
deps
);
const result = await validateFileSafety(rawFiles, progressCallback, config, deps);
expect(deps.runSecurityCheckIfEnabled).toHaveBeenCalledWith(
rawFiles,
config,
progressCallback
);
expect(deps.filterOutUntrustedFiles).toHaveBeenCalledWith(
rawFiles,
suspiciousFilesResults
);
expect(deps.runSecurityCheckIfEnabled).toHaveBeenCalledWith(rawFiles, config, progressCallback);
expect(deps.filterOutUntrustedFiles).toHaveBeenCalledWith(rawFiles, suspiciousFilesResults);
expect(result).toEqual({
safeRawFiles,
safeFilePaths: ["file1.txt", "file2.txt"],
safeFilePaths: ['file1.txt', 'file2.txt'],
suspiciousFilesResults,
});
});