Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/river/internal/value/value_object_test.go
4096 views
1
package value_test
2
3
import (
4
"testing"
5
6
"github.com/grafana/agent/pkg/river/internal/value"
7
"github.com/stretchr/testify/require"
8
)
9
10
// TestBlockRepresentation ensures that the struct tags for blocks are
11
// represented correctly.
12
func TestBlockRepresentation(t *testing.T) {
13
type UnlabledBlock struct {
14
Value int `river:"value,attr"`
15
}
16
type LabeledBlock struct {
17
Value int `river:"value,attr"`
18
Label string `river:",label"`
19
}
20
type OuterBlock struct {
21
Attr1 string `river:"attr_1,attr"`
22
Attr2 string `river:"attr_2,attr"`
23
24
UnlabledBlock1 UnlabledBlock `river:"unlabeled.a,block"`
25
UnlabledBlock2 UnlabledBlock `river:"unlabeled.b,block"`
26
UnlabledBlock3 UnlabledBlock `river:"other_unlabeled,block"`
27
28
LabeledBlock1 LabeledBlock `river:"labeled.a,block"`
29
LabeledBlock2 LabeledBlock `river:"labeled.b,block"`
30
LabeledBlock3 LabeledBlock `river:"other_labeled,block"`
31
}
32
33
val := OuterBlock{
34
Attr1: "value_1",
35
Attr2: "value_2",
36
UnlabledBlock1: UnlabledBlock{
37
Value: 1,
38
},
39
UnlabledBlock2: UnlabledBlock{
40
Value: 2,
41
},
42
UnlabledBlock3: UnlabledBlock{
43
Value: 3,
44
},
45
LabeledBlock1: LabeledBlock{
46
Value: 4,
47
Label: "label_a",
48
},
49
LabeledBlock2: LabeledBlock{
50
Value: 5,
51
Label: "label_b",
52
},
53
LabeledBlock3: LabeledBlock{
54
Value: 6,
55
Label: "label_c",
56
},
57
}
58
59
t.Run("Map decode", func(t *testing.T) {
60
var m map[string]interface{}
61
require.NoError(t, value.Decode(value.Encode(val), &m))
62
63
type object = map[string]interface{}
64
65
expect := object{
66
"attr_1": "value_1",
67
"attr_2": "value_2",
68
"unlabeled": object{
69
"a": object{"value": float64(1)},
70
"b": object{"value": float64(2)},
71
},
72
"other_unlabeled": object{"value": float64(3)},
73
"labeled": object{
74
"a": object{
75
"label_a": object{"value": float64(4)},
76
},
77
"b": object{
78
"label_b": object{"value": float64(5)},
79
},
80
},
81
"other_labeled": object{
82
"label_c": object{"value": float64(6)},
83
},
84
}
85
86
require.Equal(t, m, expect)
87
})
88
89
t.Run("Object decode from other object", func(t *testing.T) {
90
// Decode into a separate type which is structurally identical but not
91
// literally the same.
92
type OuterBlock2 OuterBlock
93
94
var actualVal OuterBlock2
95
require.NoError(t, value.Decode(value.Encode(val), &actualVal))
96
require.Equal(t, val, OuterBlock(actualVal))
97
})
98
}
99
100
// TestSquashedBlockRepresentation ensures that the struct tags for squashed
101
// blocks are represented correctly.
102
func TestSquashedBlockRepresentation(t *testing.T) {
103
type InnerStruct struct {
104
InnerField1 string `river:"inner_field_1,attr,optional"`
105
InnerField2 string `river:"inner_field_2,attr,optional"`
106
}
107
108
type OuterStruct struct {
109
OuterField1 string `river:"outer_field_1,attr,optional"`
110
Inner InnerStruct `river:",squash"`
111
OuterField2 string `river:"outer_field_2,attr,optional"`
112
}
113
114
val := OuterStruct{
115
OuterField1: "value1",
116
Inner: InnerStruct{
117
InnerField1: "value3",
118
InnerField2: "value4",
119
},
120
OuterField2: "value2",
121
}
122
123
t.Run("Map decode", func(t *testing.T) {
124
var m map[string]interface{}
125
require.NoError(t, value.Decode(value.Encode(val), &m))
126
127
type object = map[string]interface{}
128
129
expect := object{
130
"outer_field_1": "value1",
131
"inner_field_1": "value3",
132
"inner_field_2": "value4",
133
"outer_field_2": "value2",
134
}
135
136
require.Equal(t, m, expect)
137
})
138
}
139
140
func TestSliceOfBlocks(t *testing.T) {
141
type UnlabledBlock struct {
142
Value int `river:"value,attr"`
143
}
144
type LabeledBlock struct {
145
Value int `river:"value,attr"`
146
Label string `river:",label"`
147
}
148
type OuterBlock struct {
149
Attr1 string `river:"attr_1,attr"`
150
Attr2 string `river:"attr_2,attr"`
151
152
Unlabeled []UnlabledBlock `river:"unlabeled,block"`
153
Labeled []LabeledBlock `river:"labeled,block"`
154
}
155
156
val := OuterBlock{
157
Attr1: "value_1",
158
Attr2: "value_2",
159
Unlabeled: []UnlabledBlock{
160
{Value: 1},
161
{Value: 2},
162
{Value: 3},
163
},
164
Labeled: []LabeledBlock{
165
{Label: "label_a", Value: 4},
166
{Label: "label_b", Value: 5},
167
{Label: "label_c", Value: 6},
168
},
169
}
170
171
t.Run("Map decode", func(t *testing.T) {
172
var m map[string]interface{}
173
require.NoError(t, value.Decode(value.Encode(val), &m))
174
175
type object = map[string]interface{}
176
type list = []interface{}
177
178
expect := object{
179
"attr_1": "value_1",
180
"attr_2": "value_2",
181
"unlabeled": list{
182
object{"value": float64(1)},
183
object{"value": float64(2)},
184
object{"value": float64(3)},
185
},
186
"labeled": object{
187
"label_a": object{"value": float64(4)},
188
"label_b": object{"value": float64(5)},
189
"label_c": object{"value": float64(6)},
190
},
191
}
192
193
require.Equal(t, m, expect)
194
})
195
196
t.Run("Object decode from other object", func(t *testing.T) {
197
// Decode into a separate type which is structurally identical but not
198
// literally the same.
199
type OuterBlock2 OuterBlock
200
201
var actualVal OuterBlock2
202
require.NoError(t, value.Decode(value.Encode(val), &actualVal))
203
require.Equal(t, val, OuterBlock(actualVal))
204
})
205
}
206
207