11package reflect_test
22
33import (
4+ "bytes"
45 "encoding/base64"
56 . "reflect"
67 "sort"
@@ -599,6 +600,29 @@ func TestAssignableTo(t *testing.T) {
599600 if got , want := refa .Interface ().(int ), 4 ; got != want {
600601 t .Errorf ("AssignableTo / Set failed, got %v, want %v" , got , want )
601602 }
603+
604+ b := []byte {0x01 , 0x02 }
605+ refb := ValueOf (& b ).Elem ()
606+ refb .Set (ValueOf ([]byte {0x02 , 0x03 }))
607+ if got , want := refb .Interface ().([]byte ), []byte {0x02 , 0x03 }; ! bytes .Equal (got , want ) {
608+ t .Errorf ("AssignableTo / Set failed, got %v, want %v" , got , want )
609+ }
610+
611+ type bstr []byte
612+
613+ c := bstr {0x01 , 0x02 }
614+ refc := ValueOf (& c ).Elem ()
615+ refc .Set (ValueOf ([]byte {0x02 , 0x03 }))
616+ if got , want := refb .Interface ().([]byte ), []byte {0x02 , 0x03 }; ! bytes .Equal (got , want ) {
617+ t .Errorf ("AssignableTo / Set failed, got %v, want %v" , got , want )
618+ }
619+
620+ d := []byte {0x01 , 0x02 }
621+ refd := ValueOf (& d ).Elem ()
622+ refd .Set (ValueOf (bstr {0x02 , 0x03 }))
623+ if got , want := refb .Interface ().([]byte ), []byte {0x02 , 0x03 }; ! bytes .Equal (got , want ) {
624+ t .Errorf ("AssignableTo / Set failed, got %v, want %v" , got , want )
625+ }
602626}
603627
604628func TestConvert (t * testing.T ) {
@@ -624,6 +648,162 @@ func TestConvert(t *testing.T) {
624648 }
625649}
626650
651+ func TestConvertSliceToArrayOrArrayPointer (t * testing.T ) {
652+ s := make ([]byte , 2 , 4 )
653+ // a0 := [0]byte(s)
654+ // a1 := [1]byte(s[1:]) // a1[0] == s[1]
655+ // a2 := [2]byte(s) // a2[0] == s[0]
656+ // a4 := [4]byte(s) // panics: len([4]byte) > len(s)
657+
658+ v := ValueOf (s ).Convert (TypeFor [[0 ]byte ]())
659+ if v .Kind () != Array || v .Type ().Len () != 0 {
660+ t .Error ("Convert([]byte -> [0]byte)" )
661+ }
662+ v = ValueOf (s [1 :]).Convert (TypeFor [[1 ]byte ]())
663+ if v .Kind () != Array || v .Type ().Len () != 1 {
664+ t .Error ("Convert([]byte -> [1]byte)" )
665+ }
666+ v = ValueOf (s ).Convert (TypeFor [[2 ]byte ]())
667+ if v .Kind () != Array || v .Type ().Len () != 2 {
668+ t .Error ("Convert([]byte -> [2]byte)" )
669+ }
670+ if ValueOf (s ).CanConvert (TypeFor [[4 ]byte ]()) {
671+ t .Error ("Converting a slice with len smaller than array to array should fail" )
672+ }
673+
674+ // s0 := (*[0]byte)(s) // s0 != nil
675+ // s1 := (*[1]byte)(s[1:]) // &s1[0] == &s[1]
676+ // s2 := (*[2]byte)(s) // &s2[0] == &s[0]
677+ // s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s)
678+ v = ValueOf (s ).Convert (TypeFor [* [0 ]byte ]())
679+ if v .Kind () != Pointer || v .Elem ().Kind () != Array || v .Elem ().Type ().Len () != 0 {
680+ t .Error ("Convert([]byte -> *[0]byte)" )
681+ }
682+ v = ValueOf (s [1 :]).Convert (TypeFor [* [1 ]byte ]())
683+ if v .Kind () != Pointer || v .Elem ().Kind () != Array || v .Elem ().Type ().Len () != 1 {
684+ t .Error ("Convert([]byte -> *[1]byte)" )
685+ }
686+ v = ValueOf (s ).Convert (TypeFor [* [2 ]byte ]())
687+ if v .Kind () != Pointer || v .Elem ().Kind () != Array || v .Elem ().Type ().Len () != 2 {
688+ t .Error ("Convert([]byte -> *[2]byte)" )
689+ }
690+ if ValueOf (s ).CanConvert (TypeFor [* [4 ]byte ]()) {
691+ t .Error ("Converting a slice with len smaller than array to array pointer should fail" )
692+ }
693+
694+ // Test converting slices with backing arrays <= and >64bits
695+ slice64 := []byte {0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 }
696+ array64 := ValueOf (slice64 ).Convert (TypeFor [[8 ]byte ]()).Interface ().([8 ]byte )
697+ if ! bytes .Equal (slice64 , array64 [:]) {
698+ t .Errorf ("converted array %x does not match backing array of slice %x" , array64 , slice64 )
699+ }
700+
701+ slice72 := []byte {0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 }
702+ array72 := ValueOf (slice72 ).Convert (TypeFor [[9 ]byte ]()).Interface ().([9 ]byte )
703+ if ! bytes .Equal (slice72 , array72 [:]) {
704+ t .Errorf ("converted array %x does not match backing array of slice %x" , array72 , slice72 )
705+ }
706+ }
707+
708+ func TestConvertToEmptyInterface (t * testing.T ) {
709+ anyType := TypeFor [interface {}]()
710+
711+ v := ValueOf (false ).Convert (anyType )
712+ if v .Kind () != Interface || v .NumMethod () > 0 {
713+ t .Error ("Convert(bool -> interface{})" )
714+ }
715+ _ = v .Interface ().(interface {}).(bool )
716+
717+ v = ValueOf (int64 (3 )).Convert (anyType )
718+ if v .Kind () != Interface || v .NumMethod () > 0 {
719+ t .Error ("Convert(int64 -> interface{})" )
720+ }
721+ _ = v .Interface ().(interface {}).(int64 )
722+
723+ v = ValueOf (struct {}{}).Convert (anyType )
724+ if v .Kind () != Interface || v .NumMethod () > 0 {
725+ t .Error ("Convert(struct -> interface{})" )
726+ }
727+ _ = v .Interface ().(interface {}).(struct {})
728+
729+ v = ValueOf ([]struct {}{}).Convert (anyType )
730+ if v .Kind () != Interface || v .NumMethod () > 0 {
731+ t .Error ("Convert(slice -> interface{})" )
732+ }
733+ _ = v .Interface ().(interface {}).([]struct {})
734+
735+ v = ValueOf (map [string ]string {"A" : "B" }).Convert (anyType )
736+ if v .Kind () != Interface || v .NumMethod () > 0 {
737+ t .Error ("Convert(map -> interface{})" )
738+ }
739+ _ = v .Interface ().(interface {}).(map [string ]string )
740+ }
741+
742+ func TestClearSlice (t * testing.T ) {
743+ type stringSlice []string
744+ for _ , test := range []struct {
745+ slice any
746+ expect any
747+ }{
748+ {
749+ slice : []bool {true , false , true },
750+ expect : []bool {false , false , false },
751+ },
752+ {
753+ slice : []byte {0x00 , 0x01 , 0x02 , 0x03 },
754+ expect : []byte {0x00 , 0x00 , 0x00 , 0x00 },
755+ },
756+ {
757+ slice : [][]int {[]int {2 , 1 }, []int {3 }, []int {}},
758+ expect : [][]int {nil , nil , nil },
759+ },
760+ {
761+ slice : []stringSlice {stringSlice {"hello" , "world" }, stringSlice {}, stringSlice {"goodbye" }},
762+ expect : []stringSlice {nil , nil , nil },
763+ },
764+ } {
765+ v := ValueOf (test .slice )
766+ expectLen , expectCap := v .Len (), v .Cap ()
767+
768+ v .Clear ()
769+ if len := v .Len (); len != expectLen {
770+ t .Errorf ("Clear(slice) altered len, got %d, expected %d" , len , expectLen )
771+ }
772+ if cap := v .Cap (); cap != expectCap {
773+ t .Errorf ("Clear(slice) altered cap, got %d, expected %d" , cap , expectCap )
774+ }
775+ if ! DeepEqual (test .slice , test .expect ) {
776+ t .Errorf ("Clear(slice) got %v, expected %v" , test .slice , test .expect )
777+ }
778+ }
779+ }
780+
781+ func TestClearMap (t * testing.T ) {
782+ for _ , test := range []struct {
783+ m any
784+ expect any
785+ }{
786+ {
787+ m : map [int ]bool {1 : true , 2 : false , 3 : true },
788+ expect : map [int ]bool {},
789+ },
790+ {
791+ m : map [string ][]byte {"hello" : []byte ("world" )},
792+ expect : map [string ][]byte {},
793+ },
794+ } {
795+ v := ValueOf (test .m )
796+
797+ v .Clear ()
798+ if len := v .Len (); len != 0 {
799+ t .Errorf ("Clear(map) should set len to 0, got %d" , len )
800+ }
801+ if ! DeepEqual (test .m , test .expect ) {
802+ t .Errorf ("Clear(map) got %v, expected %v" , test .m , test .expect )
803+ }
804+ }
805+ }
806+
627807func TestIssue4040 (t * testing.T ) {
628808 var value interface {} = uint16 (0 )
629809
0 commit comments