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