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')
end
check_eq(Editor_state.cursor1.line, 1, '1/cursor:line')
check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')
end
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.cursor1.line, 4, '2/cursor:line')
check_eq(Editor_state.cursor1.pos, 1, '2/cursor:pos')
end
check_eq(Editor_state.cursor1.line, 2, '1/cursor:line')
check_eq(Editor_state.cursor1.pos, 1, '1/cursor:pos')
-- reset cursor
Editor_state.cursor1 = {line=1, pos=1}
check_eq(Editor_state.selection1.line, 1, 'line')
check_eq(Editor_state.selection1.pos, 2, 'pos')
end
check_eq(Editor_state.lines[1].data, 'xbc', 'baseline')
check_nil(Editor_state.selection1.line, 'baseline:selection')
-- undo
App.screen.check(y, 'xyz', 'screen:3')
end
App.screen.check(y, 'defg', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'xyz', 'baseline/screen:3')
-- undo
--? -- after undo, the backspaced key is selected
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
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')
local y = Editor_state.top
App.screen.check(y, 'xyz', 'screen:3')
end
function test_undo_delete_text()
App.screen.check(y, 'def', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'xyz', 'baseline/screen:3')
-- undo
App.screen.check(y, 'defg', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
check_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.top
check_nil(Editor_state.selection1.line, 'selection')
end
check_eq(Editor_state.cursor1.line, 2, 'cursor:line')
check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos')
-- selection is cleared
check_eq(Editor_state.lines[1].data, 'abc', 'data:1')
check_eq(Editor_state.lines[2].data, 'f', 'data:2')
-- cursor remains at start of selection
check_nil(Editor_state.selection1.line, 'selection')
end
function 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 cleared
check_eq(Editor_state.lines[1].data, 'a', 'data:1')
check_eq(Editor_state.lines[2].data, 'def', 'data:2')
-- cursor remains at start of selection
check_nil(Editor_state.selection1.line, 'selection')
end
function 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 cleared
check_eq(Editor_state.lines[1].data, 'akl', 'data:1')
check_eq(Editor_state.lines[2].data, 'mno', 'data:2')
-- cursor remains at start of selection
check_nil(Editor_state.selection1.line, 'selection')
end
function 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 cleared
check_eq(Editor_state.lines[1].data, 'bc', 'data')
-- cursor moves to start of selection
check_nil(Editor_state.selection1.line, 'selection')
end
function 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 cleared
check_eq(Editor_state.lines[1].data, 'bc', 'data')
-- cursor (remains) at start of selection
check_eq(Editor_state.lines[1].data, 'abcdef', 'check')
end
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')
end
function test_backspace_past_line_boundary()
App.screen.check(y, 'kl', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghij', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'mno', 'baseline/screen:2')
-- after hitting backspace the screen scrolls up by one screen line
App.screen.check(y, 'jkl', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'jkl', 'screen:3')
end
function test_backspace_can_scroll_up_screen_line()
App.screen.check(y, 'ghi', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abcdef', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')
check_eq(Editor_state.cursor1.line, 1, 'cursor')
y = Editor_state.top
App.screen.check(y, 'jkl', 'baseline/screen:3')
-- after hitting backspace the screen scrolls up by one line
App.screen.check(y, 'ghi', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'baseline/screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
check_eq(Editor_state.cursor1.pos, 26, 'cursor:pos')
end
function 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 mouse
App.screen.check(y, 'jkl mno pqr ', 'baseline2/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc def ghi ', 'baseline2/screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.cursor1.pos, 28, 'cursor:pos')
y = Editor_state.top
App.screen.check(y, 'xyz', 'baseline1/screen:3')
-- add to the line until it's wrapping over 3 screen lines
App.screen.check(y, 'jkl mno pqr ', 'baseline1/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc def ghi ', 'baseline1/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'jkl', 'screen:3')
end
App.screen.check(y, 'ghi ', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting end the screen scrolls down by one line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
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')
end
App.screen.check(y, 'jkl', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi ', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'mno', 'baseline/screen:2')
-- after hitting home the screen scrolls up to first screen line
App.screen.check(y, 'jkl', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'jkl', 'screen:3')
end
function test_home_scrolls_up_in_wrapped_line()
App.screen.check(y, 'ghi ', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting the right arrow the screen scrolls down by one line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
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')
end
function test_right_arrow_scrolls_down_in_wrapped_line()
App.screen.check(y, 'jkl', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi ', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'mno', 'baseline/screen:2')
-- after hitting the left arrow the screen scrolls up to first screen line
App.screen.check(y, 'jkl', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'kl', 'screen:3')
end
function test_left_arrow_scrolls_up_in_wrapped_line()
App.screen.check(y, 'ghij', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- after typing something the line wraps and the screen scrolls down
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'a', 'screen:1')
end
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')
check_eq(Editor_state.cursor1.line, 2, 'cursor:line')
check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')
local y = Editor_state.top
App.screen.check(y, 'kl', 'screen:2')
end
App.screen.check(y, 'j', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'jkl', 'baseline/screen:1')
-- after hitting the enter key the screen does not scroll down
App.screen.check(y, 'hi', 'screen:3')
end
function test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom()
App.screen.check(y, 'g', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- after hitting the enter key the screen scrolls down
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi ', 'screen:3')
end
function test_enter_on_bottom_line_scrolls_down()
App.screen.check(y, 'def', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc ', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting the page-up key the screen scrolls up to top
App.screen.check(y, 'jkl', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'screen:3')
end
function test_pageup_scrolls_up_from_middle_screen_line()
App.screen.check(y, 'def', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc ', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'mno', 'baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting the page-up key the screen scrolls up to top
App.screen.check(y, 'jkl', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:2')
end
function test_pageup_scrolls_up_by_screen_line()
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')
check_eq(Editor_state.cursor1.line, 1, 'cursor')
y = Editor_state.top
App.screen.check(y, 'ghi', 'baseline/screen:2')
-- after pageup the cursor goes to first line
App.screen.check(y, 'def', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:3')
end
function test_pageup()
App.screen.check(y, 'abc', 'screen:2')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')
check_eq(Editor_state.cursor1.line, 1, 'cursor')
y = Editor_state.top
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- after hitting the up arrow the screen scrolls up by one line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
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')
end
function test_up_arrow_scrolls_up_to_empty_line()
App.screen.check(y, 'ghi', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'mno', 'baseline/screen:3')
-- after hitting the up arrow the screen scrolls up to final screen line of previous line
App.screen.check(y, 'jkl', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'baseline/screen:1')
y = y + Editor_state.line_height
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')
end
function test_up_arrow_scrolls_up_to_final_screen_line()
App.screen.check(y, 'jkl', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi ', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'mno', 'baseline/screen:2')
-- after hitting the up arrow the screen scrolls up to first screen line
App.screen.check(y, 'jkl', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'screen:3')
end
function test_up_arrow_scrolls_up_by_one_screen_line()
App.screen.check(y, 'def', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')
check_eq(Editor_state.cursor1.line, 1, 'cursor')
y = Editor_state.top
App.screen.check(y, 'jkl', 'baseline/screen:3')
-- after hitting the up arrow the screen scrolls up by one line
App.screen.check(y, 'ghi', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'screen:3')
end
function test_up_arrow_scrolls_up_by_one_line()
App.screen.check(y, 'def', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')
check_eq(Editor_state.cursor1.line, 2, 'cursor')
-- the screen is unchanged
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- after hitting the up arrow the cursor moves up by 1 line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'mno', 'screen:3')
end
function test_up_arrow_moves_cursor()
App.screen.check(y, 'kl', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghij', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
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')
-- after hitting down arrow the screen doesn't scroll down further, and certainly doesn't scroll up
App.screen.check(y, 'ghij', 'baseline/screen:3')
-- after hitting pagedown the screen scrolls down to start of a long line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'kl', 'screen:3')
end
App.screen.check(y, 'ghij', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghij', 'baseline/screen:3')
-- after hitting the down arrow the screen scrolls down by one line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'jkl', 'screen:3')
end
function 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_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting the down arrow the screen scrolls down by one line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'jkl', 'screen:3')
end
function test_down_arrow_scrolls_down_by_one_screen_line()
App.screen.check(y, 'ghi', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')
check_eq(Editor_state.cursor1.line, 4, 'cursor')
y = Editor_state.top
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- after hitting the down arrow the screen scrolls down by one line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'screen:3')
end
function test_down_arrow_scrolls_down_by_one_line()
App.screen.check(y, 'def', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top')
check_eq(Editor_state.cursor1.line, 2, 'cursor')
-- the screen is unchanged
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- after hitting the down arrow, the cursor moves down by 1 line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')
check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')
end
App.screen.check(y, 'mno ', 'screen:3')
end
App.screen.check(y, 'jkl ', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi ', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'screen_top:line')
check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')
y = Editor_state.top
App.screen.check(y, 'ghi ', 'baseline/screen:3')
-- after pagedown we scroll down the very long wrapping line
App.screen.check(y, 'def ', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc ', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'jkl', 'screen:3')
end
App.screen.check(y, 'ghi ', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def ', 'screen:1')
y = y + Editor_state.line_height
check_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.top
App.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_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'screen:2')
end
function test_pagedown_skips_drawings()
App.screen.check(y, 'def', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 2, 'screen_top')
check_eq(Editor_state.cursor1.line, 2, 'cursor')
y = Editor_state.top
App.screen.check(y, 'def', 'baseline/screen:2')
-- after pagedown the bottom line becomes the top
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
check_nil(Editor_state.selection1.line, 'check')
end
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')
end
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')
end
function 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')
end
function test_select_text_using_mouse_and_shift()
App.screen.check(y, 'def', 'screen:3')
end
App.screen.check(y, 'zbc', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'axy', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- paste some text including a newline, check that new line is created
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
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')
end
function test_insert_from_clipboard()
App.screen.check(y, 'def', 'screen:3')
end
function test_insert_newline_at_start_of_line()
App.screen.check(y, 'bc', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'a', 'screen:1')
y = y + Editor_state.line_height
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')
y = Editor_state.top
App.screen.check(y, 'ghi', 'baseline/screen:3')
-- hitting the enter key splits the line
App.screen.check(y, 'def', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'fg', 'screen:3')
end
function test_insert_newline()
App.screen.check(y, 'de', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.screen_top1.line, 1, 'check')
check_eq(Editor_state.lines[1].data, 'ahi', 'data')
end
App.screen.check(y, 'jkl', 'baseline/screen:3')
-- set up a selection starting above the currently displayed page
App.screen.check(y, 'ghi', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'baseline/screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.lines[1].data, 'xyzdef', 'check')
end
check_eq(Editor_state.lines[1].data, 'bc', 'data')
end
function test_paste_replaces_selection()
check_eq(App.clipboard, 'a', 'clipboard')
-- selected text is deleted
check(Editor_state.selection1.line, 'check')
end
function test_cut()
check_eq(App.clipboard, 'a', 'clipboard')
-- selection is reset since shift key is not pressed
check_nil(Editor_state.selection1.line, 'check')
check_eq(Editor_state.lines[1].data, 'Dbc', 'data')
end
function test_copy_does_not_reset_selection()
check_eq(Editor_state.lines[1].data, 'xbc', 'check')
end
function test_edit_with_shift_key_deletes_selection()
check_nil(Editor_state.selection1.line, 'check')
check_eq(Editor_state.lines[1].data, 'abc', 'data')
end
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')
end
function test_cursor_movement_without_shift_resets_selection()
check_eq(Editor_state.cursor1.pos, 20, 'cursor')
end
function test_select_text()
App.screen.check(y, 'the quick brown fox ', 'baseline/screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-points
end
function test_click_past_end_of_word_wrapping_line()
App.screen.check(y, 'am', 'baseline/screen:3')
y = y + Editor_state.line_height
App.screen.check(y, 'I’m ad', 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'madam ', 'baseline/screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.cursor1.pos, 15, 'cursor') -- one more than the number of UTF-8 code-points
end
App.screen.check(y, 'am', 'baseline/screen:3')
y = y + Editor_state.line_height
App.screen.check(y, "I'm ad", 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'madam ', 'baseline/screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
end
App.screen.check(y, "I'm ad", 'baseline/screen:2')
y = y + Editor_state.line_height
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
end
App.screen.check(y, "I'm ad", 'baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'madam ', 'baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, '’m a', 'screen:3')
end
App.screen.check(y, 'am I', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'mad', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'ijk', 'screen:3')
end
function test_draw_wrapping_text_containing_non_ascii()
-- draw a long line containing non-ASCII
App.screen.check(y, 'e fgh', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abcd ', 'screen:1')
y = y + Editor_state.line_height
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')
end
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')
end
App.screen.check(y, 'ghi', 'screen:3')
end
App.screen.check(y, 'def ', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc ', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'fgh', 'screen:3')
end
function test_draw_word_wrapping_text()
App.screen.check(y, 'de', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'ghi', 'screen:3')
end
function test_draw_wrapping_text()
App.screen.check(y, 'def', 'screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'abc', 'screen:1')
y = y + Editor_state.line_height
check_eq(Editor_state.cursor1.line, 1, 'cursor')
end
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')
end
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')
end
check_nil(Editor_state.selection1.line, 'selection:line')
check_nil(Editor_state.selection1.pos, 'selection:pos')
end
check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
check_eq(Editor_state.cursor1.pos, 2, 'cursor:pos')
-- selection is empty to avoid perturbing future edits
check_eq(Editor_state.cursor1.line, 2, 'line')
check_eq(Editor_state.cursor1.pos, 4, 'pos')
end
check_eq(Editor_state.cursor1.pos, 9, 'check')
end
check_eq(Editor_state.cursor1.pos, 4, 'check')
end
check_eq(Editor_state.cursor1.pos, 8, 'check')
end
check_eq(Editor_state.cursor1.pos, 4, 'check')
end
function test_skip_to_next_word()
check_eq(Editor_state.cursor1.line, 1, 'line')
check_eq(Editor_state.cursor1.pos, 5, 'pos')
end
function test_move_past_end_of_word()
check_eq(Editor_state.cursor1.pos, 1, 'check')
end
function test_move_to_start_of_word_on_previous_line()
check_eq(Editor_state.cursor1.pos, 9, 'check')
end
function test_skip_multiple_spaces_to_previous_word()
check_eq(Editor_state.cursor1.pos, 1, 'check')
end
function test_skip_past_tab_to_previous_word()
check_eq(Editor_state.cursor1.pos, 1, 'check')
end
function test_skip_to_previous_word()
check_eq(Editor_state.cursor1.pos, 1, 'check')
end
function test_move_to_start_of_previous_word()
check_eq(Editor_state.cursor1.line, 2, 'line')
check_eq(Editor_state.cursor1.pos, 1, 'pos')
end
function 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 line
end
function test_move_right_to_next_line()
check_eq(Editor_state.cursor1.pos, 2, 'check')
end
check_eq(Editor_state.cursor1.pos, 1, 'check')
end
function test_move_right()
App.screen.check(y, 'a', 'screen:1')
end
function 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')
end
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')
end
function test_click_to_create_drawing()
check_eq(App.filesystem['foo'], 'abc\ndef\n', 'check')
end
check_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)
end
function 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')
end
function 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')
end
function 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 adjusted
check_eq(App.screen.width, 600, 'display:width')
-- left side margins are unchanged
check(Show_log_browser_side, 'check')
end
function test_show_log_browser_side_doubles_window_width_if_possible()
check(not Show_log_browser_side, 'baseline')
-- pressing ctrl+l shows log-browser side
check_eq(App.screen.width, 200, 'width')
check_eq(App.screen.height, 400, 'height')
check_eq(Editor_state.left, Margin_left, 'left_margin')
check_eq(Editor_state.right, 200-Margin_right, 'right_margin')
check_eq(Editor_state.width, 200-Margin_left-Margin_right, 'drawing_width')
-- 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')
end
function 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
end
function 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 drawing
edit.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 line
check_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-points
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-points
App.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 intermixed
local drawing_width = 50
App.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 15
Text.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 80px
edit.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 whitespace
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, '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 whitespace
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, '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 whitespace
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, '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 whitespace
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, '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 whitespace
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')
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 selection
App.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 cursor
edit.run_after_keychord(Editor_state, 'backspace')
end
function test_backspace_over_selection_reverse()
-- select just one character within a line with cursor after selection
App.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 character
edit.run_after_keychord(Editor_state, 'backspace')
end
function test_backspace_over_multiple_lines()
-- select just one character within a line with cursor after selection
App.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 side
edit.run_after_keychord(Editor_state, 'backspace')
end
function test_backspace_to_end_of_line()
-- select region from cursor to end of line
App.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 line
edit.run_after_keychord(Editor_state, 'backspace')
end
function test_backspace_to_start_of_line()
-- select region from cursor to start of line
App.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 line
edit.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.top
App.screen.check(y, 'abc', 'F - test_undo_delete_text/baseline/screen:1')
y = y + Editor_state.line_height
App.screen.check(y, 'def', 'F - test_undo_delete_text/baseline/screen:2')
y = y + Editor_state.line_height
App.screen.check(y, 'xyz', 'F - test_undo_delete_text/baseline/screen:3')
-- undo
--? -- after undo, the backspaced key is selected
edit.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.top
App.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 selected
edit.run_after_keychord(Editor_state, 'C-z')
-- display a line of text with some part selected
App.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')
end
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, '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 then
error('There were test failures:\n\n'..table.concat(Test_errors))
end