diff options
-rw-r--r-- | reencode.go | 23 | ||||
-rw-r--r-- | reencode_test.go | 131 |
2 files changed, 129 insertions, 25 deletions
diff --git a/reencode.go b/reencode.go index e781c03..e7030f8 100644 --- a/reencode.go +++ b/reencode.go @@ -214,19 +214,25 @@ func (enc *ReEncoder) handleRune(c rune, t RuneType) error { } } } else { // speculating + + // conCompress is whether we're 1-up from the leaf; + // set this *before* the calls to .handleRune. + canCompress := enc.handleRuneState.specu.indentFmt.handleRuneState.specu == nil + if err := enc.handleRuneState.specu.compactFmt.handleRune(c, t); err != nil { return err } if err := enc.handleRuneState.specu.indentFmt.handleRune(c, t); err != nil { return err } + switch { case enc.handleRuneState.specu.compactBuf.Len() >= enc.CompactIfUnder: // stop speculating; use indent if _, err := enc.handleRuneState.specu.indentBuf.WriteTo(enc.Out); err != nil { return err } enc.handleRuneState = enc.handleRuneState.specu.indentFmt.handleRuneState - case t == RuneTypeObjectEnd || t == RuneTypeArrayEnd: // stop speculating; use compact + case canCompress && (t == RuneTypeObjectEnd || t == RuneTypeArrayEnd): // stop speculating; use compact if _, err := enc.handleRuneState.specu.compactBuf.WriteTo(enc.Out); err != nil { return err } @@ -311,10 +317,8 @@ func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { case enc.Indent != "": switch t { case RuneTypeSpace: - // let us manage whitespace + // let us manage whitespace, don't pass it through return nil, false - case RuneTypeObjectBeg, RuneTypeArrayBeg: - enc.handleRuneState.curIndent++ case RuneTypeObjectEnd, RuneTypeArrayEnd: enc.handleRuneState.curIndent-- switch enc.handleRuneState.lastNonSpace { @@ -331,11 +335,14 @@ func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { if err := enc.emitNlIndent(); err != nil { return err, false } + case RuneTypeObjectColon: + if err := enc.emitByte(' '); err != nil { + return err, false + } } - } - if enc.handleRuneState.lastNonSpace == RuneTypeObjectColon { - if err := enc.emitByte(' '); err != nil { - return err, false + switch t { + case RuneTypeObjectBeg, RuneTypeArrayBeg: + enc.handleRuneState.curIndent++ } } } diff --git a/reencode_test.go b/reencode_test.go index 8886432..7f1634f 100644 --- a/reencode_test.go +++ b/reencode_test.go @@ -11,26 +11,123 @@ import ( "github.com/stretchr/testify/assert" ) -func TestReEncodeCompactIfUnder(t *testing.T) { - var out strings.Builder - enc := NewEncoder(&ReEncoder{ - Out: &out, - AllowMultipleValues: true, - Indent: "\t", - CompactIfUnder: 10, - }) - - obj := map[string][]string{ - "a": {"b", "c"}, - "d": {"eeeeeeeeeeeeeee"}, +func TestReEncode(t *testing.T) { + type testcase struct { + enc ReEncoder + in any + exp string } - - assert.NoError(t, enc.Encode(obj)) - exp := `{ + testcases := map[string]testcase{ + "basic": { + enc: ReEncoder{ + Indent: "\t", + CompactIfUnder: 10, + }, + in: map[string][]string{ + "a": {"b", "c"}, + "d": {"eeeeeeeeeeeeeee"}, + }, + exp: `{ "a": ["b","c"], "d": [ "eeeeeeeeeeeeeee" ] -}` - assert.Equal(t, exp, out.String()) +}`, + }, + "arrays1": { + enc: ReEncoder{ + Indent: "\t", + CompactIfUnder: 10, + ForceTrailingNewlines: true, + }, + in: []any{ + map[string]any{ + "generation": 123456, + }, + map[string]any{ + "a": 1, + }, + map[string]any{ + "generation": 7891011213, + }, + }, + exp: `[ + { + "generation": 123456 + }, + {"a":1}, + { + "generation": 7891011213 + } +] +`, + }, + "arrays2": { + enc: ReEncoder{ + Indent: "\t", + CompactIfUnder: 10, + ForceTrailingNewlines: true, + }, + in: []any{ + map[string]any{ + "a": 1, + }, + map[string]any{ + "generation": 123456, + }, + map[string]any{ + "generation": 7891011213, + }, + }, + exp: `[ + {"a":1}, + { + "generation": 123456 + }, + { + "generation": 7891011213 + } +] +`, + }, + "arrays3": { + enc: ReEncoder{ + Indent: "\t", + ForceTrailingNewlines: true, + }, + in: []any{ + map[string]any{ + "a": 1, + }, + map[string]any{ + "generation": 123456, + }, + map[string]any{ + "generation": 7891011213, + }, + }, + exp: `[ + { + "a": 1 + }, + { + "generation": 123456 + }, + { + "generation": 7891011213 + } +] +`, + }, + } + for tcName, tc := range testcases { + t.Run(tcName, func(t *testing.T) { + var out strings.Builder + fmter := tc.enc + fmter.Out = &out + enc := NewEncoder(&fmter) + assert.NoError(t, enc.Encode(tc.in)) + assert.Equal(t, tc.exp, out.String()) + }) + } } |