-
Notifications
You must be signed in to change notification settings - Fork 1
/
elm_test.go
113 lines (87 loc) · 2.18 KB
/
elm_test.go
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
package elmgo_test
import (
"context"
"fmt"
"testing"
"time"
"github.com/matryer/is"
"github.com/williammartin/elmgo"
)
type TextRendererSpy struct {
renderLastCalledWith string
}
func (s *TextRendererSpy) Render(text string) {
s.renderLastCalledWith = text
}
func (s *TextRendererSpy) LastCalledWith() string {
return s.renderLastCalledWith
}
// Model
type CounterModel struct {
Count int
}
// Messages
type CounterMsg interface {
isCounterMsg()
}
//go-sumtype:decl Msg
type Increment struct{}
func (*Increment) isCounterMsg() {}
type Decrement struct{}
func (*Decrement) isCounterMsg() {}
// CounterApp
type CounterApp struct {
dispatchHandle elmgo.Dispatcher[CounterMsg]
}
func (a *CounterApp) Init() CounterModel {
return CounterModel{
Count: 0,
}
}
func (a *CounterApp) Update(msg CounterMsg, model CounterModel) (CounterModel, elmgo.Cmd) {
switch CounterMsg(msg).(type) {
case *Increment:
return CounterModel{Count: model.Count + 1}, nil
case *Decrement:
return CounterModel{Count: model.Count - 1}, nil
default:
panic(fmt.Sprintf("unexpected msg type: %v", msg))
}
}
func (a *CounterApp) View(model CounterModel, dispatcher elmgo.Dispatcher[CounterMsg]) string {
a.dispatchHandle = dispatcher
return fmt.Sprintf("Count is: %d", model.Count)
}
func TestAllTheThings(t *testing.T) {
t.Parallel()
is := is.New(t)
counterApp := &CounterApp{}
renderer := &TextRendererSpy{}
elmer := elmgo.NewApp[CounterModel, CounterMsg, string](counterApp, renderer)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
elmer.Run(ctx)
is.Equal(renderer.LastCalledWith(), "Count is: 0")
counterApp.dispatchHandle.Dispatch(&Increment{})
eventually(renderer.LastCalledWith).returns("Count is: 1")
counterApp.dispatchHandle.Dispatch(&Decrement{})
eventually(renderer.LastCalledWith).returns("Count is: 0")
}
// TODO: Turn this into an expressive matcher for elmgo e.g.
// eventuallyRenders()
type AsyncAssertion struct {
fn func() string
}
func eventually(fn func() string) *AsyncAssertion {
return &AsyncAssertion{
fn: fn,
}
}
func (m *AsyncAssertion) returns(text string) {
for {
<-time.After(time.Millisecond * 10)
if m.fn() == text {
return
}
}
}