chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:47:58 +08:00
commit b16403ea71
789 changed files with 115226 additions and 0 deletions
@@ -0,0 +1,24 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import { cleanupBaseDir, createBaseDir, createRepo } from './helpers.js'
sandboxTest('git add stages files', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'hello\n')
await sandbox.git.add(repoPath)
const status = await sandbox.git.status(repoPath)
const entry = status.fileStatus.find(
(file: any) => file.name === 'README.md'
)
expect(entry?.status).toBe('added')
expect(entry?.staged).toBe(true)
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
@@ -0,0 +1,82 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
cleanupBaseDir,
createBaseDir,
createRepoWithCommit,
} from './helpers.js'
sandboxTest('git branches lists current and feature', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
await sandbox.commands.run(`git -C "${repoPath}" branch feature`)
const branches = await sandbox.git.branches(repoPath)
expect(branches.currentBranch).toBe('main')
expect(branches.branches).toContain('main')
expect(branches.branches).toContain('feature')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest('git checkoutBranch switches branch', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
await sandbox.commands.run(`git -C "${repoPath}" branch feature`)
await sandbox.git.checkoutBranch(repoPath, 'feature')
const head = (
await sandbox.commands.run(
`git -C "${repoPath}" rev-parse --abbrev-ref HEAD`
)
).stdout.trim()
expect(head).toBe('feature')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest(
'git createBranch creates and checks out branch',
async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
await sandbox.git.createBranch(repoPath, 'feature')
const branches = await sandbox.git.branches(repoPath)
expect(branches.branches).toContain('feature')
expect(branches.currentBranch).toBe('feature')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
}
)
sandboxTest('git deleteBranch removes branch', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
await sandbox.commands.run(`git -C "${repoPath}" branch feature`)
await sandbox.git.deleteBranch(repoPath, 'feature')
const branch = (
await sandbox.commands.run(`git -C "${repoPath}" branch --list feature`)
).stdout.trim()
const branches = await sandbox.git.branches(repoPath)
expect(branch).toBe('')
expect(branches.branches).not.toContain('feature')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
@@ -0,0 +1,35 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
cleanupBaseDir,
createBaseDir,
createRepoWithCommit,
startGitDaemon,
} from './helpers.js'
sandboxTest('git clone fetches repo', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
const daemon = await startGitDaemon(sandbox, baseDir)
const clonePath = `${baseDir}/clone`
try {
await sandbox.git.remoteAdd(repoPath, 'origin', daemon.remoteUrl)
await sandbox.git.push(repoPath, {
remote: 'origin',
branch: 'main',
})
await sandbox.git.clone(daemon.remoteUrl, { path: clonePath })
const contents = await sandbox.files.read(`${clonePath}/README.md`)
expect(contents).toContain('hello')
} finally {
await daemon.handle.kill()
}
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
@@ -0,0 +1,66 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
AUTHOR_EMAIL,
AUTHOR_NAME,
cleanupBaseDir,
createBaseDir,
createRepo,
} from './helpers.js'
sandboxTest('git commit creates commit', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'hello\n')
await sandbox.git.add(repoPath)
await sandbox.git.commit(repoPath, 'Initial commit', {
authorName: AUTHOR_NAME,
authorEmail: AUTHOR_EMAIL,
})
const message = (
await sandbox.commands.run(`git -C "${repoPath}" log -1 --pretty=%B`)
).stdout.trim()
expect(message).toBe('Initial commit')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest(
'git commit uses config for missing author fields',
async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.commands.run(
`git -C "${repoPath}" config --local user.email "${AUTHOR_EMAIL}"`
)
await sandbox.files.write(`${repoPath}/README.md`, 'hello\n')
await sandbox.git.add(repoPath)
const overrideName = 'Override Bot'
await sandbox.git.commit(repoPath, 'Partial author commit', {
authorName: overrideName,
})
const authorName = (
await sandbox.commands.run(`git -C "${repoPath}" log -1 --pretty=%an`)
).stdout.trim()
const authorEmail = (
await sandbox.commands.run(`git -C "${repoPath}" log -1 --pretty=%ae`)
).stdout.trim()
expect(authorName).toBe(overrideName)
expect(authorEmail).toBe(AUTHOR_EMAIL)
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
}
)
@@ -0,0 +1,87 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
AUTHOR_EMAIL,
AUTHOR_NAME,
cleanupBaseDir,
createBaseDir,
createRepo,
} from './helpers.js'
sandboxTest('git getConfig reads local config', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.commands.run(
`git -C "${repoPath}" config --local pull.rebase true`
)
const value = await sandbox.git.getConfig('pull.rebase', {
scope: 'local',
path: repoPath,
})
const commandValue = (
await sandbox.commands.run(
`git -C "${repoPath}" config --local --get pull.rebase`
)
).stdout.trim()
expect(value).toBe('true')
expect(commandValue).toBe('true')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest('git setConfig updates local config', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.git.setConfig('pull.rebase', 'true', {
scope: 'local',
path: repoPath,
})
const value = (
await sandbox.commands.run(
`git -C "${repoPath}" config --local --get pull.rebase`
)
).stdout.trim()
const configuredValue = await sandbox.git.getConfig('pull.rebase', {
scope: 'local',
path: repoPath,
})
expect(value).toBe('true')
expect(configuredValue).toBe('true')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest(
'git configureUser sets global user config',
async ({ sandbox }) => {
await sandbox.git.configureUser(AUTHOR_NAME, AUTHOR_EMAIL)
const name = (
await sandbox.commands.run('git config --global --get user.name')
).stdout.trim()
const email = (
await sandbox.commands.run('git config --global --get user.email')
).stdout.trim()
const configuredName = await sandbox.git.getConfig('user.name', {
scope: 'global',
})
const configuredEmail = await sandbox.git.getConfig('user.email', {
scope: 'global',
})
expect(name).toBe(AUTHOR_NAME)
expect(email).toBe(AUTHOR_EMAIL)
expect(configuredName).toBe(AUTHOR_NAME)
expect(configuredEmail).toBe(AUTHOR_EMAIL)
}
)
@@ -0,0 +1,22 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import { HOST, PASSWORD, PROTOCOL, USERNAME } from './helpers.js'
sandboxTest('git dangerouslyAuthenticate sets helper', async ({ sandbox }) => {
await sandbox.git.dangerouslyAuthenticate({
username: USERNAME,
password: PASSWORD,
host: HOST,
protocol: PROTOCOL,
})
const helper = (
await sandbox.commands.run('git config --global --get credential.helper')
).stdout.trim()
const configuredHelper = await sandbox.git.getConfig('credential.helper', {
scope: 'global',
})
expect(helper).toBe('store')
expect(configuredHelper).toBe('store')
})
@@ -0,0 +1,57 @@
import { randomUUID } from 'node:crypto'
export const AUTHOR_NAME = 'Sandbox Bot'
export const AUTHOR_EMAIL = 'sandbox@example.com'
export const USERNAME = 'git'
export const PASSWORD = 'token'
export const HOST = 'example.com'
export const PROTOCOL = 'https'
const BASE_DIR = '/tmp/test-git'
export async function createBaseDir(sandbox: any) {
const baseDir = `${BASE_DIR}/${randomUUID()}`
await sandbox.commands.run(`rm -rf "${baseDir}" && mkdir -p "${baseDir}"`)
return baseDir
}
export async function cleanupBaseDir(sandbox: any, baseDir: string) {
await sandbox.commands.run(`rm -rf "${baseDir}"`)
}
export async function createRepo(sandbox: any, baseDir: string) {
const repoPath = `${baseDir}/repo`
await sandbox.git.init(repoPath, { initialBranch: 'main' })
return repoPath
}
export async function createRepoWithCommit(sandbox: any, baseDir: string) {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'hello\n')
await sandbox.git.add(repoPath)
await sandbox.git.commit(repoPath, 'Initial commit', {
authorName: AUTHOR_NAME,
authorEmail: AUTHOR_EMAIL,
})
return repoPath
}
export async function startGitDaemon(sandbox: any, baseDir: string) {
const remotePath = `${baseDir}/remote.git`
await sandbox.commands.run(
`git init --bare --initial-branch=main "${remotePath}"`
)
const port = 9418 + Math.floor(Math.random() * 1000)
const handle = await sandbox.commands.run(
`git daemon --reuseaddr --base-path="${baseDir}" --export-all ` +
`--enable=receive-pack --informative-errors --listen=127.0.0.1 --port=${port}`,
{ background: true }
)
await sandbox.commands.run('sleep 1')
return {
handle,
remotePath,
remoteUrl: `git://127.0.0.1:${port}/remote.git`,
port,
}
}
@@ -0,0 +1,24 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import { cleanupBaseDir, createBaseDir } from './helpers.js'
sandboxTest('git init', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = `${baseDir}/repo`
await sandbox.git.init(repoPath, { initialBranch: 'main' })
expect(await sandbox.files.exists(`${repoPath}/.git`)).toBe(true)
const head = (
await sandbox.commands.run(
`git -C "${repoPath}" symbolic-ref --short HEAD`
)
).stdout.trim()
expect(head).toBe('main')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
@@ -0,0 +1,82 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
cleanupBaseDir,
createBaseDir,
createRepo,
startGitDaemon,
} from './helpers.js'
sandboxTest(
'git remoteGet returns undefined for missing remote',
async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
const missingUrl = await sandbox.git.remoteGet(repoPath, 'origin')
expect(missingUrl).toBeUndefined()
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
}
)
sandboxTest('git remoteAdd adds remote', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
const daemon = await startGitDaemon(sandbox, baseDir)
try {
await sandbox.git.remoteAdd(repoPath, 'origin', daemon.remoteUrl)
const remoteUrl = await sandbox.git.remoteGet(repoPath, 'origin')
expect(remoteUrl).toBe(daemon.remoteUrl)
} finally {
await daemon.handle.kill()
}
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest('git remoteAdd overwrites existing remote', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
const daemon = await startGitDaemon(sandbox, baseDir)
try {
await sandbox.git.remoteAdd(repoPath, 'origin', daemon.remoteUrl)
const currentUrl = (
await sandbox.commands.run(`git -C "${repoPath}" remote get-url origin`)
).stdout.trim()
const currentRemote = await sandbox.git.remoteGet(repoPath, 'origin')
expect(currentUrl).toBe(daemon.remoteUrl)
expect(currentRemote).toBe(daemon.remoteUrl)
const secondPath = `${baseDir}/remote-2.git`
await sandbox.commands.run(
`git init --bare --initial-branch=main "${secondPath}"`
)
const secondUrl = `git://127.0.0.1:${daemon.port}/remote-2.git`
await sandbox.git.remoteAdd(repoPath, 'origin', secondUrl, {
overwrite: true,
})
const updatedUrl = (
await sandbox.commands.run(`git -C "${repoPath}" remote get-url origin`)
).stdout.trim()
const updatedRemote = await sandbox.git.remoteGet(repoPath, 'origin')
expect(updatedUrl).toBe(secondUrl)
expect(updatedRemote).toBe(secondUrl)
} finally {
await daemon.handle.kill()
}
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
@@ -0,0 +1,30 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
cleanupBaseDir,
createBaseDir,
createRepoWithCommit,
} from './helpers.js'
sandboxTest('git reset --hard discards changes', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'changed\n')
const status = await sandbox.git.status(repoPath)
expect(status.isClean).toBe(false)
await sandbox.git.reset(repoPath, { mode: 'hard', target: 'HEAD' })
const statusAfter = await sandbox.git.status(repoPath)
expect(statusAfter.isClean).toBe(true)
const contents = await sandbox.files.read(`${repoPath}/README.md`)
expect(contents).toBe('hello\n')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
@@ -0,0 +1,58 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
cleanupBaseDir,
createBaseDir,
createRepoWithCommit,
} from './helpers.js'
sandboxTest('git restore --staged unstages changes', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'changed\n')
await sandbox.git.add(repoPath, { files: ['README.md'] })
const status = await sandbox.git.status(repoPath)
expect(status.hasStaged).toBe(true)
await sandbox.git.restore(repoPath, {
paths: ['README.md'],
staged: true,
worktree: false,
})
const statusAfter = await sandbox.git.status(repoPath)
expect(statusAfter.hasStaged).toBe(false)
expect(statusAfter.hasChanges).toBe(true)
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest(
'git restore discards working tree changes',
async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'changed\n')
const status = await sandbox.git.status(repoPath)
expect(status.isClean).toBe(false)
await sandbox.git.restore(repoPath, { paths: ['README.md'] })
const statusAfter = await sandbox.git.status(repoPath)
expect(statusAfter.isClean).toBe(true)
const contents = await sandbox.files.read(`${repoPath}/README.md`)
expect(contents).toBe('hello\n')
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
}
)
@@ -0,0 +1,99 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
AUTHOR_EMAIL,
AUTHOR_NAME,
cleanupBaseDir,
createBaseDir,
createRepo,
} from './helpers.js'
sandboxTest('git status reports untracked file', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'hello\n')
const status = await sandbox.git.status(repoPath)
const entry = status.fileStatus.find(
(file: any) => file.name === 'README.md'
)
expect(entry?.status).toBe('untracked')
expect(status.isClean).toBe(false)
expect(status.hasChanges).toBe(true)
expect(status.hasUntracked).toBe(true)
expect(status.hasStaged).toBe(false)
expect(status.hasConflicts).toBe(false)
expect(status.totalCount).toBe(1)
expect(status.stagedCount).toBe(0)
expect(status.unstagedCount).toBe(1)
expect(status.untrackedCount).toBe(1)
expect(status.conflictCount).toBe(0)
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest(
'git status reports added modified deleted renamed',
async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepo(sandbox, baseDir)
await sandbox.files.write(`${repoPath}/README.md`, 'hello\n')
await sandbox.files.write(`${repoPath}/DELETE.md`, 'delete me\n')
await sandbox.files.write(`${repoPath}/RENAME.md`, 'rename me\n')
await sandbox.git.add(repoPath)
await sandbox.git.commit(repoPath, 'Initial commit', {
authorName: AUTHOR_NAME,
authorEmail: AUTHOR_EMAIL,
})
await sandbox.files.write(`${repoPath}/README.md`, 'hello again\n')
await sandbox.files.write(`${repoPath}/NEW.md`, 'new file\n')
await sandbox.git.add(repoPath, { files: ['NEW.md'] })
await sandbox.commands.run(`git -C "${repoPath}" rm DELETE.md`)
await sandbox.commands.run(`git -C "${repoPath}" mv RENAME.md RENAMED.md`)
const status = await sandbox.git.status(repoPath)
const modified = status.fileStatus.find(
(file: any) => file.name === 'README.md'
)
const added = status.fileStatus.find(
(file: any) => file.name === 'NEW.md'
)
const deleted = status.fileStatus.find(
(file: any) => file.name === 'DELETE.md'
)
const renamed = status.fileStatus.find(
(file: any) => file.name === 'RENAMED.md'
)
expect(modified?.status).toBe('modified')
expect(modified?.staged).toBe(false)
expect(added?.status).toBe('added')
expect(added?.staged).toBe(true)
expect(deleted?.status).toBe('deleted')
expect(deleted?.staged).toBe(true)
expect(renamed?.status).toBe('renamed')
expect(renamed?.staged).toBe(true)
expect(renamed?.renamedFrom).toBe('RENAME.md')
expect(status.hasChanges).toBe(true)
expect(status.hasStaged).toBe(true)
expect(status.hasUntracked).toBe(false)
expect(status.hasConflicts).toBe(false)
expect(status.totalCount).toBe(4)
expect(status.stagedCount).toBe(3)
expect(status.unstagedCount).toBe(1)
expect(status.untrackedCount).toBe(0)
expect(status.conflictCount).toBe(0)
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
}
)
@@ -0,0 +1,116 @@
import { expect } from 'vitest'
import { sandboxTest } from '../../setup.js'
import {
AUTHOR_EMAIL,
AUTHOR_NAME,
cleanupBaseDir,
createBaseDir,
createRepoWithCommit,
startGitDaemon,
} from './helpers.js'
sandboxTest('git push updates remote', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
const daemon = await startGitDaemon(sandbox, baseDir)
try {
await sandbox.git.remoteAdd(repoPath, 'origin', daemon.remoteUrl)
await sandbox.git.push(repoPath, {
remote: 'origin',
branch: 'main',
})
const message = (
await sandbox.commands.run(
`git --git-dir="${daemon.remotePath}" log -1 --pretty=%B`
)
).stdout.trim()
expect(message).toBe('Initial commit')
} finally {
await daemon.handle.kill()
}
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest('git push warns when no upstream', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
const daemon = await startGitDaemon(sandbox, baseDir)
try {
await sandbox.git.remoteAdd(repoPath, 'origin', daemon.remoteUrl)
await expect(
sandbox.git.push(repoPath, { setUpstream: false })
).rejects.toThrow(/no upstream branch is configured/i)
} finally {
await daemon.handle.kill()
}
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest('git pull updates clone', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
const daemon = await startGitDaemon(sandbox, baseDir)
const clonePath = `${baseDir}/clone`
try {
await sandbox.git.remoteAdd(repoPath, 'origin', daemon.remoteUrl)
await sandbox.git.push(repoPath, {
remote: 'origin',
branch: 'main',
})
await sandbox.git.clone(daemon.remoteUrl, { path: clonePath })
await sandbox.files.write(`${repoPath}/README.md`, 'hello\nmore\n')
await sandbox.git.add(repoPath)
await sandbox.git.commit(repoPath, 'Update README', {
authorName: AUTHOR_NAME,
authorEmail: AUTHOR_EMAIL,
})
await sandbox.git.push(repoPath)
await sandbox.git.pull(clonePath)
const contents = await sandbox.files.read(`${clonePath}/README.md`)
expect(contents).toContain('more')
} finally {
await daemon.handle.kill()
}
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
sandboxTest('git pull warns when no upstream', async ({ sandbox }) => {
const baseDir = await createBaseDir(sandbox)
try {
const repoPath = await createRepoWithCommit(sandbox, baseDir)
const daemon = await startGitDaemon(sandbox, baseDir)
try {
await sandbox.git.remoteAdd(repoPath, 'origin', daemon.remoteUrl)
await expect(sandbox.git.pull(repoPath)).rejects.toThrow(
/no upstream branch is configured/i
)
} finally {
await daemon.handle.kill()
}
} finally {
await cleanupBaseDir(sandbox, baseDir)
}
})
@@ -0,0 +1,44 @@
import { test, expect } from 'vitest'
import { Git } from '../../../src/sandbox/git'
import type { Commands } from '../../../src/sandbox/commands'
import { InvalidArgumentError } from '../../../src/errors'
// Stub command runner that fails if a git command is actually executed —
// validation must throw before reaching it.
const failingCommands = {
run: () => {
throw new Error('commands.run should not be called')
},
} as unknown as Commands
test('git.reset throws InvalidArgumentError on an invalid mode', async () => {
const git = new Git(failingCommands)
await expect(
// @ts-expect-error - testing runtime validation with an invalid mode
git.reset('/repo', { mode: 'bogus' })
).rejects.toThrow(InvalidArgumentError)
})
test('git.reset accepts a valid mode', async () => {
const git = new Git(failingCommands)
// A valid mode must pass validation and reach the (stubbed) command runner.
await expect(git.reset('/repo', { mode: 'hard' })).rejects.toThrow(
'commands.run should not be called'
)
})
test('git.remoteAdd throws InvalidArgumentError when name or url is missing', async () => {
const git = new Git(failingCommands)
await expect(
git.remoteAdd('/repo', '', 'https://example.com')
).rejects.toThrow(InvalidArgumentError)
await expect(git.remoteAdd('/repo', 'origin', '')).rejects.toThrow(
InvalidArgumentError
)
})
test('git.remoteGet throws InvalidArgumentError when name is missing', async () => {
const git = new Git(failingCommands)
await expect(git.remoteGet('/repo', '')).rejects.toThrow(InvalidArgumentError)
})