Path: blob/main/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/test/diffState.spec.ts
13406 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { beforeEach, describe, expect, it, vi } from 'vitest';6import { TestLogService } from '../../../../../platform/testing/common/testLogService';7import {8DiffStateManager,9type ActiveDiff,10} from '../diffState';1112vi.mock('vscode', () => ({13Uri: {14file: (path: string) => ({ fsPath: path, scheme: 'file' }),15},16window: {17tabGroups: {18activeTabGroup: {19activeTab: null,20},21all: [],22onDidChangeTabGroups: () => ({ dispose: () => { } }),23onDidChangeTabs: () => ({ dispose: () => { } }),24},25},26commands: {27executeCommand: vi.fn().mockResolvedValue(undefined),28},29TabInputTextDiff: class TabInputTextDiff {30constructor(public original: any, public modified: any) { }31},32}));3334describe('diffState', () => {35let diffState: DiffStateManager;3637const createMockDiff = (tabName: string, diffIdSuffix?: string): ActiveDiff => ({38diffId: `/tmp/modified-${diffIdSuffix ?? tabName}.ts`,39tabName: tabName,40originalUri: { fsPath: `/path/to/original-${tabName}.ts`, scheme: 'file' } as any,41modifiedUri: { fsPath: `/tmp/modified-${diffIdSuffix ?? tabName}.ts`, scheme: 'file' } as any,42newContents: `// new contents for ${tabName}`,43cleanup: vi.fn(),44resolve: vi.fn(),45});4647beforeEach(() => {48diffState = new DiffStateManager(new TestLogService());49});5051describe('register and getByTabName', () => {52it('should register and retrieve a diff by tabName', () => {53const diff = createMockDiff('Test Diff 1');54diffState.register(diff);5556const retrieved = diffState.getByTabName('Test Diff 1');57expect(retrieved).toBe(diff);58});5960it('should return undefined for non-existent tabName', () => {61const retrieved = diffState.getByTabName('non-existent');62expect(retrieved).toBeUndefined();63});64});6566describe('unregister', () => {67it('should remove a registered diff', () => {68const diff = createMockDiff('Test Diff 2');69diffState.register(diff);70expect(diffState.getByTabName('Test Diff 2')).toBe(diff);7172diffState.unregister(diff.diffId);73expect(diffState.getByTabName('Test Diff 2')).toBeUndefined();74});7576it('should not throw when unregistering non-existent diff', () => {77expect(() => diffState.unregister('/tmp/non-existent.ts')).not.toThrow();78});79});8081describe('getByTabName', () => {82it('should find diff by tab name', () => {83const diff1 = createMockDiff('My Diff Tab');84const diff2 = createMockDiff('Another Tab');85diffState.register(diff1);86diffState.register(diff2);8788const found = diffState.getByTabName('My Diff Tab');89expect(found).toBe(diff1);9091const found2 = diffState.getByTabName('Another Tab');92expect(found2).toBe(diff2);93});9495it('should return undefined for non-existent tab name', () => {96const diff = createMockDiff('Existing Tab');97diffState.register(diff);9899const found = diffState.getByTabName('Non-existent Tab');100expect(found).toBeUndefined();101});102103it('should allow multiple diffs with same tab name but different diffIds', () => {104const diff1 = createMockDiff('Duplicate Name', 'diff1');105const diff2 = createMockDiff('Duplicate Name', 'diff2');106diffState.register(diff1);107diffState.register(diff2);108109const found = diffState.getByTabName('Duplicate Name');110expect(found).toBe(diff1);111112diffState.unregister(diff1.diffId);113const foundAfter = diffState.getByTabName('Duplicate Name');114expect(foundAfter).toBe(diff2);115});116});117118describe('hasActiveDiffs', () => {119it('should return false when no diffs are registered', () => {120expect(diffState.hasActiveDiffs()).toBe(false);121});122123it('should return true when diffs are registered', () => {124const diff = createMockDiff('Test Diff 3');125diffState.register(diff);126expect(diffState.hasActiveDiffs()).toBe(true);127});128129it('should return false after all diffs are unregistered', () => {130const diff = createMockDiff('Test Diff 3');131diffState.register(diff);132expect(diffState.hasActiveDiffs()).toBe(true);133134diffState.unregister(diff.diffId);135expect(diffState.hasActiveDiffs()).toBe(false);136});137});138139describe('edge cases', () => {140it('should handle multiple diffs for the same original file', () => {141const diff1: ActiveDiff = {142diffId: '/tmp/modified-v1.ts',143tabName: 'file.ts (version 1)',144originalUri: { fsPath: '/path/to/file.ts', scheme: 'file' } as any,145modifiedUri: { fsPath: '/tmp/modified-v1.ts', scheme: 'file' } as any,146newContents: '// version 1',147cleanup: vi.fn(),148resolve: vi.fn(),149};150const diff2: ActiveDiff = {151diffId: '/tmp/modified-v2.ts',152tabName: 'file.ts (version 2)',153originalUri: { fsPath: '/path/to/file.ts', scheme: 'file' } as any,154modifiedUri: { fsPath: '/tmp/modified-v2.ts', scheme: 'file' } as any,155newContents: '// version 2',156cleanup: vi.fn(),157resolve: vi.fn(),158};159160diffState.register(diff1);161diffState.register(diff2);162163expect(diffState.getByTabName('file.ts (version 1)')).toBe(diff1);164expect(diffState.getByTabName('file.ts (version 2)')).toBe(diff2);165166diffState.unregister(diff1.diffId);167diffState.unregister(diff2.diffId);168});169170it('should handle re-registering same diffId (overwrites)', () => {171const diff1 = createMockDiff('Original Tab');172const diff2: ActiveDiff = {173diffId: diff1.diffId,174tabName: 'New Tab',175originalUri: { fsPath: '/path/to/new.ts', scheme: 'file' } as any,176modifiedUri: { fsPath: '/tmp/new-modified.ts', scheme: 'file' } as any,177newContents: '// new content',178cleanup: vi.fn(),179resolve: vi.fn(),180};181182diffState.register(diff1);183expect(diffState.getByTabName('Original Tab')).toBe(diff1);184185diffState.register(diff2);186expect(diffState.getByTabName('Original Tab')).toBeUndefined();187expect(diffState.getByTabName('New Tab')).toBe(diff2);188});189190it('should handle concurrent registrations', () => {191const diffs = Array.from({ length: 10 }, (_, i) =>192createMockDiff(`Concurrent Tab ${i}`)193);194195diffs.forEach(diff => diffState.register(diff));196197diffs.forEach((diff, i) => {198expect(diffState.getByTabName(`Concurrent Tab ${i}`)).toBe(diff);199});200201diffs.forEach(diff => diffState.unregister(diff.diffId));202});203});204});205206207