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 the 'for range' construct.
      8 
      9 package main
     10 
     11 // test range over channels
     12 
     13 func gen(c chan int, lo, hi int) {
     14 	for i := lo; i <= hi; i++ {
     15 		c <- i
     16 	}
     17 	close(c)
     18 }
     19 
     20 func seq(lo, hi int) chan int {
     21 	c := make(chan int)
     22 	go gen(c, lo, hi)
     23 	return c
     24 }
     25 
     26 func testchan() {
     27 	s := ""
     28 	for i := range seq('a', 'z') {
     29 		s += string(i)
     30 	}
     31 	if s != "abcdefghijklmnopqrstuvwxyz" {
     32 		println("Wanted lowercase alphabet; got", s)
     33 		panic("fail")
     34 	}
     35 	n := 0
     36 	for range seq('a', 'z') {
     37 		n++
     38 	}
     39 	if n != 26 {
     40 		println("testchan wrong count", n, "want 26")
     41 	}
     42 }
     43 
     44 // test that range over slice only evaluates
     45 // the expression after "range" once.
     46 
     47 var nmake = 0
     48 
     49 func makeslice() []int {
     50 	nmake++
     51 	return []int{1, 2, 3, 4, 5}
     52 }
     53 
     54 func testslice() {
     55 	s := 0
     56 	nmake = 0
     57 	for _, v := range makeslice() {
     58 		s += v
     59 	}
     60 	if nmake != 1 {
     61 		println("range called makeslice", nmake, "times")
     62 		panic("fail")
     63 	}
     64 	if s != 15 {
     65 		println("wrong sum ranging over makeslice", s)
     66 		panic("fail")
     67 	}
     68 
     69 	x := []int{10, 20}
     70 	y := []int{99}
     71 	i := 1
     72 	for i, x[i] = range y {
     73 		break
     74 	}
     75 	if i != 0 || x[0] != 10 || x[1] != 99 {
     76 		println("wrong parallel assignment", i, x[0], x[1])
     77 		panic("fail")
     78 	}
     79 }
     80 
     81 func testslice1() {
     82 	s := 0
     83 	nmake = 0
     84 	for i := range makeslice() {
     85 		s += i
     86 	}
     87 	if nmake != 1 {
     88 		println("range called makeslice", nmake, "times")
     89 		panic("fail")
     90 	}
     91 	if s != 10 {
     92 		println("wrong sum ranging over makeslice", s)
     93 		panic("fail")
     94 	}
     95 }
     96 
     97 func testslice2() {
     98 	n := 0
     99 	nmake = 0
    100 	for range makeslice() {
    101 		n++
    102 	}
    103 	if nmake != 1 {
    104 		println("range called makeslice", nmake, "times")
    105 		panic("fail")
    106 	}
    107 	if n != 5 {
    108 		println("wrong count ranging over makeslice", n)
    109 		panic("fail")
    110 	}
    111 }
    112 
    113 // test that range over []byte(string) only evaluates
    114 // the expression after "range" once.
    115 
    116 func makenumstring() string {
    117 	nmake++
    118 	return "\x01\x02\x03\x04\x05"
    119 }
    120 
    121 func testslice3() {
    122 	s := byte(0)
    123 	nmake = 0
    124 	for _, v := range []byte(makenumstring()) {
    125 		s += v
    126 	}
    127 	if nmake != 1 {
    128 		println("range called makenumstring", nmake, "times")
    129 		panic("fail")
    130 	}
    131 	if s != 15 {
    132 		println("wrong sum ranging over []byte(makenumstring)", s)
    133 		panic("fail")
    134 	}
    135 }
    136 
    137 // test that range over array only evaluates
    138 // the expression after "range" once.
    139 
    140 func makearray() [5]int {
    141 	nmake++
    142 	return [5]int{1, 2, 3, 4, 5}
    143 }
    144 
    145 func testarray() {
    146 	s := 0
    147 	nmake = 0
    148 	for _, v := range makearray() {
    149 		s += v
    150 	}
    151 	if nmake != 1 {
    152 		println("range called makearray", nmake, "times")
    153 		panic("fail")
    154 	}
    155 	if s != 15 {
    156 		println("wrong sum ranging over makearray", s)
    157 		panic("fail")
    158 	}
    159 }
    160 
    161 func testarray1() {
    162 	s := 0
    163 	nmake = 0
    164 	for i := range makearray() {
    165 		s += i
    166 	}
    167 	if nmake != 1 {
    168 		println("range called makearray", nmake, "times")
    169 		panic("fail")
    170 	}
    171 	if s != 10 {
    172 		println("wrong sum ranging over makearray", s)
    173 		panic("fail")
    174 	}
    175 }
    176 
    177 func testarray2() {
    178 	n := 0
    179 	nmake = 0
    180 	for range makearray() {
    181 		n++
    182 	}
    183 	if nmake != 1 {
    184 		println("range called makearray", nmake, "times")
    185 		panic("fail")
    186 	}
    187 	if n != 5 {
    188 		println("wrong count ranging over makearray", n)
    189 		panic("fail")
    190 	}
    191 }
    192 
    193 func makearrayptr() *[5]int {
    194 	nmake++
    195 	return &[5]int{1, 2, 3, 4, 5}
    196 }
    197 
    198 func testarrayptr() {
    199 	nmake = 0
    200 	x := len(makearrayptr())
    201 	if x != 5 || nmake != 1 {
    202 		println("len called makearrayptr", nmake, "times and got len", x)
    203 		panic("fail")
    204 	}
    205 	nmake = 0
    206 	x = cap(makearrayptr())
    207 	if x != 5 || nmake != 1 {
    208 		println("cap called makearrayptr", nmake, "times and got len", x)
    209 		panic("fail")
    210 	}
    211 	s := 0
    212 	nmake = 0
    213 	for _, v := range makearrayptr() {
    214 		s += v
    215 	}
    216 	if nmake != 1 {
    217 		println("range called makearrayptr", nmake, "times")
    218 		panic("fail")
    219 	}
    220 	if s != 15 {
    221 		println("wrong sum ranging over makearrayptr", s)
    222 		panic("fail")
    223 	}
    224 }
    225 
    226 func testarrayptr1() {
    227 	s := 0
    228 	nmake = 0
    229 	for i := range makearrayptr() {
    230 		s += i
    231 	}
    232 	if nmake != 1 {
    233 		println("range called makearrayptr", nmake, "times")
    234 		panic("fail")
    235 	}
    236 	if s != 10 {
    237 		println("wrong sum ranging over makearrayptr", s)
    238 		panic("fail")
    239 	}
    240 }
    241 
    242 func testarrayptr2() {
    243 	n := 0
    244 	nmake = 0
    245 	for range makearrayptr() {
    246 		n++
    247 	}
    248 	if nmake != 1 {
    249 		println("range called makearrayptr", nmake, "times")
    250 		panic("fail")
    251 	}
    252 	if n != 5 {
    253 		println("wrong count ranging over makearrayptr", n)
    254 		panic("fail")
    255 	}
    256 }
    257 
    258 // test that range over string only evaluates
    259 // the expression after "range" once.
    260 
    261 func makestring() string {
    262 	nmake++
    263 	return "abcd"
    264 }
    265 
    266 func teststring() {
    267 	var s rune
    268 	nmake = 0
    269 	for _, v := range makestring() {
    270 		s += v
    271 	}
    272 	if nmake != 1 {
    273 		println("range called makestring", nmake, "times")
    274 		panic("fail")
    275 	}
    276 	if s != 'a'+'b'+'c'+'d'+'' {
    277 		println("wrong sum ranging over makestring", s)
    278 		panic("fail")
    279 	}
    280 }
    281 
    282 func teststring1() {
    283 	s := 0
    284 	nmake = 0
    285 	for i := range makestring() {
    286 		s += i
    287 	}
    288 	if nmake != 1 {
    289 		println("range called makestring", nmake, "times")
    290 		panic("fail")
    291 	}
    292 	if s != 10 {
    293 		println("wrong sum ranging over makestring", s)
    294 		panic("fail")
    295 	}
    296 }
    297 
    298 func teststring2() {
    299 	n := 0
    300 	nmake = 0
    301 	for range makestring() {
    302 		n++
    303 	}
    304 	if nmake != 1 {
    305 		println("range called makestring", nmake, "times")
    306 		panic("fail")
    307 	}
    308 	if n != 5 {
    309 		println("wrong count ranging over makestring", n)
    310 		panic("fail")
    311 	}
    312 }
    313 
    314 // test that range over map only evaluates
    315 // the expression after "range" once.
    316 
    317 func makemap() map[int]int {
    318 	nmake++
    319 	return map[int]int{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: ''}
    320 }
    321 
    322 func testmap() {
    323 	s := 0
    324 	nmake = 0
    325 	for _, v := range makemap() {
    326 		s += v
    327 	}
    328 	if nmake != 1 {
    329 		println("range called makemap", nmake, "times")
    330 		panic("fail")
    331 	}
    332 	if s != 'a'+'b'+'c'+'d'+'' {
    333 		println("wrong sum ranging over makemap", s)
    334 		panic("fail")
    335 	}
    336 }
    337 
    338 func testmap1() {
    339 	s := 0
    340 	nmake = 0
    341 	for i := range makemap() {
    342 		s += i
    343 	}
    344 	if nmake != 1 {
    345 		println("range called makemap", nmake, "times")
    346 		panic("fail")
    347 	}
    348 	if s != 10 {
    349 		println("wrong sum ranging over makemap", s)
    350 		panic("fail")
    351 	}
    352 }
    353 
    354 func testmap2() {
    355 	n := 0
    356 	nmake = 0
    357 	for range makemap() {
    358 		n++
    359 	}
    360 	if nmake != 1 {
    361 		println("range called makemap", nmake, "times")
    362 		panic("fail")
    363 	}
    364 	if n != 5 {
    365 		println("wrong count ranging over makemap", n)
    366 		panic("fail")
    367 	}
    368 }
    369 
    370 // test that range evaluates the index and value expressions
    371 // exactly once per iteration.
    372 
    373 var ncalls = 0
    374 
    375 func getvar(p *int) *int {
    376 	ncalls++
    377 	return p
    378 }
    379 
    380 func testcalls() {
    381 	var i, v int
    382 	si := 0
    383 	sv := 0
    384 	for *getvar(&i), *getvar(&v) = range [2]int{1, 2} {
    385 		si += i
    386 		sv += v
    387 	}
    388 	if ncalls != 4 {
    389 		println("wrong number of calls:", ncalls, "!= 4")
    390 		panic("fail")
    391 	}
    392 	if si != 1 || sv != 3 {
    393 		println("wrong sum in testcalls", si, sv)
    394 		panic("fail")
    395 	}
    396 
    397 	ncalls = 0
    398 	for *getvar(&i), *getvar(&v) = range [0]int{} {
    399 		println("loop ran on empty array")
    400 		panic("fail")
    401 	}
    402 	if ncalls != 0 {
    403 		println("wrong number of calls:", ncalls, "!= 0")
    404 		panic("fail")
    405 	}
    406 }
    407 
    408 func main() {
    409 	testchan()
    410 	testarray()
    411 	testarray1()
    412 	testarray2()
    413 	testarrayptr()
    414 	testarrayptr1()
    415 	testarrayptr2()
    416 	testslice()
    417 	testslice1()
    418 	testslice2()
    419 	testslice3()
    420 	teststring()
    421 	teststring1()
    422 	teststring2()
    423 	testmap()
    424 	testmap1()
    425 	testmap2()
    426 	testcalls()
    427 }
    428