feat: version diffs work now
This commit is contained in:
@@ -203,6 +203,48 @@ describe('GitEngine', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCommitDiffContent', () => {
|
||||
it('should return commit patch text in diff content shape', async () => {
|
||||
mockShow.mockResolvedValue([
|
||||
'diff --git a/posts/first.md b/posts/first.md',
|
||||
'index 1234567..89abcde 100644',
|
||||
'--- a/posts/first.md',
|
||||
'+++ b/posts/first.md',
|
||||
'@@ -1 +1 @@',
|
||||
'-old',
|
||||
'+new',
|
||||
'diff --git a/src/main.ts b/src/main.ts',
|
||||
'index 1234567..89abcde 100644',
|
||||
'--- a/src/main.ts',
|
||||
'+++ b/src/main.ts',
|
||||
'@@ -1 +1 @@',
|
||||
'-const oldValue = 1;',
|
||||
'+const newValue = 2;',
|
||||
].join('\n'));
|
||||
|
||||
const result = await gitEngine.getCommitDiffContent('/tmp/project', 'abc123def456');
|
||||
|
||||
expect(mockShow).toHaveBeenCalledWith(['--format=', '--patch', 'abc123def456']);
|
||||
expect(result).toEqual({
|
||||
commitHash: 'abc123def456',
|
||||
original: 'old',
|
||||
modified: 'new',
|
||||
files: [
|
||||
{
|
||||
filePath: 'posts/first.md',
|
||||
original: 'old',
|
||||
modified: 'new',
|
||||
},
|
||||
{
|
||||
filePath: 'src/main.ts',
|
||||
original: 'const oldValue = 1;',
|
||||
modified: 'const newValue = 2;',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getHistory', () => {
|
||||
it('should return latest commits from git log', async () => {
|
||||
mockLog.mockResolvedValue({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { GitDiffView } from '../../../src/renderer/components/GitDiffView/GitDiffView';
|
||||
import { useAppStore } from '../../../src/renderer/store';
|
||||
|
||||
@@ -58,6 +58,23 @@ describe('GitDiffView', () => {
|
||||
original: '# old line',
|
||||
modified: '# new line',
|
||||
}),
|
||||
getCommitDiffContent: vi.fn().mockResolvedValue({
|
||||
commitHash: 'abc123def456',
|
||||
original: '--- posts/first.md\nold',
|
||||
modified: '--- posts/first.md\nnew',
|
||||
files: [
|
||||
{
|
||||
filePath: 'posts/first.md',
|
||||
original: 'old',
|
||||
modified: 'new',
|
||||
},
|
||||
{
|
||||
filePath: 'src/main.ts',
|
||||
original: 'const oldValue = 1;',
|
||||
modified: 'const newValue = 2;',
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
app: {
|
||||
...(window as any).electronAPI?.app,
|
||||
@@ -79,4 +96,33 @@ describe('GitDiffView', () => {
|
||||
expect(screen.getByText('keepOriginal:true')).toBeInTheDocument();
|
||||
expect(screen.getByText('keepModified:true')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('loads commit diff content when a commit tab identifier is used', async () => {
|
||||
render(<GitDiffView filePath="commit:abc123def456" />);
|
||||
|
||||
const diffEditor = await screen.findByTestId('monaco-diff-editor');
|
||||
expect(diffEditor).toBeInTheDocument();
|
||||
expect(await screen.findByRole('combobox', { name: /changed files/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /previous file/i })).toBeDisabled();
|
||||
expect(screen.getByRole('button', { name: /next file/i })).toBeEnabled();
|
||||
expect((window as any).electronAPI.git.getCommitDiffContent).toHaveBeenCalledWith('/repo/path', 'abc123def456');
|
||||
expect(diffEditor).toHaveTextContent(/original:\s*old/);
|
||||
expect(diffEditor).toHaveTextContent(/modified:\s*new/);
|
||||
expect(screen.getByText('language:markdown')).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /next file/i }));
|
||||
|
||||
expect(diffEditor).toHaveTextContent(/original:\s*const oldValue = 1;/);
|
||||
expect(diffEditor).toHaveTextContent(/modified:\s*const newValue = 2;/);
|
||||
expect(screen.getByText('language:typescript')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /previous file/i })).toBeEnabled();
|
||||
expect(screen.getByRole('button', { name: /next file/i })).toBeDisabled();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /previous file/i }));
|
||||
|
||||
expect(diffEditor).toHaveTextContent(/original:\s*old/);
|
||||
expect(diffEditor).toHaveTextContent(/modified:\s*new/);
|
||||
expect(screen.getByRole('button', { name: /previous file/i })).toBeDisabled();
|
||||
expect(screen.getByRole('button', { name: /next file/i })).toBeEnabled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,6 +35,7 @@ describe('GitSidebar', () => {
|
||||
getStatus: vi.fn().mockResolvedValue({ files: [], counts: { untracked: 0, modified: 0, deleted: 0, renamed: 0, staged: 0, total: 0 } }),
|
||||
getDiff: vi.fn().mockResolvedValue({ filePath: 'posts/a.md', patch: 'diff --git a/posts/a.md b/posts/a.md' }),
|
||||
getDiffContent: vi.fn().mockResolvedValue({ filePath: 'posts/a.md', original: '', modified: '' }),
|
||||
getCommitDiffContent: vi.fn().mockResolvedValue({ commitHash: 'abc123', original: '', modified: '' }),
|
||||
getHistory: vi.fn().mockResolvedValue([]),
|
||||
fetch: vi.fn().mockResolvedValue({ success: true }),
|
||||
pull: vi.fn().mockResolvedValue({ success: true }),
|
||||
@@ -171,6 +172,72 @@ describe('GitSidebar', () => {
|
||||
expect(getStore().tabs[0]).toMatchObject({ type: 'git-diff', id: 'git-diff:posts/first.md', isTransient: false });
|
||||
});
|
||||
|
||||
it('single click on a commit opens a transient git-diff commit tab', async () => {
|
||||
(window as any).electronAPI.git.getRepoState = vi.fn().mockResolvedValue({
|
||||
isRepo: true,
|
||||
rootPath: '/repo/path',
|
||||
currentBranch: 'main',
|
||||
hasRemote: true,
|
||||
});
|
||||
(window as any).electronAPI.git.getHistory = vi.fn().mockResolvedValue([
|
||||
{
|
||||
hash: 'abc123def456',
|
||||
shortHash: 'abc123d',
|
||||
date: '2026-02-16T10:00:00.000Z',
|
||||
subject: 'feat: add sidebar history click',
|
||||
author: 'Dev One',
|
||||
},
|
||||
]);
|
||||
|
||||
render(<GitSidebar />);
|
||||
|
||||
const commitItem = await screen.findByRole('button', { name: /feat: add sidebar history click/i });
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(commitItem);
|
||||
});
|
||||
|
||||
expect(getStore().tabs).toHaveLength(1);
|
||||
expect(getStore().tabs[0]).toMatchObject({
|
||||
type: 'git-diff',
|
||||
id: 'git-diff:commit:abc123def456',
|
||||
isTransient: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('double click on a commit opens a persistent git-diff commit tab', async () => {
|
||||
(window as any).electronAPI.git.getRepoState = vi.fn().mockResolvedValue({
|
||||
isRepo: true,
|
||||
rootPath: '/repo/path',
|
||||
currentBranch: 'main',
|
||||
hasRemote: true,
|
||||
});
|
||||
(window as any).electronAPI.git.getHistory = vi.fn().mockResolvedValue([
|
||||
{
|
||||
hash: 'abc123def456',
|
||||
shortHash: 'abc123d',
|
||||
date: '2026-02-16T10:00:00.000Z',
|
||||
subject: 'feat: add sidebar history click',
|
||||
author: 'Dev One',
|
||||
},
|
||||
]);
|
||||
|
||||
render(<GitSidebar />);
|
||||
|
||||
const commitItem = await screen.findByRole('button', { name: /feat: add sidebar history click/i });
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.doubleClick(commitItem);
|
||||
});
|
||||
|
||||
expect(getStore().tabs).toHaveLength(1);
|
||||
expect(getStore().tabs[0]).toMatchObject({
|
||||
type: 'git-diff',
|
||||
id: 'git-diff:commit:abc123def456',
|
||||
isTransient: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('initializes repository and refreshes repo state after clicking Initialize Git', async () => {
|
||||
const getRepoStateMock = vi
|
||||
.fn()
|
||||
|
||||
81
tests/renderer/components/TabBar.test.tsx
Normal file
81
tests/renderer/components/TabBar.test.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import React from 'react';
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { TabBar } from '../../../src/renderer/components/TabBar/TabBar';
|
||||
import { useAppStore } from '../../../src/renderer/store';
|
||||
|
||||
describe('TabBar', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
(window as any).addEventListener = vi.fn();
|
||||
(window as any).removeEventListener = vi.fn();
|
||||
|
||||
if (!(globalThis as any).ResizeObserver) {
|
||||
(globalThis as any).ResizeObserver = class {
|
||||
observe() {}
|
||||
disconnect() {}
|
||||
};
|
||||
}
|
||||
|
||||
useAppStore.setState({
|
||||
activeProject: {
|
||||
id: 'project-1',
|
||||
name: 'Test Project',
|
||||
slug: 'test-project',
|
||||
isActive: true,
|
||||
dataPath: '/repo/path',
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
tabs: [
|
||||
{ type: 'git-diff', id: 'git-diff:commit:abc123def456', isTransient: false },
|
||||
],
|
||||
activeTabId: 'git-diff:commit:abc123def456',
|
||||
media: [],
|
||||
dirtyPosts: new Set<string>(),
|
||||
sidebarVisible: true,
|
||||
});
|
||||
|
||||
(window as any).electronAPI = {
|
||||
...(window as any).electronAPI,
|
||||
git: {
|
||||
...(window as any).electronAPI?.git,
|
||||
getHistory: vi.fn().mockResolvedValue([
|
||||
{
|
||||
hash: 'abc123def456',
|
||||
shortHash: 'abc123d',
|
||||
date: '2026-02-16T10:00:00.000Z',
|
||||
subject: 'feat: improve commit diff tabs',
|
||||
author: 'Dev One',
|
||||
},
|
||||
]),
|
||||
},
|
||||
app: {
|
||||
...(window as any).electronAPI?.app,
|
||||
getDefaultProjectPath: vi.fn().mockResolvedValue('/repo/path'),
|
||||
},
|
||||
posts: {
|
||||
...(window as any).electronAPI?.posts,
|
||||
get: vi.fn(),
|
||||
},
|
||||
chat: {
|
||||
...(window as any).electronAPI?.chat,
|
||||
getConversation: vi.fn(),
|
||||
onTitleUpdated: vi.fn(() => () => {}),
|
||||
},
|
||||
importDefinitions: {
|
||||
...(window as any).electronAPI?.importDefinitions,
|
||||
get: vi.fn(),
|
||||
onNameUpdated: vi.fn(() => () => {}),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('renders commit subject in git-diff commit tab titles when available', async () => {
|
||||
render(<TabBar />);
|
||||
|
||||
expect(await screen.findByText('abc123d feat: improve commit diff tabs')).toBeInTheDocument();
|
||||
expect((window as any).electronAPI.git.getHistory).toHaveBeenCalledWith('/repo/path', 200);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user