1
1
package reflect_test
2
2
3
3
import (
4
+ "bytes"
4
5
"encoding/base64"
5
6
. "reflect"
6
7
"sort"
@@ -599,6 +600,29 @@ func TestAssignableTo(t *testing.T) {
599
600
if got , want := refa .Interface ().(int ), 4 ; got != want {
600
601
t .Errorf ("AssignableTo / Set failed, got %v, want %v" , got , want )
601
602
}
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
+ }
602
626
}
603
627
604
628
func TestConvert (t * testing.T ) {
@@ -624,6 +648,162 @@ func TestConvert(t *testing.T) {
624
648
}
625
649
}
626
650
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
+
627
807
func TestIssue4040 (t * testing.T ) {
628
808
var value interface {} = uint16 (0 )
629
809
0 commit comments