summaryrefslogtreecommitdiff
path: root/reencode_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'reencode_test.go')
-rw-r--r--reencode_test.go122
1 files changed, 121 insertions, 1 deletions
diff --git a/reencode_test.go b/reencode_test.go
index 715e976..60180c8 100644
--- a/reencode_test.go
+++ b/reencode_test.go
@@ -5,6 +5,8 @@
package lowmemjson
import (
+ "errors"
+ "io"
"strings"
"testing"
@@ -13,7 +15,7 @@ import (
"git.lukeshu.com/go/lowmemjson/internal/fastio"
)
-func TestReEncode(t *testing.T) {
+func TestEncodeReEncode(t *testing.T) {
t.Parallel()
type testcase struct {
enc ReEncoderConfig
@@ -166,6 +168,43 @@ func TestReEncode(t *testing.T) {
}
}
+func TestReEncode(t *testing.T) {
+ t.Parallel()
+ type testcase struct {
+ Cfg ReEncoderConfig
+ In string
+ ExpOut string
+ ExpWriteErr string
+ ExpCloseErr string
+ }
+ testcases := map[string]testcase{
+ "partial-utf8-replace": {Cfg: ReEncoderConfig{InvalidUTF8: InvalidUTF8Replace}, In: "\xf0\xbf", ExpOut: ``, ExpCloseErr: "json: syntax error at input byte 0: invalid character '\uFFFD' looking for beginning of value"},
+ "partial-utf8-preserve": {Cfg: ReEncoderConfig{InvalidUTF8: InvalidUTF8Preserve}, In: "\xf0\xbf", ExpOut: ``, ExpCloseErr: `json: syntax error at input byte 0: invalid character '\xf0' looking for beginning of value`},
+ "partial-utf8-error": {Cfg: ReEncoderConfig{InvalidUTF8: InvalidUTF8Error}, In: "\xf0\xbf", ExpOut: ``, ExpCloseErr: `json: syntax error at input byte 0: truncated UTF-8: "\xf0\xbf"`},
+ }
+ for tcName, tc := range testcases {
+ tc := tc
+ t.Run(tcName, func(t *testing.T) {
+ t.Parallel()
+ var out strings.Builder
+ enc := NewReEncoder(&out, tc.Cfg)
+ _, err := enc.WriteString(tc.In)
+ assert.Equal(t, tc.ExpOut, out.String())
+ if tc.ExpWriteErr == "" {
+ assert.NoError(t, err)
+ } else {
+ assert.EqualError(t, err, tc.ExpWriteErr)
+ }
+ err = enc.Close()
+ if tc.ExpCloseErr == "" {
+ assert.NoError(t, err)
+ } else {
+ assert.EqualError(t, err, tc.ExpCloseErr)
+ }
+ })
+ }
+}
+
func TestReEncodeWriteSize(t *testing.T) {
t.Parallel()
@@ -240,3 +279,84 @@ func TestReEncoderStackSize(t *testing.T) {
assert.Equal(t, i+2, enc.stackSize())
}
}
+
+var errNoSpace = errors.New("no space left on device")
+
+type limitedWriter struct {
+ Limit int
+ Inner io.Writer
+
+ n int
+}
+
+func (w *limitedWriter) Write(p []byte) (int, error) {
+ switch {
+ case w.n >= w.Limit:
+ return 0, errNoSpace
+ case w.n+len(p) > w.Limit:
+ n, err := w.Inner.Write(p[:w.Limit-w.n])
+ if n > 0 {
+ w.n += n
+ }
+ if err == nil {
+ err = errNoSpace
+ }
+ return n, err
+ default:
+ n, err := w.Inner.Write(p)
+ if n > 0 {
+ w.n += n
+ }
+ return n, err
+ }
+}
+
+func TestReEncodeIOErr(t *testing.T) {
+ t.Parallel()
+
+ input := `"😀"`
+ assert.Len(t, input, 6)
+
+ t.Run("bytes", func(t *testing.T) {
+ t.Parallel()
+
+ var out strings.Builder
+ enc := NewReEncoder(&limitedWriter{Limit: 5, Inner: &out}, ReEncoderConfig{})
+
+ n, err := enc.Write([]byte(input[:2]))
+ assert.NoError(t, err)
+ assert.Equal(t, 2, n)
+ // Of the 2 bytes "written", only one should be in
+ // `out` yet; the other should be in the UTF-8 buffer.
+ assert.Equal(t, input[:1], out.String())
+
+ n, err = enc.Write([]byte(input[2:]))
+ assert.ErrorIs(t, err, errNoSpace)
+ // Check that the byte in the UTF-8 buffer from the
+ // first .Write didn't count toward the total for this
+ // .Write.
+ assert.Equal(t, 3, n)
+ assert.Equal(t, input[:5], out.String())
+ })
+ t.Run("string", func(t *testing.T) {
+ t.Parallel()
+
+ var out strings.Builder
+ enc := NewReEncoder(&limitedWriter{Limit: 5, Inner: &out}, ReEncoderConfig{})
+
+ n, err := enc.WriteString(input[:2])
+ assert.NoError(t, err)
+ assert.Equal(t, 2, n)
+ // Of the 2 bytes "written", only one should be in
+ // `out` yet; the other should be in the UTF-8 buffer.
+ assert.Equal(t, input[:1], out.String())
+
+ n, err = enc.WriteString(input[2:])
+ assert.ErrorIs(t, err, errNoSpace)
+ // Check that the byte in the UTF-8 buffer from the
+ // first .Write didn't count toward the total for this
+ // .Write.
+ assert.Equal(t, 3, n)
+ assert.Equal(t, input[:5], out.String())
+ })
+}