blob: 4b61ef0e77eac0691781f4e80d18112f08abbd0a [file] [log] [blame]
// Copyright 2016 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 reflectdecoder
package vdl_test
import (
"testing"
"fmt"
"reflect"
"v.io/v23/vdl"
"v.io/v23/verror"
"v.io/v23/vom/testdata/data81"
)
// Tests ReflectDecoder using ValueRead.
func TestReflectDecoder(t *testing.T) {
for _, test := range data81.Tests {
out := vdl.ZeroValue(test.Value.Type())
goValue, err := toGoValue(test.Value)
if err != nil {
t.Errorf("%s: error in toGoValue: %v", test.Name, err)
continue
}
dec := vdl.NewReflectDecoder(reflect.ValueOf(goValue))
if err := out.VDLRead(dec); err != nil {
t.Errorf("%s: error in ValueRead: %v", test.Name, err)
continue
}
if !vdl.EqualValue(test.Value, out) {
t.Errorf("%s: got %v, want %v", test.Name, out, test.Value)
}
}
}
func toGoValue(value *vdl.Value) (interface{}, error) {
if value == nil {
return nil, nil
}
if value.Kind() == vdl.Any {
return nil, nil
}
rt := vdl.TypeToReflect(value.Type())
if rt == nil {
return reflect.Value{}, fmt.Errorf("TypeToReflect(%v) failed", value.Type())
}
rv := reflect.New(rt)
if err := vdl.Convert(rv.Interface(), value); err != nil {
return reflect.Value{}, fmt.Errorf("vdl.Convert(%T, %v) failed: %v", rt, value, err)
}
return rv.Elem().Interface(), nil
}
type interfaceStructAny struct {
Any interface{}
}
// Tests ReflectDecoder with a non-empty any inside of an interface.
func TestReflectDecoderInterfaceAny(t *testing.T) {
dec := vdl.NewReflectDecoder(reflect.ValueOf(interfaceStructAny{true}))
if err := dec.StartValue(); err != nil {
t.Fatalf("error in StartValue: %v", err)
}
switch name, err := dec.NextField(); {
case err != nil:
t.Fatalf("error in NextField: %v", err)
case name != "Any":
t.Errorf("incorrect field name. got %q, want %q", name, "Any")
}
if err := dec.StartValue(); err != nil {
t.Fatalf("error in StartValue: %v", err)
}
if got, want := dec.Type(), vdl.BoolType; got != want {
t.Errorf("got %v, want %v", got, want)
}
if got, want := dec.IsAny(), true; got != want {
t.Errorf("got %v, want %v", got, want)
}
if got, want := dec.IsNil(), false; got != want {
t.Errorf("got %v, want %v", got, want)
}
switch val, err := dec.DecodeBool(); {
case err != nil:
t.Fatalf("error in DecodeBool: %v", err)
case val != true:
t.Errorf("got %v, want %v", val, true)
}
if err := dec.FinishValue(); err != nil {
t.Fatalf("error in FinishValue: %v", err)
}
if err := dec.FinishValue(); err != nil {
t.Fatalf("error in FinishValue: %v", err)
}
}