|  | // run | 
|  |  | 
|  | // Copyright 2016 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 main | 
|  |  | 
|  | import ( | 
|  | "fmt" | 
|  | "io" | 
|  | "os" | 
|  | "reflect" | 
|  | "unsafe" | 
|  | ) | 
|  |  | 
|  | type RWS struct{} | 
|  |  | 
|  | func (x *RWS) Read(p []byte) (n int, err error)                   { return } | 
|  | func (x *RWS) Write(p []byte) (n int, err error)                  { return } | 
|  | func (x *RWS) Seek(offset int64, whence int) (n int64, err error) { return } | 
|  | func (x *RWS) String() string                                     { return "rws" } | 
|  |  | 
|  | func makeRWS() io.ReadWriteSeeker { return &RWS{} } | 
|  | func makeStringer() fmt.Stringer  { return &RWS{} } | 
|  |  | 
|  | // Test correct construction of static empty interface values | 
|  | var efaces = [...]struct { | 
|  | x interface{} | 
|  | s string | 
|  | }{ | 
|  | {nil, "<nil> <nil>"}, | 
|  | {1, "int 1"}, | 
|  | {int(1), "int 1"}, | 
|  | {Int(int(2)), "main.Int Int=2"}, | 
|  | {int(Int(3)), "int 3"}, | 
|  | {[1]int{2}, "[1]int [2]"}, | 
|  | {io.Reader(io.ReadWriter(io.ReadWriteSeeker(nil))), "<nil> <nil>"}, | 
|  | {io.Reader(io.ReadWriter(io.ReadWriteSeeker(&RWS{}))), "*main.RWS rws"}, | 
|  | {makeRWS(), "*main.RWS rws"}, | 
|  | {map[string]string{"here": "there"}, "map[string]string map[here:there]"}, | 
|  | {chan bool(nil), "chan bool <nil>"}, | 
|  | {unsafe.Pointer(uintptr(0)), "unsafe.Pointer <nil>"}, | 
|  | {(*byte)(nil), "*uint8 <nil>"}, | 
|  | {io.Writer((*os.File)(nil)), "*os.File <nil>"}, | 
|  | {(interface{})(io.Writer((*os.File)(nil))), "*os.File <nil>"}, | 
|  | {fmt.Stringer(Strunger(((*Int)(nil)))), "*main.Int <nil>"}, | 
|  | } | 
|  |  | 
|  | type Int int | 
|  |  | 
|  | func (i Int) String() string { return fmt.Sprintf("Int=%d", i) } | 
|  | func (i Int) Strung()        {} | 
|  |  | 
|  | type Strunger interface { | 
|  | fmt.Stringer | 
|  | Strung() | 
|  | } | 
|  |  | 
|  | // Test correct construction of static non-empty interface values | 
|  | var ifaces = [...]struct { | 
|  | x fmt.Stringer | 
|  | s string | 
|  | }{ | 
|  | {nil, "<nil> <nil> %!s(<nil>)"}, | 
|  | {Int(3), "main.Int 3 Int=3"}, | 
|  | {Int(int(Int(4))), "main.Int 4 Int=4"}, | 
|  | {Strunger(Int(5)), "main.Int 5 Int=5"}, | 
|  | {makeStringer(), "*main.RWS &main.RWS{} rws"}, | 
|  | {fmt.Stringer(nil), "<nil> <nil> %!s(<nil>)"}, | 
|  | {(*RWS)(nil), "*main.RWS (*main.RWS)(nil) rws"}, | 
|  | } | 
|  |  | 
|  | // Test correct handling of direct interface values | 
|  | var ( | 
|  | one  int         = 1 | 
|  | iptr interface{} = &one | 
|  | clos int | 
|  | f    interface{} = func() { clos++ } | 
|  | deep interface{} = [1]struct{ a *[2]byte }{{a: &[2]byte{'z', 'w'}}} | 
|  | ch   interface{} = make(chan bool, 1) | 
|  | ) | 
|  |  | 
|  | func main() { | 
|  | var fail bool | 
|  | for i, test := range efaces { | 
|  | s := fmt.Sprintf("%[1]T %[1]v", test.x) | 
|  | if s != test.s { | 
|  | fmt.Printf("eface(%d)=%q want %q\n", i, s, test.s) | 
|  | fail = true | 
|  | } | 
|  | } | 
|  |  | 
|  | for i, test := range ifaces { | 
|  | s := fmt.Sprintf("%[1]T %#[1]v %[1]s", test.x) | 
|  | if s != test.s { | 
|  | fmt.Printf("iface(%d)=%q want %q\n", i, s, test.s) | 
|  | fail = true | 
|  | } | 
|  | } | 
|  |  | 
|  | if got := *(iptr.(*int)); got != 1 { | 
|  | fmt.Printf("bad int ptr %d\n", got) | 
|  | fail = true | 
|  | } | 
|  |  | 
|  | f.(func())() | 
|  | f.(func())() | 
|  | f.(func())() | 
|  | if clos != 3 { | 
|  | fmt.Printf("bad closure exec %d\n", clos) | 
|  | fail = true | 
|  | } | 
|  |  | 
|  | if !reflect.DeepEqual(*(deep.([1]struct{ a *[2]byte })[0].a), [2]byte{'z', 'w'}) { | 
|  | fmt.Printf("bad deep directiface\n") | 
|  | fail = true | 
|  | } | 
|  |  | 
|  | cc := ch.(chan bool) | 
|  | cc <- true | 
|  | if got := <-cc; !got { | 
|  | fmt.Printf("bad chan\n") | 
|  | fail = true | 
|  | } | 
|  |  | 
|  | if fail { | 
|  | fmt.Println("BUG") | 
|  | os.Exit(1) | 
|  | } | 
|  | } |