| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package gob |
| |
| import ( |
| "reflect"; |
| "testing"; |
| ) |
| |
| type typeT struct { |
| id typeId; |
| str string; |
| } |
| |
| var basicTypes = []typeT{ |
| typeT{tBool, "bool"}, |
| typeT{tInt, "int"}, |
| typeT{tUint, "uint"}, |
| typeT{tFloat, "float"}, |
| typeT{tBytes, "bytes"}, |
| typeT{tString, "string"}, |
| } |
| |
| func getTypeUnlocked(name string, rt reflect.Type) gobType { |
| typeLock.Lock(); |
| defer typeLock.Unlock(); |
| t, err := getType(name, rt); |
| if err != nil { |
| panicln("getTypeUnlocked:", err.String()) |
| } |
| return t; |
| } |
| |
| // Sanity checks |
| func TestBasic(t *testing.T) { |
| for _, tt := range basicTypes { |
| if tt.id.String() != tt.str { |
| t.Errorf("checkType: expected %q got %s", tt.str, tt.id.String()) |
| } |
| if tt.id == 0 { |
| t.Errorf("id for %q is zero", tt.str) |
| } |
| } |
| } |
| |
| // Reregister some basic types to check registration is idempotent. |
| func TestReregistration(t *testing.T) { |
| newtyp := getTypeUnlocked("int", reflect.Typeof(int(0))); |
| if newtyp != tInt.gobType() { |
| t.Errorf("reregistration of %s got new type", newtyp.String()) |
| } |
| newtyp = getTypeUnlocked("uint", reflect.Typeof(uint(0))); |
| if newtyp != tUint.gobType() { |
| t.Errorf("reregistration of %s got new type", newtyp.String()) |
| } |
| newtyp = getTypeUnlocked("string", reflect.Typeof("hello")); |
| if newtyp != tString.gobType() { |
| t.Errorf("reregistration of %s got new type", newtyp.String()) |
| } |
| } |
| |
| func TestArrayType(t *testing.T) { |
| var a3 [3]int; |
| a3int := getTypeUnlocked("foo", reflect.Typeof(a3)); |
| newa3int := getTypeUnlocked("bar", reflect.Typeof(a3)); |
| if a3int != newa3int { |
| t.Errorf("second registration of [3]int creates new type") |
| } |
| var a4 [4]int; |
| a4int := getTypeUnlocked("goo", reflect.Typeof(a4)); |
| if a3int == a4int { |
| t.Errorf("registration of [3]int creates same type as [4]int") |
| } |
| var b3 [3]bool; |
| a3bool := getTypeUnlocked("", reflect.Typeof(b3)); |
| if a3int == a3bool { |
| t.Errorf("registration of [3]bool creates same type as [3]int") |
| } |
| str := a3bool.String(); |
| expected := "[3]bool"; |
| if str != expected { |
| t.Errorf("array printed as %q; expected %q", str, expected) |
| } |
| } |
| |
| func TestSliceType(t *testing.T) { |
| var s []int; |
| sint := getTypeUnlocked("slice", reflect.Typeof(s)); |
| var news []int; |
| newsint := getTypeUnlocked("slice1", reflect.Typeof(news)); |
| if sint != newsint { |
| t.Errorf("second registration of []int creates new type") |
| } |
| var b []bool; |
| sbool := getTypeUnlocked("", reflect.Typeof(b)); |
| if sbool == sint { |
| t.Errorf("registration of []bool creates same type as []int") |
| } |
| str := sbool.String(); |
| expected := "[]bool"; |
| if str != expected { |
| t.Errorf("slice printed as %q; expected %q", str, expected) |
| } |
| } |
| |
| type Bar struct { |
| x string; |
| } |
| |
| // This structure has pointers and refers to itself, making it a good test case. |
| type Foo struct { |
| a int; |
| b int32; // will become int |
| c string; |
| d []byte; |
| e *float; // will become float |
| f ****float64; // will become float |
| g *Bar; |
| h *Bar; // should not interpolate the definition of Bar again |
| i *Foo; // will not explode |
| } |
| |
| func TestStructType(t *testing.T) { |
| sstruct := getTypeUnlocked("Foo", reflect.Typeof(Foo{})); |
| str := sstruct.String(); |
| // If we can print it correctly, we built it correctly. |
| expected := "Foo = struct { a int; b int; c string; d bytes; e float; f float; g Bar = struct { x string; }; h Bar; i Foo; }"; |
| if str != expected { |
| t.Errorf("struct printed as %q; expected %q", str, expected) |
| } |
| } |