2019-03-14 00:06:42 +00:00
package proto_test
import (
"bytes"
"fmt"
"reflect"
"testing"
protoV1 "github.com/golang/protobuf/proto"
"github.com/golang/protobuf/v2/proto"
"github.com/google/go-cmp/cmp"
2019-04-07 19:43:10 +00:00
test3pb "github.com/golang/protobuf/v2/internal/testprotos/test3"
2019-03-14 00:06:42 +00:00
)
func TestEncode ( t * testing . T ) {
for _ , test := range testProtos {
for _ , want := range test . decodeTo {
t . Run ( fmt . Sprintf ( "%s (%T)" , test . desc , want ) , func ( t * testing . T ) {
2019-04-03 19:17:24 +00:00
opts := proto . MarshalOptions {
AllowPartial : test . partial ,
}
wire , err := opts . Marshal ( want )
2019-03-14 00:06:42 +00:00
if err != nil {
2019-03-27 16:23:20 +00:00
t . Fatalf ( "Marshal error: %v\nMessage:\n%v" , err , marshalText ( want ) )
}
size := proto . Size ( want )
if size != len ( wire ) {
t . Errorf ( "Size and marshal disagree: Size(m)=%v; len(Marshal(m))=%v\nMessage:\n%v" , size , len ( wire ) , marshalText ( want ) )
2019-03-14 00:06:42 +00:00
}
got := reflect . New ( reflect . TypeOf ( want ) . Elem ( ) ) . Interface ( ) . ( proto . Message )
2019-04-03 19:17:24 +00:00
uopts := proto . UnmarshalOptions {
AllowPartial : test . partial ,
}
if err := uopts . Unmarshal ( wire , got ) ; err != nil {
2019-03-14 00:06:42 +00:00
t . Errorf ( "Unmarshal error: %v\nMessage:\n%v" , err , protoV1 . MarshalTextString ( want . ( protoV1 . Message ) ) )
return
}
2019-04-03 19:17:24 +00:00
if test . invalidExtensions {
// Equal doesn't work on messages containing invalid extension data.
return
}
2019-03-14 00:06:42 +00:00
if ! protoV1 . Equal ( got . ( protoV1 . Message ) , want . ( protoV1 . Message ) ) {
t . Errorf ( "Unmarshal returned unexpected result; got:\n%v\nwant:\n%v" , protoV1 . MarshalTextString ( got . ( protoV1 . Message ) ) , protoV1 . MarshalTextString ( want . ( protoV1 . Message ) ) )
}
} )
}
}
}
func TestEncodeDeterministic ( t * testing . T ) {
for _ , test := range testProtos {
for _ , want := range test . decodeTo {
t . Run ( fmt . Sprintf ( "%s (%T)" , test . desc , want ) , func ( t * testing . T ) {
2019-04-03 19:17:24 +00:00
opts := proto . MarshalOptions {
Deterministic : true ,
AllowPartial : test . partial ,
}
wire , err := opts . Marshal ( want )
2019-03-14 00:06:42 +00:00
if err != nil {
2019-03-27 16:23:20 +00:00
t . Fatalf ( "Marshal error: %v\nMessage:\n%v" , err , marshalText ( want ) )
2019-03-14 00:06:42 +00:00
}
2019-04-03 19:17:24 +00:00
wire2 , err := opts . Marshal ( want )
2019-03-14 00:06:42 +00:00
if err != nil {
2019-03-27 16:23:20 +00:00
t . Fatalf ( "Marshal error: %v\nMessage:\n%v" , err , marshalText ( want ) )
2019-03-14 00:06:42 +00:00
}
if ! bytes . Equal ( wire , wire2 ) {
t . Fatalf ( "deterministic marshal returned varying results:\n%v" , cmp . Diff ( wire , wire2 ) )
}
got := reflect . New ( reflect . TypeOf ( want ) . Elem ( ) ) . Interface ( ) . ( proto . Message )
2019-04-03 19:17:24 +00:00
uopts := proto . UnmarshalOptions {
AllowPartial : test . partial ,
}
if err := uopts . Unmarshal ( wire , got ) ; err != nil {
2019-03-27 16:23:20 +00:00
t . Errorf ( "Unmarshal error: %v\nMessage:\n%v" , err , marshalText ( want ) )
2019-03-14 00:06:42 +00:00
return
}
2019-04-03 19:17:24 +00:00
if test . invalidExtensions {
// Equal doesn't work on messages containing invalid extension data.
return
}
2019-03-14 00:06:42 +00:00
if ! protoV1 . Equal ( got . ( protoV1 . Message ) , want . ( protoV1 . Message ) ) {
2019-03-27 16:23:20 +00:00
t . Errorf ( "Unmarshal returned unexpected result; got:\n%v\nwant:\n%v" , marshalText ( got ) , marshalText ( want ) )
2019-03-14 00:06:42 +00:00
}
} )
}
}
}
2019-04-03 19:17:24 +00:00
2019-04-11 18:46:55 +00:00
func TestEncodeInvalidUTF8 ( t * testing . T ) {
for _ , test := range invalidUTF8TestProtos {
for _ , want := range test . decodeTo {
t . Run ( fmt . Sprintf ( "%s (%T)" , test . desc , want ) , func ( t * testing . T ) {
wire , err := proto . Marshal ( want )
if ! isErrInvalidUTF8 ( err ) {
t . Errorf ( "Marshal did not return expected error for invalid UTF8: %v\nMessage:\n%v" , err , marshalText ( want ) )
}
got := reflect . New ( reflect . TypeOf ( want ) . Elem ( ) ) . Interface ( ) . ( proto . Message )
if err := proto . Unmarshal ( wire , got ) ; ! isErrInvalidUTF8 ( err ) {
t . Errorf ( "Unmarshal error: %v\nMessage:\n%v" , err , marshalText ( want ) )
return
}
if ! protoV1 . Equal ( got . ( protoV1 . Message ) , want . ( protoV1 . Message ) ) {
t . Errorf ( "Unmarshal returned unexpected result; got:\n%v\nwant:\n%v" , marshalText ( got ) , marshalText ( want ) )
}
} )
}
}
}
2019-04-03 19:17:24 +00:00
func TestEncodeRequiredFieldChecks ( t * testing . T ) {
for _ , test := range testProtos {
if ! test . partial {
continue
}
for _ , m := range test . decodeTo {
t . Run ( fmt . Sprintf ( "%s (%T)" , test . desc , m ) , func ( t * testing . T ) {
_ , err := proto . Marshal ( m )
if err == nil {
t . Fatalf ( "Marshal succeeded (want error)\nMessage:\n%v" , marshalText ( m ) )
}
} )
}
}
}
2019-04-07 19:43:10 +00:00
func TestMarshalAppend ( t * testing . T ) {
want := [ ] byte ( "prefix" )
got := append ( [ ] byte ( nil ) , want ... )
got , err := proto . MarshalOptions { } . MarshalAppend ( got , & test3pb . TestAllTypes {
OptionalString : "value" ,
} )
if err != nil {
t . Fatal ( err )
}
if ! bytes . HasPrefix ( got , want ) {
t . Fatalf ( "MarshalAppend modified prefix: got %v, want prefix %v" , got , want )
}
}