v2 / vlib / x / json2 / tests / encode_struct_test.v
356 lines · 299 sloc · 14.24 KB · 07c796b670d9e498ccb25605af189617f61ec295
Raw
1// vtest build: !macos
2import x.json2 as json
3import time
4
5const fixed_time = time.new(
6 year: 2022
7 month: 3
8 day: 11
9 hour: 13
10 minute: 54
11 second: 25
12)
13
14type StringAlias = string
15type BoolAlias = bool
16type U8Alias = u8
17type U16Alias = u16
18type U32Alias = u32
19type U64Alias = u64
20type I8Alias = i8
21type I16Alias = i16
22type I32Alias = i32
23type I64Alias = i64
24type IntAlias = int
25type UsizeAlias = usize
26type IsizeAlias = isize
27type F32Alias = f32
28type F64Alias = f64
29type TimeAlias = time.Time
30type StructAlias = StructType[int]
31type EnumAlias = Enumerates
32
33type SumTypes = StructType[string] | []SumTypes | []string | bool | int | string | time.Time
34
35enum Enumerates {
36 a
37 b
38 c
39 d
40 e = 99
41 f
42}
43
44struct StructType[T] {
45mut:
46 val T
47}
48
49struct StructTypeOption[T] {
50mut:
51 val ?T
52}
53
54struct StructTypePointer[T] {
55mut:
56 val &T
57}
58
59fn test_types() {
60 assert json.encode(StructType[string]{}) == '{"val":""}'
61 assert json.encode(StructType[string]{ val: '' }) == '{"val":""}'
62 assert json.encode(StructType[string]{ val: 'a' }) == '{"val":"a"}'
63
64 assert json.encode(StructType[bool]{}) == '{"val":false}'
65 assert json.encode(StructType[bool]{ val: false }) == '{"val":false}'
66 assert json.encode(StructType[bool]{ val: true }) == '{"val":true}'
67
68 assert json.encode(StructType[int]{}) == '{"val":0}'
69 assert json.encode(StructType[int]{ val: 0 }) == '{"val":0}'
70 assert json.encode(StructType[int]{ val: 1 }) == '{"val":1}'
71
72 assert json.encode(StructType[time.Time]{}) == '{"val":"0000-01-01T00:00:00.000Z"}'
73 assert json.encode(StructType[time.Time]{ val: fixed_time }) == '{"val":"2022-03-11T13:54:25.000Z"}'
74
75 assert json.encode(StructType[StructType[int]]{
76 val: StructType[int]{
77 val: 1
78 }
79 }) == '{"val":{"val":1}}'
80
81 assert json.encode(StructType[Enumerates]{}, enum_as_int: true) == '{"val":0}'
82 assert json.encode(StructType[Enumerates]{ val: Enumerates.a },
83 enum_as_int: true
84 ) == '{"val":0}'
85 assert json.encode(StructType[Enumerates]{ val: Enumerates.d },
86 enum_as_int: true
87 ) == '{"val":3}'
88 assert json.encode(StructType[Enumerates]{ val: Enumerates.e },
89 enum_as_int: true
90 ) == '{"val":99}'
91 assert json.encode(StructType[Enumerates]{ val: Enumerates.f },
92 enum_as_int: true
93 ) == '{"val":100}'
94}
95
96fn test_option_types() {
97 assert json.encode(StructTypeOption[string]{ val: none }) == '{}'
98 assert json.encode(StructTypeOption[string]{}) == '{}'
99 assert json.encode(StructTypeOption[string]{ val: '' }) == '{"val":""}'
100 assert json.encode(StructTypeOption[string]{ val: 'a' }) == '{"val":"a"}'
101
102 assert json.encode(StructTypeOption[bool]{ val: none }) == '{}'
103 assert json.encode(StructTypeOption[bool]{}) == '{}'
104 assert json.encode(StructTypeOption[bool]{ val: false }) == '{"val":false}'
105 assert json.encode(StructTypeOption[bool]{ val: true }) == '{"val":true}'
106
107 assert json.encode(StructTypeOption[int]{ val: none }) == '{}'
108 assert json.encode(StructTypeOption[int]{}) == '{}'
109 assert json.encode(StructTypeOption[int]{ val: 0 }) == '{"val":0}'
110 assert json.encode(StructTypeOption[int]{ val: 1 }) == '{"val":1}'
111
112 assert json.encode(StructTypeOption[time.Time]{}) == '{}'
113 assert json.encode(StructTypeOption[time.Time]{ val: time.Time{} }) == '{"val":"0000-01-01T00:00:00.000Z"}'
114 assert json.encode(StructTypeOption[time.Time]{ val: fixed_time }) == '{"val":"2022-03-11T13:54:25.000Z"}'
115
116 assert json.encode(StructTypeOption[StructType[int]]{
117 val: StructType[int]{
118 val: 1
119 }
120 }) == '{"val":{"val":1}}'
121
122 assert json.encode(StructTypeOption[Enumerates]{}) == '{}'
123}
124
125fn test_array() {
126 assert json.encode(StructType[[]string]{}) == '{"val":[]}'
127 assert json.encode(StructType[[]string]{ val: [] }) == '{"val":[]}'
128 assert json.encode(StructType[[]string]{ val: ['0'] }) == '{"val":["0"]}'
129 assert json.encode(StructType[[]string]{ val: ['1'] }) == '{"val":["1"]}'
130
131 assert json.encode(StructType[[]int]{}) == '{"val":[]}'
132 assert json.encode(StructType[[]int]{ val: [] }) == '{"val":[]}'
133 assert json.encode(StructType[[]int]{ val: [0] }) == '{"val":[0]}'
134 assert json.encode(StructType[[]int]{ val: [1] }) == '{"val":[1]}'
135 assert json.encode(StructType[[]int]{ val: [0, 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
136
137 assert json.encode(StructType[[]u8]{}) == '{"val":[]}'
138 assert json.encode(StructType[[]u8]{ val: [] }) == '{"val":[]}'
139 assert json.encode(StructType[[]u8]{ val: [u8(0)] }) == '{"val":[0]}'
140 assert json.encode(StructType[[]u8]{ val: [u8(1)] }) == '{"val":[1]}'
141 assert json.encode(StructType[[]u8]{ val: [u8(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
142
143 assert json.encode(StructType[[]i64]{}) == '{"val":[]}'
144 assert json.encode(StructType[[]i64]{ val: [] }) == '{"val":[]}'
145 assert json.encode(StructType[[]i64]{ val: [i64(0)] }) == '{"val":[0]}'
146 assert json.encode(StructType[[]i64]{ val: [i64(1)] }) == '{"val":[1]}'
147 assert json.encode(StructType[[]i64]{ val: [i64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
148
149 assert json.encode(StructType[[]u64]{}) == '{"val":[]}'
150 assert json.encode(StructType[[]u64]{ val: [] }) == '{"val":[]}'
151 assert json.encode(StructType[[]u64]{ val: [u64(0)] }) == '{"val":[0]}'
152 assert json.encode(StructType[[]u64]{ val: [u64(1)] }) == '{"val":[1]}'
153 assert json.encode(StructType[[]u64]{ val: [u64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
154
155 assert json.encode(StructType[[]f64]{}) == '{"val":[]}'
156 assert json.encode(StructType[[]f64]{ val: [] }) == '{"val":[]}'
157 assert json.encode(StructType[[]f64]{ val: [f64(0)] }) == '{"val":[0]}'
158 assert json.encode(StructType[[]f64]{ val: [f64(1)] }) == '{"val":[1]}'
159 assert json.encode(StructType[[]f64]{ val: [f64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
160
161 assert json.encode(StructType[[]bool]{}) == '{"val":[]}'
162 assert json.encode(StructType[[]bool]{ val: [] }) == '{"val":[]}'
163 assert json.encode(StructType[[]bool]{ val: [true] }) == '{"val":[true]}'
164 assert json.encode(StructType[[]bool]{ val: [false] }) == '{"val":[false]}'
165 assert json.encode(StructType[[]bool]{ val: [false, true, false] }) == '{"val":[false,true,false]}'
166
167 array_of_struct := [StructType[bool]{
168 val: true
169 }, StructType[bool]{
170 val: false
171 }]
172 assert json.encode(StructType[[]StructType[bool]]{ val: array_of_struct }) == '{"val":[{"val":true},{"val":false}]}'
173
174 assert json.encode(StructType[[][]string]{ val: [['1'], ['2']] }) == '{"val":[["1"],["2"]]}'
175
176 // error: cannot use `[][]string` as `[]string` in argument 1 to `x.json2.Encoder.encode_array`
177 // assert json.encode(StructType[[][][]string]{ val: [[['1']]] }) == '{"val":[[["1"]]]}'
178}
179
180fn test_option_array() {
181 assert json.encode(StructTypeOption[[]string]{}) == '{}'
182 assert json.encode(StructTypeOption[[]string]{ val: [] }) == '{"val":[]}'
183 assert json.encode(StructTypeOption[[]string]{ val: ['0'] }) == '{"val":["0"]}'
184 assert json.encode(StructTypeOption[[]string]{ val: ['1'] }) == '{"val":["1"]}'
185
186 assert json.encode(StructTypeOption[[]int]{}) == '{}'
187 assert json.encode(StructTypeOption[[]int]{ val: [] }) == '{"val":[]}'
188 assert json.encode(StructTypeOption[[]int]{ val: [0] }) == '{"val":[0]}'
189 assert json.encode(StructTypeOption[[]int]{ val: [1] }) == '{"val":[1]}'
190 assert json.encode(StructTypeOption[[]int]{ val: [0, 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
191
192 assert json.encode(StructTypeOption[[]u8]{}) == '{}'
193 assert json.encode(StructTypeOption[[]u8]{ val: [] }) == '{"val":[]}'
194 assert json.encode(StructTypeOption[[]u8]{ val: [u8(0)] }) == '{"val":[0]}'
195 assert json.encode(StructTypeOption[[]u8]{ val: [u8(1)] }) == '{"val":[1]}'
196 assert json.encode(StructTypeOption[[]u8]{ val: [u8(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
197
198 assert json.encode(StructTypeOption[[]i64]{}) == '{}'
199 assert json.encode(StructTypeOption[[]i64]{ val: [] }) == '{"val":[]}'
200 assert json.encode(StructTypeOption[[]i64]{ val: [i64(0)] }) == '{"val":[0]}'
201 assert json.encode(StructTypeOption[[]i64]{ val: [i64(1)] }) == '{"val":[1]}'
202 assert json.encode(StructTypeOption[[]i64]{ val: [i64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
203
204 assert json.encode(StructTypeOption[[]u64]{}) == '{}'
205 assert json.encode(StructTypeOption[[]u64]{ val: [] }) == '{"val":[]}'
206 assert json.encode(StructTypeOption[[]u64]{ val: [u64(0)] }) == '{"val":[0]}'
207 assert json.encode(StructTypeOption[[]u64]{ val: [u64(1)] }) == '{"val":[1]}'
208 assert json.encode(StructTypeOption[[]u64]{ val: [u64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
209
210 assert json.encode(StructTypeOption[[]f64]{}) == '{}'
211 assert json.encode(StructTypeOption[[]f64]{ val: [] }) == '{"val":[]}'
212 assert json.encode(StructTypeOption[[]f64]{ val: [f64(0)] }) == '{"val":[0]}'
213 assert json.encode(StructTypeOption[[]f64]{ val: [f64(1)] }) == '{"val":[1]}'
214 assert json.encode(StructTypeOption[[]f64]{ val: [f64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
215
216 assert json.encode(StructTypeOption[[]bool]{}) == '{}'
217 assert json.encode(StructTypeOption[[]bool]{ val: [] }) == '{"val":[]}'
218 assert json.encode(StructTypeOption[[]bool]{ val: [true] }) == '{"val":[true]}'
219 assert json.encode(StructTypeOption[[]bool]{ val: [false] }) == '{"val":[false]}'
220 assert json.encode(StructTypeOption[[]bool]{ val: [false, true, false] }) == '{"val":[false,true,false]}'
221
222 array_of_struct := [StructType[bool]{
223 val: true
224 }, StructType[bool]{
225 val: false
226 }]
227 assert json.encode(StructTypeOption[[]StructType[bool]]{ val: array_of_struct }) == '{"val":[{"val":true},{"val":false}]}'
228
229 // assert json.encode(StructTypeOption[[][]int]{
230 // val: [[0, 1], [0, 2, 3], [2], [5, 1]]
231 // }) == '{"val":[[0,1],[0,2,3],[2],[5,1]]}'
232}
233
234fn test_alias() {
235 assert json.encode(StructType[StringAlias]{}) == '{"val":""}'
236 assert json.encode(StructType[StringAlias]{ val: '' }) == '{"val":""}'
237 assert json.encode(StructType[StringAlias]{ val: 'a' }) == '{"val":"a"}'
238
239 assert json.encode(StructType[BoolAlias]{}) == '{"val":false}'
240 assert json.encode(StructType[BoolAlias]{ val: false }) == '{"val":false}'
241 assert json.encode(StructType[BoolAlias]{ val: true }) == '{"val":true}'
242
243 assert json.encode(StructType[IntAlias]{}) == '{"val":0}'
244 assert json.encode(StructType[IntAlias]{ val: 0 }) == '{"val":0}'
245 assert json.encode(StructType[IntAlias]{ val: 1 }) == '{"val":1}'
246
247 assert json.encode(StructType[TimeAlias]{}) == '{"val":"0000-01-01T00:00:00.000Z"}'
248 assert json.encode(StructType[TimeAlias]{ val: fixed_time }) == '{"val":"2022-03-11T13:54:25.000Z"}'
249
250 assert json.encode(StructType[StructAlias]{}) == '{"val":{"val":0}}'
251 assert json.encode(StructType[StructAlias]{ val: StructType[int]{0} }) == '{"val":{"val":0}}'
252 assert json.encode(StructType[StructAlias]{ val: StructType[int]{1} }) == '{"val":{"val":1}}'
253}
254
255fn test_pointer() {
256 mut string_initialized_with_reference := ''
257 assert json.encode(StructTypePointer[string]{ val: unsafe { nil } }) == '{}'
258 assert json.encode(StructTypePointer[string]{ val: &string_initialized_with_reference }) == '{"val":""}'
259 string_initialized_with_reference = 'a'
260 assert json.encode(StructTypePointer[string]{ val: &string_initialized_with_reference }) == '{"val":"a"}'
261
262 mut bool_initialized_with_reference := false
263 assert json.encode(StructTypePointer[bool]{ val: unsafe { nil } }) == '{}'
264 assert json.encode(StructTypePointer[bool]{ val: &bool_initialized_with_reference }) == '{"val":false}'
265 bool_initialized_with_reference = true
266 assert json.encode(StructTypePointer[bool]{ val: &bool_initialized_with_reference }) == '{"val":true}'
267
268 mut int_initialized_with_reference := int(0)
269 assert json.encode(StructTypePointer[int]{ val: unsafe { nil } }) == '{}'
270 assert json.encode(StructTypePointer[int]{ val: &int_initialized_with_reference }) == '{"val":0}'
271 int_initialized_with_reference = 1
272 assert json.encode(StructTypePointer[int]{ val: &int_initialized_with_reference }) == '{"val":1}'
273}
274
275fn test_sumtypes() {
276 assert json.encode(StructType[SumTypes]{}) == '{"val":{"val":"","_type":"${typeof(StructType[string]{}).name}"}}' // is_none := val.$(field.name).str() == 'unknown sum type value'
277 assert json.encode(StructType[SumTypes]{ val: '' }) == '{"val":""}'
278 assert json.encode(StructType[SumTypes]{ val: 'a' }) == '{"val":"a"}'
279
280 assert json.encode(StructType[SumTypes]{ val: false }) == '{"val":false}'
281 assert json.encode(StructType[SumTypes]{ val: true }) == '{"val":true}'
282
283 assert json.encode(StructType[SumTypes]{ val: 0 }) == '{"val":0}'
284 assert json.encode(StructType[SumTypes]{ val: 1 }) == '{"val":1}'
285
286 assert json.encode(StructType[SumTypes]{ val: fixed_time }) == '{"val":{"_type":"${typeof(time.Time{}).name.all_after_last('.')}","value":${fixed_time.unix()}}}'
287
288 assert json.encode(StructType[StructType[SumTypes]]{
289 val: StructType[SumTypes]{
290 val: 1
291 }
292 }) == '{"val":{"val":1}}'
293
294 assert json.encode(StructType[SumTypes]{
295 val: StructType[string]{
296 val: '111111'
297 }
298 }) == '{"val":{"val":"111111","_type":"${typeof(StructType[string]{}).name}"}}'
299
300 assert json.encode(StructType[StructType[SumTypes]]{
301 val: StructType[SumTypes]{
302 val: 1
303 }
304 }) == '{"val":{"val":1}}'
305
306 // assert json.encode(StructType{ val: [SumTypes('a')] }) == '{"val":["a"]}'
307 // assert json.encode(StructType[SumTypes]{ val: ['a'] }) == '{"val":["a"]}'
308 // assert json.encode(StructType[SumTypes]{ val: [SumTypes('a')] }) == '{"val":["a"]}'
309 // assert json.encode(StructType[SumTypes]{ val: '' }) == '{"val":""}'
310}
311
312fn test_maps() {
313 assert json.encode(StructType[map[string]map[string]int]{}) == '{"val":{}}'
314 assert json.encode(StructType[map[string]string]{
315 val: {
316 '1': '1'
317 }
318 }) == '{"val":{"1":"1"}}'
319 assert json.encode(StructType[map[string]int]{
320 val: {
321 '1': 1
322 }
323 }) == '{"val":{"1":1}}'
324 assert json.encode(StructType[map[string]map[string]int]{
325 val: {
326 'a': {
327 '1': 1
328 }
329 }
330 }) == '{"val":{"a":{"1":1}}}'
331}
332
333struct AliasStruct {
334 f_string StringAlias = 'hello'
335 f_bool BoolAlias = true
336 f_u8 U8Alias = 123
337 f_u16 U16Alias = 456
338 f_u32 U32Alias = 789
339 f_u64 U64Alias = 112233
340 f_i8 I8Alias = -123
341 f_i16 I16Alias = -456
342 f_i32 I32Alias = -789
343 f_i64 I64Alias = -112233
344 f_int IntAlias = 7788
345 f_usize UsizeAlias = 9900
346 f_isize IsizeAlias = -9900
347 f_f32 F32Alias = -1.5
348 f_f64 F64Alias = 7.25
349}
350
351fn test_struct_alias() {
352 s := AliasStruct{}
353 str := json.encode(s)
354 assert str == '{"f_string":"hello","f_bool":true,"f_u8":123,"f_u16":456,"f_u32":789,"f_u64":112233,"f_i8":-123,"f_i16":-456,"f_i32":-789,"f_i64":-112233,"f_int":7788,"f_usize":9900,"f_isize":-9900,"f_f32":-1.5,"f_f64":7.25}'
355 assert json.decode[AliasStruct](str)! == s
356}
357