summaryrefslogtreecommitdiff
path: root/packages/vscode-ide-companion/src/recent-files-manager.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/vscode-ide-companion/src/recent-files-manager.test.ts')
-rw-r--r--packages/vscode-ide-companion/src/recent-files-manager.test.ts202
1 files changed, 134 insertions, 68 deletions
diff --git a/packages/vscode-ide-companion/src/recent-files-manager.test.ts b/packages/vscode-ide-companion/src/recent-files-manager.test.ts
index 27742ed2..97f19f30 100644
--- a/packages/vscode-ide-companion/src/recent-files-manager.test.ts
+++ b/packages/vscode-ide-companion/src/recent-files-manager.test.ts
@@ -13,11 +13,19 @@ import {
} from './recent-files-manager.js';
vi.mock('vscode', () => ({
- EventEmitter: vi.fn(() => ({
- event: vi.fn(),
- fire: vi.fn(),
- dispose: vi.fn(),
- })),
+ EventEmitter: vi.fn(() => {
+ const listeners: Array<(e: void) => unknown> = [];
+ return {
+ event: vi.fn((listener) => {
+ listeners.push(listener);
+ return { dispose: vi.fn() };
+ }),
+ fire: vi.fn(() => {
+ listeners.forEach((listener) => listener(undefined));
+ }),
+ dispose: vi.fn(),
+ };
+ }),
window: {
onDidChangeActiveTextEditor: vi.fn(),
},
@@ -29,14 +37,48 @@ vi.mock('vscode', () => ({
Uri: {
file: (path: string) => ({
fsPath: path,
+ scheme: 'file',
}),
},
}));
describe('RecentFilesManager', () => {
let context: vscode.ExtensionContext;
+ let onDidChangeActiveTextEditorListener: (
+ editor: vscode.TextEditor | undefined,
+ ) => void;
+ let onDidDeleteFilesListener: (e: vscode.FileDeleteEvent) => void;
+ let onDidCloseTextDocumentListener: (doc: vscode.TextDocument) => void;
+ let onDidRenameFilesListener: (e: vscode.FileRenameEvent) => void;
beforeEach(() => {
+ vi.useFakeTimers();
+
+ vi.mocked(vscode.window.onDidChangeActiveTextEditor).mockImplementation(
+ (listener) => {
+ onDidChangeActiveTextEditorListener = listener;
+ return { dispose: vi.fn() };
+ },
+ );
+ vi.mocked(vscode.workspace.onDidDeleteFiles).mockImplementation(
+ (listener) => {
+ onDidDeleteFilesListener = listener;
+ return { dispose: vi.fn() };
+ },
+ );
+ vi.mocked(vscode.workspace.onDidCloseTextDocument).mockImplementation(
+ (listener) => {
+ onDidCloseTextDocumentListener = listener;
+ return { dispose: vi.fn() };
+ },
+ );
+ vi.mocked(vscode.workspace.onDidRenameFiles).mockImplementation(
+ (listener) => {
+ onDidRenameFilesListener = listener;
+ return { dispose: vi.fn() };
+ },
+ );
+
context = {
subscriptions: [],
} as unknown as vscode.ExtensionContext;
@@ -44,33 +86,40 @@ describe('RecentFilesManager', () => {
afterEach(() => {
vi.restoreAllMocks();
+ vi.useRealTimers();
});
- it('adds a file to the list', () => {
+ const getUri = (path: string) =>
+ vscode.Uri.file(path) as unknown as vscode.Uri;
+
+ it('adds a file to the list', async () => {
const manager = new RecentFilesManager(context);
- const uri = vscode.Uri.file('/test/file1.txt');
+ const uri = getUri('/test/file1.txt');
manager.add(uri);
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(1);
expect(manager.recentFiles[0].filePath).toBe('/test/file1.txt');
});
- it('moves an existing file to the top', () => {
+ it('moves an existing file to the top', async () => {
const manager = new RecentFilesManager(context);
- const uri1 = vscode.Uri.file('/test/file1.txt');
- const uri2 = vscode.Uri.file('/test/file2.txt');
+ const uri1 = getUri('/test/file1.txt');
+ const uri2 = getUri('/test/file2.txt');
manager.add(uri1);
manager.add(uri2);
manager.add(uri1);
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(2);
expect(manager.recentFiles[0].filePath).toBe('/test/file1.txt');
});
- it('does not exceed the max number of files', () => {
+ it('does not exceed the max number of files', async () => {
const manager = new RecentFilesManager(context);
for (let i = 0; i < MAX_FILES + 5; i++) {
- const uri = vscode.Uri.file(`/test/file${i}.txt`);
+ const uri = getUri(`/test/file${i}.txt`);
manager.add(uri);
}
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(MAX_FILES);
expect(manager.recentFiles[0].filePath).toBe(
`/test/file${MAX_FILES + 4}.txt`,
@@ -78,134 +127,151 @@ describe('RecentFilesManager', () => {
expect(manager.recentFiles[MAX_FILES - 1].filePath).toBe(`/test/file5.txt`);
});
- it('fires onDidChange when a file is added', () => {
+ it('fires onDidChange when a file is added', async () => {
const manager = new RecentFilesManager(context);
- const spy = vi.spyOn(manager['onDidChangeEmitter'], 'fire');
- const uri = vscode.Uri.file('/test/file1.txt');
+ const onDidChangeSpy = vi.fn();
+ manager.onDidChange(onDidChangeSpy);
+
+ const uri = getUri('/test/file1.txt');
manager.add(uri);
- expect(spy).toHaveBeenCalled();
+
+ await vi.advanceTimersByTimeAsync(100);
+ expect(onDidChangeSpy).toHaveBeenCalled();
});
- it('removes a file when it is closed', () => {
+ it('removes a file when it is closed', async () => {
const manager = new RecentFilesManager(context);
- const uri = vscode.Uri.file('/test/file1.txt');
+ const uri = getUri('/test/file1.txt');
manager.add(uri);
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(1);
- // Simulate closing the file
- const closeHandler = vi.mocked(vscode.workspace.onDidCloseTextDocument).mock
- .calls[0][0];
- closeHandler({ uri } as vscode.TextDocument);
+ onDidCloseTextDocumentListener({ uri } as vscode.TextDocument);
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(0);
});
- it('fires onDidChange when a file is removed', () => {
+ it('fires onDidChange when a file is removed', async () => {
const manager = new RecentFilesManager(context);
- const uri = vscode.Uri.file('/test/file1.txt');
+ const uri = getUri('/test/file1.txt');
manager.add(uri);
+ await vi.advanceTimersByTimeAsync(100);
+
+ const onDidChangeSpy = vi.fn();
+ manager.onDidChange(onDidChangeSpy);
- const spy = vi.spyOn(manager['onDidChangeEmitter'], 'fire');
- const closeHandler = vi.mocked(vscode.workspace.onDidCloseTextDocument).mock
- .calls[0][0];
- closeHandler({ uri } as vscode.TextDocument);
+ onDidCloseTextDocumentListener({ uri } as vscode.TextDocument);
+ await vi.advanceTimersByTimeAsync(100);
- expect(spy).toHaveBeenCalled();
+ expect(onDidChangeSpy).toHaveBeenCalled();
});
- it('removes a file when it is deleted', () => {
+ it('removes a file when it is deleted', async () => {
const manager = new RecentFilesManager(context);
- const uri1 = vscode.Uri.file('/test/file1.txt');
- const uri2 = vscode.Uri.file('/test/file2.txt');
+ const uri1 = getUri('/test/file1.txt');
+ const uri2 = getUri('/test/file2.txt');
manager.add(uri1);
manager.add(uri2);
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(2);
- // Simulate deleting a file
- const deleteHandler = vi.mocked(vscode.workspace.onDidDeleteFiles).mock
- .calls[0][0];
- deleteHandler({ files: [uri1] });
+ onDidDeleteFilesListener({ files: [uri1] });
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(1);
expect(manager.recentFiles[0].filePath).toBe('/test/file2.txt');
});
- it('fires onDidChange when a file is deleted', () => {
+ it('fires onDidChange when a file is deleted', async () => {
const manager = new RecentFilesManager(context);
- const uri = vscode.Uri.file('/test/file1.txt');
+ const uri = getUri('/test/file1.txt');
manager.add(uri);
+ await vi.advanceTimersByTimeAsync(100);
+
+ const onDidChangeSpy = vi.fn();
+ manager.onDidChange(onDidChangeSpy);
- const spy = vi.spyOn(manager['onDidChangeEmitter'], 'fire');
- const deleteHandler = vi.mocked(vscode.workspace.onDidDeleteFiles).mock
- .calls[0][0];
- deleteHandler({ files: [uri] });
+ onDidDeleteFilesListener({ files: [uri] });
+ await vi.advanceTimersByTimeAsync(100);
- expect(spy).toHaveBeenCalled();
+ expect(onDidChangeSpy).toHaveBeenCalled();
});
- it('removes multiple files when they are deleted', () => {
+ it('removes multiple files when they are deleted', async () => {
const manager = new RecentFilesManager(context);
- const uri1 = vscode.Uri.file('/test/file1.txt');
- const uri2 = vscode.Uri.file('/test/file2.txt');
- const uri3 = vscode.Uri.file('/test/file3.txt');
+ const uri1 = getUri('/test/file1.txt');
+ const uri2 = getUri('/test/file2.txt');
+ const uri3 = getUri('/test/file3.txt');
manager.add(uri1);
manager.add(uri2);
manager.add(uri3);
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(3);
- // Simulate deleting multiple files
- const deleteHandler = vi.mocked(vscode.workspace.onDidDeleteFiles).mock
- .calls[0][0];
- deleteHandler({ files: [uri1, uri3] });
+ onDidDeleteFilesListener({ files: [uri1, uri3] });
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(1);
expect(manager.recentFiles[0].filePath).toBe('/test/file2.txt');
});
it('prunes files older than the max age', () => {
- vi.useFakeTimers();
-
const manager = new RecentFilesManager(context);
- const uri1 = vscode.Uri.file('/test/file1.txt');
+ const uri1 = getUri('/test/file1.txt');
manager.add(uri1);
// Advance time by more than the max age
const twoMinutesMs = (MAX_FILE_AGE_MINUTES + 1) * 60 * 1000;
vi.advanceTimersByTime(twoMinutesMs);
- const uri2 = vscode.Uri.file('/test/file2.txt');
+ const uri2 = getUri('/test/file2.txt');
manager.add(uri2);
expect(manager.recentFiles).toHaveLength(1);
expect(manager.recentFiles[0].filePath).toBe('/test/file2.txt');
-
- vi.useRealTimers();
});
- it('fires onDidChange only once when adding an existing file', () => {
+ it('fires onDidChange only once when adding an existing file', async () => {
const manager = new RecentFilesManager(context);
- const uri = vscode.Uri.file('/test/file1.txt');
+ const uri = getUri('/test/file1.txt');
manager.add(uri);
+ await vi.advanceTimersByTimeAsync(100);
+
+ const onDidChangeSpy = vi.fn();
+ manager.onDidChange(onDidChangeSpy);
- const spy = vi.spyOn(manager['onDidChangeEmitter'], 'fire');
manager.add(uri);
- expect(spy).toHaveBeenCalledTimes(1);
+ await vi.advanceTimersByTimeAsync(100);
+ expect(onDidChangeSpy).toHaveBeenCalledTimes(1);
});
- it('updates the file when it is renamed', () => {
+ it('updates the file when it is renamed', async () => {
const manager = new RecentFilesManager(context);
- const oldUri = vscode.Uri.file('/test/file1.txt');
- const newUri = vscode.Uri.file('/test/file2.txt');
+ const oldUri = getUri('/test/file1.txt');
+ const newUri = getUri('/test/file2.txt');
manager.add(oldUri);
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(1);
expect(manager.recentFiles[0].filePath).toBe('/test/file1.txt');
- // Simulate renaming the file
- const renameHandler = vi.mocked(vscode.workspace.onDidRenameFiles).mock
- .calls[0][0];
- renameHandler({ files: [{ oldUri, newUri }] });
+ onDidRenameFilesListener({ files: [{ oldUri, newUri }] });
+ await vi.advanceTimersByTimeAsync(100);
expect(manager.recentFiles).toHaveLength(1);
expect(manager.recentFiles[0].filePath).toBe('/test/file2.txt');
});
+
+ it('adds a file when the active editor changes', async () => {
+ const manager = new RecentFilesManager(context);
+ const uri = getUri('/test/file1.txt');
+
+ onDidChangeActiveTextEditorListener({
+ document: { uri },
+ } as vscode.TextEditor);
+ await vi.advanceTimersByTimeAsync(100);
+
+ expect(manager.recentFiles).toHaveLength(1);
+ expect(manager.recentFiles[0].filePath).toBe('/test/file1.txt');
+ });
});