Skip to content

Commit

Permalink
test: add streaming encoding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tdakkota committed Jan 31, 2023
1 parent 959c294 commit b5865f5
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 174 deletions.
39 changes: 20 additions & 19 deletions enc_b64_test.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
package jx

import (
"encoding/base64"
"bytes"
"fmt"
"testing"

"github.com/stretchr/testify/require"
)

func TestEncoder_Base64(t *testing.T) {
t.Run("Values", func(t *testing.T) {
for _, s := range [][]byte{
for i, s := range [][]byte{
[]byte(`1`),
[]byte(`12`),
[]byte(`2345`),
{1, 2, 3, 4, 5, 6},
} {
var e Encoder
e.Base64(s)

expected := fmt.Sprintf("%q", base64.StdEncoding.EncodeToString(s))
require.Equal(t, expected, e.String())

requireCompat(t, e.Bytes(), s)
bytes.Repeat([]byte{1}, encoderBufSize-1),
bytes.Repeat([]byte{1}, encoderBufSize),
bytes.Repeat([]byte{1}, encoderBufSize+1),
} {
s := s
t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
requireCompat(t, func(e *Encoder) {
e.Base64(s)
}, s)
})
}
})
t.Run("Zeroes", func(t *testing.T) {
t.Run("Nil", func(t *testing.T) {
v := []byte(nil)
var e Encoder
e.Base64(v)
requireCompat(t, e.Bytes(), v)
s := []byte(nil)
requireCompat(t, func(e *Encoder) {
e.Base64(s)
}, s)
})
t.Run("ZeroLen", func(t *testing.T) {
v := make([]byte, 0)
var e Encoder
e.Base64(v)
requireCompat(t, e.Bytes(), v)
s := make([]byte, 0)
requireCompat(t, func(e *Encoder) {
e.Base64(s)
}, s)
})
})
}
Expand Down
60 changes: 35 additions & 25 deletions enc_str_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package jx
import (
"encoding/json"
"fmt"
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -21,25 +22,31 @@ func TestEncoder_Str(t *testing.T) {
{"\x00"},
{"\x00 "},
{`"hello, world!"`},

{strings.Repeat("a", encoderBufSize)},
}
for i, tt := range testCases {
tt := tt
t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
for _, enc := range []struct {
name string
enc func(e *Encoder, input string)
enc func(e *Encoder, input string) bool
}{
{"Str", (*Encoder).Str},
{"Bytes", func(e *Encoder, input string) {
e.ByteStr([]byte(tt.input))
{"Bytes", func(e *Encoder, input string) bool {
return e.ByteStr([]byte(tt.input))
}},
} {
enc := enc
t.Run(enc.name, func(t *testing.T) {
e := GetEncoder()
enc.enc(e, tt.input)
requireCompat(t, e.Bytes(), tt.input)
requireCompat(t, func(e *Encoder) {
enc.enc(e, tt.input)
}, tt.input)

t.Run("Decode", func(t *testing.T) {
e := GetEncoder()
enc.enc(e, tt.input)

i := GetDecoder()
i.ResetBytes(e.Bytes())
s, err := i.Str()
Expand All @@ -54,27 +61,31 @@ func TestEncoder_Str(t *testing.T) {
const (
v = "\"/\""
)
var e Encoder
e.Str(v)
requireCompat(t, e.Bytes(), v)
requireCompat(t, func(e *Encoder) {
e.StrEscape(v)
}, v)
})
t.Run("QuotesObj", func(t *testing.T) {
const (
k = "k"
v = "\"/\""
)

cb := func(e *Encoder) {
e.ObjStart()
e.FieldStart(k)
e.Str(v)
e.ObjEnd()
t.Log(e)
}

var e Encoder
e.ObjStart()
e.FieldStart(k)
e.Str(v)
e.ObjEnd()
t.Log(e)
cb(&e)

var target map[string]string
require.NoError(t, json.Unmarshal(e.Bytes(), &target))
assert.Equal(t, v, target[k])
requireCompat(t, e.Bytes(), map[string]string{k: v})
requireCompat(t, cb, map[string]string{k: v})
})
}

Expand All @@ -96,19 +107,18 @@ func TestEncoder_StrEscape(t *testing.T) {
t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
for _, enc := range []struct {
name string
enc func(e *Encoder, input string)
enc func(e *Encoder, input string) bool
}{
{"Str", (*Encoder).StrEscape},
{"Bytes", func(e *Encoder, input string) {
e.ByteStrEscape([]byte(tt.input))
{"Bytes", func(e *Encoder, input string) bool {
return e.ByteStrEscape([]byte(tt.input))
}},
} {
enc := enc
t.Run(enc.name, func(t *testing.T) {
e := GetEncoder()
enc.enc(e, tt.input)
require.Equal(t, tt.expect, string(e.Bytes()))
requireCompat(t, e.Bytes(), tt.input)
requireCompat(t, func(e *Encoder) {
enc.enc(e, tt.input)
}, tt.input)
})
}
})
Expand All @@ -117,8 +127,8 @@ func TestEncoder_StrEscape(t *testing.T) {
const (
v = "\"/\""
)
var e Encoder
e.StrEscape(v)
requireCompat(t, e.Bytes(), v)
requireCompat(t, func(e *Encoder) {
e.StrEscape(v)
}, v)
})
}
103 changes: 103 additions & 0 deletions enc_stream_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package jx

import (
"io"
"strings"
"testing"

"github.com/stretchr/testify/require"

"github.com/go-faster/errors"
)

func TestEncoderStreamingCheck(t *testing.T) {
a := require.New(t)

e := NewStreamingEncoder(io.Discard, 512)

_, err := e.Write([]byte("hello"))
a.ErrorIs(err, errStreaming)

_, err = e.WriteTo(io.Discard)
a.ErrorIs(err, errStreaming)

a.PanicsWithError(errStreaming.Error(), func() {
_ = e.String()
})
}

type errWriter struct {
err error
n int
}

func (e *errWriter) Write(p []byte) (int, error) {
n := e.n
if n <= 0 {
n = len(p)
}
return n, e.err
}

func TestEncoder_Close(t *testing.T) {
errTest := errors.New("test")

t.Run("FlushErr", func(t *testing.T) {
ew := &errWriter{err: errTest}
e := NewStreamingEncoder(ew, -1)
e.Null()

require.ErrorIs(t, e.Close(), errTest)
})
t.Run("WriteErr", func(t *testing.T) {
ew := &errWriter{err: errTest}
e := NewStreamingEncoder(ew, 32)
e.Obj(func(e *Encoder) {
e.FieldStart(strings.Repeat("a", 32))
e.Null()
})

require.ErrorIs(t, e.Close(), errTest)
})
t.Run("ShortWrite", func(t *testing.T) {
ew := &errWriter{n: 1}
e := NewStreamingEncoder(ew, -1)
e.Null()

require.ErrorIs(t, e.Close(), io.ErrShortWrite)
})
t.Run("OK", func(t *testing.T) {
e := NewStreamingEncoder(io.Discard, -1)
e.Null()

require.NoError(t, e.Close())
})
t.Run("NoStreaming", func(t *testing.T) {
var e Encoder
e.Null()

require.NoError(t, e.Close())
})
}

func TestEncoder_ResetWriter(t *testing.T) {
do := func(e *Encoder) {
e.ObjStart()
e.FieldStart(strings.Repeat("a", 32))
e.Null()
e.ObjEnd()

require.NoError(t, e.Close())
}

var e Encoder
do(&e)
expected := e.String()

for range [3]struct{}{} {
var got strings.Builder
e.ResetWriter(&got)
do(&e)
require.Equal(t, expected, got.String())
}
}
Loading

0 comments on commit b5865f5

Please sign in to comment.