v2 / vlib / x / json2 / tests / encoder_test.v
206 lines · 165 sloc · 5.21 KB · 07c796b670d9e498ccb25605af189617f61ec295
Raw
1import x.json2 as json
2import time
3
4struct StructType[T] {
5mut:
6 val T
7}
8
9fn test_json_string_characters() {
10 assert json.encode([u8(`/`)].bytestr()).bytes() == r'"/"'.bytes()
11 assert json.encode([u8(`\\`)].bytestr()).bytes() == r'"\\"'.bytes()
12 assert json.encode([u8(`"`)].bytestr()).bytes() == r'"\""'.bytes()
13 assert json.encode([u8(`\n`)].bytestr()).bytes() == r'"\n"'.bytes()
14 assert json.encode(r'\n\r') == r'"\\n\\r"'
15 assert json.encode('\\n') == r'"\\n"'
16 assert json.encode(r'\n\r\b') == r'"\\n\\r\\b"'
17 assert json.encode(r'\"/').bytes() == r'"\\\"/"'.bytes()
18
19 assert json.encode(r'\n\r\b\f\t\\\"\/') == r'"\\n\\r\\b\\f\\t\\\\\\\"\\/"'
20
21 text := json.decode[json.Any](r'"\n\r\b\f\t\\\"\/"') or { '' }
22 assert text.json_str() == '"\\n\\r\\b\\f\\t\\\\\\"/"'
23
24 assert json.encode("fn main(){nprintln('Hello World! Helo \$a')\n}") == '"fn main(){nprintln(\'Hello World! Helo \$a\')\\n}"'
25 assert json.encode(' And when "\'s are in the string, along with # "') == '" And when \\"\'s are in the string, along with # \\""'
26 assert json.encode('a \\\nb') == r'"a \\\nb"'
27 assert json.encode('Name\tJosé\nLocation\tSF.') == '"Name\\tJosé\\nLocation\\tSF."'
28}
29
30fn test_json_escape_low_chars() {
31 esc := '\u001b'
32 assert esc.len == 1
33 text := json.Any(esc)
34 assert text.json_str() == r'"\u001b"'
35
36 assert json.encode('\u000f') == r'"\u000f"'
37 assert json.encode('\u0020') == r'" "'
38 assert json.encode('\u0000') == r'"\u0000"'
39}
40
41fn test_json_string() {
42 text := json.Any('te✔st')
43
44 assert text.json_str() == r'"te✔st"'
45 assert json.encode('te✔st', escape_unicode: true) == r'"te\u2714st"'
46
47 boolean := json.Any(true)
48 assert boolean.json_str() == 'true'
49 integer := json.Any(int(-5))
50 assert integer.json_str() == '-5'
51 u64integer := json.Any(u64(5000))
52 assert u64integer.json_str() == '5000'
53 i64integer := json.Any(i64(-17))
54 assert i64integer.json_str() == '-17'
55}
56
57fn test_json_string_emoji() {
58 text := json.Any('🐈')
59 assert text.json_str() == r'"🐈"'
60 assert json.Any('💀').json_str() == r'"💀"'
61
62 assert json.encode('🐈') == r'"🐈"'
63 assert json.encode('💀') == r'"💀"'
64 // assert json.encode('🐈💀') == r'"🐈💀"'
65}
66
67fn test_json_string_non_ascii() {
68 text := json.Any('ひらがな')
69 assert text.json_str() == r'"ひらがな"'
70
71 assert json.encode('ひらがな', escape_unicode: true) == r'"\u3072\u3089\u304c\u306a"'
72}
73
74fn test_utf8_strings_are_not_modified() {
75 original := '{"s":"Schilddrüsenerkrankungen"}'
76 deresult := json.decode[json.Any](original)!
77 assert deresult.str() == original
78
79 assert json.encode('ü') == '"ü"'
80 assert json.encode('Schilddrüsenerkrankungen') == '"Schilddrüsenerkrankungen"'
81}
82
83fn test_encoder_unescaped_utf32() ! {
84 jap_text := json.Any('ひらがな')
85
86 assert json.encode(jap_text) == '"${jap_text}"'
87
88 emoji_text := json.Any('🐈')
89 assert json.encode(emoji_text) == '"${emoji_text}"'
90
91 assert json.encode('ひらがな') == '"ひらがな"'
92}
93
94fn test_encoder_prettify() {
95 obj := {
96 'hello': json.Any('world')
97 'arr': [json.Any('im a string'), [json.Any('3rd level')]]
98 'obj': {
99 'map': json.Any('map inside a map')
100 }
101 }
102 assert json.encode(obj, prettify: true, indent_string: ' ') == '{
103 "hello": "world",
104 "arr": [
105 "im a string",
106 [
107 "3rd level"
108 ]
109 ],
110 "obj": {
111 "map": "map inside a map"
112 }
113}'
114}
115
116pub struct Test {
117 val string
118}
119
120struct SharedMapHolder {
121 a int
122 cache shared map[u64]string
123}
124
125fn test_encode_struct() {
126 enc := json.encode(Test{'hello!'})
127 assert enc == '{"val":"hello!"}'
128}
129
130fn test_encode_struct_with_shared_map_field() {
131 mut holder := SharedMapHolder{
132 a: 1
133 }
134
135 rlock holder.cache {
136 assert json.encode(holder) == '{"a":1,"cache":{}}'
137 }
138}
139
140pub struct Uri {
141 protocol string
142 path string
143}
144
145pub fn (u Uri) json_str() string {
146 return '"${u.protocol}://${u.path}"'
147}
148
149fn test_encode_encodable() {
150 assert json.encode(Uri{'file', 'path/to/file'}) == '"file://path/to/file"'
151}
152
153fn test_encode_array() {
154 array_of_struct := [StructType[[]bool]{
155 val: [false, true]
156 }, StructType[[]bool]{
157 val: [true, false]
158 }]
159
160 assert json.encode([1, 2, 3]) == '[1,2,3]'
161
162 assert json.encode(array_of_struct) == '[{"val":[false,true]},{"val":[true,false]}]'
163}
164
165fn test_encode_simple() {
166 assert json.encode('hello!') == '"hello!"'
167 assert json.encode(1) == '1'
168}
169
170fn test_encode_value() {
171 mut manifest := map[string]json.Any{}
172
173 manifest['server_path'] = json.Any('new_path')
174 manifest['last_updated'] = json.Any('timestamp.format_ss()')
175 manifest['from_source'] = json.Any('from_source')
176
177 assert json.encode(manifest, prettify: true, indent_string: ' ') == r'{
178 "server_path": "new_path",
179 "last_updated": "timestamp.format_ss()",
180 "from_source": "from_source"
181}'
182}
183
184fn test_encode_time() {
185 assert json.encode({
186 'bro': json.Any(time.Time{})
187 }) == '{"bro":"0000-01-01T00:00:00.000Z"}'
188
189 assert json.encode({
190 'bro': time.Time{}
191 }) == '{"bro":"0000-01-01T00:00:00.000Z"}'
192
193 assert json.encode(time.Time{}) == '"0000-01-01T00:00:00.000Z"'
194}
195
196fn test_encode_float() {
197 // remove ending `.0`
198 assert json.encode(1.0) == '1'
199
200 // TODO: better generate `1e10` instead of `1e+10`
201 assert json.encode(1.0e+10) == '1e+10'
202 assert json.encode(1.0e10) == '1e+10'
203 assert json.encode(1.e10) == '1e+10'
204 assert json.encode(1.0e-10) == '1e-10'
205 assert json.encode(1.1e10) == '1.1e+10'
206}
207