mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 08:47:44 +00:00
chore: sync gemini-cli v0.1.19
This commit is contained in:
@@ -50,6 +50,7 @@ describe('useAtCompletion', () => {
|
||||
respectGitIgnore: true,
|
||||
respectGeminiIgnore: true,
|
||||
})),
|
||||
getEnableRecursiveFileSearch: () => true,
|
||||
} as unknown as Config;
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
@@ -113,8 +114,8 @@ describe('useAtCompletion', () => {
|
||||
expect(result.current.suggestions.map((s) => s.value)).toEqual([
|
||||
'src/',
|
||||
'src/components/',
|
||||
'src/components/Button.tsx',
|
||||
'src/index.js',
|
||||
'src/components/Button.tsx',
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -156,7 +157,7 @@ describe('useAtCompletion', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT show a loading indicator for subsequent searches that complete under 100ms', async () => {
|
||||
it('should NOT show a loading indicator for subsequent searches that complete under 200ms', async () => {
|
||||
const structure: FileSystemStructure = { 'a.txt': '', 'b.txt': '' };
|
||||
testRootDir = await createTmpDir(structure);
|
||||
|
||||
@@ -185,7 +186,7 @@ describe('useAtCompletion', () => {
|
||||
expect(result.current.isLoadingSuggestions).toBe(false);
|
||||
});
|
||||
|
||||
it('should show a loading indicator and clear old suggestions for subsequent searches that take longer than 100ms', async () => {
|
||||
it('should show a loading indicator and clear old suggestions for subsequent searches that take longer than 200ms', async () => {
|
||||
const structure: FileSystemStructure = { 'a.txt': '', 'b.txt': '' };
|
||||
testRootDir = await createTmpDir(structure);
|
||||
|
||||
@@ -193,7 +194,7 @@ describe('useAtCompletion', () => {
|
||||
const originalSearch = FileSearch.prototype.search;
|
||||
vi.spyOn(FileSearch.prototype, 'search').mockImplementation(
|
||||
async function (...args) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
return originalSearch.apply(this, args);
|
||||
},
|
||||
);
|
||||
@@ -283,6 +284,61 @@ describe('useAtCompletion', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('State Management', () => {
|
||||
it('should reset the state when disabled after being in a READY state', async () => {
|
||||
const structure: FileSystemStructure = { 'a.txt': '' };
|
||||
testRootDir = await createTmpDir(structure);
|
||||
|
||||
const { result, rerender } = renderHook(
|
||||
({ enabled }) =>
|
||||
useTestHarnessForAtCompletion(enabled, 'a', mockConfig, testRootDir),
|
||||
{ initialProps: { enabled: true } },
|
||||
);
|
||||
|
||||
// Wait for the hook to be ready and have suggestions
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.map((s) => s.value)).toEqual([
|
||||
'a.txt',
|
||||
]);
|
||||
});
|
||||
|
||||
// Now, disable the hook
|
||||
rerender({ enabled: false });
|
||||
|
||||
// The suggestions should be cleared immediately because of the RESET action
|
||||
expect(result.current.suggestions).toEqual([]);
|
||||
});
|
||||
|
||||
it('should reset the state when disabled after being in an ERROR state', async () => {
|
||||
testRootDir = await createTmpDir({});
|
||||
|
||||
// Force an error during initialization
|
||||
vi.spyOn(FileSearch.prototype, 'initialize').mockRejectedValueOnce(
|
||||
new Error('Initialization failed'),
|
||||
);
|
||||
|
||||
const { result, rerender } = renderHook(
|
||||
({ enabled }) =>
|
||||
useTestHarnessForAtCompletion(enabled, '', mockConfig, testRootDir),
|
||||
{ initialProps: { enabled: true } },
|
||||
);
|
||||
|
||||
// Wait for the hook to enter the error state
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoadingSuggestions).toBe(false);
|
||||
});
|
||||
expect(result.current.suggestions).toEqual([]); // No suggestions on error
|
||||
|
||||
// Now, disable the hook
|
||||
rerender({ enabled: false });
|
||||
|
||||
// The state should still be reset (though visually it's the same)
|
||||
// We can't directly inspect the internal state, but we can ensure it doesn't crash
|
||||
// and the suggestions remain empty.
|
||||
expect(result.current.suggestions).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Filtering and Configuration', () => {
|
||||
it('should respect .gitignore files', async () => {
|
||||
const gitignoreContent = ['dist/', '*.log'].join('\n');
|
||||
@@ -376,5 +432,42 @@ describe('useAtCompletion', () => {
|
||||
await cleanupTmpDir(rootDir1);
|
||||
await cleanupTmpDir(rootDir2);
|
||||
});
|
||||
|
||||
it('should perform a non-recursive search when enableRecursiveFileSearch is false', async () => {
|
||||
const structure: FileSystemStructure = {
|
||||
'file.txt': '',
|
||||
src: {
|
||||
'index.js': '',
|
||||
},
|
||||
};
|
||||
testRootDir = await createTmpDir(structure);
|
||||
|
||||
const nonRecursiveConfig = {
|
||||
getEnableRecursiveFileSearch: () => false,
|
||||
getFileFilteringOptions: vi.fn(() => ({
|
||||
respectGitIgnore: true,
|
||||
respectGeminiIgnore: true,
|
||||
})),
|
||||
} as unknown as Config;
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useTestHarnessForAtCompletion(
|
||||
true,
|
||||
'',
|
||||
nonRecursiveConfig,
|
||||
testRootDir,
|
||||
),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// Should only contain top-level items
|
||||
expect(result.current.suggestions.map((s) => s.value)).toEqual([
|
||||
'src/',
|
||||
'file.txt',
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user