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