blob: 8fb1e2f8b47528a85f29176ddaf7eab34d7c5e8f [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build newvdltests
package vom
import (
"fmt"
"reflect"
"strings"
"testing"
"v.io/v23/vdl"
"v.io/v23/vom/vomtest"
)
func TestDecoderNew(t *testing.T) {
for _, test := range vomtest.Data() {
// Decode hex patterns into binary data.
binversion := string([]byte{test.Version})
bintype, err := binFromHexPat(test.HexType)
if err != nil {
t.Errorf("%s: couldn't convert to binary from hextype: %q", test.Name, test.HexType)
continue
}
binvalue, err := binFromHexPat(test.HexValue)
if err != nil {
t.Errorf("%s: couldn't convert to binary from hexvalue: %q", test.Name, test.HexValue)
continue
}
vdlValue := vdl.ValueOf(test.Value)
name := test.Name + " [vdl.Value]"
testDecodeVDLNew(t, name, binversion+bintype+binvalue, vdlValue)
name = test.Name + " [vdl.Value] (with TypeDecoder)"
testDecodeVDLWithTypeDecoderNew(t, name, binversion, bintype, binvalue, vdlValue)
name = test.Name + " [vdl.Any]"
testDecodeVDLNew(t, name, binversion+bintype+binvalue, vdl.AnyValue(vdlValue))
name = test.Name + " [vdl.Any] (with TypeDecoder)"
testDecodeVDLWithTypeDecoderNew(t, name, binversion, bintype, binvalue, vdl.AnyValue(vdlValue))
// Convert in
name = test.Name + " [go value]"
testDecodeGoNew(t, name, binversion+bintype+binvalue, reflect.TypeOf(test.Value), test.Value)
name = test.Name + " [go value] (with TypeDecoder)"
testDecodeGoWithTypeDecoderNew(t, name, binversion, bintype, binvalue, reflect.TypeOf(test.Value), test.Value)
name = test.Name + " [go interface]"
testDecodeGoNew(t, name, binversion+bintype+binvalue, reflect.TypeOf((*interface{})(nil)).Elem(), test.Value)
name = test.Name + " [go interface] (with TypeDecoder)"
testDecodeGoWithTypeDecoderNew(t, name, binversion, bintype, binvalue, reflect.TypeOf((*interface{})(nil)).Elem(), test.Value)
}
}
func testDecodeVDLNew(t *testing.T, name, bin string, value *vdl.Value) {
for _, mode := range allReadModes {
head := fmt.Sprintf("%s (%s)", name, mode)
decoder := NewXDecoder(mode.testReader(strings.NewReader(bin)))
if value == nil {
value = vdl.ZeroValue(vdl.AnyType)
}
got := vdl.ZeroValue(value.Type())
if err := decoder.Decode(got); err != nil {
t.Errorf("%s: Decode failed: %v", head, err)
return
}
if want := value; !vdl.EqualValue(got, want) {
t.Errorf("%s: Decode mismatch\nGOT %v\nWANT %v", head, got, want)
return
}
}
// Test single-shot vom.Decode twice, to ensure we test the cache hit case.
testDecodeVDLSingleShotNew(t, name, bin, value)
testDecodeVDLSingleShotNew(t, name, bin, value)
}
func testDecodeVDLSingleShotNew(t *testing.T, name, bin string, value *vdl.Value) {
// Test the single-shot vom.Decode.
head := fmt.Sprintf("%s (single-shot)", name)
got := vdl.ZeroValue(value.Type())
if err := XDecode([]byte(bin), got); err != nil {
t.Errorf("%s: Decode failed: %v", head, err)
return
}
if want := value; !vdl.EqualValue(got, want) {
t.Errorf("%s: Decode mismatch\nGOT %v\nWANT %v", head, got, want)
return
}
}
func testDecodeVDLWithTypeDecoderNew(t *testing.T, name, binversion, bintype, binvalue string, value *vdl.Value) {
for _, mode := range allReadModes {
head := fmt.Sprintf("%s (%s)", name, mode)
typedec := NewTypeDecoder(mode.testReader(strings.NewReader(binversion + bintype)))
typedec.Start()
decoder := NewXDecoderWithTypeDecoder(mode.testReader(strings.NewReader(binversion+binvalue)), typedec)
if value == nil {
value = vdl.ZeroValue(vdl.AnyType)
}
got := vdl.ZeroValue(value.Type())
if err := decoder.Decode(got); err != nil {
t.Errorf("%s: Decode failed: %v", head, err)
return
}
if want := value; !vdl.EqualValue(got, want) {
t.Errorf("%s: Decode mismatch\nGOT %v\nWANT %v", head, got, want)
return
}
typedec.Stop()
}
}
func testDecodeGoNew(t *testing.T, name, bin string, rt reflect.Type, want interface{}) {
for _, mode := range allReadModes {
head := fmt.Sprintf("%s (%s)", name, mode)
decoder := NewXDecoder(mode.testReader(strings.NewReader(bin)))
var got interface{}
if rt != nil {
got = reflect.New(rt).Elem().Interface()
}
if err := decoder.Decode(&got); err != nil {
t.Errorf("%s: Decode failed: %v", head, err)
return
}
if !vdl.DeepEqual(got, want) {
t.Errorf("%s: Decode mismatch\nGOT %T %+v\nWANT %T %+v", head, got, got, want, want)
return
}
}
// Test single-shot vom.Decode twice, to ensure we test the cache hit case.
testDecodeGoSingleShotNew(t, name, bin, rt, want)
testDecodeGoSingleShotNew(t, name, bin, rt, want)
}
func testDecodeGoSingleShotNew(t *testing.T, name, bin string, rt reflect.Type, want interface{}) {
head := fmt.Sprintf("%s (single-shot)", name)
var got interface{}
if rt != nil {
got = reflect.New(rt).Elem().Interface()
}
if err := XDecode([]byte(bin), &got); err != nil {
t.Errorf("%s: Decode failed: %v", head, err)
return
}
if !vdl.DeepEqual(got, want) {
t.Errorf("%s: Decode mismatch\nGOT %T %+v\nWANT %T %+v", head, got, got, want, want)
return
}
}
func testDecodeGoWithTypeDecoderNew(t *testing.T, name, binversion, bintype, binvalue string, rt reflect.Type, want interface{}) {
for _, mode := range allReadModes {
head := fmt.Sprintf("%s (%s)", name, mode)
typedec := NewTypeDecoder(mode.testReader(strings.NewReader(binversion + bintype)))
typedec.Start()
decoder := NewXDecoderWithTypeDecoder(mode.testReader(strings.NewReader(binversion+binvalue)), typedec)
var got interface{}
if rt != nil {
got = reflect.New(rt).Elem().Interface()
}
if err := decoder.Decode(&got); err != nil {
t.Errorf("%s: Decode failed: %v", head, err)
return
}
if !vdl.DeepEqual(got, want) {
t.Errorf("%s: Decode mismatch\nGOT %T %+v\nWANT %T %+v", head, got, got, want, want)
return
}
typedec.Stop()
}
}