encode_test.gno
4.65 Kb ยท 254 lines
1package json
2
3import "testing"
4
5func TestMarshal_Primitive(t *testing.T) {
6 tests := []struct {
7 name string
8 node *Node
9 }{
10 {
11 name: "null",
12 node: NullNode(""),
13 },
14 {
15 name: "true",
16 node: BoolNode("", true),
17 },
18 {
19 name: "false",
20 node: BoolNode("", false),
21 },
22 {
23 name: `"string"`,
24 node: StringNode("", "string"),
25 },
26 {
27 name: `"one \"encoded\" string"`,
28 node: StringNode("", `one "encoded" string`),
29 },
30 {
31 name: `{"foo":"bar"}`,
32 node: ObjectNode("", map[string]*Node{
33 "foo": StringNode("foo", "bar"),
34 }),
35 },
36 {
37 name: "42",
38 node: NumberNode("", 42),
39 },
40 {
41 name: "3.14",
42 node: NumberNode("", 3.14),
43 },
44 {
45 name: `[1,2,3]`,
46 node: ArrayNode("", []*Node{
47 NumberNode("0", 1),
48 NumberNode("2", 2),
49 NumberNode("3", 3),
50 }),
51 },
52 }
53 for _, test := range tests {
54 t.Run(test.name, func(t *testing.T) {
55 value, err := Marshal(test.node)
56 if err != nil {
57 t.Errorf("unexpected error: %s", err)
58 } else if string(value) != test.name {
59 t.Errorf("wrong result: '%s', expected '%s'", value, test.name)
60 }
61 })
62 }
63}
64
65func TestMarshal_Object(t *testing.T) {
66 node := ObjectNode("", map[string]*Node{
67 "foo": StringNode("foo", "bar"),
68 "baz": NumberNode("baz", 100500),
69 "qux": NullNode("qux"),
70 })
71
72 mustKey := []string{"foo", "baz", "qux"}
73
74 value, err := Marshal(node)
75 if err != nil {
76 t.Errorf("unexpected error: %s", err)
77 }
78
79 // the order of keys in the map is not guaranteed
80 // so we need to unmarshal the result and check the keys
81 decoded, err := Unmarshal(value)
82 if err != nil {
83 t.Errorf("unexpected error: %s", err)
84 }
85
86 for _, key := range mustKey {
87 if node, err := decoded.GetKey(key); err != nil {
88 t.Errorf("unexpected error: %s", err)
89 } else {
90 if node == nil {
91 t.Errorf("node is nil")
92 } else if node.key == nil {
93 t.Errorf("key is nil")
94 } else if *node.key != key {
95 t.Errorf("wrong key: '%s', expected '%s'", *node.key, key)
96 }
97 }
98 }
99}
100
101func valueNode(prev *Node, key string, typ ValueType, val any) *Node {
102 curr := &Node{
103 prev: prev,
104 data: nil,
105 key: &key,
106 borders: [2]int{0, 0},
107 value: val,
108 modified: true,
109 }
110
111 if val != nil {
112 curr.nodeType = typ
113 }
114
115 return curr
116}
117
118func TestMarshal_Errors(t *testing.T) {
119 tests := []struct {
120 name string
121 node func() (node *Node)
122 }{
123 {
124 name: "nil",
125 node: func() (node *Node) {
126 return
127 },
128 },
129 {
130 name: "broken",
131 node: func() (node *Node) {
132 node = Must(Unmarshal([]byte(`{}`)))
133 node.borders[1] = 0
134 return
135 },
136 },
137 {
138 name: "Numeric",
139 node: func() (node *Node) {
140 return valueNode(nil, "", Number, false)
141 },
142 },
143 {
144 name: "String",
145 node: func() (node *Node) {
146 return valueNode(nil, "", String, false)
147 },
148 },
149 {
150 name: "Bool",
151 node: func() (node *Node) {
152 return valueNode(nil, "", Boolean, 1)
153 },
154 },
155 {
156 name: "Array_1",
157 node: func() (node *Node) {
158 node = ArrayNode("", nil)
159 node.next["1"] = NullNode("1")
160 return
161 },
162 },
163 {
164 name: "Array_2",
165 node: func() (node *Node) {
166 return ArrayNode("", []*Node{valueNode(nil, "", Boolean, 1)})
167 },
168 },
169 {
170 name: "Object",
171 node: func() (node *Node) {
172 return ObjectNode("", map[string]*Node{"key": valueNode(nil, "key", Boolean, 1)})
173 },
174 },
175 }
176 for _, test := range tests {
177 t.Run(test.name, func(t *testing.T) {
178 value, err := Marshal(test.node())
179 if err == nil {
180 t.Errorf("expected error")
181 } else if len(value) != 0 {
182 t.Errorf("wrong result")
183 }
184 })
185 }
186}
187
188func TestMarshal_Nil(t *testing.T) {
189 _, err := Marshal(nil)
190 if err == nil {
191 t.Error("Expected error for nil node, but got nil")
192 }
193}
194
195func TestMarshal_NotModified(t *testing.T) {
196 node := &Node{}
197 _, err := Marshal(node)
198 if err == nil {
199 t.Error("Expected error for not modified node, but got nil")
200 }
201}
202
203func TestMarshalCycleReference(t *testing.T) {
204 node1 := &Node{
205 key: stringPtr("node1"),
206 nodeType: String,
207 next: map[string]*Node{
208 "next": nil,
209 },
210 }
211
212 node2 := &Node{
213 key: stringPtr("node2"),
214 nodeType: String,
215 prev: node1,
216 }
217
218 node1.next["next"] = node2
219
220 _, err := Marshal(node1)
221 if err == nil {
222 t.Error("Expected error for cycle reference, but got nil")
223 }
224}
225
226func TestMarshalNoCycleReference(t *testing.T) {
227 node1 := &Node{
228 key: stringPtr("node1"),
229 nodeType: String,
230 value: "value1",
231 modified: true,
232 }
233
234 node2 := &Node{
235 key: stringPtr("node2"),
236 nodeType: String,
237 value: "value2",
238 modified: true,
239 }
240
241 _, err := Marshal(node1)
242 if err != nil {
243 t.Errorf("Unexpected error: %v", err)
244 }
245
246 _, err = Marshal(node2)
247 if err != nil {
248 t.Errorf("Unexpected error: %v", err)
249 }
250}
251
252func stringPtr(s string) *string {
253 return &s
254}