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
|
package gomponents_test
import (
"errors"
"fmt"
"strings"
"testing"
g "github.com/maragudk/gomponents"
"github.com/maragudk/gomponents/assert"
)
func TestNodeFunc(t *testing.T) {
t.Run("implements fmt.Stringer", func(t *testing.T) {
fn := g.NodeFunc(func() string { return "hat" })
if fn.String() != "hat" {
t.FailNow()
}
})
}
func TestAttr(t *testing.T) {
t.Run("renders just the local name with one argument", func(t *testing.T) {
a := g.Attr("required")
assert.Equal(t, " required", a)
})
t.Run("renders the name and value when given two arguments", func(t *testing.T) {
a := g.Attr("id", "hat")
assert.Equal(t, ` id="hat"`, a)
})
t.Run("panics with more than two arguments", func(t *testing.T) {
called := false
defer func() {
if err := recover(); err != nil {
called = true
}
}()
g.Attr("name", "value", "what is this?")
if !called {
t.FailNow()
}
})
t.Run("implements fmt.Stringer", func(t *testing.T) {
a := g.Attr("required")
s := fmt.Sprintf("%v", a)
if s != " required" {
t.FailNow()
}
})
}
type outsider struct{}
func (o outsider) Render() string {
return "outsider"
}
func TestEl(t *testing.T) {
t.Run("renders an empty element if no children given", func(t *testing.T) {
e := g.El("div")
assert.Equal(t, "<div />", e)
})
t.Run("renders an empty element if only attributes given as children", func(t *testing.T) {
e := g.El("div", g.Attr("class", "hat"))
assert.Equal(t, `<div class="hat" />`, e)
})
t.Run("renders an element, attributes, and element children", func(t *testing.T) {
e := g.El("div", g.Attr("class", "hat"), g.El("span"))
assert.Equal(t, `<div class="hat"><span /></div>`, e)
})
t.Run("renders attributes at the correct place regardless of placement in parameter list", func(t *testing.T) {
e := g.El("div", g.El("span"), g.Attr("class", "hat"))
assert.Equal(t, `<div class="hat"><span /></div>`, e)
})
t.Run("renders outside if node does not implement placer", func(t *testing.T) {
e := g.El("div", outsider{})
assert.Equal(t, `<div>outsider</div>`, e)
})
}
func TestText(t *testing.T) {
t.Run("renders escaped text", func(t *testing.T) {
e := g.Text("<div />")
assert.Equal(t, "<div />", e)
})
}
func TestTextf(t *testing.T) {
t.Run("renders interpolated and escaped text", func(t *testing.T) {
e := g.Textf("<%v />", "div")
assert.Equal(t, "<div />", e)
})
}
func TestRaw(t *testing.T) {
t.Run("renders raw text", func(t *testing.T) {
e := g.Raw("<div />")
assert.Equal(t, "<div />", e)
})
}
type erroringWriter struct{}
func (w *erroringWriter) Write(p []byte) (n int, err error) {
return 0, errors.New("don't want to write")
}
func TestWrite(t *testing.T) {
t.Run("writes to the writer", func(t *testing.T) {
e := g.El("div")
var b strings.Builder
err := g.Write(&b, e)
if err != nil {
t.FailNow()
}
if b.String() != e.Render() {
t.FailNow()
}
})
t.Run("errors on write error", func(t *testing.T) {
e := g.El("div")
err := g.Write(&erroringWriter{}, e)
if err == nil {
t.FailNow()
}
})
}
|