From bc1bacc410ddfa444c5bf0e56f33a7da440658ae Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 30 Jan 2023 11:42:51 -0700 Subject: decode: Inline noWsRuneTypeScanner into runeTypeScannerImpl --- decode_scan_test.go | 113 ++++++++++------------------------------------------ 1 file changed, 22 insertions(+), 91 deletions(-) (limited to 'decode_scan_test.go') diff --git a/decode_scan_test.go b/decode_scan_test.go index 6a430ab..5bf5e2a 100644 --- a/decode_scan_test.go +++ b/decode_scan_test.go @@ -69,7 +69,6 @@ func TestRuneTypeScanner(t *testing.T) { {'o', 1, internal.RuneTypeStringChar, nil}, {'"', 1, internal.RuneTypeStringEnd, nil}, {':', 1, internal.RuneTypeObjectColon, nil}, - {' ', 1, internal.RuneTypeSpace, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, {'2', 1, internal.RuneTypeNumberIntDig, nil}, {'.', 1, internal.RuneTypeNumberFracDot, nil}, @@ -86,7 +85,6 @@ func TestRuneTypeScanner(t *testing.T) { {'o', 1, internal.RuneTypeStringChar, nil}, {'"', 1, internal.RuneTypeStringEnd, nil}, {':', 1, internal.RuneTypeObjectColon, nil}, - {' ', 1, internal.RuneTypeSpace, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, {0, -1, 0, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, @@ -105,7 +103,6 @@ func TestRuneTypeScanner(t *testing.T) { {'o', 1, internal.RuneTypeStringChar, nil}, {'"', 1, internal.RuneTypeStringEnd, nil}, {':', 1, internal.RuneTypeObjectColon, nil}, - {' ', 1, internal.RuneTypeSpace, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, {0, -1, 0, nil}, {0, -1, 0, ErrInvalidUnreadRune}, @@ -125,7 +122,6 @@ func TestRuneTypeScanner(t *testing.T) { {'o', 1, internal.RuneTypeStringChar, nil}, {'"', 1, internal.RuneTypeStringEnd, nil}, {':', 1, internal.RuneTypeObjectColon, nil}, - {' ', 1, internal.RuneTypeSpace, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, {'2', 1, internal.RuneTypeNumberIntDig, nil}, {'.', 1, internal.RuneTypeNumberFracDot, nil}, @@ -136,44 +132,7 @@ func TestRuneTypeScanner(t *testing.T) { {0, 0, internal.RuneTypeEOF, nil}, {0, 0, internal.RuneTypeEOF, nil}, }}, - "syntax-error": {`[[0,]`, ``, []ReadRuneTypeResult{ - {'[', 1, internal.RuneTypeArrayBeg, nil}, - {'[', 1, internal.RuneTypeArrayBeg, nil}, - {'0', 1, internal.RuneTypeNumberIntZero, nil}, - {',', 1, internal.RuneTypeArrayComma, nil}, - {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 4, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, - {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 4, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, - {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 4, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, - }}, - "multi-value": {`1{}`, `}`, []ReadRuneTypeResult{ - {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {'{', 1, internal.RuneTypeEOF, nil}, - {'{', 1, internal.RuneTypeEOF, nil}, - {'{', 1, internal.RuneTypeEOF, nil}, - }}, - "early-eof": {`{`, ``, []ReadRuneTypeResult{ - {'{', 1, internal.RuneTypeObjectBeg, nil}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 1, Err: io.ErrUnexpectedEOF}}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 1, Err: io.ErrUnexpectedEOF}}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 1, Err: io.ErrUnexpectedEOF}}, - }}, - "empty": {``, ``, []ReadRuneTypeResult{ - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, - }}, - } - testRuneTypeScanner(t, testcases, func(reader io.RuneScanner) runeTypeScanner { - return &runeTypeScannerImpl{ - inner: reader, - } - }) -} - -func TestNoWSRuneTypeScanner(t *testing.T) { - t.Parallel() - testcases := map[string]runeTypeScannerTestcase{ - "basic": {`{"foo": 12.0}`, ``, []ReadRuneTypeResult{ + "tail-ws": {`{"foo": 12.0} `, ``, []ReadRuneTypeResult{ {'{', 1, internal.RuneTypeObjectBeg, nil}, {'"', 1, internal.RuneTypeStringBeg, nil}, {'f', 1, internal.RuneTypeStringChar, nil}, @@ -189,39 +148,14 @@ func TestNoWSRuneTypeScanner(t *testing.T) { {0, 0, internal.RuneTypeEOF, nil}, {0, 0, internal.RuneTypeEOF, nil}, }}, - "unread": {`{"foo": 12.0}`, ``, []ReadRuneTypeResult{ - {'{', 1, internal.RuneTypeObjectBeg, nil}, - {'"', 1, internal.RuneTypeStringBeg, nil}, - {'f', 1, internal.RuneTypeStringChar, nil}, - {'o', 1, internal.RuneTypeStringChar, nil}, - {'o', 1, internal.RuneTypeStringChar, nil}, - {'"', 1, internal.RuneTypeStringEnd, nil}, - {':', 1, internal.RuneTypeObjectColon, nil}, - {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {0, -1, 0, nil}, - {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {'2', 1, internal.RuneTypeNumberIntDig, nil}, - {'.', 1, internal.RuneTypeNumberFracDot, nil}, - {'0', 1, internal.RuneTypeNumberFracDig, nil}, - {'}', 1, internal.RuneTypeObjectEnd, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - }}, - "tail": {`{"foo": 12.0} `, ``, []ReadRuneTypeResult{ - {'{', 1, internal.RuneTypeObjectBeg, nil}, - {'"', 1, internal.RuneTypeStringBeg, nil}, - {'f', 1, internal.RuneTypeStringChar, nil}, - {'o', 1, internal.RuneTypeStringChar, nil}, - {'o', 1, internal.RuneTypeStringChar, nil}, - {'"', 1, internal.RuneTypeStringEnd, nil}, - {':', 1, internal.RuneTypeObjectColon, nil}, - {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {'2', 1, internal.RuneTypeNumberIntDig, nil}, - {'.', 1, internal.RuneTypeNumberFracDot, nil}, - {'0', 1, internal.RuneTypeNumberFracDig, nil}, - {'}', 1, internal.RuneTypeObjectEnd, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - {0, 0, internal.RuneTypeEOF, nil}, + "syntax-error": {`[[0,]`, ``, []ReadRuneTypeResult{ + {'[', 1, internal.RuneTypeArrayBeg, nil}, + {'[', 1, internal.RuneTypeArrayBeg, nil}, + {'0', 1, internal.RuneTypeNumberIntZero, nil}, + {',', 1, internal.RuneTypeArrayComma, nil}, + {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 4, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, + {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 4, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, + {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 4, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, }}, "multi-value": {`1{}`, `}`, []ReadRuneTypeResult{ {'1', 1, internal.RuneTypeNumberIntDig, nil}, @@ -235,12 +169,15 @@ func TestNoWSRuneTypeScanner(t *testing.T) { {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 2, Err: io.ErrUnexpectedEOF}}, {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 2, Err: io.ErrUnexpectedEOF}}, }}, + "empty": {``, ``, []ReadRuneTypeResult{ + {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, + {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, + {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, + }}, } testRuneTypeScanner(t, testcases, func(reader io.RuneScanner) runeTypeScanner { - return &noWSRuneTypeScanner{ - inner: &runeTypeScannerImpl{ - inner: reader, - }, + return &runeTypeScannerImpl{ + inner: reader, } }) } @@ -301,10 +238,8 @@ func TestElemRuneTypeScanner(t *testing.T) { t.Parallel() testRuneTypeScanner(t, toplevelTestcases, func(reader io.RuneScanner) runeTypeScanner { return &elemRuneTypeScanner{ - inner: &noWSRuneTypeScanner{ - inner: &runeTypeScannerImpl{ - inner: reader, - }, + inner: &runeTypeScannerImpl{ + inner: reader, }, } }) @@ -312,10 +247,8 @@ func TestElemRuneTypeScanner(t *testing.T) { t.Run("child", func(t *testing.T) { t.Parallel() testRuneTypeScanner(t, childTestcases, func(reader io.RuneScanner) runeTypeScanner { - inner := &noWSRuneTypeScanner{ - inner: &runeTypeScannerImpl{ - inner: reader, - }, + inner := &runeTypeScannerImpl{ + inner: reader, } var res ReadRuneTypeResult res.r, res.s, res.t, res.e = inner.ReadRuneType() @@ -332,10 +265,8 @@ func TestElemRuneTypeScanner(t *testing.T) { func TestElemRuneTypeScanner2(t *testing.T) { t.Parallel() - parent := &noWSRuneTypeScanner{ - inner: &runeTypeScannerImpl{ - inner: strings.NewReader(` { "foo" : 12.0 } `), - }, + parent := &runeTypeScannerImpl{ + inner: strings.NewReader(` { "foo" : 12.0 } `), } exp := []ReadRuneTypeResult{ {'{', 1, internal.RuneTypeObjectBeg, nil}, -- cgit v1.2.3-2-g168b From b3f4186f2b8e992f56f898784b1cd28bfd7550ca Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 29 Jan 2023 20:59:37 -0700 Subject: Invent "barriers" instead of nesting parsers --- decode_scan_test.go | 263 +++++++++++++++++++++------------------------------- 1 file changed, 104 insertions(+), 159 deletions(-) (limited to 'decode_scan_test.go') diff --git a/decode_scan_test.go b/decode_scan_test.go index 5bf5e2a..d0725e5 100644 --- a/decode_scan_test.go +++ b/decode_scan_test.go @@ -11,7 +11,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "git.lukeshu.com/go/lowmemjson/internal" ) @@ -23,8 +22,26 @@ type ReadRuneTypeResult struct { e error } +const ( + unreadRune = -1 + pushReadBarrier = -2 + popReadBarrier = -3 + reset = -4 +) + func (r ReadRuneTypeResult) String() string { - return fmt.Sprintf("{%q, %d, %#v, %v}", r.r, r.s, r.t, r.e) + switch r.s { + case unreadRune: + return fmt.Sprintf("{%q, unreadRune, %#v, %v}", r.r, r.t, r.e) + case pushReadBarrier: + return fmt.Sprintf("{%q, pushReadBarrier, %#v, %v}", r.r, r.t, r.e) + case popReadBarrier: + return fmt.Sprintf("{%q, popReadBarrier, %#v, %v}", r.r, r.t, r.e) + case reset: + return fmt.Sprintf("{%q, reset, %#v, %v}", r.r, r.t, r.e) + default: + return fmt.Sprintf("{%q, %d, %#v, %v}", r.r, r.s, r.t, r.e) + } } type runeTypeScannerTestcase struct { @@ -33,31 +50,6 @@ type runeTypeScannerTestcase struct { Exp []ReadRuneTypeResult } -func testRuneTypeScanner(t *testing.T, testcases map[string]runeTypeScannerTestcase, factory func(io.RuneScanner) runeTypeScanner) { - for tcName, tc := range testcases { - tc := tc - t.Run(tcName, func(t *testing.T) { - t.Parallel() - reader := strings.NewReader(tc.Input) - sc := factory(reader) - var exp, act []string - for _, iExp := range tc.Exp { - var iAct ReadRuneTypeResult - if iExp.s < 0 { - iAct.s = iExp.s - iAct.e = sc.UnreadRune() - } else { - iAct.r, iAct.s, iAct.t, iAct.e = sc.ReadRuneType() - } - exp = append(exp, iExp.String()) - act = append(act, iAct.String()) - } - assert.Equal(t, exp, act) - assert.Equal(t, tc.ExpRemainder, tc.Input[len(tc.Input)-reader.Len():]) - }) - } -} - func TestRuneTypeScanner(t *testing.T) { t.Parallel() testcases := map[string]runeTypeScannerTestcase{ @@ -86,7 +78,7 @@ func TestRuneTypeScanner(t *testing.T) { {'"', 1, internal.RuneTypeStringEnd, nil}, {':', 1, internal.RuneTypeObjectColon, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {0, -1, 0, nil}, + {0, unreadRune, 0, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, {'2', 1, internal.RuneTypeNumberIntDig, nil}, {'.', 1, internal.RuneTypeNumberFracDot, nil}, @@ -104,8 +96,8 @@ func TestRuneTypeScanner(t *testing.T) { {'"', 1, internal.RuneTypeStringEnd, nil}, {':', 1, internal.RuneTypeObjectColon, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {0, -1, 0, nil}, - {0, -1, 0, ErrInvalidUnreadRune}, + {0, unreadRune, 0, nil}, + {0, unreadRune, 0, ErrInvalidUnreadRune}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, {'2', 1, internal.RuneTypeNumberIntDig, nil}, {'.', 1, internal.RuneTypeNumberFracDot, nil}, @@ -128,7 +120,7 @@ func TestRuneTypeScanner(t *testing.T) { {'0', 1, internal.RuneTypeNumberFracDig, nil}, {'}', 1, internal.RuneTypeObjectEnd, nil}, {0, 0, internal.RuneTypeEOF, nil}, - {0, -1, 0, ErrInvalidUnreadRune}, + {0, unreadRune, 0, ErrInvalidUnreadRune}, {0, 0, internal.RuneTypeEOF, nil}, {0, 0, internal.RuneTypeEOF, nil}, }}, @@ -174,150 +166,103 @@ func TestRuneTypeScanner(t *testing.T) { {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 0, Err: io.EOF}}, }}, - } - testRuneTypeScanner(t, testcases, func(reader io.RuneScanner) runeTypeScanner { - return &runeTypeScannerImpl{ - inner: reader, - } - }) -} - -func TestElemRuneTypeScanner(t *testing.T) { - t.Parallel() - toplevelTestcases := map[string]runeTypeScannerTestcase{ - "basic": {`1`, ``, []ReadRuneTypeResult{ + "basic2": {`1`, ``, []ReadRuneTypeResult{ {'1', 1, internal.RuneTypeNumberIntDig, nil}, {0, 0, internal.RuneTypeEOF, nil}, {0, 0, internal.RuneTypeEOF, nil}, {0, 0, internal.RuneTypeEOF, nil}, }}, - "syntax-error": {`[[0,]`, ``, []ReadRuneTypeResult{ - {'[', 1, internal.RuneTypeArrayBeg, nil}, - {'[', 1, internal.RuneTypeArrayBeg, nil}, - {'0', 1, internal.RuneTypeNumberIntZero, nil}, - {',', 1, internal.RuneTypeArrayComma, nil}, - {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 5, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, - {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 5, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, - {']', 1, internal.RuneTypeError, &DecodeSyntaxError{Offset: 5, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}}, - }}, - "multi-value": {`1{}`, `{}`, []ReadRuneTypeResult{ + "fragment": {`1,`, ``, []ReadRuneTypeResult{ {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - {0, 0, internal.RuneTypeEOF, nil}, + {',', 1, internal.RuneTypeEOF, nil}, + {',', 1, internal.RuneTypeEOF, nil}, + {',', 1, internal.RuneTypeEOF, nil}, }}, - "fragment": {`1,`, `,`, []ReadRuneTypeResult{ + "elem": {` { "foo" : 12.0 } `, ``, []ReadRuneTypeResult{ + {'{', 1, internal.RuneTypeObjectBeg, nil}, + {'"', 1, internal.RuneTypeStringBeg, nil}, + {'f', 1, internal.RuneTypeStringChar, nil}, + {'o', 1, internal.RuneTypeStringChar, nil}, + {'o', 1, internal.RuneTypeStringChar, nil}, + {'"', 1, internal.RuneTypeStringEnd, nil}, + {':', 1, internal.RuneTypeObjectColon, nil}, + {0, pushReadBarrier, 0, nil}, {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {0, 0, internal.RuneTypeEOF, nil}, + {'2', 1, internal.RuneTypeNumberIntDig, nil}, + {'.', 1, internal.RuneTypeNumberFracDot, nil}, + {'0', 1, internal.RuneTypeNumberFracDig, nil}, + {'}', 1, internal.RuneTypeEOF, nil}, + {'}', 1, internal.RuneTypeEOF, nil}, + {0, popReadBarrier, 0, nil}, + {'}', 1, internal.RuneTypeObjectEnd, nil}, {0, 0, internal.RuneTypeEOF, nil}, {0, 0, internal.RuneTypeEOF, nil}, }}, - "early-eof": {`{`, ``, []ReadRuneTypeResult{ - {'{', 1, internal.RuneTypeObjectBeg, nil}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 1, Err: io.ErrUnexpectedEOF}}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 1, Err: io.ErrUnexpectedEOF}}, - {0, 0, internal.RuneTypeError, &DecodeSyntaxError{Offset: 1, Err: io.ErrUnexpectedEOF}}, - }}, } - - childTestcases := make(map[string]runeTypeScannerTestcase, len(toplevelTestcases)) - for tcName, tc := range toplevelTestcases { - tc.Input = `[` + tc.Input - tc.Exp = append([]ReadRuneTypeResult(nil), tc.Exp...) // copy - for i, res := range tc.Exp { - if se, ok := res.e.(*DecodeSyntaxError); ok { - seCopy := *se - seCopy.Offset++ - tc.Exp[i].e = &seCopy + func() { + childTestcases := make(map[string]runeTypeScannerTestcase) + for tcName, tc := range testcases { + canChild := true + for _, res := range tc.Exp { + if res.s == pushReadBarrier { + canChild = false + break + } } - } - childTestcases[tcName] = tc - } - - t.Run("top-level", func(t *testing.T) { - t.Parallel() - testRuneTypeScanner(t, toplevelTestcases, func(reader io.RuneScanner) runeTypeScanner { - return &elemRuneTypeScanner{ - inner: &runeTypeScannerImpl{ - inner: reader, - }, + if !canChild { + continue } - }) - }) - t.Run("child", func(t *testing.T) { - t.Parallel() - testRuneTypeScanner(t, childTestcases, func(reader io.RuneScanner) runeTypeScanner { - inner := &runeTypeScannerImpl{ - inner: reader, + tc.Input = `[1,` + tc.Input + tc.Exp = append([]ReadRuneTypeResult{ + {'[', 1, internal.RuneTypeArrayBeg, nil}, + {'1', 1, internal.RuneTypeNumberIntDig, nil}, + {',', 1, internal.RuneTypeArrayComma, nil}, + {0, pushReadBarrier, 0, nil}, + }, tc.Exp...) + for i := 2; i < len(tc.Exp); i++ { + if se, ok := tc.Exp[i].e.(*DecodeSyntaxError); ok { + seCopy := *se + seCopy.Offset += 3 + tc.Exp[i].e = &seCopy + } } - var res ReadRuneTypeResult - res.r, res.s, res.t, res.e = inner.ReadRuneType() - require.Equal(t, - ReadRuneTypeResult{'[', 1, internal.RuneTypeArrayBeg, nil}.String(), - res.String()) - - return &elemRuneTypeScanner{ - inner: inner, + childTestcases["child-"+tcName] = tc + } + for tcName, tc := range childTestcases { + testcases[tcName] = tc + } + }() + for tcName, tc := range testcases { + tc := tc + t.Run(tcName, func(t *testing.T) { + t.Parallel() + t.Logf("input=%q", tc.Input) + reader := strings.NewReader(tc.Input) + sc := &runeTypeScanner{inner: reader} + var exp, act []string + for _, iExp := range tc.Exp { + var iAct ReadRuneTypeResult + switch iExp.s { + case unreadRune: + iAct.s = iExp.s + iAct.e = sc.UnreadRune() + case pushReadBarrier: + sc.PushReadBarrier() + iAct.s = iExp.s + case popReadBarrier: + sc.PopReadBarrier() + iAct.s = iExp.s + case reset: + sc.Reset() + iAct.s = iExp.s + default: + iAct.r, iAct.s, iAct.t, iAct.e = sc.ReadRuneType() + } + exp = append(exp, iExp.String()) + act = append(act, iAct.String()) } + assert.Equal(t, exp, act) + assert.Equal(t, tc.ExpRemainder, tc.Input[len(tc.Input)-reader.Len():]) }) - }) -} - -func TestElemRuneTypeScanner2(t *testing.T) { - t.Parallel() - parent := &runeTypeScannerImpl{ - inner: strings.NewReader(` { "foo" : 12.0 } `), - } - exp := []ReadRuneTypeResult{ - {'{', 1, internal.RuneTypeObjectBeg, nil}, - {'"', 1, internal.RuneTypeStringBeg, nil}, - {'f', 1, internal.RuneTypeStringChar, nil}, - {'o', 1, internal.RuneTypeStringChar, nil}, - {'o', 1, internal.RuneTypeStringChar, nil}, - {'"', 1, internal.RuneTypeStringEnd, nil}, - {':', 1, internal.RuneTypeObjectColon, nil}, - } - expStr := make([]string, 0, len(exp)) - actStr := make([]string, 0, len(exp)) - for _, iExp := range exp { - var iAct ReadRuneTypeResult - iAct.r, iAct.s, iAct.t, iAct.e = parent.ReadRuneType() - expStr = append(expStr, iExp.String()) - actStr = append(actStr, iAct.String()) - require.Equal(t, expStr, actStr) - } - - child := &elemRuneTypeScanner{ - inner: parent, - } - exp = []ReadRuneTypeResult{ - {'1', 1, internal.RuneTypeNumberIntDig, nil}, - {'2', 1, internal.RuneTypeNumberIntDig, nil}, - {'.', 1, internal.RuneTypeNumberFracDot, nil}, - {'0', 1, internal.RuneTypeNumberFracDig, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - } - expStr, actStr = nil, nil - for _, iExp := range exp { - var iAct ReadRuneTypeResult - iAct.r, iAct.s, iAct.t, iAct.e = child.ReadRuneType() - expStr = append(expStr, iExp.String()) - actStr = append(actStr, iAct.String()) - require.Equal(t, expStr, actStr) - } - - exp = []ReadRuneTypeResult{ - {'}', 1, internal.RuneTypeObjectEnd, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - {0, 0, internal.RuneTypeEOF, nil}, - } - expStr, actStr = nil, nil - for _, iExp := range exp { - var iAct ReadRuneTypeResult - iAct.r, iAct.s, iAct.t, iAct.e = parent.ReadRuneType() - expStr = append(expStr, iExp.String()) - actStr = append(actStr, iAct.String()) - require.Equal(t, expStr, actStr) } } -- cgit v1.2.3-2-g168b