1 ## clicking on sandbox results to 'fix' them and turn sandboxes into tests
  2 
  3 scenario sandbox-click-on-result-toggles-color-to-green [
  4   local-scope
  5   trace-until 100/app  # trace too long
  6   assume-screen 100/width, 20/height
  7   # basic recipe
  8   assume-resources [
  9   ¦ [lesson/recipes.mu] <- [
 10   ¦ ¦ |recipe foo [|
 11   ¦ ¦ |  reply 4|
 12   ¦ ¦ |]|
 13   ¦ ]
 14   ]
 15   env:&:environment <- new-programming-environment resources, screen, [foo]
 16   render-all screen, env, render
 17   # run it
 18   assume-console [
 19   ¦ press F4
 20   ]
 21   event-loop screen, console, env, resources
 22   screen-should-contain [
 23   ¦ .                                                                                 run (F4)           .
 24   ¦ .recipe foo [                                      ╎                                                 .
 25   ¦ .  reply 4                                         ╎─────────────────────────────────────────────────.
 26   ¦ .]                                                 ╎0   edit       copy       to recipe    delete    .
 27   ¦ .                                                  ╎foo                                              .
 28   ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎4                                                .
 29   ¦ .                                                  ╎─────────────────────────────────────────────────.
 30   ¦ .                                                  ╎                                                 .
 31   ]
 32   # click on the '4' in the result
 33   $clear-trace
 34   assume-console [
 35   ¦ left-click 5, 51
 36   ]
 37   run [
 38   ¦ event-loop screen, console, env, resources
 39   ]
 40   # color toggles to green
 41   screen-should-contain-in-color 2/green, [
 42   ¦ .                                                                                                    .
 43   ¦ .                                                                                                    .
 44   ¦ .                                                                                                    .
 45   ¦ .                                                                                                    .
 46   ¦ .                                                                                                    .
 47   ¦ .                                                   4                                                .
 48   ¦ .                                                                                                    .
 49   ¦ .                                                                                                    .
 50   ]
 51   # don't render entire sandbox side
 52   check-trace-count-for-label-lesser-than 250, [print-character]  # say 5 sandbox lines
 53   # cursor should remain unmoved
 54   run [
 55   ¦ cursor:char <- copy 9251/␣
 56   ¦ print screen, cursor
 57   ]
 58   screen-should-contain [
 59   ¦ .                                                                                 run (F4)           .
 60   ¦ .␣ecipe foo [                                      ╎                                                 .
 61   ¦ .  reply 4                                         ╎─────────────────────────────────────────────────.
 62   ¦ .]                                                 ╎0   edit       copy       to recipe    delete    .
 63   ¦ .                                                  ╎foo                                              .
 64   ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎4                                                .
 65   ¦ .                                                  ╎─────────────────────────────────────────────────.
 66   ¦ .                                                  ╎                                                 .
 67   ]
 68   # now change the result
 69   # then rerun
 70   assume-console [
 71   ¦ left-click 2, 11  # cursor to end of line
 72   ¦ press backspace
 73   ¦ type [3]
 74   ¦ press F4
 75   ]
 76   run [
 77   ¦ event-loop screen, console, env, resources
 78   ]
 79   # result turns red
 80   screen-should-contain-in-color 1/red, [
 81   ¦ .                                                                                                    .
 82   ¦ .                                                                                                    .
 83   ¦ .                                                                                                    .
 84   ¦ .                                                                                                    .
 85   ¦ .                                                                                                    .
 86   ¦ .                                                   3                                                .
 87   ¦ .                                                                                                    .
 88   ¦ .                                                                                                    .
 89   ]
 90 ]
 91 
 92 # this requires tracking a couple more things
 93 container sandbox [
 94   response-starting-row-on-screen:num
 95   expected-response:text
 96 ]
 97 
 98 # include expected response when saving or restoring a sandbox
 99 before <end-save-sandbox> [
100   {
101   ¦ expected-response:text <- get *sandbox, expected-response:offset
102   ¦ break-unless expected-response
103   ¦ filename <- append filename, [.out]
104   ¦ resources <- dump resources, filename, expected-response
105   }
106 ]
107 
108 before <end-restore-sandbox> [
109   {
110   ¦ filename <- append filename, [.out]
111   ¦ contents <- slurp resources, filename
112   ¦ break-unless contents
113   ¦ *curr <- put *curr, expected-response:offset, contents
114   }
115 ]
116 
117 # clicks on sandbox responses save it as 'expected'
118 after <global-touch> [
119   # check if it's inside the output of any sandbox
120   {
121   ¦ sandbox-left-margin:num <- get *current-sandbox, left:offset
122   ¦ click-column:num <- get t, column:offset
123   ¦ on-sandbox-side?:bool <- greater-or-equal click-column, sandbox-left-margin
124   ¦ break-unless on-sandbox-side?
125   ¦ first-sandbox:&:sandbox <- get *env, sandbox:offset
126   ¦ break-unless first-sandbox
127   ¦ first-sandbox-begins:num <- get *first-sandbox, starting-row-on-screen:offset
128   ¦ click-row:num <- get t, row:offset
129   ¦ below-sandbox-editor?:bool <- greater-or-equal click-row, first-sandbox-begins
130   ¦ break-unless below-sandbox-editor?
131   ¦ # identify the sandbox whose output is being clicked on
132   ¦ sandbox:&:sandbox, sandbox-index:num <- find-click-in-sandbox-output env, click-row
133   ¦ break-unless sandbox
134   ¦ # update it
135   ¦ sandbox <- toggle-expected-response sandbox
136   ¦ # minimal update to disk
137   ¦ save-sandbox resources, sandbox, sandbox-index
138   ¦ # minimal update to screen
139   ¦ sandbox-right-margin:num <- get *current-sandbox, right:offset
140   ¦ row:num <- render-sandbox-response screen, sandbox, sandbox-left-margin, sandbox-right-margin
141   ¦ {
142   ¦ ¦ height:num <- screen-height screen
143   ¦ ¦ at-bottom?:bool <- greater-or-equal row, height
144   ¦ ¦ break-if at-bottom?
145   ¦ ¦ draw-horizontal screen, row, sandbox-left-margin, sandbox-right-margin
146   ¦ }
147   ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
148   ¦ loop +next-event
149   }
150 ]
151 
152 def find-click-in-sandbox-output env:&:environment, click-row:num -> sandbox:&:sandbox, sandbox-index:num [
153   local-scope
154   load-inputs
155   # assert click-row >= sandbox.starting-row-on-screen
156   sandbox:&:sandbox <- get *env, sandbox:offset
157   start:num <- get *sandbox, starting-row-on-screen:offset
158   clicked-on-sandboxes?:bool <- greater-or-equal click-row, start
159   assert clicked-on-sandboxes?, [extract-sandbox called on click to sandbox editor]
160   # while click-row < sandbox.next-sandbox.starting-row-on-screen
161   sandbox-index <- copy 0
162   {
163   ¦ next-sandbox:&:sandbox <- get *sandbox, next-sandbox:offset
164   ¦ break-unless next-sandbox
165   ¦ next-start:num <- get *next-sandbox, starting-row-on-screen:offset
166   ¦ found?:bool <- lesser-than click-row, next-start
167   ¦ break-if found?
168   ¦ sandbox <- copy next-sandbox
169   ¦ sandbox-index <- add sandbox-index, 1
170   ¦ loop
171   }
172   # return sandbox if click is in its output region
173   response-starting-row:num <- get *sandbox, response-starting-row-on-screen:offset
174   return-unless response-starting-row, 0/no-click-in-sandbox-output, 0/sandbox-index
175   click-in-response?:bool <- greater-or-equal click-row, response-starting-row
176   return-unless click-in-response?, 0/no-click-in-sandbox-output, 0/sandbox-index
177   return sandbox, sandbox-index
178 ]
179 
180 def toggle-expected-response sandbox:&:sandbox -> sandbox:&:sandbox [
181   local-scope
182   load-inputs
183   expected-response:text <- get *sandbox, expected-response:offset
184   {
185   ¦ # if expected-response is set, reset
186   ¦ break-unless expected-response
187   ¦ *sandbox <- put *sandbox, expected-response:offset, 0
188   }
189   {
190   ¦ # if not, set expected response to the current response
191   ¦ break-if expected-response
192   ¦ response:text <- get *sandbox, response:offset
193   ¦ *sandbox <- put *sandbox, expected-response:offset, response
194   }
195 ]
196 
197 # when rendering a sandbox, color it in red/green if expected response exists
198 after <render-sandbox-response> [
199   {
200   ¦ break-unless sandbox-response
201   ¦ *sandbox <- put *sandbox, response-starting-row-on-screen:offset, row
202   ¦ row <- render-sandbox-response screen, sandbox, left, right
203   ¦ jump +render-sandbox-end
204   }
205 ]
206 
207 def render-sandbox-response screen:&:screen, sandbox:&:sandbox, left:num, right:num -> row:num, screen:&:screen [
208   local-scope
209   load-inputs
210   sandbox-response:text <- get *sandbox, response:offset
211   expected-response:text <- get *sandbox, expected-response:offset
212   row:num <- get *sandbox response-starting-row-on-screen:offset
213   {
214   ¦ break-if expected-response
215   ¦ row <- render-text screen, sandbox-response, left, right, 245/grey, row
216   ¦ return
217   }
218   response-is-expected?:bool <- equal expected-response, sandbox-response
219   {
220   ¦ break-if response-is-expected?
221   ¦ row <- render-text screen, sandbox-response, left, right, 1/red, row
222   }
223   {
224   ¦ break-unless response-is-expected?:bool
225   ¦ row <- render-text screen, sandbox-response, left, right, 2/green, row
226   }
227 ]
228 
229 before <end-render-sandbox-reset-hidden> [
230   *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0
231 ]