@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,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @vitest-environment happy-dom
|
|
3
3
|
*/
|
|
4
|
-
import { describe, it, expect, beforeEach, vi } from
|
|
5
|
-
import { render } from
|
|
6
|
-
import React from
|
|
7
|
-
import { WorktreeManagerScreen } from
|
|
8
|
-
import { Window } from
|
|
4
|
+
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
5
|
+
import { render } from "@testing-library/react";
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { WorktreeManagerScreen } from "../../../components/screens/WorktreeManagerScreen.js";
|
|
8
|
+
import { Window } from "happy-dom";
|
|
9
9
|
|
|
10
|
-
describe(
|
|
10
|
+
describe("WorktreeManagerScreen", () => {
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
// Setup happy-dom
|
|
13
13
|
const window = new Window();
|
|
@@ -17,69 +17,85 @@ describe('WorktreeManagerScreen', () => {
|
|
|
17
17
|
|
|
18
18
|
const mockWorktrees = [
|
|
19
19
|
{
|
|
20
|
-
branch:
|
|
21
|
-
path:
|
|
20
|
+
branch: "feature/test-1",
|
|
21
|
+
path: "/path/to/worktree-1",
|
|
22
22
|
isAccessible: true,
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
|
-
branch:
|
|
26
|
-
path:
|
|
25
|
+
branch: "feature/test-2",
|
|
26
|
+
path: "/path/to/worktree-2",
|
|
27
27
|
isAccessible: true,
|
|
28
28
|
},
|
|
29
29
|
];
|
|
30
30
|
|
|
31
|
-
it(
|
|
31
|
+
it("should render header with title", () => {
|
|
32
32
|
const onBack = vi.fn();
|
|
33
33
|
const onSelect = vi.fn();
|
|
34
34
|
const { getByText } = render(
|
|
35
|
-
<WorktreeManagerScreen
|
|
35
|
+
<WorktreeManagerScreen
|
|
36
|
+
worktrees={mockWorktrees}
|
|
37
|
+
onBack={onBack}
|
|
38
|
+
onSelect={onSelect}
|
|
39
|
+
/>,
|
|
36
40
|
);
|
|
37
41
|
|
|
38
42
|
expect(getByText(/Worktree Manager/i)).toBeDefined();
|
|
39
43
|
});
|
|
40
44
|
|
|
41
|
-
it(
|
|
45
|
+
it("should render worktree list", () => {
|
|
42
46
|
const onBack = vi.fn();
|
|
43
47
|
const onSelect = vi.fn();
|
|
44
48
|
const { getByText } = render(
|
|
45
|
-
<WorktreeManagerScreen
|
|
49
|
+
<WorktreeManagerScreen
|
|
50
|
+
worktrees={mockWorktrees}
|
|
51
|
+
onBack={onBack}
|
|
52
|
+
onSelect={onSelect}
|
|
53
|
+
/>,
|
|
46
54
|
);
|
|
47
55
|
|
|
48
56
|
expect(getByText(/feature\/test-1/)).toBeDefined();
|
|
49
57
|
expect(getByText(/feature\/test-2/)).toBeDefined();
|
|
50
58
|
});
|
|
51
59
|
|
|
52
|
-
it(
|
|
60
|
+
it("should render footer with actions", () => {
|
|
53
61
|
const onBack = vi.fn();
|
|
54
62
|
const onSelect = vi.fn();
|
|
55
63
|
const { getAllByText } = render(
|
|
56
|
-
<WorktreeManagerScreen
|
|
64
|
+
<WorktreeManagerScreen
|
|
65
|
+
worktrees={mockWorktrees}
|
|
66
|
+
onBack={onBack}
|
|
67
|
+
onSelect={onSelect}
|
|
68
|
+
/>,
|
|
57
69
|
);
|
|
58
70
|
|
|
59
71
|
expect(getAllByText(/enter/i).length).toBeGreaterThan(0);
|
|
60
72
|
expect(getAllByText(/esc/i).length).toBeGreaterThan(0);
|
|
61
73
|
});
|
|
62
74
|
|
|
63
|
-
it(
|
|
75
|
+
it("should handle empty worktree list", () => {
|
|
64
76
|
const onBack = vi.fn();
|
|
65
77
|
const onSelect = vi.fn();
|
|
66
78
|
const { getByText } = render(
|
|
67
|
-
<WorktreeManagerScreen
|
|
79
|
+
<WorktreeManagerScreen
|
|
80
|
+
worktrees={[]}
|
|
81
|
+
onBack={onBack}
|
|
82
|
+
onSelect={onSelect}
|
|
83
|
+
/>,
|
|
68
84
|
);
|
|
69
85
|
|
|
70
86
|
expect(getByText(/No worktrees found/i)).toBeDefined();
|
|
71
87
|
});
|
|
72
88
|
|
|
73
|
-
it(
|
|
89
|
+
it("should display inaccessible worktrees differently", () => {
|
|
74
90
|
const worktreesWithInaccessible = [
|
|
75
91
|
{
|
|
76
|
-
branch:
|
|
77
|
-
path:
|
|
92
|
+
branch: "feature/accessible",
|
|
93
|
+
path: "/path/accessible",
|
|
78
94
|
isAccessible: true,
|
|
79
95
|
},
|
|
80
96
|
{
|
|
81
|
-
branch:
|
|
82
|
-
path:
|
|
97
|
+
branch: "feature/inaccessible",
|
|
98
|
+
path: "/path/inaccessible",
|
|
83
99
|
isAccessible: false,
|
|
84
100
|
},
|
|
85
101
|
];
|
|
@@ -91,21 +107,25 @@ describe('WorktreeManagerScreen', () => {
|
|
|
91
107
|
worktrees={worktreesWithInaccessible}
|
|
92
108
|
onBack={onBack}
|
|
93
109
|
onSelect={onSelect}
|
|
94
|
-
|
|
110
|
+
/>,
|
|
95
111
|
);
|
|
96
112
|
|
|
97
113
|
expect(getByText(/feature\/accessible/)).toBeDefined();
|
|
98
114
|
expect(getByText(/feature\/inaccessible/)).toBeDefined();
|
|
99
115
|
});
|
|
100
116
|
|
|
101
|
-
it(
|
|
117
|
+
it("should use terminal height for layout calculation", () => {
|
|
102
118
|
const originalRows = process.stdout.rows;
|
|
103
119
|
process.stdout.rows = 30;
|
|
104
120
|
|
|
105
121
|
const onBack = vi.fn();
|
|
106
122
|
const onSelect = vi.fn();
|
|
107
123
|
const { container } = render(
|
|
108
|
-
<WorktreeManagerScreen
|
|
124
|
+
<WorktreeManagerScreen
|
|
125
|
+
worktrees={mockWorktrees}
|
|
126
|
+
onBack={onBack}
|
|
127
|
+
onSelect={onSelect}
|
|
128
|
+
/>,
|
|
109
129
|
);
|
|
110
130
|
|
|
111
131
|
expect(container).toBeDefined();
|
|
@@ -113,11 +133,15 @@ describe('WorktreeManagerScreen', () => {
|
|
|
113
133
|
process.stdout.rows = originalRows;
|
|
114
134
|
});
|
|
115
135
|
|
|
116
|
-
it(
|
|
136
|
+
it("should display worktree count in stats", () => {
|
|
117
137
|
const onBack = vi.fn();
|
|
118
138
|
const onSelect = vi.fn();
|
|
119
139
|
const { getByText, getAllByText } = render(
|
|
120
|
-
<WorktreeManagerScreen
|
|
140
|
+
<WorktreeManagerScreen
|
|
141
|
+
worktrees={mockWorktrees}
|
|
142
|
+
onBack={onBack}
|
|
143
|
+
onSelect={onSelect}
|
|
144
|
+
/>,
|
|
121
145
|
);
|
|
122
146
|
|
|
123
147
|
// Check for worktree count
|
|
@@ -2,20 +2,28 @@
|
|
|
2
2
|
* @vitest-environment happy-dom
|
|
3
3
|
* Edge case tests for UI components
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
import {
|
|
6
|
+
describe,
|
|
7
|
+
it,
|
|
8
|
+
expect,
|
|
9
|
+
beforeEach,
|
|
10
|
+
afterEach,
|
|
11
|
+
afterAll,
|
|
12
|
+
vi,
|
|
13
|
+
} from "vitest";
|
|
14
|
+
import { render } from "@testing-library/react";
|
|
15
|
+
import React from "react";
|
|
16
|
+
import { App } from "../../components/App.js";
|
|
17
|
+
import { BranchListScreen } from "../../components/screens/BranchListScreen.js";
|
|
18
|
+
import { Window } from "happy-dom";
|
|
19
|
+
import type { BranchInfo, BranchItem, Statistics } from "../../types.js";
|
|
20
|
+
import * as useGitDataModule from "../../hooks/useGitData.js";
|
|
13
21
|
|
|
14
22
|
const mockRefresh = vi.fn();
|
|
15
23
|
const originalUseGitData = useGitDataModule.useGitData;
|
|
16
|
-
const useGitDataSpy = vi.spyOn(useGitDataModule,
|
|
24
|
+
const useGitDataSpy = vi.spyOn(useGitDataModule, "useGitData");
|
|
17
25
|
|
|
18
|
-
describe(
|
|
26
|
+
describe("Edge Cases Integration Tests", () => {
|
|
19
27
|
beforeEach(() => {
|
|
20
28
|
// Setup happy-dom
|
|
21
29
|
const window = new Window();
|
|
@@ -31,7 +39,7 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
31
39
|
/**
|
|
32
40
|
* T091: Terminal size極小(10行以下)の動作確認
|
|
33
41
|
*/
|
|
34
|
-
it(
|
|
42
|
+
it("[T091] should handle minimal terminal size (10 rows)", () => {
|
|
35
43
|
// Save original rows
|
|
36
44
|
const originalRows = process.stdout.rows;
|
|
37
45
|
|
|
@@ -39,9 +47,9 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
39
47
|
process.stdout.rows = 10;
|
|
40
48
|
|
|
41
49
|
const mockBranches: BranchItem[] = [
|
|
42
|
-
{ name:
|
|
43
|
-
{ name:
|
|
44
|
-
{ name:
|
|
50
|
+
{ name: "main", label: "main", value: "main" },
|
|
51
|
+
{ name: "feature/a", label: "feature/a", value: "feature/a" },
|
|
52
|
+
{ name: "feature/b", label: "feature/b", value: "feature/b" },
|
|
45
53
|
];
|
|
46
54
|
|
|
47
55
|
const mockStats: Statistics = {
|
|
@@ -54,7 +62,11 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
54
62
|
|
|
55
63
|
const onSelect = vi.fn();
|
|
56
64
|
const { container } = render(
|
|
57
|
-
<BranchListScreen
|
|
65
|
+
<BranchListScreen
|
|
66
|
+
branches={mockBranches}
|
|
67
|
+
stats={mockStats}
|
|
68
|
+
onSelect={onSelect}
|
|
69
|
+
/>,
|
|
58
70
|
);
|
|
59
71
|
|
|
60
72
|
// Should render without crashing
|
|
@@ -64,12 +76,12 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
64
76
|
process.stdout.rows = originalRows;
|
|
65
77
|
});
|
|
66
78
|
|
|
67
|
-
it(
|
|
79
|
+
it("[T091] should handle extremely small terminal (5 rows)", () => {
|
|
68
80
|
const originalRows = process.stdout.rows;
|
|
69
81
|
process.stdout.rows = 5;
|
|
70
82
|
|
|
71
83
|
const mockBranches: BranchItem[] = [
|
|
72
|
-
{ name:
|
|
84
|
+
{ name: "main", label: "main", value: "main" },
|
|
73
85
|
];
|
|
74
86
|
|
|
75
87
|
const mockStats: Statistics = {
|
|
@@ -82,7 +94,11 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
82
94
|
|
|
83
95
|
const onSelect = vi.fn();
|
|
84
96
|
const { getByText } = render(
|
|
85
|
-
<BranchListScreen
|
|
97
|
+
<BranchListScreen
|
|
98
|
+
branches={mockBranches}
|
|
99
|
+
stats={mockStats}
|
|
100
|
+
onSelect={onSelect}
|
|
101
|
+
/>,
|
|
86
102
|
);
|
|
87
103
|
|
|
88
104
|
// Header should still be visible
|
|
@@ -94,15 +110,15 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
94
110
|
/**
|
|
95
111
|
* T092: 非常に長いブランチ名の表示確認
|
|
96
112
|
*/
|
|
97
|
-
it(
|
|
113
|
+
it("[T092] should handle very long branch names", () => {
|
|
98
114
|
const longBranchName =
|
|
99
|
-
|
|
115
|
+
"feature/very-long-branch-name-that-exceeds-normal-terminal-width-and-should-be-handled-gracefully";
|
|
100
116
|
|
|
101
117
|
const mockBranches: BranchItem[] = [
|
|
102
118
|
{
|
|
103
|
-
name:
|
|
104
|
-
label:
|
|
105
|
-
value:
|
|
119
|
+
name: "main",
|
|
120
|
+
label: "main",
|
|
121
|
+
value: "main",
|
|
106
122
|
latestCommitTimestamp: 1_700_000_000,
|
|
107
123
|
},
|
|
108
124
|
{
|
|
@@ -123,27 +139,33 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
123
139
|
|
|
124
140
|
const onSelect = vi.fn();
|
|
125
141
|
const { container } = render(
|
|
126
|
-
<BranchListScreen
|
|
142
|
+
<BranchListScreen
|
|
143
|
+
branches={mockBranches}
|
|
144
|
+
stats={mockStats}
|
|
145
|
+
onSelect={onSelect}
|
|
146
|
+
/>,
|
|
127
147
|
);
|
|
128
148
|
|
|
129
149
|
// Long branch name should be displayed (Ink will handle wrapping/truncation)
|
|
130
150
|
expect(container.textContent).toMatch(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}/);
|
|
131
151
|
});
|
|
132
152
|
|
|
133
|
-
it(
|
|
153
|
+
it("[T092] should handle branch names with special characters", () => {
|
|
134
154
|
const specialBranchNames = [
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
155
|
+
"feature/bug-fix-#123",
|
|
156
|
+
"hotfix/issue@456",
|
|
157
|
+
"release/v1.0.0-beta.1",
|
|
158
|
+
"feature/改善-日本語",
|
|
139
159
|
];
|
|
140
160
|
|
|
141
|
-
const mockBranches: BranchItem[] = specialBranchNames.map(
|
|
142
|
-
name,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
161
|
+
const mockBranches: BranchItem[] = specialBranchNames.map(
|
|
162
|
+
(name, index) => ({
|
|
163
|
+
name,
|
|
164
|
+
label: name,
|
|
165
|
+
value: name,
|
|
166
|
+
latestCommitTimestamp: 1_700_001_000 + index * 60,
|
|
167
|
+
}),
|
|
168
|
+
);
|
|
147
169
|
|
|
148
170
|
const mockStats: Statistics = {
|
|
149
171
|
localCount: mockBranches.length,
|
|
@@ -155,7 +177,11 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
155
177
|
|
|
156
178
|
const onSelect = vi.fn();
|
|
157
179
|
const { container } = render(
|
|
158
|
-
<BranchListScreen
|
|
180
|
+
<BranchListScreen
|
|
181
|
+
branches={mockBranches}
|
|
182
|
+
stats={mockStats}
|
|
183
|
+
onSelect={onSelect}
|
|
184
|
+
/>,
|
|
159
185
|
);
|
|
160
186
|
|
|
161
187
|
// All special branch names should be displayed
|
|
@@ -167,13 +193,13 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
167
193
|
/**
|
|
168
194
|
* T093: Error Boundary動作確認
|
|
169
195
|
*/
|
|
170
|
-
it(
|
|
196
|
+
it("[T093] should catch errors in App component", async () => {
|
|
171
197
|
// Mock useGitData to throw an error after initial render
|
|
172
198
|
let callCount = 0;
|
|
173
199
|
useGitDataSpy.mockImplementation(() => {
|
|
174
200
|
callCount++;
|
|
175
201
|
if (callCount > 1) {
|
|
176
|
-
throw new Error(
|
|
202
|
+
throw new Error("Simulated error");
|
|
177
203
|
}
|
|
178
204
|
return {
|
|
179
205
|
branches: [],
|
|
@@ -192,8 +218,8 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
192
218
|
expect(container).toBeDefined();
|
|
193
219
|
});
|
|
194
220
|
|
|
195
|
-
it(
|
|
196
|
-
const testError = new Error(
|
|
221
|
+
it("[T093] should display error message when data loading fails", () => {
|
|
222
|
+
const testError = new Error("Test error: Failed to load Git data");
|
|
197
223
|
useGitDataSpy.mockReturnValue({
|
|
198
224
|
branches: [],
|
|
199
225
|
worktrees: [],
|
|
@@ -211,7 +237,7 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
211
237
|
expect(getByText(/Failed to load Git data/i)).toBeDefined();
|
|
212
238
|
});
|
|
213
239
|
|
|
214
|
-
it(
|
|
240
|
+
it("[T093] should handle empty branches list gracefully", () => {
|
|
215
241
|
useGitDataSpy.mockReturnValue({
|
|
216
242
|
branches: [],
|
|
217
243
|
worktrees: [],
|
|
@@ -231,11 +257,11 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
231
257
|
/**
|
|
232
258
|
* Additional edge cases
|
|
233
259
|
*/
|
|
234
|
-
it(
|
|
260
|
+
it("should handle large number of worktrees", () => {
|
|
235
261
|
const mockBranches: BranchInfo[] = Array.from({ length: 50 }, (_, i) => ({
|
|
236
262
|
name: `feature/branch-${i}`,
|
|
237
|
-
type:
|
|
238
|
-
branchType:
|
|
263
|
+
type: "local" as const,
|
|
264
|
+
branchType: "feature" as const,
|
|
239
265
|
isCurrent: false,
|
|
240
266
|
}));
|
|
241
267
|
|
|
@@ -259,14 +285,14 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
259
285
|
expect(container).toBeDefined();
|
|
260
286
|
});
|
|
261
287
|
|
|
262
|
-
it(
|
|
288
|
+
it("should handle terminal resize gracefully", () => {
|
|
263
289
|
const originalRows = process.stdout.rows;
|
|
264
290
|
|
|
265
291
|
// Start with normal size
|
|
266
292
|
process.stdout.rows = 30;
|
|
267
293
|
|
|
268
294
|
const mockBranches: BranchItem[] = [
|
|
269
|
-
{ name:
|
|
295
|
+
{ name: "main", label: "main", value: "main" },
|
|
270
296
|
];
|
|
271
297
|
|
|
272
298
|
const mockStats: Statistics = {
|
|
@@ -279,7 +305,11 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
279
305
|
|
|
280
306
|
const onSelect = vi.fn();
|
|
281
307
|
const { container, rerender } = render(
|
|
282
|
-
<BranchListScreen
|
|
308
|
+
<BranchListScreen
|
|
309
|
+
branches={mockBranches}
|
|
310
|
+
stats={mockStats}
|
|
311
|
+
onSelect={onSelect}
|
|
312
|
+
/>,
|
|
283
313
|
);
|
|
284
314
|
|
|
285
315
|
expect(container).toBeDefined();
|
|
@@ -288,7 +318,13 @@ describe('Edge Cases Integration Tests', () => {
|
|
|
288
318
|
process.stdout.rows = 15;
|
|
289
319
|
|
|
290
320
|
// Re-render
|
|
291
|
-
rerender(
|
|
321
|
+
rerender(
|
|
322
|
+
<BranchListScreen
|
|
323
|
+
branches={mockBranches}
|
|
324
|
+
stats={mockStats}
|
|
325
|
+
onSelect={onSelect}
|
|
326
|
+
/>,
|
|
327
|
+
);
|
|
292
328
|
|
|
293
329
|
expect(container).toBeDefined();
|
|
294
330
|
|