From c52794f9d420e319900f27e9f16c8444e8842e92 Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Fri, 21 Jul 2023 13:00:57 +0100 Subject: Fixes JSONWriter to work with implicit data structures --- json/write_test.go | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 json/write_test.go (limited to 'json/write_test.go') diff --git a/json/write_test.go b/json/write_test.go new file mode 100644 index 0000000..60ad609 --- /dev/null +++ b/json/write_test.go @@ -0,0 +1,183 @@ +package json + +import ( + "bufio" + "main/walk" + "strings" + "testing" + "encoding/json" +) + +type writeTester struct { + writer *JSONWriter + output *strings.Builder + t *testing.T +} + +func (t writeTester) write(value walk.Value, path ...interface{}) writeTester { + var pathValues []walk.Value + for _, segment := range path { + switch s := segment.(type) { + case int: + pathValues = append(pathValues, walk.NumberScalar(s)) + case string: + pathValues = append(pathValues, walk.StringStructure(s)) + default: + panic("Invalid path segment type") + } + } + + t.writer.Write(walk.WalkItem { + Value: []walk.Value{value}, + Path: pathValues, + }) + + return t +} + +func (t writeTester) expect(expected interface{}) writeTester { + t.writer.AssertDone() + output := t.output.String() + var actual interface{} + err := json.Unmarshal([]byte(output), &actual) + if err != nil { + t.t.Log("Produced invalid JSON:") + t.t.Log(output) + t.t.FailNow() + } + + expectedBytes, err1 := json.Marshal(expected) + actualBytes, err2 := json.Marshal(actual) + + if err1 != nil || err2 != nil { + panic("Error marshalling") + } + + expectedString := string(expectedBytes) + actualString := string(actualBytes) + + if expectedString != actualString { + t.t.Log("Expected:") + t.t.Log(expectedString) + t.t.Log("Found:") + t.t.Log(actualString) + t.t.FailNow() + } + + return t +} + +func tester(t *testing.T) writeTester { + var output strings.Builder + return writeTester { + writer: NewJSONWriter(bufio.NewWriter(&output)), + output: &output, + t: t, + } +} + +func TestImplicitStructures(t *testing.T) { + tester(t).write( + walk.NullScalar{}, + 0, "test", 0, + ).expect( + []interface{}{ + map[string]interface{}{ + "test": []interface{}{ + nil, + }, + }, + }, + ) +} + +func TestExplicitMap(t *testing.T) { + tester(t).write( + make(walk.MapStructure), + ).write( + walk.NullScalar{}, + "test", + ).expect( + map[string]interface{}{ + "test": nil, + }, + ) +} + +func TestExplicitNested(t *testing.T) { + tester(t).write( + make(walk.MapStructure), + ).write( + make(walk.MapStructure), + "first", + ).write( + make(walk.MapStructure), + "first", "second", + ).write( + walk.StringStructure("test"), + "first", "second", "third", + ).expect( + map[string]interface{}{ + "first": map[string]interface{}{ + "second": map[string]interface{}{ + "third": "test", + }, + }, + }, + ) +} + +func TestArrayOfMaps(t *testing.T) { + tester(t).write( + walk.ArrayStructure{}, + ).write( + make(walk.MapStructure), + 0, + ).write( + walk.NumberScalar(0), + 0, "number", + ).write( + make(walk.MapStructure), + 1, + ).write( + walk.NumberScalar(1), + 1, "nested", "number", + ).write( + make(walk.MapStructure), + 2, + ).write( + walk.NumberScalar(2), + 2, "number", + ).expect( + []interface{}{ + map[string]interface{}{ + "number": 0, + }, + map[string]interface{}{ + "nested": map[string]interface{}{ + "number": 1, + }, + }, + map[string]interface{}{ + "number": 2, + }, + }, + ) +} + +func TestStructures1(t *testing.T) { + tester(t).write( + make(walk.MapStructure), + ).write( + make(walk.MapStructure), + "map", + ).write( + walk.ArrayStructure{}, + "array", + ).expect( + map[string]interface{}{ + "map": map[string]interface{}{}, + "array": []interface{}{}, + }, + ) +} -- cgit v1.2.3