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}