Skip to content

Commit e31cb79

Browse files
test: added row test
1 parent 246073d commit e31cb79

File tree

2 files changed

+309
-0
lines changed

2 files changed

+309
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package row_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestRow(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Row Suite")
13+
}
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
package row_test
2+
3+
import (
4+
"strings"
5+
6+
c "github.com/achannarasappa/ticker/v4/internal/common"
7+
"github.com/achannarasappa/ticker/v4/internal/ui/component/watchlist/row"
8+
9+
. "github.com/onsi/ginkgo/v2"
10+
. "github.com/onsi/gomega"
11+
12+
"regexp"
13+
)
14+
15+
var styles = c.Styles{
16+
Text: func(v string) string { return v },
17+
TextLight: func(v string) string { return v },
18+
TextLabel: func(v string) string { return v },
19+
TextBold: func(v string) string { return v },
20+
TextLine: func(v string) string { return v },
21+
TextPrice: func(percent float64, text string) string { return text },
22+
Tag: func(v string) string { return v },
23+
}
24+
25+
var _ = Describe("Row", func() {
26+
27+
Describe("Update", func() {
28+
29+
Describe("UpdateAssetMsg", func() {
30+
31+
When("the price has not changed or the symbol has changed", func() {
32+
33+
It("should update the asset", func() {
34+
35+
inputRow := row.New(row.Config{
36+
Styles: styles,
37+
Asset: &c.Asset{
38+
Symbol: "AAPL",
39+
QuotePrice: c.QuotePrice{
40+
Price: 150.00,
41+
},
42+
},
43+
})
44+
45+
outputRow, _ := inputRow.Update(row.UpdateAssetMsg(&c.Asset{
46+
Symbol: "AAPL",
47+
QuotePrice: c.QuotePrice{
48+
Price: 150.00,
49+
},
50+
}))
51+
52+
Expect(outputRow.View()).To(Equal(inputRow.View()))
53+
})
54+
55+
When("the price has changed and symbol is the same", func() {
56+
57+
When("the price has increased", func() {
58+
59+
It("should animate the price increase", func() {
60+
stripANSI := func(str string) string {
61+
re := regexp.MustCompile(`\x1b\[[0-9;]*m`)
62+
return re.ReplaceAllString(str, "")
63+
}
64+
65+
inputRow := row.New(row.Config{
66+
ID: 1,
67+
Styles: styles,
68+
Asset: &c.Asset{
69+
Symbol: "AAPL",
70+
QuotePrice: c.QuotePrice{
71+
Price: 150.00,
72+
},
73+
},
74+
})
75+
76+
// First update to trigger animation
77+
outputRow, cmd := inputRow.Update(row.UpdateAssetMsg(&c.Asset{
78+
Symbol: "AAPL",
79+
QuotePrice: c.QuotePrice{
80+
Price: 151.00,
81+
},
82+
}))
83+
84+
view := stripANSI(outputRow.View())
85+
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
86+
Expect(view).To(ContainSubstring("151.00"), "output was: %q", view)
87+
Expect(cmd).ToNot(BeNil())
88+
89+
// Simulate frame updates
90+
for i := 0; i < 4; i++ {
91+
outputRow, cmd = outputRow.Update(row.FrameMsg(1))
92+
Expect(cmd).ToNot(BeNil())
93+
}
94+
95+
// Final frame should have no animation
96+
outputRow, cmd = outputRow.Update(row.FrameMsg(1))
97+
98+
view = stripANSI(outputRow.View())
99+
Expect(cmd).To(BeNil(), "expected cmd to be nil after final frame, got: %v", cmd)
100+
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
101+
Expect(view).To(ContainSubstring("151.00"), "output was: %q", view)
102+
})
103+
104+
})
105+
106+
When("the price has decreased", func() {
107+
108+
It("should animate the price decrease", func() {
109+
stripANSI := func(str string) string {
110+
re := regexp.MustCompile(`\x1b\[[0-9;]*m`)
111+
return re.ReplaceAllString(str, "")
112+
}
113+
114+
inputRow := row.New(row.Config{
115+
ID: 1,
116+
Styles: styles,
117+
Asset: &c.Asset{
118+
Symbol: "AAPL",
119+
QuotePrice: c.QuotePrice{
120+
Price: 151.00,
121+
},
122+
},
123+
})
124+
125+
// First update to trigger animation
126+
outputRow, cmd := inputRow.Update(row.UpdateAssetMsg(&c.Asset{
127+
Symbol: "AAPL",
128+
QuotePrice: c.QuotePrice{
129+
Price: 150.00,
130+
},
131+
}))
132+
133+
view := stripANSI(outputRow.View())
134+
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
135+
Expect(view).To(ContainSubstring("150.00"), "output was: %q", view)
136+
Expect(cmd).ToNot(BeNil())
137+
138+
// Simulate frame updates
139+
for i := 0; i < 4; i++ {
140+
outputRow, cmd = outputRow.Update(row.FrameMsg(1))
141+
Expect(cmd).ToNot(BeNil())
142+
}
143+
144+
// Final frame should have no animation
145+
outputRow, cmd = outputRow.Update(row.FrameMsg(1))
146+
147+
view = stripANSI(outputRow.View())
148+
Expect(cmd).To(BeNil(), "expected cmd to be nil after final frame, got: %v", cmd)
149+
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
150+
Expect(view).To(ContainSubstring("150.00"), "output was: %q", view)
151+
})
152+
153+
})
154+
155+
When("the number of digits in the new and old price is different", func() {
156+
157+
It("should animate the entire price", func() {
158+
stripANSI := func(str string) string {
159+
re := regexp.MustCompile(`\x1b\[[0-9;]*m`)
160+
return re.ReplaceAllString(str, "")
161+
}
162+
163+
inputRow := row.New(row.Config{
164+
ID: 1,
165+
Styles: styles,
166+
Asset: &c.Asset{
167+
Symbol: "AAPL",
168+
QuotePrice: c.QuotePrice{
169+
Price: 150.00,
170+
},
171+
},
172+
})
173+
174+
// First update to trigger animation with different number of digits
175+
outputRow, cmd := inputRow.Update(row.UpdateAssetMsg(&c.Asset{
176+
Symbol: "AAPL",
177+
QuotePrice: c.QuotePrice{
178+
Price: 1500.00,
179+
},
180+
}))
181+
182+
view := stripANSI(outputRow.View())
183+
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
184+
Expect(view).To(ContainSubstring("1500.00"), "output was: %q", view)
185+
Expect(cmd).ToNot(BeNil())
186+
187+
// Simulate frame updates
188+
for i := 0; i < 4; i++ {
189+
outputRow, cmd = outputRow.Update(row.FrameMsg(1))
190+
Expect(cmd).ToNot(BeNil())
191+
}
192+
193+
// Final frame should have no animation
194+
outputRow, cmd = outputRow.Update(row.FrameMsg(1))
195+
196+
view = stripANSI(outputRow.View())
197+
Expect(cmd).To(BeNil(), "expected cmd to be nil after final frame, got: %v", cmd)
198+
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
199+
Expect(view).To(ContainSubstring("1500.00"), "output was: %q", view)
200+
})
201+
202+
})
203+
204+
})
205+
206+
})
207+
208+
})
209+
210+
Describe("FrameMsg", func() {
211+
212+
When("the message is for a different row", func() {
213+
214+
It("should not animate the price", func() {
215+
stripANSI := func(str string) string {
216+
re := regexp.MustCompile(`\x1b\[[0-9;]*m`)
217+
return re.ReplaceAllString(str, "")
218+
}
219+
220+
inputRow := row.New(row.Config{
221+
ID: 1,
222+
Styles: styles,
223+
Asset: &c.Asset{
224+
Symbol: "AAPL",
225+
QuotePrice: c.QuotePrice{
226+
Price: 150.00,
227+
},
228+
},
229+
})
230+
231+
// First update to trigger animation
232+
outputRow, cmd := inputRow.Update(row.UpdateAssetMsg(&c.Asset{
233+
Symbol: "AAPL",
234+
QuotePrice: c.QuotePrice{
235+
Price: 151.00,
236+
},
237+
}))
238+
239+
// Send frame message for a different row ID
240+
outputRow, cmd = outputRow.Update(row.FrameMsg(2))
241+
242+
view := stripANSI(outputRow.View())
243+
Expect(cmd).To(BeNil(), "expected cmd to be nil for different row ID")
244+
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
245+
Expect(view).To(ContainSubstring("151.00"), "output was: %q", view)
246+
})
247+
248+
})
249+
250+
})
251+
252+
Describe("SetCellWidthsMsg", func() {
253+
254+
It("should update the width and cell widths", func() {
255+
asset := &c.Asset{
256+
Symbol: "AAPL",
257+
QuotePrice: c.QuotePrice{
258+
Price: 150.00,
259+
},
260+
}
261+
262+
inputRow := row.New(row.Config{
263+
Styles: styles,
264+
Asset: asset,
265+
})
266+
267+
expectedCellWidths := row.CellWidthsContainer{
268+
PositionLength: 10,
269+
QuoteLength: 8,
270+
WidthQuote: 12,
271+
WidthQuoteExtended: 15,
272+
WidthQuoteRange: 20,
273+
WidthPosition: 12,
274+
WidthPositionExtended: 15,
275+
WidthVolumeMarketCap: 15,
276+
}
277+
expectedWidth := 100
278+
279+
outputRow, cmd := inputRow.Update(row.SetCellWidthsMsg{
280+
Width: expectedWidth,
281+
CellWidths: expectedCellWidths,
282+
})
283+
284+
Expect(cmd).To(BeNil())
285+
286+
// Verify the width is applied by checking the rendered output
287+
view := outputRow.View()
288+
lines := strings.Split(view, "\n")
289+
Expect(lines[0]).To(HaveLen(expectedWidth))
290+
})
291+
292+
})
293+
294+
})
295+
296+
})

0 commit comments

Comments
 (0)