Open History to see the last commit
1import { describe, expect, it } from "vite-plus/test";
2
3import {
4 fillNewTaskWorkspaceBranch,
5 resolveNewTaskBranchLabel,
6 resolveNewTaskBranchWorktreePath,
7 resolveNewTaskLocalWorkspaceSelection,
8 resolveNewTaskWorkspaceSelection,
9} from "./new-task-context-presentation";
10
11describe("resolveNewTaskWorkspaceSelection", () => {
12 const fallback = { mode: "worktree", branch: null, worktreePath: null } as const;
13
14 it("falls back to the current checkout when a non-git project defaults to worktree", () => {
15 expect(
16 resolveNewTaskWorkspaceSelection({ selection: undefined, fallback, isGitRepo: false }),
17 ).toEqual({ mode: "local", branch: null, worktreePath: null });
18 });
19
20 it.each(["local", "worktree"] as const)(
21 "clears stale %s selections for non-git projects",
22 (mode) => {
23 expect(
24 resolveNewTaskWorkspaceSelection({
25 selection: {
26 mode,
27 branch: "main",
28 worktreePath: "/old-worktree",
29 startFromOrigin: true,
30 pullRequestReference: "https://github.com/acme/repo/pull/123",
31 },
32 fallback,
33 isGitRepo: false,
34 }),
35 ).toEqual({ mode: "local", branch: null, worktreePath: null });
36 },
37 );
38
39 // regression: #21404 use current checkout for non-git projects
40 it("preserves the selection and defaults for git projects", () => {
41 const selection = { mode: "local", branch: "feature", worktreePath: "/worktree" } as const;
42 expect(resolveNewTaskWorkspaceSelection({ selection, fallback, isGitRepo: true })).toBe(
43 selection,
44 );
45 expect(
46 resolveNewTaskWorkspaceSelection({ selection: undefined, fallback, isGitRepo: true }),
47 ).toBe(fallback);
48 });
49});
50
51describe("resolveNewTaskBranchLabel", () => {
52 it.each([
53 ["https://github.com/acme/repo/pull/123", "From PR #123"],
54 ["https://gitlab.com/acme/repo/-/merge_requests/123", "From MR #123"],
55 ])("names the change request a worktree starts from (%s)", (pullRequestReference, label) => {
56 expect(
57 resolveNewTaskBranchLabel({
58 branchName: null,
59 startFromOrigin: false,
60 workspaceMode: "worktree",
61 pullRequestReference,
62 }),
63 ).toBe(label);
64 });
65});
66
67describe("resolveNewTaskLocalWorkspaceSelection", () => {
68 it("waits for refs instead of carrying a worktree base into Current checkout", () => {
69 expect(
70 resolveNewTaskLocalWorkspaceSelection({
71 branches: [],
72 projectCwd: "/repo",
73 }),
74 ).toEqual({
75 branch: null,
76 worktreePath: null,
77 awaitsCurrentBranch: true,
78 });
79 });
80
81 it("carries the worktree path when the current branch lives in another worktree", () => {
82 expect(
83 resolveNewTaskLocalWorkspaceSelection({
84 branches: [
85 { name: "feature/split", current: true, worktreePath: "/repo/.t3/worktrees/split" },
86 { name: "main", current: false, worktreePath: "/repo" },
87 ],
88 projectCwd: "/repo",
89 }),
90 ).toEqual({
91 branch: "feature/split",
92 worktreePath: "/repo/.t3/worktrees/split",
93 awaitsCurrentBranch: false,
94 });
95 });
96});
97
98describe("resolveNewTaskBranchWorktreePath", () => {
99 it("does not reuse an existing worktree while creating a new one", () => {
100 expect(
101 resolveNewTaskBranchWorktreePath({
102 workspaceMode: "worktree",
103 projectCwd: "/repo",
104 branchWorktreePath: "/repo/.t3/worktrees/feature",
105 }),
106 ).toBeNull();
107 });
108});
109
110describe("fillNewTaskWorkspaceBranch", () => {
111 const branches = [
112 { name: "origin/main", current: false, isDefault: true, isRemote: true },
113 { name: "feature", current: true, isDefault: false, worktreePath: "/repo-feature" },
114 ];
115 const base = {
116 branches,
117 projectCwd: "/repo",
118 worktreeDefaultSettled: true,
119 };
120
121 it("bases a new worktree on the default branch, even when only the remote has it", () => {
122 expect(
123 fillNewTaskWorkspaceBranch({
124 ...base,
125 selection: { mode: "worktree", branch: null, worktreePath: null },
126 }),
127 ).toEqual({ mode: "worktree", branch: "origin/main", worktreePath: null });
128 });
129
130 it("waits for the workspace default to settle before picking a base", () => {
131 const selection = { mode: "worktree", branch: null, worktreePath: null } as const;
132 expect(fillNewTaskWorkspaceBranch({ ...base, selection, worktreeDefaultSettled: false })).toBe(
133 selection,
134 );
135 });
136
137 it("follows the current checkout only for a local selection the user just chose", () => {
138 const selection = { mode: "local", branch: null, worktreePath: null } as const;
139 expect(fillNewTaskWorkspaceBranch({ ...base, selection })).toBe(selection);
140 expect(
141 fillNewTaskWorkspaceBranch({
142 ...base,
143 selection: { ...selection, followsCurrentCheckout: true },
144 }),
145 ).toEqual({
146 mode: "local",
147 branch: "feature",
148 worktreePath: "/repo-feature",
149 followsCurrentCheckout: true,
150 });
151 });
152
153 it("fills the current branch once refs arrive after local mode was chosen", () => {
154 const selection = {
155 mode: "local",
156 branch: null,
157 worktreePath: null,
158 followsCurrentCheckout: true,
159 } as const;
160 expect(fillNewTaskWorkspaceBranch({ ...base, branches: [], selection })).toBe(selection);
161 expect(fillNewTaskWorkspaceBranch({ ...base, selection })).toMatchObject({
162 branch: "feature",
163 worktreePath: "/repo-feature",
164 });
165 });
166
167 it("keeps an explicit branch", () => {
168 const selection = { mode: "worktree", branch: "release", worktreePath: null } as const;
169 expect(fillNewTaskWorkspaceBranch({ ...base, selection })).toBe(selection);
170 });
171});