https://github.com/akkartik/mu/blob/master/edit/011-errors.mu
1
2
3 container environment [
4 recipe-errors:text
5 ]
6
7
8 def! update-recipes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, resources:&:resources, screen:&:screen [
9 local-scope
10 load-inputs
11 recipes:&:editor <- get *env, recipes:offset
12 in:text <- editor-contents recipes
13 resources <- dump resources, [lesson/recipes.mu], in
14 recipe-errors:text <- reload in
15 *env <- put *env, recipe-errors:offset, recipe-errors
16
17 {
18 break-unless recipe-errors
19 update-status screen, [errors found ], 1/red
20 errors-found? <- copy true
21 return
22 }
23 errors-found? <- copy false
24 ]
25
26 after <begin-run-sandboxes-on-F4> [
27 old-recipe-errors:text <- get *env, recipe-errors:offset
28 ]
29 before <end-run-sandboxes-on-F4> [
30
31 {
32 break-unless old-recipe-errors
33 screen <- render-recipes screen, env, render
34 }
35 render-recipe-errors env, screen
36 ]
37
38 before <end-render-recipe-components> [
39 row <- render-recipe-errors env, screen
40 ]
41
42 def render-recipe-errors env:&:environment, screen:&:screen -> row:num, screen:&:screen [
43 local-scope
44 load-inputs
45 recipe-errors:text <- get *env, recipe-errors:offset
46 recipes:&:editor <- get *env, recipes:offset
47 row:num <- get *recipes, bottom:offset
48 row <- add row, 1
49 return-unless recipe-errors
50 left:num <- get *recipes, left:offset
51 right:num <- get *recipes, right:offset
52 row, screen <- render-text screen, recipe-errors, left, right, 1/red, row
53
54 draw-horizontal screen, row, left, right, 9480/horizontal-dotted
55 row <- add row, 1
56 clear-screen-from screen, row, left, left, right
57 ]
58
59 container environment [
60 error-index:num
61 ]
62
63 after <programming-environment-initialization> [
64 *result <- put *result, error-index:offset, -1
65 ]
66
67 after <begin-run-sandboxes> [
68 *env <- put *env, error-index:offset, -1
69 ]
70
71 before <end-run-sandboxes> [
72 {
73 error-index:num <- get *env, error-index:offset
74 sandboxes-completed-successfully?:bool <- equal error-index, -1
75 break-if sandboxes-completed-successfully?
76 errors-found? <- copy true
77 }
78 ]
79
80 before <end-run-sandboxes-on-F4> [
81 {
82 break-unless error?
83 recipe-errors:text <- get *env, recipe-errors:offset
84 break-if recipe-errors
85 error-index:num <- get *env, error-index:offset
86 sandboxes-completed-successfully?:bool <- equal error-index, -1
87 break-if sandboxes-completed-successfully?
88 error-index-text:text <- to-text error-index
89 status:text <- interpolate [errors found (_) ], error-index-text
90 update-status screen, status, 1/red
91 }
92 ]
93
94 container sandbox [
95 errors:text
96 ]
97
98 def! update-sandbox sandbox:&:sandbox, env:&:environment, idx:num -> sandbox:&:sandbox, env:&:environment [
99 local-scope
100 load-inputs
101 data:text <- get *sandbox, data:offset
102 response:text, errors:text, fake-screen:&:screen, trace:text, completed?:bool <- run-sandboxed data
103 *sandbox <- put *sandbox, response:offset, response
104 *sandbox <- put *sandbox, errors:offset, errors
105 *sandbox <- put *sandbox, screen:offset, fake-screen
106 *sandbox <- put *sandbox, trace:offset, trace
107 {
108 break-if errors
109 break-if completed?
110 errors <- new [took too long!
111 ]
112 *sandbox <- put *sandbox, errors:offset, errors
113 }
114 {
115 break-unless errors
116 error-index:num <- get *env, error-index:offset
117 error-not-set?:bool <- equal error-index, -1
118 break-unless error-not-set?
119 *env <- put *env, error-index:offset, idx
120 }
121 ]
122
123
124 after <render-sandbox-trace-done> [
125 {
126 sandbox-errors:text <- get *sandbox, errors:offset
127 break-unless sandbox-errors
128 *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0
129 row, screen <- render-text screen, sandbox-errors, left, right, 1/red, row
130
131 jump +render-sandbox-end
132 }
133 ]
134
135 scenario run-shows-errors-in-get [
136 local-scope
137 trace-until 100/app
138 assume-screen 100/width, 15/height
139 assume-resources [
140 [lesson/recipes.mu] <- [
141 |recipe foo [|
142 | get 123:num, foo:offset|
143 |]|
144 ]
145 ]
146 env:&:environment <- new-programming-environment resources, screen, [foo]
147 render-all screen, env, render
148 screen-should-contain [
149 . run (F4) .
150 .recipe foo [ ╎foo .
151 . get 123:num, foo:offset ╎─────────────────────────────────────────────────.
152 .] ╎ .
153 . ╎ .
154 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
155 . ╎ .
156 ]
157 assume-console [
158 press F4
159 ]
160 run [
161 event-loop screen, console, env, resources
162 ]
163 screen-should-contain [
164 . errors found run (F4) .
165 .recipe foo [ ╎foo .
166 . get 123:num, foo:offset ╎─────────────────────────────────────────────────.
167 .] ╎ .
168 . ╎ .
169 .foo: unknown element 'foo' in container 'number' ╎ .
170 .foo: first ingredient of 'get' should be a contai↩╎ .
171 .ner, but got '123:num' ╎ .
172 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
173 . ╎ .
174 ]
175 screen-should-contain-in-color 1/red, [
176 . errors found .
177 . .
178 . .
179 . .
180 . .
181 .foo: unknown element 'foo' in container 'number' .
182 .foo: first ingredient of 'get' should be a contai .
183 .ner, but got '123:num' .
184 . .
185 ]
186 ]
187
188 scenario run-shows-errors-without-final-newline-in-recipe-side [
189 local-scope
190 trace-until 100/app
191 assume-screen 100/width, 15/height
192 assume-resources [
193 ]
194 env:&:environment <- new-programming-environment resources, screen
195 render-all screen, env, render
196 assume-console [
197 type [recipe foo x [
198 ]]
199 press F4
200 ]
201 run [
202 event-loop screen, console, env, resources
203 ]
204 screen-should-contain [
205 . errors found run (F4) .
206 .recipe foo x [ ╎ .
207 .] ╎─────────────────────────────────────────────────.
208 .foo: ingredient 'x' has no type ╎ .
209 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
210 . ╎ .
211 ]
212 ]
213
214 scenario run-updates-status-with-first-erroneous-sandbox [
215 local-scope
216 trace-until 100/app
217 assume-screen 100/width, 15/height
218 assume-resources [
219 ]
220 env:&:environment <- new-programming-environment resources, screen, []
221 render-all screen, env, render
222 assume-console [
223 left-click 3, 80
224
225 type [get foo, x:offset]
226 press F4
227
228 type [get foo, x:offset]
229 press F4
230 ]
231 run [
232 event-loop screen, console, env, resources
233 ]
234
235 screen-should-contain [
236 . errors found (0) run (F4) .
237 ]
238 ]
239
240 scenario run-updates-status-with-first-erroneous-sandbox-2 [
241 local-scope
242 trace-until 100/app
243 assume-screen 100/width, 15/height
244 assume-resources [
245 ]
246 env:&:environment <- new-programming-environment resources, screen, []
247 render-all screen, env, render
248 assume-console [
249 left-click 3, 80
250
251 type [get foo, x:offset]
252 press F4
253
254 type [get foo, x:offset]
255 press F4
256
257 type [add 2, 2]
258 press F4
259 ]
260 run [
261 event-loop screen, console, env, resources
262 ]
263
264 screen-should-contain [
265 . errors found (1) run (F4) .
266 ]
267 ]
268
269 scenario run-hides-errors-from-past-sandboxes [
270 local-scope
271 trace-until 100/app
272 assume-screen 100/width, 15/height
273 assume-resources [
274 ]
275 env:&:environment <- new-programming-environment resources, screen, [get foo, x:offset]
276 render-all screen, env, render
277 assume-console [
278 press F4
279 ]
280 event-loop screen, console, env, resources
281 assume-console [
282 left-click 3, 58
283 press ctrl-k
284 type [add 2, 2]
285 press F4
286 ]
287 run [
288 event-loop screen, console, env, resources
289 ]
290
291 screen-should-contain [
292 . run (F4) .
293 . ╎ .
294 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
295 . ╎0 edit copy to recipe delete .
296 . ╎add 2, 2 .
297 . ╎4 .
298 . ╎─────────────────────────────────────────────────.
299 . ╎ .
300 ]
301 ]
302
303 scenario run-updates-errors-for-shape-shifting-recipes [
304 local-scope
305 trace-until 100/app
306 assume-screen 100/width, 15/height
307
308 assume-resources [
309 [lesson/recipes.mu] <- [
310 |recipe foo x:_elem -> z:_elem [|
311 | local-scope|
312 | load-ingredients|
313 | y:&:num <- copy null|
314 | z <- add x, y|
315 |]|
316 ]
317 ]
318 env:&:environment <- new-programming-environment resources, screen, [foo 2]
319 render-all screen, env, render
320 assume-console [
321 press F4
322 ]
323 event-loop screen, console, env, resources
324 screen-should-contain [
325 . errors found (0) run (F4) .
326 .recipe foo x:_elem -> z:_elem [ ╎ .
327 . local-scope ╎─────────────────────────────────────────────────.
328 . load-ingredients ╎0 edit copy to recipe delete .
329 . y:&:num <- copy null ╎foo 2 .
330 . z <- add x, y ╎foo_2: 'add' requires number ingredients, but go↩.
331 .] ╎t 'y' .
332 . ╎─────────────────────────────────────────────────.
333 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
334 . ╎ .
335 ]
336
337 assume-console [
338 press F4
339 ]
340 run [
341 event-loop screen, console, env, resources
342 ]
343
344 screen-should-contain [
345 . errors found (0) run (F4) .
346 .recipe foo x:_elem -> z:_elem [ ╎ .
347 . local-scope ╎─────────────────────────────────────────────────.
348 . load-ingredients ╎0 edit copy to recipe delete .
349 . y:&:num <- copy null ╎foo 2 .
350 . z <- add x, y ╎foo_3: 'add' requires number ingredients, but go↩.
351 .] ╎t 'y' .
352 . ╎─────────────────────────────────────────────────.
353 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
354 . ╎ .
355 ]
356 ]
357
358 scenario run-avoids-spurious-errors-on-reloading-shape-shifting-recipes [
359 local-scope
360 trace-until 100/app
361 assume-screen 100/width, 15/height
362
363 assume-resources [
364 [lesson/recipes.mu] <- [
365 |recipe length l:&:list:_elem -> n:num [|
366 |]|
367 ]
368 ]
369
370 test-sandbox:text <- new [x:&:list:num <- copy null
371 to-text x]
372 env:&:environment <- new-programming-environment resources, screen, test-sandbox
373 render-all screen, env, render
374
375 assume-console [
376 press F4
377 ]
378 event-loop screen, console, env, resources
379
380 screen-should-contain-in-color 1/red, [
381 . .
382 . .
383 . .
384 . .
385 . <- .
386 . .
387 . .
388 . .
389 . .
390 . .
391 . .
392 . .
393 . .
394 . .
395 . .
396 ]
397
398 assume-console [
399 press F4
400 ]
401 run [
402 event-loop screen, console, env, resources
403 ]
404
405 screen-should-contain-in-color 1/red, [
406 . .
407 . .
408 . .
409 . .
410 . <- .
411 . .
412 . .
413 . .
414 . .
415 . .
416 . .
417 . .
418 . .
419 . .
420 . .
421 ]
422 ]
423
424 scenario run-shows-missing-type-errors [
425 local-scope
426 trace-until 100/app
427 assume-screen 100/width, 15/height
428 assume-resources [
429 [lesson/recipes.mu] <- [
430 |recipe foo [|
431 | x <- copy 0|
432 |]|
433 ]
434 ]
435 env:&:environment <- new-programming-environment resources, screen, [foo]
436 render-all screen, env, render
437 assume-console [
438 press F4
439 ]
440 run [
441 event-loop screen, console, env, resources
442 ]
443 screen-should-contain [
444 . errors found run (F4) .
445 .recipe foo [ ╎foo .
446 . x <- copy 0 ╎─────────────────────────────────────────────────.
447 .] ╎ .
448 . ╎ .
449 .foo: missing type for 'x' in 'x <- copy 0' ╎ .
450 .foo: can't copy '0' to 'x'; types don't match ╎ .
451 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
452 . ╎ .
453 ]
454 ]
455
456 scenario run-shows-unbalanced-bracket-errors [
457 local-scope
458 trace-until 100/app
459 assume-screen 100/width, 15/height
460
461 assume-resources [
462 [lesson/recipes.mu] <- [
463 |recipe foo \\\[|
464 | x <- copy 0|
465 ]
466 ]
467 env:&:environment <- new-programming-environment resources, screen, [foo]
468 render-all screen, env, render
469 assume-console [
470 press F4
471 ]
472 run [
473 event-loop screen, console, env, resources
474 ]
475 screen-should-contain [
476 . errors found run (F4) .
477 .recipe foo \\[ ╎foo .
478 . x <- copy 0 ╎─────────────────────────────────────────────────.
479 . ╎ .
480 .9: unbalanced '\\[' for recipe ╎ .
481 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
482 . ╎ .
483 ]
484 ]
485
486 scenario run-shows-get-on-non-container-errors [
487 local-scope
488 trace-until 100/app
489 assume-screen 100/width, 15/height
490 assume-resources [
491 [lesson/recipes.mu] <- [
492 |recipe foo [|
493 | local-scope|
494 | x:&:point <- new point:type|
495 | get x:&:point, 1:offset|
496 |]|
497 ]
498 ]
499 env:&:environment <- new-programming-environment resources, screen, [foo]
500 render-all screen, env, render
501 assume-console [
502 press F4
503 ]
504 run [
505 event-loop screen, console, env, resources
506 ]
507 screen-should-contain [
508 . errors found run (F4) .
509 .recipe foo [ ╎foo .
510 . local-scope ╎─────────────────────────────────────────────────.
511 . x:&:point <- new point:type ╎ .
512 . get x:&:point, 1:offset ╎ .
513 .] ╎ .
514 . ╎ .
515 .foo: first ingredient of 'get' should be a contai↩╎ .
516 .ner, but got 'x:&:point' ╎ .
517 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
518 . ╎ .
519 ]
520 ]
521
522 scenario run-shows-non-literal-get-argument-errors [
523 local-scope
524 trace-until 100/app
525 assume-screen 100/width, 15/height
526 assume-resources [
527 [lesson/recipes.mu] <- [
528 |recipe foo [|
529 | local-scope|
530 | x:num <- copy 0|
531 | y:&:point <- new point:type|
532 | get *y:&:point, x:num|
533 |]|
534 ]
535 ]
536 env:&:environment <- new-programming-environment resources, screen, [foo]
537 render-all screen, env, render
538 assume-console [
539 press F4
540 ]
541 run [
542 event-loop screen, console, env, resources
543 ]
544 screen-should-contain [
545 . errors found run (F4) .
546 .recipe foo [ ╎foo .
547 . local-scope ╎─────────────────────────────────────────────────.
548 . x:num <- copy 0 ╎ .
549 . y:&:point <- new point:type ╎ .
550 . get *y:&:point, x:num ╎ .
551 .] ╎ .
552 . ╎ .
553 .foo: second ingredient of 'get' should have type ↩╎ .
554 .'offset', but got 'x:num' ╎ .
555 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
556 . ╎ .
557 ]
558 ]
559
560 scenario run-shows-errors-every-time [
561 local-scope
562 trace-until 100/app
563 assume-screen 100/width, 15/height
564
565 assume-resources [
566 [lesson/recipes.mu] <- [
567 |recipe foo [|
568 | local-scope|
569 | x:num <- copy y:num|
570 |]|
571 ]
572 ]
573 env:&:environment <- new-programming-environment resources, screen, [foo]
574 render-all screen, env, render
575 assume-console [
576 press F4
577 ]
578 event-loop screen, console, env, resources
579 screen-should-contain [
580 . errors found run (F4) .
581 .recipe foo [ ╎foo .
582 . local-scope ╎─────────────────────────────────────────────────.
583 . x:num <- copy y:num ╎ .
584 .] ╎ .
585 . ╎ .
586 .foo: tried to read ingredient 'y' in 'x:num <- co↩╎ .
587 .py y:num' but it hasn't been written to yet ╎ .
588 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
589 . ╎ .
590 ]
591
592 assume-console [
593 press F4
594 ]
595 run [
596 event-loop screen, console, env, resources
597 ]
598 screen-should-contain [
599 . errors found run (F4) .
600 .recipe foo [ ╎foo .
601 . local-scope ╎─────────────────────────────────────────────────.
602 . x:num <- copy y:num ╎ .
603 .] ╎ .
604 . ╎ .
605 .foo: tried to read ingredient 'y' in 'x:num <- co↩╎ .
606 .py y:num' but it hasn't been written to yet ╎ .
607 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
608 . ╎ .
609 ]
610 ]
611
612 scenario run-hides-errors [
613 local-scope
614 trace-until 100/app
615 assume-screen 100/width, 15/height
616
617 assume-resources [
618 [lesson/recipes.mu] <- [
619 |recipe foo [|
620 | local-scope|
621 | x:num <- copy y:num|
622 |]|
623 ]
624 ]
625 env:&:environment <- new-programming-environment resources, screen, [foo]
626 render-all screen, env, render
627 assume-console [
628 press F4
629 ]
630 event-loop screen, console, env, resources
631 screen-should-contain [
632 . errors found run (F4) .
633 .recipe foo [ ╎foo .
634 . local-scope ╎─────────────────────────────────────────────────.
635 . x:num <- copy y:num ╎ .
636 .] ╎ .
637 . ╎ .
638 .foo: tried to read ingredient 'y' in 'x:num <- co↩╎ .
639 .py y:num' but it hasn't been written to yet ╎ .
640 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
641 . ╎ .
642 ]
643
644 assume-console [
645 left-click 3, 16
646 press ctrl-k
647 type [0]
648 press F4
649 ]
650 event-loop screen, console, env, resources
651
652 screen-should-contain [
653 . run (F4) .
654 .recipe foo [ ╎ .
655 . local-scope ╎─────────────────────────────────────────────────.
656 . x:num <- copy 0 ╎0 edit copy to recipe delete .
657 .] ╎foo .
658 . ╎─────────────────────────────────────────────────.
659 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
660 . ╎ .
661 ]
662 ]
663
664 scenario scrolling-recipe-side-reveals-errors [
665 local-scope
666 trace-until 100/app
667 assume-screen 100/width, 5/height
668
669 assume-resources [
670 [lesson/recipes.mu] <- [
671 |recipe foo [|
672 | a:num <- copy 0| # padding to overflow recipe side
673 | b:num <- copy 0| # padding to overflow recipe side
674 | get 123:num, foo:offset| # line containing error
675 |]|
676 ]
677 ]
678 env:&:environment <- new-programming-environment resources, screen, [foo]
679 render-all screen, env, render
680
681 assume-console [
682 press F4
683 press page-down
684 ]
685 run [
686 event-loop screen, console, env, resources
687 ]
688
689 screen-should-contain [
690 . errors found run (F4) .
691 . get 123:num, foo:offset ╎foo .
692 .\\] ╎─────────────────────────────────────────────────.
693 . ╎ .
694 .foo: unknown element 'foo' in container 'number' ╎ .
695 ]
696 ]
697
698 scenario run-instruction-and-print-errors [
699 local-scope
700 trace-until 100/app
701 assume-screen 100/width, 10/height
702 assume-resources [
703 ]
704
705 env:&:environment <- new-programming-environment resources, screen, [get 1234:num, foo:offset]
706 render-all screen, env, render
707 assume-console [
708 press F4
709 ]
710 run [
711 event-loop screen, console, env, resources
712 ]
713
714 screen-should-contain [
715 . errors found (0) run (F4) .
716 . ╎ .
717 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
718 . ╎0 edit copy to recipe delete .
719 . ╎get 1234:num, foo:offset .
720 . ╎unknown element 'foo' in container 'number' .
721 . ╎first ingredient of 'get' should be a container,↩.
722 . ╎ but got '1234:num' .
723 . ╎─────────────────────────────────────────────────.
724 . ╎ .
725 ]
726 screen-should-contain-in-color 7/white, [
727 . .
728 . .
729 . .
730 . .
731 . get 1234:num, foo:offset .
732 . .
733 . .
734 . .
735 ]
736 screen-should-contain-in-color 1/red, [
737 . errors found (0) .
738 . .
739 . .
740 . .
741 . .
742 . unknown element 'foo' in container 'number' .
743 . first ingredient of 'get' should be a container, .
744 . but got '1234:num' .
745 . .
746 ]
747 screen-should-contain-in-color 245/grey, [
748 . .
749 . ╎ .
750 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
751 . ╎ .
752 . ╎ .
753 . ╎ .
754 . ╎ ↩.
755 . ╎ .
756 . ╎─────────────────────────────────────────────────.
757 . ╎ .
758 ]
759 ]
760
761 scenario run-instruction-and-print-errors-only-once [
762 local-scope
763 trace-until 100/app
764 assume-screen 100/width, 10/height
765 assume-resources [
766 ]
767
768 env:&:environment <- new-programming-environment resources, screen, [get 1234:num, foo:offset]
769 render-all screen, env, render
770
771 assume-console [
772 press F4
773 press F4
774 ]
775 run [
776 event-loop screen, console, env, resources
777 ]
778
779 screen-should-contain [
780 . errors found (0) run (F4) .
781 . ╎ .
782 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
783 . ╎0 edit copy to recipe delete .
784 . ╎get 1234:num, foo:offset .
785 . ╎unknown element 'foo' in container 'number' .
786 . ╎first ingredient of 'get' should be a container,↩.
787 . ╎ but got '1234:num' .
788 . ╎─────────────────────────────────────────────────.
789 . ╎ .
790 ]
791 ]
792
793 scenario sandbox-can-handle-infinite-loop [
794 local-scope
795 trace-until 100/app
796 assume-screen 100/width, 20/height
797
798 assume-resources [
799 [lesson/recipes.mu] <- [
800 |recipe foo [|
801 | {|
802 | loop|
803 | }|
804 |]|
805 ]
806 ]
807 env:&:environment <- new-programming-environment resources, screen, [foo]
808 render-all screen, env, render
809
810 assume-console [
811 press F4
812 ]
813 run [
814 event-loop screen, console, env, resources
815 ]
816 screen-should-contain [
817 . errors found (0) run (F4) .
818 .recipe foo [ ╎ .
819 . { ╎─────────────────────────────────────────────────.
820 . loop ╎0 edit copy to recipe delete .
821 . } ╎foo .
822 .] ╎took too long! .
823 . ╎─────────────────────────────────────────────────.
824 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
825 . ╎ .
826 ]
827 ]
828
829 scenario sandbox-with-errors-shows-trace [
830 local-scope
831 trace-until 100/app
832 assume-screen 100/width, 10/height
833
834 assume-resources [
835 [lesson/recipes.mu] <- [
836 |recipe foo [|
837 | local-scope|
838 | a:num <- next-ingredient|
839 | b:num <- next-ingredient|
840 | stash [dividing by], b|
841 | _, c:num <- divide-with-remainder a, b|
842 | reply b|
843 |]|
844 ]
845 ]
846 env:&:environment <- new-programming-environment resources, screen, [foo 4, 0]
847 render-all screen, env, render
848
849 assume-console [
850 press F4
851 ]
852 event-loop screen, console, env, resources
853
854 screen-should-contain [
855 . errors found (0) run (F4) .
856 .recipe foo [ ╎ .
857 . local-scope ╎─────────────────────────────────────────────────.
858 . a:num <- next-ingredient ╎0 edit copy to recipe delete .
859 . b:num <- next-ingredient ╎foo 4, 0 .
860 . stash [dividing by], b ╎foo: divide by zero in '_, c:num <- divide-with-↩.
861 . _, c:num <- divide-with-remainder a, b ╎remainder a, b' .
862 . reply b ╎─────────────────────────────────────────────────.
863 .] ╎ .
864 . ╎ .
865 ]
866
867 assume-console [
868 left-click 4, 55
869 ]
870 run [
871 event-loop screen, console, env, resources
872 ]
873
874 screen-should-contain [
875 . errors found (0) run (F4) .
876 .recipe foo [ ╎ .
877 . local-scope ╎─────────────────────────────────────────────────.
878 . a:num <- next-ingredient ╎0 edit copy to recipe delete .
879 . b:num <- next-ingredient ╎foo 4, 0 .
880 . stash [dividing by], b ╎dividing by 0 .
881 . _, c:num <- divide-with-remainder a, b ╎14 instructions run .
882 . reply b ╎foo: divide by zero in '_, c:num <- divide-with-↩.
883 .] ╎remainder a, b' .
884 . ╎─────────────────────────────────────────────────.
885 ]
886 ]