much love
[mu.git] / 504test-screen.mu
blobf6bdae3b494d34498c6522e6e4f849e28674c62a
1 # Some primitives for checking the state of fake screen objects.
3 # validate data on screen regardless of attributes (color, bold, etc.)
4 # Mu doesn't have multi-line strings, so we provide functions for rows or portions of rows.
5 # Tab characters (that translate into multiple screen cells) not supported.
7 fn check-screen-row screen: (addr screen), y: int, expected: (addr array byte), msg: (addr array byte) {
8   check-screen-row-from screen, 0/x, y, expected, msg
11 fn check-screen-row-from _screen: (addr screen), x: int, y: int, expected: (addr array byte), msg: (addr array byte) {
12   var screen/esi: (addr screen) <- copy _screen
13   var failure-count/edi: int <- copy 0
14   var index/ecx: int <- screen-cell-index screen, x, y
15   # compare 'expected' with the screen contents starting at 'index', code-point-utf8 by code-point-utf8
16   var e: (stream byte 0x100)
17   var e-addr/edx: (addr stream byte) <- address e
18   write e-addr, expected
19   {
20     var done?/eax: boolean <- stream-empty? e-addr
21     compare done?, 0
22     break-if-!=
23     {
24       var unused?/eax: boolean <- screen-cell-unused-at-index? screen, index
25       compare unused?, 0/false
26       break-if-!=
27       var _c/eax: code-point <- screen-code-point-at-index screen, index
28       var c/ebx: code-point <- copy _c
29       var expected-code-point-utf8/eax: code-point-utf8 <- read-code-point-utf8 e-addr
30       var expected-code-point/eax: code-point <- to-code-point expected-code-point-utf8
31       # compare code-point-utf8s
32       $check-screen-row-from:compare-code-point-utf8s: {
33         # if expected-code-point is space, null code-point-utf8 is also ok
34         {
35           compare expected-code-point, 0x20
36           break-if-!=
37           compare c, 0
38           break-if-= $check-screen-row-from:compare-code-point-utf8s
39         }
40         # if (c == expected-code-point) print "."
41         compare c, expected-code-point
42         break-if-=
43         # otherwise print an error
44         failure-count <- increment
45         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg=cyan, 0/bg
46         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg=cyan, 0/bg
47         draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg
48         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg=cyan, 0/bg
49         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg=cyan, 0/bg
50         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg=cyan, 0/bg
51         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg=cyan, 0/bg
52         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg=cyan, 0/bg
53         draw-code-point-at-cursor-over-full-screen 0/screen, c, 3/cyan, 0/bg
54         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg=cyan, 0/bg
55         move-cursor-to-left-margin-of-next-line 0/screen
56       }
57     }
58     index <- increment
59     increment x
60     loop
61   }
62   # if any assertions failed, count the test as failed
63   compare failure-count, 0
64   {
65     break-if-=
66     count-test-failure
67     return
68   }
69   # otherwise print a "."
70   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
73 # various variants by screen-cell attribute; spaces in the 'expected' data should not match the attribute
75 fn check-screen-row-in-color screen: (addr screen), fg: int, y: int, expected: (addr array byte), msg: (addr array byte) {
76   check-screen-row-in-color-from screen, fg, y, 0/x, expected, msg
79 fn check-screen-row-in-color-from _screen: (addr screen), fg: int, y: int, x: int, expected: (addr array byte), msg: (addr array byte) {
80   var screen/esi: (addr screen) <- copy _screen
81   var index/ecx: int <- screen-cell-index screen, x, y
82   # compare 'expected' with the screen contents starting at 'index', code-point-utf8 by code-point-utf8
83   var e: (stream byte 0x100)
84   var e-addr/edx: (addr stream byte) <- address e
85   write e-addr, expected
86   {
87     var done?/eax: boolean <- stream-empty? e-addr
88     compare done?, 0
89     break-if-!=
90     {
91       var unused?/eax: boolean <- screen-cell-unused-at-index? screen, index
92       compare unused?, 0/false
93       break-if-!=
94       var _c/eax: code-point <- screen-code-point-at-index screen, index
95       var c/ebx: code-point <- copy _c
96       var expected-code-point-utf8/eax: code-point-utf8 <- read-code-point-utf8 e-addr
97       var _expected-code-point/eax: code-point <- to-code-point expected-code-point-utf8
98       var expected-code-point/edi: code-point <- copy _expected-code-point
99       $check-screen-row-in-color-from:compare-cells: {
100         # if expected-code-point is space, null code-point-utf8 is also ok
101         {
102           compare expected-code-point, 0x20
103           break-if-!=
104           compare c, 0
105           break-if-= $check-screen-row-in-color-from:compare-cells
106         }
107         # if expected-code-point is space, a different color is ok
108         {
109           compare expected-code-point, 0x20
110           break-if-!=
111           var color/eax: int <- screen-color-at-index screen, index
112           compare color, fg
113           break-if-!= $check-screen-row-in-color-from:compare-cells
114         }
115         # compare code-point-utf8s
116         $check-screen-row-in-color-from:compare-code-point-utf8s: {
117           # if (c == expected-code-point) print "."
118           compare c, expected-code-point
119           {
120             break-if-!=
121             draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
122             break $check-screen-row-in-color-from:compare-code-point-utf8s
123           }
124           # otherwise print an error
125           count-test-failure
126           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg=cyan, 0/bg
127           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg=cyan, 0/bg
128           draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg
129           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg=cyan, 0/bg
130           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg=cyan, 0/bg
131           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg=cyan, 0/bg
132           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg=cyan, 0/bg
133           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg=cyan, 0/bg
134           draw-code-point-at-cursor-over-full-screen 0/screen, c, 3/cyan, 0/bg
135           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg=cyan, 0/bg
136           move-cursor-to-left-margin-of-next-line 0/screen
137         }
138         $check-screen-row-in-color-from:compare-colors: {
139           var color/eax: int <- screen-color-at-index screen, index
140           compare fg, color
141           {
142             break-if-!=
143             draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
144             break $check-screen-row-in-color-from:compare-colors
145           }
146           # otherwise print an error
147           count-test-failure
148           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg=cyan, 0/bg
149           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg=cyan, 0/bg
150           draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg
151           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg=cyan, 0/bg
152           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg=cyan, 0/bg
153           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg=cyan, 0/bg
154           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg=cyan, 0/bg
155           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in color ", 3/fg=cyan, 0/bg
156           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, fg, 3/fg=cyan, 0/bg
157           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed color ", 3/fg=cyan, 0/bg
158           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, color, 3/fg=cyan, 0/bg
159           move-cursor-to-left-margin-of-next-line 0/screen
160         }
161       }
162     }
163     index <- increment
164     increment x
165     loop
166   }
169 fn check-screen-row-in-background-color screen: (addr screen), bg: int, y: int, expected: (addr array byte), msg: (addr array byte) {
170   check-screen-row-in-background-color-from screen, bg, y, 0/x, expected, msg
173 fn check-screen-row-in-background-color-from _screen: (addr screen), bg: int, y: int, x: int, expected: (addr array byte), msg: (addr array byte) {
174   var screen/esi: (addr screen) <- copy _screen
175   var index/ecx: int <- screen-cell-index screen, x, y
176   # compare 'expected' with the screen contents starting at 'index', code-point-utf8 by code-point-utf8
177   var e: (stream byte 0x100)
178   var e-addr/edx: (addr stream byte) <- address e
179   write e-addr, expected
180   {
181     var done?/eax: boolean <- stream-empty? e-addr
182     compare done?, 0
183     break-if-!=
184     {
185       var unused?/eax: boolean <- screen-cell-unused-at-index? screen, index
186       compare unused?, 0/false
187       break-if-!=
188       var _g/eax: code-point <- screen-code-point-at-index screen, index
189       var g/ebx: code-point <- copy _g
190       var expected-code-point-utf8/eax: code-point-utf8 <- read-code-point-utf8 e-addr
191       var _expected-code-point/eax: code-point <- to-code-point expected-code-point-utf8
192       var expected-code-point/edi: code-point <- copy _expected-code-point
193       $check-screen-row-in-background-color-from:compare-cells: {
194         # if expected-code-point is space, null code-point-utf8 is also ok
195         {
196           compare expected-code-point, 0x20
197           break-if-!=
198           compare g, 0
199           break-if-= $check-screen-row-in-background-color-from:compare-cells
200         }
201         # if expected-code-point is space, a different background-color is ok
202         {
203           compare expected-code-point, 0x20
204           break-if-!=
205           var background-color/eax: int <- screen-background-color-at-index screen, index
206           compare background-color, bg
207           break-if-!= $check-screen-row-in-background-color-from:compare-cells
208         }
209         # compare code-point-utf8s
210         $check-screen-row-in-background-color-from:compare-code-point-utf8s: {
211           # if (g == expected-code-point) print "."
212           compare g, expected-code-point
213           {
214             break-if-!=
215             draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
216             break $check-screen-row-in-background-color-from:compare-code-point-utf8s
217           }
218           # otherwise print an error
219           count-test-failure
220           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg=cyan, 0/bg
221           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg=cyan, 0/bg
222           draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg
223           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg=cyan, 0/bg
224           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg=cyan, 0/bg
225           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg=cyan, 0/bg
226           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg=cyan, 0/bg
227           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg=cyan, 0/bg
228           draw-code-point-at-cursor-over-full-screen 0/screen, g, 3/cyan, 0/bg
229           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg=cyan, 0/bg
230           move-cursor-to-left-margin-of-next-line 0/screen
231           break $check-screen-row-in-background-color-from:compare-code-point-utf8s
232         }
233         $check-screen-row-in-background-color-from:compare-background-colors: {
234           var background-color/eax: int <- screen-background-color-at-index screen, index
235           compare bg, background-color
236           {
237             break-if-!=
238             draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
239             break $check-screen-row-in-background-color-from:compare-background-colors
240           }
241           # otherwise print an error
242           count-test-failure
243           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg=cyan, 0/bg
244           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg=cyan, 0/bg
245           draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg
246           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg=cyan, 0/bg
247           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg=cyan, 0/bg
248           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg=cyan, 0/bg
249           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg=cyan, 0/bg
250           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in background-color ", 3/fg=cyan, 0/bg
251           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg=cyan, 0/bg
252           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed background-color ", 3/fg=cyan, 0/bg
253           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, background-color, 3/fg=cyan, 0/bg
254           move-cursor-to-left-margin-of-next-line 0/screen
255         }
256       }
257     }
258     index <- increment
259     increment x
260     loop
261   }
264 # helpers for checking just background color, not screen contents
265 # these can validate bg for spaces
267 fn check-background-color-in-screen-row screen: (addr screen), bg: int, y: int, expected-bitmap: (addr array byte), msg: (addr array byte) {
268   check-background-color-in-screen-row-from screen, bg, y, 0/x, expected-bitmap, msg
271 fn check-background-color-in-screen-row-from _screen: (addr screen), bg: int, y: int, x: int, expected-bitmap: (addr array byte), msg: (addr array byte) {
272   var screen/esi: (addr screen) <- copy _screen
273   var failure-count: int
274   var index/ecx: int <- screen-cell-index screen, x, y
275   # compare background color where 'expected-bitmap' is a non-space
276   var e: (stream byte 0x100)
277   var e-addr/edx: (addr stream byte) <- address e
278   write e-addr, expected-bitmap
279   {
280     var done?/eax: boolean <- stream-empty? e-addr
281     compare done?, 0
282     break-if-!=
283     {
284       var unused?/eax: boolean <- screen-cell-unused-at-index? screen, index
285       compare unused?, 0/false
286       break-if-!=
287       var _expected-bit/eax: code-point-utf8 <- read-code-point-utf8 e-addr
288       var expected-bit/edi: code-point-utf8 <- copy _expected-bit
289       $check-background-color-in-screen-row-from:compare-cells: {
290         var background-color/eax: int <- screen-background-color-at-index screen, index
291         # if expected-bit is space, assert that background is NOT bg
292         compare expected-bit, 0x20
293         {
294           break-if-!=
295           compare background-color, bg
296           break-if-!= $check-background-color-in-screen-row-from:compare-cells
297           increment failure-count
298           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg=cyan, 0/bg
299           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected (", 3/fg=cyan, 0/bg
300           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg=cyan, 0/bg
301           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg=cyan, 0/bg
302           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg=cyan, 0/bg
303           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") to not be in background-color ", 3/fg=cyan, 0/bg
304           draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg=cyan, 0/bg
305           move-cursor-to-left-margin-of-next-line 0/screen
306           break $check-background-color-in-screen-row-from:compare-cells
307         }
308         # otherwise assert that background IS bg
309         compare background-color, bg
310         break-if-= $check-background-color-in-screen-row-from:compare-cells
311         increment failure-count
312         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg=cyan, 0/bg
313         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected (", 3/fg=cyan, 0/bg
314         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg=cyan, 0/bg
315         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg=cyan, 0/bg
316         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg=cyan, 0/bg
317         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in background-color ", 3/fg=cyan, 0/bg
318         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg=cyan, 0/bg
319         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed background-color ", 3/fg=cyan, 0/bg
320         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, background-color, 3/fg=cyan, 0/bg
321         move-cursor-to-left-margin-of-next-line 0/screen
322       }
323     }
324     index <- increment
325     increment x
326     loop
327   }
328   # if any assertions failed, count the test as failed
329   compare failure-count, 0
330   {
331     break-if-=
332     count-test-failure
333     return
334   }
335   # otherwise print a "."
336   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
339 fn test-draw-single-code-point-utf8 {
340   var _screen: screen
341   var screen/esi: (addr screen) <- address _screen
342   initialize-screen screen, 5, 4, 0/no-pixel-graphics
343   var dummy/eax: int <- draw-code-point screen, 0x61/a, 0/x, 0/y, 1/fg, 2/bg
344   check-screen-row screen, 0/y, "a", "F - test-draw-single-code-point-utf8"  # top-left corner of the screen
345   check-screen-row-in-color screen, 1/fg, 0/y, "a", "F - test-draw-single-code-point-utf8-fg"
346   check-screen-row-in-background-color screen, 2/bg, 0/y, "a", "F - test-draw-single-code-point-utf8-bg"
347   check-background-color-in-screen-row screen, 2/bg, 0/y, "x ", "F - test-draw-single-code-point-utf8-bg2"
350 fn test-draw-multiple-code-point-utf8s {
351   var _screen: screen
352   var screen/esi: (addr screen) <- address _screen
353   initialize-screen screen, 0x10/rows, 4/cols, 0/no-pixel-graphics
354   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "Hello, 世界", 1/fg, 2/bg
355   check-screen-row screen, 0/y, "Hello, 世界", "F - test-draw-multiple-code-point-utf8s"
356   check-screen-row-in-color screen, 1/fg, 0/y, "Hello, 世界", "F - test-draw-multiple-code-point-utf8s-fg"
357   check-background-color-in-screen-row screen, 2/bg, 0/y, "xxxxxxxxx ", "F - test-draw-multiple-code-point-utf8s-bg2"