3SMSYTKNRPZXV5TFOVAKW7FUPPPDSTG6BWVT3ZAXB23YCH36MXCAC ZMRMC3O6RXECMBAPOOKUSYDJ3K6CQVRFHFE2BID4BUBOL3YB6MGAC A4BSGS2CX4JK7IELL655EC6HAY6ILCWTGIHWZXHRGQOKU3HSUPLAC R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC LXTTOB33N2HCUZFIUDRQGGBVHK2HODRG4NBLH6RXRQZDCHF27BSAC 3VHUIIATPOF7FXB7NTL5MESCV5BCQACII2D7QZ4UIUCBX3CWXMMAC AMOPICKVRHMQERJLFPMAAEBV7TL5QACGGSBJWRCMV5R5O3KDVETAC ORRSP7FVCHI2TF5GXBRGQYYJAA3JFYXZBM3T663BKSBV22FCZVCAC MSOQI3A5BC5PY2MZXZQAQ4EQDT4KICQJPN3YUZVDYTWXSPZWBLIAC LLAOOMULEBXFMIGRBY6LRVEK4RXQGPNTFVWMCZNUEJZHWC7UGUEAC FZBXBUFFNRE5ZJO5DLRU375HOXT2B7FO35XD7BTHHUXSARVWDFLQC S2YQBEYCOBS4ADO5VX4YLAWY6CJEQOOZM3THYTDOTXM7ADID6PGQC 2CK5QI7WA7M4IVSACFGOJYAIDKRUTZVMMPSFWEJTUNMWTN7AX4NAC LF7BWEG4DKQI7NMXMZC4LC2BE5PB42HK5PD6OYBNIDMAZBJASOKQC ORKN6EOBUFVAD2TXYW5OIKSL55RU24LOFDTTTXHDZUZ57QRDCY7QC UHB4GARJI5AB5UCDCZRFSCJNXGJSLU5DYGUGX5ITYEXI7Q43Z4CAC APYPFFS3G6TDEUMIHQGMDBJNRNDTCNTPKI5M2AFACJ73P725XQRQC DSLD74DK3P6J2VAFCYF5BGTHZ637QTW3PDHOUHFACDZU66YNM3IAC HTWAM4NZFOY463TNSKYIM2EWB7QNBGDRRTTGHF5N3Z4TGC7Q3SFAC NZKYPBSKYJ7NQU7ABRHLYZ2P2P5V2UF76OLRURGTGRUB54R4SPBQC QKAMUWSB6GWKEGLXFKALGCIU7HBTZ4YGLIR7TLA6ZZCUK7WNCNUQC Y4SPXCM3PKARGUU22FNBEDRU7S6CJSNYVAA76JYH4I4EMMMKP6LQC CVSRHMJ2BM4LPVG67ULIVQMP2NW3YY2JC2ZQBEA6EB5KVM4O2L5AC T3B4NLV33PBD2L3YL3MHSOXZUWHDOGHPWLKKKHEBKJFSHYQWUK3AC RMKMPFT5L67WIFWIO4GTC6XESX6UPKNL4GPNQLOBC5CXSUZABEHQC JFFUF5ALUWPDM7IEDEZVAYG2SVXO334STONRGKVB3QKY2TT5QGBQC WAR3HXHTN7JZVV6TFMU2F3QYAG6NDH7DN7KKPTM2ICEHRNQYP6PAC CUIV2LE5D6GUQ4NU7K2TGUVO5CTUXVJDRCZUIV47LXTOUSEPEJHQC 4J2L6JMR7NZBGCNX63CL2E3AIB7P7QTCC7QQBPNAEPQ7ISQXL7EQC KMRJOSLYYHHPGMYXBSLUQTICP6F4LXRCGYSP55YTZQSX4SZISDEAC VG75U7IM2ZQTGM2QETDT6QQ4CSLQPB4APK436POAAQJWOMINPIJAC 4WAFGF4ZMUQOLBWRZ2SI6RWEBKMFNFZQJMPECT25C2VPYHNDK2JQC CIQN2MDEMWAASJAHOHMUZTI5PF4JV5SZSOBYYDCIIFYO2VHWULKAC 7EQLPB3O4DPUWGILY4P5D32SSIKL63QWWU5XRL2HISGNJXFWD2SAC FYS7TCDWKNRNOJSGRD2JMU4B2LHX5S63ZISM7YF7KZYEYLVCIKIAC DFGPHG5TJUE5Z5UT72Q5DWRMUG6TR3FHWNSKCQISZC4DZXCA36WQC IWYLK45KJSPRXKW55OD4GEPMLTYMMTXNFJJU26JTZN3RE35DWSCQC EMHRPJ3RAVIVJEQIRXIVDGENV6QHUUGXXRWTJ3BXC7SZNC66VK5QC 4VKEE43Z7MUPNIAOCK36INVBNHRTSWRRN37TIKRPXPH3DRKGHHAQC GJLOKCYKETWXJXBOS5222HVZIKBDOGLLR5QLUZYCTZG7FBYDTQMQC MYC7XR5QOT2AXHF6UNGSNFFD5VL6UHGUZQBP7PWWLZ5NNXE7UMTAC DGK5BPVI6PAD3WK2ZB2ITMBE6WYSU3ZR7TV7RTCQ2WJQ4RGJE5RQC EKKFWP4D2MNOHU265UCJU37KIFQV424CRLVASQMHDYUYY5T67D3QC H3ECRBXFBASVUPMZYM5APUK6AR3UF2O6I7BF7KQPV3YHBNT6YZWQC Y2ZIPXEMMCY5GHJDDF7OMRKEQYMSDR5QTJDA7Y2SBOTHAJKHWVOAC 5BMR5HRT7GN5L4XB4ISP4JJP3ONZESHEEQBCTQE4EVEDL7MBSDGAC P6SYWBLBN2KAYQ6VJBPYZQNCD2WQHOZGC6XOKWW4SLAMFFGH3ZYQC NUZFHX6IUV2KXZOIJQTD5VIU7ELDQCFPDXYBUNQGWLKH3OMYND5QC V3EABA35RWCOOU5OMIYRWXAKZOLHO4XPGTPOKY24RR2LOAD7ZQAQC 2LC3BM2NCIR76UILI5D4DVC5KYJSBVHDNMOC5G3TOJNCRLX6PZEQC KOTI3MFGQ4PDS4I75JIJG734LTET6745VGTSMNFYYASVIO6H2KPAC AJP4OSTJSREBMJ5FOAHMOF6D4LKMKMRHU5NUURDLVCB4ADPX66TAC 62JEPVQ34SOTQI6VQNLGLKS5O4KFU52UKAVDHN6N7G5T6Z5EZO5QC LNUHQOGHIOFGJXNGA3DZLYEASLYYDGLN2I3EDZY5ANASQAHCG3YQC JOPVPUSAMMU6RFVDQR4NJC4GNNUFB7GPKVH7OS5FKCYS5QZ53VLQC 22K3VJIL4SRPXVAEJSWRS7KM4UPV4SOODPSTSSKPFWKLTYRG365QC AYX33NBCPCBFWEZI5KZXHP3Y2Q62GYVT4WHYJUYRIPYV67KPSYZAC TFM6F5ODCDCNZPYVB5NZMW6MUEDTDUQNTBLPOVBTJ3IH7KT3ETKQC LLQC2M2IMEJBJQXZTKC3OAKG5WKHSERXKAKCYHQRUZZD6CVRIHAQC 3PSFWAILGRA4OYXWS2DX7VF332AIBPYBXHEA4GIQY2XEJVD65UMAC GG2553RBUKMCWIAD3EWJV7C2QH2BIS5V2E3BDTFSTYRHAPXGBF7QC 5XMBCKJZ7YCUOOQWWZRNLXMXD3MUYC2VAF3VKA4BIEHQRPDQMUMAC XGHCLIKBWIW24G7O5QLYH6EUIY3TWTYFTUIYTWE25RFEGBHMZOKQC D4B52CQ2QKG2HQKFUQOO5S2ME325DTW3PH2D7SBXCW4BPQFYG7CAC DIAP63OYZA2Q5EJN767BNV7VORLASO5T6MNESDFCNVTODU7Z36WQC CE4LZV4TNXJT54CVGM3QANCBP42TMLMZWF2DBSMUYKAHILXIZEMQC CNCYMM6ABOXCRI2IP5A4T2OGBO5FQ7GWBXBP2OQYL4YET5BLJCGQC TOJA6VDEWPXDE4KE6URFLNIZBQ6ASAFDZMSYSIBDBKACBGUKZI3QC 3LWDKR5FPZNW2ESSTTLWBBEBJ3B77UH4NEOC26PHOVG4HKOU4VQAC 4FL2EDGBMB7ORKXCHLSZTSMNDZELNV65M4OYHMFMU6FCSQFM3BMQC 3QNOKBFMKBGXBVJIRHR2444JRRMBTABHE4674NR3DT67RRM2X6GAC AVTNUQYRBW7IX2YQ3KDLVQ23RGW3BAKTAE7P73ASBYNKOHMQMH5AC check_eq(Editor_state.cursor1.line, 1, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 5, '1/cursor:pos')endcheck_eq(Editor_state.cursor1.line, 1, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')endcheck_eq(Editor_state.cursor1.line, 1, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')endcheck_eq(Editor_state.cursor1.line, 4, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')endcheck_eq(Editor_state.cursor1.line, 2, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')-- reset cursorEditor_state.cursor1 = {line=1, pos=1}check_eq(Editor_state.selection1.line, 1, 'line')check_eq(Editor_state.selection1.pos, 2, 'pos')endcheck_eq(Editor_state.lines[1].data, 'xbc', 'baseline')check_nil(Editor_state.selection1.line, 'baseline:selection')-- undoApp.screen.check(y, 'xyz', 'screen:3')endApp.screen.check(y, 'defg', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')--? check_eq(Editor_state.selection1.line, 2, 'selection:line')--? check_eq(Editor_state.selection1.pos, 4, 'selection:pos')y = Editor_state.topApp.screen.check(y, 'xyz', 'baseline/screen:3')-- undo--? -- after undo, the backspaced key is selectedApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'baseline/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'baseline/cursor:pos')check_nil(Editor_state.selection1.line, 'baseline/selection:line')check_nil(Editor_state.selection1.pos, 'baseline/selection:pos')local y = Editor_state.topApp.screen.check(y, 'xyz', 'screen:3')endfunction test_undo_delete_text()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')y = Editor_state.topApp.screen.check(y, 'xyz', 'baseline/screen:3')-- undoApp.screen.check(y, 'defg', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'baseline/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'baseline/cursor:pos')check_nil(Editor_state.selection1.line, 'baseline/selection:line')check_nil(Editor_state.selection1.pos, 'baseline/selection:pos')local y = Editor_state.topcheck_nil(Editor_state.selection1.line, 'selection')endcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'abc', 'data:1')check_eq(Editor_state.lines[2].data, 'f', 'data:2')-- cursor remains at start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_to_start_of_line()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'a', 'data:1')check_eq(Editor_state.lines[2].data, 'def', 'data:2')-- cursor remains at start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_to_end_of_line()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'akl', 'data:1')check_eq(Editor_state.lines[2].data, 'mno', 'data:2')-- cursor remains at start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_over_multiple_lines()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'bc', 'data')-- cursor moves to start of selectioncheck_nil(Editor_state.selection1.line, 'selection')endfunction test_backspace_over_selection_reverse()check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')-- selection is clearedcheck_eq(Editor_state.lines[1].data, 'bc', 'data')-- cursor (remains) at start of selectioncheck_eq(Editor_state.lines[1].data, 'abcdef', 'check')endApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_backspace_past_line_boundary()App.screen.check(y, 'kl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghij', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting backspace the screen scrolls up by one screen lineApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_backspace_can_scroll_up_screen_line()App.screen.check(y, 'ghi', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abcdef', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:3')-- after hitting backspace the screen scrolls up by one lineApp.screen.check(y, 'ghi', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 26, 'cursor:pos')endfunction test_backspace_can_scroll_up()App.screen.check(y, 'stu', 'baseline2/screen:3')-- try to move the cursor earlier in the third screen line by clicking the mouseApp.screen.check(y, 'jkl mno pqr ', 'baseline2/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc def ghi ', 'baseline2/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.pos, 28, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'xyz', 'baseline1/screen:3')-- add to the line until it's wrapping over 3 screen linesApp.screen.check(y, 'jkl mno pqr ', 'baseline1/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc def ghi ', 'baseline1/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endApp.screen.check(y, 'ghi ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 8, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting end the screen scrolls down by one lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')endApp.screen.check(y, 'jkl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting home the screen scrolls up to first screen lineApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_home_scrolls_up_in_wrapped_line()App.screen.check(y, 'ghi ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the right arrow the screen scrolls down by one lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_right_arrow_scrolls_down_in_wrapped_line()App.screen.check(y, 'jkl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting the left arrow the screen scrolls up to first screen lineApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'kl', 'screen:3')endfunction test_left_arrow_scrolls_up_in_wrapped_line()App.screen.check(y, 'ghij', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 7, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after typing something the line wraps and the screen scrolls downApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'a', 'screen:1')endcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')local y = Editor_state.topApp.screen.check(y, 'kl', 'screen:2')endApp.screen.check(y, 'j', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 4, 'screen_top')check_eq(Editor_state.cursor1.line, 5, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:1')-- after hitting the enter key the screen does not scroll downApp.screen.check(y, 'hi', 'screen:3')endfunction test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom()App.screen.check(y, 'g', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the enter key the screen scrolls downApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:3')endfunction test_enter_on_bottom_line_scrolls_down()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the page-up key the screen scrolls up to topApp.screen.check(y, 'jkl', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_pageup_scrolls_up_from_middle_screen_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the page-up key the screen scrolls up to topApp.screen.check(y, 'jkl', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:2')endfunction test_pageup_scrolls_up_by_screen_line()App.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:2')-- after pageup the cursor goes to first lineApp.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:3')endfunction test_pageup()App.screen.check(y, 'abc', 'screen:2')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the up arrow the screen scrolls up by one lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 5, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')endfunction test_up_arrow_scrolls_up_to_empty_line()App.screen.check(y, 'ghi', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:3')-- after hitting the up arrow the screen scrolls up to final screen line of previous lineApp.screen.check(y, 'jkl', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')endfunction test_up_arrow_scrolls_up_to_final_screen_line()App.screen.check(y, 'jkl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'baseline/screen:2')-- after hitting the up arrow the screen scrolls up to first screen lineApp.screen.check(y, 'jkl', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_up_arrow_scrolls_up_by_one_screen_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')y = Editor_state.topApp.screen.check(y, 'jkl', 'baseline/screen:3')-- after hitting the up arrow the screen scrolls up by one lineApp.screen.check(y, 'ghi', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_up_arrow_scrolls_up_by_one_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')-- the screen is unchangedApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the up arrow the cursor moves up by 1 lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'mno', 'screen:3')endfunction test_up_arrow_moves_cursor()App.screen.check(y, 'kl', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghij', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 3, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')y = Editor_state.topcheck_eq(Editor_state.screen_top1.line, 3, 'baseline2/screen_top')check_eq(Editor_state.cursor1.line, 3, 'baseline2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'baseline2/cursor:pos')-- after hitting down arrow the screen doesn't scroll down further, and certainly doesn't scroll upApp.screen.check(y, 'ghij', 'baseline/screen:3')-- after hitting pagedown the screen scrolls down to start of a long lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'kl', 'screen:3')endApp.screen.check(y, 'ghij', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghij', 'baseline/screen:3')-- after hitting the down arrow the screen scrolls down by one lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word()App.screen.check(y, 'ghi ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace-- after hitting the down arrow the screen scrolls down by one lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endfunction test_down_arrow_scrolls_down_by_one_screen_line()App.screen.check(y, 'ghi', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the down arrow the screen scrolls down by one lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_down_arrow_scrolls_down_by_one_line()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')-- the screen is unchangedApp.screen.check(y, 'ghi', 'baseline/screen:3')-- after hitting the down arrow, the cursor moves down by 1 lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')endApp.screen.check(y, 'mno ', 'screen:3')endApp.screen.check(y, 'jkl ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3')-- after pagedown we scroll down the very long wrapping lineApp.screen.check(y, 'def ', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'jkl', 'screen:3')endApp.screen.check(y, 'ghi ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi ', 'baseline/screen:3')-- after pagedown we start drawing from the bottom _line_ (multiple screen lines)App.screen.check(y, 'def ', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:2')endfunction test_pagedown_skips_drawings()App.screen.check(y, 'def', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')y = Editor_state.topApp.screen.check(y, 'def', 'baseline/screen:2')-- after pagedown the bottom line becomes the topApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_nil(Editor_state.selection1.line, 'check')endcheck_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')endcheck_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_select_text_repeatedly_using_mouse_and_shift()check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')endfunction test_select_text_using_mouse_and_shift()App.screen.check(y, 'def', 'screen:3')endApp.screen.check(y, 'zbc', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'axy', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- paste some text including a newline, check that new line is createdApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_eq(Editor_state.lines[1].data, '', 'data:1')check_eq(Editor_state.lines[2].data, 'abc', 'data:2')endfunction test_insert_from_clipboard()App.screen.check(y, 'def', 'screen:3')endfunction test_insert_newline_at_start_of_line()App.screen.check(y, 'bc', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'a', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')y = Editor_state.topApp.screen.check(y, 'ghi', 'baseline/screen:3')-- hitting the enter key splits the lineApp.screen.check(y, 'def', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'fg', 'screen:3')endfunction test_insert_newline()App.screen.check(y, 'de', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.screen_top1.line, 1, 'check')check_eq(Editor_state.lines[1].data, 'ahi', 'data')endApp.screen.check(y, 'jkl', 'baseline/screen:3')-- set up a selection starting above the currently displayed pageApp.screen.check(y, 'ghi', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.lines[1].data, 'xyzdef', 'check')endcheck_eq(Editor_state.lines[1].data, 'bc', 'data')endfunction test_paste_replaces_selection()check_eq(App.clipboard, 'a', 'clipboard')-- selected text is deletedcheck(Editor_state.selection1.line, 'check')endfunction test_cut()check_eq(App.clipboard, 'a', 'clipboard')-- selection is reset since shift key is not pressedcheck_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'Dbc', 'data')endfunction test_copy_does_not_reset_selection()check_eq(Editor_state.lines[1].data, 'xbc', 'check')endfunction test_edit_with_shift_key_deletes_selection()check_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'abc', 'data')endcheck_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 1, 'selection:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')endfunction test_cursor_movement_without_shift_resets_selection()check_eq(Editor_state.cursor1.pos, 20, 'cursor')endfunction test_select_text()App.screen.check(y, 'the quick brown fox ', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-pointsendfunction test_click_past_end_of_word_wrapping_line()App.screen.check(y, 'am', 'baseline/screen:3')y = y + Editor_state.line_heightApp.screen.check(y, 'I’m ad', 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'madam ', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-pointsendApp.screen.check(y, 'am', 'baseline/screen:3')y = y + Editor_state.line_heightApp.screen.check(y, "I'm ad", 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'madam ', 'baseline/screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')endApp.screen.check(y, "I'm ad", 'baseline/screen:2')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')endApp.screen.check(y, "I'm ad", 'baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'madam ', 'baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, '’m a', 'screen:3')endApp.screen.check(y, 'am I', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'mad', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ijk', 'screen:3')endfunction test_draw_wrapping_text_containing_non_ascii()-- draw a long line containing non-ASCIIApp.screen.check(y, 'e fgh', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abcd ', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endApp.screen.check(y, 'ghi', 'screen:3')endApp.screen.check(y, 'def ', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc ', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'fgh', 'screen:3')endfunction test_draw_word_wrapping_text()App.screen.check(y, 'de', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'ghi', 'screen:3')endfunction test_draw_wrapping_text()App.screen.check(y, 'def', 'screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'abc', 'screen:1')y = y + Editor_state.line_heightcheck_eq(Editor_state.cursor1.line, 1, 'cursor')endcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')endcheck_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')endcheck_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')-- selection is empty to avoid perturbing future editscheck_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos')endcheck_eq(Editor_state.cursor1.pos, 9, 'check')endcheck_eq(Editor_state.cursor1.pos, 4, 'check')endcheck_eq(Editor_state.cursor1.pos, 8, 'check')endcheck_eq(Editor_state.cursor1.pos, 4, 'check')endfunction test_skip_to_next_word()check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 5, 'pos')endfunction test_move_past_end_of_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_move_to_start_of_word_on_previous_line()check_eq(Editor_state.cursor1.pos, 9, 'check')endfunction test_skip_multiple_spaces_to_previous_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_skip_past_tab_to_previous_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_skip_to_previous_word()check_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_move_to_start_of_previous_word()check_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 1, 'pos')endfunction test_move_to_start_of_word()check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos') -- past end of lineendfunction test_move_right_to_next_line()check_eq(Editor_state.cursor1.pos, 2, 'check')endcheck_eq(Editor_state.cursor1.pos, 1, 'check')endfunction test_move_right()App.screen.check(y, 'a', 'screen:1')endfunction test_press_ctrl()check_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')endcheck_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')endfunction test_click_to_create_drawing()
check_eq(App.filesystem['foo'], 'abc\ndef\n', 'check')endcheck_eq(#Editor_state.lines, 3, '#lines')check_eq(Editor_state.lines[1].data, 'abc', 'lines:1')check_eq(Editor_state.lines[2].data, 'def', 'lines:2')check_eq(Editor_state.lines[3].data, 'ghi', 'lines:3')edit.draw(Editor_state)endfunction test_drop_file_saves_previous()check_eq(Editor_state.left, Margin_left, 'edit:left')check_eq(Editor_state.right, App.screen.width/2 - Margin_right, 'edit:right')check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'log:right')endfunction test_drop_file()check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'log:right')endfunction test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width()check_eq(Editor_state.left, Margin_left, 'edit:left')check_eq(Editor_state.right, old_editor_right, 'edit:right')-- log browser margins are adjustedcheck_eq(App.screen.width, 600, 'display:width')-- left side margins are unchangedcheck(Show_log_browser_side, 'check')endfunction test_show_log_browser_side_doubles_window_width_if_possible()check(not Show_log_browser_side, 'baseline')-- pressing ctrl+l shows log-browser sidecheck_eq(App.screen.width, 200, 'width')check_eq(App.screen.height, 400, 'height')check_eq(Editor_state.left, Margin_left, 'left_margin')check_eq(Editor_state.right, 200-Margin_right, 'right_margin')check_eq(Editor_state.width, 200-Margin_left-Margin_right, 'drawing_width')-- TODO: how to make assertions about when App.update got past the early exit?check_eq(App.screen.width, 300, 'baseline/width')check_eq(App.screen.height, 300, 'baseline/height')check_eq(Editor_state.left, Test_margin_left, 'baseline/left_margin')check_eq(Editor_state.right, 300 - Test_margin_right, 'baseline/right_margin')App.resize(200, 400)
check_eq(#Editor_state.lines, 1, 'F - test_initial_state/#lines')check_eq(Editor_state.cursor1.line, 1, 'F - test_initial_state/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_initial_state/cursor:pos')check_eq(Editor_state.screen_top1.line, 1, 'F - test_initial_state/screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'F - test_initial_state/screen_top:pos')
check_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')
endfunction test_click_to_create_drawing()App.screen.init{width=120, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{}Text.redraw_all(Editor_state)edit.draw(Editor_state)edit.run_after_mouse_click(Editor_state, 8,Editor_state.top+8, 1)-- cursor skips drawing to always remain on text
endfunction test_backspace_to_delete_drawing()-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)App.screen.init{width=120, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'```lines', '```', ''}Text.redraw_all(Editor_state)-- cursor is on text as always (outside tests this will get initialized correctly)Editor_state.cursor1.line = 2-- backspacing deletes the drawingedit.run_after_keychord(Editor_state, 'backspace')
check_eq(#Editor_state.lines, 1, 'F - test_backspace_from_start_of_final_line/#lines')check_eq(Editor_state.cursor1.line, 1, 'F - test_backspace_from_start_of_final_line/cursor')check_eq(Editor_state.screen_top1.line, 1, 'F - test_backspace_from_start_of_final_line/screen_top')
check_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')
check_eq(Editor_state.cursor1.line, 1, 'F - test_move_left_to_previous_line/line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_move_left_to_previous_line/pos') -- past end of line
check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos') -- past end of line
check_eq(Editor_state.cursor1.line, 2, 'F - test_move_right_to_next_line/line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_move_right_to_next_line/pos')
check_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 1, 'pos')
check_eq(Editor_state.cursor1.pos, 1, 'F - test_move_to_start_of_word')check_eq(#Editor_state.lines, 1, '#lines')check_eq(Editor_state.cursor1.line, 1, 'cursor')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')App.screen.check(y, 'a', 'screen:1')check_eq(Editor_state.cursor1.pos, 1, 'check')check_eq(Editor_state.cursor1.pos, 2, 'check')check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos') -- past end of linecheck_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 1, 'pos')check_eq(Editor_state.cursor1.pos, 1, 'check')check_eq(Editor_state.cursor1.pos, 1, 'check')check_eq(Editor_state.cursor1.pos, 1, 'check')check_eq(Editor_state.cursor1.pos, 9, 'check')
check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 5, 'pos')check_eq(Editor_state.cursor1.pos, 4, 'check')check_eq(Editor_state.cursor1.pos, 8, 'check')check_eq(Editor_state.cursor1.pos, 4, 'check')check_eq(Editor_state.cursor1.pos, 9, 'check')check_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')check_eq(Editor_state.cursor1.line, 1, 'cursor')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'ghi', 'screen:3')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'de', 'screen:2')App.screen.check(y, 'fgh', 'screen:3')App.screen.check(y, 'abc ', 'screen:1')App.screen.check(y, 'def ', 'screen:2')App.screen.check(y, 'ghi', 'screen:3')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')App.screen.check(y, 'abcd ', 'screen:1')App.screen.check(y, 'e fgh', 'screen:2')App.screen.check(y, 'ijk', 'screen:3')App.screen.check(y, 'mad', 'screen:1')App.screen.check(y, 'am I', 'screen:2')App.screen.check(y, '’m a', 'screen:3')App.screen.check(y, 'madam ', 'baseline/screen:1')App.screen.check(y, "I'm ad", 'baseline/screen:2')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')App.screen.check(y, "I'm ad", 'baseline/screen:2')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')App.screen.check(y, 'madam ', 'baseline/screen:1')App.screen.check(y, "I'm ad", 'baseline/screen:2')App.screen.check(y, 'am', 'baseline/screen:3')check_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-pointsApp.screen.check(y, 'madam ', 'baseline/screen:1')App.screen.check(y, 'I’m ad', 'baseline/screen:2')App.screen.check(y, 'am', 'baseline/screen:3')check_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-pointsApp.screen.check(y, 'the quick brown fox ', 'baseline/screen:1')check_eq(Editor_state.cursor1.pos, 20, 'cursor')check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 1, 'selection:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'abc', 'data')check_eq(Editor_state.lines[1].data, 'xbc', 'check')check_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'Dbc', 'data')check_eq(App.clipboard, 'a', 'clipboard')check(Editor_state.selection1.line, 'check')check_eq(App.clipboard, 'a', 'clipboard')check_eq(Editor_state.lines[1].data, 'bc', 'data')
check_eq(Editor_state.lines[1].data, 'xyzdef', 'check')App.screen.check(y, 'def', 'baseline/screen:1')App.screen.check(y, 'ghi', 'baseline/screen:2')App.screen.check(y, 'jkl', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'check')check_eq(Editor_state.lines[1].data, 'ahi', 'data')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'de', 'screen:2')App.screen.check(y, 'fg', 'screen:3')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')App.screen.check(y, 'a', 'screen:1')App.screen.check(y, 'bc', 'screen:2')App.screen.check(y, 'def', 'screen:3')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_eq(Editor_state.lines[1].data, '', 'data:1')check_eq(Editor_state.lines[2].data, 'abc', 'data:2')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')App.screen.check(y, 'axy', 'screen:1')App.screen.check(y, 'zbc', 'screen:2')App.screen.check(y, 'def', 'screen:3')check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'check')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghi', 'screen:2')
check_eq(Editor_state.cursor1.line, 1, 'F - test_move_to_start_of_word_on_previous_line/line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_move_to_start_of_word_on_previous_line/pos')
check_eq(Editor_state.cursor1.line, 1, 'line')check_eq(Editor_state.cursor1.pos, 5, 'pos')
check_eq(Editor_state.cursor1.line, 2, 'F - test_move_past_end_of_word_on_next_line/line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_move_past_end_of_word_on_next_line/pos')
check_eq(Editor_state.cursor1.line, 2, 'line')check_eq(Editor_state.cursor1.pos, 4, 'pos')
check_eq(Editor_state.cursor1.line, 1, 'F - test_click_moves_cursor/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_click_moves_cursor/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')
check_nil(Editor_state.selection1.line, 'F - test_click_moves_cursor/selection:line')check_nil(Editor_state.selection1.pos, 'F - test_click_moves_cursor/selection:pos')
check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')
check_eq(Editor_state.cursor1.line, 1, 'F - test_click_to_left_of_line/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_click_to_left_of_line/cursor:pos')check_nil(Editor_state.selection1.line, 'F - test_click_to_left_of_line/selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'F - test_click_takes_margins_into_account/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_click_takes_margins_into_account/cursor:pos')check_nil(Editor_state.selection1.line, 'F - test_click_takes_margins_into_account/selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'F - test_click_on_wrapping_line/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_click_on_wrapping_line/cursor:pos')check_nil(Editor_state.selection1.line, 'F - test_click_on_wrapping_line/selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'F - test_click_on_wrapping_line_takes_margins_into_account/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_click_on_wrapping_line_takes_margins_into_account/cursor:pos')check_nil(Editor_state.selection1.line, 'F - test_click_on_wrapping_line_takes_margins_into_account/selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
check_eq(Editor_state.cursor1.line, 1, 'F - test_click_on_wrapping_line/cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'F - test_click_on_wrapping_line/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'F - test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen/cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'F - test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
check_eq(Editor_state.cursor1.pos, 15, 'F - test_click_past_end_of_wrapping_line_containing_non_ascii/cursor') -- one more than the number of UTF-8 code-points
check_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-points
check_eq(Editor_state.selection1.line, 1, 'F - test_select_text/selection:line')check_eq(Editor_state.selection1.pos, 1, 'F - test_select_text/selection:pos')check_eq(Editor_state.cursor1.line, 1, 'F - test_select_text/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_select_text/cursor:pos')
check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 1, 'selection:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')
check_nil(Editor_state.selection1.line, 'F - test_cursor_movement_without_shift_resets_selection')check_eq(Editor_state.lines[1].data, 'abc', 'F - test_cursor_movement_without_shift_resets_selection/data')
check_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'abc', 'data')
check_nil(Editor_state.selection1.line, 'F - test_edit_with_shift_key_deletes_selection')check_eq(Editor_state.lines[1].data, 'Dbc', 'F - test_edit_with_shift_key_deletes_selection/data')
check_nil(Editor_state.selection1.line, 'check')check_eq(Editor_state.lines[1].data, 'Dbc', 'data')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_deleting_selection_may_scroll')check_eq(Editor_state.lines[1].data, 'ahi', 'F - test_deleting_selection_may_scroll/data')
check_eq(Editor_state.screen_top1.line, 1, 'check')check_eq(Editor_state.lines[1].data, 'ahi', 'data')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_insert_newline/screen_top')check_eq(Editor_state.cursor1.line, 2, 'F - test_insert_newline/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_insert_newline/cursor:pos')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
check_eq(Editor_state.cursor1.line, 2, 'F - test_insert_newline_at_start_of_line/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_insert_newline_at_start_of_line/cursor:pos')check_eq(Editor_state.lines[1].data, '', 'F - test_insert_newline_at_start_of_line/data:1')check_eq(Editor_state.lines[2].data, 'abc', 'F - test_insert_newline_at_start_of_line/data:2')
check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')check_eq(Editor_state.lines[1].data, '', 'data:1')check_eq(Editor_state.lines[2].data, 'abc', 'data:2')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_insert_from_clipboard/screen_top')check_eq(Editor_state.cursor1.line, 2, 'F - test_insert_from_clipboard/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_insert_from_clipboard/cursor:pos')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')
check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_using_mouse/selection:line')check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_using_mouse/selection:pos')check_eq(Editor_state.cursor1.line, 2, 'F - test_select_text_using_mouse/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_select_text_using_mouse/cursor:pos')
check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_using_mouse_and_shift/selection:line')check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_using_mouse_and_shift/selection:pos')check_eq(Editor_state.cursor1.line, 2, 'F - test_select_text_using_mouse_and_shift/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_select_text_using_mouse_and_shift/cursor:pos')
check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:line')check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:pos')check_eq(Editor_state.cursor1.line, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:pos')
check_eq(Editor_state.selection1.line, 1, 'selection:line')check_eq(Editor_state.selection1.pos, 2, 'selection:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'F - test_pagedown/screen_top')check_eq(Editor_state.cursor1.line, 2, 'F - test_pagedown/cursor')
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')
-- some lines of text with a drawing intermixedlocal drawing_width = 50App.screen.init{width=Editor_state.left+drawing_width, height=80}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc', -- height 15'```lines', '```', -- height 25'def', -- height 15'ghi'} -- height 15Text.redraw_all(Editor_state)
Editor_state.cursor1 = {line=1, pos=1}Editor_state.screen_top1 = {line=1, pos=1}Editor_state.screen_bottom1 = {}local drawing_height = Drawing_padding_height + drawing_width/2 -- default-- initially the screen displays the first line and the drawing-- 15px margin + 15px line1 + 10px margin + 25px drawing + 10px margin = 75px < screen height 80pxedit.draw(Editor_state)local y = Editor_state.top
check_eq(Editor_state.screen_top1.line, 1, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:pos')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_pagedown_never_moves_up/screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'F - test_pagedown_never_moves_up/screen_top:pos')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_down_arrow_moves_cursor/screen_top')check_eq(Editor_state.cursor1.line, 2, 'F - test_down_arrow_moves_cursor/cursor')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')
check_eq(Editor_state.screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_line/screen_top')check_eq(Editor_state.cursor1.line, 4, 'F - test_down_arrow_scrolls_down_by_one_line/cursor')
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor')
App.screen.check(y, 'ghi ', 'F - test_down_arrow_scrolls_down_by_one_screen_line/baseline/screen:3') -- line wrapping includes trailing whitespace
App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
check_eq(Editor_state.screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
App.screen.init{width=Editor_state.left+30, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc', 'def', 'ghijkl', 'mno'}Text.redraw_all(Editor_state)Editor_state.cursor1 = {line=3, pos=1}Editor_state.screen_top1 = {line=1, pos=1}Editor_state.screen_bottom1 = {}edit.draw(Editor_state)local y = Editor_state.top
check_eq(Editor_state.screen_top1.line, 3, 'F - test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up/baseline2/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up/baseline2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up/baseline2/cursor:pos')
check_eq(Editor_state.screen_top1.line, 3, 'F - test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up/cursor:pos')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_up_arrow_moves_cursor/screen_top')check_eq(Editor_state.cursor1.line, 2, 'F - test_up_arrow_moves_cursor/cursor')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_by_one_line/screen_top')check_eq(Editor_state.cursor1.line, 1, 'F - test_up_arrow_scrolls_up_by_one_line/cursor')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')
App.screen.check(y, 'mno', 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen:3')check_eq(Editor_state.screen_top1.line, 3, 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen_top')check_eq(Editor_state.screen_top1.pos, 1, 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_up_arrow_scrolls_up_by_one_screen_line/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_up_arrow_scrolls_up_by_one_screen_line/cursor:pos')
App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen_top')check_eq(Editor_state.screen_top1.pos, 5, 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen_top')check_eq(Editor_state.cursor1.line, 1, 'F - test_up_arrow_scrolls_up_to_final_screen_line/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_up_arrow_scrolls_up_to_final_screen_line/cursor:pos')
App.screen.check(y, 'jkl', 'screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 5, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_to_empty_line/screen_top')check_eq(Editor_state.cursor1.line, 1, 'F - test_up_arrow_scrolls_up_to_empty_line/cursor')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_pageup/screen_top')check_eq(Editor_state.cursor1.line, 1, 'F - test_pageup/cursor')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')
App.screen.check(y, 'mno', 'F - test_pageup_scrolls_up_by_screen_line/baseline/screen:3') -- line wrapping includes trailing whitespace
App.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace
check_eq(Editor_state.screen_top1.line, 1, 'F - test_pageup_scrolls_up_by_screen_line/screen_top')check_eq(Editor_state.cursor1.line, 1, 'F - test_pageup_scrolls_up_by_screen_line/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_pageup_scrolls_up_by_screen_line/cursor:pos')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
App.screen.check(y, 'mno', 'F - test_pageup_scrolls_up_from_middle_screen_line/baseline/screen:3') -- line wrapping includes trailing whitespace
App.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace
check_eq(Editor_state.screen_top1.line, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/screen_top')check_eq(Editor_state.cursor1.line, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/cursor:pos')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'F - test_enter_on_bottom_line_scrolls_down/screen_top')check_eq(Editor_state.cursor1.line, 4, 'F - test_enter_on_bottom_line_scrolls_down/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_enter_on_bottom_line_scrolls_down/cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
check_eq(Editor_state.screen_top1.line, 4, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen_top')check_eq(Editor_state.cursor1.line, 5, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:pos')
check_eq(Editor_state.screen_top1.line, 4, 'screen_top')check_eq(Editor_state.cursor1.line, 5, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen_top')check_eq(Editor_state.cursor1.line, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'F - test_typing_on_bottom_line_scrolls_down/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_typing_on_bottom_line_scrolls_down/cursor:line')check_eq(Editor_state.cursor1.pos, 7, 'F - test_typing_on_bottom_line_scrolls_down/cursor:pos')
App.screen.check(y, 'mno', 'F - test_left_arrow_scrolls_up_in_wrapped_line/screen:3')check_eq(Editor_state.screen_top1.line, 3, 'F - test_left_arrow_scrolls_up_in_wrapped_line/screen_top')check_eq(Editor_state.screen_top1.pos, 1, 'F - test_left_arrow_scrolls_up_in_wrapped_line/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_left_arrow_scrolls_up_in_wrapped_line/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_left_arrow_scrolls_up_in_wrapped_line/cursor:pos')
App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
App.screen.check(y, 'ghi ', 'F - test_right_arrow_scrolls_down_in_wrapped_line/baseline/screen:3') -- line wrapping includes trailing whitespace
App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
check_eq(Editor_state.screen_top1.line, 2, 'F - test_right_arrow_scrolls_down_in_wrapped_line/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_right_arrow_scrolls_down_in_wrapped_line/cursor:line')check_eq(Editor_state.cursor1.pos, 6, 'F - test_right_arrow_scrolls_down_in_wrapped_line/cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
App.screen.check(y, 'mno', 'F - test_home_scrolls_up_in_wrapped_line/screen:3')check_eq(Editor_state.screen_top1.line, 3, 'F - test_home_scrolls_up_in_wrapped_line/screen_top')check_eq(Editor_state.screen_top1.pos, 1, 'F - test_home_scrolls_up_in_wrapped_line/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_home_scrolls_up_in_wrapped_line/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_home_scrolls_up_in_wrapped_line/cursor:pos')
App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
App.screen.check(y, 'ghi ', 'F - test_end_scrolls_down_in_wrapped_line/baseline/screen:3') -- line wrapping includes trailing whitespace
App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
check_eq(Editor_state.screen_top1.line, 2, 'F - test_end_scrolls_down_in_wrapped_line/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_end_scrolls_down_in_wrapped_line/cursor:line')check_eq(Editor_state.cursor1.pos, 8, 'F - test_end_scrolls_down_in_wrapped_line/cursor:pos')
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 8, 'cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'F - test_position_cursor_on_recently_edited_wrapping_line/cursor:line')check_eq(Editor_state.cursor1.pos, 26, 'F - test_position_cursor_on_recently_edited_wrapping_line/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 26, 'cursor:pos')
check_eq(Editor_state.screen_top1.line, 1, 'F - test_backspace_can_scroll_up/screen_top')check_eq(Editor_state.cursor1.line, 1, 'F - test_backspace_can_scroll_up/cursor')
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')
App.screen.check(y, 'mno', 'F - test_backspace_can_scroll_up_screen_line/screen:3')check_eq(Editor_state.screen_top1.line, 3, 'F - test_backspace_can_scroll_up_screen_line/screen_top')check_eq(Editor_state.screen_top1.pos, 1, 'F - test_backspace_can_scroll_up_screen_line/screen_top')check_eq(Editor_state.cursor1.line, 3, 'F - test_backspace_can_scroll_up_screen_line/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_backspace_can_scroll_up_screen_line/cursor:pos')
App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'abc ', 'baseline/screen:1')App.screen.check(y, 'def ', 'baseline/screen:2')App.screen.check(y, 'ghi ', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')App.screen.check(y, 'ghi ', 'screen:1')App.screen.check(y, 'jkl ', 'screen:2')App.screen.check(y, 'mno ', 'screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'ghi', 'screen:3')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghi', 'screen:2')App.screen.check(y, 'jkl', 'screen:3')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespacecheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghi ', 'screen:2')App.screen.check(y, 'jkl', 'screen:3')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghij', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghij', 'screen:2')App.screen.check(y, 'kl', 'screen:3')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghij', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 3, 'baseline2/screen_top')check_eq(Editor_state.cursor1.line, 3, 'baseline2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'baseline2/cursor:pos')check_eq(Editor_state.screen_top1.line, 3, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')App.screen.check(y, 'ghij', 'screen:1')App.screen.check(y, 'kl', 'screen:2')App.screen.check(y, 'mno', 'screen:3')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'ghi', 'screen:3')App.screen.check(y, 'def', 'baseline/screen:1')App.screen.check(y, 'ghi', 'baseline/screen:2')App.screen.check(y, 'jkl', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'ghi', 'screen:3')App.screen.check(y, 'jkl', 'baseline/screen:1')App.screen.check(y, 'mno', 'baseline/screen:2')App.screen.check(y, 'ghi ', 'screen:1')App.screen.check(y, 'jkl', 'screen:2')App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')App.screen.check(y, 'ghi', 'baseline/screen:1')App.screen.check(y, 'jkl', 'baseline/screen:2')App.screen.check(y, 'mno', 'baseline/screen:3')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghi', 'screen:2')App.screen.check(y, 'jkl', 'screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 5, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')App.screen.check(y, 'abc', 'screen:2')App.screen.check(y, 'def', 'screen:3')App.screen.check(y, 'def', 'baseline/screen:1')App.screen.check(y, 'ghi', 'baseline/screen:2')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'ghi', 'baseline/screen:1')App.screen.check(y, 'jkl', 'baseline/screen:2')App.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespacecheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')App.screen.check(y, 'abc ', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'ghi', 'screen:3')App.screen.check(y, 'jkl', 'baseline/screen:2')App.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespacecheck_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')App.screen.check(y, 'abc ', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'ghi ', 'screen:3')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 4, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'g', 'screen:2')App.screen.check(y, 'hi', 'screen:3')App.screen.check(y, 'jkl', 'baseline/screen:1')check_eq(Editor_state.screen_top1.line, 4, 'screen_top')check_eq(Editor_state.cursor1.line, 5, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')App.screen.check(y, 'j', 'screen:1')App.screen.check(y, 'kl', 'screen:2')check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')App.screen.check(y, 'a', 'screen:1')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 7, 'cursor:pos')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghij', 'screen:2')App.screen.check(y, 'kl', 'screen:3')App.screen.check(y, 'jkl', 'baseline/screen:1')App.screen.check(y, 'mno', 'baseline/screen:2')App.screen.check(y, 'ghi ', 'screen:1')App.screen.check(y, 'jkl', 'screen:2')App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespacecheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghi ', 'screen:2')App.screen.check(y, 'jkl', 'screen:3')App.screen.check(y, 'jkl', 'baseline/screen:1')App.screen.check(y, 'mno', 'baseline/screen:2')App.screen.check(y, 'ghi ', 'screen:1')App.screen.check(y, 'jkl', 'screen:2')App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespacecheck_eq(Editor_state.screen_top1.line, 2, 'screen_top')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 8, 'cursor:pos')App.screen.check(y, 'def', 'screen:1')App.screen.check(y, 'ghi ', 'screen:2')App.screen.check(y, 'jkl', 'screen:3')App.screen.check(y, 'abc def ghi ', 'baseline1/screen:1')App.screen.check(y, 'jkl mno pqr ', 'baseline1/screen:2')App.screen.check(y, 'xyz', 'baseline1/screen:3')check_eq(Editor_state.cursor1.pos, 28, 'cursor:pos')App.screen.check(y, 'abc def ghi ', 'baseline2/screen:1')App.screen.check(y, 'jkl mno pqr ', 'baseline2/screen:2')App.screen.check(y, 'stu', 'baseline2/screen:3')check_eq(Editor_state.cursor1.line, 1, 'cursor:line')check_eq(Editor_state.cursor1.pos, 26, 'cursor:pos')App.screen.check(y, 'def', 'baseline/screen:1')App.screen.check(y, 'ghi', 'baseline/screen:2')App.screen.check(y, 'jkl', 'baseline/screen:3')check_eq(Editor_state.screen_top1.line, 1, 'screen_top')check_eq(Editor_state.cursor1.line, 1, 'cursor')App.screen.check(y, 'abcdef', 'screen:1')App.screen.check(y, 'ghi', 'screen:2')App.screen.check(y, 'jkl', 'screen:3')App.screen.check(y, 'jkl', 'baseline/screen:1')App.screen.check(y, 'mno', 'baseline/screen:2')App.screen.check(y, 'ghij', 'screen:1')App.screen.check(y, 'kl', 'screen:2')App.screen.check(y, 'mno', 'screen:3')check_eq(Editor_state.screen_top1.line, 3, 'screen_top:line')check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos')check_eq(Editor_state.cursor1.line, 3, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')check_eq(Editor_state.lines[1].data, 'abcdef', 'check')
-- select just one character within a line with cursor before selectionApp.screen.init{width=Editor_state.left+30, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}Text.redraw_all(Editor_state)Editor_state.cursor1 = {line=1, pos=1}Editor_state.selection1 = {line=1, pos=2}-- backspace deletes the selected character, even though it's after the cursoredit.run_after_keychord(Editor_state, 'backspace')
endfunction test_backspace_over_selection_reverse()-- select just one character within a line with cursor after selectionApp.screen.init{width=Editor_state.left+30, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}Text.redraw_all(Editor_state)Editor_state.cursor1 = {line=1, pos=2}Editor_state.selection1 = {line=1, pos=1}-- backspace deletes the selected characteredit.run_after_keychord(Editor_state, 'backspace')
endfunction test_backspace_over_multiple_lines()-- select just one character within a line with cursor after selectionApp.screen.init{width=Editor_state.left+30, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}Text.redraw_all(Editor_state)Editor_state.cursor1 = {line=1, pos=2}Editor_state.selection1 = {line=4, pos=2}-- backspace deletes the region and joins the remaining portions of lines on either sideedit.run_after_keychord(Editor_state, 'backspace')
endfunction test_backspace_to_end_of_line()-- select region from cursor to end of lineApp.screen.init{width=Editor_state.left+30, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}Text.redraw_all(Editor_state)Editor_state.cursor1 = {line=1, pos=2}Editor_state.selection1 = {line=1, pos=4}-- backspace deletes rest of line without joining to any other lineedit.run_after_keychord(Editor_state, 'backspace')
endfunction test_backspace_to_start_of_line()-- select region from cursor to start of lineApp.screen.init{width=Editor_state.left+30, height=60}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}Text.redraw_all(Editor_state)Editor_state.cursor1 = {line=2, pos=1}Editor_state.selection1 = {line=2, pos=3}-- backspace deletes beginning of line without joining to any other lineedit.run_after_keychord(Editor_state, 'backspace')
check_eq(Editor_state.cursor1.line, 2, 'F - test_undo_insert_text/baseline/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_undo_insert_text/baseline/cursor:pos')check_nil(Editor_state.selection1.line, 'F - test_undo_insert_text/baseline/selection:line')check_nil(Editor_state.selection1.pos, 'F - test_undo_insert_text/baseline/selection:pos')
check_eq(Editor_state.cursor1.line, 2, 'F - test_undo_insert_text/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_undo_insert_text/cursor:pos')App.screen.check(y, 'abc', 'baseline/screen:1')App.screen.check(y, 'defg', 'baseline/screen:2')App.screen.check(y, 'xyz', 'baseline/screen:3')check_nil(Editor_state.selection1.line, 'F - test_undo_insert_text/selection:line')check_nil(Editor_state.selection1.pos, 'F - test_undo_insert_text/selection:pos')
check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')
check_eq(Editor_state.cursor1.line, 2, 'F - test_undo_delete_text/baseline/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'F - test_undo_delete_text/baseline/cursor:pos')check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'def', 'screen:2')App.screen.check(y, 'xyz', 'screen:3')check_nil(Editor_state.selection1.line, 'F - test_undo_delete_text/baseline/selection:line')check_nil(Editor_state.selection1.pos, 'F - test_undo_delete_text/baseline/selection:pos')local y = Editor_state.topApp.screen.check(y, 'abc', 'F - test_undo_delete_text/baseline/screen:1')y = y + Editor_state.line_heightApp.screen.check(y, 'def', 'F - test_undo_delete_text/baseline/screen:2')y = y + Editor_state.line_heightApp.screen.check(y, 'xyz', 'F - test_undo_delete_text/baseline/screen:3')-- undo--? -- after undo, the backspaced key is selectededit.run_after_keychord(Editor_state, 'C-z')check_eq(Editor_state.cursor1.line, 2, 'F - test_undo_delete_text/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_undo_delete_text/cursor:pos')
check_eq(Editor_state.cursor1.line, 2, 'baseline/cursor:line')check_eq(Editor_state.cursor1.pos, 4, 'baseline/cursor:pos')check_nil(Editor_state.selection1.line, 'baseline/selection:line')check_nil(Editor_state.selection1.pos, 'baseline/selection:pos')App.screen.check(y, 'abc', 'baseline/screen:1')
App.screen.check(y, 'def', 'baseline/screen:2')App.screen.check(y, 'xyz', 'baseline/screen:3')check_nil(Editor_state.selection1.line, 'F - test_undo_delete_text/selection:line')check_nil(Editor_state.selection1.pos, 'F - test_undo_delete_text/selection:pos')--? check_eq(Editor_state.selection1.line, 2, 'F - test_undo_delete_text/selection:line')--? check_eq(Editor_state.selection1.pos, 4, 'F - test_undo_delete_text/selection:pos')y = Editor_state.topApp.screen.check(y, 'abc', 'F - test_undo_delete_text/screen:1')
check_eq(Editor_state.cursor1.line, 2, 'cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')check_nil(Editor_state.selection1.line, 'selection:line')check_nil(Editor_state.selection1.pos, 'selection:pos')--? check_eq(Editor_state.selection1.line, 2, 'selection:line')--? check_eq(Editor_state.selection1.pos, 4, 'selection:pos')App.screen.check(y, 'abc', 'screen:1')App.screen.check(y, 'defg', 'screen:2')App.screen.check(y, 'xyz', 'screen:3')
App.screen.check(y, 'xyz', 'baseline/screen:3')-- undo--? -- after undo, the backspaced key is selectededit.run_after_keychord(Editor_state, 'C-z')
-- display a line of text with some part selectedApp.screen.init{width=75, height=80}Editor_state = edit.initialize_test_state()Editor_state.lines = load_array{'abc'}Text.redraw_all(Editor_state)Editor_state.cursor1 = {line=1, pos=1}Editor_state.selection1 = {line=1, pos=2}Editor_state.screen_top1 = {line=1, pos=1}Editor_state.screen_bottom1 = {}edit.draw(Editor_state)-- delete selected text
check_eq(Editor_state.lines[1].data, 'xbc', 'F - test_undo_restores_selection/baseline')check_nil(Editor_state.selection1.line, 'F - test_undo_restores_selection/baseline:selection')
check_eq(Editor_state.cursor1.line, 2, 'F - test_search/1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_search/1/cursor:pos')
check_eq(Editor_state.cursor1.line, 2, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')
check_eq(Editor_state.cursor1.line, 4, 'F - test_search/2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_search/2/cursor:pos')
check_eq(Editor_state.cursor1.line, 4, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'F - test_search_upwards/2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_search_upwards/2/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'F - test_search_wrap/1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, 'F - test_search_wrap/1/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')
check_eq(Editor_state.cursor1.line, 1, 'F - test_search_wrap_upwards/1/cursor:line')check_eq(Editor_state.cursor1.pos, 5, 'F - test_search_wrap_upwards/1/cursor:pos')endcheck_eq(Editor_state.cursor1.line, 2, '1/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')check_eq(Editor_state.cursor1.line, 4, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')check_eq(Editor_state.cursor1.line, 1, '2/cursor:line')check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')
end
check_eq(Editor_state.left, Margin_left, 'F - test_show_log_browser_side_doubles_window_width_if_possible/edit:left')check_eq(Editor_state.right, old_editor_right, 'F - test_show_log_browser_side_doubles_window_width_if_possible/edit:right')
check_eq(Editor_state.left, Margin_left, 'edit:left')check_eq(Editor_state.right, old_editor_right, 'edit:right')
check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'F - test_show_log_browser_side_doubles_window_width_if_possible/log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'F - test_show_log_browser_side_doubles_window_width_if_possible/log:right')
check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'log:right')
check_eq(Editor_state.left, Margin_left, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/edit:left')check_eq(Editor_state.right, App.screen.width/2 - Margin_right, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/edit:right')check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/log:right')
check_eq(Editor_state.left, Margin_left, 'edit:left')check_eq(Editor_state.right, App.screen.width/2 - Margin_right, 'edit:right')check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'log:left')check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'log:right')
Test_errors = {}if #Test_errors > 0 thenerror('There were test failures:\n\n'..table.concat(Test_errors))end