1
2
3
4
5 package rangefunc_test
6
7 import (
8 "fmt"
9 "regexp"
10 "slices"
11 "testing"
12 )
13
14 type Seq[T any] func(yield func(T) bool)
15 type Seq2[T1, T2 any] func(yield func(T1, T2) bool)
16
17
18
19 func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] {
20 return func(yield func(int, T) bool) {
21 for i, v := range s {
22 if !yield(i, v) {
23 return
24 }
25 }
26 return
27 }
28 }
29
30
31
32 func BadOfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] {
33 return func(yield func(int, T) bool) {
34 for i, v := range s {
35 yield(i, v)
36 }
37 return
38 }
39 }
40
41
42
43
44 func VeryBadOfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] {
45 return func(yield func(int, T) bool) {
46 for i, v := range s {
47 func() {
48 defer func() {
49 recover()
50 }()
51 yield(i, v)
52 }()
53 }
54 return
55 }
56 }
57
58
59 func SwallowPanicOfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] {
60 return func(yield func(int, T) bool) {
61 for i, v := range s {
62 done := false
63 func() {
64 defer func() {
65 if r := recover(); r != nil {
66 done = true
67 }
68 }()
69 done = !yield(i, v)
70 }()
71 if done {
72 return
73 }
74 }
75 return
76 }
77 }
78
79
80 func PanickyOfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] {
81 return func(yield func(int, T) bool) {
82 for i, v := range s {
83 if !yield(i, v) {
84 panic(fmt.Errorf("Panicky iterator panicking"))
85 }
86 }
87 return
88 }
89 }
90
91
92
93 func CooperativeBadOfSliceIndex[T any, S ~[]T](s S, proceed chan any) Seq2[int, T] {
94 return func(yield func(int, T) bool) {
95 for i, v := range s {
96 if !yield(i, v) {
97
98 go func() {
99 <-proceed
100 defer func() {
101 proceed <- recover()
102 }()
103 yield(0, s[0])
104 }()
105 return
106 }
107 }
108 return
109 }
110 }
111
112
113
114
115 type TrickyIterator struct {
116 yield func(int, int) bool
117 }
118
119 func (ti *TrickyIterator) iterEcho(s []int) Seq2[int, int] {
120 return func(yield func(int, int) bool) {
121 for i, v := range s {
122 if !yield(i, v) {
123 ti.yield = yield
124 return
125 }
126 if ti.yield != nil && !ti.yield(i, v) {
127 return
128 }
129 }
130 ti.yield = yield
131 return
132 }
133 }
134
135 func (ti *TrickyIterator) iterAll(s []int) Seq2[int, int] {
136 return func(yield func(int, int) bool) {
137 ti.yield = yield
138 for i, v := range s {
139 if !yield(i, v) {
140 return
141 }
142 }
143 return
144 }
145 }
146
147 func (ti *TrickyIterator) iterOne(s []int) Seq2[int, int] {
148 return func(yield func(int, int) bool) {
149 ti.yield = yield
150 if len(s) > 0 {
151 yield(0, s[0])
152 }
153 return
154 }
155 }
156
157 func (ti *TrickyIterator) iterZero(s []int) Seq2[int, int] {
158 return func(yield func(int, int) bool) {
159 ti.yield = yield
160
161 return
162 }
163 }
164
165 func (ti *TrickyIterator) fail() {
166 if ti.yield != nil {
167 ti.yield(1, 1)
168 }
169 }
170
171 const DONE = 0
172 const READY = 1
173 const PANIC = 2
174 const EXHAUSTED = 3
175
176 const MISSING_PANIC = 4
177
178
179
180
181
182
183
184 func Check2[U, V any](forall Seq2[U, V]) Seq2[U, V] {
185 return func(body func(U, V) bool) {
186 state := READY
187 forall(func(u U, v V) bool {
188 tmp := state
189 state = PANIC
190 if tmp != READY {
191 panic(fail[tmp])
192 }
193 ret := body(u, v)
194 if ret {
195 state = READY
196 } else {
197 state = DONE
198 }
199 return ret
200 })
201 if state == PANIC {
202 panic(fail[MISSING_PANIC])
203 }
204 state = EXHAUSTED
205 }
206 }
207
208 func Check[U any](forall Seq[U]) Seq[U] {
209 return func(body func(U) bool) {
210 state := READY
211 forall(func(u U) bool {
212 tmp := state
213 state = PANIC
214 if tmp != READY {
215 panic(fail[tmp])
216 }
217 ret := body(u)
218 if ret {
219 state = READY
220 } else {
221 state = DONE
222 }
223 return ret
224 })
225 if state == PANIC {
226 panic(fail[MISSING_PANIC])
227 }
228 state = EXHAUSTED
229 }
230 }
231
232 func matchError(r any, x string) bool {
233 if r == nil {
234 return false
235 }
236 if x == "" {
237 return true
238 }
239 if p, ok := r.(errorString); ok {
240 return p.Error() == x
241 }
242 if p, ok := r.(error); ok {
243 e, err := regexp.Compile(x)
244 if err != nil {
245 panic(fmt.Errorf("Bad regexp '%s' passed to matchError", x))
246 }
247 return e.MatchString(p.Error())
248 }
249 return false
250 }
251
252 func matchErrorHelper(t *testing.T, r any, x string) {
253 if matchError(r, x) {
254 t.Logf("Saw expected panic '%v'", r)
255 } else {
256 t.Errorf("Saw wrong panic '%v', expected '%s'", r, x)
257 }
258 }
259
260
261 type errorString string
262
263 func (e errorString) Error() string {
264 return string(e)
265 }
266
267 const (
268
269 RERR_DONE = "runtime error: range function continued iteration after function for loop body returned false"
270 RERR_PANIC = "runtime error: range function continued iteration after loop body panic"
271 RERR_EXHAUSTED = "runtime error: range function continued iteration after whole loop exit"
272 RERR_MISSING = "runtime error: range function recovered a loop body panic and did not resume panicking"
273
274
275 CERR_PFX = "checked rangefunc error: "
276 CERR_DONE = CERR_PFX + "loop iteration after body done"
277 CERR_PANIC = CERR_PFX + "loop iteration after panic"
278 CERR_EXHAUSTED = CERR_PFX + "loop iteration after iterator exit"
279 CERR_MISSING = CERR_PFX + "loop iterator swallowed panic"
280 )
281
282 var fail []error = []error{
283 errorString(CERR_DONE),
284 errorString(CERR_PFX + "loop iterator, unexpected error"),
285 errorString(CERR_PANIC),
286 errorString(CERR_EXHAUSTED),
287 errorString(CERR_MISSING),
288 }
289
290
291
292
293
294 func TestNoVars(t *testing.T) {
295 i, k := 0, 0
296 for range Check2(OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) {
297 i++
298 }
299 for j := range Check2(OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) {
300 k += j
301 }
302 if i != 10 {
303 t.Errorf("Expected 10, got %d", i)
304 }
305 if k != 45 {
306 t.Errorf("Expected 45, got %d", k)
307 }
308 }
309
310 func TestCheck(t *testing.T) {
311 i := 0
312 defer func() {
313 if r := recover(); r != nil {
314 if matchError(r, CERR_DONE) {
315 t.Logf("Saw expected panic '%v'", r)
316 } else {
317 t.Errorf("Saw wrong panic '%v'", r)
318 }
319 } else {
320 t.Error("Wanted to see a failure")
321 }
322 }()
323 for _, x := range Check2(BadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) {
324 i += x
325 if i > 4*9 {
326 break
327 }
328 }
329 }
330
331 func TestCooperativeBadOfSliceIndex(t *testing.T) {
332 i := 0
333 proceed := make(chan any)
334 for _, x := range CooperativeBadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, proceed) {
335 i += x
336 if i >= 36 {
337 break
338 }
339 }
340 proceed <- true
341 if r := <-proceed; r != nil {
342 if matchError(r, RERR_EXHAUSTED) {
343 t.Logf("Saw expected panic '%v'", r)
344 } else {
345 t.Errorf("Saw wrong panic '%v'", r)
346 }
347 } else {
348 t.Error("Wanted to see a failure")
349 }
350 if i != 36 {
351 t.Errorf("Expected i == 36, saw %d instead", i)
352 } else {
353 t.Logf("i = %d", i)
354 }
355 }
356
357 func TestCooperativeBadOfSliceIndexCheck(t *testing.T) {
358 i := 0
359 proceed := make(chan any)
360 for _, x := range Check2(CooperativeBadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, proceed)) {
361 i += x
362 if i >= 36 {
363 break
364 }
365 }
366 proceed <- true
367 if r := <-proceed; r != nil {
368 if matchError(r, CERR_EXHAUSTED) {
369 t.Logf("Saw expected panic '%v'", r)
370 } else {
371 t.Errorf("Saw wrong panic '%v'", r)
372 }
373
374 } else {
375 t.Error("Wanted to see a failure")
376 }
377 if i != 36 {
378 t.Errorf("Expected i == 36, saw %d instead", i)
379 } else {
380 t.Logf("i = %d", i)
381 }
382 }
383
384 func TestTrickyIterAll(t *testing.T) {
385 trickItAll := TrickyIterator{}
386 i := 0
387 for _, x := range trickItAll.iterAll([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
388 i += x
389 if i >= 36 {
390 break
391 }
392 }
393
394 if i != 36 {
395 t.Errorf("Expected i == 36, saw %d instead", i)
396 } else {
397 t.Logf("i = %d", i)
398 }
399
400 defer func() {
401 if r := recover(); r != nil {
402 if matchError(r, RERR_EXHAUSTED) {
403 t.Logf("Saw expected panic '%v'", r)
404 } else {
405 t.Errorf("Saw wrong panic '%v'", r)
406 }
407 } else {
408 t.Error("Wanted to see a failure")
409 }
410 }()
411
412 trickItAll.fail()
413 }
414
415 func TestTrickyIterOne(t *testing.T) {
416 trickItOne := TrickyIterator{}
417 i := 0
418 for _, x := range trickItOne.iterOne([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
419 i += x
420 if i >= 36 {
421 break
422 }
423 }
424
425
426 t.Logf("i = %d", i)
427
428 defer func() {
429 if r := recover(); r != nil {
430 if matchError(r, RERR_EXHAUSTED) {
431 t.Logf("Saw expected panic '%v'", r)
432 } else {
433 t.Errorf("Saw wrong panic '%v'", r)
434 }
435 } else {
436 t.Error("Wanted to see a failure")
437 }
438 }()
439
440 trickItOne.fail()
441 }
442
443 func TestTrickyIterZero(t *testing.T) {
444 trickItZero := TrickyIterator{}
445 i := 0
446 for _, x := range trickItZero.iterZero([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
447 i += x
448 if i >= 36 {
449 break
450 }
451 }
452
453
454 t.Logf("i = %d", i)
455
456 defer func() {
457 if r := recover(); r != nil {
458 if matchError(r, RERR_EXHAUSTED) {
459 t.Logf("Saw expected panic '%v'", r)
460 } else {
461 t.Errorf("Saw wrong panic '%v'", r)
462 }
463 } else {
464 t.Error("Wanted to see a failure")
465 }
466 }()
467
468 trickItZero.fail()
469 }
470
471 func TestTrickyIterZeroCheck(t *testing.T) {
472 trickItZero := TrickyIterator{}
473 i := 0
474 for _, x := range Check2(trickItZero.iterZero([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) {
475 i += x
476 if i >= 36 {
477 break
478 }
479 }
480
481
482 t.Logf("i = %d", i)
483
484 defer func() {
485 if r := recover(); r != nil {
486 if matchError(r, CERR_EXHAUSTED) {
487 t.Logf("Saw expected panic '%v'", r)
488 } else {
489 t.Errorf("Saw wrong panic '%v'", r)
490 }
491 } else {
492 t.Error("Wanted to see a failure")
493 }
494 }()
495
496 trickItZero.fail()
497 }
498
499 func TestTrickyIterEcho(t *testing.T) {
500 trickItAll := TrickyIterator{}
501 i := 0
502 for _, x := range trickItAll.iterAll([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
503 t.Logf("first loop i=%d", i)
504 i += x
505 if i >= 10 {
506 break
507 }
508 }
509
510 if i != 10 {
511 t.Errorf("Expected i == 10, saw %d instead", i)
512 } else {
513 t.Logf("i = %d", i)
514 }
515
516 defer func() {
517 if r := recover(); r != nil {
518 if matchError(r, RERR_EXHAUSTED) {
519 t.Logf("Saw expected panic '%v'", r)
520 } else {
521 t.Errorf("Saw wrong panic '%v'", r)
522 }
523 } else {
524 t.Error("Wanted to see a failure")
525 }
526 }()
527
528 i = 0
529 for _, x := range trickItAll.iterEcho([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
530 t.Logf("second loop i=%d", i)
531 if x >= 5 {
532 break
533 }
534 }
535
536 }
537
538 func TestTrickyIterEcho2(t *testing.T) {
539 trickItAll := TrickyIterator{}
540 var i int
541
542 defer func() {
543 if r := recover(); r != nil {
544 if matchError(r, RERR_EXHAUSTED) {
545 t.Logf("Saw expected panic '%v'", r)
546 } else {
547 t.Errorf("Saw wrong panic '%v'", r)
548 }
549 } else {
550 t.Error("Wanted to see a failure")
551 }
552 }()
553
554 for k := range 2 {
555 i = 0
556 for _, x := range trickItAll.iterEcho([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
557 t.Logf("k,x,i=%d,%d,%d", k, x, i)
558 i += x
559 if i >= 10 {
560 break
561 }
562 }
563 t.Logf("i = %d", i)
564
565 if i != 10 {
566 t.Errorf("Expected i == 10, saw %d instead", i)
567 }
568 }
569 }
570
571
572
573 func TestBreak1(t *testing.T) {
574 var result []int
575 var expect = []int{1, 2, -1, 1, 2, -2, 1, 2, -3}
576 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4}) {
577 if x == -4 {
578 break
579 }
580 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
581 if y == 3 {
582 break
583 }
584 result = append(result, y)
585 }
586 result = append(result, x)
587 }
588 if !slices.Equal(expect, result) {
589 t.Errorf("Expected %v, got %v", expect, result)
590 }
591 }
592
593
594
595 func TestBreak2(t *testing.T) {
596 var result []int
597 var expect = []int{1, 2, -1, 1, 2, -2, 1, 2, -3}
598 outer:
599 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4}) {
600 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
601 if y == 3 {
602 break
603 }
604 if x == -4 {
605 break outer
606 }
607
608 result = append(result, y)
609 }
610 result = append(result, x)
611 }
612 if !slices.Equal(expect, result) {
613 t.Errorf("Expected %v, got %v", expect, result)
614 }
615 }
616
617
618
619 func TestContinue(t *testing.T) {
620 var result []int
621 var expect = []int{-1, 1, 2, -2, 1, 2, -3, 1, 2, -4}
622 outer:
623 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4}) {
624 result = append(result, x)
625 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
626 if y == 3 {
627 continue outer
628 }
629 if x == -4 {
630 break outer
631 }
632
633 result = append(result, y)
634 }
635 result = append(result, x-10)
636 }
637 if !slices.Equal(expect, result) {
638 t.Errorf("Expected %v, got %v", expect, result)
639 }
640 }
641
642
643
644 func TestBreak3(t *testing.T) {
645 var result []int
646 var expect = []int{100, 10, 2, 4, 200, 10, 2, 4, 20, 2, 4, 300, 10, 2, 4, 20, 2, 4, 30}
647 X:
648 for _, x := range OfSliceIndex([]int{100, 200, 300, 400}) {
649 Y:
650 for _, y := range OfSliceIndex([]int{10, 20, 30, 40}) {
651 if 10*y >= x {
652 break
653 }
654 result = append(result, y)
655 if y == 30 {
656 continue X
657 }
658 Z:
659 for _, z := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
660 if z&1 == 1 {
661 continue Z
662 }
663 result = append(result, z)
664 if z >= 4 {
665 continue Y
666 }
667 }
668 result = append(result, -y)
669 }
670 result = append(result, x)
671 }
672 if !slices.Equal(expect, result) {
673 t.Errorf("Expected %v, got %v", expect, result)
674 }
675 }
676
677
678
679 func TestBreak1BadA(t *testing.T) {
680 var result []int
681 var expect = []int{1, 2, -1, 1, 2, -2, 1, 2, -3}
682
683 defer func() {
684 if r := recover(); r != nil {
685 if matchError(r, RERR_DONE) {
686 t.Logf("Saw expected panic '%v'", r)
687 } else {
688 t.Errorf("Saw wrong panic '%v'", r)
689 }
690 if !slices.Equal(expect, result) {
691 t.Errorf("Expected %v, got %v", expect, result)
692 }
693 } else {
694 t.Error("Wanted to see a failure")
695 }
696 }()
697
698 for _, x := range BadOfSliceIndex([]int{-1, -2, -3, -4, -5}) {
699 if x == -4 {
700 break
701 }
702 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
703 if y == 3 {
704 break
705 }
706 result = append(result, y)
707 }
708 result = append(result, x)
709 }
710 }
711
712
713
714 func TestBreak1BadB(t *testing.T) {
715 var result []int
716 var expect = []int{1, 2}
717
718 defer func() {
719 if r := recover(); r != nil {
720 if matchError(r, RERR_DONE) {
721 t.Logf("Saw expected panic '%v'", r)
722 } else {
723 t.Errorf("Saw wrong panic '%v'", r)
724 }
725 if !slices.Equal(expect, result) {
726 t.Errorf("Expected %v, got %v", expect, result)
727 }
728 } else {
729 t.Error("Wanted to see a failure")
730 }
731 }()
732
733 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
734 if x == -4 {
735 break
736 }
737 for _, y := range BadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
738 if y == 3 {
739 break
740 }
741 result = append(result, y)
742 }
743 result = append(result, x)
744 }
745 }
746
747
748
749 func TestMultiCont0(t *testing.T) {
750 var result []int
751 var expect = []int{1000, 10, 2, 4, 2000}
752
753 W:
754 for _, w := range OfSliceIndex([]int{1000, 2000}) {
755 result = append(result, w)
756 if w == 2000 {
757 break
758 }
759 for _, x := range OfSliceIndex([]int{100, 200, 300, 400}) {
760 for _, y := range OfSliceIndex([]int{10, 20, 30, 40}) {
761 result = append(result, y)
762 for _, z := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
763 if z&1 == 1 {
764 continue
765 }
766 result = append(result, z)
767 if z >= 4 {
768 continue W
769 }
770 }
771 result = append(result, -y)
772 }
773 result = append(result, x)
774 }
775 }
776 if !slices.Equal(expect, result) {
777 t.Errorf("Expected %v, got %v", expect, result)
778 }
779 }
780
781
782
783 func TestMultiCont1(t *testing.T) {
784 var result []int
785 var expect = []int{1000, 10, 2, 4}
786 defer func() {
787 if r := recover(); r != nil {
788 if matchError(r, RERR_DONE) {
789 t.Logf("Saw expected panic '%v'", r)
790 } else {
791 t.Errorf("Saw wrong panic '%v'", r)
792 }
793 if !slices.Equal(expect, result) {
794 t.Errorf("Expected %v, got %v", expect, result)
795 }
796 } else {
797 t.Errorf("Wanted to see a failure, result was %v", result)
798 }
799 }()
800
801 W:
802 for _, w := range OfSliceIndex([]int{1000, 2000}) {
803 result = append(result, w)
804 if w == 2000 {
805 break
806 }
807 for _, x := range BadOfSliceIndex([]int{100, 200, 300, 400}) {
808 for _, y := range OfSliceIndex([]int{10, 20, 30, 40}) {
809 result = append(result, y)
810 for _, z := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
811 if z&1 == 1 {
812 continue
813 }
814 result = append(result, z)
815 if z >= 4 {
816 continue W
817 }
818 }
819 result = append(result, -y)
820 }
821 result = append(result, x)
822 }
823 }
824 if !slices.Equal(expect, result) {
825 t.Errorf("Expected %v, got %v", expect, result)
826 }
827 }
828
829
830
831 func TestMultiCont2(t *testing.T) {
832 var result []int
833 var expect = []int{1000, 10, 2, 4}
834 defer func() {
835 if r := recover(); r != nil {
836 if matchError(r, RERR_DONE) {
837 t.Logf("Saw expected panic '%v'", r)
838 } else {
839 t.Errorf("Saw wrong panic '%v'", r)
840 }
841 if !slices.Equal(expect, result) {
842 t.Errorf("Expected %v, got %v", expect, result)
843 }
844 } else {
845 t.Errorf("Wanted to see a failure, result was %v", result)
846 }
847 }()
848
849 W:
850 for _, w := range OfSliceIndex([]int{1000, 2000}) {
851 result = append(result, w)
852 if w == 2000 {
853 break
854 }
855 for _, x := range OfSliceIndex([]int{100, 200, 300, 400}) {
856 for _, y := range BadOfSliceIndex([]int{10, 20, 30, 40}) {
857 result = append(result, y)
858 for _, z := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
859 if z&1 == 1 {
860 continue
861 }
862 result = append(result, z)
863 if z >= 4 {
864 continue W
865 }
866 }
867 result = append(result, -y)
868 }
869 result = append(result, x)
870 }
871 }
872 if !slices.Equal(expect, result) {
873 t.Errorf("Expected %v, got %v", expect, result)
874 }
875 }
876
877
878
879 func TestMultiCont3(t *testing.T) {
880 var result []int
881 var expect = []int{1000, 10, 2, 4}
882 defer func() {
883 if r := recover(); r != nil {
884 if matchError(r, RERR_DONE) {
885 t.Logf("Saw expected panic '%v'", r)
886 } else {
887 t.Errorf("Saw wrong panic '%v'", r)
888 }
889 if !slices.Equal(expect, result) {
890 t.Errorf("Expected %v, got %v", expect, result)
891 }
892 } else {
893 t.Errorf("Wanted to see a failure, result was %v", result)
894 }
895 }()
896
897 W:
898 for _, w := range OfSliceIndex([]int{1000, 2000}) {
899 result = append(result, w)
900 if w == 2000 {
901 break
902 }
903 for _, x := range OfSliceIndex([]int{100, 200, 300, 400}) {
904 for _, y := range OfSliceIndex([]int{10, 20, 30, 40}) {
905 result = append(result, y)
906 for _, z := range BadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
907 if z&1 == 1 {
908 continue
909 }
910 result = append(result, z)
911 if z >= 4 {
912 continue W
913 }
914 }
915 result = append(result, -y)
916 }
917 result = append(result, x)
918 }
919 }
920 if !slices.Equal(expect, result) {
921 t.Errorf("Expected %v, got %v", expect, result)
922 }
923 }
924
925
926
927 func TestMultiBreak0(t *testing.T) {
928 var result []int
929 var expect = []int{1000, 10, 2, 4}
930 defer func() {
931 if r := recover(); r != nil {
932 if matchError(r, RERR_DONE) {
933 t.Logf("Saw expected panic '%v'", r)
934 } else {
935 t.Errorf("Saw wrong panic '%v'", r)
936 }
937 if !slices.Equal(expect, result) {
938 t.Errorf("Expected %v, got %v", expect, result)
939 }
940 } else {
941 t.Errorf("Wanted to see a failure, result was %v", result)
942 }
943 }()
944
945 W:
946 for _, w := range BadOfSliceIndex([]int{1000, 2000}) {
947 result = append(result, w)
948 if w == 2000 {
949 break
950 }
951 for _, x := range OfSliceIndex([]int{100, 200, 300, 400}) {
952 for _, y := range OfSliceIndex([]int{10, 20, 30, 40}) {
953 result = append(result, y)
954 for _, z := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
955 if z&1 == 1 {
956 continue
957 }
958 result = append(result, z)
959 if z >= 4 {
960 break W
961 }
962 }
963 result = append(result, -y)
964 }
965 result = append(result, x)
966 }
967 }
968 if !slices.Equal(expect, result) {
969 t.Errorf("Expected %v, got %v", expect, result)
970 }
971 }
972
973
974
975 func TestMultiBreak1(t *testing.T) {
976 var result []int
977 var expect = []int{1000, 10, 2, 4}
978 defer func() {
979 if r := recover(); r != nil {
980 if matchError(r, RERR_DONE) {
981 t.Logf("Saw expected panic '%v'", r)
982 } else {
983 t.Errorf("Saw wrong panic '%v'", r)
984 }
985 if !slices.Equal(expect, result) {
986 t.Errorf("Expected %v, got %v", expect, result)
987 }
988 } else {
989 t.Errorf("Wanted to see a failure, result was %v", result)
990 }
991 }()
992
993 W:
994 for _, w := range OfSliceIndex([]int{1000, 2000}) {
995 result = append(result, w)
996 if w == 2000 {
997 break
998 }
999 for _, x := range BadOfSliceIndex([]int{100, 200, 300, 400}) {
1000 for _, y := range OfSliceIndex([]int{10, 20, 30, 40}) {
1001 result = append(result, y)
1002 for _, z := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1003 if z&1 == 1 {
1004 continue
1005 }
1006 result = append(result, z)
1007 if z >= 4 {
1008 break W
1009 }
1010 }
1011 result = append(result, -y)
1012 }
1013 result = append(result, x)
1014 }
1015 }
1016 if !slices.Equal(expect, result) {
1017 t.Errorf("Expected %v, got %v", expect, result)
1018 }
1019 }
1020
1021
1022
1023 func TestMultiBreak2(t *testing.T) {
1024 var result []int
1025 var expect = []int{1000, 10, 2, 4}
1026 defer func() {
1027 if r := recover(); r != nil {
1028 if matchError(r, RERR_DONE) {
1029 t.Logf("Saw expected panic '%v'", r)
1030 } else {
1031 t.Errorf("Saw wrong panic '%v'", r)
1032 }
1033 if !slices.Equal(expect, result) {
1034 t.Errorf("Expected %v, got %v", expect, result)
1035 }
1036 } else {
1037 t.Errorf("Wanted to see a failure, result was %v", result)
1038 }
1039 }()
1040
1041 W:
1042 for _, w := range OfSliceIndex([]int{1000, 2000}) {
1043 result = append(result, w)
1044 if w == 2000 {
1045 break
1046 }
1047 for _, x := range BadOfSliceIndex([]int{100, 200, 300, 400}) {
1048 for _, y := range BadOfSliceIndex([]int{10, 20, 30, 40}) {
1049 result = append(result, y)
1050 for _, z := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1051 if z&1 == 1 {
1052 continue
1053 }
1054 result = append(result, z)
1055 if z >= 4 {
1056 break W
1057 }
1058 }
1059 result = append(result, -y)
1060 }
1061 result = append(result, x)
1062 }
1063 }
1064 if !slices.Equal(expect, result) {
1065 t.Errorf("Expected %v, got %v", expect, result)
1066 }
1067 }
1068
1069
1070
1071 func TestMultiBreak3(t *testing.T) {
1072 var result []int
1073 var expect = []int{1000, 10, 2, 4}
1074 defer func() {
1075 if r := recover(); r != nil {
1076 if matchError(r, RERR_DONE) {
1077 t.Logf("Saw expected panic '%v'", r)
1078 } else {
1079 t.Errorf("Saw wrong panic '%v'", r)
1080 }
1081 if !slices.Equal(expect, result) {
1082 t.Errorf("Expected %v, got %v", expect, result)
1083 }
1084 } else {
1085 t.Errorf("Wanted to see a failure, result was %v", result)
1086 }
1087 }()
1088
1089 W:
1090 for _, w := range OfSliceIndex([]int{1000, 2000}) {
1091 result = append(result, w)
1092 if w == 2000 {
1093 break
1094 }
1095 for _, x := range OfSliceIndex([]int{100, 200, 300, 400}) {
1096 for _, y := range OfSliceIndex([]int{10, 20, 30, 40}) {
1097 result = append(result, y)
1098 for _, z := range BadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1099 if z&1 == 1 {
1100 continue
1101 }
1102 result = append(result, z)
1103 if z >= 4 {
1104 break W
1105 }
1106 }
1107 result = append(result, -y)
1108 }
1109 result = append(result, x)
1110 }
1111 }
1112 if !slices.Equal(expect, result) {
1113 t.Errorf("Expected %v, got %v", expect, result)
1114 }
1115 }
1116
1117 func TestPanickyIterator1(t *testing.T) {
1118 var result []int
1119 var expect = []int{1, 2, 3, 4}
1120 defer func() {
1121 if r := recover(); r != nil {
1122 if matchError(r, "Panicky iterator panicking") {
1123 t.Logf("Saw expected panic '%v'", r)
1124 } else {
1125 t.Errorf("Saw wrong panic '%v'", r)
1126 }
1127 if !slices.Equal(expect, result) {
1128 t.Errorf("Expected %v, got %v", expect, result)
1129 }
1130 } else {
1131 t.Errorf("Wanted to see a failure, result was %v", result)
1132 }
1133 }()
1134 for _, z := range PanickyOfSliceIndex([]int{1, 2, 3, 4}) {
1135 result = append(result, z)
1136 if z == 4 {
1137 break
1138 }
1139 }
1140 }
1141
1142 func TestPanickyIterator1Check(t *testing.T) {
1143 var result []int
1144 var expect = []int{1, 2, 3, 4}
1145 defer func() {
1146 if r := recover(); r != nil {
1147 if matchError(r, "Panicky iterator panicking") {
1148 t.Logf("Saw expected panic '%v'", r)
1149 } else {
1150 t.Errorf("Saw wrong panic '%v'", r)
1151 }
1152 if !slices.Equal(expect, result) {
1153 t.Errorf("Expected %v, got %v", expect, result)
1154 }
1155 } else {
1156 t.Errorf("Wanted to see a failure, result was %v", result)
1157 }
1158 }()
1159 for _, z := range Check2(PanickyOfSliceIndex([]int{1, 2, 3, 4})) {
1160 result = append(result, z)
1161 if z == 4 {
1162 break
1163 }
1164 }
1165 }
1166
1167 func TestPanickyIterator2(t *testing.T) {
1168 var result []int
1169 var expect = []int{100, 10, 1, 2}
1170 defer func() {
1171 if r := recover(); r != nil {
1172 if matchError(r, RERR_MISSING) {
1173 t.Logf("Saw expected panic '%v'", r)
1174 } else {
1175 t.Errorf("Saw wrong panic '%v'", r)
1176 }
1177 if !slices.Equal(expect, result) {
1178 t.Errorf("Expected %v, got %v", expect, result)
1179 }
1180 } else {
1181 t.Errorf("Wanted to see a failure, result was %v", result)
1182 }
1183 }()
1184 for _, x := range OfSliceIndex([]int{100, 200}) {
1185 result = append(result, x)
1186 Y:
1187
1188 for _, y := range VeryBadOfSliceIndex([]int{10, 20}) {
1189 result = append(result, y)
1190
1191
1192 for k, z := range PanickyOfSliceIndex([]int{1, 2}) {
1193 result = append(result, z)
1194 if k == 1 {
1195 break Y
1196 }
1197 }
1198 }
1199 }
1200 }
1201
1202 func TestPanickyIterator2Check(t *testing.T) {
1203 var result []int
1204 var expect = []int{100, 10, 1, 2}
1205 defer func() {
1206 if r := recover(); r != nil {
1207 if matchError(r, CERR_MISSING) {
1208 t.Logf("Saw expected panic '%v'", r)
1209 } else {
1210 t.Errorf("Saw wrong panic '%v'", r)
1211 }
1212 if !slices.Equal(expect, result) {
1213 t.Errorf("Expected %v, got %v", expect, result)
1214 }
1215 } else {
1216 t.Errorf("Wanted to see a panic, result was %v", result)
1217 }
1218 }()
1219 for _, x := range Check2(OfSliceIndex([]int{100, 200})) {
1220 result = append(result, x)
1221 Y:
1222
1223 for _, y := range Check2(VeryBadOfSliceIndex([]int{10, 20})) {
1224 result = append(result, y)
1225
1226
1227 for k, z := range Check2(PanickyOfSliceIndex([]int{1, 2})) {
1228 result = append(result, z)
1229 if k == 1 {
1230 break Y
1231 }
1232 }
1233 }
1234 }
1235 }
1236
1237 func TestPanickyIterator3(t *testing.T) {
1238 var result []int
1239 var expect = []int{100, 10, 1, 2}
1240 defer func() {
1241 if r := recover(); r != nil {
1242 if matchError(r, RERR_MISSING) {
1243 t.Logf("Saw expected panic '%v'", r)
1244 } else {
1245 t.Errorf("Saw wrong panic '%v'", r)
1246 }
1247 if !slices.Equal(expect, result) {
1248 t.Errorf("Expected %v, got %v", expect, result)
1249 }
1250 } else {
1251 t.Errorf("Wanted to see a panic, result was %v", result)
1252 }
1253 }()
1254 for _, x := range OfSliceIndex([]int{100, 200}) {
1255 result = append(result, x)
1256 Y:
1257
1258
1259 for _, y := range VeryBadOfSliceIndex([]int{10, 20}) {
1260 result = append(result, y)
1261
1262 for k, z := range OfSliceIndex([]int{1, 2}) {
1263 result = append(result, z)
1264 if k == 1 {
1265 break Y
1266 }
1267 }
1268 }
1269 }
1270 }
1271 func TestPanickyIterator3Check(t *testing.T) {
1272 var result []int
1273 var expect = []int{100, 10, 1, 2}
1274 defer func() {
1275 if r := recover(); r != nil {
1276 if matchError(r, CERR_MISSING) {
1277 t.Logf("Saw expected panic '%v'", r)
1278 } else {
1279 t.Errorf("Saw wrong panic '%v'", r)
1280 }
1281 if !slices.Equal(expect, result) {
1282 t.Errorf("Expected %v, got %v", expect, result)
1283 }
1284 } else {
1285 t.Errorf("Wanted to see a panic, result was %v", result)
1286 }
1287 }()
1288 for _, x := range Check2(OfSliceIndex([]int{100, 200})) {
1289 result = append(result, x)
1290 Y:
1291
1292 for _, y := range Check2(VeryBadOfSliceIndex([]int{10, 20})) {
1293 result = append(result, y)
1294
1295 for k, z := range Check2(OfSliceIndex([]int{1, 2})) {
1296 result = append(result, z)
1297 if k == 1 {
1298 break Y
1299 }
1300 }
1301 }
1302 }
1303 }
1304
1305 func TestPanickyIterator4(t *testing.T) {
1306 var result []int
1307 var expect = []int{1, 2, 3}
1308 defer func() {
1309 if r := recover(); r != nil {
1310 if matchError(r, RERR_MISSING) {
1311 t.Logf("Saw expected panic '%v'", r)
1312 } else {
1313 t.Errorf("Saw wrong panic '%v'", r)
1314 }
1315 if !slices.Equal(expect, result) {
1316 t.Errorf("Expected %v, got %v", expect, result)
1317 }
1318 } else {
1319 t.Errorf("Wanted to see a panic, result was %v", result)
1320 }
1321 }()
1322 for _, x := range SwallowPanicOfSliceIndex([]int{1, 2, 3, 4}) {
1323 result = append(result, x)
1324 if x == 3 {
1325 panic("x is 3")
1326 }
1327 }
1328
1329 }
1330 func TestPanickyIterator4Check(t *testing.T) {
1331 var result []int
1332 var expect = []int{1, 2, 3}
1333 defer func() {
1334 if r := recover(); r != nil {
1335 if matchError(r, CERR_MISSING) {
1336 t.Logf("Saw expected panic '%v'", r)
1337 } else {
1338 t.Errorf("Saw wrong panic '%v'", r)
1339 }
1340 if !slices.Equal(expect, result) {
1341 t.Errorf("Expected %v, got %v", expect, result)
1342 }
1343 } else {
1344 t.Errorf("Wanted to see a panic, result was %v", result)
1345 }
1346 }()
1347 for _, x := range Check2(SwallowPanicOfSliceIndex([]int{1, 2, 3, 4})) {
1348 result = append(result, x)
1349 if x == 3 {
1350 panic("x is 3")
1351 }
1352 }
1353
1354 }
1355
1356
1357
1358
1359
1360 func veryBad(s []int) []int {
1361 var result []int
1362 X:
1363 for _, x := range OfSliceIndex([]int{1, 2, 3}) {
1364
1365 result = append(result, x)
1366
1367 for _, y := range VeryBadOfSliceIndex(s) {
1368 result = append(result, y)
1369 break X
1370 }
1371 for _, z := range OfSliceIndex([]int{100, 200, 300}) {
1372 result = append(result, z)
1373 if z == 100 {
1374 break
1375 }
1376 }
1377 }
1378 return result
1379 }
1380
1381
1382
1383
1384 func veryBadCheck(s []int) []int {
1385 var result []int
1386 X:
1387 for _, x := range OfSliceIndex([]int{1, 2, 3}) {
1388
1389 result = append(result, x)
1390
1391 for _, y := range Check2(VeryBadOfSliceIndex(s)) {
1392 result = append(result, y)
1393 break X
1394 }
1395 for _, z := range OfSliceIndex([]int{100, 200, 300}) {
1396 result = append(result, z)
1397 if z == 100 {
1398 break
1399 }
1400 }
1401 }
1402 return result
1403 }
1404
1405
1406
1407 func okay(s []int) []int {
1408 var result []int
1409 X:
1410 for _, x := range OfSliceIndex([]int{1, 2, 3}) {
1411
1412 result = append(result, x)
1413
1414 for _, y := range OfSliceIndex(s) {
1415 result = append(result, y)
1416 break X
1417 }
1418 for _, z := range OfSliceIndex([]int{100, 200, 300}) {
1419 result = append(result, z)
1420 if z == 100 {
1421 break
1422 }
1423 }
1424 }
1425 return result
1426 }
1427
1428
1429 func TestVeryBad1(t *testing.T) {
1430 expect := []int{}
1431 var result []int
1432
1433 defer func() {
1434 if r := recover(); r != nil {
1435 expectPanic(t, r, RERR_MISSING)
1436 if !slices.Equal(expect, result) {
1437 t.Errorf("(Inner) Expected %v, got %v", expect, result)
1438 }
1439 } else {
1440 t.Error("Wanted to see a failure")
1441 }
1442 }()
1443
1444 result = veryBad([]int{10, 20, 30, 40, 50})
1445
1446 }
1447
1448 func expectPanic(t *testing.T, r any, s string) {
1449 if matchError(r, s) {
1450 t.Logf("Saw expected panic '%v'", r)
1451 } else {
1452 t.Errorf("Saw wrong panic '%v'", r)
1453 }
1454 }
1455
1456 func expectError(t *testing.T, err any, s string) {
1457 if matchError(err, s) {
1458 t.Logf("Saw expected error '%v'", err)
1459 } else {
1460 t.Errorf("Saw wrong error '%v'", err)
1461 }
1462 }
1463
1464
1465 func TestVeryBad2(t *testing.T) {
1466 result := []int{}
1467 expect := []int{}
1468
1469 defer func() {
1470 if r := recover(); r != nil {
1471 expectPanic(t, r, RERR_MISSING)
1472 if !slices.Equal(expect, result) {
1473 t.Errorf("(Inner) Expected %v, got %v", expect, result)
1474 }
1475 } else {
1476 t.Error("Wanted to see a failure")
1477 }
1478 }()
1479
1480 result = veryBad([]int{10, 20, 30, 40})
1481
1482 }
1483
1484
1485
1486 func TestVeryBadCheck(t *testing.T) {
1487 expect := []int{}
1488 var result []int
1489 defer func() {
1490 if r := recover(); r != nil {
1491 expectPanic(t, r, CERR_MISSING)
1492 }
1493 if !slices.Equal(expect, result) {
1494 t.Errorf("Expected %v, got %v", expect, result)
1495 }
1496 }()
1497
1498 result = veryBadCheck([]int{10, 20, 30, 40})
1499
1500 }
1501
1502
1503 func TestOk(t *testing.T) {
1504 result := okay([]int{10, 20, 30, 40, 50})
1505 expect := []int{1, 10}
1506
1507 if !slices.Equal(expect, result) {
1508 t.Errorf("Expected %v, got %v", expect, result)
1509 }
1510 }
1511
1512
1513
1514
1515 func testBreak1BadDefer(t *testing.T) (result []int) {
1516 var expect = []int{1, 2, -1, 1, 2, -2, 1, 2, -3, -30, -20, -10}
1517
1518 defer func() {
1519 if r := recover(); r != nil {
1520 if matchError(r, RERR_DONE) {
1521 t.Logf("Saw expected panic '%v'", r)
1522 } else {
1523 t.Errorf("Saw wrong panic '%v'", r)
1524 }
1525 if !slices.Equal(expect, result) {
1526 t.Errorf("(Inner) Expected %v, got %v", expect, result)
1527 }
1528 } else {
1529 t.Error("Wanted to see a failure")
1530 }
1531 }()
1532
1533 for _, x := range BadOfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1534 if x == -4 {
1535 break
1536 }
1537 defer func() {
1538 result = append(result, x*10)
1539 }()
1540 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1541 if y == 3 {
1542 break
1543 }
1544 result = append(result, y)
1545 }
1546 result = append(result, x)
1547 }
1548 return
1549 }
1550
1551 func TestBreak1BadDefer(t *testing.T) {
1552 var result []int
1553 var expect = []int{1, 2, -1, 1, 2, -2, 1, 2, -3, -30, -20, -10}
1554 result = testBreak1BadDefer(t)
1555 if !slices.Equal(expect, result) {
1556 t.Errorf("(Outer) Expected %v, got %v", expect, result)
1557 }
1558 }
1559
1560
1561 func testReturn1(t *testing.T) (result []int, err any) {
1562 defer func() {
1563 err = recover()
1564 }()
1565 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1566 result = append(result, x)
1567 if x == -4 {
1568 break
1569 }
1570 defer func() {
1571 result = append(result, x*10)
1572 }()
1573 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1574 if y == 3 {
1575 return
1576 }
1577 result = append(result, y)
1578 }
1579 result = append(result, x)
1580 }
1581 return
1582 }
1583
1584
1585 func testReturn2(t *testing.T) (result []int, err any) {
1586 defer func() {
1587 err = recover()
1588 }()
1589 for _, x := range BadOfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1590 result = append(result, x)
1591 if x == -4 {
1592 break
1593 }
1594 defer func() {
1595 result = append(result, x*10)
1596 }()
1597 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1598 if y == 3 {
1599 return
1600 }
1601 result = append(result, y)
1602 }
1603 result = append(result, x)
1604 }
1605 return
1606 }
1607
1608
1609 func testReturn3(t *testing.T) (result []int, err any) {
1610 defer func() {
1611 err = recover()
1612 }()
1613 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1614 result = append(result, x)
1615 if x == -4 {
1616 break
1617 }
1618 defer func() {
1619 result = append(result, x*10)
1620 }()
1621 for _, y := range BadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1622 if y == 3 {
1623 return
1624 }
1625 result = append(result, y)
1626 }
1627 }
1628 return
1629 }
1630
1631
1632
1633
1634 func testReturn4(t *testing.T) (_ []int, _ []int, err any) {
1635 var result []int
1636 defer func() {
1637 err = recover()
1638 }()
1639 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1640 result = append(result, x)
1641 if x == -4 {
1642 break
1643 }
1644 defer func() {
1645 result = append(result, x*10)
1646 }()
1647 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1648 if y == 3 {
1649 return result, result, nil
1650 }
1651 result = append(result, y)
1652 }
1653 result = append(result, x)
1654 }
1655 return
1656 }
1657
1658
1659
1660 func TestReturns(t *testing.T) {
1661 var result []int
1662 var result2 []int
1663 var expect = []int{-1, 1, 2, -10}
1664 var expect2 = []int{-1, 1, 2}
1665 var err any
1666
1667 result, err = testReturn1(t)
1668 if !slices.Equal(expect, result) {
1669 t.Errorf("Expected %v, got %v", expect, result)
1670 }
1671 if err != nil {
1672 t.Errorf("Unexpected error %v", err)
1673 }
1674
1675 result, err = testReturn2(t)
1676 if !slices.Equal(expect, result) {
1677 t.Errorf("Expected %v, got %v", expect, result)
1678 }
1679 if err == nil {
1680 t.Errorf("Missing expected error")
1681 } else {
1682 if matchError(err, RERR_DONE) {
1683 t.Logf("Saw expected panic '%v'", err)
1684 } else {
1685 t.Errorf("Saw wrong panic '%v'", err)
1686 }
1687 }
1688
1689 result, err = testReturn3(t)
1690 if !slices.Equal(expect, result) {
1691 t.Errorf("Expected %v, got %v", expect, result)
1692 }
1693 if err == nil {
1694 t.Errorf("Missing expected error")
1695 } else {
1696 if matchError(err, RERR_DONE) {
1697 t.Logf("Saw expected panic '%v'", err)
1698 } else {
1699 t.Errorf("Saw wrong panic '%v'", err)
1700 }
1701 }
1702
1703 result, result2, err = testReturn4(t)
1704 if !slices.Equal(expect2, result) {
1705 t.Errorf("Expected %v, got %v", expect2, result)
1706 }
1707 if !slices.Equal(expect2, result2) {
1708 t.Errorf("Expected %v, got %v", expect2, result2)
1709 }
1710 if err != nil {
1711 t.Errorf("Unexpected error %v", err)
1712 }
1713 }
1714
1715
1716 func testGotoA1(t *testing.T) (result []int, err any) {
1717 defer func() {
1718 err = recover()
1719 }()
1720 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1721 result = append(result, x)
1722 if x == -4 {
1723 break
1724 }
1725 defer func() {
1726 result = append(result, x*10)
1727 }()
1728 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1729 if y == 3 {
1730 goto A
1731 }
1732 result = append(result, y)
1733 }
1734 result = append(result, x)
1735 A:
1736 }
1737 return
1738 }
1739
1740
1741 func testGotoA2(t *testing.T) (result []int, err any) {
1742 defer func() {
1743 err = recover()
1744 }()
1745 for _, x := range BadOfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1746 result = append(result, x)
1747 if x == -4 {
1748 break
1749 }
1750 defer func() {
1751 result = append(result, x*10)
1752 }()
1753 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1754 if y == 3 {
1755 goto A
1756 }
1757 result = append(result, y)
1758 }
1759 result = append(result, x)
1760 A:
1761 }
1762 return
1763 }
1764
1765
1766 func testGotoA3(t *testing.T) (result []int, err any) {
1767 defer func() {
1768 err = recover()
1769 }()
1770 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1771 result = append(result, x)
1772 if x == -4 {
1773 break
1774 }
1775 defer func() {
1776 result = append(result, x*10)
1777 }()
1778 for _, y := range BadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1779 if y == 3 {
1780 goto A
1781 }
1782 result = append(result, y)
1783 }
1784 result = append(result, x)
1785 A:
1786 }
1787 return
1788 }
1789
1790 func TestGotoA(t *testing.T) {
1791 var result []int
1792 var expect = []int{-1, 1, 2, -2, 1, 2, -3, 1, 2, -4, -30, -20, -10}
1793 var expect3 = []int{-1, 1, 2, -10}
1794 var err any
1795
1796 result, err = testGotoA1(t)
1797 if !slices.Equal(expect, result) {
1798 t.Errorf("Expected %v, got %v", expect, result)
1799 }
1800 if err != nil {
1801 t.Errorf("Unexpected error %v", err)
1802 }
1803
1804 result, err = testGotoA2(t)
1805 if !slices.Equal(expect, result) {
1806 t.Errorf("Expected %v, got %v", expect, result)
1807 }
1808 if err == nil {
1809 t.Errorf("Missing expected error")
1810 } else {
1811 if matchError(err, RERR_DONE) {
1812 t.Logf("Saw expected panic '%v'", err)
1813 } else {
1814 t.Errorf("Saw wrong panic '%v'", err)
1815 }
1816 }
1817
1818 result, err = testGotoA3(t)
1819 if !slices.Equal(expect3, result) {
1820 t.Errorf("Expected %v, got %v", expect3, result)
1821 }
1822 if err == nil {
1823 t.Errorf("Missing expected error")
1824 } else {
1825 if matchError(err, RERR_DONE) {
1826 t.Logf("Saw expected panic '%v'", err)
1827 } else {
1828 t.Errorf("Saw wrong panic '%v'", err)
1829 }
1830 }
1831 }
1832
1833
1834 func testGotoB1(t *testing.T) (result []int, err any) {
1835 defer func() {
1836 err = recover()
1837 }()
1838 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1839 result = append(result, x)
1840 if x == -4 {
1841 break
1842 }
1843 defer func() {
1844 result = append(result, x*10)
1845 }()
1846 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1847 if y == 3 {
1848 goto B
1849 }
1850 result = append(result, y)
1851 }
1852 result = append(result, x)
1853 }
1854 B:
1855 result = append(result, 999)
1856 return
1857 }
1858
1859
1860 func testGotoB2(t *testing.T) (result []int, err any) {
1861 defer func() {
1862 err = recover()
1863 }()
1864 for _, x := range BadOfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1865 result = append(result, x)
1866 if x == -4 {
1867 break
1868 }
1869 defer func() {
1870 result = append(result, x*10)
1871 }()
1872 for _, y := range OfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1873 if y == 3 {
1874 goto B
1875 }
1876 result = append(result, y)
1877 }
1878 result = append(result, x)
1879 }
1880 B:
1881 result = append(result, 999)
1882 return
1883 }
1884
1885
1886 func testGotoB3(t *testing.T) (result []int, err any) {
1887 defer func() {
1888 err = recover()
1889 }()
1890 for _, x := range OfSliceIndex([]int{-1, -2, -3, -4, -5}) {
1891 result = append(result, x)
1892 if x == -4 {
1893 break
1894 }
1895 defer func() {
1896 result = append(result, x*10)
1897 }()
1898 for _, y := range BadOfSliceIndex([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
1899 if y == 3 {
1900 goto B
1901 }
1902 result = append(result, y)
1903 }
1904 result = append(result, x)
1905 }
1906 B:
1907 result = append(result, 999)
1908 return
1909 }
1910
1911 func TestGotoB(t *testing.T) {
1912 var result []int
1913 var expect = []int{-1, 1, 2, 999, -10}
1914 var expectX = []int{-1, 1, 2, -10}
1915 var err any
1916
1917 result, err = testGotoB1(t)
1918 if !slices.Equal(expect, result) {
1919 t.Errorf("Expected %v, got %v", expect, result)
1920 }
1921 if err != nil {
1922 t.Errorf("Unexpected error %v", err)
1923 }
1924
1925 result, err = testGotoB2(t)
1926 if !slices.Equal(expectX, result) {
1927 t.Errorf("Expected %v, got %v", expectX, result)
1928 }
1929 if err == nil {
1930 t.Errorf("Missing expected error")
1931 } else {
1932 if matchError(err, RERR_DONE) {
1933 t.Logf("Saw expected panic '%v'", err)
1934 } else {
1935 t.Errorf("Saw wrong panic '%v'", err)
1936 }
1937 }
1938
1939 result, err = testGotoB3(t)
1940 if !slices.Equal(expectX, result) {
1941 t.Errorf("Expected %v, got %v", expectX, result)
1942 }
1943 if err == nil {
1944 t.Errorf("Missing expected error")
1945 } else {
1946 matchErrorHelper(t, err, RERR_DONE)
1947 }
1948 }
1949
1950
1951 func once[T any](x T) Seq[T] {
1952 return func(yield func(T) bool) {
1953 yield(x)
1954 }
1955 }
1956
1957
1958
1959
1960 func terrify[T any](s string, forall Seq[T]) Seq[T] {
1961 return func(yield func(T) bool) {
1962 forall(func(v T) bool {
1963 if !yield(v) {
1964 panic(s)
1965 }
1966 return true
1967 })
1968 }
1969 }
1970
1971 func use[T any](T) {
1972 }
1973
1974
1975
1976 func f() string {
1977 defer func() { recover() }()
1978 defer panic("f panic")
1979 for _, s := range []string{"f return"} {
1980 return s
1981 }
1982 return "f not reached"
1983 }
1984
1985
1986
1987 func g() string {
1988 defer func() { recover() }()
1989 for s := range terrify("g panic", once("g return")) {
1990 return s
1991 }
1992 return "g not reached"
1993 }
1994
1995
1996
1997
1998 func h() (hashS string) {
1999 defer func() { recover() }()
2000 for s := range terrify("h panic", once("h return")) {
2001 hashS := s
2002 use(hashS)
2003 return s
2004 }
2005 return "h not reached"
2006 }
2007
2008 func j() (hashS string) {
2009 defer func() { recover() }()
2010 for s := range terrify("j panic", once("j return")) {
2011 hashS = s
2012 return
2013 }
2014 return "j not reached"
2015 }
2016
2017
2018
2019
2020
2021 func k() (hashS string) {
2022 _return := func(s string) { hashS = s }
2023
2024 defer func() { recover() }()
2025 for s := range terrify("k panic", once("k return")) {
2026 _return(s)
2027 return
2028 }
2029 return "k not reached"
2030 }
2031
2032 func m() (hashS string) {
2033 _return := func(s string) { hashS = s }
2034
2035 defer func() { recover() }()
2036 for s := range terrify("m panic", once("m return")) {
2037 defer _return(s)
2038 return s + ", but should be replaced in a defer"
2039 }
2040 return "m not reached"
2041 }
2042
2043 func n() string {
2044 defer func() { recover() }()
2045 for s := range terrify("n panic", once("n return")) {
2046 return s + func(s string) string {
2047 defer func() { recover() }()
2048 for s := range terrify("n closure panic", once(s)) {
2049 return s
2050 }
2051 return "n closure not reached"
2052 }(" and n closure return")
2053 }
2054 return "n not reached"
2055 }
2056
2057 type terrifyTestCase struct {
2058 f func() string
2059 e string
2060 }
2061
2062 func TestPanicReturns(t *testing.T) {
2063 tcs := []terrifyTestCase{
2064 {f, "f return"},
2065 {g, "g return"},
2066 {h, "h return"},
2067 {k, "k return"},
2068 {j, "j return"},
2069 {m, "m return"},
2070 {n, "n return and n closure return"},
2071 }
2072
2073 for _, tc := range tcs {
2074 got := tc.f()
2075 if got != tc.e {
2076 t.Errorf("Got %s expected %s", got, tc.e)
2077 } else {
2078 t.Logf("Got expected %s", got)
2079 }
2080 }
2081 }
2082
2083
2084
2085
2086
2087 func twice[T any](x, y T) Seq[T] {
2088 return func(yield func(T) bool) {
2089 var p any
2090 done := false
2091 func() {
2092 defer func() {
2093 p = recover()
2094 }()
2095 done = !yield(x)
2096 }()
2097 if done {
2098 return
2099 }
2100 yield(y)
2101 if p != nil {
2102
2103 panic(p)
2104 }
2105 }
2106 }
2107
2108 func TestRunBodyAfterPanic(t *testing.T) {
2109 defer func() {
2110 if r := recover(); r != nil {
2111 if matchError(r, RERR_PANIC) {
2112 t.Logf("Saw expected panic '%v'", r)
2113 } else {
2114 t.Errorf("Saw wrong panic '%v'", r)
2115 }
2116 } else {
2117 t.Errorf("Wanted to see a failure, result")
2118 }
2119 }()
2120 for x := range twice(0, 1) {
2121 if x == 0 {
2122 panic("x is zero")
2123 }
2124 }
2125 }
2126
2127 func TestRunBodyAfterPanicCheck(t *testing.T) {
2128 defer func() {
2129 if r := recover(); r != nil {
2130 if matchError(r, CERR_PANIC) {
2131 t.Logf("Saw expected panic '%v'", r)
2132 } else {
2133 t.Errorf("Saw wrong panic '%v'", r)
2134 }
2135 } else {
2136 t.Errorf("Wanted to see a failure, result")
2137 }
2138 }()
2139 for x := range Check(twice(0, 1)) {
2140 if x == 0 {
2141 panic("x is zero")
2142 }
2143 }
2144 }
2145
2146 func TestTwoLevelReturn(t *testing.T) {
2147 f := func() int {
2148 for a := range twice(0, 1) {
2149 for b := range twice(0, 2) {
2150 x := a + b
2151 t.Logf("x=%d", x)
2152 if x == 3 {
2153 return x
2154 }
2155 }
2156 }
2157 return -1
2158 }
2159 y := f()
2160 if y != 3 {
2161 t.Errorf("Expected y=3, got y=%d\n", y)
2162 }
2163 }
2164
2165 func TestTwoLevelReturnCheck(t *testing.T) {
2166 f := func() int {
2167 for a := range Check(twice(0, 1)) {
2168 for b := range Check(twice(0, 2)) {
2169 x := a + b
2170 t.Logf("a=%d, b=%d, x=%d", a, b, x)
2171 if x == 3 {
2172 return x
2173 }
2174 }
2175 }
2176 return -1
2177 }
2178 y := f()
2179 if y != 3 {
2180 t.Errorf("Expected y=3, got y=%d\n", y)
2181 }
2182 }
2183
2184 func Bug70035(s1, s2, s3 []string) string {
2185 var c1 string
2186 for v1 := range slices.Values(s1) {
2187 var c2 string
2188 for v2 := range slices.Values(s2) {
2189 var c3 string
2190 for v3 := range slices.Values(s3) {
2191 c3 = c3 + v3
2192 }
2193 c2 = c2 + v2 + c3
2194 }
2195 c1 = c1 + v1 + c2
2196 }
2197 return c1
2198 }
2199
2200 func Test70035(t *testing.T) {
2201 got := Bug70035([]string{"1", "2", "3"}, []string{"a", "b", "c"}, []string{"A", "B", "C"})
2202 want := "1aABCbABCcABC2aABCbABCcABC3aABCbABCcABC"
2203 if got != want {
2204 t.Errorf("got %v, want %v", got, want)
2205 }
2206 }
2207
View as plain text