62540f7a18ba3ea3af4df86b4b334abf4fb4cbb9 — Martin Angers 6 days ago 824f0ac master
notes for improvements
2 files changed, 80 insertions(+), 61 deletions(-)

M zerojson.go
M zerojson_test.go
M zerojson.go => zerojson.go +2 -0
@@ 195,6 195,8 @@
 			fmt.Printf("%d: stack=%c [%d : %b] ; allow=%c ; atEOF=%t ; char=%c\n", start, peek, p.stack.depth, p.stack.static[0], p.allow, atEOF, typ)
 		}
 
+		// TODO: probably need to emit ':' and ',' to keep track of where we are (key vs value),
+		// or add a "role" arg that indicates key, value or array value?
 		switch p.allow {
 		case ':':
 			if typ == ':' {

M zerojson_test.go => zerojson_test.go +78 -61
@@ 2,6 2,7 @@
 
 import (
 	"bytes"
+	"encoding/json"
 	"fmt"
 	"io"
 	"io/ioutil"


@@ 15,34 16,6 @@
 	"github.com/stretchr/testify/require"
 )
 
-func TestParser_Testdata(t *testing.T) {
-	// parse each JSON document in testdata/ directory, make sure it parses
-	// without error.
-	files, err := ioutil.ReadDir("testdata")
-	require.NoError(t, err)
-	for _, file := range files {
-		if ext := filepath.Ext(file.Name()); ext != ".json" {
-			continue
-		}
-		t.Run(file.Name(), func(t *testing.T) {
-			b, err := ioutil.ReadFile(filepath.Join("testdata", file.Name()))
-			require.NoError(t, err)
-
-			p := parser{
-				input: b,
-				emit: func(offset int, typ byte, v []byte, err error) error {
-					if err != nil && err != io.EOF {
-						return fmt.Errorf("%d: %c: %s: %v", offset, typ, string(v), err)
-					}
-					return nil
-				},
-			}
-			err = p.parse()
-			require.NoError(t, err)
-		})
-	}
-}
-
 func TestParser(t *testing.T) {
 	cases := []struct {
 		in, out string


@@ 245,6 218,83 @@
 	}
 }
 
+func TestParser_Testdata(t *testing.T) {
+	// parse each JSON document in testdata/ directory, make sure it parses
+	// without error.
+	files, err := ioutil.ReadDir("testdata")
+	require.NoError(t, err)
+	for _, file := range files {
+		if ext := filepath.Ext(file.Name()); ext != ".json" {
+			continue
+		}
+
+		t.Run(file.Name(), func(t *testing.T) {
+			b, err := ioutil.ReadFile(filepath.Join("testdata", file.Name()))
+			require.NoError(t, err)
+
+			var buf bytes.Buffer
+			p := parser{
+				input: b,
+				emit: func(offset int, typ byte, v []byte, err error) error {
+					if err == io.EOF {
+						return nil
+					}
+
+					if err != nil {
+						return fmt.Errorf("%d: %c: %s: %v", offset, typ, string(v), err)
+					}
+					buf.Write(v)
+					return nil
+				},
+			}
+
+			// assert that zerojson parses without error
+			err = p.parse()
+			require.NoError(t, err)
+
+			// assert correctness by parsing with encoding/json and then parsing the zerojson-emitted
+			// document, and comparing the result.
+			var m1, m2 map[string]interface{}
+			require.NoError(t, json.Unmarshal(b, &m1))
+			require.NoError(t, json.Unmarshal(buf.Bytes(), &m2))
+			require.Equal(t, m1, m2)
+		})
+	}
+}
+
+func TestParser_Depth(t *testing.T) {
+	depths := []int{1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000}
+	for _, depth := range depths {
+		t.Run(strconv.Itoa(depth), func(t *testing.T) {
+			var open, clos int
+
+			p := parser{
+				input: append(bytes.Repeat([]byte{'['}, depth), bytes.Repeat([]byte{']'}, depth)...),
+				emit: func(offset int, typ byte, v []byte, err error) error {
+					if err == io.EOF {
+						return nil
+					}
+
+					switch typ {
+					case '[':
+						open++
+					case ']':
+						clos++
+					default:
+						t.Fatalf("unexpected JSON token type: %c", typ)
+					}
+					return err
+				},
+			}
+
+			err := p.parse()
+			require.NoError(t, err)
+			require.Equal(t, depth, open)
+			require.Equal(t, depth, clos)
+		})
+	}
+}
+
 func TestStack(t *testing.T) {
 	seed := time.Now().UnixNano()
 	rnd := rand.New(rand.NewSource(seed))


@@ 299,36 349,3 @@
 		}
 	}
 }
-
-func TestParser_Depth(t *testing.T) {
-	depths := []int{1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000}
-	for _, depth := range depths {
-		t.Run(strconv.Itoa(depth), func(t *testing.T) {
-			var open, clos int
-
-			p := parser{
-				input: append(bytes.Repeat([]byte{'['}, depth), bytes.Repeat([]byte{']'}, depth)...),
-				emit: func(offset int, typ byte, v []byte, err error) error {
-					if err == io.EOF {
-						return nil
-					}
-
-					switch typ {
-					case '[':
-						open++
-					case ']':
-						clos++
-					default:
-						t.Fatalf("unexpected JSON token type: %c", typ)
-					}
-					return err
-				},
-			}
-
-			err := p.parse()
-			require.NoError(t, err)
-			require.Equal(t, depth, open)
-			require.Equal(t, depth, clos)
-		})
-	}
-}