]> Cypherpunks.ru repositories - gostls13.git/blobdiff - test/range4.go
test: run range-over-integer tests without need for -goexperiment
[gostls13.git] / test / range4.go
diff --git a/test/range4.go b/test/range4.go
new file mode 100644 (file)
index 0000000..561b3b5
--- /dev/null
@@ -0,0 +1,326 @@
+// run -goexperiment range
+
+// Copyright 2023 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.
+
+// Test the 'for range' construct ranging over functions.
+
+package main
+
+var gj int
+
+func yield4x(yield func() bool) {
+       _ = yield() && yield() && yield() && yield()
+}
+
+func yield4(yield func(int) bool) {
+       _ = yield(1) && yield(2) && yield(3) && yield(4)
+}
+
+func yield3(yield func(int) bool) {
+       _ = yield(1) && yield(2) && yield(3)
+}
+
+func yield2(yield func(int) bool) {
+       _ = yield(1) && yield(2)
+}
+
+func testfunc0() {
+       j := 0
+       for range yield4x {
+               j++
+       }
+       if j != 4 {
+               println("wrong count ranging over yield4x:", j)
+               panic("testfunc0")
+       }
+
+       j = 0
+       for _ = range yield4 {
+               j++
+       }
+       if j != 4 {
+               println("wrong count ranging over yield4:", j)
+               panic("testfunc0")
+       }
+}
+
+func testfunc1() {
+       bad := false
+       j := 1
+       for i := range yield4 {
+               if i != j {
+                       println("range var", i, "want", j)
+                       bad = true
+               }
+               j++
+       }
+       if j != 5 {
+               println("wrong count ranging over f:", j)
+               bad = true
+       }
+       if bad {
+               panic("testfunc1")
+       }
+}
+
+func testfunc2() {
+       bad := false
+       j := 1
+       var i int
+       for i = range yield4 {
+               if i != j {
+                       println("range var", i, "want", j)
+                       bad = true
+               }
+               j++
+       }
+       if j != 5 {
+               println("wrong count ranging over f:", j)
+               bad = true
+       }
+       if i != 4 {
+               println("wrong final i ranging over f:", i)
+               bad = true
+       }
+       if bad {
+               panic("testfunc2")
+       }
+}
+
+func testfunc3() {
+       bad := false
+       j := 1
+       var i int
+       for i = range yield4 {
+               if i != j {
+                       println("range var", i, "want", j)
+                       bad = true
+               }
+               j++
+               if i == 2 {
+                       break
+               }
+               continue
+       }
+       if j != 3 {
+               println("wrong count ranging over f:", j)
+               bad = true
+       }
+       if i != 2 {
+               println("wrong final i ranging over f:", i)
+               bad = true
+       }
+       if bad {
+               panic("testfunc3")
+       }
+}
+
+func testfunc4() {
+       bad := false
+       j := 1
+       var i int
+       func() {
+               for i = range yield4 {
+                       if i != j {
+                               println("range var", i, "want", j)
+                               bad = true
+                       }
+                       j++
+                       if i == 2 {
+                               return
+                       }
+               }
+       }()
+       if j != 3 {
+               println("wrong count ranging over f:", j)
+               bad = true
+       }
+       if i != 2 {
+               println("wrong final i ranging over f:", i)
+               bad = true
+       }
+       if bad {
+               panic("testfunc3")
+       }
+}
+
+func func5() (int, int) {
+       for i := range yield4 {
+               return 10, i
+       }
+       panic("still here")
+}
+
+func testfunc5() {
+       x, y := func5()
+       if x != 10 || y != 1 {
+               println("wrong results", x, y, "want", 10, 1)
+               panic("testfunc5")
+       }
+}
+
+func func6() (z, w int) {
+       for i := range yield4 {
+               z = 10
+               w = i
+               return
+       }
+       panic("still here")
+}
+
+func testfunc6() {
+       x, y := func6()
+       if x != 10 || y != 1 {
+               println("wrong results", x, y, "want", 10, 1)
+               panic("testfunc6")
+       }
+}
+
+var saved []int
+
+func save(x int) {
+       saved = append(saved, x)
+}
+
+func printslice(s []int) {
+       print("[")
+       for i, x := range s {
+               if i > 0 {
+                       print(", ")
+               }
+               print(x)
+       }
+       print("]")
+}
+
+func eqslice(s, t []int) bool {
+       if len(s) != len(t) {
+               return false
+       }
+       for i, x := range s {
+               if x != t[i] {
+                       return false
+               }
+       }
+       return true
+}
+
+func func7() {
+       defer save(-1)
+       for i := range yield4 {
+               defer save(i)
+       }
+       defer save(5)
+}
+
+func checkslice(name string, saved, want []int) {
+       if !eqslice(saved, want) {
+               print("wrong results ")
+               printslice(saved)
+               print(" want ")
+               printslice(want)
+               print("\n")
+               panic(name)
+       }
+}
+
+func testfunc7() {
+       saved = nil
+       func7()
+       want := []int{5, 4, 3, 2, 1, -1}
+       checkslice("testfunc7", saved, want)
+}
+
+func func8() {
+       defer save(-1)
+       for i := range yield2 {
+               for j := range yield3 {
+                       defer save(i*10 + j)
+               }
+               defer save(i)
+       }
+       defer save(-2)
+       for i := range yield4 {
+               defer save(i)
+       }
+       defer save(-3)
+}
+
+func testfunc8() {
+       saved = nil
+       func8()
+       want := []int{-3, 4, 3, 2, 1, -2, 2, 23, 22, 21, 1, 13, 12, 11, -1}
+       checkslice("testfunc8", saved, want)
+}
+
+func func9() {
+       n := 0
+       for _ = range yield2 {
+               for _ = range yield3 {
+                       n++
+                       defer save(n)
+               }
+       }
+}
+
+func testfunc9() {
+       saved = nil
+       func9()
+       want := []int{6, 5, 4, 3, 2, 1}
+       checkslice("testfunc9", saved, want)
+}
+
+// test that range evaluates the index and value expressions
+// exactly once per iteration.
+
+var ncalls = 0
+
+func getvar(p *int) *int {
+       ncalls++
+       return p
+}
+
+func iter2(list ...int) func(func(int, int) bool) {
+       return func(yield func(int, int) bool) {
+               for i, x := range list {
+                       if !yield(i, x) {
+                               return
+                       }
+               }
+       }
+}
+
+func testcalls() {
+       var i, v int
+       ncalls = 0
+       si := 0
+       sv := 0
+       for *getvar(&i), *getvar(&v) = range iter2(1, 2) {
+               si += i
+               sv += v
+       }
+       if ncalls != 4 {
+               println("wrong number of calls:", ncalls, "!= 4")
+               panic("fail")
+       }
+       if si != 1 || sv != 3 {
+               println("wrong sum in testcalls", si, sv)
+               panic("fail")
+       }
+}
+
+func main() {
+       testfunc0()
+       testfunc1()
+       testfunc2()
+       testfunc3()
+       testfunc4()
+       testfunc5()
+       testfunc6()
+       testfunc7()
+       testfunc8()
+       testfunc9()
+       testcalls()
+}