mirror of
https://github.com/netbirdio/easyjson.git
synced 2026-05-22 18:44:42 -07:00
74 lines
1.7 KiB
Go
74 lines
1.7 KiB
Go
package tests
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"unsafe"
|
|
|
|
"github.com/mailru/easyjson"
|
|
)
|
|
|
|
// verifies if string pointer belongs to the given buffer or outside of it
|
|
func strBelongsTo(s string, buf []byte) bool {
|
|
sPtr := (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
|
|
bufPtr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)).Data
|
|
|
|
if bufPtr <= sPtr && sPtr < bufPtr+uintptr(len(buf)) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func TestNocopy(t *testing.T) {
|
|
data := []byte(`{"a": "valueA", "b": "valueB"}`)
|
|
exp := NocopyStruct{
|
|
A: "valueA",
|
|
B: "valueB",
|
|
}
|
|
res := NocopyStruct{}
|
|
|
|
err := easyjson.Unmarshal(data, &res)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if !reflect.DeepEqual(exp, res) {
|
|
t.Errorf("TestNocopy(): got=%+v, exp=%+v", res, exp)
|
|
}
|
|
|
|
if strBelongsTo(res.A, data) {
|
|
t.Error("TestNocopy(): field A was not copied and refers to buffer")
|
|
}
|
|
if !strBelongsTo(res.B, data) {
|
|
t.Error("TestNocopy(): field B was copied rather than refer to bufferr")
|
|
}
|
|
|
|
data = []byte(`{"b": "valueNoCopy"}`)
|
|
res = NocopyStruct{}
|
|
allocsPerRun := testing.AllocsPerRun(1000, func() {
|
|
err := easyjson.Unmarshal(data, &res)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if res.B != "valueNoCopy" {
|
|
t.Fatalf("wrong value: %q", res.B)
|
|
}
|
|
})
|
|
if allocsPerRun > 1 {
|
|
t.Fatalf("noCopy field unmarshal: expected <= 1 allocs, got %f", allocsPerRun)
|
|
}
|
|
|
|
data = []byte(`{"a": "valueNoCopy"}`)
|
|
allocsPerRun = testing.AllocsPerRun(1000, func() {
|
|
err := easyjson.Unmarshal(data, &res)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if res.A != "valueNoCopy" {
|
|
t.Fatalf("wrong value: %q", res.A)
|
|
}
|
|
})
|
|
if allocsPerRun > 2 {
|
|
t.Fatalf("copy field unmarshal: expected <= 2 allocs, got %f", allocsPerRun)
|
|
}
|
|
}
|