diff options
Diffstat (limited to 'archive/2.vm/sandbox/005-sandbox.mu')
-rw-r--r-- | archive/2.vm/sandbox/005-sandbox.mu | 1081 |
1 files changed, 0 insertions, 1081 deletions
diff --git a/archive/2.vm/sandbox/005-sandbox.mu b/archive/2.vm/sandbox/005-sandbox.mu deleted file mode 100644 index 632a5df1..00000000 --- a/archive/2.vm/sandbox/005-sandbox.mu +++ /dev/null @@ -1,1081 +0,0 @@ -## running code from the editor and creating sandboxes -# -# Running code in the sandbox editor prepends its contents to a list of -# (non-editable) sandboxes below the editor, showing the result and maybe a -# few other things (later layers). -# -# This layer draws the menubar buttons in non-editable sandboxes but they -# don't do anything yet. Later layers implement each button. - -def! main [ - local-scope - open-console - clear-screen null/screen # non-scrolling app - env:&:environment <- new-programming-environment null/filesystem, null/screen - env <- restore-sandboxes env, null/filesystem - render-all null/screen, env, render - event-loop null/screen, null/console, env, null/filesystem -] - -container environment [ - sandbox:&:sandbox # list of sandboxes, from top to bottom. TODO: switch to &:list:sandbox - render-from:num - number-of-sandboxes:num -] - -after <programming-environment-initialization> [ - *result <- put *result, render-from:offset, -1 -] - -container sandbox [ - data:text - response:text - # coordinates to track clicks - # constraint: will be 0 for sandboxes at positions before env.render-from - starting-row-on-screen:num - code-ending-row-on-screen:num # past end of code - screen:&:screen # prints in the sandbox go here - next-sandbox:&:sandbox -] - -scenario run-and-show-results [ - local-scope - trace-until 100/app # trace too long - assume-screen 50/width, 15/height - # recipes.mu is empty - assume-resources [ - ] - # sandbox editor contains an instruction without storing outputs - env:&:environment <- new-programming-environment resources, screen, [divide-with-remainder 11, 3] - render-all screen, env, render - # run the code in the editors - assume-console [ - press F4 - ] - run [ - event-loop screen, console, env, resources - ] - # check that screen prints the results - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .divide-with-remainder 11, 3 . - .3 . - .2 . - .──────────────────────────────────────────────────. - . . - ] - screen-should-contain-in-color 7/white, [ - . . - . . - . . - . . - .divide-with-remainder 11, 3 . - . . - . . - . . - . . - ] - screen-should-contain-in-color 245/grey, [ - . . - . . - .──────────────────────────────────────────────────. - . . - . . - .3 . - .2 . - .──────────────────────────────────────────────────. - . . - ] - # run another command - assume-console [ - left-click 1, 80 - type [add 2, 2] - press F4 - ] - run [ - event-loop screen, console, env, resources - ] - # check that screen prints both sandboxes - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .divide-with-remainder 11, 3 . - .3 . - .2 . - .──────────────────────────────────────────────────. - . . - ] -] - -after <global-keypress> [ - # F4? load all code and run all sandboxes. - { - do-run?:bool <- equal k, 65532/F4 - break-unless do-run? - screen <- update-status screen, [running... ], 245/grey - error?:bool <- run-sandboxes env, resources, screen - # F4 might update warnings and results on both sides - screen <- render-all screen, env, render - { - break-if error? - screen <- update-status screen, [ ], 245/grey - } - screen <- update-cursor screen, current-sandbox, env - loop +next-event - } -] - -def run-sandboxes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, resources:&:resources, screen:&:screen [ - local-scope - load-inputs - errors-found?:bool <- update-recipes env, resources, screen - # check contents of editor - <begin-run-sandboxes> - current-sandbox:&:editor <- get *env, current-sandbox:offset - { - sandbox-contents:text <- editor-contents current-sandbox - break-unless sandbox-contents - # if contents exist, first save them - # run them and turn them into a new sandbox - new-sandbox:&:sandbox <- new sandbox:type - *new-sandbox <- put *new-sandbox, data:offset, sandbox-contents - # push to head of sandbox list - dest:&:sandbox <- get *env, sandbox:offset - *new-sandbox <- put *new-sandbox, next-sandbox:offset, dest - *env <- put *env, sandbox:offset, new-sandbox - # update sandbox count - sandbox-count:num <- get *env, number-of-sandboxes:offset - sandbox-count <- add sandbox-count, 1 - *env <- put *env, number-of-sandboxes:offset, sandbox-count - # save all sandboxes - # needs to be before running them, in case we die when running - save-sandboxes env, resources - # clear sandbox editor - init:&:duplex-list:char <- push 167/§, null - *current-sandbox <- put *current-sandbox, data:offset, init - *current-sandbox <- put *current-sandbox, top-of-screen:offset, init - } - # run all sandboxes - curr:&:sandbox <- get *env, sandbox:offset - idx:num <- copy 0 - { - break-unless curr - curr <- update-sandbox curr, env, idx - curr <- get *curr, next-sandbox:offset - idx <- add idx, 1 - loop - } - <end-run-sandboxes> - { - break-if resources # ignore this in tests - $system [./snapshot_lesson] - } -] - -# load code from disk -# replaced in a later layer (whereupon errors-found? will actually be set) -def update-recipes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, screen:&:screen [ - local-scope - load-inputs - in:text <- slurp resources, [lesson/recipes.mu] - reload in - errors-found? <- copy false -] - -# replaced in a later layer -def update-sandbox sandbox:&:sandbox, env:&:environment, idx:num -> sandbox:&:sandbox, env:&:environment [ - local-scope - load-inputs - data:text <- get *sandbox, data:offset - response:text, _, fake-screen:&:screen <- run-sandboxed data - *sandbox <- put *sandbox, response:offset, response - *sandbox <- put *sandbox, screen:offset, fake-screen -] - -def update-status screen:&:screen, msg:text, color:num -> screen:&:screen [ - local-scope - load-inputs - screen <- move-cursor screen, 0, 2 - screen <- print screen, msg, color, 238/grey/background -] - -def save-sandboxes env:&:environment, resources:&:resources -> resources:&:resources [ - local-scope - load-inputs - trace 11, [app], [save sandboxes] - current-sandbox:&:editor <- get *env, current-sandbox:offset - # first clear previous versions, in case we deleted some sandbox - $system [rm lesson/[0-9]* >/dev/null 2>/dev/null] # some shells can't handle '>&' - curr:&:sandbox <- get *env, sandbox:offset - idx:num <- copy 0 - { - break-unless curr - resources <- save-sandbox resources, curr, idx - idx <- add idx, 1 - curr <- get *curr, next-sandbox:offset - loop - } -] - -def save-sandbox resources:&:resources, sandbox:&:sandbox, sandbox-index:num -> resources:&:resources [ - local-scope - load-inputs - data:text <- get *sandbox, data:offset - filename:text <- append [lesson/], sandbox-index - resources <- dump resources, filename, data - <end-save-sandbox> -] - -def! render-sandbox-side screen:&:screen, env:&:environment, render-editor:render-recipe -> screen:&:screen, env:&:environment [ - local-scope - load-inputs - trace 11, [app], [render sandbox side] - old-top-idx:num <- save-top-idx screen - current-sandbox:&:editor <- get *env, current-sandbox:offset - row:num, column:num <- copy 1, 0 - left:num <- get *current-sandbox, left:offset - right:num <- get *current-sandbox, right:offset - # render sandbox editor - render-from:num <- get *env, render-from:offset - { - render-current-sandbox?:bool <- equal render-from, -1 - break-unless render-current-sandbox? - row, column, screen, current-sandbox <- call render-editor, screen, current-sandbox - } - # render sandboxes - draw-horizontal screen, row, left, right - sandbox:&:sandbox <- get *env, sandbox:offset - row, screen <- render-sandboxes screen, sandbox, left, right, row, render-from, 0, env - clear-rest-of-screen screen, row, left, right - # - assert-no-scroll screen, old-top-idx -] - -def render-sandboxes screen:&:screen, sandbox:&:sandbox, left:num, right:num, row:num, render-from:num, idx:num -> row:num, screen:&:screen, sandbox:&:sandbox [ - local-scope - load-inputs - env:&:environment, _/optional <- next-input - return-unless sandbox - screen-height:num <- screen-height screen - hidden?:bool <- lesser-than idx, render-from - { - break-if hidden? - # render sandbox menu - row <- add row, 1 - at-bottom?:bool <- greater-or-equal row, screen-height - return-if at-bottom? - screen <- move-cursor screen, row, left - screen <- render-sandbox-menu screen, idx, left, right - # save menu row so we can detect clicks to it later - *sandbox <- put *sandbox, starting-row-on-screen:offset, row - # render sandbox contents - row <- add row, 1 - screen <- move-cursor screen, row, left - sandbox-data:text <- get *sandbox, data:offset - row, screen <- render-code screen, sandbox-data, left, right, row - *sandbox <- put *sandbox, code-ending-row-on-screen:offset, row - # render sandbox warnings, screen or response, in that order - sandbox-response:text <- get *sandbox, response:offset - <render-sandbox-results> - { - sandbox-screen:&:screen <- get *sandbox, screen:offset - empty-screen?:bool <- fake-screen-is-empty? sandbox-screen - break-if empty-screen? - row, screen <- render-screen screen, sandbox-screen, left, right, row - } - { - break-unless empty-screen? - <render-sandbox-response> - row, screen <- render-text screen, sandbox-response, left, right, 245/grey, row - } - +render-sandbox-end - at-bottom?:bool <- greater-or-equal row, screen-height - return-if at-bottom? - # draw solid line after sandbox - draw-horizontal screen, row, left, right - } - # if hidden, reset row attributes - { - break-unless hidden? - *sandbox <- put *sandbox, starting-row-on-screen:offset, 0 - *sandbox <- put *sandbox, code-ending-row-on-screen:offset, 0 - <end-render-sandbox-reset-hidden> - } - # draw next sandbox - next-sandbox:&:sandbox <- get *sandbox, next-sandbox:offset - next-idx:num <- add idx, 1 - row, screen <- render-sandboxes screen, next-sandbox, left, right, row, render-from, next-idx, env -] - -def render-sandbox-menu screen:&:screen, sandbox-index:num, left:num, right:num -> screen:&:screen [ - local-scope - load-inputs - move-cursor-to-column screen, left - edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num <- sandbox-menu-columns left, right - print screen, sandbox-index, 232/dark-grey, 245/grey - start-buttons:num <- subtract edit-button-left, 1 - clear-line-until screen, start-buttons, 245/grey - print screen, [edit], 232/black, 25/background-blue - clear-line-until screen, edit-button-right, 25/background-blue - print screen, [copy], 232/black, 58/background-green - clear-line-until screen, copy-button-right, 58/background-green - print screen, [delete], 232/black, 52/background-red - clear-line-until screen, right, 52/background-red -] - -scenario skip-rendering-sandbox-menu-past-bottom-row [ - trace-until 100/app # trace too long - assume-screen 50/width, 6/height - # recipes.mu is empty - assume-resources [ - [lesson/0] <- [|add 2, 2|] - [lesson/1] <- [|add 1, 1|] - ] - # create two sandboxes such that the top one just barely fills the screen - env:&:environment <- new-programming-environment resources, screen, [] - env <- restore-sandboxes env, resources - run [ - render-all screen, env, render - ] - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 2, 2 . - .──────────────────────────────────────────────────. - ] -] - -# divide up the menu bar for a sandbox into 3 segments, for edit/copy/delete buttons -# delete-button-right == right -# all left/right pairs are inclusive -def sandbox-menu-columns left:num, right:num -> edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num [ - local-scope - load-inputs - start-buttons:num <- add left, 4/space-for-sandbox-index - buttons-space:num <- subtract right, start-buttons - button-width:num <- divide-with-remainder buttons-space, 3 # integer division - buttons-wide-enough?:bool <- greater-or-equal button-width, 8 - assert buttons-wide-enough?, [sandbox must be at least 30 or so characters wide] - edit-button-left:num <- copy start-buttons - copy-button-left:num <- add start-buttons, button-width - edit-button-right:num <- subtract copy-button-left, 1 - delete-button-left:num <- subtract right, button-width - copy-button-right:num <- subtract delete-button-left, 1 -] - -# print a text 's' to 'editor' in 'color' starting at 'row' -# clear rest of last line, move cursor to next line -def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num -> row:num, screen:&:screen [ - local-scope - load-inputs - return-unless s - column:num <- copy left - screen <- move-cursor screen, row, column - screen-height:num <- screen-height screen - i:num <- copy 0 - len:num <- length *s - { - +next-character - done?:bool <- greater-or-equal i, len - break-if done? - done? <- greater-or-equal row, screen-height - break-if done? - c:char <- index *s, i - { - # newline? move to left rather than 0 - newline?:bool <- equal c, 10/newline - break-unless newline? - # clear rest of line in this window - { - done?:bool <- greater-than column, right - break-if done? - space:char <- copy 32/space - print screen, space - column <- add column, 1 - loop - } - row <- add row, 1 - column <- copy left - screen <- move-cursor screen, row, column - i <- add i, 1 - loop +next-character - } - { - # at right? wrap. - at-right?:bool <- equal column, right - break-unless at-right? - # print wrap icon - wrap-icon:char <- copy 8617/loop-back-to-left - print screen, wrap-icon, 245/grey - column <- copy left - row <- add row, 1 - screen <- move-cursor screen, row, column - # don't increment i - loop +next-character - } - i <- add i, 1 - print screen, c, color - column <- add column, 1 - loop - } - was-at-left?:bool <- equal column, left - clear-line-until screen, right - { - break-if was-at-left? - row <- add row, 1 - } - move-cursor screen, row, left -] - -scenario render-text-wraps-barely-long-lines [ - local-scope - assume-screen 5/width, 5/height - run [ - render-text screen, [abcde], 0/left, 4/right, 7/white, 1/row - ] - screen-should-contain [ - . . - .abcd↩. - .e . - . . - ] -] - -# assumes programming environment has no sandboxes; restores them from previous session -def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environment [ - local-scope - load-inputs - # read all scenarios, pushing them to end of a list of scenarios - idx:num <- copy 0 - curr:&:sandbox <- copy null - prev:&:sandbox <- copy null - { - filename:text <- append [lesson/], idx - contents:text <- slurp resources, filename - break-unless contents # stop at first error; assuming file didn't exist - # todo: handle empty sandbox - # create new sandbox for file - curr <- new sandbox:type - *curr <- put *curr, data:offset, contents - <end-restore-sandbox> - { - break-if idx - *env <- put *env, sandbox:offset, curr - } - { - break-unless idx - *prev <- put *prev, next-sandbox:offset, curr - } - idx <- add idx, 1 - prev <- copy curr - loop - } - # update sandbox count - *env <- put *env, number-of-sandboxes:offset, idx -] - -# print the fake sandbox screen to 'screen' with appropriate delimiters -# leave cursor at start of next line -def render-screen screen:&:screen, sandbox-screen:&:screen, left:num, right:num, row:num -> row:num, screen:&:screen [ - local-scope - load-inputs - return-unless sandbox-screen - # print 'screen:' - row <- render-text screen, [screen:], left, right, 245/grey, row - screen <- move-cursor screen, row, left - # start printing sandbox-screen - column:num <- copy left - s-width:num <- screen-width sandbox-screen - s-height:num <- screen-height sandbox-screen - buf:&:@:screen-cell <- get *sandbox-screen, data:offset - stop-printing:num <- add left, s-width, 3 - max-column:num <- min stop-printing, right - i:num <- copy 0 - len:num <- length *buf - screen-height:num <- screen-height screen - { - done?:bool <- greater-or-equal i, len - break-if done? - done? <- greater-or-equal row, screen-height - break-if done? - column <- copy left - screen <- move-cursor screen, row, column - # initial leader for each row: two spaces and a '.' - space:char <- copy 32/space - print screen, space, 245/grey - print screen, space, 245/grey - full-stop:char <- copy 46/period - print screen, full-stop, 245/grey - column <- add left, 3 - { - # print row - row-done?:bool <- greater-or-equal column, max-column - break-if row-done? - curr:screen-cell <- index *buf, i - c:char <- get curr, contents:offset - color:num <- get curr, color:offset - { - # damp whites down to grey - white?:bool <- equal color, 7/white - break-unless white? - color <- copy 245/grey - } - print screen, c, color - column <- add column, 1 - i <- add i, 1 - loop - } - # print final '.' - print screen, full-stop, 245/grey - column <- add column, 1 - { - # clear rest of current line - line-done?:bool <- greater-than column, right - break-if line-done? - print screen, space - column <- add column, 1 - loop - } - row <- add row, 1 - loop - } -] - -scenario run-updates-results [ - local-scope - trace-until 100/app # trace too long - assume-screen 50/width, 12/height - # define a recipe (no indent for the 'add' line below so column numbers are more obvious) - assume-resources [ - [lesson/recipes.mu] <- [ - || - |recipe foo [| - | local-scope| - | z:num <- add 2, 2| - | reply z| - |]| - ] - ] - # sandbox editor contains an instruction without storing outputs - env:&:environment <- new-programming-environment resources, screen, [foo] # contents of sandbox editor - render-all screen, env, render - $clear-trace - # run the code in the editors - assume-console [ - press F4 - ] - event-loop screen, console, env, resources - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .foo . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # the new sandbox should be saved to disk - trace-should-contain [ - app: save sandboxes - ] - # make a change (incrementing one of the args to 'add'), then rerun - assume-resources [ - [lesson/recipes.mu] <- [ - || - |recipe foo [| - | local-scope| - | z:num <- add 2, 3| - | reply z| - |]| - ] - ] - $clear-trace - assume-console [ - press F4 - ] - run [ - event-loop screen, console, env, resources - ] - # check that screen updates the result on the right - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .foo . - .5 . - .──────────────────────────────────────────────────. - . . - ] - # no need to save sandboxes all over again - trace-should-not-contain [ - app: save sandboxes - ] -] - -scenario run-instruction-manages-screen-per-sandbox [ - local-scope - trace-until 100/app # trace too long - assume-screen 50/width, 20/height - # empty recipes - assume-resources [ - ] - # sandbox editor contains an instruction - env:&:environment <- new-programming-environment resources, screen, [print screen, 4] # contents of sandbox editor - render-all screen, env, render - # run the code in the editor - assume-console [ - press F4 - ] - run [ - event-loop screen, console, env, resources - ] - # check that it prints a little toy screen - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .print screen, 4 . - .screen: . - . .4 . . - . . . . - . . . . - . . . . - . . . . - .──────────────────────────────────────────────────. - . . - ] -] - -def editor-contents editor:&:editor -> result:text [ - local-scope - load-inputs - buf:&:buffer:char <- new-buffer 80 - curr:&:duplex-list:char <- get *editor, data:offset - # skip § sentinel - assert curr, [editor without data is illegal; must have at least a sentinel] - curr <- next curr - return-unless curr, null - { - break-unless curr - c:char <- get *curr, value:offset - buf <- append buf, c - curr <- next curr - loop - } - result <- buffer-to-array buf -] - -scenario editor-provides-edited-contents [ - local-scope - assume-screen 10/width, 5/height - e:&:editor <- new-editor [abc], 0/left, 10/right - assume-console [ - left-click 1, 2 - type [def] - ] - run [ - editor-event-loop screen, console, e - s:text <- editor-contents e - 1:@:char/raw <- copy *s - ] - memory-should-contain [ - 1:array:character <- [abdefc] - ] -] - -# scrolling through sandboxes - -scenario scrolling-down-past-bottom-of-sandbox-editor [ - local-scope - trace-until 100/app # trace too long - assume-screen 50/width, 20/height - # initialize - assume-resources [ - ] - env:&:environment <- new-programming-environment resources, screen, [add 2, 2] - render-all screen, env, render - assume-console [ - # create a sandbox - press F4 - ] - event-loop screen, console, env, resources - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-down' - assume-console [ - press page-down - ] - run [ - event-loop screen, console, env, resources - cursor:char <- copy 9251/␣ - print screen, cursor - ] - # sandbox editor hidden; first sandbox displayed - # cursor moves to first sandbox - screen-should-contain [ - . run (F4) . - .──────────────────────────────────────────────────. - .␣ edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-up' - assume-console [ - press page-up - ] - run [ - event-loop screen, console, env, resources - cursor:char <- copy 9251/␣ - print screen, cursor - ] - # sandbox editor displays again - screen-should-contain [ - . run (F4) . - .␣ . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] -] - -# page-down updates render-from to scroll sandboxes -after <global-keypress> [ - { - page-down?:bool <- equal k, 65518/page-down - break-unless page-down? - sandbox:&:sandbox <- get *env, sandbox:offset - break-unless sandbox - # slide down if possible - { - render-from:num <- get *env, render-from:offset - number-of-sandboxes:num <- get *env, number-of-sandboxes:offset - max:num <- subtract number-of-sandboxes, 1 - at-end?:bool <- greater-or-equal render-from, max - break-if at-end? - render-from <- add render-from, 1 - *env <- put *env, render-from:offset, render-from - } - screen <- render-sandbox-side screen, env, render - screen <- update-cursor screen, current-sandbox, env - loop +next-event - } -] - -# update-cursor takes render-from into account -after <update-cursor-special-cases> [ - { - render-from:num <- get *env, render-from:offset - scrolling?:bool <- greater-or-equal render-from, 0 - break-unless scrolling? - cursor-column:num <- get *current-sandbox, left:offset - screen <- move-cursor screen, 2/row, cursor-column # highlighted sandbox will always start at row 2 - return - } -] - -# 'page-up' is like 'page-down': updates first-sandbox-to-render when necessary -after <global-keypress> [ - { - page-up?:bool <- equal k, 65519/page-up - break-unless page-up? - render-from:num <- get *env, render-from:offset - at-beginning?:bool <- equal render-from, -1 - break-if at-beginning? - render-from <- subtract render-from, 1 - *env <- put *env, render-from:offset, render-from - screen <- render-sandbox-side screen, env, render - screen <- update-cursor screen, current-sandbox, env - loop +next-event - } -] - -# sandbox belonging to 'env' whose next-sandbox is 'in' -# return null if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox -def previous-sandbox env:&:environment, in:&:sandbox -> out:&:sandbox [ - local-scope - load-inputs - curr:&:sandbox <- get *env, sandbox:offset - return-unless curr, null - next:&:sandbox <- get *curr, next-sandbox:offset - { - return-unless next, null - found?:bool <- equal next, in - break-if found? - curr <- copy next - next <- get *curr, next-sandbox:offset - loop - } - return curr -] - -scenario scrolling-through-multiple-sandboxes [ - local-scope - trace-until 100/app # trace too long - assume-screen 50/width, 20/height - # initialize environment - assume-resources [ - ] - env:&:environment <- new-programming-environment resources, screen, [] - render-all screen, env, render - # create 2 sandboxes - assume-console [ - press ctrl-n - type [add 2, 2] - press F4 - type [add 1, 1] - press F4 - ] - event-loop screen, console, env, resources - cursor:char <- copy 9251/␣ - print screen, cursor - screen-should-contain [ - . run (F4) . - .␣ . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-down' - assume-console [ - press page-down - ] - run [ - event-loop screen, console, env, resources - cursor:char <- copy 9251/␣ - print screen, cursor - ] - # sandbox editor hidden; first sandbox displayed - # cursor moves to first sandbox - screen-should-contain [ - . run (F4) . - .──────────────────────────────────────────────────. - .␣ edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-down' again - assume-console [ - press page-down - ] - run [ - event-loop screen, console, env, resources - ] - # just second sandbox displayed - screen-should-contain [ - . run (F4) . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-down' again - assume-console [ - press page-down - ] - run [ - event-loop screen, console, env, resources - ] - # no change - screen-should-contain [ - . run (F4) . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-up' - assume-console [ - press page-up - ] - run [ - event-loop screen, console, env, resources - ] - # back to displaying both sandboxes without editor - screen-should-contain [ - . run (F4) . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-up' again - assume-console [ - press page-up - ] - run [ - event-loop screen, console, env, resources - cursor:char <- copy 9251/␣ - print screen, cursor - ] - # back to displaying both sandboxes as well as editor - screen-should-contain [ - . run (F4) . - .␣ . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-up' again - assume-console [ - press page-up - ] - run [ - event-loop screen, console, env, resources - cursor:char <- copy 9251/␣ - print screen, cursor - ] - # no change - screen-should-contain [ - . run (F4) . - .␣ . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - .1 edit copy delete . - .add 2, 2 . - .4 . - .──────────────────────────────────────────────────. - . . - ] -] - -scenario scrolling-manages-sandbox-index-correctly [ - local-scope - trace-until 100/app # trace too long - assume-screen 50/width, 20/height - # initialize environment - assume-resources [ - ] - env:&:environment <- new-programming-environment resources, screen, [] - render-all screen, env, render - # create a sandbox - assume-console [ - press ctrl-n - type [add 1, 1] - press F4 - ] - event-loop screen, console, env, resources - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-down' and 'page-up' a couple of times. sandbox index should be stable - assume-console [ - press page-down - ] - run [ - event-loop screen, console, env, resources - ] - # sandbox editor hidden; first sandbox displayed - # cursor moves to first sandbox - screen-should-contain [ - . run (F4) . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-up' again - assume-console [ - press page-up - ] - run [ - event-loop screen, console, env, resources - ] - # back to displaying both sandboxes as well as editor - screen-should-contain [ - . run (F4) . - . . - .──────────────────────────────────────────────────. - .0 edit copy delete . - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - . . - ] - # hit 'page-down' - assume-console [ - press page-down - ] - run [ - event-loop screen, console, env, resources - ] - # sandbox editor hidden; first sandbox displayed - # cursor moves to first sandbox - screen-should-contain [ - . run (F4) . - .──────────────────────────────────────────────────. - .0 edit copy delete . # no change - .add 1, 1 . - .2 . - .──────────────────────────────────────────────────. - . . - ] -] |