178 lines
8.0 KiB
TypeScript
178 lines
8.0 KiB
TypeScript
import * as path from 'node:path'
|
|
import * as fsSync from 'node:fs' // For reading test file content directly
|
|
// import * as fs from 'node:fs/promises' // No longer needed for this test
|
|
import { describe, it, expect } from 'vitest' // Removed afterAll, beforeAll
|
|
import { E_Mode, run, IKBotTask, complete_options, complete_messages, complete_params, E_WrapMode } from '../../src/index'
|
|
// import { LOGGING_DIRECTORY } from '../../src/constants.js' // No longer needed for this test
|
|
// import { sync as rimrafSync } from 'rimraf' // No longer needed for this test
|
|
|
|
describe('globExtension with collected files verification', () => {
|
|
const testDataBaseDir = path.resolve(__dirname, '../test-data');
|
|
const testDataRoot = path.resolve(testDataBaseDir, 'glob');
|
|
// const defaultLogsDir = path.resolve(LOGGING_DIRECTORY); // No longer needed
|
|
// const paramsJsonPath = path.resolve(defaultLogsDir, 'params.json'); // No longer needed
|
|
|
|
// beforeAll/afterAll for log cleanup removed
|
|
|
|
const expectedFileNames = [
|
|
'PHApp.h',
|
|
'PHApp.cpp',
|
|
'PHApp-Modbus.cpp',
|
|
'PHApp-Profiles.cpp',
|
|
'PHAppNetwork.cpp',
|
|
'PHAppSettings.cpp',
|
|
'PHAppWeb.cpp',
|
|
'PHApp.md'
|
|
];
|
|
const expectedAbsoluteFilePaths = expectedFileNames.map(f => path.normalize(path.resolve(testDataRoot, f)));
|
|
|
|
const mockLogger = {
|
|
debug: () => {}, info: () => {}, warn: () => {}, error: () => {}, fatal: () => {},
|
|
} as any;
|
|
|
|
it('should collect .h, related .cpp, and .md files when using brace expansion in globExtension', async () => {
|
|
const initialOpts: IKBotTask = {
|
|
path: testDataRoot,
|
|
include: ['*.h'],
|
|
globExtension: '${SRC_DIR}/${SRC_NAME}*.{cpp,md}',
|
|
mode: E_Mode.COMPLETION,
|
|
prompt: 'test-prompt-direct-file-check',
|
|
logger: mockLogger,
|
|
// wrap: 'none' // Default is 'none', explicitly test this or remove for default
|
|
};
|
|
|
|
// 1. Complete Options
|
|
const completedOptions = await complete_options(initialOpts);
|
|
expect(completedOptions).not.toBeNull();
|
|
if (!completedOptions) return;
|
|
|
|
// 2. Complete Messages - and get the raw `files` array
|
|
const { files: collectedFileObjects } = await complete_messages(initialOpts, completedOptions);
|
|
expect(collectedFileObjects).toBeInstanceOf(Array);
|
|
|
|
// 3. Assert directly on the paths from collectedFileObjects
|
|
// These paths should be relative to `completedOptions.path` (which is testDataRoot)
|
|
const actualCollectedPaths: string[] = collectedFileObjects
|
|
.map((fileObj: any) => {
|
|
if (fileObj && typeof fileObj.path === 'string') {
|
|
return path.normalize(path.resolve(testDataRoot, fileObj.path));
|
|
}
|
|
return null;
|
|
})
|
|
.filter((p: string | null) => p !== null) as string[];
|
|
|
|
const collectedPathsSet = new Set(actualCollectedPaths);
|
|
|
|
// console.log("Expected absolute paths:", expectedAbsoluteFilePaths);
|
|
// console.log("Actual collected absolute paths:", actualCollectedPaths);
|
|
|
|
expectedAbsoluteFilePaths.forEach(expectedFile => {
|
|
expect(collectedPathsSet.has(expectedFile), `Expected file ${path.basename(expectedFile)} (${expectedFile}) to be collected.`).toBe(true);
|
|
});
|
|
|
|
expect(collectedPathsSet.size, "Number of unique collected files should match expected").toBe(expectedAbsoluteFilePaths.length);
|
|
}, 10000);
|
|
});
|
|
|
|
describe('globExtension and wrap modes with complete_params output', () => {
|
|
const testDataBaseDir = path.resolve(__dirname, '../test-data');
|
|
const testDataRoot = path.resolve(testDataBaseDir, 'glob');
|
|
|
|
const expectedFileNamesDefaultTest = [
|
|
'PHApp.h',
|
|
'PHApp.cpp',
|
|
'PHApp-Modbus.cpp',
|
|
'PHApp-Profiles.cpp',
|
|
'PHAppNetwork.cpp',
|
|
'PHAppSettings.cpp',
|
|
'PHAppWeb.cpp',
|
|
'PHApp.md'
|
|
];
|
|
const expectedAbsoluteFilePathsDefaultTest = expectedFileNamesDefaultTest.map(f => path.normalize(path.resolve(testDataRoot, f)));
|
|
|
|
const mockLogger = {
|
|
debug: () => {}, info: () => {}, warn: () => {}, error: () => {}, fatal: () => {},
|
|
} as any;
|
|
|
|
it('should collect .h, related .cpp, and .md files when using brace expansion in globExtension (default wrap:none)', async () => {
|
|
const initialOpts: IKBotTask = {
|
|
path: testDataRoot,
|
|
include: ['*.h'],
|
|
globExtension: '${SRC_DIR}/${SRC_NAME}*.{cpp,md}',
|
|
mode: E_Mode.COMPLETION,
|
|
prompt: 'test-prompt-direct-file-check',
|
|
logger: mockLogger,
|
|
};
|
|
// ... (existing test logic for wrap:none - this test remains the same)
|
|
// 1. Complete Options
|
|
const completedOptions = await complete_options(initialOpts);
|
|
expect(completedOptions).not.toBeNull();
|
|
if (!completedOptions) return;
|
|
|
|
// 2. Complete Messages - and get the raw `files` array
|
|
const { files: collectedFileObjects } = await complete_messages(initialOpts, completedOptions);
|
|
expect(collectedFileObjects).toBeInstanceOf(Array);
|
|
|
|
const actualCollectedPaths: string[] = collectedFileObjects
|
|
.map((fileObj: any) => {
|
|
if (fileObj && typeof fileObj.path === 'string') {
|
|
return path.normalize(path.resolve(testDataRoot, fileObj.path));
|
|
}
|
|
return null;
|
|
})
|
|
.filter((p: string | null) => p !== null) as string[];
|
|
|
|
const collectedPathsSet = new Set(actualCollectedPaths);
|
|
expectedAbsoluteFilePathsDefaultTest.forEach(expectedFile => {
|
|
expect(collectedPathsSet.has(expectedFile), `Expected file ${path.basename(expectedFile)} (${expectedFile}) to be collected.`).toBe(true);
|
|
});
|
|
expect(collectedPathsSet.size, "Number of unique collected files should match expected").toBe(expectedAbsoluteFilePathsDefaultTest.length);
|
|
}, 10000);
|
|
|
|
// New test case for wrap: 'meta'
|
|
it('should correctly wrap content with metadata when options.wrap is \'meta\'', async () => {
|
|
const targetFileName = 'PHApp.h';
|
|
const targetFileAbsolutePath = path.normalize(path.resolve(testDataRoot, targetFileName));
|
|
const originalFileContent = fsSync.readFileSync(targetFileAbsolutePath, 'utf-8');
|
|
|
|
const initialOptsMeta: IKBotTask = {
|
|
path: testDataRoot,
|
|
include: [targetFileName], // Focus on a single known text file
|
|
wrap: E_WrapMode.enum.meta, // Explicitly set wrap mode to meta
|
|
mode: E_Mode.COMPLETION,
|
|
prompt: 'test-prompt-wrap-meta',
|
|
logger: mockLogger,
|
|
};
|
|
|
|
const completedOptionsMeta = await complete_options(initialOptsMeta);
|
|
expect(completedOptionsMeta).not.toBeNull();
|
|
if (!completedOptionsMeta) return;
|
|
|
|
const { messages: gatheredMessagesMeta } = await complete_messages(initialOptsMeta, completedOptionsMeta);
|
|
const finalParamsMeta = await complete_params(completedOptionsMeta, gatheredMessagesMeta);
|
|
|
|
const targetFileMessage = finalParamsMeta.messages.find((msg: any) => {
|
|
if (msg.role === 'user' && typeof msg.content === 'string') {
|
|
// Check if the content contains the file path, good indicator for meta-wrapped file
|
|
// More robust: check if msg.content includes `File: ${targetFileName}`
|
|
return msg.content.includes(`File: ${targetFileName}`);
|
|
}
|
|
return false;
|
|
});
|
|
|
|
expect(targetFileMessage, `Message for ${targetFileName} should be found`).toBeDefined();
|
|
if (!targetFileMessage) return;
|
|
|
|
const messageContent = targetFileMessage.content as string;
|
|
expect(messageContent).toContain(`File: ${targetFileName}`);
|
|
expect(messageContent).toContain(`Absolute Path: ${targetFileAbsolutePath}`);
|
|
// expect(messageContent).toContain(`CWD: ${process.cwd()}`); // CWD can vary based on test runner, more fragile
|
|
expect(messageContent).toContain('\nOriginal Content:\n' + originalFileContent);
|
|
expect(messageContent.startsWith('IMPORTANT: The following information is file metadata.')).toBe(true);
|
|
expect(messageContent.includes('METADATA_START')).toBe(true);
|
|
expect(messageContent.includes('METADATA_END')).toBe(true);
|
|
}, 10000);
|
|
|
|
});
|
|
|
|
// To run this test, you would typically use your npm script, e.g., `npm run vi-test` or `npx vitest`
|