1 -- major tests for drawings
2 -- We minimize assumptions about specific pixels, and try to test at the level
3 -- of specific shapes. In particular, no tests of freehand drawings.
5 function test_creating_drawing_saves()
6 App
.screen
.init
{width
=120, height
=60}
7 Editor_state
= edit
.initialize_test_state()
8 Editor_state
.filename
= 'foo'
9 Editor_state
.lines
= load_array
{}
10 Text
.redraw_all(Editor_state
)
11 edit
.draw(Editor_state
)
12 -- click on button to create drawing
13 edit
.run_after_mouse_click(Editor_state
, 8,Editor_state
.top
+8, 1)
14 -- file not immediately saved
15 edit
.update(Editor_state
, 0.01)
16 check_nil(App
.filesystem
['foo'], 'early')
18 Current_time
= Current_time
+ 3.1
19 edit
.update(Editor_state
, 0)
20 -- filesystem contains drawing and an empty line of text
21 check_eq(App
.filesystem
['foo'], '```lines\n```\n\n', 'check')
24 function test_draw_line()
25 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
26 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
27 Editor_state
= edit
.initialize_test_state()
28 Editor_state
.filename
= 'foo'
29 Editor_state
.lines
= load_array
{'```lines', '```', ''}
30 Text
.redraw_all(Editor_state
)
31 Editor_state
.current_drawing_mode
= 'line'
32 edit
.draw(Editor_state
)
33 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
34 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
35 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
36 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
37 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
39 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
40 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
41 local drawing
= Editor_state
.lines
[1]
42 check_eq(#drawing
.shapes
, 1, '#shapes')
43 check_eq(#drawing
.points
, 2, '#points')
44 check_eq(drawing
.shapes
[1].mode
, 'line', 'shape:1')
45 local p1
= drawing
.points
[drawing
.shapes
[1].p1
]
46 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
47 check_eq(p1
.x
, 5, 'p1:x')
48 check_eq(p1
.y
, 6, 'p1:y')
49 check_eq(p2
.x
, 35, 'p2:x')
50 check_eq(p2
.y
, 36, 'p2:y')
52 Current_time
= Current_time
+ 3.1
53 edit
.update(Editor_state
, 0)
54 -- The format on disk isn't perfectly stable. Table fields can be reordered.
55 -- So just reload from disk to verify.
56 load_from_disk(Editor_state
)
57 Text
.redraw_all(Editor_state
)
58 local drawing
= Editor_state
.lines
[1]
59 check_eq(#drawing
.shapes
, 1, 'save/#shapes')
60 check_eq(#drawing
.points
, 2, 'save/#points')
61 check_eq(drawing
.shapes
[1].mode
, 'line', 'save/shape:1')
62 local p1
= drawing
.points
[drawing
.shapes
[1].p1
]
63 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
64 check_eq(p1
.x
, 5, 'save/p1:x')
65 check_eq(p1
.y
, 6, 'save/p1:y')
66 check_eq(p2
.x
, 35, 'save/p2:x')
67 check_eq(p2
.y
, 36, 'save/p2:y')
70 function test_draw_horizontal_line()
71 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
72 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
73 Editor_state
= edit
.initialize_test_state()
74 Editor_state
.lines
= load_array
{'```lines', '```', ''}
75 Text
.redraw_all(Editor_state
)
76 Editor_state
.current_drawing_mode
= 'manhattan'
77 edit
.draw(Editor_state
)
78 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
79 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
80 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
81 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
82 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
83 -- draw a line that is more horizontal than vertical
84 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
85 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+26, 1)
86 local drawing
= Editor_state
.lines
[1]
87 check_eq(#drawing
.shapes
, 1, '#shapes')
88 check_eq(#drawing
.points
, 2, '#points')
89 check_eq(drawing
.shapes
[1].mode
, 'manhattan', 'shape_mode')
90 local p1
= drawing
.points
[drawing
.shapes
[1].p1
]
91 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
92 check_eq(p1
.x
, 5, 'p1:x')
93 check_eq(p1
.y
, 6, 'p1:y')
94 check_eq(p2
.x
, 35, 'p2:x')
95 check_eq(p2
.y
, p1
.y
, 'p2:y')
98 function test_draw_circle()
99 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
100 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
101 Editor_state
= edit
.initialize_test_state()
102 Editor_state
.lines
= load_array
{'```lines', '```', ''}
103 Text
.redraw_all(Editor_state
)
104 Editor_state
.current_drawing_mode
= 'line'
105 edit
.draw(Editor_state
)
106 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
107 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
108 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
109 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
110 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
112 App
.mouse_move(Editor_state
.left
+4, Editor_state
.top
+Drawing_padding_top
+4) -- hover on drawing
113 edit
.run_after_keychord(Editor_state
, 'C-o')
114 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
115 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35+30, Editor_state
.top
+Drawing_padding_top
+36, 1)
116 local drawing
= Editor_state
.lines
[1]
117 check_eq(#drawing
.shapes
, 1, '#shapes')
118 check_eq(#drawing
.points
, 1, '#points')
119 check_eq(drawing
.shapes
[1].mode
, 'circle', 'shape_mode')
120 check_eq(drawing
.shapes
[1].radius
, 30, 'radius')
121 local center
= drawing
.points
[drawing
.shapes
[1].center
]
122 check_eq(center
.x
, 35, 'center:x')
123 check_eq(center
.y
, 36, 'center:y')
126 function test_cancel_stroke()
127 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
128 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
129 Editor_state
= edit
.initialize_test_state()
130 Editor_state
.filename
= 'foo'
131 Editor_state
.lines
= load_array
{'```lines', '```', ''}
132 Text
.redraw_all(Editor_state
)
133 Editor_state
.current_drawing_mode
= 'line'
134 edit
.draw(Editor_state
)
135 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
136 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
137 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
138 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
139 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
140 -- start drawing a line
141 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
143 edit
.run_after_keychord(Editor_state
, 'escape')
144 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
145 local drawing
= Editor_state
.lines
[1]
146 check_eq(#drawing
.shapes
, 0, '#shapes')
149 function test_keys_do_not_affect_shape_when_mouse_up()
150 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
151 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
152 Editor_state
= edit
.initialize_test_state()
153 Editor_state
.lines
= load_array
{'```lines', '```', ''}
154 Text
.redraw_all(Editor_state
)
155 Editor_state
.current_drawing_mode
= 'line'
156 edit
.draw(Editor_state
)
157 -- hover over drawing and press 'o' without holding mouse
158 App
.mouse_move(Editor_state
.left
+4, Editor_state
.top
+Drawing_padding_top
+4) -- hover on drawing
159 edit
.run_after_keychord(Editor_state
, 'o')
160 -- no change to drawing mode
161 check_eq(Editor_state
.current_drawing_mode
, 'line', 'drawing_mode')
162 -- no change to text either because we didn't run the text_input event
165 function test_draw_circle_mid_stroke()
166 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
167 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
168 Editor_state
= edit
.initialize_test_state()
169 Editor_state
.lines
= load_array
{'```lines', '```', ''}
170 Text
.redraw_all(Editor_state
)
171 Editor_state
.current_drawing_mode
= 'line'
172 edit
.draw(Editor_state
)
173 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
174 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
175 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
176 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
177 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
179 App
.mouse_move(Editor_state
.left
+4, Editor_state
.top
+Drawing_padding_top
+4) -- hover on drawing
180 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
181 edit
.run_after_text_input(Editor_state
, 'o')
182 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35+30, Editor_state
.top
+Drawing_padding_top
+36, 1)
183 local drawing
= Editor_state
.lines
[1]
184 check_eq(#drawing
.shapes
, 1, '#shapes')
185 check_eq(#drawing
.points
, 1, '#points')
186 check_eq(drawing
.shapes
[1].mode
, 'circle', 'shape_mode')
187 check_eq(drawing
.shapes
[1].radius
, 30, 'radius')
188 local center
= drawing
.points
[drawing
.shapes
[1].center
]
189 check_eq(center
.x
, 35, 'center:x')
190 check_eq(center
.y
, 36, 'center:y')
193 function test_draw_arc()
194 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
195 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
196 Editor_state
= edit
.initialize_test_state()
197 Editor_state
.lines
= load_array
{'```lines', '```', ''}
198 Text
.redraw_all(Editor_state
)
199 Editor_state
.current_drawing_mode
= 'circle'
200 edit
.draw(Editor_state
)
201 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
202 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
203 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
204 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
205 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
207 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
208 App
.mouse_move(Editor_state
.left
+35+30, Editor_state
.top
+Drawing_padding_top
+36)
209 edit
.run_after_text_input(Editor_state
, 'a') -- arc mode
210 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35+50, Editor_state
.top
+Drawing_padding_top
+36+50, 1) -- 45°
211 local drawing
= Editor_state
.lines
[1]
212 check_eq(#drawing
.shapes
, 1, '#shapes')
213 check_eq(#drawing
.points
, 1, '#points')
214 check_eq(drawing
.shapes
[1].mode
, 'arc', 'shape_mode')
215 local arc
= drawing
.shapes
[1]
216 check_eq(arc
.radius
, 30, 'radius')
217 local center
= drawing
.points
[arc
.center
]
218 check_eq(center
.x
, 35, 'center:x')
219 check_eq(center
.y
, 36, 'center:y')
220 check_eq(arc
.start_angle
, 0, 'start:angle')
221 check_eq(arc
.end_angle
, math
.pi
/4, 'end:angle')
224 function test_draw_polygon()
225 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
226 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
227 Editor_state
= edit
.initialize_test_state()
228 Editor_state
.lines
= load_array
{'```lines', '```', ''}
229 Text
.redraw_all(Editor_state
)
230 edit
.draw(Editor_state
)
231 check_eq(Editor_state
.current_drawing_mode
, 'line', 'baseline/drawing_mode')
232 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
233 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
234 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
235 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
236 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
238 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
239 edit
.run_after_text_input(Editor_state
, 'g') -- polygon mode
241 App
.mouse_move(Editor_state
.left
+65, Editor_state
.top
+Drawing_padding_top
+36)
242 edit
.run_after_text_input(Editor_state
, 'p') -- add point
244 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+26, 1)
245 local drawing
= Editor_state
.lines
[1]
246 check_eq(#drawing
.shapes
, 1, '#shapes')
247 check_eq(#drawing
.points
, 3, 'vertices')
248 local shape
= drawing
.shapes
[1]
249 check_eq(shape
.mode
, 'polygon', 'shape_mode')
250 check_eq(#shape
.vertices
, 3, 'vertices')
251 local p
= drawing
.points
[shape
.vertices
[1]]
252 check_eq(p
.x
, 5, 'p1:x')
253 check_eq(p
.y
, 6, 'p1:y')
254 local p
= drawing
.points
[shape
.vertices
[2]]
255 check_eq(p
.x
, 65, 'p2:x')
256 check_eq(p
.y
, 36, 'p2:y')
257 local p
= drawing
.points
[shape
.vertices
[3]]
258 check_eq(p
.x
, 35, 'p3:x')
259 check_eq(p
.y
, 26, 'p3:y')
262 function test_draw_rectangle()
263 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
264 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
265 Editor_state
= edit
.initialize_test_state()
266 Editor_state
.lines
= load_array
{'```lines', '```', ''}
267 Text
.redraw_all(Editor_state
)
268 edit
.draw(Editor_state
)
269 check_eq(Editor_state
.current_drawing_mode
, 'line', 'baseline/drawing_mode')
270 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
271 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
272 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
273 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
274 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
276 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
277 edit
.run_after_text_input(Editor_state
, 'r') -- rectangle mode
278 -- second point/first edge
279 App
.mouse_move(Editor_state
.left
+42, Editor_state
.top
+Drawing_padding_top
+45)
280 edit
.run_after_text_input(Editor_state
, 'p')
281 -- override second point/first edge
282 App
.mouse_move(Editor_state
.left
+75, Editor_state
.top
+Drawing_padding_top
+76)
283 edit
.run_after_text_input(Editor_state
, 'p')
284 -- release (decides 'thickness' of rectangle perpendicular to first edge)
285 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+15, Editor_state
.top
+Drawing_padding_top
+26, 1)
286 local drawing
= Editor_state
.lines
[1]
287 check_eq(#drawing
.shapes
, 1, '#shapes')
288 check_eq(#drawing
.points
, 5, '#points') -- currently includes every point added
289 local shape
= drawing
.shapes
[1]
290 check_eq(shape
.mode
, 'rectangle', 'shape_mode')
291 check_eq(#shape
.vertices
, 4, 'vertices')
292 local p
= drawing
.points
[shape
.vertices
[1]]
293 check_eq(p
.x
, 35, 'p1:x')
294 check_eq(p
.y
, 36, 'p1:y')
295 local p
= drawing
.points
[shape
.vertices
[2]]
296 check_eq(p
.x
, 75, 'p2:x')
297 check_eq(p
.y
, 76, 'p2:y')
298 local p
= drawing
.points
[shape
.vertices
[3]]
299 check_eq(p
.x
, 70, 'p3:x')
300 check_eq(p
.y
, 81, 'p3:y')
301 local p
= drawing
.points
[shape
.vertices
[4]]
302 check_eq(p
.x
, 30, 'p4:x')
303 check_eq(p
.y
, 41, 'p4:y')
306 function test_draw_rectangle_intermediate()
307 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
308 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
309 Editor_state
= edit
.initialize_test_state()
310 Editor_state
.lines
= load_array
{'```lines', '```', ''}
311 Text
.redraw_all(Editor_state
)
312 edit
.draw(Editor_state
)
313 check_eq(Editor_state
.current_drawing_mode
, 'line', 'baseline/drawing_mode')
314 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
315 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
316 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
317 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
318 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
320 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
321 edit
.run_after_text_input(Editor_state
, 'r') -- rectangle mode
322 -- second point/first edge
323 App
.mouse_move(Editor_state
.left
+42, Editor_state
.top
+Drawing_padding_top
+45)
324 edit
.run_after_text_input(Editor_state
, 'p')
325 -- override second point/first edge
326 App
.mouse_move(Editor_state
.left
+75, Editor_state
.top
+Drawing_padding_top
+76)
327 edit
.run_after_text_input(Editor_state
, 'p')
328 local drawing
= Editor_state
.lines
[1]
329 check_eq(#drawing
.points
, 3, '#points') -- currently includes every point added
330 local pending
= drawing
.pending
331 check_eq(pending
.mode
, 'rectangle', 'shape_mode')
332 check_eq(#pending
.vertices
, 2, 'vertices')
333 local p
= drawing
.points
[pending
.vertices
[1]]
334 check_eq(p
.x
, 35, 'p1:x')
335 check_eq(p
.y
, 36, 'p1:y')
336 local p
= drawing
.points
[pending
.vertices
[2]]
337 check_eq(p
.x
, 75, 'p2:x')
338 check_eq(p
.y
, 76, 'p2:y')
339 -- outline of rectangle is drawn based on where the mouse is, but we can't check that so far
342 function test_draw_square()
343 -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
344 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
345 Editor_state
= edit
.initialize_test_state()
346 Editor_state
.lines
= load_array
{'```lines', '```', ''}
347 Text
.redraw_all(Editor_state
)
348 edit
.draw(Editor_state
)
349 check_eq(Editor_state
.current_drawing_mode
, 'line', 'baseline/drawing_mode')
350 check_eq(#Editor_state
.lines
, 2, 'baseline/#lines')
351 check_eq(Editor_state
.lines
[1].mode
, 'drawing', 'baseline/mode')
352 check_eq(Editor_state
.line_cache
[1].starty
, Editor_state
.top
+Drawing_padding_top
, 'baseline/y')
353 check_eq(Editor_state
.lines
[1].h
, 128, 'baseline/y')
354 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'baseline/#shapes')
356 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
357 edit
.run_after_text_input(Editor_state
, 's') -- square mode
358 -- second point/first edge
359 App
.mouse_move(Editor_state
.left
+42, Editor_state
.top
+Drawing_padding_top
+45)
360 edit
.run_after_text_input(Editor_state
, 'p')
361 -- override second point/first edge
362 App
.mouse_move(Editor_state
.left
+65, Editor_state
.top
+Drawing_padding_top
+66)
363 edit
.run_after_text_input(Editor_state
, 'p')
364 -- release (decides which side of first edge to draw square on)
365 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+15, Editor_state
.top
+Drawing_padding_top
+26, 1)
366 local drawing
= Editor_state
.lines
[1]
367 check_eq(#drawing
.shapes
, 1, '#shapes')
368 check_eq(#drawing
.points
, 5, '#points') -- currently includes every point added
369 check_eq(drawing
.shapes
[1].mode
, 'square', 'shape_mode')
370 check_eq(#drawing
.shapes
[1].vertices
, 4, 'vertices')
371 local p
= drawing
.points
[drawing
.shapes
[1].vertices
[1]]
372 check_eq(p
.x
, 35, 'p1:x')
373 check_eq(p
.y
, 36, 'p1:y')
374 local p
= drawing
.points
[drawing
.shapes
[1].vertices
[2]]
375 check_eq(p
.x
, 65, 'p2:x')
376 check_eq(p
.y
, 66, 'p2:y')
377 local p
= drawing
.points
[drawing
.shapes
[1].vertices
[3]]
378 check_eq(p
.x
, 35, 'p3:x')
379 check_eq(p
.y
, 96, 'p3:y')
380 local p
= drawing
.points
[drawing
.shapes
[1].vertices
[4]]
381 check_eq(p
.x
, 5, 'p4:x')
382 check_eq(p
.y
, 66, 'p4:y')
385 function test_name_point()
386 -- create a drawing with a line
387 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
388 Editor_state
= edit
.initialize_test_state()
389 Editor_state
.filename
= 'foo'
390 Editor_state
.lines
= load_array
{'```lines', '```', ''}
391 Text
.redraw_all(Editor_state
)
392 Editor_state
.current_drawing_mode
= 'line'
393 edit
.draw(Editor_state
)
395 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
396 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
397 local drawing
= Editor_state
.lines
[1]
398 check_eq(#drawing
.shapes
, 1, 'baseline/#shapes')
399 check_eq(#drawing
.points
, 2, 'baseline/#points')
400 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
401 local p1
= drawing
.points
[drawing
.shapes
[1].p1
]
402 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
403 check_eq(p1
.x
, 5, 'baseline/p1:x')
404 check_eq(p1
.y
, 6, 'baseline/p1:y')
405 check_eq(p2
.x
, 35, 'baseline/p2:x')
406 check_eq(p2
.y
, 36, 'baseline/p2:y')
407 check_nil(p2
.name
, 'baseline/p2:name')
408 -- enter 'name' mode without moving the mouse
409 edit
.run_after_keychord(Editor_state
, 'C-n')
410 check_eq(Editor_state
.current_drawing_mode
, 'name', 'mode:1')
411 edit
.run_after_text_input(Editor_state
, 'A')
412 check_eq(p2
.name
, 'A', 'check1')
413 -- still in 'name' mode
414 check_eq(Editor_state
.current_drawing_mode
, 'name', 'mode:2')
416 edit
.run_after_keychord(Editor_state
, 'return')
417 check_eq(Editor_state
.current_drawing_mode
, 'line', 'mode:3')
418 check_eq(p2
.name
, 'A', 'check2')
420 Current_time
= Current_time
+ 3.1
421 edit
.update(Editor_state
, 0)
423 load_from_disk(Editor_state
)
424 Text
.redraw_all(Editor_state
)
425 local p2
= Editor_state
.lines
[1].points
[drawing
.shapes
[1].p2
]
426 check_eq(p2
.name
, 'A', 'save')
429 function test_move_point()
430 -- create a drawing with a line
431 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
432 Editor_state
= edit
.initialize_test_state()
433 Editor_state
.filename
= 'foo'
434 Editor_state
.lines
= load_array
{'```lines', '```', ''}
435 Text
.redraw_all(Editor_state
)
436 Editor_state
.current_drawing_mode
= 'line'
437 edit
.draw(Editor_state
)
438 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
439 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
440 local drawing
= Editor_state
.lines
[1]
441 check_eq(#drawing
.shapes
, 1, 'baseline/#shapes')
442 check_eq(#drawing
.points
, 2, 'baseline/#points')
443 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
444 local p1
= drawing
.points
[drawing
.shapes
[1].p1
]
445 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
446 check_eq(p1
.x
, 5, 'baseline/p1:x')
447 check_eq(p1
.y
, 6, 'baseline/p1:y')
448 check_eq(p2
.x
, 35, 'baseline/p2:x')
449 check_eq(p2
.y
, 36, 'baseline/p2:y')
451 Current_time
= Current_time
+ 3.1
452 edit
.update(Editor_state
, 0)
453 -- line is saved to disk
454 load_from_disk(Editor_state
)
455 Text
.redraw_all(Editor_state
)
456 local drawing
= Editor_state
.lines
[1]
457 local p2
= Editor_state
.lines
[1].points
[drawing
.shapes
[1].p2
]
458 check_eq(p2
.x
, 35, 'save/x')
459 check_eq(p2
.y
, 36, 'save/y')
460 edit
.draw(Editor_state
)
461 -- enter 'move' mode without moving the mouse
462 edit
.run_after_keychord(Editor_state
, 'C-u')
463 check_eq(Editor_state
.current_drawing_mode
, 'move', 'mode:1')
465 check_eq(drawing
.pending
.mode
, 'move', 'mode:2')
466 check_eq(drawing
.pending
.target_point
, p2
, 'target')
468 App
.mouse_move(Editor_state
.left
+26, Editor_state
.top
+Drawing_padding_top
+44)
469 edit
.update(Editor_state
, 0.05)
470 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
471 check_eq(p2
.x
, 26, 'x')
472 check_eq(p2
.y
, 44, 'y')
474 edit
.run_after_mouse_click(Editor_state
, Editor_state
.left
+26, Editor_state
.top
+Drawing_padding_top
+44, 1)
475 check_eq(Editor_state
.current_drawing_mode
, 'line', 'mode:3')
476 check_eq(drawing
.pending
, {}, 'pending')
478 Current_time
= Current_time
+ 3.1
479 edit
.update(Editor_state
, 0)
481 load_from_disk(Editor_state
)
482 Text
.redraw_all(Editor_state
)
483 local p2
= Editor_state
.lines
[1].points
[drawing
.shapes
[1].p2
]
484 check_eq(p2
.x
, 26, 'save/x')
485 check_eq(p2
.y
, 44, 'save/y')
488 function test_move_point_on_manhattan_line()
489 -- create a drawing with a manhattan line
490 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
491 Editor_state
= edit
.initialize_test_state()
492 Editor_state
.filename
= 'foo'
493 Editor_state
.lines
= load_array
{'```lines', '```', ''}
494 Text
.redraw_all(Editor_state
)
495 Editor_state
.current_drawing_mode
= 'manhattan'
496 edit
.draw(Editor_state
)
497 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
498 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+46, 1)
499 local drawing
= Editor_state
.lines
[1]
500 check_eq(#drawing
.shapes
, 1, 'baseline/#shapes')
501 check_eq(#drawing
.points
, 2, 'baseline/#points')
502 check_eq(drawing
.shapes
[1].mode
, 'manhattan', 'baseline/shape:1')
503 edit
.draw(Editor_state
)
505 edit
.run_after_keychord(Editor_state
, 'C-u')
506 check_eq(Editor_state
.current_drawing_mode
, 'move', 'mode:1')
508 App
.mouse_move(Editor_state
.left
+26, Editor_state
.top
+Drawing_padding_top
+44)
509 edit
.update(Editor_state
, 0.05)
510 -- line is no longer manhattan
511 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
514 function test_delete_lines_at_point()
515 -- create a drawing with two lines connected at a point
516 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
517 Editor_state
= edit
.initialize_test_state()
518 Editor_state
.filename
= 'foo'
519 Editor_state
.lines
= load_array
{'```lines', '```', ''}
520 Text
.redraw_all(Editor_state
)
521 Editor_state
.current_drawing_mode
= 'line'
522 edit
.draw(Editor_state
)
523 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
524 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
525 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
526 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+55, Editor_state
.top
+Drawing_padding_top
+26, 1)
527 local drawing
= Editor_state
.lines
[1]
528 check_eq(#drawing
.shapes
, 2, 'baseline/#shapes')
529 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
530 check_eq(drawing
.shapes
[2].mode
, 'line', 'baseline/shape:2')
531 -- hover on the common point and delete
532 App
.mouse_move(Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36)
533 edit
.run_after_keychord(Editor_state
, 'C-d')
534 check_eq(drawing
.shapes
[1].mode
, 'deleted', 'shape:1')
535 check_eq(drawing
.shapes
[2].mode
, 'deleted', 'shape:2')
536 -- wait for some time
537 Current_time
= Current_time
+ 3.1
538 edit
.update(Editor_state
, 0)
539 -- deleted points disappear after file is reloaded
540 load_from_disk(Editor_state
)
541 Text
.redraw_all(Editor_state
)
542 check_eq(#Editor_state
.lines
[1].shapes
, 0, 'save')
545 function test_delete_line_under_mouse_pointer()
546 -- create a drawing with two lines connected at a point
547 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
548 Editor_state
= edit
.initialize_test_state()
549 Editor_state
.lines
= load_array
{'```lines', '```', ''}
550 Text
.redraw_all(Editor_state
)
551 Editor_state
.current_drawing_mode
= 'line'
552 edit
.draw(Editor_state
)
553 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
554 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
555 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
556 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+55, Editor_state
.top
+Drawing_padding_top
+26, 1)
557 local drawing
= Editor_state
.lines
[1]
558 check_eq(#drawing
.shapes
, 2, 'baseline/#shapes')
559 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
560 check_eq(drawing
.shapes
[2].mode
, 'line', 'baseline/shape:2')
561 -- hover on one of the lines and delete
562 App
.mouse_move(Editor_state
.left
+25, Editor_state
.top
+Drawing_padding_top
+26)
563 edit
.run_after_keychord(Editor_state
, 'C-d')
564 -- only that line is deleted
565 check_eq(drawing
.shapes
[1].mode
, 'deleted', 'shape:1')
566 check_eq(drawing
.shapes
[2].mode
, 'line', 'shape:2')
569 function test_delete_point_from_polygon()
570 -- create a drawing with two lines connected at a point
571 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
572 Editor_state
= edit
.initialize_test_state()
573 Editor_state
.lines
= load_array
{'```lines', '```', ''}
574 Text
.redraw_all(Editor_state
)
575 Editor_state
.current_drawing_mode
= 'line'
576 edit
.draw(Editor_state
)
578 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
579 edit
.run_after_text_input(Editor_state
, 'g') -- polygon mode
581 App
.mouse_move(Editor_state
.left
+65, Editor_state
.top
+Drawing_padding_top
+36)
582 edit
.run_after_text_input(Editor_state
, 'p') -- add point
584 App
.mouse_move(Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+26)
585 edit
.run_after_text_input(Editor_state
, 'p') -- add point
587 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+14, Editor_state
.top
+Drawing_padding_top
+16, 1)
588 local drawing
= Editor_state
.lines
[1]
589 check_eq(#drawing
.shapes
, 1, 'baseline/#shapes')
590 check_eq(drawing
.shapes
[1].mode
, 'polygon', 'baseline/mode')
591 check_eq(#drawing
.shapes
[1].vertices
, 4, 'baseline/vertices')
592 -- hover on a point and delete
593 App
.mouse_move(Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+26)
594 edit
.run_after_keychord(Editor_state
, 'C-d')
595 -- just the one point is deleted
596 check_eq(drawing
.shapes
[1].mode
, 'polygon', 'shape')
597 check_eq(#drawing
.shapes
[1].vertices
, 3, 'vertices')
600 function test_delete_point_from_polygon()
601 -- create a drawing with two lines connected at a point
602 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
603 Editor_state
= edit
.initialize_test_state()
604 Editor_state
.lines
= load_array
{'```lines', '```', ''}
605 Text
.redraw_all(Editor_state
)
606 Editor_state
.current_drawing_mode
= 'line'
607 edit
.draw(Editor_state
)
609 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
610 edit
.run_after_text_input(Editor_state
, 'g') -- polygon mode
612 App
.mouse_move(Editor_state
.left
+65, Editor_state
.top
+Drawing_padding_top
+36)
613 edit
.run_after_text_input(Editor_state
, 'p') -- add point
615 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+14, Editor_state
.top
+Drawing_padding_top
+16, 1)
616 local drawing
= Editor_state
.lines
[1]
617 check_eq(#drawing
.shapes
, 1, 'baseline/#shapes')
618 check_eq(drawing
.shapes
[1].mode
, 'polygon', 'baseline/mode')
619 check_eq(#drawing
.shapes
[1].vertices
, 3, 'baseline/vertices')
620 -- hover on a point and delete
621 App
.mouse_move(Editor_state
.left
+65, Editor_state
.top
+Drawing_padding_top
+36)
622 edit
.run_after_keychord(Editor_state
, 'C-d')
623 -- there's < 3 points left, so the whole polygon is deleted
624 check_eq(drawing
.shapes
[1].mode
, 'deleted', 'check')
627 function test_undo_name_point()
628 -- create a drawing with a line
629 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
630 Editor_state
= edit
.initialize_test_state()
631 Editor_state
.filename
= 'foo'
632 Editor_state
.lines
= load_array
{'```lines', '```', ''}
633 Text
.redraw_all(Editor_state
)
634 Editor_state
.current_drawing_mode
= 'line'
635 edit
.draw(Editor_state
)
637 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
638 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
639 local drawing
= Editor_state
.lines
[1]
640 check_eq(#drawing
.shapes
, 1, 'baseline/#shapes')
641 check_eq(#drawing
.points
, 2, 'baseline/#points')
642 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
643 local p1
= drawing
.points
[drawing
.shapes
[1].p1
]
644 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
645 check_eq(p1
.x
, 5, 'baseline/p1:x')
646 check_eq(p1
.y
, 6, 'baseline/p1:y')
647 check_eq(p2
.x
, 35, 'baseline/p2:x')
648 check_eq(p2
.y
, 36, 'baseline/p2:y')
649 check_nil(p2
.name
, 'baseline/p2:name')
650 check_eq(#Editor_state
.history
, 1, 'baseline/history:1')
651 --? print('a', Editor_state.lines.current_drawing)
652 -- enter 'name' mode without moving the mouse
653 edit
.run_after_keychord(Editor_state
, 'C-n')
654 edit
.run_after_text_input(Editor_state
, 'A')
655 edit
.run_after_keychord(Editor_state
, 'return')
656 check_eq(p2
.name
, 'A', 'baseline')
657 check_eq(#Editor_state
.history
, 3, 'baseline/history:2')
658 check_eq(Editor_state
.next_history
, 4, 'baseline/next_history')
659 --? print('b', Editor_state.lines.current_drawing)
661 edit
.run_after_keychord(Editor_state
, 'C-z')
662 local drawing
= Editor_state
.lines
[1]
663 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
664 check_eq(Editor_state
.next_history
, 3, 'next_history')
665 check_eq(p2
.name
, '', 'undo') -- not quite what it was before, but close enough
667 Current_time
= Current_time
+ 3.1
668 edit
.update(Editor_state
, 0)
670 load_from_disk(Editor_state
)
671 Text
.redraw_all(Editor_state
)
672 local p2
= Editor_state
.lines
[1].points
[drawing
.shapes
[1].p2
]
673 check_eq(p2
.name
, '', 'save')
676 function test_undo_move_point()
677 -- create a drawing with a line
678 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
679 Editor_state
= edit
.initialize_test_state()
680 Editor_state
.filename
= 'foo'
681 Editor_state
.lines
= load_array
{'```lines', '```', ''}
682 Text
.redraw_all(Editor_state
)
683 Editor_state
.current_drawing_mode
= 'line'
684 edit
.draw(Editor_state
)
685 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
686 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
687 local drawing
= Editor_state
.lines
[1]
688 check_eq(#drawing
.shapes
, 1, 'baseline/#shapes')
689 check_eq(#drawing
.points
, 2, 'baseline/#points')
690 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
691 local p1
= drawing
.points
[drawing
.shapes
[1].p1
]
692 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
693 check_eq(p1
.x
, 5, 'baseline/p1:x')
694 check_eq(p1
.y
, 6, 'baseline/p1:y')
695 check_eq(p2
.x
, 35, 'baseline/p2:x')
696 check_eq(p2
.y
, 36, 'baseline/p2:y')
697 check_nil(p2
.name
, 'baseline/p2:name')
699 edit
.run_after_keychord(Editor_state
, 'C-u')
700 App
.mouse_move(Editor_state
.left
+26, Editor_state
.top
+Drawing_padding_top
+44)
701 edit
.update(Editor_state
, 0.05)
702 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
703 check_eq(p2
.x
, 26, 'x')
704 check_eq(p2
.y
, 44, 'y')
706 edit
.run_after_mouse_click(Editor_state
, Editor_state
.left
+26, Editor_state
.top
+Drawing_padding_top
+44, 1)
707 check_eq(Editor_state
.next_history
, 4, 'next_history')
709 edit
.run_after_keychord(Editor_state
, 'C-z')
710 edit
.run_after_keychord(Editor_state
, 'C-z') -- bug: need to undo twice
711 local drawing
= Editor_state
.lines
[1]
712 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
713 check_eq(Editor_state
.next_history
, 2, 'next_history')
714 check_eq(p2
.x
, 35, 'x')
715 check_eq(p2
.y
, 36, 'y')
717 Current_time
= Current_time
+ 3.1
718 edit
.update(Editor_state
, 0)
720 load_from_disk(Editor_state
)
721 Text
.redraw_all(Editor_state
)
722 local p2
= Editor_state
.lines
[1].points
[drawing
.shapes
[1].p2
]
723 check_eq(p2
.x
, 35, 'save/x')
724 check_eq(p2
.y
, 36, 'save/y')
727 function test_undo_delete_point()
728 -- create a drawing with two lines connected at a point
729 App
.screen
.init
{width
=Test_margin_left
+256, height
=300} -- drawing coordinates 1:1 with pixels
730 Editor_state
= edit
.initialize_test_state()
731 Editor_state
.filename
= 'foo'
732 Editor_state
.lines
= load_array
{'```lines', '```', ''}
733 Text
.redraw_all(Editor_state
)
734 Editor_state
.current_drawing_mode
= 'line'
735 edit
.draw(Editor_state
)
736 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+5, Editor_state
.top
+Drawing_padding_top
+6, 1)
737 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
738 edit
.run_after_mouse_press(Editor_state
, Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36, 1)
739 edit
.run_after_mouse_release(Editor_state
, Editor_state
.left
+55, Editor_state
.top
+Drawing_padding_top
+26, 1)
740 local drawing
= Editor_state
.lines
[1]
741 check_eq(#drawing
.shapes
, 2, 'baseline/#shapes')
742 check_eq(drawing
.shapes
[1].mode
, 'line', 'baseline/shape:1')
743 check_eq(drawing
.shapes
[2].mode
, 'line', 'baseline/shape:2')
744 -- hover on the common point and delete
745 App
.mouse_move(Editor_state
.left
+35, Editor_state
.top
+Drawing_padding_top
+36)
746 edit
.run_after_keychord(Editor_state
, 'C-d')
747 check_eq(drawing
.shapes
[1].mode
, 'deleted', 'shape:1')
748 check_eq(drawing
.shapes
[2].mode
, 'deleted', 'shape:2')
750 edit
.run_after_keychord(Editor_state
, 'C-z')
751 local drawing
= Editor_state
.lines
[1]
752 local p2
= drawing
.points
[drawing
.shapes
[1].p2
]
753 check_eq(Editor_state
.next_history
, 3, 'next_history')
754 check_eq(drawing
.shapes
[1].mode
, 'line', 'shape:1')
755 check_eq(drawing
.shapes
[2].mode
, 'line', 'shape:2')
757 Current_time
= Current_time
+ 3.1
758 edit
.update(Editor_state
, 0)
760 load_from_disk(Editor_state
)
761 Text
.redraw_all(Editor_state
)
762 check_eq(#Editor_state
.lines
[1].shapes
, 2, 'save')