@akiojin/gwt 2.10.0 → 2.11.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/dist/cli/ui/components/App.d.ts.map +1 -1
- package/dist/cli/ui/components/App.js +5 -47
- package/dist/cli/ui/components/App.js.map +1 -1
- package/dist/cli/ui/components/common/Input.d.ts +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts +1 -2
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js +19 -14
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/ModelSelectorScreen.js +6 -6
- package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -3
- package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +1 -1
- package/dist/cli/ui/hooks/useGitData.d.ts.map +1 -1
- package/dist/cli/ui/hooks/useGitData.js +43 -2
- package/dist/cli/ui/hooks/useGitData.js.map +1 -1
- package/dist/cli/ui/types.d.ts +16 -4
- package/dist/cli/ui/types.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.js +124 -15
- package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
- package/dist/cli/ui/utils/modelOptions.d.ts.map +1 -1
- package/dist/cli/ui/utils/modelOptions.js.map +1 -1
- package/dist/client/assets/{index-CNWntAlF.js → index-Dl798X5w.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/git.d.ts +6 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +40 -5
- package/dist/git.js.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/pages/BranchDetailPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/BranchDetailPage.js +8 -3
- package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
- package/dist/web/server/routes/sessions.d.ts.map +1 -1
- package/dist/web/server/routes/sessions.js +4 -2
- package/dist/web/server/routes/sessions.js.map +1 -1
- package/dist/worktree.d.ts.map +1 -1
- package/dist/worktree.js +31 -44
- package/dist/worktree.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +9 -17
- package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +14 -20
- package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +14 -44
- package/src/cli/ui/__tests__/components/App.test.tsx +8 -15
- package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +12 -5
- package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/common/Input.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +15 -14
- package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +3 -3
- package/src/cli/ui/__tests__/components/common/Select.test.tsx +1 -4
- package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/parts/Header.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/screens/AIToolSelectorScreen.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +31 -41
- package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +3 -2
- package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +3 -2
- package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +18 -17
- package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +3 -2
- package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +5 -12
- package/src/cli/ui/__tests__/integration/navigation.test.tsx +15 -10
- package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +3 -2
- package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -4
- package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +3 -5
- package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +24 -22
- package/src/cli/ui/components/App.tsx +3 -74
- package/src/cli/ui/components/common/Input.tsx +1 -1
- package/src/cli/ui/components/screens/BranchListScreen.tsx +32 -22
- package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +46 -49
- package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -3
- package/src/cli/ui/hooks/useGitData.ts +59 -1
- package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +3 -2
- package/src/cli/ui/types.ts +24 -5
- package/src/cli/ui/utils/branchFormatter.ts +123 -15
- package/src/cli/ui/utils/modelOptions.test.ts +4 -6
- package/src/cli/ui/utils/modelOptions.ts +1 -2
- package/src/config/index.ts +2 -1
- package/src/git.ts +56 -16
- package/src/web/client/src/components/BranchGraph.tsx +1 -1
- package/src/web/client/src/pages/BranchDetailPage.tsx +8 -3
- package/src/web/server/routes/sessions.ts +12 -5
- package/src/worktree.ts +31 -59
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.d.ts +0 -20
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.js +0 -65
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.js.map +0 -1
- package/src/cli/ui/__tests__/components/screens/WorktreeManagerScreen.test.tsx +0 -151
- package/src/cli/ui/components/screens/WorktreeManagerScreen.tsx +0 -117
|
@@ -24,8 +24,9 @@ beforeEach(() => {
|
|
|
24
24
|
vi.useFakeTimers();
|
|
25
25
|
}
|
|
26
26
|
const window = new Window();
|
|
27
|
-
globalThis.window = window as
|
|
28
|
-
globalThis.document =
|
|
27
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
28
|
+
globalThis.document =
|
|
29
|
+
window.document as unknown as typeof globalThis.document;
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
afterEach(() => {
|
|
@@ -78,18 +79,18 @@ describe("LoadingIndicator", () => {
|
|
|
78
79
|
|
|
79
80
|
expect(getMessageText(container)).toContain("Loading data");
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
82
|
+
await act(async () => {
|
|
83
|
+
rerender(
|
|
84
|
+
<LoadingIndicator
|
|
85
|
+
isLoading={false}
|
|
86
|
+
message="Loading data"
|
|
87
|
+
delay={10}
|
|
88
|
+
/>,
|
|
89
|
+
);
|
|
90
|
+
if (typeof vi.advanceTimersByTimeAsync === "function") {
|
|
91
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
93
94
|
|
|
94
95
|
expect(container.textContent).toBe("");
|
|
95
96
|
});
|
|
@@ -19,14 +19,14 @@ import { Select, type SelectItem } from "../../../components/common/Select.js";
|
|
|
19
19
|
describe.skip("Select Component React.memo (T082-2)", () => {
|
|
20
20
|
beforeEach(() => {
|
|
21
21
|
const window = new Window();
|
|
22
|
-
globalThis.window = window as
|
|
23
|
-
globalThis.document =
|
|
22
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
23
|
+
globalThis.document =
|
|
24
|
+
window.document as unknown as typeof globalThis.document;
|
|
24
25
|
vi.clearAllMocks();
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
it("should not re-render when items array reference changes but content is the same", () => {
|
|
28
29
|
const onSelect = vi.fn();
|
|
29
|
-
const renderCount = 0;
|
|
30
30
|
|
|
31
31
|
// Wrapper component to track renders
|
|
32
32
|
function TestWrapper() {
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @vitest-environment happy-dom
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import { describe, it, expect, vi } from "vitest";
|
|
6
6
|
import { render } from "ink-testing-library";
|
|
7
7
|
import React from "react";
|
|
8
8
|
import { Select } from "../../../components/common/Select.js";
|
|
9
9
|
|
|
10
|
-
// Helper to wait for async updates
|
|
11
|
-
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
-
|
|
13
10
|
interface TestItem {
|
|
14
11
|
label: string;
|
|
15
12
|
value: string;
|
|
@@ -11,8 +11,9 @@ describe("Footer", () => {
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
// Setup happy-dom
|
|
13
13
|
const window = new Window();
|
|
14
|
-
globalThis.window = window as
|
|
15
|
-
globalThis.document =
|
|
14
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
15
|
+
globalThis.document =
|
|
16
|
+
window.document as unknown as typeof globalThis.document;
|
|
16
17
|
});
|
|
17
18
|
|
|
18
19
|
const mockActions = [
|
|
@@ -11,8 +11,9 @@ describe("Header", () => {
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
// Setup happy-dom
|
|
13
13
|
const window = new Window();
|
|
14
|
-
globalThis.window = window as
|
|
15
|
-
globalThis.document =
|
|
14
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
15
|
+
globalThis.document =
|
|
16
|
+
window.document as unknown as typeof globalThis.document;
|
|
16
17
|
});
|
|
17
18
|
|
|
18
19
|
it("should render title", () => {
|
|
@@ -12,8 +12,9 @@ describe("ScrollableList", () => {
|
|
|
12
12
|
beforeEach(() => {
|
|
13
13
|
// Setup happy-dom
|
|
14
14
|
const window = new Window();
|
|
15
|
-
globalThis.window = window as
|
|
16
|
-
globalThis.document =
|
|
15
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
16
|
+
globalThis.document =
|
|
17
|
+
window.document as unknown as typeof globalThis.document;
|
|
17
18
|
});
|
|
18
19
|
|
|
19
20
|
it("should render children", () => {
|
|
@@ -12,8 +12,9 @@ describe("Stats", () => {
|
|
|
12
12
|
beforeEach(() => {
|
|
13
13
|
// Setup happy-dom
|
|
14
14
|
const window = new Window();
|
|
15
|
-
globalThis.window = window as
|
|
16
|
-
globalThis.document =
|
|
15
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
16
|
+
globalThis.document =
|
|
17
|
+
window.document as unknown as typeof globalThis.document;
|
|
17
18
|
});
|
|
18
19
|
|
|
19
20
|
const mockStats: Statistics = {
|
|
@@ -27,8 +27,9 @@ describe("AIToolSelectorScreen", () => {
|
|
|
27
27
|
beforeEach(() => {
|
|
28
28
|
// Setup happy-dom
|
|
29
29
|
const window = new Window();
|
|
30
|
-
globalThis.window = window as
|
|
31
|
-
globalThis.document =
|
|
30
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
31
|
+
globalThis.document =
|
|
32
|
+
window.document as unknown as typeof globalThis.document;
|
|
32
33
|
});
|
|
33
34
|
|
|
34
35
|
it("should render header with title", () => {
|
|
@@ -13,8 +13,9 @@ describe("BranchCreatorScreen", () => {
|
|
|
13
13
|
vi.useFakeTimers();
|
|
14
14
|
// Setup happy-dom
|
|
15
15
|
const window = new Window();
|
|
16
|
-
globalThis.window = window as
|
|
17
|
-
globalThis.document =
|
|
16
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
17
|
+
globalThis.document =
|
|
18
|
+
window.document as unknown as typeof globalThis.document;
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
afterEach(() => {
|
|
@@ -27,8 +27,9 @@ describe("BranchListScreen", () => {
|
|
|
27
27
|
vi.useFakeTimers();
|
|
28
28
|
// Setup happy-dom
|
|
29
29
|
const window = new Window();
|
|
30
|
-
globalThis.window = window as
|
|
31
|
-
globalThis.document =
|
|
30
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
31
|
+
globalThis.document =
|
|
32
|
+
window.document as unknown as typeof globalThis.document;
|
|
32
33
|
});
|
|
33
34
|
|
|
34
35
|
afterEach(() => {
|
|
@@ -142,7 +143,7 @@ describe("BranchListScreen", () => {
|
|
|
142
143
|
|
|
143
144
|
it("should display loading indicator after the configured delay", async () => {
|
|
144
145
|
const onSelect = vi.fn();
|
|
145
|
-
const {
|
|
146
|
+
const { getByText } = render(
|
|
146
147
|
<BranchListScreen
|
|
147
148
|
branches={mockBranches}
|
|
148
149
|
stats={mockStats}
|
|
@@ -153,8 +154,8 @@ describe("BranchListScreen", () => {
|
|
|
153
154
|
);
|
|
154
155
|
|
|
155
156
|
await act(async () => {
|
|
156
|
-
if (typeof
|
|
157
|
-
|
|
157
|
+
if (typeof vi.advanceTimersByTime === "function") {
|
|
158
|
+
vi.advanceTimersByTime(10);
|
|
158
159
|
} else {
|
|
159
160
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
160
161
|
}
|
|
@@ -299,7 +300,7 @@ describe("BranchListScreen", () => {
|
|
|
299
300
|
);
|
|
300
301
|
});
|
|
301
302
|
|
|
302
|
-
const frame = renderResult
|
|
303
|
+
const frame = renderResult?.lastFrame() ?? "";
|
|
303
304
|
expect(frame).toContain("\u001b[46m"); // cyan background ANSI code
|
|
304
305
|
});
|
|
305
306
|
|
|
@@ -356,7 +357,7 @@ describe("BranchListScreen", () => {
|
|
|
356
357
|
);
|
|
357
358
|
});
|
|
358
359
|
|
|
359
|
-
const frame = renderResult
|
|
360
|
+
const frame = renderResult?.lastFrame() ?? "";
|
|
360
361
|
const timestampLines = frame
|
|
361
362
|
.split("\n")
|
|
362
363
|
.map((line) => stripControlSequences(stripAnsi(line)))
|
|
@@ -417,10 +418,9 @@ describe("BranchListScreen", () => {
|
|
|
417
418
|
expect(container.textContent).toContain("(press f to filter)");
|
|
418
419
|
|
|
419
420
|
// Press 'f' key
|
|
420
|
-
const fKeyEvent = new
|
|
421
|
-
"
|
|
422
|
-
|
|
423
|
-
);
|
|
421
|
+
const fKeyEvent = new globalThis.window.KeyboardEvent("keydown", {
|
|
422
|
+
key: "f",
|
|
423
|
+
});
|
|
424
424
|
document.dispatchEvent(fKeyEvent);
|
|
425
425
|
|
|
426
426
|
// Filter input should be active (placeholder visible)
|
|
@@ -439,17 +439,15 @@ describe("BranchListScreen", () => {
|
|
|
439
439
|
);
|
|
440
440
|
|
|
441
441
|
// Enter filter mode first
|
|
442
|
-
const fKeyEvent = new
|
|
443
|
-
"
|
|
444
|
-
|
|
445
|
-
);
|
|
442
|
+
const fKeyEvent = new globalThis.window.KeyboardEvent("keydown", {
|
|
443
|
+
key: "f",
|
|
444
|
+
});
|
|
446
445
|
document.dispatchEvent(fKeyEvent);
|
|
447
446
|
|
|
448
447
|
// Press Escape
|
|
449
|
-
const escKeyEvent = new
|
|
450
|
-
"
|
|
451
|
-
|
|
452
|
-
);
|
|
448
|
+
const escKeyEvent = new globalThis.window.KeyboardEvent("keydown", {
|
|
449
|
+
key: "Escape",
|
|
450
|
+
});
|
|
453
451
|
document.dispatchEvent(escKeyEvent);
|
|
454
452
|
|
|
455
453
|
// Should return to branch selection mode
|
|
@@ -473,7 +471,7 @@ describe("BranchListScreen", () => {
|
|
|
473
471
|
);
|
|
474
472
|
});
|
|
475
473
|
|
|
476
|
-
const frame = renderResult
|
|
474
|
+
const frame = renderResult?.lastFrame() ?? "";
|
|
477
475
|
// Should contain cyan background (cursor highlight) even in filter mode
|
|
478
476
|
expect(frame).toContain("\u001b[46m");
|
|
479
477
|
});
|
|
@@ -570,10 +568,9 @@ describe("BranchListScreen", () => {
|
|
|
570
568
|
);
|
|
571
569
|
|
|
572
570
|
// Enter filter mode
|
|
573
|
-
const fKeyEvent = new
|
|
574
|
-
"
|
|
575
|
-
|
|
576
|
-
);
|
|
571
|
+
const fKeyEvent = new globalThis.window.KeyboardEvent("keydown", {
|
|
572
|
+
key: "f",
|
|
573
|
+
});
|
|
577
574
|
document.dispatchEvent(fKeyEvent);
|
|
578
575
|
|
|
579
576
|
// Type something in filter
|
|
@@ -584,10 +581,9 @@ describe("BranchListScreen", () => {
|
|
|
584
581
|
}
|
|
585
582
|
|
|
586
583
|
// Press Escape (should clear query first)
|
|
587
|
-
const escKeyEvent = new
|
|
588
|
-
"
|
|
589
|
-
|
|
590
|
-
);
|
|
584
|
+
const escKeyEvent = new globalThis.window.KeyboardEvent("keydown", {
|
|
585
|
+
key: "Escape",
|
|
586
|
+
});
|
|
591
587
|
document.dispatchEvent(escKeyEvent);
|
|
592
588
|
|
|
593
589
|
// Filter input should still be visible, but query cleared
|
|
@@ -608,17 +604,15 @@ describe("BranchListScreen", () => {
|
|
|
608
604
|
);
|
|
609
605
|
|
|
610
606
|
// Enter filter mode
|
|
611
|
-
const fKeyEvent = new
|
|
612
|
-
"
|
|
613
|
-
|
|
614
|
-
);
|
|
607
|
+
const fKeyEvent = new globalThis.window.KeyboardEvent("keydown", {
|
|
608
|
+
key: "f",
|
|
609
|
+
});
|
|
615
610
|
document.dispatchEvent(fKeyEvent);
|
|
616
611
|
|
|
617
612
|
// Press Escape with empty query (should exit filter mode)
|
|
618
|
-
const escKeyEvent = new
|
|
619
|
-
"
|
|
620
|
-
|
|
621
|
-
);
|
|
613
|
+
const escKeyEvent = new globalThis.window.KeyboardEvent("keydown", {
|
|
614
|
+
key: "Escape",
|
|
615
|
+
});
|
|
622
616
|
document.dispatchEvent(escKeyEvent);
|
|
623
617
|
|
|
624
618
|
// Should return to branch selection mode
|
|
@@ -641,9 +635,8 @@ describe("BranchListScreen", () => {
|
|
|
641
635
|
expect(container.textContent).toContain("feature/test");
|
|
642
636
|
});
|
|
643
637
|
|
|
644
|
-
it("should disable other key bindings (
|
|
638
|
+
it("should disable other key bindings (c, r) while typing in filter", () => {
|
|
645
639
|
const onSelect = vi.fn();
|
|
646
|
-
const onNavigate = vi.fn();
|
|
647
640
|
const onCleanupCommand = vi.fn();
|
|
648
641
|
const onRefresh = vi.fn();
|
|
649
642
|
|
|
@@ -652,7 +645,6 @@ describe("BranchListScreen", () => {
|
|
|
652
645
|
branches={mockBranches}
|
|
653
646
|
stats={mockStats}
|
|
654
647
|
onSelect={onSelect}
|
|
655
|
-
onNavigate={onNavigate}
|
|
656
648
|
onCleanupCommand={onCleanupCommand}
|
|
657
649
|
onRefresh={onRefresh}
|
|
658
650
|
/>,
|
|
@@ -665,10 +657,8 @@ describe("BranchListScreen", () => {
|
|
|
665
657
|
act(() => {
|
|
666
658
|
inkApp.stdin.write("c");
|
|
667
659
|
inkApp.stdin.write("r");
|
|
668
|
-
inkApp.stdin.write("m");
|
|
669
660
|
});
|
|
670
661
|
|
|
671
|
-
expect(onNavigate).not.toHaveBeenCalled();
|
|
672
662
|
expect(onCleanupCommand).not.toHaveBeenCalled();
|
|
673
663
|
expect(onRefresh).not.toHaveBeenCalled();
|
|
674
664
|
|
|
@@ -11,8 +11,9 @@ describe("ExecutionModeSelectorScreen", () => {
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
// Setup happy-dom
|
|
13
13
|
const window = new Window();
|
|
14
|
-
globalThis.window = window as
|
|
15
|
-
globalThis.document =
|
|
14
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
15
|
+
globalThis.document =
|
|
16
|
+
window.document as unknown as typeof globalThis.document;
|
|
16
17
|
});
|
|
17
18
|
|
|
18
19
|
it("should render header with title", () => {
|
|
@@ -12,8 +12,9 @@ describe("PRCleanupScreen", () => {
|
|
|
12
12
|
beforeEach(() => {
|
|
13
13
|
// Setup happy-dom
|
|
14
14
|
const window = new Window();
|
|
15
|
-
globalThis.window = window as
|
|
16
|
-
globalThis.document =
|
|
15
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
16
|
+
globalThis.document =
|
|
17
|
+
window.document as unknown as typeof globalThis.document;
|
|
17
18
|
});
|
|
18
19
|
|
|
19
20
|
const mockTargets: CleanupTarget[] = [
|
|
@@ -11,8 +11,9 @@ describe("SessionSelectorScreen", () => {
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
// Setup happy-dom
|
|
13
13
|
const window = new Window();
|
|
14
|
-
globalThis.window = window as
|
|
15
|
-
globalThis.document =
|
|
14
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
15
|
+
globalThis.document =
|
|
16
|
+
window.document as unknown as typeof globalThis.document;
|
|
16
17
|
});
|
|
17
18
|
|
|
18
19
|
const mockSessions = ["session-1", "session-2", "session-3"];
|
|
@@ -11,8 +11,9 @@ describe("useScreenState", () => {
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
// Setup happy-dom
|
|
13
13
|
const window = new Window();
|
|
14
|
-
globalThis.window = window as
|
|
15
|
-
globalThis.document =
|
|
14
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
15
|
+
globalThis.document =
|
|
16
|
+
window.document as unknown as typeof globalThis.document;
|
|
16
17
|
});
|
|
17
18
|
it("should initialize with branch-list as active screen", () => {
|
|
18
19
|
const { result } = renderHook(() => useScreenState());
|
|
@@ -24,20 +25,20 @@ describe("useScreenState", () => {
|
|
|
24
25
|
const { result } = renderHook(() => useScreenState());
|
|
25
26
|
|
|
26
27
|
act(() => {
|
|
27
|
-
result.current.navigateTo("
|
|
28
|
+
result.current.navigateTo("branch-creator");
|
|
28
29
|
});
|
|
29
30
|
|
|
30
|
-
expect(result.current.currentScreen).toBe("
|
|
31
|
+
expect(result.current.currentScreen).toBe("branch-creator");
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
it("should navigate back to previous screen", () => {
|
|
34
35
|
const { result } = renderHook(() => useScreenState());
|
|
35
36
|
|
|
36
37
|
act(() => {
|
|
37
|
-
result.current.navigateTo("
|
|
38
|
+
result.current.navigateTo("branch-creator");
|
|
38
39
|
});
|
|
39
40
|
|
|
40
|
-
expect(result.current.currentScreen).toBe("
|
|
41
|
+
expect(result.current.currentScreen).toBe("branch-creator");
|
|
41
42
|
|
|
42
43
|
act(() => {
|
|
43
44
|
result.current.goBack();
|
|
@@ -50,20 +51,20 @@ describe("useScreenState", () => {
|
|
|
50
51
|
const { result } = renderHook(() => useScreenState());
|
|
51
52
|
|
|
52
53
|
act(() => {
|
|
53
|
-
result.current.navigateTo("
|
|
54
|
+
result.current.navigateTo("branch-creator");
|
|
54
55
|
});
|
|
55
56
|
|
|
56
57
|
act(() => {
|
|
57
|
-
result.current.navigateTo("
|
|
58
|
+
result.current.navigateTo("ai-tool-selector");
|
|
58
59
|
});
|
|
59
60
|
|
|
60
|
-
expect(result.current.currentScreen).toBe("
|
|
61
|
+
expect(result.current.currentScreen).toBe("ai-tool-selector");
|
|
61
62
|
|
|
62
63
|
act(() => {
|
|
63
64
|
result.current.goBack();
|
|
64
65
|
});
|
|
65
66
|
|
|
66
|
-
expect(result.current.currentScreen).toBe("
|
|
67
|
+
expect(result.current.currentScreen).toBe("branch-creator");
|
|
67
68
|
|
|
68
69
|
act(() => {
|
|
69
70
|
result.current.goBack();
|
|
@@ -88,9 +89,9 @@ describe("useScreenState", () => {
|
|
|
88
89
|
const { result } = renderHook(() => useScreenState());
|
|
89
90
|
|
|
90
91
|
const screens: ScreenType[] = [
|
|
91
|
-
"worktree-manager",
|
|
92
92
|
"branch-creator",
|
|
93
93
|
"ai-tool-selector",
|
|
94
|
+
"model-selector",
|
|
94
95
|
"execution-mode-selector",
|
|
95
96
|
];
|
|
96
97
|
|
|
@@ -106,17 +107,17 @@ describe("useScreenState", () => {
|
|
|
106
107
|
act(() => {
|
|
107
108
|
result.current.goBack();
|
|
108
109
|
});
|
|
109
|
-
expect(result.current.currentScreen).toBe("
|
|
110
|
+
expect(result.current.currentScreen).toBe("model-selector");
|
|
110
111
|
|
|
111
112
|
act(() => {
|
|
112
113
|
result.current.goBack();
|
|
113
114
|
});
|
|
114
|
-
expect(result.current.currentScreen).toBe("
|
|
115
|
+
expect(result.current.currentScreen).toBe("ai-tool-selector");
|
|
115
116
|
|
|
116
117
|
act(() => {
|
|
117
118
|
result.current.goBack();
|
|
118
119
|
});
|
|
119
|
-
expect(result.current.currentScreen).toBe("
|
|
120
|
+
expect(result.current.currentScreen).toBe("branch-creator");
|
|
120
121
|
|
|
121
122
|
act(() => {
|
|
122
123
|
result.current.goBack();
|
|
@@ -128,14 +129,14 @@ describe("useScreenState", () => {
|
|
|
128
129
|
const { result } = renderHook(() => useScreenState());
|
|
129
130
|
|
|
130
131
|
act(() => {
|
|
131
|
-
result.current.navigateTo("
|
|
132
|
+
result.current.navigateTo("branch-creator");
|
|
132
133
|
});
|
|
133
134
|
|
|
134
135
|
act(() => {
|
|
135
|
-
result.current.navigateTo("
|
|
136
|
+
result.current.navigateTo("ai-tool-selector");
|
|
136
137
|
});
|
|
137
138
|
|
|
138
|
-
expect(result.current.currentScreen).toBe("
|
|
139
|
+
expect(result.current.currentScreen).toBe("ai-tool-selector");
|
|
139
140
|
|
|
140
141
|
act(() => {
|
|
141
142
|
result.current.reset();
|
|
@@ -13,8 +13,9 @@ describe("useTerminalSize", () => {
|
|
|
13
13
|
beforeEach(() => {
|
|
14
14
|
// Setup happy-dom
|
|
15
15
|
const window = new Window();
|
|
16
|
-
globalThis.window = window as
|
|
17
|
-
globalThis.document =
|
|
16
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
17
|
+
globalThis.document =
|
|
18
|
+
window.document as unknown as typeof globalThis.document;
|
|
18
19
|
|
|
19
20
|
// デフォルト値を設定
|
|
20
21
|
process.stdout.rows = 24;
|
|
@@ -2,15 +2,7 @@
|
|
|
2
2
|
* @vitest-environment happy-dom
|
|
3
3
|
* Edge case tests for UI components
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
describe,
|
|
7
|
-
it,
|
|
8
|
-
expect,
|
|
9
|
-
beforeEach,
|
|
10
|
-
afterEach,
|
|
11
|
-
afterAll,
|
|
12
|
-
vi,
|
|
13
|
-
} from "vitest";
|
|
5
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
14
6
|
import { render } from "@testing-library/react";
|
|
15
7
|
import React from "react";
|
|
16
8
|
import * as BranchListScreenModule from "../../components/screens/BranchListScreen.js";
|
|
@@ -24,7 +16,7 @@ const useGitDataMock = vi.fn();
|
|
|
24
16
|
let App: typeof import("../../components/App.js").App;
|
|
25
17
|
|
|
26
18
|
vi.mock("../../hooks/useGitData.js", () => ({
|
|
27
|
-
useGitData: (...args:
|
|
19
|
+
useGitData: (...args: unknown[]) => useGitDataMock(...args),
|
|
28
20
|
}));
|
|
29
21
|
|
|
30
22
|
vi.mock("../../components/screens/BranchListScreen.js", () => ({
|
|
@@ -53,8 +45,9 @@ describe("Edge Cases Integration Tests", () => {
|
|
|
53
45
|
beforeEach(async () => {
|
|
54
46
|
// Setup happy-dom
|
|
55
47
|
const window = new Window();
|
|
56
|
-
globalThis.window = window as
|
|
57
|
-
globalThis.document =
|
|
48
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
49
|
+
globalThis.document =
|
|
50
|
+
window.document as unknown as typeof globalThis.document;
|
|
58
51
|
|
|
59
52
|
// Reset mocks
|
|
60
53
|
vi.clearAllMocks();
|
|
@@ -18,7 +18,9 @@ import { App } from "../../components/App.js";
|
|
|
18
18
|
import { Window } from "happy-dom";
|
|
19
19
|
import type { BranchInfo, BranchItem } from "../../types.js";
|
|
20
20
|
import * as BranchListScreenModule from "../../components/screens/BranchListScreen.js";
|
|
21
|
+
import type { BranchListScreenProps } from "../../components/screens/BranchListScreen.js";
|
|
21
22
|
import * as BranchActionSelectorScreenModule from "../../screens/BranchActionSelectorScreen.js";
|
|
23
|
+
import type { BranchActionSelectorScreenProps } from "../../screens/BranchActionSelectorScreen.js";
|
|
22
24
|
|
|
23
25
|
vi.mock("../../../../git.ts", () => ({
|
|
24
26
|
__esModule: true,
|
|
@@ -26,6 +28,8 @@ vi.mock("../../../../git.ts", () => ({
|
|
|
26
28
|
getRepositoryRoot: vi.fn(async () => "/repo"),
|
|
27
29
|
deleteBranch: vi.fn(async () => undefined),
|
|
28
30
|
fetchAllRemotes: vi.fn(async () => undefined),
|
|
31
|
+
collectUpstreamMap: vi.fn(async () => new Map()),
|
|
32
|
+
getBranchDivergenceStatuses: vi.fn(async () => []),
|
|
29
33
|
}));
|
|
30
34
|
|
|
31
35
|
const { mockIsProtectedBranchName, mockSwitchToProtectedBranch } = vi.hoisted(
|
|
@@ -90,8 +94,9 @@ describe("Navigation Integration Tests", () => {
|
|
|
90
94
|
beforeEach(() => {
|
|
91
95
|
// Setup happy-dom
|
|
92
96
|
const window = new Window();
|
|
93
|
-
globalThis.window = window as
|
|
94
|
-
globalThis.document =
|
|
97
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
98
|
+
globalThis.document =
|
|
99
|
+
window.document as unknown as typeof globalThis.document;
|
|
95
100
|
|
|
96
101
|
// Reset mocks
|
|
97
102
|
mockedGetAllBranches.mockReset();
|
|
@@ -243,8 +248,8 @@ describe("Navigation Integration Tests", () => {
|
|
|
243
248
|
});
|
|
244
249
|
|
|
245
250
|
describe("Protected Branch Navigation (T103)", () => {
|
|
246
|
-
const branchListProps:
|
|
247
|
-
const branchActionProps:
|
|
251
|
+
const branchListProps: BranchListScreenProps[] = [];
|
|
252
|
+
const branchActionProps: BranchActionSelectorScreenProps[] = [];
|
|
248
253
|
let branchListSpy: ReturnType<typeof vi.spyOn>;
|
|
249
254
|
let branchActionSpy: ReturnType<typeof vi.spyOn>;
|
|
250
255
|
|
|
@@ -265,8 +270,9 @@ describe("Protected Branch Navigation (T103)", () => {
|
|
|
265
270
|
|
|
266
271
|
beforeEach(() => {
|
|
267
272
|
const window = new Window();
|
|
268
|
-
globalThis.window = window as
|
|
269
|
-
globalThis.document =
|
|
273
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
274
|
+
globalThis.document =
|
|
275
|
+
window.document as unknown as typeof globalThis.document;
|
|
270
276
|
mockedGetAllBranches.mockReset();
|
|
271
277
|
mockedListAdditionalWorktrees.mockReset();
|
|
272
278
|
mockedGetRepositoryRoot.mockReset();
|
|
@@ -284,13 +290,13 @@ describe("Protected Branch Navigation (T103)", () => {
|
|
|
284
290
|
aiToolScreenProps.length = 0;
|
|
285
291
|
branchListSpy = vi
|
|
286
292
|
.spyOn(BranchListScreenModule, "BranchListScreen")
|
|
287
|
-
.mockImplementation((props:
|
|
293
|
+
.mockImplementation((props: BranchListScreenProps) => {
|
|
288
294
|
branchListProps.push(props);
|
|
289
295
|
return React.createElement(originalBranchListScreen, props);
|
|
290
296
|
});
|
|
291
297
|
branchActionSpy = vi
|
|
292
298
|
.spyOn(BranchActionSelectorScreenModule, "BranchActionSelectorScreen")
|
|
293
|
-
.mockImplementation((props:
|
|
299
|
+
.mockImplementation((props: BranchActionSelectorScreenProps) => {
|
|
294
300
|
branchActionProps.push(props);
|
|
295
301
|
return React.createElement(originalBranchActionSelectorScreen, props);
|
|
296
302
|
});
|
|
@@ -337,8 +343,7 @@ describe("Protected Branch Navigation (T103)", () => {
|
|
|
337
343
|
|
|
338
344
|
// Simulate selecting the branch from the list
|
|
339
345
|
const listProps =
|
|
340
|
-
branchListProps.find((p) => p.branches?.length) ??
|
|
341
|
-
branchListProps.at(-1);
|
|
346
|
+
branchListProps.find((p) => p.branches?.length) ?? branchListProps.at(-1);
|
|
342
347
|
expect(listProps?.branches?.length).toBeGreaterThan(0);
|
|
343
348
|
listProps.onSelect(listProps.branches[0]);
|
|
344
349
|
|
|
@@ -26,8 +26,9 @@ describe("Real-time Update Integration", () => {
|
|
|
26
26
|
beforeEach(() => {
|
|
27
27
|
// Setup happy-dom
|
|
28
28
|
const window = new Window();
|
|
29
|
-
globalThis.window = window as
|
|
30
|
-
globalThis.document =
|
|
29
|
+
globalThis.window = window as unknown as typeof globalThis.window;
|
|
30
|
+
globalThis.document =
|
|
31
|
+
window.document as unknown as typeof globalThis.document;
|
|
31
32
|
|
|
32
33
|
// Reset mocks
|
|
33
34
|
vi.clearAllMocks();
|
|
@@ -84,7 +84,6 @@ describe("BranchListScreen Performance", () => {
|
|
|
84
84
|
branches={branches}
|
|
85
85
|
stats={stats}
|
|
86
86
|
onSelect={() => {}}
|
|
87
|
-
onNavigate={() => {}}
|
|
88
87
|
onQuit={() => {}}
|
|
89
88
|
/>,
|
|
90
89
|
);
|
|
@@ -123,7 +122,6 @@ describe("BranchListScreen Performance", () => {
|
|
|
123
122
|
branches={branches}
|
|
124
123
|
stats={stats}
|
|
125
124
|
onSelect={() => {}}
|
|
126
|
-
onNavigate={() => {}}
|
|
127
125
|
onQuit={() => {}}
|
|
128
126
|
lastUpdated={new Date()}
|
|
129
127
|
/>,
|
|
@@ -137,7 +135,6 @@ describe("BranchListScreen Performance", () => {
|
|
|
137
135
|
branches={branches}
|
|
138
136
|
stats={{ ...stats, total: stats.total + 1 }}
|
|
139
137
|
onSelect={() => {}}
|
|
140
|
-
onNavigate={() => {}}
|
|
141
138
|
onQuit={() => {}}
|
|
142
139
|
lastUpdated={new Date()}
|
|
143
140
|
/>,
|
|
@@ -174,7 +171,6 @@ describe("BranchListScreen Performance", () => {
|
|
|
174
171
|
branches={branches}
|
|
175
172
|
stats={stats}
|
|
176
173
|
onSelect={() => {}}
|
|
177
|
-
onNavigate={() => {}}
|
|
178
174
|
onQuit={() => {}}
|
|
179
175
|
/>,
|
|
180
176
|
);
|