-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathview_test.go
More file actions
245 lines (205 loc) · 7.62 KB
/
view_test.go
File metadata and controls
245 lines (205 loc) · 7.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
package main
import (
"strings"
"testing"
"time"
"charm.land/bubbles/v2/progress"
"charm.land/bubbles/v2/table"
"charm.land/lipgloss/v2"
"github.com/stretchr/testify/assert"
"tiny-timer/status"
)
func TestViewWithTitle(t *testing.T) {
// Create a model with a title
statusCmp := status.NewStatusCmp()
statusCmp.SetKeyMap(newTestModel().keys)
m := model{
progress: progress.New(progress.WithColors(lipgloss.Color(colorMontezumaGold), lipgloss.Color(colorCream)), progress.WithoutPercentage()),
startTime: time.Now().Unix(),
targetDuration: 60,
title: "Test Task",
status: statusCmp,
help: newHelpModel(),
keys: newTestModel().keys,
}
view := m.View().Content
// Verify that the title is displayed in the view
assert.Contains(t, view, "Test Task", "Expected view to contain the title")
}
func TestViewWithoutTitle(t *testing.T) {
// Create a model without a title
statsuCmp := status.NewStatusCmp()
statsuCmp.SetKeyMap(newTestModel().keys)
m := model{
progress: progress.New(progress.WithColors(lipgloss.Color(colorMontezumaGold), lipgloss.Color(colorCream)), progress.WithoutPercentage()),
startTime: time.Now().Unix(),
targetDuration: 60,
title: "",
status: statsuCmp,
help: newHelpModel(),
keys: newTestModel().keys,
}
view := m.View().Content
// Count the number of lines - should have one fewer line when no title is present
lines := strings.Split(view, "\n")
// Verify that empty title doesn't add extra newlines
// The view should not have a title line
for _, line := range lines {
// Make sure no line is JUST padding (which would indicate an empty title line)
trimmed := strings.TrimSpace(line)
if trimmed == "" {
// Empty lines are okay, just not lines with only padding
continue
}
}
}
func TestTableViewMode(t *testing.T) {
m := newTestModel()
m.title = "Test Task"
m.mode = timerView
// Verify initial mode is timer view
assert.Equal(t, timerView, m.mode)
// Verify timer view is displayed with help text
view := m.View().Content
assert.Contains(t, view, "title")
assert.Contains(t, view, "history")
}
func TestTableHeadersAreLeftAligned(t *testing.T) {
// Set up a temporary database path
_, cleanup := setupTestDB(t)
defer cleanup()
// Create a test session
err := saveSessionToDB(1500, true, "Test Task")
assert.NoError(t, err)
// Create a model and trigger table view
statsuCmp := status.NewStatusCmp()
statsuCmp.SetKeyMap(newTestModel().keys)
m := model{
progress: progress.New(progress.WithColors(lipgloss.Color(colorMontezumaGold), lipgloss.Color(colorCream)), progress.WithoutPercentage()),
startTime: time.Now().Unix(),
targetDuration: 60,
title: "Test Task",
mode: timerView,
status: statsuCmp,
help: newHelpModel(),
keys: newTestModel().keys,
}
// Simulate pressing 't' to show table
sessions, err := getRecentSessions(10)
assert.NoError(t, err)
// Build table (same logic as in updateKey)
columns := []table.Column{
{Title: "Title", Width: 40},
{Title: "Duration", Width: 10},
{Title: "Date", Width: 20},
}
rows := []table.Row{}
for _, s := range sessions {
title := s.title
if title == "" {
title = "(no title)"
}
duration := formatDurationAsMMSS(s.duration)
datetime := s.datetime
// SQLite DATETIME can store dates in different formats, try both
var parsedTime time.Time
var err error
if parsedTime, err = time.Parse("2006-01-02 15:04:05", s.datetime); err != nil {
parsedTime, err = time.Parse("2006-01-02T15:04:05Z", s.datetime)
}
if err == nil {
datetime = parsedTime.Format("Monday, 2 Jan 06")
}
rows = append(rows, table.Row{title, duration, datetime})
}
tbl := table.New(
table.WithColumns(columns),
table.WithRows(rows),
table.WithFocused(false),
table.WithHeight(len(rows)+2), // Add extra height for visibility
table.WithWidth(40+10+20), // Sum of column widths
)
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color(colorGrey)).
BorderBottom(true).
Bold(false).
Padding(0, 0)
s.Cell = s.Cell.
Padding(0, 0)
s.Selected = s.Cell // No cursor highlighting for unfocused table
tbl.SetStyles(s)
m.table = tbl
m.mode = tableView
// Get the rendered view
view := m.View().Content
// Check that headers appear in the output
assert.Contains(t, view, "Title", "Table should contain 'Title' header")
assert.Contains(t, view, "Duration", "Table should contain 'Duration' header")
assert.Contains(t, view, "Date", "Table should contain 'Date' header")
// Find header line and first data line to compare alignment
lines := strings.Split(view, "\n")
var headerLineRaw string
var firstDataLineRaw string
foundHeader := false
for _, line := range lines {
// Find the header line (contains all three headers)
if !foundHeader && strings.Contains(line, "Title") && strings.Contains(line, "Duration") && strings.Contains(line, "Date") {
headerLineRaw = line
foundHeader = true
continue
}
// Find the first data line (after border line, non-empty, not help text)
if foundHeader && len(strings.TrimSpace(line)) > 0 && !strings.Contains(line, "─") && !strings.Contains(line, "Press any key") {
firstDataLineRaw = line
break
}
}
assert.NotEmpty(t, headerLineRaw, "Should have found the header line")
assert.NotEmpty(t, firstDataLineRaw, "Should have found a data line")
// Compare using the RAW lines (with padding included)
// Headers and data should start at the same column position
headerTitleStartRaw := strings.Index(headerLineRaw, "Title")
dataTitleStartRaw := strings.Index(firstDataLineRaw, "Test Task")
assert.Equal(t, headerTitleStartRaw, dataTitleStartRaw,
"Header and data should start at the same column in the rendered output. Header starts at %d, Data starts at %d",
headerTitleStartRaw, dataTitleStartRaw)
}
func TestCountUpViewDisplay(t *testing.T) {
m := newTestModel()
m.startTime = time.Now().Unix() - 600
m.targetDuration = 3600
m.countUpMode = true
m.mode = timerView
m.title = "My Task"
view := m.View().Content
assert.Contains(t, view, "My Task", "Expected title to be displayed")
assert.Contains(t, view, "done", "Expected count-up mode help text")
assert.Contains(t, view, "title", "Expected title change help text")
}
func TestHelpTextUsesTwoToneGrey(t *testing.T) {
// Test that help text renders keys in light grey (#a0a0a0) and descriptions in dark grey (#626262)
m := newTestModel()
m.help.SetWidth(80)
// Render test strings with the key and description styles
keyStyle := m.help.Styles.ShortKey
descStyle := m.help.Styles.ShortDesc
testKey := "d"
testDesc := "done"
keyRendered := keyStyle.Render(testKey)
descRendered := descStyle.Render(testDesc)
// Verify that the styles render differently
// The key should use light grey (#a0a0a0) and description should use dark grey (#626262)
// We check by rendering and looking for color codes, or by verifying the styles are different
// If colors are rendered, they should be different
assert.NotEqual(t, keyRendered, descRendered,
"Key and description should have different color codes")
// Verify the help view contains the expected content
helpView := m.help.View(m.keys)
assert.Contains(t, helpView, testKey, "Help should contain key")
assert.Contains(t, helpView, testDesc, "Help should contain description")
// The key point: verify that styles are configured with the correct colors
// We'll verify this by checking that customizing the styles produces the expected result
// This test documents the expected behavior: keys in light grey, descriptions in dark grey
}