~repos /gromer
git clone https://pyrossh.dev/repos/gromer.git
gromer is a framework and cli to build multipage web apps in golang using htmx and alpinejs.
expose NewElement
- attributes.go +2 -1
- element.go +4 -0
- html.go +17 -23
- raw_test.go +158 -114
- testing.go +141 -135
- testing_test.go +10 -10
attributes.go
CHANGED
|
@@ -123,7 +123,7 @@ type HelmetDescription string
|
|
|
123
123
|
type HelmetAuthor string
|
|
124
124
|
type HelmetKeywords string
|
|
125
125
|
|
|
126
|
-
func
|
|
126
|
+
func MergeAttributes(parent *Element, uis ...interface{}) *Element {
|
|
127
127
|
elems := []UI{}
|
|
128
128
|
for _, v := range uis {
|
|
129
129
|
switch c := v.(type) {
|
|
@@ -160,4 +160,5 @@ func mergeAttributes(parent *Element, uis ...interface{}) {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
parent.setBody(elems)
|
|
163
|
+
return parent
|
|
163
164
|
}
|
element.go
CHANGED
|
@@ -18,6 +18,10 @@ type Element struct {
|
|
|
18
18
|
this UI
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
func NewElement(tag string, selfClosing bool, uis ...interface{}) *Element {
|
|
22
|
+
return MergeAttributes(&Element{tag: tag, selfClosing: selfClosing}, uis...)
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
func (e *Element) JSValue() js.Value {
|
|
22
26
|
return e.jsvalue
|
|
23
27
|
}
|
html.go
CHANGED
|
@@ -51,45 +51,39 @@ func Script(str string) *Element {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
func Div(uis ...interface{}) *Element {
|
|
54
|
-
|
|
54
|
+
return NewElement("div", false, uis)
|
|
55
|
-
mergeAttributes(e, uis...)
|
|
56
|
-
return e
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
func A(uis ...interface{}) *Element {
|
|
60
|
-
|
|
58
|
+
return NewElement("a", false, uis)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func P(uis ...interface{}) *Element {
|
|
61
|
-
|
|
62
|
+
return NewElement("p", false, uis)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func Span(uis ...interface{}) *Element {
|
|
62
|
-
return
|
|
66
|
+
return NewElement("span", false, uis)
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
func Input(uis ...interface{}) *Element {
|
|
66
|
-
|
|
70
|
+
return NewElement("input", false, uis)
|
|
67
|
-
mergeAttributes(e, uis...)
|
|
68
|
-
return e
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
func Image(uis ...interface{}) *Element {
|
|
72
|
-
|
|
74
|
+
return NewElement("image", false, uis)
|
|
73
|
-
mergeAttributes(e, uis...)
|
|
74
|
-
return e
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
func Button(uis ...interface{}) *Element {
|
|
78
|
-
|
|
78
|
+
return NewElement("button", false, uis)
|
|
79
|
-
mergeAttributes(e, uis...)
|
|
80
|
-
return e
|
|
81
79
|
}
|
|
82
80
|
|
|
83
|
-
func Svg(
|
|
81
|
+
func Svg(uis ...interface{}) *Element {
|
|
84
|
-
|
|
82
|
+
return NewElement("svg", false, uis)
|
|
85
|
-
mergeAttributes(e, elems...)
|
|
86
|
-
return e
|
|
87
83
|
}
|
|
88
84
|
|
|
89
|
-
func SvgText(
|
|
85
|
+
func SvgText(uis ...interface{}) *Element {
|
|
90
|
-
|
|
86
|
+
return NewElement("text", false, uis)
|
|
91
|
-
mergeAttributes(e, elems...)
|
|
92
|
-
return e
|
|
93
87
|
}
|
|
94
88
|
|
|
95
89
|
func Row(uis ...interface{}) UI {
|
raw_test.go
CHANGED
|
@@ -1,116 +1,160 @@
|
|
|
1
1
|
package app
|
|
2
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
|
-
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
"github.com/stretchr/testify/require"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
var rawhtml = `
|
|
10
|
+
<div>
|
|
11
|
+
<p>slug: “/blog/gopibot-to-the-rescue”
|
|
12
|
+
date: “2017-10-04”</p>
|
|
13
|
+
|
|
14
|
+
<h2>title: “Gopibot To The Rescue”</h2>
|
|
15
|
+
|
|
16
|
+
<p>High Ho Gopibot away!</p>
|
|
17
|
+
|
|
18
|
+
<p>Everybody please meet Gopibot our chatops bot which I built at Numberz to help us deploy our countless microservices to QA.</p>
|
|
19
|
+
|
|
20
|
+
<p><img src="../images/posts/gopibot1.png" alt="Gopibot 1" /></p>
|
|
21
|
+
|
|
22
|
+
<p>So here is the backstory,</p>
|
|
23
|
+
|
|
24
|
+
<p>I was one of the developers who had access to our QA and Prod servers and the other person was the Head of Engineering
|
|
25
|
+
and he is generally a busy guy. So whenever there is a change that needs to be deployed everyone comes to me and tells me
|
|
26
|
+
to deploy their microservice/frontend to the QA and blatantly interrupts my awesome coding cycle.</p>
|
|
27
|
+
|
|
28
|
+
<p>Alright then, I break off from my flow, ssh into the server and start running the deploy command.
|
|
29
|
+
And all of you jsdev wannabes who have worked with react and webpack will know the horrors about deploying frontend code right.
|
|
30
|
+
It takes forever so I have to wait there looking at the console along with the dev who wanted me to deploy it (lets call him kokill for now).
|
|
31
|
+
So kokill and I patiently wait for the webpack build to finish. 1m , 2m, 3m and WTH 15m.
|
|
32
|
+
And then its built and the new frontend is deployed to QA. YES! Now I can continue with my work.
|
|
33
|
+
But wait then some other dev comes likes call him (D-Ne0) and he asks to deploy something else and again the same process
|
|
34
|
+
of ssh’ing the server and another wait. This got repetitive and irritating. Then I started searching for solutions to the problem
|
|
35
|
+
and looked high and low and thought that CI/CD is the only thing that can solve this problem. But then I saw something new called ChatOps
|
|
36
|
+
where developers have chatbots to talk to automate this manual work. Just like we have bots these days to help you out in your work
|
|
37
|
+
like getting your laundry, grocery and making orders.</p>
|
|
38
|
+
|
|
39
|
+
<p>So I decided to take a shot at this in my free time. And it seems it was simpler than I thought and decided to use Slack our primary
|
|
40
|
+
team communication platform. We used it daily for everything and I thought why not have a specific channel just where the bot resides
|
|
41
|
+
and people could talk to the bot.</p>
|
|
42
|
+
|
|
43
|
+
<p>Since we are typically a nodejs shop I decided to find a way to send messages to a slack bot. And slack has this really great sdk for nodejs.
|
|
44
|
+
<a href="https://github.com/slackapi/node-slack-sdk">https://github.com/slackapi/node-slack-sdk</a></p>
|
|
45
|
+
|
|
46
|
+
<p>First I went and created the bot in my slack team settings.
|
|
47
|
+
And then wrote a script which would allow it to read messages from the channel it was added.</p>
|
|
48
|
+
|
|
49
|
+
<p>Here is the simple script,</p>
|
|
50
|
+
</div>
|
|
51
|
+
`
|
|
52
|
+
|
|
53
|
+
func TestRawRootTagName(t *testing.T) {
|
|
54
|
+
tests := []struct {
|
|
55
|
+
scenario string
|
|
56
|
+
raw string
|
|
57
|
+
expected string
|
|
58
|
+
}{
|
|
59
|
+
{
|
|
60
|
+
scenario: "tag set",
|
|
61
|
+
raw: `
|
|
62
|
+
<div>
|
|
63
|
+
<span></span>
|
|
64
|
+
</div>`,
|
|
65
|
+
expected: "div",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
scenario: "tag is empty",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
scenario: "opening tag missing",
|
|
72
|
+
raw: "</div>",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
scenario: "tag is not set",
|
|
76
|
+
raw: "div",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
scenario: "tag is not closing",
|
|
80
|
+
raw: "<div",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
scenario: "tag is not closing",
|
|
84
|
+
raw: "<div",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
scenario: "tag without value",
|
|
88
|
+
raw: "<>",
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for _, test := range tests {
|
|
93
|
+
t.Run(test.scenario, func(t *testing.T) {
|
|
94
|
+
tag := rawRootTagName(test.raw)
|
|
95
|
+
require.Equal(t, test.expected, tag)
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
func TestRawMountDismount(t *testing.T) {
|
|
101
|
+
testMountDismount(t, []mountTest{
|
|
102
|
+
{
|
|
103
|
+
scenario: "raw html element",
|
|
104
|
+
node: Raw(`<h1>Hello</h1>`),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
scenario: "raw svg element",
|
|
108
|
+
node: Raw(`<svg></svg>`),
|
|
109
|
+
},
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
func TestRawUpdate(t *testing.T) {
|
|
114
|
+
testUpdate(t, []updateTest{
|
|
115
|
+
{
|
|
116
|
+
scenario: "raw html element returns replace error when updated with a non text-element",
|
|
117
|
+
a: Raw("<svg></svg>"),
|
|
118
|
+
b: Div(),
|
|
119
|
+
replaceErr: true,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
scenario: "raw html element is replace by another raw html element",
|
|
123
|
+
a: Div(
|
|
124
|
+
Raw("<div></div>"),
|
|
125
|
+
),
|
|
126
|
+
b: Div(
|
|
127
|
+
Raw("<svg></svg>"),
|
|
128
|
+
),
|
|
129
|
+
matches: []TestUIDescriptor{
|
|
130
|
+
{
|
|
131
|
+
Path: TestPath(),
|
|
132
|
+
Expected: Div(),
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
Path: TestPath(0),
|
|
136
|
+
Expected: Raw("<svg></svg>"),
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
scenario: "raw html element is replace by non-raw html element",
|
|
142
|
+
a: Div(
|
|
143
|
+
Raw("<div></div>"),
|
|
144
|
+
),
|
|
145
|
+
b: Div(
|
|
146
|
+
Text("hello"),
|
|
147
|
+
),
|
|
148
|
+
matches: []TestUIDescriptor{
|
|
149
|
+
{
|
|
150
|
+
Path: TestPath(),
|
|
151
|
+
Expected: Div(),
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
Path: TestPath(0),
|
|
155
|
+
Expected: Text("hello"),
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
}
|
testing.go
CHANGED
|
@@ -1,146 +1,152 @@
|
|
|
1
1
|
package app
|
|
2
2
|
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
|
|
6
|
+
"github.com/pyros2097/wapp/errors"
|
|
7
|
+
)
|
|
8
|
+
|
|
3
9
|
// import (
|
|
4
10
|
// "fmt"
|
|
5
11
|
|
|
6
12
|
// "github.com/pyros2097/wapp/errors"
|
|
7
13
|
// )
|
|
8
14
|
|
|
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
|
-
|
|
15
|
+
// TestUIDescriptor represents a descriptor that describes a UI element and its
|
|
16
|
+
// location from its parents.
|
|
17
|
+
type TestUIDescriptor struct {
|
|
18
|
+
// The location of the node. It is used by the TestMatch to find the
|
|
19
|
+
// element to test.
|
|
20
|
+
//
|
|
21
|
+
// If empty, the expected UI element is compared with the root of the tree.
|
|
22
|
+
//
|
|
23
|
+
// Otherwise, each integer represents the index of the element to traverse,
|
|
24
|
+
// from the root's children to the element to compare
|
|
25
|
+
Path []int
|
|
26
|
+
|
|
27
|
+
// The element to compare with the element targeted by Path. Compare
|
|
28
|
+
// behavior varies depending on the element kind.
|
|
29
|
+
//
|
|
30
|
+
// Simple text elements only have their text value compared.
|
|
31
|
+
//
|
|
32
|
+
// HTML elements have their attribute compared and check if their event
|
|
33
|
+
// handlers are set.
|
|
34
|
+
//
|
|
35
|
+
// Components have their exported field values compared.
|
|
36
|
+
Expected UI
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// TestPath is a helper function that returns a path to use in a
|
|
40
|
+
// TestUIDescriptor.
|
|
41
|
+
func TestPath(p ...int) []int {
|
|
42
|
+
return p
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// TestMatch looks for the element targeted by the descriptor in the given tree
|
|
46
|
+
// and reports whether it matches with the expected element.
|
|
47
|
+
//
|
|
48
|
+
// Eg:
|
|
49
|
+
// tree := app.Div().Body(
|
|
50
|
+
// app.H2().Body(
|
|
51
|
+
// app.Text("foo"),
|
|
52
|
+
// ),
|
|
53
|
+
// app.P().Body(
|
|
54
|
+
// app.Text("bar"),
|
|
55
|
+
// ),
|
|
56
|
+
// )
|
|
57
|
+
//
|
|
58
|
+
// // Testing root:
|
|
59
|
+
// err := app.TestMatch(tree, app.TestUIDescriptor{
|
|
60
|
+
// Path: TestPath(),
|
|
61
|
+
// Expected: app.Div(),
|
|
62
|
+
// })
|
|
63
|
+
// // OK => err == nil
|
|
64
|
+
//
|
|
65
|
+
// // Testing h2:
|
|
66
|
+
// err := app.TestMatch(tree, app.TestUIDescriptor{
|
|
67
|
+
// Path: TestPath(0),
|
|
68
|
+
// Expected: app.H3(),
|
|
69
|
+
// })
|
|
70
|
+
// // KO => err != nil because we ask h2 to match with h3
|
|
71
|
+
//
|
|
72
|
+
// // Testing text from p:
|
|
73
|
+
// err = app.TestMatch(tree, app.TestUIDescriptor{
|
|
74
|
+
// Path: TestPath(1, 0),
|
|
75
|
+
// Expected: app.Text("bar"),
|
|
76
|
+
// })
|
|
77
|
+
// // OK => err == nil
|
|
78
|
+
func TestMatch(tree UI, d TestUIDescriptor) error {
|
|
79
|
+
if !tree.Mounted() {
|
|
80
|
+
if err := mount(tree); err != nil {
|
|
81
|
+
return err
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if d.Expected != nil {
|
|
86
|
+
d.Expected.setSelf(d.Expected)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if len(d.Path) != 0 {
|
|
90
|
+
idx := d.Path[0]
|
|
91
|
+
|
|
92
|
+
if idx < 0 || idx >= len(tree.children()) {
|
|
93
|
+
// Check that the element does not exists.
|
|
94
|
+
if d.Expected == nil {
|
|
95
|
+
return nil
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return errors.New("ui element to match is out of range").
|
|
99
|
+
Tag("name", d.Expected.name()).
|
|
100
|
+
Tag("parent-name", tree.name()).
|
|
101
|
+
Tag("parent-children-count", len(tree.children())).
|
|
102
|
+
Tag("index", idx)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
c := tree.children()[idx]
|
|
106
|
+
p := c.parent()
|
|
107
|
+
|
|
108
|
+
if p != tree {
|
|
109
|
+
return errors.New("unexpected ui element parent").
|
|
110
|
+
Tag("name", d.Expected.name()).
|
|
111
|
+
Tag("parent-name", p.name()).
|
|
112
|
+
Tag("parent-addr", fmt.Sprintf("%p", p)).
|
|
113
|
+
Tag("expected-parent-name", tree.name()).
|
|
114
|
+
Tag("expected-parent-addr", fmt.Sprintf("%p", tree))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
d.Path = d.Path[1:]
|
|
118
|
+
return TestMatch(c, d)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if d.Expected.name() != tree.name() {
|
|
122
|
+
return errors.New("the UI element is not matching the descriptor").
|
|
123
|
+
Tag("expected-name", d.Expected.name()).
|
|
124
|
+
Tag("current-name", tree.name())
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// switch d.Expected.Kind() {
|
|
128
|
+
// case SimpleText:
|
|
129
|
+
// return matchText(tree, d)
|
|
130
|
+
|
|
131
|
+
// case HTML:
|
|
132
|
+
// if err := matchHTMLElemAttrs(tree, d); err != nil {
|
|
133
|
+
// return err
|
|
134
|
+
// }
|
|
135
|
+
// return matchHTMLElemEventHandlers(tree, d)
|
|
136
|
+
|
|
137
|
+
// // case Component:
|
|
138
|
+
// // return matchComponent(tree, d)
|
|
139
|
+
|
|
140
|
+
// case RawHTML:
|
|
141
|
+
// return matchRaw(tree, d)
|
|
142
|
+
|
|
143
|
+
// default:
|
|
144
|
+
// return errors.New("the UI element is not matching the descriptor").
|
|
145
|
+
// Tag("reason", "unavailable matching for the kind").
|
|
146
|
+
// Tag("kind", d.Expected.Kind())
|
|
147
|
+
// }
|
|
148
|
+
return nil
|
|
149
|
+
}
|
|
144
150
|
|
|
145
151
|
// func matchText(n UI, d TestUIDescriptor) error {
|
|
146
152
|
// a := n.(*text)
|
testing_test.go
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
package app
|
|
2
2
|
|
|
3
|
+
import (
|
|
4
|
+
"runtime"
|
|
5
|
+
"testing"
|
|
6
|
+
)
|
|
7
|
+
|
|
3
8
|
// import (
|
|
4
9
|
// "io/ioutil"
|
|
5
10
|
// "os"
|
|
@@ -9,16 +14,11 @@ package app
|
|
|
9
14
|
// "github.com/stretchr/testify/require"
|
|
10
15
|
// )
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
func testSkipNonWasm(t *testing.T) {
|
|
13
|
-
|
|
18
|
+
if goarch := runtime.GOARCH; goarch != "wasm" {
|
|
14
|
-
|
|
19
|
+
t.Skip("skipping test")
|
|
15
|
-
// // t.Skip(logs.New("skipping test").
|
|
16
|
-
// // Tag("reason", "unsupported architecture").
|
|
17
|
-
// // Tag("required-architecture", "wasm").
|
|
18
|
-
// // Tag("current-architecture", goarch),
|
|
19
|
-
// // )
|
|
20
|
-
// }
|
|
21
|
-
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
22
|
|
|
23
23
|
// func testSkipWasm(t *testing.T) {
|
|
24
24
|
// if goarch := runtime.GOARCH; goarch == "wasm" {
|