github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/test/range.go (about)

     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  }