This was an update of which I cannot remember what it did but it was surely something that I needed so let's commit it. YOLO
CI / check (push) Waiting to run
CI / check (push) Waiting to run
This commit is contained in:
@@ -10,6 +10,7 @@ vi.mock('../src/renderer/src/terminals', () => {
|
||||
|
||||
import { App } from '../src/renderer/src/App'
|
||||
import { ProjectProvider } from '../src/renderer/src/project'
|
||||
import { normalizeCommitMsg } from '../src/renderer/src/components'
|
||||
|
||||
beforeAll(() => {
|
||||
globalThis.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} } as never
|
||||
@@ -78,7 +79,7 @@ describe('Pass on to Agent', () => {
|
||||
})
|
||||
|
||||
describe('Stage + commit', () => {
|
||||
it('stages a file and commits via Shift+Enter (no commit button)', async () => {
|
||||
it('stages a file and commits via Shift+Enter', async () => {
|
||||
const c = renderApp()
|
||||
const row = await waitFor(() => {
|
||||
const r = find(c, '.git-row', 'UserController.php')
|
||||
@@ -86,13 +87,26 @@ describe('Stage + commit', () => {
|
||||
return r
|
||||
})
|
||||
fireEvent.click(row.querySelector<HTMLButtonElement>('button[title="Stage changes"]')!)
|
||||
// the commit button is intentionally gone — committing is keyboard-only
|
||||
expect(c.querySelector('.commit-btn')).toBeNull()
|
||||
const msg = c.querySelector<HTMLTextAreaElement>('.commit-input')!
|
||||
fireEvent.change(msg, { target: { value: 'wire up balance' } })
|
||||
fireEvent.keyDown(msg, { key: 'Enter', shiftKey: true })
|
||||
await waitFor(() => expect(find(c, '.toast', 'Committed')).toBeTruthy())
|
||||
})
|
||||
|
||||
it('commits from the button once a file is staged', async () => {
|
||||
const c = renderApp()
|
||||
const row = await waitFor(() => {
|
||||
const r = find(c, '.git-row', 'UserController.php')
|
||||
if (!r) throw new Error('git not ready')
|
||||
return r
|
||||
})
|
||||
fireEvent.click(row.querySelector<HTMLButtonElement>('button[title="Stage changes"]')!)
|
||||
await waitFor(() => expect(c.querySelector<HTMLButtonElement>('.commit-btn')!.disabled).toBe(false))
|
||||
const msg = c.querySelector<HTMLTextAreaElement>('.commit-input')!
|
||||
fireEvent.change(msg, { target: { value: 'wire up balance' } })
|
||||
fireEvent.click(c.querySelector<HTMLButtonElement>('.commit-btn')!)
|
||||
await waitFor(() => expect(find(c, '.toast', 'Committed')).toBeTruthy())
|
||||
})
|
||||
})
|
||||
|
||||
describe('Explorer background menu', () => {
|
||||
@@ -126,3 +140,9 @@ describe('Explorer background menu', () => {
|
||||
expect(find(c, '.ctx-item', 'Copy file name')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Commit message normalization', () => {
|
||||
it('lowercases the text and folds the line breaks into one line', () => {
|
||||
expect(normalizeCommitMsg('Fix Login\nAnd Logout\r\n Flow')).toBe('fix login and logout flow')
|
||||
})
|
||||
})
|
||||
|
||||
+19
-1
@@ -5,7 +5,25 @@ import { afterEach, describe, expect, it } from 'vitest'
|
||||
import { simpleGit } from 'simple-git'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { classify, discard, load, stage } from '../src/main/git-service'
|
||||
import { classify, discard, load, parseAhead, stage } from '../src/main/git-service'
|
||||
|
||||
describe('parseAhead', () => {
|
||||
it('reads the ahead count from the porcelain header', () => {
|
||||
expect(parseAhead('main...origin/main [ahead 3]')).toEqual({ ahead: 3, canPush: true })
|
||||
expect(parseAhead('main...origin/main [ahead 1, behind 2]')).toEqual({ ahead: 1, canPush: true })
|
||||
})
|
||||
it('reports nothing to push on a branch in sync', () => {
|
||||
expect(parseAhead('main...origin/main')).toEqual({ ahead: 0, canPush: false })
|
||||
expect(parseAhead('main...origin/main [behind 2]')).toEqual({ ahead: 0, canPush: false })
|
||||
})
|
||||
it('treats a branch without an upstream as pushable, count unknown', () => {
|
||||
expect(parseAhead('feature/x')).toEqual({ ahead: 0, canPush: true })
|
||||
})
|
||||
it('reports nothing to push on an empty repo or a detached HEAD', () => {
|
||||
expect(parseAhead('No commits yet on main')).toEqual({ ahead: 0, canPush: false })
|
||||
expect(parseAhead('HEAD (no branch)')).toEqual({ ahead: 0, canPush: false })
|
||||
})
|
||||
})
|
||||
|
||||
describe('classify', () => {
|
||||
it('reads the index code as staged, working code as unstaged', () => {
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ function stubBridge(): void {
|
||||
write: async (t: string) => { stored = t; writes.push(t) },
|
||||
},
|
||||
git: {
|
||||
load: async () => ({ branch: 'main', changes: [] }),
|
||||
load: async () => ({ branch: 'main', ahead: 0, canPush: false, changes: [] }),
|
||||
stage: async () => {}, unstage: async () => {}, commit: async () => {},
|
||||
push: async () => ({ ok: true, message: '' }), discard: async () => {},
|
||||
},
|
||||
@@ -68,7 +68,7 @@ afterEach(() => {
|
||||
|
||||
async function boot(): Promise<HTMLElement> {
|
||||
const c = render(<ProjectProvider><App /></ProjectProvider>).container
|
||||
await waitFor(() => { if (!c.querySelector('.git-foot')) throw new Error('not ready') })
|
||||
await waitFor(() => { if (!c.querySelector('.commit-box')) throw new Error('not ready') })
|
||||
return c
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ export function installBridge(rows: StubRow[], files: Record<string, string>): v
|
||||
shell: { reveal: noop },
|
||||
notes: { read: async () => '', write: async () => {} },
|
||||
git: {
|
||||
load: async () => ({ branch: 'main', changes: rows }),
|
||||
load: async () => ({ branch: 'main', ahead: 0, canPush: false, changes: rows }),
|
||||
stage: async () => {}, unstage: async () => {}, commit: async () => {},
|
||||
push: async () => ({ ok: true, message: '' }), discard: async () => {},
|
||||
},
|
||||
|
||||
@@ -38,7 +38,7 @@ function stubBridge(): void {
|
||||
shell: { reveal: noop },
|
||||
notes: { read: async () => '', write: async () => {} },
|
||||
git: {
|
||||
load: async () => ({ branch: 'main', changes: [] }),
|
||||
load: async () => ({ branch: 'main', ahead: 0, canPush: false, changes: [] }),
|
||||
stage: async () => {}, unstage: async () => {}, commit: async () => {},
|
||||
push: async () => ({ ok: true, message: '' }), discard: async () => {},
|
||||
},
|
||||
@@ -69,7 +69,7 @@ afterEach(() => {
|
||||
|
||||
async function boot(): Promise<HTMLElement> {
|
||||
const c = render(<ProjectProvider><App /></ProjectProvider>).container
|
||||
await waitFor(() => { if (!c.querySelector('.git-foot')) throw new Error('not ready') })
|
||||
await waitFor(() => { if (!c.querySelector('.commit-box')) throw new Error('not ready') })
|
||||
return c
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user