Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add internal tests and fix some bugs #39

Merged
merged 41 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6c976a0
add string tests
shamaton Aug 1, 2024
35822e5
add decording string tests
shamaton Aug 1, 2024
393f875
add decoding string test
shamaton Aug 2, 2024
7710f56
add decoding uint tests
shamaton Aug 2, 2024
8bbffc9
add decoding ext tests
shamaton Aug 3, 2024
4aea8d6
add decoding bool and map tests
shamaton Aug 5, 2024
f5a9a1a
add decoding complex tests
shamaton Aug 6, 2024
f70d95f
use errorTemplate in decoding/complex.go
shamaton Aug 6, 2024
8191431
add ReadCount to some testcases
shamaton Aug 6, 2024
912c5b1
fix TestComplex
shamaton Aug 6, 2024
fa57eea
add decoding interface tests
shamaton Aug 6, 2024
a201ea4
add decoding bin tests
shamaton Aug 6, 2024
2226b13
add decoding float tests, struct tests
shamaton Aug 7, 2024
3f12965
add decoding int tests
shamaton Aug 7, 2024
ed51f6b
fix some tests
shamaton Aug 7, 2024
57e5210
fix decoding int tests
shamaton Aug 7, 2024
5dc8e94
add decoding slice tests
shamaton Aug 8, 2024
62005b8
add more decoding slice tests
shamaton Aug 8, 2024
041830c
add decoding tests
shamaton Aug 9, 2024
795043d
add more decoding tests
shamaton Aug 9, 2024
597e18f
fix decoding tests
shamaton Aug 9, 2024
eac8243
define error valiables in def package
shamaton Aug 10, 2024
0097937
fix stream decoding tests
shamaton Aug 10, 2024
5ac2f33
add test helper adn bin tests
shamaton Aug 10, 2024
7155d37
fix bugs and add decoding tests
shamaton Aug 15, 2024
9f8997d
fix test cases
shamaton Aug 15, 2024
d79d112
use error definitions
shamaton Aug 15, 2024
8c48060
add encoding bool, int tests
shamaton Aug 22, 2024
1671bb8
fix print format error
shamaton Aug 22, 2024
85865ed
add encoding map, slice tests
shamaton Aug 22, 2024
e6c3a73
add encording primitive type tests
shamaton Aug 23, 2024
bf52e78
add encoding main, ext tests
shamaton Aug 23, 2024
ab6c756
add encoding struct tests
shamaton Aug 24, 2024
5848d6a
remove testutil from coverage
shamaton Aug 24, 2024
80b3e74
add encoding tests
shamaton Aug 24, 2024
fbac5d3
add common test
shamaton Aug 25, 2024
dbef5c6
add msgpack.Error
shamaton Aug 25, 2024
90d8baa
change from ErrUnsupported to ErrUnsupportedType
shamaton Aug 25, 2024
ea02dc3
add def.ErrUnsupportedLength as a error definition
shamaton Aug 25, 2024
69ee43d
fix testcase logic in stream decoding
shamaton Aug 26, 2024
aaf2f86
fix gosimple, govet
shamaton Aug 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ jobs:
run: go build -v ./...

- name: Test
run: go test -v --coverpkg=github.com/shamaton/msgpack/... --coverprofile=coverage.coverprofile --covermode=atomic ./...
run: go test -v --coverpkg=github.com/shamaton/msgpack/... --coverprofile=coverage.coverprofile.tmp --covermode=atomic ./...

- name: Remove testutil from coverage
shell: bash
run: |
cat coverage.coverprofile.tmp | grep -v testutil > coverage.coverprofile
rm coverage.coverprofile.tmp

- name: Upload coverage to Codecov
if: success() && matrix.go == '1.22' && matrix.os == 'ubuntu-latest'
Expand Down
31 changes: 31 additions & 0 deletions def/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package def

import (
"errors"
"fmt"
)

var (
// base errors

ErrMsgpack = errors.New("")

// decoding errors

ErrNoData = fmt.Errorf("%wno data", ErrMsgpack)
ErrHasLeftOver = fmt.Errorf("%wdata has left over", ErrMsgpack)
ErrReceiverNotPointer = fmt.Errorf("%wreceiver not pointer", ErrMsgpack)
ErrNotMatchArrayElement = fmt.Errorf("%wnot match array element", ErrMsgpack)
ErrCanNotDecode = fmt.Errorf("%winvalid code", ErrMsgpack)
ErrCanNotSetSliceAsMapKey = fmt.Errorf("%wcan not set slice as map key", ErrMsgpack)
ErrCanNotSetMapAsMapKey = fmt.Errorf("%wcan not set map as map key", ErrMsgpack)

// encoding errors

ErrTooShortBytes = fmt.Errorf("%wtoo short bytes", ErrMsgpack)
ErrLackDataLengthToSlice = fmt.Errorf("%wdata length lacks to create slice", ErrMsgpack)
ErrLackDataLengthToMap = fmt.Errorf("%wdata length lacks to create map", ErrMsgpack)
ErrUnsupportedType = fmt.Errorf("%wunsupported type", ErrMsgpack)
ErrUnsupportedLength = fmt.Errorf("%wunsupported length", ErrMsgpack)
ErrNotMatchLastIndex = fmt.Errorf("%wnot match last index", ErrMsgpack)
)
8 changes: 8 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package msgpack

import (
"github.com/shamaton/msgpack/v2/def"
)

// Error is used in all msgpack error as the based error.
var Error = def.ErrMsgpack
2 changes: 1 addition & 1 deletion internal/common/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ type Buffer struct {
func (b *Buffer) Write(w io.Writer, vs ...byte) error {
if len(b.Data) < b.offset+len(vs) {
_, err := w.Write(b.Data[:b.offset])
b.offset = 0
if err != nil {
return err
}
if len(b.Data) < len(vs) {
b.Data = append(b.Data, make([]byte, len(vs)-len(b.Data))...)
}
b.offset = 0
}
for i := range vs {
b.Data[b.offset+i] = vs[i]
Expand Down
48 changes: 48 additions & 0 deletions internal/common/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package common

import (
"reflect"
"testing"

tu "github.com/shamaton/msgpack/v2/internal/common/testutil"
)

func TestCommon_CheckField(t *testing.T) {
common := Common{}

t.Run("tag:-", func(t *testing.T) {
field := reflect.StructField{
Name: "A",
Tag: `msgpack:"-"`,
}
b, v := common.CheckField(field)
tu.Equal(t, b, false)
tu.Equal(t, v, "")
})
t.Run("tag:B", func(t *testing.T) {
field := reflect.StructField{
Name: "A",
Tag: `msgpack:"B"`,
}
b, v := common.CheckField(field)
tu.Equal(t, b, true)
tu.Equal(t, v, "B")
})
t.Run("name:A", func(t *testing.T) {
field := reflect.StructField{
Name: "A",
Tag: `msgpack:""`,
}
b, v := common.CheckField(field)
tu.Equal(t, b, true)
tu.Equal(t, v, "A")
})
t.Run("private", func(t *testing.T) {
field := reflect.StructField{
Name: "a",
}
b, v := common.CheckField(field)
tu.Equal(t, b, false)
tu.Equal(t, v, "")
})
}
42 changes: 42 additions & 0 deletions internal/common/testutil/reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package testutil

import (
"errors"
"io"
)

var ErrReaderErr = errors.New("reader error")

type ErrReader struct{}

func NewErrReader() *ErrReader {
return &ErrReader{}
}

func (ErrReader) Read(_ []byte) (int, error) {
return 0, ErrReaderErr
}

type TestReader struct {
s []byte
i int64 // current reading index
count int
}

func NewTestReader(b []byte) *TestReader {
return &TestReader{s: b, i: 0, count: 0}
}

func (r *TestReader) Read(b []byte) (n int, err error) {
if r.i >= int64(len(r.s)) {
return 0, io.EOF
}
n = copy(b, r.s[r.i:])
r.i += int64(n)
r.count++
return
}

func (r *TestReader) Count() int {
return r.count
}
56 changes: 56 additions & 0 deletions internal/common/testutil/struct.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package testutil

import (
"math"
"reflect"
"strconv"

"github.com/shamaton/msgpack/v2/def"
)

// CreateStruct returns a struct that is made dynamically and encoded bytes.
func CreateStruct(fieldNum int) (v any, asMapBytes []byte, asArrayBytes []byte) {
if fieldNum < 0 {
panic("negative field number")
}

fields := make([]reflect.StructField, 0, fieldNum)
asMapBytes = make([]byte, 0, fieldNum*2)
asArrayBytes = make([]byte, 0, fieldNum)

for i := 0; i < fieldNum; i++ {
// create struct field
name := "A" + strconv.Itoa(i)
typ := reflect.TypeOf(1)
field := reflect.StructField{
Name: name,
Type: typ,
Tag: `json:"B"`,
}
fields = append(fields, field)

// set encoded bytes
if len(name) < 32 {
asMapBytes = append(asMapBytes, def.FixStr+byte(len(name)))
} else if len(name) < math.MaxUint8 {
asMapBytes = append(asMapBytes, def.Str8)
asMapBytes = append(asMapBytes, byte(len(name)))
}
for _, c := range name {
asMapBytes = append(asMapBytes, byte(c))
}
value := byte(i % 0x7f)
asMapBytes = append(asMapBytes, value)
asArrayBytes = append(asArrayBytes, value)
}
t := reflect.StructOf(fields)

// set field values
v = reflect.New(t).Interface()
rv := reflect.ValueOf(v)
for i := 0; i < rv.Elem().NumField(); i++ {
field := rv.Elem().Field(i)
field.SetInt(int64(i % 0x7f))
}
return v, asMapBytes, asArrayBytes
}
93 changes: 93 additions & 0 deletions internal/common/testutil/testutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package testutil

import (
"errors"
"reflect"
"strings"
"testing"
)

func NoError(t *testing.T, err error) {
t.Helper()
if err != nil {
t.Fatalf("error is not nil: %v", err)
}
}

func Error(t *testing.T, err error) {
t.Helper()
if err == nil {
t.Fatal(err)
}
}

func IsError(t *testing.T, actual, expected error) {
t.Helper()
if !errors.Is(actual, expected) {
t.Fatalf("not equal. actual: %v, expected: %v", actual, expected)
}
}

func ErrorContains(t *testing.T, err error, errStr string) {
t.Helper()
if err == nil {
t.Fatal("error should occur")
}
if !strings.Contains(err.Error(), errStr) {
t.Fatalf("error does not contain '%s'. err: %v", errStr, err)
}
}

func Equal[T any](t *testing.T, actual, expected T) {
t.Helper()
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("not equal. actual: %v, expected: %v", actual, expected)
}
}

func EqualSlice[T comparable](t *testing.T, actual, expected []T) {
t.Helper()
if len(actual) != len(expected) {
switch a := any(actual).(type) {
case []byte:
e := any(expected).([]byte)
t.Fatalf("diffrent length. actual: [% 02x], expected: [% 02x]", a, e)
default:
t.Fatalf("diffrent length. actual: %v, expected: %v", actual, expected)
}
}
for i := range actual {
if !reflect.DeepEqual(actual[i], expected[i]) {
switch a := any(actual).(type) {
case []byte:
e := any(expected).([]byte)
t.Fatalf("not equal. actual: [% 02x], expected: [% 02x]", a, e)
default:
t.Fatalf("not equal. actual: %v, expected: %v", actual, expected)
}
}
}
}

func EqualMap[K comparable, V comparable](t *testing.T, actual, expected map[K]V) {
t.Helper()
if len(actual) != len(expected) {
t.Fatalf("diffrent length. actual: %v, expected: %v", actual, expected)
}
for k, v1 := range actual {
if v2, ok := expected[k]; !ok || v1 != v2 {
t.Fatalf("not equal. actual: %v, expected: %v", actual, expected)
}
}
}

type Equaler[T any] interface {
Equal(other T) bool
}

func EqualEqualer[T Equaler[T]](t *testing.T, actual, expected T) {
t.Helper()
if !actual.Equal(expected) {
t.Fatalf("not equal. actual: %v, expected: %v", actual, expected)
}
}
21 changes: 15 additions & 6 deletions internal/decoding/bin.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,31 @@ func (d *decoder) asBin(offset int, k reflect.Kind) ([]byte, int, error) {
if err != nil {
return emptyBytes, 0, err
}
o := offset + int(uint8(l))
return d.data[offset:o], o, nil
v, offset, err := d.readSizeN(offset, int(uint8(l)))
if err != nil {
return emptyBytes, 0, err
}
return v, offset, nil
case def.Bin16:
bs, offset, err := d.readSize2(offset)
o := offset + int(binary.BigEndian.Uint16(bs))
if err != nil {
return emptyBytes, 0, err
}
return d.data[offset:o], o, nil
v, offset, err := d.readSizeN(offset, int(binary.BigEndian.Uint16(bs)))
if err != nil {
return emptyBytes, 0, err
}
return v, offset, nil
case def.Bin32:
bs, offset, err := d.readSize4(offset)
o := offset + int(binary.BigEndian.Uint32(bs))
if err != nil {
return emptyBytes, 0, err
}
return d.data[offset:o], o, nil
v, offset, err := d.readSizeN(offset, int(binary.BigEndian.Uint32(bs)))
if err != nil {
return emptyBytes, 0, err
}
return v, offset, nil
}

return emptyBytes, 0, d.errorTemplate(code, k)
Expand Down
Loading
Loading