@akiojin/gwt 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +4 -4
- package/README.md +4 -4
- package/dist/cli/ui/components/App.d.ts +4 -4
- package/dist/cli/ui/components/App.d.ts.map +1 -1
- package/dist/cli/ui/components/App.js +144 -105
- package/dist/cli/ui/components/App.js.map +1 -1
- package/dist/cli/ui/components/common/Confirm.d.ts +1 -1
- package/dist/cli/ui/components/common/Confirm.d.ts.map +1 -1
- package/dist/cli/ui/components/common/Confirm.js +7 -7
- package/dist/cli/ui/components/common/Confirm.js.map +1 -1
- package/dist/cli/ui/components/common/ErrorBoundary.d.ts +1 -1
- package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +1 -1
- package/dist/cli/ui/components/common/ErrorBoundary.js +4 -4
- package/dist/cli/ui/components/common/ErrorBoundary.js.map +1 -1
- package/dist/cli/ui/components/common/Input.d.ts +2 -2
- package/dist/cli/ui/components/common/Input.d.ts.map +1 -1
- package/dist/cli/ui/components/common/Input.js +4 -4
- package/dist/cli/ui/components/common/Input.js.map +1 -1
- package/dist/cli/ui/components/common/LoadingIndicator.d.ts +1 -1
- package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +1 -1
- package/dist/cli/ui/components/common/LoadingIndicator.js +4 -4
- package/dist/cli/ui/components/common/LoadingIndicator.js.map +1 -1
- package/dist/cli/ui/components/common/Select.d.ts +1 -1
- package/dist/cli/ui/components/common/Select.d.ts.map +1 -1
- package/dist/cli/ui/components/common/Select.js +11 -12
- package/dist/cli/ui/components/common/Select.js.map +1 -1
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.d.ts +2 -2
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.js +11 -11
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +1 -1
- package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchCreatorScreen.js +39 -36
- package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts +3 -3
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js +55 -50
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +2 -2
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +25 -25
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +2 -2
- package/dist/cli/ui/components/screens/PRCleanupScreen.js +21 -21
- package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +1 -1
- package/dist/cli/ui/components/screens/SessionSelectorScreen.js +8 -8
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.d.ts +1 -1
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.js +8 -8
- package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +1 -1
- package/dist/cli/ui/screens/BranchActionSelectorScreen.js +7 -4
- package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +1 -1
- package/dist/cli/ui/types.d.ts.map +1 -1
- package/dist/client/assets/{index-V6hDu9KS.js → index-Difv1Hwu.js} +2 -2
- package/dist/client/index.html +1 -1
- package/dist/config/builtin-tools.d.ts +10 -2
- package/dist/config/builtin-tools.d.ts.map +1 -1
- package/dist/config/builtin-tools.js +40 -4
- package/dist/config/builtin-tools.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/tools.d.ts.map +1 -1
- package/dist/config/tools.js +4 -3
- package/dist/config/tools.js.map +1 -1
- package/dist/gemini.d.ts +12 -0
- package/dist/gemini.d.ts.map +1 -0
- package/dist/gemini.js +154 -0
- package/dist/gemini.js.map +1 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/dist/qwen.d.ts +12 -0
- package/dist/qwen.d.ts.map +1 -0
- package/dist/qwen.js +154 -0
- package/dist/qwen.js.map +1 -0
- package/dist/services/git.service.d.ts.map +1 -1
- package/dist/services/git.service.js.map +1 -1
- package/dist/web/client/src/components/BranchGraph.d.ts.map +1 -1
- package/dist/web/client/src/components/BranchGraph.js +1 -1
- package/dist/web/client/src/components/BranchGraph.js.map +1 -1
- package/dist/web/client/src/components/EnvEditor.d.ts.map +1 -1
- package/dist/web/client/src/components/EnvEditor.js +7 -4
- package/dist/web/client/src/components/EnvEditor.js.map +1 -1
- package/dist/web/client/src/pages/BranchDetailPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/BranchDetailPage.js +55 -18
- package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
- package/dist/web/client/src/pages/BranchListPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/BranchListPage.js +10 -4
- package/dist/web/client/src/pages/BranchListPage.js.map +1 -1
- package/dist/web/client/src/pages/ConfigManagementPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/ConfigManagementPage.js +4 -2
- package/dist/web/client/src/pages/ConfigManagementPage.js.map +1 -1
- package/package.json +2 -1
- package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +69 -50
- package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +67 -45
- package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +117 -75
- package/src/cli/ui/__tests__/components/App.test.tsx +45 -37
- package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +35 -22
- package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +22 -22
- package/src/cli/ui/__tests__/components/common/Input.test.tsx +29 -22
- package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +40 -34
- package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +57 -66
- package/src/cli/ui/__tests__/components/common/Select.test.tsx +121 -91
- package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +18 -16
- package/src/cli/ui/__tests__/components/parts/Header.test.tsx +13 -13
- package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +20 -20
- package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +38 -26
- package/src/cli/ui/__tests__/components/screens/AIToolSelectorScreen.test.tsx +31 -31
- package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +73 -37
- package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +261 -153
- package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +38 -32
- package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +39 -39
- package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +49 -21
- package/src/cli/ui/__tests__/components/screens/WorktreeManagerScreen.test.tsx +52 -28
- package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +84 -48
- package/src/cli/ui/__tests__/integration/navigation.test.tsx +111 -83
- package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +111 -108
- package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +50 -37
- package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +75 -76
- package/src/cli/ui/components/App.tsx +247 -150
- package/src/cli/ui/components/common/Confirm.tsx +13 -9
- package/src/cli/ui/components/common/ErrorBoundary.tsx +8 -5
- package/src/cli/ui/components/common/Input.tsx +12 -4
- package/src/cli/ui/components/common/LoadingIndicator.tsx +8 -5
- package/src/cli/ui/components/common/Select.tsx +28 -17
- package/src/cli/ui/components/parts/Header.test.tsx +5 -15
- package/src/cli/ui/components/screens/AIToolSelectorScreen.tsx +19 -13
- package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +74 -54
- package/src/cli/ui/components/screens/BranchListScreen.tsx +92 -75
- package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +35 -28
- package/src/cli/ui/components/screens/PRCleanupScreen.tsx +22 -22
- package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +8 -8
- package/src/cli/ui/components/screens/WorktreeManagerScreen.tsx +8 -8
- package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +9 -4
- package/src/cli/ui/types.ts +8 -1
- package/src/config/builtin-tools.ts +42 -4
- package/src/config/index.ts +2 -12
- package/src/config/tools.ts +16 -6
- package/src/gemini.ts +202 -0
- package/src/git.ts +2 -1
- package/src/index.ts +30 -0
- package/src/qwen.ts +208 -0
- package/src/services/git.service.ts +2 -1
- package/src/web/client/src/components/BranchGraph.tsx +3 -2
- package/src/web/client/src/components/EnvEditor.tsx +44 -11
- package/src/web/client/src/pages/BranchDetailPage.tsx +165 -54
- package/src/web/client/src/pages/BranchListPage.tsx +37 -13
- package/src/web/client/src/pages/ConfigManagementPage.tsx +28 -9
|
@@ -1,34 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @vitest-environment happy-dom
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
import {
|
|
5
|
+
describe,
|
|
6
|
+
it,
|
|
7
|
+
expect,
|
|
8
|
+
beforeEach,
|
|
9
|
+
afterEach,
|
|
10
|
+
afterAll,
|
|
11
|
+
vi,
|
|
12
|
+
} from "vitest";
|
|
13
|
+
import type { Mock } from "vitest";
|
|
14
|
+
import { render, waitFor } from "@testing-library/react";
|
|
15
|
+
import { act } from "react-dom/test-utils";
|
|
16
|
+
import React from "react";
|
|
17
|
+
import { App } from "../../components/App.js";
|
|
18
|
+
import { Window } from "happy-dom";
|
|
19
|
+
import type { BranchInfo, BranchItem } from "../../types.js";
|
|
20
|
+
import * as BranchListScreenModule from "../../components/screens/BranchListScreen.js";
|
|
21
|
+
import * as BranchActionSelectorScreenModule from "../../screens/BranchActionSelectorScreen.js";
|
|
22
|
+
|
|
23
|
+
vi.mock("../../../../git.ts", () => ({
|
|
16
24
|
__esModule: true,
|
|
17
25
|
getAllBranches: vi.fn(),
|
|
18
|
-
getRepositoryRoot: vi.fn(async () =>
|
|
26
|
+
getRepositoryRoot: vi.fn(async () => "/repo"),
|
|
19
27
|
deleteBranch: vi.fn(async () => undefined),
|
|
20
28
|
}));
|
|
21
29
|
|
|
22
|
-
const { mockIsProtectedBranchName, mockSwitchToProtectedBranch } = vi.hoisted(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const { mockIsProtectedBranchName, mockSwitchToProtectedBranch } = vi.hoisted(
|
|
31
|
+
() => ({
|
|
32
|
+
mockIsProtectedBranchName: vi.fn(() => false),
|
|
33
|
+
mockSwitchToProtectedBranch: vi.fn(async () => "none" as const),
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
26
36
|
|
|
27
|
-
vi.mock(
|
|
37
|
+
vi.mock("../../../../worktree.ts", () => ({
|
|
28
38
|
__esModule: true,
|
|
29
39
|
listAdditionalWorktrees: vi.fn(),
|
|
30
40
|
createWorktree: vi.fn(async () => undefined),
|
|
31
|
-
generateWorktreePath: vi.fn(async () =>
|
|
41
|
+
generateWorktreePath: vi.fn(async () => "/repo/.git/worktree/test"),
|
|
32
42
|
getMergedPRWorktrees: vi.fn(async () => []),
|
|
33
43
|
removeWorktree: vi.fn(async () => undefined),
|
|
34
44
|
isProtectedBranchName: mockIsProtectedBranchName,
|
|
@@ -37,23 +47,27 @@ vi.mock('../../../../worktree.ts', () => ({
|
|
|
37
47
|
|
|
38
48
|
const aiToolScreenProps: unknown[] = [];
|
|
39
49
|
|
|
40
|
-
vi.mock(
|
|
50
|
+
vi.mock("../../components/screens/AIToolSelectorScreen.js", () => {
|
|
41
51
|
return {
|
|
42
52
|
AIToolSelectorScreen: (props: unknown) => {
|
|
43
53
|
aiToolScreenProps.push(props);
|
|
44
|
-
return React.createElement(
|
|
54
|
+
return React.createElement("div");
|
|
45
55
|
},
|
|
46
56
|
};
|
|
47
57
|
});
|
|
48
58
|
|
|
49
|
-
import {
|
|
59
|
+
import {
|
|
60
|
+
getAllBranches,
|
|
61
|
+
getRepositoryRoot,
|
|
62
|
+
deleteBranch,
|
|
63
|
+
} from "../../../../git.ts";
|
|
50
64
|
import {
|
|
51
65
|
listAdditionalWorktrees,
|
|
52
66
|
createWorktree,
|
|
53
67
|
generateWorktreePath,
|
|
54
68
|
getMergedPRWorktrees,
|
|
55
69
|
removeWorktree,
|
|
56
|
-
} from
|
|
70
|
+
} from "../../../../worktree.ts";
|
|
57
71
|
|
|
58
72
|
const mockedGetAllBranches = getAllBranches as Mock;
|
|
59
73
|
const mockedGetRepositoryRoot = getRepositoryRoot as Mock;
|
|
@@ -69,7 +83,7 @@ const originalBranchListScreen = BranchListScreenModule.BranchListScreen;
|
|
|
69
83
|
const originalBranchActionSelectorScreen =
|
|
70
84
|
BranchActionSelectorScreenModule.BranchActionSelectorScreen;
|
|
71
85
|
|
|
72
|
-
describe(
|
|
86
|
+
describe("Navigation Integration Tests", () => {
|
|
73
87
|
beforeEach(() => {
|
|
74
88
|
// Setup happy-dom
|
|
75
89
|
const window = new Window();
|
|
@@ -87,27 +101,29 @@ describe('Navigation Integration Tests', () => {
|
|
|
87
101
|
mockedRemoveWorktree.mockReset();
|
|
88
102
|
mockedIsProtectedBranchName.mockReset();
|
|
89
103
|
mockedSwitchToProtectedBranch.mockReset();
|
|
90
|
-
mockedGetRepositoryRoot.mockResolvedValue(
|
|
91
|
-
mockedSwitchToProtectedBranch.mockResolvedValue(
|
|
104
|
+
mockedGetRepositoryRoot.mockResolvedValue("/repo");
|
|
105
|
+
mockedSwitchToProtectedBranch.mockResolvedValue("local");
|
|
92
106
|
});
|
|
93
107
|
|
|
94
108
|
const mockBranches: BranchInfo[] = [
|
|
95
109
|
{
|
|
96
|
-
name:
|
|
97
|
-
type:
|
|
98
|
-
branchType:
|
|
110
|
+
name: "main",
|
|
111
|
+
type: "local",
|
|
112
|
+
branchType: "main",
|
|
99
113
|
isCurrent: true,
|
|
100
114
|
},
|
|
101
115
|
{
|
|
102
|
-
name:
|
|
103
|
-
type:
|
|
104
|
-
branchType:
|
|
116
|
+
name: "feature/test",
|
|
117
|
+
type: "local",
|
|
118
|
+
branchType: "feature",
|
|
105
119
|
isCurrent: false,
|
|
106
120
|
},
|
|
107
121
|
];
|
|
108
122
|
|
|
109
|
-
it(
|
|
110
|
-
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
123
|
+
it("should start with branch-list screen", async () => {
|
|
124
|
+
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
125
|
+
mockBranches,
|
|
126
|
+
);
|
|
111
127
|
(listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
112
128
|
|
|
113
129
|
const onExit = vi.fn();
|
|
@@ -119,8 +135,10 @@ describe('Navigation Integration Tests', () => {
|
|
|
119
135
|
});
|
|
120
136
|
});
|
|
121
137
|
|
|
122
|
-
it(
|
|
123
|
-
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
138
|
+
it("should support navigation between screens", async () => {
|
|
139
|
+
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
140
|
+
mockBranches,
|
|
141
|
+
);
|
|
124
142
|
(listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
125
143
|
|
|
126
144
|
const onExit = vi.fn();
|
|
@@ -134,8 +152,10 @@ describe('Navigation Integration Tests', () => {
|
|
|
134
152
|
expect(container).toBeDefined();
|
|
135
153
|
});
|
|
136
154
|
|
|
137
|
-
it(
|
|
138
|
-
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
155
|
+
it("should maintain state across screen transitions", async () => {
|
|
156
|
+
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
157
|
+
mockBranches,
|
|
158
|
+
);
|
|
139
159
|
(listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
140
160
|
|
|
141
161
|
const onExit = vi.fn();
|
|
@@ -149,8 +169,10 @@ describe('Navigation Integration Tests', () => {
|
|
|
149
169
|
expect(container).toBeDefined();
|
|
150
170
|
});
|
|
151
171
|
|
|
152
|
-
it(
|
|
153
|
-
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
172
|
+
it("should handle back navigation correctly", async () => {
|
|
173
|
+
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
174
|
+
mockBranches,
|
|
175
|
+
);
|
|
154
176
|
(listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
155
177
|
|
|
156
178
|
const onExit = vi.fn();
|
|
@@ -164,8 +186,10 @@ describe('Navigation Integration Tests', () => {
|
|
|
164
186
|
expect(container).toBeDefined();
|
|
165
187
|
});
|
|
166
188
|
|
|
167
|
-
it(
|
|
168
|
-
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
189
|
+
it("should handle navigation history", async () => {
|
|
190
|
+
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
191
|
+
mockBranches,
|
|
192
|
+
);
|
|
169
193
|
(listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
170
194
|
|
|
171
195
|
const onExit = vi.fn();
|
|
@@ -179,8 +203,10 @@ describe('Navigation Integration Tests', () => {
|
|
|
179
203
|
expect(container).toBeDefined();
|
|
180
204
|
});
|
|
181
205
|
|
|
182
|
-
it(
|
|
183
|
-
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
206
|
+
it("should display correct screen on navigation", async () => {
|
|
207
|
+
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
208
|
+
mockBranches,
|
|
209
|
+
);
|
|
184
210
|
(listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
185
211
|
|
|
186
212
|
const onExit = vi.fn();
|
|
@@ -194,8 +220,10 @@ describe('Navigation Integration Tests', () => {
|
|
|
194
220
|
expect(container).toBeDefined();
|
|
195
221
|
});
|
|
196
222
|
|
|
197
|
-
it(
|
|
198
|
-
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
223
|
+
it("should call onExit when branch is selected", async () => {
|
|
224
|
+
(getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(
|
|
225
|
+
mockBranches,
|
|
226
|
+
);
|
|
199
227
|
(listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
200
228
|
|
|
201
229
|
const onExit = vi.fn();
|
|
@@ -210,7 +238,7 @@ describe('Navigation Integration Tests', () => {
|
|
|
210
238
|
});
|
|
211
239
|
});
|
|
212
240
|
|
|
213
|
-
describe(
|
|
241
|
+
describe("Protected Branch Navigation (T103)", () => {
|
|
214
242
|
const branchListProps: any[] = [];
|
|
215
243
|
const branchActionProps: any[] = [];
|
|
216
244
|
let branchListSpy: ReturnType<typeof vi.spyOn>;
|
|
@@ -218,15 +246,15 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
218
246
|
|
|
219
247
|
const baseBranches: BranchInfo[] = [
|
|
220
248
|
{
|
|
221
|
-
name:
|
|
222
|
-
type:
|
|
223
|
-
branchType:
|
|
249
|
+
name: "main",
|
|
250
|
+
type: "local",
|
|
251
|
+
branchType: "main",
|
|
224
252
|
isCurrent: true,
|
|
225
253
|
},
|
|
226
254
|
{
|
|
227
|
-
name:
|
|
228
|
-
type:
|
|
229
|
-
branchType:
|
|
255
|
+
name: "feature/test",
|
|
256
|
+
type: "local",
|
|
257
|
+
branchType: "feature",
|
|
230
258
|
isCurrent: false,
|
|
231
259
|
},
|
|
232
260
|
];
|
|
@@ -245,28 +273,28 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
245
273
|
mockedRemoveWorktree.mockReset();
|
|
246
274
|
mockedIsProtectedBranchName.mockReset();
|
|
247
275
|
mockedSwitchToProtectedBranch.mockReset();
|
|
248
|
-
mockedGetRepositoryRoot.mockResolvedValue(
|
|
276
|
+
mockedGetRepositoryRoot.mockResolvedValue("/repo");
|
|
249
277
|
branchListProps.length = 0;
|
|
250
278
|
branchActionProps.length = 0;
|
|
251
279
|
aiToolScreenProps.length = 0;
|
|
252
280
|
branchListSpy = vi
|
|
253
|
-
.spyOn(BranchListScreenModule,
|
|
281
|
+
.spyOn(BranchListScreenModule, "BranchListScreen")
|
|
254
282
|
.mockImplementation((props: any) => {
|
|
255
283
|
branchListProps.push(props);
|
|
256
284
|
return React.createElement(originalBranchListScreen, props);
|
|
257
285
|
});
|
|
258
286
|
branchActionSpy = vi
|
|
259
|
-
.spyOn(BranchActionSelectorScreenModule,
|
|
287
|
+
.spyOn(BranchActionSelectorScreenModule, "BranchActionSelectorScreen")
|
|
260
288
|
.mockImplementation((props: any) => {
|
|
261
289
|
branchActionProps.push(props);
|
|
262
290
|
return React.createElement(originalBranchActionSelectorScreen, props);
|
|
263
291
|
});
|
|
264
292
|
|
|
265
293
|
mockedIsProtectedBranchName.mockImplementation((name: string) =>
|
|
266
|
-
[
|
|
294
|
+
["main", "develop", "origin/main", "origin/develop"].includes(name),
|
|
267
295
|
);
|
|
268
|
-
mockedSwitchToProtectedBranch.mockResolvedValue(
|
|
269
|
-
mockedGetRepositoryRoot.mockResolvedValue(
|
|
296
|
+
mockedSwitchToProtectedBranch.mockResolvedValue("local");
|
|
297
|
+
mockedGetRepositoryRoot.mockResolvedValue("/repo");
|
|
270
298
|
});
|
|
271
299
|
|
|
272
300
|
afterEach(() => {
|
|
@@ -274,7 +302,7 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
274
302
|
branchActionSpy.mockRestore();
|
|
275
303
|
});
|
|
276
304
|
|
|
277
|
-
it(
|
|
305
|
+
it("switches local protected branches via root workflow and navigates to AI tool", async () => {
|
|
278
306
|
mockedGetAllBranches.mockResolvedValue(baseBranches);
|
|
279
307
|
mockedListAdditionalWorktrees.mockResolvedValue([]);
|
|
280
308
|
|
|
@@ -288,15 +316,15 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
288
316
|
await waitFor(() => {
|
|
289
317
|
const latest = branchListProps.at(-1);
|
|
290
318
|
const names = (latest?.branches as BranchItem[] | undefined)?.map(
|
|
291
|
-
(item) => item.name
|
|
319
|
+
(item) => item.name,
|
|
292
320
|
);
|
|
293
321
|
expect(names).toBeDefined();
|
|
294
|
-
expect(names).toContain(
|
|
322
|
+
expect(names).toContain("main");
|
|
295
323
|
});
|
|
296
324
|
|
|
297
325
|
const latestProps = branchListProps.at(-1);
|
|
298
326
|
const protectedBranch = (latestProps?.branches as BranchItem[]).find(
|
|
299
|
-
(item) => item.name ===
|
|
327
|
+
(item) => item.name === "main",
|
|
300
328
|
);
|
|
301
329
|
expect(protectedBranch).toBeDefined();
|
|
302
330
|
|
|
@@ -310,8 +338,8 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
310
338
|
});
|
|
311
339
|
|
|
312
340
|
const actionProps = branchActionProps.at(-1);
|
|
313
|
-
expect(actionProps?.mode).toBe(
|
|
314
|
-
expect(actionProps?.infoMessage).toContain(
|
|
341
|
+
expect(actionProps?.mode).toBe("protected");
|
|
342
|
+
expect(actionProps?.infoMessage).toContain("is a root branch");
|
|
315
343
|
|
|
316
344
|
await act(async () => {
|
|
317
345
|
await actionProps?.onUseExisting();
|
|
@@ -319,8 +347,8 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
319
347
|
});
|
|
320
348
|
|
|
321
349
|
expect(mockedSwitchToProtectedBranch).toHaveBeenCalledWith({
|
|
322
|
-
branchName:
|
|
323
|
-
repoRoot:
|
|
350
|
+
branchName: "main",
|
|
351
|
+
repoRoot: "/repo",
|
|
324
352
|
remoteRef: null,
|
|
325
353
|
});
|
|
326
354
|
|
|
@@ -329,24 +357,24 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
329
357
|
});
|
|
330
358
|
});
|
|
331
359
|
|
|
332
|
-
it(
|
|
360
|
+
it("creates tracking branch for remote protected selections before navigating to AI tool", async () => {
|
|
333
361
|
const remoteBranches: BranchInfo[] = [
|
|
334
362
|
{
|
|
335
|
-
name:
|
|
336
|
-
type:
|
|
337
|
-
branchType:
|
|
363
|
+
name: "origin/develop",
|
|
364
|
+
type: "remote",
|
|
365
|
+
branchType: "develop",
|
|
338
366
|
isCurrent: false,
|
|
339
367
|
},
|
|
340
368
|
{
|
|
341
|
-
name:
|
|
342
|
-
type:
|
|
343
|
-
branchType:
|
|
369
|
+
name: "feature/test",
|
|
370
|
+
type: "local",
|
|
371
|
+
branchType: "feature",
|
|
344
372
|
isCurrent: false,
|
|
345
373
|
},
|
|
346
374
|
];
|
|
347
375
|
mockedGetAllBranches.mockResolvedValue(remoteBranches);
|
|
348
376
|
mockedListAdditionalWorktrees.mockResolvedValue([]);
|
|
349
|
-
mockedSwitchToProtectedBranch.mockResolvedValue(
|
|
377
|
+
mockedSwitchToProtectedBranch.mockResolvedValue("remote");
|
|
350
378
|
|
|
351
379
|
const onExit = vi.fn();
|
|
352
380
|
render(<App onExit={onExit} />);
|
|
@@ -358,15 +386,15 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
358
386
|
await waitFor(() => {
|
|
359
387
|
const latest = branchListProps.at(-1);
|
|
360
388
|
const names = (latest?.branches as BranchItem[] | undefined)?.map(
|
|
361
|
-
(item) => item.name
|
|
389
|
+
(item) => item.name,
|
|
362
390
|
);
|
|
363
391
|
expect(names).toBeDefined();
|
|
364
|
-
expect(names).toContain(
|
|
392
|
+
expect(names).toContain("origin/develop");
|
|
365
393
|
});
|
|
366
394
|
|
|
367
395
|
const latestProps = branchListProps.at(-1);
|
|
368
396
|
const protectedBranch = (latestProps?.branches as BranchItem[]).find(
|
|
369
|
-
(item) => item.name ===
|
|
397
|
+
(item) => item.name === "origin/develop",
|
|
370
398
|
);
|
|
371
399
|
expect(protectedBranch).toBeDefined();
|
|
372
400
|
|
|
@@ -380,8 +408,8 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
380
408
|
});
|
|
381
409
|
|
|
382
410
|
const actionProps = branchActionProps.at(-1);
|
|
383
|
-
expect(actionProps?.mode).toBe(
|
|
384
|
-
expect(actionProps?.primaryLabel).toContain(
|
|
411
|
+
expect(actionProps?.mode).toBe("protected");
|
|
412
|
+
expect(actionProps?.primaryLabel).toContain("root");
|
|
385
413
|
|
|
386
414
|
await act(async () => {
|
|
387
415
|
await actionProps?.onUseExisting();
|
|
@@ -389,9 +417,9 @@ describe('Protected Branch Navigation (T103)', () => {
|
|
|
389
417
|
});
|
|
390
418
|
|
|
391
419
|
expect(mockedSwitchToProtectedBranch).toHaveBeenCalledWith({
|
|
392
|
-
branchName:
|
|
393
|
-
repoRoot:
|
|
394
|
-
remoteRef:
|
|
420
|
+
branchName: "develop",
|
|
421
|
+
repoRoot: "/repo",
|
|
422
|
+
remoteRef: "origin/develop",
|
|
395
423
|
});
|
|
396
424
|
|
|
397
425
|
await waitFor(() => {
|