aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/json/json_test.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/json/json_test.v')
-rw-r--r--v_windows/v/vlib/json/json_test.v368
1 files changed, 368 insertions, 0 deletions
diff --git a/v_windows/v/vlib/json/json_test.v b/v_windows/v/vlib/json/json_test.v
new file mode 100644
index 0000000..ca6b2ac
--- /dev/null
+++ b/v_windows/v/vlib/json/json_test.v
@@ -0,0 +1,368 @@
+import json
+import time
+
+enum JobTitle {
+ manager
+ executive
+ worker
+}
+
+struct Employee {
+ name string
+ age int
+ salary f32
+ title JobTitle
+}
+
+fn test_simple() ? {
+ x := Employee{'Peter', 28, 95000.5, .worker}
+ s := json.encode(x)
+ eprintln('Employee x: $s')
+ assert s == '{"name":"Peter","age":28,"salary":95000.5,"title":2}'
+ y := json.decode(Employee, s) ?
+ eprintln('Employee y: $y')
+ assert y.name == 'Peter'
+ assert y.age == 28
+ assert y.salary == 95000.5
+ assert y.title == .worker
+}
+
+fn test_decode_top_level_array() {
+ s := '[{"name":"Peter", "age": 29}, {"name":"Bob", "age":31}]'
+ x := json.decode([]Employee, s) or { panic(err) }
+ assert x.len == 2
+ assert x[0].name == 'Peter'
+ assert x[0].age == 29
+ assert x[1].name == 'Bob'
+ assert x[1].age == 31
+}
+
+fn bar<T>(payload string) ?Bar { // ?T doesn't work currently
+ result := json.decode(T, payload) ?
+ return result
+}
+
+struct Bar {
+ x string
+}
+
+fn test_generic() {
+ result := bar<Bar>('{"x":"test"}') or { Bar{} }
+ assert result.x == 'test'
+}
+
+struct User2 {
+ age int
+ nums []int
+ reg_date time.Time
+}
+
+struct User {
+ age int
+ nums []int
+ last_name string [json: lastName]
+ is_registered bool [json: IsRegistered]
+ typ int [json: 'type']
+ pets string [json: 'pet_animals'; raw]
+}
+
+fn test_parse_user() ? {
+ s := '{"age": 10, "nums": [1,2,3], "type": 1, "lastName": "Johnson", "IsRegistered": true, "pet_animals": {"name": "Bob", "animal": "Dog"}}'
+ u2 := json.decode(User2, s) ?
+ println(u2)
+ u := json.decode(User, s) ?
+ println(u)
+ assert u.age == 10
+ assert u.last_name == 'Johnson'
+ assert u.is_registered == true
+ assert u.nums.len == 3
+ assert u.nums[0] == 1
+ assert u.nums[1] == 2
+ assert u.nums[2] == 3
+ assert u.typ == 1
+ assert u.pets == '{"name":"Bob","animal":"Dog"}'
+}
+
+fn test_encode_decode_time() ? {
+ user := User2{
+ age: 25
+ reg_date: time.new_time(year: 2020, month: 12, day: 22, hour: 7, minute: 23)
+ }
+ s := json.encode(user)
+ println(s)
+ assert s.contains('"reg_date":1608621780')
+ user2 := json.decode(User2, s) ?
+ assert user2.reg_date.str() == '2020-12-22 07:23:00'
+ println(user2)
+ println(user2.reg_date)
+}
+
+fn (mut u User) foo() string {
+ return json.encode(u)
+}
+
+fn test_encode_user() {
+ mut usr := User{
+ age: 10
+ nums: [1, 2, 3]
+ last_name: 'Johnson'
+ is_registered: true
+ typ: 0
+ pets: 'foo'
+ }
+ expected := '{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"foo"}'
+ out := json.encode(usr)
+ println(out)
+ assert out == expected
+ // Test json.encode on mutable pointers
+ assert usr.foo() == expected
+}
+
+struct Color {
+ space string
+ point string [raw]
+}
+
+fn test_raw_json_field() {
+ color := json.decode(Color, '{"space": "YCbCr", "point": {"Y": 123}}') or {
+ println('text')
+ return
+ }
+ assert color.point == '{"Y":123}'
+ assert color.space == 'YCbCr'
+}
+
+fn test_bad_raw_json_field() {
+ color := json.decode(Color, '{"space": "YCbCr"}') or {
+ println('text')
+ return
+ }
+ assert color.point == ''
+ assert color.space == 'YCbCr'
+}
+
+struct City {
+ name string
+}
+
+struct Country {
+ cities []City
+ name string
+}
+
+fn test_struct_in_struct() ? {
+ country := json.decode(Country, '{ "name": "UK", "cities": [{"name":"London"}, {"name":"Manchester"}]}') ?
+ assert country.name == 'UK'
+ assert country.cities.len == 2
+ assert country.cities[0].name == 'London'
+ assert country.cities[1].name == 'Manchester'
+ println(country.cities)
+}
+
+fn test_encode_map() {
+ expected := '{"one":1,"two":2,"three":3,"four":4}'
+ numbers := {
+ 'one': 1
+ 'two': 2
+ 'three': 3
+ 'four': 4
+ }
+ out := json.encode(numbers)
+ println(out)
+ assert out == expected
+}
+
+fn test_parse_map() ? {
+ expected := {
+ 'one': 1
+ 'two': 2
+ 'three': 3
+ 'four': 4
+ }
+ out := json.decode(map[string]int, '{"one":1,"two":2,"three":3,"four":4}') ?
+ println(out)
+ assert out == expected
+}
+
+struct Data {
+ countries []Country
+ users map[string]User
+ extra map[string]map[string]int
+}
+
+fn test_nested_type() ? {
+ data_expected := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":[{"name":"Donlon"},{"name":"Termanches"}],"name":"KU"}],"users":{"Foo":{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},"Boo":{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}},"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
+ data := Data{
+ countries: [
+ Country{
+ name: 'UK'
+ cities: [City{'London'}, City{'Manchester'}]
+ },
+ Country{
+ name: 'KU'
+ cities: [City{'Donlon'}, City{'Termanches'}]
+ },
+ ]
+ users: {
+ 'Foo': User{
+ age: 10
+ nums: [1, 2, 3]
+ last_name: 'Johnson'
+ is_registered: true
+ typ: 0
+ pets: 'little foo'
+ }
+ 'Boo': User{
+ age: 20
+ nums: [5, 3, 1]
+ last_name: 'Smith'
+ is_registered: false
+ typ: 4
+ pets: 'little boo'
+ }
+ }
+ extra: {
+ '2': {
+ 'n1': 2
+ 'n2': 4
+ 'n3': 8
+ 'n4': 16
+ }
+ '3': {
+ 'n1': 3
+ 'n2': 9
+ 'n3': 27
+ 'n4': 81
+ }
+ }
+ }
+ out := json.encode(data)
+ println(out)
+ assert out == data_expected
+ data2 := json.decode(Data, data_expected) ?
+ assert data2.countries.len == data.countries.len
+ for i in 0 .. 1 {
+ assert data2.countries[i].name == data.countries[i].name
+ assert data2.countries[i].cities.len == data.countries[i].cities.len
+ for j in 0 .. 1 {
+ assert data2.countries[i].cities[j].name == data.countries[i].cities[j].name
+ }
+ }
+ for key, user in data.users {
+ assert data2.users[key].age == user.age
+ assert data2.users[key].nums == user.nums
+ assert data2.users[key].last_name == user.last_name
+ assert data2.users[key].is_registered == user.is_registered
+ assert data2.users[key].typ == user.typ
+ // assert data2.users[key].pets == user.pets // TODO FIX
+ }
+ for k, v in data.extra {
+ for k2, v2 in v {
+ assert data2.extra[k][k2] == v2
+ }
+ }
+}
+
+struct Foo<T> {
+pub:
+ name string
+ data T
+}
+
+fn test_generic_struct() ? {
+ foo_int := Foo<int>{'bar', 12}
+ foo_enc := json.encode(foo_int)
+ assert foo_enc == '{"name":"bar","data":12}'
+ foo_dec := json.decode(Foo<int>, foo_enc) ?
+ assert foo_dec.name == 'bar'
+ assert foo_dec.data == 12
+}
+
+fn test_errors() {
+ invalid_array := fn () {
+ data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":{"name":"Donlon"},"name":"KU"}],"users":{"Foo":{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},"Boo":{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}},"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
+ json.decode(Data, data) or {
+ println(err)
+ assert err.msg.starts_with('Json element is not an array:')
+ return
+ }
+ assert false
+ }
+ invalid_object := fn () {
+ data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":[{"name":"Donlon"},{"name":"Termanches"}],"name":"KU"}],"users":[{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}],"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
+ json.decode(Data, data) or {
+ println(err)
+ assert err.msg.starts_with('Json element is not an object:')
+ return
+ }
+ assert false
+ }
+ invalid_array()
+ invalid_object()
+}
+
+type ID = string
+
+struct Message {
+ id ID
+}
+
+fn test_decode_alias_struct() ? {
+ msg := json.decode(Message, '{"id": "118499178790780929"}') ?
+ // hacky way of comparing aliased strings
+ assert msg.id.str() == '118499178790780929'
+}
+
+fn test_encode_alias_struct() {
+ expected := '{"id":"118499178790780929"}'
+ msg := Message{'118499178790780929'}
+ out := json.encode(msg)
+ assert out == expected
+}
+
+struct List {
+ id int
+ items []string
+}
+
+fn test_list() ? {
+ list := json.decode(List, '{"id": 1, "items": ["1", "2"]}') ?
+ assert list.id == 1
+ assert list.items == ['1', '2']
+}
+
+fn test_list_no_id() ? {
+ list := json.decode(List, '{"items": ["1", "2"]}') ?
+ assert list.id == 0
+ assert list.items == ['1', '2']
+}
+
+fn test_list_no_items() ? {
+ list := json.decode(List, '{"id": 1}') ?
+ assert list.id == 1
+ assert list.items == []
+}
+
+struct Info {
+ id int
+ items []string
+ maps map[string]string
+}
+
+fn test_decode_null_object() ? {
+ info := json.decode(Info, '{"id": 22, "items": null, "maps": null}') ?
+ assert info.id == 22
+ assert '$info.items' == '[]'
+ assert '$info.maps' == '{}'
+}
+
+struct Foo2 {
+ name string
+}
+
+fn test_pretty() {
+ foo := Foo2{'Bob'}
+ assert json.encode_pretty(foo) == '{
+ "name": "Bob"
+}'
+}