detached 6af0a61

progress_view_test.go RawHistoryFolder

1package views
2
3import (
4	"strings"
5	"testing"
6
7	"github.com/bnema/archup/internal/application/dto"
8	"github.com/bnema/archup/internal/interfaces/tui/models"
9)
10
11func TestRenderProgress(t *testing.T) {
12	pm := models.NewProgressModel()
13
14	// Update with some progress
15	update := &dto.ProgressUpdate{
16		Phase:           "Partitioning",
17		PhaseNumber:     2,
18		TotalPhases:     7,
19		ProgressPercent: 25,
20		Message:         "Partitioning disk...",
21		IsError:         false,
22	}
23	pm.UpdateProgress(update)
24
25	// Render the progress
26	output := RenderProgress(pm)
27
28	// Verify key content is present
29	checks := []string{
30		"Installation Progress", // Title
31		"Phase 2/7",             // Phase info
32		"Partitioning",          // Phase name
33		"Partitioning disk...",  // Message
34		"[",                     // Progress bar start
35		"]",                     // Progress bar end
36		"25%",                   // Progress percentage
37	}
38
39	for _, check := range checks {
40		if !strings.Contains(output, check) {
41			t.Errorf("Expected progress output to contain '%s', but it didn't", check)
42		}
43	}
44
45	// Verify output is not empty
46	if len(output) == 0 {
47		t.Error("Progress output should not be empty")
48	}
49
50	t.Logf("Progress rendered successfully with %d characters", len(output))
51}
52
53func TestRenderProgressError(t *testing.T) {
54	pm := models.NewProgressModel()
55
56	// Update with error message
57	update := &dto.ProgressUpdate{
58		Phase:           "Base Installation",
59		PhaseNumber:     3,
60		TotalPhases:     7,
61		ProgressPercent: 40,
62		Message:         "Failed to install base packages",
63		IsError:         true,
64	}
65	pm.UpdateProgress(update)
66
67	// Render the progress
68	output := RenderProgress(pm)
69
70	// Verify error message is present
71	if !strings.Contains(output, "Failed to install base packages") {
72		t.Error("Expected error message in output")
73	}
74
75	if !strings.Contains(output, "Base Installation") {
76		t.Error("Expected phase name in output")
77	}
78}
79
80func TestProgressMessageHistory(t *testing.T) {
81	pm := models.NewProgressModel()
82
83	// Add several messages
84	messages := []string{
85		"Starting installation...",
86		"Checking system...",
87		"Partitioning disk...",
88		"Installing base system...",
89	}
90
91	for i, msg := range messages {
92		update := &dto.ProgressUpdate{
93			Phase:           "Test Phase",
94			PhaseNumber:     1,
95			TotalPhases:     7,
96			ProgressPercent: (i + 1) * 20,
97			Message:         msg,
98			IsError:         false,
99		}
100		pm.UpdateProgress(update)
101	}
102
103	// Render the progress
104	output := RenderProgress(pm)
105
106	// Verify history section exists
107	if !strings.Contains(output, "Recent activities") {
108		t.Error("Expected recent activities section in output")
109	}
110
111	// Verify recent messages are shown
112	if !strings.Contains(output, "Partitioning disk...") {
113		t.Error("Expected recent message in output")
114	}
115}
116
117func TestProgressBar(t *testing.T) {
118	pm := models.NewProgressModel()
119
120	testCases := []struct {
121		percent int
122		name    string
123	}{
124		{0, "empty"},
125		{25, "quarter"},
126		{50, "half"},
127		{75, "three-quarters"},
128		{100, "full"},
129	}
130
131	for _, tc := range testCases {
132		update := &dto.ProgressUpdate{
133			Phase:           "Test",
134			PhaseNumber:     1,
135			TotalPhases:     7,
136			ProgressPercent: tc.percent,
137			Message:         "Testing",
138			IsError:         false,
139		}
140		pm.UpdateProgress(update)
141
142		output := RenderProgress(pm)
143
144		if !strings.Contains(output, "[") || !strings.Contains(output, "]") {
145			t.Errorf("Progress bar for %s should contain [ and ]", tc.name)
146		}
147
148		if !strings.Contains(output, "100%") && tc.percent == 100 {
149			t.Errorf("Progress bar for %s should show 100%%", tc.name)
150		}
151	}
152}
153
154func TestProgressModelGetters(t *testing.T) {
155	pm := models.NewProgressModel()
156
157	// Initial state
158	if phase, total := pm.GetPhaseProgress(); phase != 0 || total != 0 {
159		t.Error("Initial phase progress should be 0/0")
160	}
161
162	if pm.GetProgressPercent() != 0 {
163		t.Error("Initial progress percent should be 0")
164	}
165
166	if pm.GetCurrentPhase() != "" {
167		t.Error("Initial current phase should be empty")
168	}
169
170	// Update
171	update := &dto.ProgressUpdate{
172		Phase:           "Partitioning",
173		PhaseNumber:     2,
174		TotalPhases:     7,
175		ProgressPercent: 30,
176		Message:         "Working...",
177		IsError:         false,
178	}
179	pm.UpdateProgress(update)
180
181	// Verify getters work
182	if phase, total := pm.GetPhaseProgress(); phase != 2 || total != 7 {
183		t.Errorf("Expected 2/7 phases, got %d/%d", phase, total)
184	}
185
186	if pm.GetProgressPercent() != 30 {
187		t.Errorf("Expected 30%%, got %d%%", pm.GetProgressPercent())
188	}
189
190	if pm.GetCurrentPhase() != "Partitioning" {
191		t.Error("Expected current phase to be 'Partitioning'")
192	}
193
194	if pm.GetMessage() != "Working..." {
195		t.Error("Expected message to be 'Working...'")
196	}
197
198	if pm.IsError() {
199		t.Error("Expected IsError to be false")
200	}
201}
202
203func BenchmarkRenderProgress(b *testing.B) {
204	pm := models.NewProgressModel()
205
206	update := &dto.ProgressUpdate{
207		Phase:           "Test",
208		PhaseNumber:     1,
209		TotalPhases:     7,
210		ProgressPercent: 50,
211		Message:         "Testing",
212		IsError:         false,
213	}
214	pm.UpdateProgress(update)
215
216	b.ResetTimer()
217	for i := 0; i < b.N; i++ {
218		_ = RenderProgress(pm)
219	}
220}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 0

    ↑↓ moveenter openesc close