import type { VcsStatusResult } from "@t3tools/contracts";import { assert, describe, it } from "vite-plus/test";import { buildGitActionProgressStages, buildMenuItems, formatGitActionElapsed, requiresDefaultBranchConfirmation, resolveAutoFeatureBranchName, resolveDefaultBranchActionDialogCopy, resolveGitActionProgressPresentation, resolveGitActionResultToastTiming, resolveLiveThreadBranchUpdate, resolveQuickAction, resolveThreadBranchUpdate, resolveThreadBranchMetadataPatch,} from "./GitActionsControl.logic"; function status(overrides: Partial<VcsStatusResult> = {}): VcsStatusResult { return { isRepo: true, hasPrimaryRemote: true, isDefaultRef: false, refName: "feature/test", hasWorkingTreeChanges: false, workingTree: { files: [], insertions: 0, deletions: 0, }, hasUpstream: true, aheadCount: 0, behindCount: 0, pr: null, ...overrides, };} describe("git action progress presentation", () => { it("keeps the phase on the first row and hook output on the second", () => { assert.deepEqual( resolveGitActionProgressPresentation({ isRunning: true, operation: "run_change_request", currentLabel: "Running pre-commit...", lastOutputLine: "Checking formatting and lint rules", phaseStartedAtMs: 1_000, hookStartedAtMs: 2_000, }), { status: "Running pre-commit...", output: "Checking formatting and lint rules", startedAtMs: 2_000, }, ); }); it("omits empty output and supplies a brief startup label", () => { assert.deepEqual( resolveGitActionProgressPresentation({ isRunning: true, operation: "run_change_request", currentLabel: "Running source control action", lastOutputLine: " ", phaseStartedAtMs: 1_000, hookStartedAtMs: null, }), { status: "Starting source control action...", output: null, startedAtMs: 1_000, }, ); }); it("presents pull progress inline without a second row", () => { assert.deepEqual( resolveGitActionProgressPresentation({ isRunning: true, operation: "pull", currentLabel: "Pulling latest changes...", lastOutputLine: null, phaseStartedAtMs: 1_000, hookStartedAtMs: null, }), { status: "Pulling latest changes...", output: null, startedAtMs: 1_000, }, ); }); it("does not present unrelated or completed actions", () => { const input = { isRunning: true, operation: "publish_repository", currentLabel: "Publishing repository", lastOutputLine: null, phaseStartedAtMs: 1_000, hookStartedAtMs: null, }; assert.isNull(resolveGitActionProgressPresentation(input)); assert.isNull(resolveGitActionProgressPresentation({ ...input, isRunning: false })); }); it("formats compact elapsed time without allowing negative values", () => { assert.isNull(formatGitActionElapsed(null, 10_000)); assert.equal(formatGitActionElapsed(10_000, 9_000), "0s"); assert.equal(formatGitActionElapsed(10_000, 14_900), "4s"); assert.equal(formatGitActionElapsed(10_000, 75_000), "1m 5s"); });}); describe("git action result toast timing", () => { it("keeps errors sticky and dismisses successes after visible time", () => { assert.deepEqual(resolveGitActionResultToastTiming("error"), { timeout: 0, dismissAfterVisibleMs: null, }); assert.deepEqual(resolveGitActionResultToastTiming("success"), { timeout: 0, dismissAfterVisibleMs: 10_000, }); });}); describe("when: ref is clean and has an open PR", () => { it("resolveQuickAction rests in the disabled up-to-date state", () => { const quick = resolveQuickAction( status({ pr: { number: 10, title: "Open PR", url: "https://example.com/pr/10", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true, hint: "Branch is up to date. No action needed.", }); }); it("buildMenuItems disables commit/push and omits the PR entry", () => { const items = buildMenuItems( status({ pr: { number: 11, title: "Existing PR", url: "https://example.com/pr/11", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, ]); });}); describe("when: actions are busy", () => { it("resolveQuickAction returns running disabled state", () => { const quick = resolveQuickAction(status(), true); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true, hint: "Git action in progress.", }); }); it("buildMenuItems disables all actions", () => { const items = buildMenuItems(status(), true); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: true, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); });}); describe("when: git status is unavailable", () => { it("resolveQuickAction returns unavailable disabled state", () => { const quick = resolveQuickAction(null, false); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true, hint: "Git status is unavailable.", }); }); it("buildMenuItems returns no menu items", () => { const items = buildMenuItems(null, false); assert.deepEqual(items, []); });}); describe("when: ref is clean, ahead, and has an open PR", () => { it("resolveQuickAction prefers push", () => { const quick = resolveQuickAction( status({ aheadCount: 3, pr: { number: 13, title: "Open PR", url: "https://example.com/pr/13", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepInclude(quick, { kind: "run_action", action: "push", label: "Push" }); }); it("buildMenuItems enables push and omits the PR entry", () => { const items = buildMenuItems( status({ aheadCount: 2, pr: { number: 12, title: "Existing PR", url: "https://example.com/pr/12", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: false, icon: "push", kind: "open_dialog", dialogAction: "push", }, ]); });}); describe("when: ref is clean, ahead, and has no open PR", () => { it("resolveQuickAction pushes and creates a PR", () => { const quick = resolveQuickAction(status({ aheadCount: 2, pr: null }), false); assert.deepInclude(quick, { kind: "run_action", action: "create_pr", label: "Push & create PR", }); }); it("buildMenuItems enables push and create PR, with commit disabled", () => { const items = buildMenuItems(status({ aheadCount: 2, pr: null }), false); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: false, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: false, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); });}); describe("when: source control provider uses merge requests", () => { it("uses GitLab MR terminology in quick actions and menu items", () => { const gitlabStatus = status({ aheadCount: 2, sourceControlProvider: { kind: "gitlab", name: "GitLab", baseUrl: "https://gitlab.com", }, }); const quick = resolveQuickAction(gitlabStatus, false); const items = buildMenuItems(gitlabStatus, false); assert.deepInclude(quick, { kind: "run_action", action: "create_pr", label: "Push & create MR", }); assert.deepInclude(items[2], { id: "pr", label: "Create MR", }); });}); describe("when: ref is clean, up to date, and has no open PR", () => { it("enables create PR when synced with upstream but ahead of default", () => { const syncedFeature = status({ aheadCount: 0, behindCount: 0, aheadOfDefaultCount: 1, pr: null, }); const quick = resolveQuickAction(syncedFeature, false); assert.deepInclude(quick, { label: "Create PR", disabled: false, kind: "run_action", action: "create_pr", }); const items = buildMenuItems(syncedFeature, false); assert.equal(items.find((item) => item.id === "pr")?.disabled, false); }); it("resolveQuickAction returns disabled no-action state", () => { const quick = resolveQuickAction( status({ aheadCount: 0, behindCount: 0, hasWorkingTreeChanges: false, pr: null }), false, ); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true }); }); it("buildMenuItems disables commit, push, and create PR", () => { const items = buildMenuItems(status({ aheadCount: 0, behindCount: 0, pr: null }), false); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: true, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); });}); describe("when: ref is behind upstream", () => { it("resolveQuickAction returns pull", () => { const quick = resolveQuickAction(status({ behindCount: 2 }), false); assert.deepInclude(quick, { kind: "run_pull", label: "Pull", disabled: false }); }); it("buildMenuItems disables push and create PR", () => { const items = buildMenuItems(status({ behindCount: 1, pr: null }), false); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: true, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); });}); describe("when: ref has diverged from upstream", () => { it("resolveQuickAction returns a disabled sync hint", () => { const quick = resolveQuickAction(status({ aheadCount: 2, behindCount: 1 }), false); assert.deepEqual(quick, { label: "Sync ref", disabled: true, kind: "show_hint", hint: "Branch has diverged from upstream. Rebase/merge first.", }); });}); describe("when: working tree has local changes", () => { it("resolveQuickAction returns commit, push, and create PR", () => { const quick = resolveQuickAction(status({ hasWorkingTreeChanges: true }), false); assert.deepInclude(quick, { kind: "run_action", action: "commit_push_pr", label: "Commit, push & PR", }); }); it("resolveQuickAction falls back to commit when no origin remote exists", () => { const quick = resolveQuickAction( status({ hasWorkingTreeChanges: true, hasUpstream: false }), false, false, false, ); assert.deepInclude(quick, { kind: "run_action", action: "commit", label: "Commit", disabled: false, }); }); Lines 1–500 of 1240. Load more
import type { VcsStatusResult } from "@t3tools/contracts"; import { assert, describe, it } from "vite-plus/test"; import { buildGitActionProgressStages, buildMenuItems, formatGitActionElapsed, requiresDefaultBranchConfirmation, resolveAutoFeatureBranchName, resolveDefaultBranchActionDialogCopy, resolveGitActionProgressPresentation, resolveGitActionResultToastTiming, resolveLiveThreadBranchUpdate, resolveQuickAction, resolveThreadBranchUpdate, resolveThreadBranchMetadataPatch, } from "./GitActionsControl.logic"; function status(overrides: Partial<VcsStatusResult> = {}): VcsStatusResult { return { isRepo: true, hasPrimaryRemote: true, isDefaultRef: false, refName: "feature/test", hasWorkingTreeChanges: false, workingTree: { files: [], insertions: 0, deletions: 0, }, hasUpstream: true, aheadCount: 0, behindCount: 0, pr: null, ...overrides, }; } describe("git action progress presentation", () => { it("keeps the phase on the first row and hook output on the second", () => { assert.deepEqual( resolveGitActionProgressPresentation({ isRunning: true, operation: "run_change_request", currentLabel: "Running pre-commit...", lastOutputLine: "Checking formatting and lint rules", phaseStartedAtMs: 1_000, hookStartedAtMs: 2_000, }), { status: "Running pre-commit...", output: "Checking formatting and lint rules", startedAtMs: 2_000, }, ); }); it("omits empty output and supplies a brief startup label", () => { assert.deepEqual( resolveGitActionProgressPresentation({ isRunning: true, operation: "run_change_request", currentLabel: "Running source control action", lastOutputLine: " ", phaseStartedAtMs: 1_000, hookStartedAtMs: null, }), { status: "Starting source control action...", output: null, startedAtMs: 1_000, }, ); }); it("presents pull progress inline without a second row", () => { assert.deepEqual( resolveGitActionProgressPresentation({ isRunning: true, operation: "pull", currentLabel: "Pulling latest changes...", lastOutputLine: null, phaseStartedAtMs: 1_000, hookStartedAtMs: null, }), { status: "Pulling latest changes...", output: null, startedAtMs: 1_000, }, ); }); it("does not present unrelated or completed actions", () => { const input = { isRunning: true, operation: "publish_repository", currentLabel: "Publishing repository", lastOutputLine: null, phaseStartedAtMs: 1_000, hookStartedAtMs: null, }; assert.isNull(resolveGitActionProgressPresentation(input)); assert.isNull(resolveGitActionProgressPresentation({ ...input, isRunning: false })); }); it("formats compact elapsed time without allowing negative values", () => { assert.isNull(formatGitActionElapsed(null, 10_000)); assert.equal(formatGitActionElapsed(10_000, 9_000), "0s"); assert.equal(formatGitActionElapsed(10_000, 14_900), "4s"); assert.equal(formatGitActionElapsed(10_000, 75_000), "1m 5s"); }); }); describe("git action result toast timing", () => { it("keeps errors sticky and dismisses successes after visible time", () => { assert.deepEqual(resolveGitActionResultToastTiming("error"), { timeout: 0, dismissAfterVisibleMs: null, }); assert.deepEqual(resolveGitActionResultToastTiming("success"), { timeout: 0, dismissAfterVisibleMs: 10_000, }); }); }); describe("when: ref is clean and has an open PR", () => { it("resolveQuickAction rests in the disabled up-to-date state", () => { const quick = resolveQuickAction( status({ pr: { number: 10, title: "Open PR", url: "https://example.com/pr/10", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true, hint: "Branch is up to date. No action needed.", }); }); it("buildMenuItems disables commit/push and omits the PR entry", () => { const items = buildMenuItems( status({ pr: { number: 11, title: "Existing PR", url: "https://example.com/pr/11", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, ]); }); }); describe("when: actions are busy", () => { it("resolveQuickAction returns running disabled state", () => { const quick = resolveQuickAction(status(), true); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true, hint: "Git action in progress.", }); }); it("buildMenuItems disables all actions", () => { const items = buildMenuItems(status(), true); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: true, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); }); }); describe("when: git status is unavailable", () => { it("resolveQuickAction returns unavailable disabled state", () => { const quick = resolveQuickAction(null, false); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true, hint: "Git status is unavailable.", }); }); it("buildMenuItems returns no menu items", () => { const items = buildMenuItems(null, false); assert.deepEqual(items, []); }); }); describe("when: ref is clean, ahead, and has an open PR", () => { it("resolveQuickAction prefers push", () => { const quick = resolveQuickAction( status({ aheadCount: 3, pr: { number: 13, title: "Open PR", url: "https://example.com/pr/13", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepInclude(quick, { kind: "run_action", action: "push", label: "Push" }); }); it("buildMenuItems enables push and omits the PR entry", () => { const items = buildMenuItems( status({ aheadCount: 2, pr: { number: 12, title: "Existing PR", url: "https://example.com/pr/12", baseRef: "main", headRef: "feature/test", state: "open", }, }), false, ); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: false, icon: "push", kind: "open_dialog", dialogAction: "push", }, ]); }); }); describe("when: ref is clean, ahead, and has no open PR", () => { it("resolveQuickAction pushes and creates a PR", () => { const quick = resolveQuickAction(status({ aheadCount: 2, pr: null }), false); assert.deepInclude(quick, { kind: "run_action", action: "create_pr", label: "Push & create PR", }); }); it("buildMenuItems enables push and create PR, with commit disabled", () => { const items = buildMenuItems(status({ aheadCount: 2, pr: null }), false); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: false, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: false, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); }); }); describe("when: source control provider uses merge requests", () => { it("uses GitLab MR terminology in quick actions and menu items", () => { const gitlabStatus = status({ aheadCount: 2, sourceControlProvider: { kind: "gitlab", name: "GitLab", baseUrl: "https://gitlab.com", }, }); const quick = resolveQuickAction(gitlabStatus, false); const items = buildMenuItems(gitlabStatus, false); assert.deepInclude(quick, { kind: "run_action", action: "create_pr", label: "Push & create MR", }); assert.deepInclude(items[2], { id: "pr", label: "Create MR", }); }); }); describe("when: ref is clean, up to date, and has no open PR", () => { it("enables create PR when synced with upstream but ahead of default", () => { const syncedFeature = status({ aheadCount: 0, behindCount: 0, aheadOfDefaultCount: 1, pr: null, }); const quick = resolveQuickAction(syncedFeature, false); assert.deepInclude(quick, { label: "Create PR", disabled: false, kind: "run_action", action: "create_pr", }); const items = buildMenuItems(syncedFeature, false); assert.equal(items.find((item) => item.id === "pr")?.disabled, false); }); it("resolveQuickAction returns disabled no-action state", () => { const quick = resolveQuickAction( status({ aheadCount: 0, behindCount: 0, hasWorkingTreeChanges: false, pr: null }), false, ); assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true }); }); it("buildMenuItems disables commit, push, and create PR", () => { const items = buildMenuItems(status({ aheadCount: 0, behindCount: 0, pr: null }), false); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: true, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); }); }); describe("when: ref is behind upstream", () => { it("resolveQuickAction returns pull", () => { const quick = resolveQuickAction(status({ behindCount: 2 }), false); assert.deepInclude(quick, { kind: "run_pull", label: "Pull", disabled: false }); }); it("buildMenuItems disables push and create PR", () => { const items = buildMenuItems(status({ behindCount: 1, pr: null }), false); assert.deepEqual(items, [ { id: "commit", label: "Commit", disabled: true, icon: "commit", kind: "open_dialog", dialogAction: "commit", }, { id: "push", label: "Push", disabled: true, icon: "push", kind: "open_dialog", dialogAction: "push", }, { id: "pr", label: "Create PR", disabled: true, icon: "pr", kind: "open_dialog", dialogAction: "create_pr", }, ]); }); }); describe("when: ref has diverged from upstream", () => { it("resolveQuickAction returns a disabled sync hint", () => { const quick = resolveQuickAction(status({ aheadCount: 2, behindCount: 1 }), false); assert.deepEqual(quick, { label: "Sync ref", disabled: true, kind: "show_hint", hint: "Branch has diverged from upstream. Rebase/merge first.", }); }); }); describe("when: working tree has local changes", () => { it("resolveQuickAction returns commit, push, and create PR", () => { const quick = resolveQuickAction(status({ hasWorkingTreeChanges: true }), false); assert.deepInclude(quick, { kind: "run_action", action: "commit_push_pr", label: "Commit, push & PR", }); }); it("resolveQuickAction falls back to commit when no origin remote exists", () => { const quick = resolveQuickAction( status({ hasWorkingTreeChanges: true, hasUpstream: false }), false, false, false, ); assert.deepInclude(quick, { kind: "run_action", action: "commit", label: "Commit", disabled: false, }); });