]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/encoding/gob/type_test.go
libgo: Update to current sources.
[thirdparty/gcc.git] / libgo / go / encoding / gob / type_test.go
CommitLineData
7a938933
ILT
1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package gob
6
7import (
4ccad563 8 "bytes"
7a938933
ILT
9 "reflect"
10 "testing"
11)
12
13type typeT struct {
14 id typeId
15 str string
16}
17
18var basicTypes = []typeT{
19 {tBool, "bool"},
20 {tInt, "int"},
21 {tUint, "uint"},
22 {tFloat, "float"},
23 {tBytes, "bytes"},
24 {tString, "string"},
25}
26
27func getTypeUnlocked(name string, rt reflect.Type) gobType {
28 typeLock.Lock()
29 defer typeLock.Unlock()
8039ca76 30 t, err := getBaseType(name, rt)
7a938933 31 if err != nil {
2fd401c8 32 panic("getTypeUnlocked: " + err.Error())
7a938933
ILT
33 }
34 return t
35}
36
37// Sanity checks
38func TestBasic(t *testing.T) {
39 for _, tt := range basicTypes {
40 if tt.id.string() != tt.str {
41 t.Errorf("checkType: expected %q got %s", tt.str, tt.id.string())
42 }
43 if tt.id == 0 {
44 t.Errorf("id for %q is zero", tt.str)
45 }
46 }
47}
48
49// Reregister some basic types to check registration is idempotent.
50func TestReregistration(t *testing.T) {
9ff56c95 51 newtyp := getTypeUnlocked("int", reflect.TypeOf(int(0)))
7a938933
ILT
52 if newtyp != tInt.gobType() {
53 t.Errorf("reregistration of %s got new type", newtyp.string())
54 }
9ff56c95 55 newtyp = getTypeUnlocked("uint", reflect.TypeOf(uint(0)))
7a938933
ILT
56 if newtyp != tUint.gobType() {
57 t.Errorf("reregistration of %s got new type", newtyp.string())
58 }
9ff56c95 59 newtyp = getTypeUnlocked("string", reflect.TypeOf("hello"))
7a938933
ILT
60 if newtyp != tString.gobType() {
61 t.Errorf("reregistration of %s got new type", newtyp.string())
62 }
63}
64
65func TestArrayType(t *testing.T) {
66 var a3 [3]int
9ff56c95
ILT
67 a3int := getTypeUnlocked("foo", reflect.TypeOf(a3))
68 newa3int := getTypeUnlocked("bar", reflect.TypeOf(a3))
7a938933
ILT
69 if a3int != newa3int {
70 t.Errorf("second registration of [3]int creates new type")
71 }
72 var a4 [4]int
9ff56c95 73 a4int := getTypeUnlocked("goo", reflect.TypeOf(a4))
7a938933
ILT
74 if a3int == a4int {
75 t.Errorf("registration of [3]int creates same type as [4]int")
76 }
77 var b3 [3]bool
9ff56c95 78 a3bool := getTypeUnlocked("", reflect.TypeOf(b3))
7a938933
ILT
79 if a3int == a3bool {
80 t.Errorf("registration of [3]bool creates same type as [3]int")
81 }
82 str := a3bool.string()
83 expected := "[3]bool"
84 if str != expected {
85 t.Errorf("array printed as %q; expected %q", str, expected)
86 }
87}
88
89func TestSliceType(t *testing.T) {
90 var s []int
9ff56c95 91 sint := getTypeUnlocked("slice", reflect.TypeOf(s))
7a938933 92 var news []int
9ff56c95 93 newsint := getTypeUnlocked("slice1", reflect.TypeOf(news))
7a938933
ILT
94 if sint != newsint {
95 t.Errorf("second registration of []int creates new type")
96 }
97 var b []bool
9ff56c95 98 sbool := getTypeUnlocked("", reflect.TypeOf(b))
7a938933
ILT
99 if sbool == sint {
100 t.Errorf("registration of []bool creates same type as []int")
101 }
102 str := sbool.string()
103 expected := "[]bool"
104 if str != expected {
105 t.Errorf("slice printed as %q; expected %q", str, expected)
106 }
107}
108
109func TestMapType(t *testing.T) {
110 var m map[string]int
9ff56c95 111 mapStringInt := getTypeUnlocked("map", reflect.TypeOf(m))
7a938933 112 var newm map[string]int
9ff56c95 113 newMapStringInt := getTypeUnlocked("map1", reflect.TypeOf(newm))
7a938933
ILT
114 if mapStringInt != newMapStringInt {
115 t.Errorf("second registration of map[string]int creates new type")
116 }
117 var b map[string]bool
9ff56c95 118 mapStringBool := getTypeUnlocked("", reflect.TypeOf(b))
7a938933
ILT
119 if mapStringBool == mapStringInt {
120 t.Errorf("registration of map[string]bool creates same type as map[string]int")
121 }
122 str := mapStringBool.string()
123 expected := "map[string]bool"
124 if str != expected {
125 t.Errorf("map printed as %q; expected %q", str, expected)
126 }
127}
128
129type Bar struct {
8039ca76 130 X string
7a938933
ILT
131}
132
133// This structure has pointers and refers to itself, making it a good test case.
134type Foo struct {
8039ca76
ILT
135 A int
136 B int32 // will become int
137 C string
138 D []byte
139 E *float64 // will become float64
140 F ****float64 // will become float64
141 G *Bar
142 H *Bar // should not interpolate the definition of Bar again
143 I *Foo // will not explode
7a938933
ILT
144}
145
146func TestStructType(t *testing.T) {
9ff56c95 147 sstruct := getTypeUnlocked("Foo", reflect.TypeOf(Foo{}))
7a938933
ILT
148 str := sstruct.string()
149 // If we can print it correctly, we built it correctly.
8039ca76 150 expected := "Foo = struct { A int; B int; C string; D bytes; E float; F float; G Bar = struct { X string; }; H Bar; I Foo; }"
7a938933
ILT
151 if str != expected {
152 t.Errorf("struct printed as %q; expected %q", str, expected)
153 }
154}
9c63abc9
ILT
155
156// Should be OK to register the same type multiple times, as long as they're
157// at the same level of indirection.
158func TestRegistration(t *testing.T) {
159 type T struct{ a int }
160 Register(new(T))
161 Register(new(T))
162}
4ccad563
ILT
163
164type N1 struct{}
165type N2 struct{}
166
167// See comment in type.go/Register.
168func TestRegistrationNaming(t *testing.T) {
169 testCases := []struct {
170 t interface{}
171 name string
172 }{
173 {&N1{}, "*gob.N1"},
174 {N2{}, "encoding/gob.N2"},
175 }
176
177 for _, tc := range testCases {
178 Register(tc.t)
179
180 tct := reflect.TypeOf(tc.t)
181 registerLock.RLock()
182 ct := nameToConcreteType[tc.name]
183 registerLock.RUnlock()
184 if ct != tct {
185 t.Errorf("nameToConcreteType[%q] = %v, want %v", tc.name, ct, tct)
186 }
187 // concreteTypeToName is keyed off the base type.
188 if tct.Kind() == reflect.Ptr {
189 tct = tct.Elem()
190 }
191 if n := concreteTypeToName[tct]; n != tc.name {
192 t.Errorf("concreteTypeToName[%v] got %v, want %v", tct, n, tc.name)
193 }
194 }
195}
196
197func TestStressParallel(t *testing.T) {
198 type T2 struct{ A int }
199 c := make(chan bool)
200 const N = 10
201 for i := 0; i < N; i++ {
202 go func() {
203 p := new(T2)
204 Register(p)
205 b := new(bytes.Buffer)
206 enc := NewEncoder(b)
207 err := enc.Encode(p)
208 if err != nil {
209 t.Error("encoder fail:", err)
210 }
211 dec := NewDecoder(b)
212 err = dec.Decode(p)
213 if err != nil {
214 t.Error("decoder fail:", err)
215 }
216 c <- true
217 }()
218 }
219 for i := 0; i < N; i++ {
220 <-c
221 }
222}