Merge text.love
[?]
Jan 21, 2023, 6:30 AM
ECBDENZ4ZEIYS3FJQNTIW2NITDIQLYUFPIPA7KV4Z5TYVI5EECPACDependencies
- [2]
JCXL74WVbring back everything from commit a68647ae22 - [3]
4DHGKUMDMerge text.love - [4]
A4BSGS2CMerge lines.love - [5]
2CK5QI7Wmake love event names consistent - [6]
APX2PY6Gstop tracking wallclock time - [7]
OWK3U6VDtests for drawing polygons - [8]
TO6Y2G3Umore decoupling editor tests from App - [9]
JOPVPUSAediting source code from within the app - [10]
UTDSCN3GMerge lines.love - [11]
RXNR3U5EMerge text.love - [12]
GUOQRUL7Merge lines.love - [13]
D4B52CQ2Merge lines.love - [14]
ORKN6EOBMerge lines.love - [15]
DB7HJBHJMerge lines.love - [16]
66X36NZNa little more prose describing manual_tests - [17]
ZTZOO2OQMerge lines.love - [18]
CE4LZV4Tdrop last couple of manual tests - [19]
VHQCNMARseveral more modules - [20]
3PSFWAILMerge lines.love - [21]
V7LATJC7bugfix: resize - [22]
T7SJSJIHtest: undo naming a point - [23]
OTIBCAUJlove2d scaffold - [24]
CRYGI3LRmore drawing tests - [25]
ETXNVRPTMerge lines.love - [26]
W5H5YI6SMerge text.love - [27]
HOUCPP7PMerge text.love - [28]
VP5KC4XZMerge lines.love - [29]
LNUHQOGHstart passing in Editor_state explicitly - [30]
VXORMHMEdelete experimental REPL - [31]
KAUD3YIKtests: deleting points/shapes - [32]
T4FRZSYLdelete an ancient, unused file - [33]
2CTN2IEFMerge lines.love - [34]
R5QXEHUIsomebody stop me - [35]
APYPFFS3call edit rather than App callbacks in tests - [36]
73OCE2MCafter much struggle, a brute-force undo - [37]
TFM6F5ODMerge lines.love - [38]
TGZAJUEFbring back a set of constants - [39]
36Z442IVback to commit 8123959e52f without code editing - [40]
VZJHGWSPMerge lines.love - [41]
VHUNJHXBMerge lines.love - [42]
XX7G2FFJintermingle freehand line drawings with text - [43]
L6XA5EY2test: moving a point - [44]
3QNOKBFMbeginnings of a test harness - [45]
LXTTOB33extract a couple of files - [46]
RSZD5A7Gforgot to add json.lua - [47]
7DYUAOI6test: undo moving point - [48]
XGHCLIKBMerge lines.love - [49]
BLWAYPKVextract a module - [50]
LF7BWEG4group all editor globals - [51]
42LVB4DEtest: naming a point - [52]
ORRSP7FVdeduce test names on failures - [53]
FS2ITYYHrecord a known issue - [54]
4AXV2HG4all pending manual tests done! - [55]
OGUV4HSAremove some memory leaks from rendered fragments - [56]
TVCPXAAUrename - [57]
6LJZN727handle chords - [58]
PX7DDEMOautosave slightly less aggressively - [59]
2L5MEZV3experiment: new edit namespace - [60]
KKMFQDR4editing source code from within the app - [61]
UHB4GARJleft/right margin -> left/right coordinates - [62]
K2X6G75Zstart writing some tests for drawings - [63]
CNCYMM6Amake test initializations a little more obvious - [64]
KMSL74GAsupport selections in the source editor - [65]
C3GUE45IMerge text.love - [66]
4YDBYBA4clean up memory leak experiments - [67]
VSJS6O4CMerge text.love - [68]
MD3W5IRAnew fork: rip out drawing support - [69]
KG7YVGVRMerge lines.love - [70]
EX43CDDIMerge text.love - [71]
2WGHUWE6self-documenting 0 Test_right_margin - [72]
BJ5X5O4Alet's prevent the text cursor from ever getting on a drawing - [73]
D2GCFTTTclean up repl functionality - [74]
TLOAPLBJadd a license - [75]
BULPIBEGbeginnings of a module for the text editor - [76]
AYX33NBCMerge lines.love - [77]
AVTNUQYRbasic test-enabled framework - [78]
THRPA4VVMerge text.love
Change contents
- file deletion: drawing_tests.lua drawing_tests.lua
check_eq(Editor_state.next_history, 3, 'next_history')check_eq(drawing.shapes[1].mode, 'line', 'shape:1')check_eq(drawing.shapes[2].mode, 'line', 'shape:2')-- wait until savecheck_eq(#Editor_state.lines[1].shapes, 2, 'save')endCurrent_time = Current_time + 3.1-- wait until savecheck_eq(Editor_state.next_history, 2, 'next_history')check_eq(p2.x, 35, 'x')check_eq(p2.y, 36, 'y')-- wait until savecheck_eq(drawing.shapes[1].mode, 'deleted', 'shape:1')check_eq(drawing.shapes[2].mode, 'deleted', 'shape:2')-- undoedit.run_after_keychord(Editor_state, 'C-z')local drawing = Editor_state.lines[1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(#drawing.shapes, 2, 'baseline/#shapes')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')check_eq(drawing.shapes[2].mode, 'line', 'baseline/shape:2')-- hover on the common point and deleteApp.mouse_move(Editor_state.left+35, Editor_state.top+Drawing_padding_top+36)edit.run_after_keychord(Editor_state, 'C-d')check_eq(p2.x, 35, 'save/x')check_eq(p2.y, 36, 'save/y')endfunction test_undo_delete_point()Current_time = Current_time + 3.1-- wait until savecheck_eq(Editor_state.next_history, 3, 'next_history')check_eq(p2.name, '', 'undo') -- not quite what it was before, but close enough-- wait until savecheck_eq(Editor_state.next_history, 4, 'next_history')-- undoedit.run_after_keychord(Editor_state, 'C-z')edit.run_after_keychord(Editor_state, 'C-z') -- bug: need to undo twicelocal drawing = Editor_state.lines[1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(p2.x, 26, 'x')check_eq(p2.y, 44, 'y')-- exit 'move' modeedit.run_after_mouse_click(Editor_state, Editor_state.left+26, Editor_state.top+Drawing_padding_top+44, 1)check_eq(p1.x, 5, 'baseline/p1:x')check_eq(p1.y, 6, 'baseline/p1:y')check_eq(p2.x, 35, 'baseline/p2:x')check_eq(p2.y, 36, 'baseline/p2:y')check_nil(p2.name, 'baseline/p2:name')-- move p2edit.run_after_keychord(Editor_state, 'C-u')App.mouse_move(Editor_state.left+26, Editor_state.top+Drawing_padding_top+44)edit.update(Editor_state, 0.05)local p2 = drawing.points[drawing.shapes[1].p2]check_eq(#drawing.shapes, 1, 'baseline/#shapes')check_eq(#drawing.points, 2, 'baseline/#points')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(p2.name, '', 'save')endfunction test_undo_move_point()Current_time = Current_time + 3.1-- wait until savecheck_eq(drawing.shapes[1].mode, 'deleted', 'shape:1')check_eq(drawing.shapes[2].mode, 'deleted', 'shape:2')-- wait for some timecheck_eq(p2.name, 'A', 'baseline')check_eq(#Editor_state.history, 3, 'baseline/history:2')check_eq(Editor_state.next_history, 4, 'baseline/next_history')--? print('b', Editor_state.lines.current_drawing)-- undoedit.run_after_keychord(Editor_state, 'C-z')local drawing = Editor_state.lines[1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(p1.x, 5, 'baseline/p1:x')check_eq(p1.y, 6, 'baseline/p1:y')check_eq(p2.x, 35, 'baseline/p2:x')check_eq(p2.y, 36, 'baseline/p2:y')check_nil(p2.name, 'baseline/p2:name')check_eq(#Editor_state.history, 1, 'baseline/history:1')--? print('a', Editor_state.lines.current_drawing)-- enter 'name' mode without moving the mouseedit.run_after_keychord(Editor_state, 'C-n')check_eq(#drawing.shapes, 1, 'baseline/#shapes')check_eq(#drawing.points, 2, 'baseline/#points')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(drawing.shapes[1].mode, 'deleted', 'check')endfunction test_undo_name_point()check_eq(#drawing.shapes, 1, 'baseline/#shapes')check_eq(drawing.shapes[1].mode, 'polygon', 'baseline/mode')check_eq(#drawing.shapes[1].vertices, 3, 'baseline/vertices')-- hover on a point and deleteApp.mouse_move(Editor_state.left+65, Editor_state.top+Drawing_padding_top+36)edit.run_after_keychord(Editor_state, 'C-d')-- there's < 3 points left, so the whole polygon is deletedcheck_eq(drawing.shapes[1].mode, 'polygon', 'shape')check_eq(#drawing.shapes[1].vertices, 3, 'vertices')endfunction test_delete_point_from_polygon()check_eq(#drawing.shapes, 1, 'baseline/#shapes')check_eq(drawing.shapes[1].mode, 'polygon', 'baseline/mode')check_eq(#drawing.shapes[1].vertices, 4, 'baseline/vertices')-- hover on a point and deleteApp.mouse_move(Editor_state.left+35, Editor_state.top+Drawing_padding_top+26)edit.run_after_keychord(Editor_state, 'C-d')-- just the one point is deletedcheck_eq(drawing.shapes[1].mode, 'deleted', 'shape:1')check_eq(drawing.shapes[2].mode, 'line', 'shape:2')endfunction test_delete_point_from_polygon()check_eq(#drawing.shapes, 2, 'baseline/#shapes')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')check_eq(drawing.shapes[2].mode, 'line', 'baseline/shape:2')-- hover on one of the lines and deleteApp.mouse_move(Editor_state.left+25, Editor_state.top+Drawing_padding_top+26)edit.run_after_keychord(Editor_state, 'C-d')-- only that line is deletedcheck_eq(#Editor_state.lines[1].shapes, 0, 'save')endfunction test_delete_line_under_mouse_pointer()Current_time = Current_time + 3.1-- wait for some timecheck_eq(Editor_state.current_drawing_mode, 'line', 'mode:3')check_eq(drawing.pending, {}, 'pending')-- wait until savecheck_eq(#drawing.shapes, 2, 'baseline/#shapes')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')check_eq(drawing.shapes[2].mode, 'line', 'baseline/shape:2')-- hover on the common point and deleteApp.mouse_move(Editor_state.left+35, Editor_state.top+Drawing_padding_top+36)edit.run_after_keychord(Editor_state, 'C-d')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')endfunction test_delete_lines_at_point()check_eq(Editor_state.current_drawing_mode, 'move', 'mode:1')-- move pointApp.mouse_move(Editor_state.left+26, Editor_state.top+Drawing_padding_top+44)edit.update(Editor_state, 0.05)-- line is no longer manhattancheck_eq(#drawing.shapes, 1, 'baseline/#shapes')check_eq(#drawing.points, 2, 'baseline/#points')check_eq(drawing.shapes[1].mode, 'manhattan', 'baseline/shape:1')edit.draw(Editor_state)-- enter 'move' modeedit.run_after_keychord(Editor_state, 'C-u')check_eq(p2.x, 26, 'save/x')check_eq(p2.y, 44, 'save/y')endfunction test_move_point_on_manhattan_line()Current_time = Current_time + 3.1-- wait until savecheck_eq(p1.x, 5, 'baseline/p1:x')check_eq(p1.y, 6, 'baseline/p1:y')check_eq(p2.x, 35, 'baseline/p2:x')check_eq(p2.y, 36, 'baseline/p2:y')-- wait until savecheck_eq(p2.x, 26, 'x')check_eq(p2.y, 44, 'y')-- exit 'move' modeedit.run_after_mouse_click(Editor_state, Editor_state.left+26, Editor_state.top+Drawing_padding_top+44, 1)check_eq(drawing.pending.mode, 'move', 'mode:2')check_eq(drawing.pending.target_point, p2, 'target')-- move pointApp.mouse_move(Editor_state.left+26, Editor_state.top+Drawing_padding_top+44)edit.update(Editor_state, 0.05)local p2 = drawing.points[drawing.shapes[1].p2]check_eq(Editor_state.current_drawing_mode, 'move', 'mode:1')-- point is liftedcheck_eq(p2.x, 35, 'save/x')check_eq(p2.y, 36, 'save/y')edit.draw(Editor_state)-- enter 'move' mode without moving the mouseedit.run_after_keychord(Editor_state, 'C-u')Current_time = Current_time + 3.1-- wait until savecheck_eq(#drawing.shapes, 1, 'baseline/#shapes')check_eq(#drawing.points, 2, 'baseline/#points')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(Editor_state.current_drawing_mode, 'line', 'mode:3')check_eq(p2.name, 'A', 'check2')-- wait until savecheck_eq(p2.name, 'A', 'save')endfunction test_move_point()Current_time = Current_time + 3.1-- wait until savecheck_eq(Editor_state.current_drawing_mode, 'name', 'mode:2')-- exit 'name' modeedit.run_after_keychord(Editor_state, 'return')-- exit 'name' modecheck_eq(p2.name, 'A', 'check1')-- still in 'name' mode-- still in 'name' modecheck_eq(Editor_state.current_drawing_mode, 'name', 'mode:1')edit.run_after_text_input(Editor_state, 'A')edit.run_after_text_input(Editor_state, 'A')check_eq(p1.x, 5, 'baseline/p1:x')check_eq(p1.y, 6, 'baseline/p1:y')check_eq(p2.x, 35, 'baseline/p2:x')check_eq(p2.y, 36, 'baseline/p2:y')check_nil(p2.name, 'baseline/p2:name')-- enter 'name' mode without moving the mouseedit.run_after_keychord(Editor_state, 'C-n')-- enter 'name' mode without moving the mousecheck_eq(#drawing.shapes, 1, 'baseline/#shapes')check_eq(#drawing.points, 2, 'baseline/#points')check_eq(drawing.shapes[1].mode, 'line', 'baseline/shape:1')local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(p1.x, 5, 'p1:x')check_eq(p1.y, 6, 'p1:y')check_eq(p2.x, 35, 'p2:x')check_eq(p2.y, 36, 'p2:y')-- wait until savecheck_eq(p.x, 5, 'p4:x')check_eq(p.y, 66, 'p4:y')endfunction test_name_point()check_eq(p.x, 35, 'p3:x')check_eq(p.y, 96, 'p3:y')local p = drawing.points[drawing.shapes[1].vertices[4]]check_eq(p.x, 65, 'p2:x')check_eq(p.y, 66, 'p2:y')local p = drawing.points[drawing.shapes[1].vertices[3]]check_eq(p.x, 35, 'p1:x')check_eq(p.y, 36, 'p1:y')local p = drawing.points[drawing.shapes[1].vertices[2]]check_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 5, '#points') -- currently includes every point addedcheck_eq(drawing.shapes[1].mode, 'square', 'shape_mode')check_eq(#drawing.shapes[1].vertices, 4, 'vertices')local p = drawing.points[drawing.shapes[1].vertices[1]]check_eq(Editor_state.current_drawing_mode, 'line', 'baseline/drawing_mode')check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- first pointedit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)check_eq(p.x, 75, 'p2:x')check_eq(p.y, 76, 'p2:y')-- outline of rectangle is drawn based on where the mouse is, but we can't check that so farendfunction test_draw_square()check_eq(p.x, 35, 'p1:x')check_eq(p.y, 36, 'p1:y')local p = drawing.points[pending.vertices[2]]check_eq(pending.mode, 'rectangle', 'shape_mode')check_eq(#pending.vertices, 2, 'vertices')local p = drawing.points[pending.vertices[1]]check_eq(#drawing.points, 3, '#points') -- currently includes every point addedlocal pending = drawing.pendingcheck_eq(Editor_state.current_drawing_mode, 'line', 'baseline/drawing_mode')check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- first pointedit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)check_eq(p.x, 30, 'p4:x')check_eq(p.y, 41, 'p4:y')endfunction test_draw_rectangle_intermediate()check_eq(p.x, 70, 'p3:x')check_eq(p.y, 81, 'p3:y')local p = drawing.points[shape.vertices[4]]check_eq(p.x, 75, 'p2:x')check_eq(p.y, 76, 'p2:y')local p = drawing.points[shape.vertices[3]]check_eq(p.x, 35, 'p1:x')check_eq(p.y, 36, 'p1:y')local p = drawing.points[shape.vertices[2]]check_eq(shape.mode, 'rectangle', 'shape_mode')check_eq(#shape.vertices, 4, 'vertices')local p = drawing.points[shape.vertices[1]]check_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 5, '#points') -- currently includes every point addedlocal shape = drawing.shapes[1]check_eq(Editor_state.current_drawing_mode, 'line', 'baseline/drawing_mode')check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- first pointedit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)check_eq(p.x, 35, 'p3:x')check_eq(p.y, 26, 'p3:y')endfunction test_draw_rectangle()check_eq(p.x, 65, 'p2:x')check_eq(p.y, 36, 'p2:y')local p = drawing.points[shape.vertices[3]]check_eq(p.x, 5, 'p1:x')check_eq(p.y, 6, 'p1:y')local p = drawing.points[shape.vertices[2]]check_eq(shape.mode, 'polygon', 'shape_mode')check_eq(#shape.vertices, 3, 'vertices')local p = drawing.points[shape.vertices[1]]check_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 3, 'vertices')local shape = drawing.shapes[1]check_eq(Editor_state.current_drawing_mode, 'line', 'baseline/drawing_mode')check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- first pointedit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Drawing_padding_top+6, 1)check_eq(center.x, 35, 'center:x')check_eq(center.y, 36, 'center:y')check_eq(arc.start_angle, 0, 'start:angle')check_eq(arc.end_angle, math.pi/4, 'end:angle')endfunction test_draw_polygon()check_eq(arc.radius, 30, 'radius')local center = drawing.points[arc.center]check_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 1, '#points')check_eq(drawing.shapes[1].mode, 'arc', 'shape_mode')local arc = drawing.shapes[1]check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- draw an arcedit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)App.mouse_move(Editor_state.left+35+30, Editor_state.top+Drawing_padding_top+36)check_eq(center.x, 35, 'center:x')check_eq(center.y, 36, 'center:y')endfunction test_draw_arc()check_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 1, '#points')check_eq(drawing.shapes[1].mode, 'circle', 'shape_mode')check_eq(drawing.shapes[1].radius, 30, 'radius')local center = drawing.points[drawing.shapes[1].center]check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- draw a circleApp.mouse_move(Editor_state.left+4, Editor_state.top+Drawing_padding_top+4) -- hover on drawingedit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)check_eq(Editor_state.current_drawing_mode, 'line', 'drawing_mode')-- no change to text either because we didn't run the text_input eventcheck_eq(#drawing.shapes, 0, '#shapes')endfunction test_keys_do_not_affect_shape_when_mouse_up()check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- start drawing a lineedit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Drawing_padding_top+6, 1)-- canceledit.run_after_keychord(Editor_state, 'escape')edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)local drawing = Editor_state.lines[1]check_eq(center.x, 35, 'center:x')check_eq(center.y, 36, 'center:y')endfunction test_cancel_stroke()check_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 1, '#points')check_eq(drawing.shapes[1].mode, 'circle', 'shape_mode')check_eq(drawing.shapes[1].radius, 30, 'radius')local center = drawing.points[drawing.shapes[1].center]check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- draw a circleApp.mouse_move(Editor_state.left+4, Editor_state.top+Drawing_padding_top+4) -- hover on drawingedit.run_after_keychord(Editor_state, 'C-o')edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)edit.run_after_mouse_release(Editor_state, Editor_state.left+35+30, Editor_state.top+Drawing_padding_top+36, 1)local drawing = Editor_state.lines[1]check_eq(p1.x, 5, 'p1:x')check_eq(p1.y, 6, 'p1:y')check_eq(p2.x, 35, 'p2:x')check_eq(p2.y, p1.y, 'p2:y')endfunction test_draw_circle()check_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 2, '#points')check_eq(drawing.shapes[1].mode, 'manhattan', 'shape_mode')local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- draw a line that is more horizontal than verticaledit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Drawing_padding_top+6, 1)edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+26, 1)local drawing = Editor_state.lines[1]check_eq(p1.x, 5, 'save/p1:x')check_eq(p1.y, 6, 'save/p1:y')check_eq(p2.x, 35, 'save/p2:x')check_eq(p2.y, 36, 'save/p2:y')endfunction test_draw_horizontal_line()check_eq(#drawing.shapes, 1, 'save/#shapes')check_eq(#drawing.points, 2, 'save/#points')check_eq(drawing.shapes[1].mode, 'line', 'save/shape:1')local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]Current_time = Current_time + 3.1-- wait until savecheck_eq(#drawing.shapes, 1, '#shapes')check_eq(#drawing.points, 2, '#points')check_eq(drawing.shapes[1].mode, 'line', 'shape:1')local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]local p1 = drawing.points[drawing.shapes[1].p1]local p2 = drawing.points[drawing.shapes[1].p2]check_eq(#Editor_state.lines, 2, 'baseline/#lines')check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode')check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y')check_eq(Editor_state.lines[1].h, 128, 'baseline/y')check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes')-- draw a lineedit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Drawing_padding_top+6, 1)edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1)local drawing = Editor_state.lines[1]-- draw a linecheck_nil(App.filesystem['foo'], 'early')-- wait until savecheck_eq(App.filesystem['foo'], '```lines\n```\n\n', 'check')endfunction test_draw_line()Current_time = Current_time + 3.1-- wait until save - file deletion: source_text_tests.lua source_text_tests.lua
check_eq(Editor_state.cursor1.line, 1, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 5, '1/cursor:pos')endcheck_eq(Editor_state.cursor1.line, 1, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')endfunction test_search_wrap_upwards()check_eq(Editor_state.cursor1.line, 1, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')endfunction test_search_wrap()check_eq(Editor_state.cursor1.line, 4, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')endfunction test_search_upwards()check_eq(Editor_state.cursor1.line, 2, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')-- reset cursorEditor_state.cursor1 = {line=1, pos=1}Editor_state.screen_top1 = {line=1, pos=1}-- search for second occurrenceedit.run_after_keychord(Editor_state, 'C-f')check_eq(Editor_state.selection1.line, 1, 'line')check_eq(Editor_state.selection1.pos, 2, 'pos')endcheck_eq(Editor_state.lines[1].data, 'xbc', 'baseline')check_nil(Editor_state.selection1.line, 'baseline:selection')-- undoedit.run_after_keychord(Editor_state, 'C-z')edit.run_after_keychord(Editor_state, 'C-z')-- selection is restoredApp.screen.check(y, 'xyz', 'screen:3')endApp.screen.check(y, 'defg', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')--? check_eq(Editor_state.selection1.line, 2, 'selection:line')--? check_eq(Editor_state.selection1.pos, 4, 'selection:pos')y = Editor_state.topApp.screen.check(y, 'xyz', 'baseline/screen:3')-- undo--? -- after undo, the backspaced key is selectededit.run_after_keychord(Editor_state, 'C-z')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'baseline/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'baseline/cursor:pos')check_nil(Editor_state.selection1.line, 'baseline/selection:line')check_nil(Editor_state.selection1.pos, 'baseline/selection:pos')local y = Editor_state.topApp.screen.check(y, 'xyz', 'screen:3')endfunction test_undo_delete_text()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')y = Editor_state.topApp.screen.check(y, 'xyz', 'baseline/screen:3')-- undoedit.run_after_keychord(Editor_state, 'C-z')App.screen.check(y, 'defg', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'baseline/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'baseline/cursor:pos')check_nil(Editor_state.selection1.line, 'baseline/selection:line')check_nil(Editor_state.selection1.pos, 'baseline/selection:pos')local y = Editor_state.topcheck_nil(Editor_state.selection1.line, 'selection')endcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'abc', 'data:1')check_eq(Editor_state.lines[2].data, 'f', 'data:2')-- cursor remains at start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_to_start_of_line()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'a', 'data:1')check_eq(Editor_state.lines[2].data, 'def', 'data:2')-- cursor remains at start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_to_end_of_line()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'akl', 'data:1')check_eq(Editor_state.lines[2].data, 'mno', 'data:2')-- cursor remains at start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_over_multiple_lines()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'bc', 'data')-- cursor moves to start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_over_selection_reverse()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'bc', 'data')-- cursor (remains) at start of selectioncheck_eq(Editor_state.lines[1].data, 'abcdef', 'check')endApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_backspace_past_line_boundary()App.screen.check(y, 'kl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghij', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting backspace the screen scrolls up by one screen lineedit.run_after_keychord(Editor_state, 'backspace')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_backspace_can_scroll_up_screen_line()App.screen.check(y, 'ghi', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abcdef', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:3')-- after hitting backspace the screen scrolls up by one lineedit.run_after_keychord(Editor_state, 'backspace')App.screen.check(y, 'ghi', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 26, 'cursor:pos')endfunction test_backspace_can_scroll_up()App.screen.check(y, 'stu', 'baseline2/screen:3')-- try to move the cursor earlier in the third screen line by clicking the mouseApp.screen.check(y, 'jkl mno pqr ', 'baseline2/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc def ghi ', 'baseline2/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.pos, 28, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'xyz', 'baseline1/screen:3')-- add to the line until it's wrapping over 3 screen linesApp.screen.check(y, 'jkl mno pqr ', 'baseline1/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc def ghi ', 'baseline1/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_position_cursor_on_recently_edited_wrapping_line()-- draw a line wrapping over 2 screen linesApp.screen.check(y, 'ghi ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 8, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting end the screen scrolls down by one lineedit.run_after_keychord(Editor_state, 'end')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')endfunction test_end_scrolls_down_in_wrapped_line()App.screen.check(y, 'jkl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting home the screen scrolls up to first screen lineedit.run_after_keychord(Editor_state, 'home')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_home_scrolls_up_in_wrapped_line()App.screen.check(y, 'ghi ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the right arrow the screen scrolls down by one lineedit.run_after_keychord(Editor_state, 'right')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_right_arrow_scrolls_down_in_wrapped_line()App.screen.check(y, 'jkl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting the left arrow the screen scrolls up to first screen lineedit.run_after_keychord(Editor_state, 'left')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'kl', 'screen:3')endfunction test_left_arrow_scrolls_up_in_wrapped_line()App.screen.check(y, 'ghij', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 7, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after typing something the line wraps and the screen scrolls downApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'a', 'screen:1')endfunction test_typing_on_bottom_line_scrolls_down()check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')local y = Editor_state.topApp.screen.check(y, 'kl', 'screen:2')endfunction test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom()App.screen.check(y, 'j', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 4, 'screen_top')check_eq(Editor_state.cursor1.line, 5, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:1')-- after hitting the enter key the screen does not scroll downedit.run_after_keychord(Editor_state, 'return')App.screen.check(y, 'hi', 'screen:3')endfunction test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom()App.screen.check(y, 'g', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the enter key the screen scrolls downedit.run_after_keychord(Editor_state, 'return')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:3')endfunction test_enter_on_bottom_line_scrolls_down()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the page-up key the screen scrolls up to topedit.run_after_keychord(Editor_state, 'pageup')App.screen.check(y, 'jkl', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_pageup_scrolls_up_from_middle_screen_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the page-up key the screen scrolls up to topedit.run_after_keychord(Editor_state, 'pageup')App.screen.check(y, 'jkl', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:2')endfunction test_pageup_scrolls_up_by_screen_line()App.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:2')-- after pageup the cursor goes to first lineedit.run_after_keychord(Editor_state, 'pageup')App.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:3')endfunction test_pageup()App.screen.check(y, 'abc', 'screen:2')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.top-- empty first liney = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the up arrow the screen scrolls up by one lineedit.run_after_keychord(Editor_state, 'up')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 5, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')endfunction test_up_arrow_scrolls_up_to_empty_line()App.screen.check(y, 'ghi', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:3')-- after hitting the up arrow the screen scrolls up to final screen line of previous lineedit.run_after_keychord(Editor_state, 'up')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')endfunction test_up_arrow_scrolls_up_to_final_screen_line()App.screen.check(y, 'jkl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting the up arrow the screen scrolls up to first screen lineedit.run_after_keychord(Editor_state, 'up')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_up_arrow_scrolls_up_by_one_screen_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:3')-- after hitting the up arrow the screen scrolls up by one lineedit.run_after_keychord(Editor_state, 'up')App.screen.check(y, 'ghi', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_up_arrow_scrolls_up_by_one_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')-- the screen is unchangedy = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the up arrow the cursor moves up by 1 lineedit.run_after_keychord(Editor_state, 'up')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')endfunction test_up_arrow_moves_cursor()App.screen.check(y, 'kl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghij', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 3, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')y = Editor_state.topcheck_eq(Editor_state.screen_top1.line, 3, 'baseline2/screen_top')check_eq(Editor_state.cursor1.line, 3, 'baseline2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'baseline2/cursor:pos')-- after hitting down arrow the screen doesn't scroll down further, and certainly doesn't scroll upedit.run_after_keychord(Editor_state, 'down')App.screen.check(y, 'ghij', 'baseline/screen:3')-- after hitting pagedown the screen scrolls down to start of a long lineedit.run_after_keychord(Editor_state, 'pagedown')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'kl', 'screen:3')endApp.screen.check(y, 'ghij', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghij', 'baseline/screen:3')-- after hitting the down arrow the screen scrolls down by one lineedit.run_after_keychord(Editor_state, 'down')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word()App.screen.check(y, 'ghi ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the down arrow the screen scrolls down by one lineedit.run_after_keychord(Editor_state, 'down')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_down_arrow_scrolls_down_by_one_screen_line()App.screen.check(y, 'ghi', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the down arrow the screen scrolls down by one lineedit.run_after_keychord(Editor_state, 'down')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_down_arrow_scrolls_down_by_one_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')-- the screen is unchangedy = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the down arrow, the cursor moves down by 1 lineedit.run_after_keychord(Editor_state, 'down')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')endfunction test_down_arrow_moves_cursor()App.screen.check(y, 'mno ', 'screen:3')endfunction test_pagedown_never_moves_up()App.screen.check(y, 'jkl ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3')-- after pagedown we scroll down the very long wrapping lineedit.run_after_keychord(Editor_state, 'pagedown')App.screen.check(y, 'def ', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')endfunction test_pagedown_can_start_from_middle_of_long_wrapping_line()check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor')y = Editor_state.top + drawing_heightApp.screen.check(y, 'abc', 'baseline/screen:1')-- after pagedown the screen draws the drawing up top-- 15px margin + 10px margin + 25px drawing + 10px margin + 15px line3 = 75px < screen height 80pxedit.run_after_keychord(Editor_state, 'pagedown')check_eq(Editor_state.lines[2].mode, 'drawing', 'baseline/lines')Editor_state.cursor1 = {line=1, pos=1}Editor_state.screen_top1 = {line=1, pos=1}Editor_state.screen_bottom1 = {}local drawing_height = Drawing_padding_height + drawing_width/2 -- default-- initially the screen displays the first line and the drawing-- 15px margin + 15px line1 + 10px margin + 25px drawing + 10px margin = 75px < screen height 80pxedit.draw(Editor_state)local y = Editor_state.topApp.screen.check(y, 'ghi', 'screen:2')endfunction test_pagedown_skips_drawings()App.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')y = Editor_state.topApp.screen.check(y, 'def', 'baseline/screen:2')-- after pagedown the bottom line becomes the topedit.run_after_keychord(Editor_state, 'pagedown')App.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_nil(Editor_state.selection1.line, 'check')endcheck_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')endcheck_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_select_text_repeatedly_using_mouse_and_shift()check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_select_text_using_mouse_and_shift()App.screen.check(y, 'def', 'screen:3')endfunction test_select_text_using_mouse()App.screen.check(y, 'zbc', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'axy', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- paste some text including a newline, check that new line is createdApp.clipboard = 'xy\nz'edit.run_after_keychord(Editor_state, 'C-v')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_eq(Editor_state.lines[1].data, '', 'data:1')check_eq(Editor_state.lines[2].data, 'abc', 'data:2')endfunction test_insert_from_clipboard()App.screen.check(y, 'def', 'screen:3')endfunction test_insert_newline_at_start_of_line()App.screen.check(y, 'bc', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'a', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- hitting the enter key splits the lineedit.run_after_keychord(Editor_state, 'return')App.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'fg', 'screen:3')endfunction test_insert_newline()App.screen.check(y, 'de', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'check')check_eq(Editor_state.lines[1].data, 'ahi', 'data')endApp.screen.check(y, 'jkl', 'baseline/screen:3')-- set up a selection starting above the currently displayed pageEditor_state.selection1 = {line=1, pos=2}-- delete selectionedit.run_after_keychord(Editor_state, 'backspace')-- page scrolls upApp.screen.check(y, 'ghi', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.lines[1].data, 'xyzdef', 'check')endfunction test_deleting_selection_may_scroll()check_eq(Editor_state.lines[1].data, 'bc', 'data')endfunction test_paste_replaces_selection()check_eq(App.clipboard, 'a', 'clipboard')-- selected text is deletedcheck(Editor_state.selection1.line, 'check')endfunction test_cut()check_eq(App.clipboard, 'a', 'clipboard')-- selection is reset since shift key is not pressedcheck_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'Dbc', 'data')endfunction test_copy_does_not_reset_selection()check_eq(Editor_state.lines[1].data, 'xbc', 'check')endfunction test_edit_with_shift_key_deletes_selection()check_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'abc', 'data')endcheck_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 1, 'selection:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')endfunction test_cursor_movement_without_shift_resets_selection()check_eq(Editor_state.cursor1.pos, 20, 'cursor')endfunction test_select_text()App.screen.check(y, 'the quick brown fox ', 'baseline/screen:1')y = y + Editor_state.line_height-- click past the end of the screen lineedit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)-- cursor moves to end of screen linecheck_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-pointsendfunction test_click_past_end_of_word_wrapping_line()App.screen.check(y, 'am', 'baseline/screen:3')y = y + Editor_state.line_height-- click past the end of itedit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)-- cursor moves to end of lineApp.screen.check(y, 'I’m ad', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'madam ', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-pointsendfunction test_click_past_end_of_wrapping_line_containing_non_ascii()App.screen.check(y, 'am', 'baseline/screen:3')y = y + Editor_state.line_height-- click past the end of itedit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)-- cursor moves to end of lineApp.screen.check(y, "I'm ad", 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'madam ', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')endfunction test_click_past_end_of_wrapping_line()App.screen.check(y, "I'm ad", 'baseline/screen:2')y = y + Editor_state.line_height-- click past end of second screen lineedit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)-- cursor moves to end of screen linecheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')endfunction test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen()App.screen.check(y, "I'm ad", 'baseline/screen:2')y = y + Editor_state.line_height-- click past end of second screen lineedit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)-- cursor moves to end of screen lineApp.screen.check(y, 'madam ', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, '’m a', 'screen:3')endfunction test_click_on_wrapping_line()App.screen.check(y, 'am I', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'mad', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ijk', 'screen:3')endfunction test_draw_wrapping_text_containing_non_ascii()-- draw a long line containing non-ASCIIApp.screen.check(y, 'e fgh', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abcd ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endfunction test_draw_text_wrapping_within_word()-- arrange a screen line that needs to be split within a wordcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endApp.screen.check(y, 'ghi', 'screen:3')endApp.screen.check(y, 'def ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'fgh', 'screen:3')endfunction test_draw_word_wrapping_text()App.screen.check(y, 'de', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_draw_wrapping_text()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor')endfunction test_draw_text()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endcheck_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')endcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')-- selection is empty to avoid perturbing future editscheck_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos')endcheck_eq(Editor_state.cursor1.pos, 9, 'check')endfunction test_move_past_end_of_word_on_next_line()check_eq(Editor_state.cursor1.pos, 4, 'check')endfunction test_skip_multiple_spaces_to_next_word()check_eq(Editor_state.cursor1.pos, 8, 'check')endfunction test_skip_past_tab_to_next_word()check_eq(Editor_state.cursor1.pos, 4, 'check')endfunction test_skip_to_next_word()check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 5, 'pos')endfunction test_move_past_end_of_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_move_to_start_of_word_on_previous_line()check_eq(Editor_state.cursor1.pos, 9, 'check')endfunction test_skip_multiple_spaces_to_previous_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_skip_past_tab_to_previous_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_skip_to_previous_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_move_to_start_of_previous_word()check_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 1, 'pos')endfunction test_move_to_start_of_word()check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos') -- past end of lineendfunction test_move_right_to_next_line()check_eq(Editor_state.cursor1.pos, 2, 'check')endfunction test_move_left_to_previous_line()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_move_right()App.screen.check(y, 'a', 'screen:1')endfunction test_press_ctrl()check_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')endfunction test_insert_first_character()check_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor')endfunction test_backspace_from_start_of_final_line()check_eq(#Editor_state.lines, 2, '#lines')check_eq(Editor_state.cursor1.line, 2, 'cursor')endfunction test_backspace_to_delete_drawing()check_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')endfunction test_click_to_create_drawing() - file deletion: source_tests.lua source_tests.lua
check_eq(App.filesystem['foo'], 'abc\ndef\n', 'check')endcheck_eq(#Editor_state.lines, 3, '#lines')check_eq(Editor_state.lines[1].data, 'abc', 'lines:1')check_eq(Editor_state.lines[2].data, 'def', 'lines:2')check_eq(Editor_state.lines[3].data, 'ghi', 'lines:3')edit.draw(Editor_state)endfunction test_drop_file_saves_previous()check_eq(Editor_state.left, Margin_left, 'edit:left')check_eq(Editor_state.right, App.screen.width/2 - Margin_right, 'edit:right')check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'log:right')endfunction test_drop_file()check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'log:right')endfunction test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width()check_eq(Editor_state.left, Margin_left, 'edit:left')check_eq(Editor_state.right, old_editor_right, 'edit:right')-- log browser margins are adjustedcheck_eq(App.screen.width, 600, 'display:width')-- left side margins are unchangedcheck(Show_log_browser_side, 'check')endfunction test_show_log_browser_side_doubles_window_width_if_possible()check(not Show_log_browser_side, 'baseline')-- pressing ctrl+l shows log-browser sidecheck_eq(App.screen.width, 200, 'width')check_eq(App.screen.height, 400, 'height')check_eq(Editor_state.left, Margin_left, 'left_margin')check_eq(Editor_state.right, 200-Margin_right, 'right_margin')check_eq(Editor_state.width, 200-Margin_left-Margin_right, 'drawing_width')-- TODO: how to make assertions about when App.update got past the early exit?check_eq(App.screen.width, 300, 'baseline/width')check_eq(App.screen.height, 300, 'baseline/height')check_eq(Editor_state.left, Test_margin_left, 'baseline/left_margin')check_eq(Editor_state.right, 300 - Test_margin_right, 'baseline/right_margin')App.resize(200, 400) - edit in main_tests.lua at line 5
check_eq(Editor_state.right, 300 - Test_margin_right, 'F - test_resize_window/baseline/left_margin') - resurrect zombie in main_tests.lua at line 10
-- ugly; resize switches to real, non-test margins - replacement in main_tests.lua at line 11[5.466]→[2.2372:2453](∅→∅),[5.466]→[2.2372:2453](∅→∅),[5.489]→[2.2454:2555](∅→∅),[5.489]→[2.2454:2555](∅→∅)
check_eq(Editor_state.left, Margin_left, 'F - test_resize_window/left_margin')check_eq(Editor_state.width, 200-Margin_left-Margin_right, 'F - test_resize_window/drawing_width')check_eq(App.screen.width, 200, 'width')check_eq(App.screen.height, 400, 'height')check_eq(Editor_state.left, Margin_left, 'left_margin')check_eq(Editor_state.right, 200-Margin_right, 'right_margin')check_eq(Editor_state.width, 200-Margin_left-Margin_right, 'drawing_width') - resurrect zombie in app.lua at line 127
-- save/restore various framework globals we care about -- only on very first loadfunction App.snapshot_love()if Love_snapshot then return endLove_snapshot = {}-- save the entire initial font; it doesn't seem reliably recreated using newFontLove_snapshot.initial_font = love.graphics.getFont()endfunction App.undo_initialize()love.graphics.setFont(Love_snapshot.initial_font)end - edit in app.lua at line 139[2.4492]→[5.86:86](∅→∅),[5.209859]→[5.86:86](∅→∅),[5.209731]→[4.35182:35201](∅→∅),[5.209731]→[4.35182:35201](∅→∅),[5.209749]→[4.35202:35305](∅→∅),[5.209749]→[4.35202:35305](∅→∅),[5.209859]→[4.35307:35307](∅→∅),[5.209859]→[4.35307:35307](∅→∅)
Test_errors = {}if #Test_errors > 0 thenerror('There were test failures:\n\n'..table.concat(Test_errors))end - resolve order conflict in app.lua at line 139