Home | History | Annotate | Download | only in test
      1 // run
      2 
      3 // Copyright 2009 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file.
      6 
      7 // Test nil.
      8 
      9 package main
     10 
     11 import (
     12 	"fmt"
     13 	"time"
     14 )
     15 
     16 type T struct {
     17 	i int
     18 }
     19 
     20 type IN interface{}
     21 
     22 func main() {
     23 	var i *int
     24 	var f *float32
     25 	var s *string
     26 	var m map[float32]*int
     27 	var c chan int
     28 	var t *T
     29 	var in IN
     30 	var ta []IN
     31 
     32 	i = nil
     33 	f = nil
     34 	s = nil
     35 	m = nil
     36 	c = nil
     37 	t = nil
     38 	i = nil
     39 	ta = make([]IN, 1)
     40 	ta[0] = nil
     41 
     42 	_, _, _, _, _, _, _, _ = i, f, s, m, c, t, in, ta
     43 
     44 	arraytest()
     45 	chantest()
     46 	maptest()
     47 	slicetest()
     48 }
     49 
     50 func shouldPanic(f func()) {
     51 	defer func() {
     52 		if recover() == nil {
     53 			panic("not panicking")
     54 		}
     55 	}()
     56 	f()
     57 }
     58 
     59 func shouldBlock(f func()) {
     60 	go func() {
     61 		f()
     62 		panic("did not block")
     63 	}()
     64 	time.Sleep(1e7)
     65 }
     66 
     67 // nil array pointer
     68 
     69 func arraytest() {
     70 	var p *[10]int
     71 
     72 	// Looping over indices is fine.
     73 	s := 0
     74 	for i := range p {
     75 		s += i
     76 	}
     77 	if s != 45 {
     78 		panic(s)
     79 	}
     80 
     81 	s = 0
     82 	for i := 0; i < len(p); i++ {
     83 		s += i
     84 	}
     85 	if s != 45 {
     86 		panic(s)
     87 	}
     88 
     89 	// Looping over values is not.
     90 	shouldPanic(func() {
     91 		for i, v := range p {
     92 			s += i + v
     93 		}
     94 	})
     95 
     96 	shouldPanic(func() {
     97 		for i := 0; i < len(p); i++ {
     98 			s += p[i]
     99 		}
    100 	})
    101 }
    102 
    103 // nil channel
    104 // select tests already handle select on nil channel
    105 
    106 func chantest() {
    107 	var ch chan int
    108 
    109 	// nil channel is never ready
    110 	shouldBlock(func() {
    111 		ch <- 1
    112 	})
    113 	shouldBlock(func() {
    114 		<-ch
    115 	})
    116 	shouldBlock(func() {
    117 		x, ok := <-ch
    118 		println(x, ok) // unreachable
    119 	})
    120 
    121 	if len(ch) != 0 {
    122 		panic(len(ch))
    123 	}
    124 	if cap(ch) != 0 {
    125 		panic(cap(ch))
    126 	}
    127 }
    128 
    129 // nil map
    130 
    131 func maptest() {
    132 	var m map[int]int
    133 
    134 	// nil map appears empty
    135 	if len(m) != 0 {
    136 		panic(len(m))
    137 	}
    138 	if m[1] != 0 {
    139 		panic(m[1])
    140 	}
    141 	if x, ok := m[1]; x != 0 || ok {
    142 		panic(fmt.Sprint(x, ok))
    143 	}
    144 
    145 	for k, v := range m {
    146 		panic(k)
    147 		panic(v)
    148 	}
    149 
    150 	// can delete (non-existent) entries
    151 	delete(m, 2)
    152 
    153 	// but cannot be written to
    154 	shouldPanic(func() {
    155 		m[2] = 3
    156 	})
    157 }
    158 
    159 // nil slice
    160 
    161 func slicetest() {
    162 	var x []int
    163 
    164 	// nil slice is just a 0-element slice.
    165 	if len(x) != 0 {
    166 		panic(len(x))
    167 	}
    168 	if cap(x) != 0 {
    169 		panic(cap(x))
    170 	}
    171 
    172 	// no 0-element slices can be read from or written to
    173 	var s int
    174 	shouldPanic(func() {
    175 		s += x[1]
    176 	})
    177 	shouldPanic(func() {
    178 		x[2] = s
    179 	})
    180 }
    181