lines.love/text_tests.lua

1382 lines
61 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- major tests for text editing flows
function test_initial_state()
io.write('\ntest_initial_state')
App.screen.init{width=120, height=60}
Lines = load_array{}
App.draw()
check_eq(#Lines, 1, 'F - test_initial_state/#lines')
check_eq(Cursor1.line, 1, 'F - test_initial_state/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_initial_state/cursor:pos')
check_eq(Screen_top1.line, 1, 'F - test_initial_state/screen_top:line')
check_eq(Screen_top1.pos, 1, 'F - test_initial_state/screen_top:pos')
end
function test_click_to_create_drawing()
io.write('\ntest_click_to_create_drawing')
App.screen.init{width=120, height=60}
Lines = load_array{}
App.draw()
App.run_after_mouse_click(8,Margin_top+8, 1)
-- cursor skips drawing to always remain on text
check_eq(#Lines, 2, 'F - test_click_to_create_drawing/#lines')
check_eq(Cursor1.line, 2, 'F - test_click_to_create_drawing/cursor')
end
function test_backspace_to_delete_drawing()
io.write('\ntest_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}
Lines = load_array{'```lines', '```', ''}
-- cursor is on text as always (outside tests this will get initialized correctly)
Cursor1.line = 2
-- backspacing deletes the drawing
App.run_after_keychord('backspace')
check_eq(#Lines, 1, 'F - test_backspace_to_delete_drawing/#lines')
check_eq(Cursor1.line, 1, 'F - test_backspace_to_delete_drawing/cursor')
end
function test_insert_first_character()
io.write('\ntest_insert_first_character')
App.screen.init{width=120, height=60}
Lines = load_array{}
App.draw()
App.run_after_textinput('a')
local y = Margin_top
App.screen.check(y, 'a', 'F - test_insert_first_character/screen:1')
end
function test_press_ctrl()
io.write('\ntest_press_ctrl')
-- press ctrl while the cursor is on text
App.screen.init{width=50, height=80}
Lines = load_array{''}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.run_after_keychord('C-m')
end
function test_click_with_mouse()
io.write('\ntest_click_with_mouse')
-- display two lines with cursor on one of them
App.screen.init{width=50, height=80}
Lines = load_array{'abc', 'def'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
-- click on the other line
App.draw()
App.run_after_mouse_click(Margin_left+8,Margin_top+5, 1)
-- cursor moves
check_eq(Cursor1.line, 1, 'F - test_click_with_mouse/cursor')
end
function test_draw_text()
io.write('\ntest_draw_text')
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'def', 'ghi'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_draw_text/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_draw_text/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_draw_text/screen:3')
end
function test_draw_wrapping_text()
io.write('\ntest_draw_wrapping_text')
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'defgh', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_draw_wrapping_text/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_draw_wrapping_text/screen:2')
y = y + Line_height
App.screen.check(y, 'gh', 'F - test_draw_wrapping_text/screen:3')
end
function test_draw_word_wrapping_text()
io.write('\ntest_draw_word_wrapping_text')
App.screen.init{width=60, height=60}
Lines = load_array{'abc def ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc ', 'F - test_draw_word_wrapping_text/screen:1')
y = y + Line_height
App.screen.check(y, 'def ', 'F - test_draw_word_wrapping_text/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_draw_word_wrapping_text/screen:3')
end
function test_draw_text_wrapping_within_word()
-- arrange a screen line that needs to be split within a word
io.write('\ntest_draw_text_wrapping_within_word')
App.screen.init{width=60, height=60}
Lines = load_array{'abcd e fghijk', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abcd ', 'F - test_draw_text_wrapping_within_word/screen:1')
y = y + Line_height
App.screen.check(y, 'e fghi', 'F - test_draw_text_wrapping_within_word/screen:2')
y = y + Line_height
App.screen.check(y, 'jk', 'F - test_draw_text_wrapping_within_word/screen:3')
end
function test_draw_wrapping_text_containing_non_ascii()
-- draw a long line containing non-ASCII
io.write('\ntest_draw_wrapping_text_containing_non_ascii')
App.screen.init{width=60, height=60}
Lines = load_array{'madam Im adam', 'xyz'} -- notice the non-ASCII apostrophe
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'mada', 'F - test_draw_wrapping_text_containing_non_ascii/screen:1')
y = y + Line_height
App.screen.check(y, 'm I', 'F - test_draw_wrapping_text_containing_non_ascii/screen:2')
y = y + Line_height
App.screen.check(y, 'm ad', 'F - test_draw_wrapping_text_containing_non_ascii/screen:3')
end
function test_click_on_wrapping_line_containing_non_ascii()
io.write('\ntest_click_on_wrapping_line_containing_non_ascii')
-- display a wrapping line containing non-ASCII
App.screen.init{width=80, height=80}
-- 12345678901234
Lines = load_array{'madam Im adam'} -- notice the non-ASCII apostrophe
Line_width = 75
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'madam ', 'F - test_click_on_wrapping_line_containing_non_ascii/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'Im ada', 'F - test_click_on_wrapping_line_containing_non_ascii/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'm', 'F - test_click_on_wrapping_line_containing_non_ascii/baseline/screen:3')
y = y + Line_height
-- click past the end of it
App.draw()
App.run_after_mouse_click(App.screen.width-2,y-2, 1)
-- cursor moves to end of line
check_eq(Cursor1.pos, 15, 'F - test_click_on_wrapping_line_containing_non_ascii/cursor') -- one more than the number of UTF-8 code-points
end
function test_select_text()
io.write('\ntest_select_text')
-- display a line of text
App.screen.init{width=80, height=80}
Lines = load_array{'abc def'}
Line_width = 75
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
-- select a letter
App.fake_key_press('lshift')
App.run_after_keychord('S-right')
App.fake_key_release('lshift')
App.keyreleased('lshift')
-- selection persists even after shift is released
check_eq(Selection1.line, 1, 'F - test_select_text/selection:line')
check_eq(Selection1.pos, 1, 'F - test_select_text/selection:pos')
check_eq(Cursor1.line, 1, 'F - test_select_text/cursor:line')
check_eq(Cursor1.pos, 2, 'F - test_select_text/cursor:pos')
end
function test_edit_after_click_resets_selection()
io.write('\ntest_edit_after_click_resets_selection')
-- display a line of text
App.screen.init{width=80, height=80}
Lines = load_array{'abc'}
Line_width = 75
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
-- click past the end of it and hit enter
App.run_after_mouse_click(Margin_left+40,Margin_top+5, 1)
check(Selection1.line, 'F - test_edit_after_click_resets_selection/baseline')
App.run_after_keychord('return')
-- selection is reset since shift key is not pressed
check_nil(Selection1.line, 'F - test_edit_after_click_resets_selection')
end
function test_edit_deletes_selection()
io.write('\ntest_edit_deletes_selection')
-- display a line of text with some part selected
App.screen.init{width=80, height=80}
Lines = load_array{'abc'}
Line_width = 75
Cursor1 = {line=1, pos=1}
Selection1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
-- press a key
App.run_after_textinput('x')
-- selected text is deleted and replaced with the key
check_eq(Lines[1].data, 'xbc', 'F - test_edit_deletes_selection')
end
function test_copy_does_not_reset_selection()
io.write('\ntest_copy_does_not_reset_selection')
-- display a line of text with a selection
App.screen.init{width=80, height=80}
Lines = load_array{'abc'}
Line_width = 75
Cursor1 = {line=1, pos=1}
Selection1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
-- copy selection
App.run_after_keychord('C-c')
check_eq(App.clipboard, 'a', 'F - test_copy_does_not_reset_selection/clipboard')
-- selection is reset since shift key is not pressed
check(Selection1.line, 'F - test_copy_does_not_reset_selection')
end
function test_cut()
io.write('\ntest_cut')
-- display a line of text with some part selected
App.screen.init{width=80, height=80}
Lines = load_array{'abc'}
Line_width = 75
Cursor1 = {line=1, pos=1}
Selection1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
-- press a key
App.run_after_keychord('C-x')
check_eq(App.clipboard, 'a', 'F - test_cut/clipboard')
-- selected text is deleted
check_eq(Lines[1].data, 'bc', 'F - test_cut/data')
end
function test_paste_replaces_selection()
io.write('\ntest_paste_replaces_selection')
-- display a line of text with a selection
App.screen.init{width=80, height=80}
Lines = load_array{'abc', 'def'}
Line_width = 75
Cursor1 = {line=2, pos=1}
Selection1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
-- set clipboard
App.clipboard = 'xyz'
-- paste selection
App.run_after_keychord('C-v')
-- selection is reset since shift key is not pressed
-- selection includes the newline, so it's also deleted
check_eq(Lines[1].data, 'xyzdef', 'F - test_paste_replaces_selection')
end
function test_edit_wrapping_text()
io.write('\ntest_edit_wrapping_text')
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'def', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=4}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
App.run_after_textinput('g')
App.run_after_textinput('h')
App.run_after_textinput('i')
App.run_after_textinput('j')
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_edit_wrapping_text/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_edit_wrapping_text/screen:2')
y = y + Line_height
App.screen.check(y, 'ghij', 'F - test_edit_wrapping_text/screen:3')
end
function test_insert_newline()
io.write('\ntest_insert_newline')
-- display a few lines
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_insert_newline/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_insert_newline/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_insert_newline/baseline/screen:3')
-- hitting the enter key splits the line
App.run_after_keychord('return')
check_eq(Screen_top1.line, 1, 'F - test_insert_newline/screen_top')
check_eq(Cursor1.line, 2, 'F - test_insert_newline/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_insert_newline/cursor:pos')
y = Margin_top
App.screen.check(y, 'a', 'F - test_insert_newline/screen:1')
y = y + Line_height
App.screen.check(y, 'bc', 'F - test_insert_newline/screen:2')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_insert_newline/screen:3')
end
function test_insert_newline_at_start_of_line()
io.write('\ntest_insert_newline_at_start_of_line')
-- display a line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
-- hitting the enter key splits the line
App.run_after_keychord('return')
check_eq(Cursor1.line, 2, 'F - test_insert_newline_at_start_of_line/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_insert_newline_at_start_of_line/cursor:pos')
check_eq(Lines[1].data, '', 'F - test_insert_newline_at_start_of_line/data:1')
check_eq(Lines[2].data, 'abc', 'F - test_insert_newline_at_start_of_line/data:2')
end
function test_insert_from_clipboard()
io.write('\ntest_insert_from_clipboard')
-- display a few lines
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_insert_from_clipboard/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_insert_from_clipboard/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_insert_from_clipboard/baseline/screen:3')
-- paste some text including a newline, check that new line is created
App.clipboard = 'xy\nz'
App.run_after_keychord('C-v')
check_eq(Screen_top1.line, 1, 'F - test_insert_from_clipboard/screen_top')
check_eq(Cursor1.line, 2, 'F - test_insert_from_clipboard/cursor:line')
check_eq(Cursor1.pos, 2, 'F - test_insert_from_clipboard/cursor:pos')
y = Margin_top
App.screen.check(y, 'axy', 'F - test_insert_from_clipboard/screen:1')
y = y + Line_height
App.screen.check(y, 'zbc', 'F - test_insert_from_clipboard/screen:2')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_insert_from_clipboard/screen:3')
end
function test_move_cursor_using_mouse()
io.write('\ntest_move_cursor_using_mouse')
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'def', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
Selection1 = {}
App.draw() -- populate line.y for each line in Lines
App.run_after_mouse_release(Margin_left+8,Margin_top+5, 1)
check_eq(Cursor1.line, 1, 'F - test_move_cursor_using_mouse/cursor:line')
check_eq(Cursor1.pos, 2, 'F - test_move_cursor_using_mouse/cursor:pos')
check_nil(Selection1.line, 'F - test_move_cursor_using_mouse/selection:line')
check_nil(Selection1.pos, 'F - test_move_cursor_using_mouse/selection:pos')
end
function test_select_text_using_mouse()
io.write('\ntest_select_text_using_mouse')
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'def', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
Selection1 = {}
App.draw() -- populate line.y for each line in Lines
-- press and hold on first location
App.run_after_mouse_press(Margin_left+8,Margin_top+5, 1)
-- drag and release somewhere else
App.run_after_mouse_release(Margin_left+20,Margin_top+Line_height+5, 1)
check_eq(Selection1.line, 1, 'F - test_select_text_using_mouse/selection:line')
check_eq(Selection1.pos, 2, 'F - test_select_text_using_mouse/selection:pos')
check_eq(Cursor1.line, 2, 'F - test_select_text_using_mouse/cursor:line')
check_eq(Cursor1.pos, 4, 'F - test_select_text_using_mouse/cursor:pos')
end
function test_select_text_using_mouse_and_shift()
io.write('\ntest_select_text_using_mouse_and_shift')
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'def', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
Selection1 = {}
App.draw() -- populate line.y for each line in Lines
-- click on first location
App.run_after_mouse_press(Margin_left+8,Margin_top+5, 1)
App.run_after_mouse_release(Margin_left+8,Margin_top+5, 1)
-- hold down shift and click somewhere else
App.fake_key_press('lshift')
App.run_after_mouse_press(Margin_left+20,Margin_top+5, 1)
App.run_after_mouse_release(Margin_left+20,Margin_top+Line_height+5, 1)
App.fake_key_release('lshift')
check_eq(Selection1.line, 1, 'F - test_select_text_using_mouse_and_shift/selection:line')
check_eq(Selection1.pos, 2, 'F - test_select_text_using_mouse_and_shift/selection:pos')
check_eq(Cursor1.line, 2, 'F - test_select_text_using_mouse_and_shift/cursor:line')
check_eq(Cursor1.pos, 4, 'F - test_select_text_using_mouse_and_shift/cursor:pos')
end
function test_select_text_repeatedly_using_mouse_and_shift()
io.write('\ntest_select_text_repeatedly_using_mouse_and_shift')
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'def', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
Selection1 = {}
App.draw() -- populate line.y for each line in Lines
-- click on first location
App.run_after_mouse_press(Margin_left+8,Margin_top+5, 1)
App.run_after_mouse_release(Margin_left+8,Margin_top+5, 1)
-- hold down shift and click on a second location
App.fake_key_press('lshift')
App.run_after_mouse_press(Margin_left+20,Margin_top+5, 1)
App.run_after_mouse_release(Margin_left+20,Margin_top+Line_height+5, 1)
-- hold down shift and click at a third location
App.fake_key_press('lshift')
App.run_after_mouse_press(Margin_left+20,Margin_top+5, 1)
App.run_after_mouse_release(Margin_left+8,Margin_top+Line_height+5, 1)
App.fake_key_release('lshift')
-- selection is between first and third location. forget the second location, not the first.
check_eq(Selection1.line, 1, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:line')
check_eq(Selection1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:pos')
check_eq(Cursor1.line, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:line')
check_eq(Cursor1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:pos')
end
function test_cut_without_selection()
io.write('\ntest_cut_without_selection')
-- display a few lines
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
Selection1 = {}
App.draw()
-- try to cut without selecting text
App.run_after_keychord('C-x')
-- no crash
check_nil(Selection1.line, 'F - test_cut_without_selection')
end
function test_pagedown()
io.write('\ntest_pagedown')
App.screen.init{width=120, height=45}
Lines = load_array{'abc', 'def', 'ghi'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
-- initially the first two lines are displayed
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_pagedown/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_pagedown/baseline/screen:2')
-- after pagedown the bottom line becomes the top
App.run_after_keychord('pagedown')
check_eq(Screen_top1.line, 2, 'F - test_pagedown/screen_top')
check_eq(Cursor1.line, 2, 'F - test_pagedown/cursor')
y = Margin_top
App.screen.check(y, 'def', 'F - test_pagedown/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_pagedown/screen:2')
end
function test_pagedown_skips_drawings()
io.write('\ntest_pagedown_skips_drawings')
-- some lines of text with a drawing intermixed
local drawing_width = 50
App.screen.init{width=Margin_left+drawing_width, height=80}
Lines = load_array{'abc', -- height 15
'```lines', '```', -- height 25
'def', -- height 15
'ghi'} -- height 15
check_eq(Lines[2].mode, 'drawing', 'F - test_pagedown_skips_drawings/baseline/lines')
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
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
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_pagedown_skips_drawings/baseline/screen:1')
-- after pagedown the screen draws the drawing up top
-- 15px margin + 10px margin + 25px drawing + 10px margin + 15px line3 = 75px < screen height 80px
App.run_after_keychord('pagedown')
check_eq(Screen_top1.line, 2, 'F - test_pagedown_skips_drawings/screen_top')
check_eq(Cursor1.line, 3, 'F - test_pagedown_skips_drawings/cursor')
y = Margin_top + drawing_height
App.screen.check(y, 'def', 'F - test_pagedown_skips_drawings/screen:1')
end
function test_pagedown_often_shows_start_of_wrapping_line()
io.write('\ntest_pagedown_often_shows_start_of_wrapping_line')
-- draw a few lines ending in part of a wrapping line
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'def ghi jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def ', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi ', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:3')
-- after pagedown we start drawing from the bottom _line_ (multiple screen lines)
App.run_after_keychord('pagedown')
check_eq(Screen_top1.line, 2, 'F - test_pagedown_often_shows_start_of_wrapping_line/screen_top:line')
check_eq(Screen_top1.pos, 1, 'F - test_pagedown_often_shows_start_of_wrapping_line/screen_top:pos')
check_eq(Cursor1.line, 2, 'F - test_pagedown_often_shows_start_of_wrapping_line/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_pagedown_often_shows_start_of_wrapping_line/cursor:pos')
y = Margin_top
App.screen.check(y, 'def ', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi ', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:2')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:3')
end
function test_pagedown_can_start_from_middle_of_long_wrapping_line()
io.write('\ntest_pagedown_can_start_from_middle_of_long_wrapping_line')
-- draw a few lines starting from a very long wrapping line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc def ghi jkl mno pqr stu vwx yza bcd efg hij', 'XYZ'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:3')
-- after pagedown we scroll down the very long wrapping line
App.run_after_keychord('pagedown')
check_eq(Screen_top1.line, 1, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:line')
check_eq(Screen_top1.pos, 9, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:pos')
y = Margin_top
App.screen.check(y, 'ghi ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:1')
y = y + Line_height
App.screen.check(y, 'jkl m', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:2')
y = y + Line_height
App.screen.check(y, 'no ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:3')
end
function test_down_arrow_moves_cursor()
io.write('\ntest_down_arrow_moves_cursor')
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
-- initially the first three lines are displayed
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_down_arrow_moves_cursor/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_down_arrow_moves_cursor/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_down_arrow_moves_cursor/baseline/screen:3')
-- after hitting the down arrow, the cursor moves down by 1 line
App.run_after_keychord('down')
check_eq(Screen_top1.line, 1, 'F - test_down_arrow_moves_cursor/screen_top')
check_eq(Cursor1.line, 2, 'F - test_down_arrow_moves_cursor/cursor')
-- the screen is unchanged
y = Margin_top
App.screen.check(y, 'abc', 'F - test_down_arrow_moves_cursor/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_down_arrow_moves_cursor/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_down_arrow_moves_cursor/screen:3')
end
function test_down_arrow_scrolls_down_by_one_line()
io.write('\ntest_down_arrow_scrolls_down_by_one_line')
-- display the first three lines with the cursor on the bottom line
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_down_arrow_scrolls_down_by_one_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_down_arrow_scrolls_down_by_one_line/baseline/screen:3')
-- after hitting the down arrow the screen scrolls down by one line
App.run_after_keychord('down')
check_eq(Screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_line/screen_top')
check_eq(Cursor1.line, 4, 'F - test_down_arrow_scrolls_down_by_one_line/cursor')
y = Margin_top
App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_line/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_down_arrow_scrolls_down_by_one_line/screen:2')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_down_arrow_scrolls_down_by_one_line/screen:3')
end
function test_down_arrow_scrolls_down_by_one_screen_line()
io.write('\ntest_down_arrow_scrolls_down_by_one_screen_line')
-- display the first three lines with the cursor on the bottom line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_down_arrow_scrolls_down_by_one_screen_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi ', 'F - test_down_arrow_scrolls_down_by_one_screen_line/baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting the down arrow the screen scrolls down by one line
App.run_after_keychord('down')
check_eq(Screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen_top')
check_eq(Cursor1.line, 3, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:line')
check_eq(Cursor1.pos, 5, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:pos')
y = Margin_top
App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi ', 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen:2')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen:3')
end
function test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word()
io.write('\ntest_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word')
-- display the first three lines with the cursor on the bottom line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghijkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghijk', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/baseline/screen:3')
-- after hitting the down arrow the screen scrolls down by one line
App.run_after_keychord('down')
check_eq(Screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen_top')
check_eq(Cursor1.line, 3, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/cursor:line')
check_eq(Cursor1.pos, 6, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/cursor:pos')
y = Margin_top
App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen:1')
y = y + Line_height
App.screen.check(y, 'ghijk', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen:2')
y = y + Line_height
App.screen.check(y, 'l', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen:3')
end
function test_page_down_followed_by_down_arrow_does_not_scroll_screen_up()
io.write('\ntest_page_down_followed_by_down_arrow_does_not_scroll_screen_up')
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghijkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghijk', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline/screen:3')
-- after hitting pagedown the screen scrolls down to start of a long line
App.run_after_keychord('pagedown')
check_eq(Screen_top1.line, 3, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline2/screen_top')
check_eq(Cursor1.line, 3, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline2/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline2/cursor:pos')
-- after hitting down arrow the screen doesn't scroll down further, and certainly doesn't scroll up
App.run_after_keychord('down')
check_eq(Screen_top1.line, 3, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/screen_top')
check_eq(Cursor1.line, 3, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/cursor:line')
check_eq(Cursor1.pos, 6, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/cursor:pos')
y = Margin_top
App.screen.check(y, 'ghijk', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/screen:1')
y = y + Line_height
App.screen.check(y, 'l', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/screen:2')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/screen:3')
end
function test_up_arrow_moves_cursor()
io.write('\ntest_up_arrow_moves_cursor')
-- display the first 3 lines with the cursor on the bottom line
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = 120
Cursor1 = {line=3, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_up_arrow_moves_cursor/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_up_arrow_moves_cursor/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_up_arrow_moves_cursor/baseline/screen:3')
-- after hitting the up arrow the cursor moves up by 1 line
App.run_after_keychord('up')
check_eq(Screen_top1.line, 1, 'F - test_up_arrow_moves_cursor/screen_top')
check_eq(Cursor1.line, 2, 'F - test_up_arrow_moves_cursor/cursor')
-- the screen is unchanged
y = Margin_top
App.screen.check(y, 'abc', 'F - test_up_arrow_moves_cursor/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_up_arrow_moves_cursor/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_up_arrow_moves_cursor/screen:3')
end
function test_up_arrow_scrolls_up_by_one_line()
io.write('\ntest_up_arrow_scrolls_up_by_one_line')
-- display the lines 2/3/4 with the cursor on line 2
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = 120
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_by_one_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_by_one_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_by_one_line/baseline/screen:3')
-- after hitting the up arrow the screen scrolls up by one line
App.run_after_keychord('up')
check_eq(Screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_by_one_line/screen_top')
check_eq(Cursor1.line, 1, 'F - test_up_arrow_scrolls_up_by_one_line/cursor')
y = Margin_top
App.screen.check(y, 'abc', 'F - test_up_arrow_scrolls_up_by_one_line/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_by_one_line/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_by_one_line/screen:3')
end
function test_up_arrow_scrolls_up_by_one_screen_line()
io.write('\ntest_up_arrow_scrolls_up_by_one_screen_line')
-- display lines starting from second screen line of a line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=6}
Screen_top1 = {line=3, pos=5}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_by_one_screen_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_up_arrow_scrolls_up_by_one_screen_line/baseline/screen:2')
-- after hitting the up arrow the screen scrolls up to first screen line
App.run_after_keychord('up')
y = Margin_top
App.screen.check(y, 'ghi ', 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen:1')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen:2')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen:3')
check_eq(Screen_top1.line, 3, 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen_top')
check_eq(Screen_top1.pos, 1, 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen_top')
check_eq(Cursor1.line, 3, 'F - test_up_arrow_scrolls_up_by_one_screen_line/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_up_arrow_scrolls_up_by_one_screen_line/cursor:pos')
end
function test_up_arrow_scrolls_up_to_final_screen_line()
io.write('\ntest_up_arrow_scrolls_up_to_final_screen_line')
-- display lines starting just after a long line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:3')
-- after hitting the up arrow the screen scrolls up to final screen line of previous line
App.run_after_keychord('up')
y = Margin_top
App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:2')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:3')
check_eq(Screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen_top')
check_eq(Screen_top1.pos, 5, 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen_top')
check_eq(Cursor1.line, 1, 'F - test_up_arrow_scrolls_up_to_final_screen_line/cursor:line')
check_eq(Cursor1.pos, 5, 'F - test_up_arrow_scrolls_up_to_final_screen_line/cursor:pos')
end
function test_up_arrow_scrolls_up_to_empty_line()
io.write('\ntest_up_arrow_scrolls_up_to_empty_line')
-- display a screenful of text with an empty line just above it outside the screen
App.screen.init{width=120, height=60}
Lines = load_array{'', 'abc', 'def', 'ghi', 'jkl'}
Line_width = 120
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_up_arrow_scrolls_up_to_empty_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_to_empty_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_to_empty_line/baseline/screen:3')
-- after hitting the up arrow the screen scrolls up by one line
App.run_after_keychord('up')
check_eq(Screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_to_empty_line/screen_top')
check_eq(Cursor1.line, 1, 'F - test_up_arrow_scrolls_up_to_empty_line/cursor')
y = Margin_top
-- empty first line
y = y + Line_height
App.screen.check(y, 'abc', 'F - test_up_arrow_scrolls_up_to_empty_line/screen:2')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_to_empty_line/screen:3')
end
function test_pageup()
io.write('\ntest_pageup')
App.screen.init{width=120, height=45}
Lines = load_array{'abc', 'def', 'ghi'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
-- initially the last two lines are displayed
App.draw()
local y = Margin_top
App.screen.check(y, 'def', 'F - test_pageup/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_pageup/baseline/screen:2')
-- after pageup the cursor goes to first line
App.run_after_keychord('pageup')
check_eq(Screen_top1.line, 1, 'F - test_pageup/screen_top')
check_eq(Cursor1.line, 1, 'F - test_pageup/cursor')
y = Margin_top
App.screen.check(y, 'abc', 'F - test_pageup/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_pageup/screen:2')
end
function test_pageup_scrolls_up_by_screen_line()
io.write('\ntest_pageup_scrolls_up_by_screen_line')
-- display the first three lines with the cursor on the bottom line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'ghi', 'F - test_pageup_scrolls_up_by_screen_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_pageup_scrolls_up_by_screen_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_pageup_scrolls_up_by_screen_line/baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting the page-up key the screen scrolls up to top
App.run_after_keychord('pageup')
check_eq(Screen_top1.line, 1, 'F - test_pageup_scrolls_up_by_screen_line/screen_top')
check_eq(Cursor1.line, 1, 'F - test_pageup_scrolls_up_by_screen_line/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_pageup_scrolls_up_by_screen_line/cursor:pos')
y = Margin_top
App.screen.check(y, 'abc ', 'F - test_pageup_scrolls_up_by_screen_line/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_pageup_scrolls_up_by_screen_line/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_pageup_scrolls_up_by_screen_line/screen:3')
end
function test_pageup_scrolls_up_from_middle_screen_line()
io.write('\ntest_pageup_scrolls_up_from_middle_screen_line')
-- display a few lines starting from the middle of a line (Cursor1.pos > 1)
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc def', 'ghi jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=5}
Screen_top1 = {line=2, pos=5}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'jkl', 'F - test_pageup_scrolls_up_from_middle_screen_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_pageup_scrolls_up_from_middle_screen_line/baseline/screen:3') -- line wrapping includes trailing whitespace
-- after hitting the page-up key the screen scrolls up to top
App.run_after_keychord('pageup')
check_eq(Screen_top1.line, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/screen_top')
check_eq(Cursor1.line, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/cursor:pos')
y = Margin_top
App.screen.check(y, 'abc ', 'F - test_pageup_scrolls_up_from_middle_screen_line/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_pageup_scrolls_up_from_middle_screen_line/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi ', 'F - test_pageup_scrolls_up_from_middle_screen_line/screen:3')
end
function test_enter_on_bottom_line_scrolls_down()
io.write('\ntest_enter_on_bottom_line_scrolls_down')
-- display a few lines with cursor on bottom line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_enter_on_bottom_line_scrolls_down/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_enter_on_bottom_line_scrolls_down/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_enter_on_bottom_line_scrolls_down/baseline/screen:3')
-- after hitting the enter key the screen scrolls down
App.run_after_keychord('return')
check_eq(Screen_top1.line, 2, 'F - test_enter_on_bottom_line_scrolls_down/screen_top')
check_eq(Cursor1.line, 4, 'F - test_enter_on_bottom_line_scrolls_down/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_enter_on_bottom_line_scrolls_down/cursor:pos')
y = Margin_top
App.screen.check(y, 'def', 'F - test_enter_on_bottom_line_scrolls_down/screen:1')
y = y + Line_height
App.screen.check(y, 'g', 'F - test_enter_on_bottom_line_scrolls_down/screen:2')
y = y + Line_height
App.screen.check(y, 'hi', 'F - test_enter_on_bottom_line_scrolls_down/screen:3')
end
function test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom()
io.write('\ntest_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom')
-- display just the bottom line on screen
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=4, pos=2}
Screen_top1 = {line=4, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'jkl', 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/baseline/screen:1')
-- after hitting the enter key the screen does not scroll down
App.run_after_keychord('return')
check_eq(Screen_top1.line, 4, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen_top')
check_eq(Cursor1.line, 5, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:pos')
y = Margin_top
App.screen.check(y, 'j', 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen:1')
y = y + Line_height
App.screen.check(y, 'kl', 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen:2')
end
function test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom()
io.write('\ntest_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom')
-- display just an empty bottom line on screen
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', ''}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
App.draw()
-- after hitting the inserting_text key the screen does not scroll down
App.run_after_textinput('a')
check_eq(Screen_top1.line, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen_top')
check_eq(Cursor1.line, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:line')
check_eq(Cursor1.pos, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:pos')
local y = Margin_top
App.screen.check(y, 'a', 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen:1')
end
function test_typing_on_bottom_line_scrolls_down()
io.write('\ntest_typing_on_bottom_line_scrolls_down')
-- display a few lines with cursor on bottom line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=4}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_typing_on_bottom_line_scrolls_down/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_typing_on_bottom_line_scrolls_down/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_typing_on_bottom_line_scrolls_down/baseline/screen:3')
-- after typing something the line wraps and the screen scrolls down
App.run_after_textinput('j')
App.run_after_textinput('k')
App.run_after_textinput('l')
check_eq(Screen_top1.line, 2, 'F - test_typing_on_bottom_line_scrolls_down/screen_top')
check_eq(Cursor1.line, 3, 'F - test_typing_on_bottom_line_scrolls_down/cursor:line')
check_eq(Cursor1.pos, 7, 'F - test_typing_on_bottom_line_scrolls_down/cursor:pos')
y = Margin_top
App.screen.check(y, 'def', 'F - test_typing_on_bottom_line_scrolls_down/screen:1')
y = y + Line_height
App.screen.check(y, 'ghijk', 'F - test_typing_on_bottom_line_scrolls_down/screen:2')
y = y + Line_height
App.screen.check(y, 'l', 'F - test_typing_on_bottom_line_scrolls_down/screen:3')
end
function test_position_cursor_on_recently_edited_wrapping_line()
-- draw a line wrapping over 2 screen lines
io.write('\ntest_position_cursor_on_recently_edited_wrapping_line')
App.screen.init{width=120, height=200}
Lines = load_array{'abc def ghi jkl mno pqr ', 'xyz'}
Line_width = 100
Cursor1 = {line=1, pos=25}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc def ghi ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline1/screen:1')
y = y + Line_height
App.screen.check(y, 'jkl mno pqr ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline1/screen:2')
y = y + Line_height
App.screen.check(y, 'xyz', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline1/screen:3')
-- add to the line until it's wrapping over 3 screen lines
App.run_after_textinput('s')
App.run_after_textinput('t')
App.run_after_textinput('u')
check_eq(Cursor1.pos, 28, 'F - test_move_cursor_using_mouse/cursor:pos')
y = Margin_top
App.screen.check(y, 'abc def ghi ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline2/screen:1')
y = y + Line_height
App.screen.check(y, 'jkl mno pqr ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline2/screen:2')
y = y + Line_height
App.screen.check(y, 'stu', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline2/screen:3')
-- try to move the cursor earlier in the third screen line by clicking the mouse
App.run_after_mouse_release(Margin_left+8,Margin_top+Line_height*2+5, 1)
-- cursor should move
check_eq(Cursor1.line, 1, 'F - test_move_cursor_using_mouse/cursor:line')
check_eq(Cursor1.pos, 26, 'F - test_move_cursor_using_mouse/cursor:pos')
end
function test_backspace_can_scroll_up()
io.write('\ntest_backspace_can_scroll_up')
-- display the lines 2/3/4 with the cursor on line 2
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl'}
Line_width = 120
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'def', 'F - test_backspace_can_scroll_up/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_backspace_can_scroll_up/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_backspace_can_scroll_up/baseline/screen:3')
-- after hitting backspace the screen scrolls up by one line
App.run_after_keychord('backspace')
check_eq(Screen_top1.line, 1, 'F - test_backspace_can_scroll_up/screen_top')
check_eq(Cursor1.line, 1, 'F - test_backspace_can_scroll_up/cursor')
y = Margin_top
App.screen.check(y, 'abcdef', 'F - test_backspace_can_scroll_up/screen:1')
y = y + Line_height
App.screen.check(y, 'ghi', 'F - test_backspace_can_scroll_up/screen:2')
y = y + Line_height
App.screen.check(y, 'jkl', 'F - test_backspace_can_scroll_up/screen:3')
end
function test_backspace_can_scroll_up_screen_line()
io.write('\ntest_backspace_can_scroll_up_screen_line')
-- display lines starting from second screen line of a line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=3, pos=5}
Screen_top1 = {line=3, pos=5}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'jkl', 'F - test_backspace_can_scroll_up_screen_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_backspace_can_scroll_up_screen_line/baseline/screen:2')
-- after hitting backspace the screen scrolls up by one screen line
App.run_after_keychord('backspace')
y = Margin_top
App.screen.check(y, 'ghijk', 'F - test_backspace_can_scroll_up_screen_line/screen:1')
y = y + Line_height
App.screen.check(y, 'l', 'F - test_backspace_can_scroll_up_screen_line/screen:2')
y = y + Line_height
App.screen.check(y, 'mno', 'F - test_backspace_can_scroll_up_screen_line/screen:3')
check_eq(Screen_top1.line, 3, 'F - test_backspace_can_scroll_up_screen_line/screen_top')
check_eq(Screen_top1.pos, 1, 'F - test_backspace_can_scroll_up_screen_line/screen_top')
check_eq(Cursor1.line, 3, 'F - test_backspace_can_scroll_up_screen_line/cursor:line')
check_eq(Cursor1.pos, 4, 'F - test_backspace_can_scroll_up_screen_line/cursor:pos')
end
function test_backspace_past_line_boundary()
io.write('\ntest_backspace_past_line_boundary')
-- position cursor at start of a (non-first) line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
-- backspace joins with previous line
App.run_after_keychord('backspace')
check_eq(Lines[1].data, 'abcdef', "F - test_backspace_past_line_boundary")
end
-- some tests for operating over selections created using Shift- chords
-- we're just testing delete_selection, and it works the same for all keys
function test_backspace_over_selection()
io.write('\ntest_backspace_over_selection')
-- select just one character within a line with cursor before selection
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Selection1 = {line=1, pos=2}
-- backspace deletes the selected character, even though it's after the cursor
App.run_after_keychord('backspace')
check_eq(Lines[1].data, 'bc', "F - test_backspace_over_selection/data")
-- cursor (remains) at start of selection
check_eq(Cursor1.line, 1, "F - test_backspace_over_selection/cursor:line")
check_eq(Cursor1.pos, 1, "F - test_backspace_over_selection/cursor:pos")
-- selection is cleared
check_nil(Selection1.line, "F - test_backspace_over_selection/selection")
end
function test_backspace_over_selection_reverse()
io.write('\ntest_backspace_over_selection_reverse')
-- select just one character within a line with cursor after selection
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Selection1 = {line=1, pos=1}
-- backspace deletes the selected character
App.run_after_keychord('backspace')
check_eq(Lines[1].data, 'bc', "F - test_backspace_over_selection_reverse/data")
-- cursor moves to start of selection
check_eq(Cursor1.line, 1, "F - test_backspace_over_selection_reverse/cursor:line")
check_eq(Cursor1.pos, 1, "F - test_backspace_over_selection_reverse/cursor:pos")
-- selection is cleared
check_nil(Selection1.line, "F - test_backspace_over_selection_reverse/selection")
end
function test_backspace_over_multiple_lines()
io.write('\ntest_backspace_over_multiple_lines')
-- select just one character within a line with cursor after selection
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Selection1 = {line=4, pos=2}
-- backspace deletes the region and joins the remaining portions of lines on either side
App.run_after_keychord('backspace')
check_eq(Lines[1].data, 'akl', "F - test_backspace_over_multiple_lines/data:1")
check_eq(Lines[2].data, 'mno', "F - test_backspace_over_multiple_lines/data:2")
-- cursor remains at start of selection
check_eq(Cursor1.line, 1, "F - test_backspace_over_multiple_lines/cursor:line")
check_eq(Cursor1.pos, 2, "F - test_backspace_over_multiple_lines/cursor:pos")
-- selection is cleared
check_nil(Selection1.line, "F - test_backspace_over_multiple_lines/selection")
end
function test_backspace_to_end_of_line()
io.write('\ntest_backspace_to_end_of_line')
-- select region from cursor to end of line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Selection1 = {line=1, pos=4}
-- backspace deletes rest of line without joining to any other line
App.run_after_keychord('backspace')
check_eq(Lines[1].data, 'a', "F - test_backspace_to_start_of_line/data:1")
check_eq(Lines[2].data, 'def', "F - test_backspace_to_start_of_line/data:2")
-- cursor remains at start of selection
check_eq(Cursor1.line, 1, "F - test_backspace_to_start_of_line/cursor:line")
check_eq(Cursor1.pos, 2, "F - test_backspace_to_start_of_line/cursor:pos")
-- selection is cleared
check_nil(Selection1.line, "F - test_backspace_to_start_of_line/selection")
end
function test_backspace_to_start_of_line()
io.write('\ntest_backspace_to_start_of_line')
-- select region from cursor to start of line
App.screen.init{width=Margin_left+30, height=60}
Lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
Selection1 = {line=2, pos=3}
-- backspace deletes beginning of line without joining to any other line
App.run_after_keychord('backspace')
check_eq(Lines[1].data, 'abc', "F - test_backspace_to_start_of_line/data:1")
check_eq(Lines[2].data, 'f', "F - test_backspace_to_start_of_line/data:2")
-- cursor remains at start of selection
check_eq(Cursor1.line, 2, "F - test_backspace_to_start_of_line/cursor:line")
check_eq(Cursor1.pos, 1, "F - test_backspace_to_start_of_line/cursor:pos")
-- selection is cleared
check_nil(Selection1.line, "F - test_backspace_to_start_of_line/selection")
end
function test_undo_insert_text()
io.write('\ntest_undo_insert_text')
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'def', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=4}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
-- insert a character
App.draw()
App.run_after_textinput('g')
check_eq(Cursor1.line, 2, 'F - test_undo_insert_text/baseline/cursor:line')
check_eq(Cursor1.pos, 5, 'F - test_undo_insert_text/baseline/cursor:pos')
check_nil(Selection1.line, 'F - test_undo_insert_text/baseline/selection:line')
check_nil(Selection1.pos, 'F - test_undo_insert_text/baseline/selection:pos')
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_undo_insert_text/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'defg', 'F - test_undo_insert_text/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'xyz', 'F - test_undo_insert_text/baseline/screen:3')
-- undo
App.run_after_keychord('C-z')
check_eq(Cursor1.line, 2, 'F - test_undo_insert_text/cursor:line')
check_eq(Cursor1.pos, 4, 'F - test_undo_insert_text/cursor:pos')
check_nil(Selection1.line, 'F - test_undo_insert_text/selection:line')
check_nil(Selection1.pos, 'F - test_undo_insert_text/selection:pos')
y = Margin_top
App.screen.check(y, 'abc', 'F - test_undo_insert_text/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_undo_insert_text/screen:2')
y = y + Line_height
App.screen.check(y, 'xyz', 'F - test_undo_insert_text/screen:3')
end
function test_undo_delete_text()
io.write('\ntest_undo_delete_text')
App.screen.init{width=120, height=60}
Lines = load_array{'abc', 'defg', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=5}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
-- delete a character
App.run_after_keychord('backspace')
check_eq(Cursor1.line, 2, 'F - test_undo_delete_text/baseline/cursor:line')
check_eq(Cursor1.pos, 4, 'F - test_undo_delete_text/baseline/cursor:pos')
check_nil(Selection1.line, 'F - test_undo_delete_text/baseline/selection:line')
check_nil(Selection1.pos, 'F - test_undo_delete_text/baseline/selection:pos')
local y = Margin_top
App.screen.check(y, 'abc', 'F - test_undo_delete_text/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def', 'F - test_undo_delete_text/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'xyz', 'F - test_undo_delete_text/baseline/screen:3')
-- undo
--? -- after undo, the backspaced key is selected
App.run_after_keychord('C-z')
check_eq(Cursor1.line, 2, 'F - test_undo_delete_text/cursor:line')
check_eq(Cursor1.pos, 5, 'F - test_undo_delete_text/cursor:pos')
check_nil(Selection1.line, 'F - test_undo_delete_text/selection:line')
check_nil(Selection1.pos, 'F - test_undo_delete_text/selection:pos')
--? check_eq(Selection1.line, 2, 'F - test_undo_delete_text/selection:line')
--? check_eq(Selection1.pos, 4, 'F - test_undo_delete_text/selection:pos')
y = Margin_top
App.screen.check(y, 'abc', 'F - test_undo_delete_text/screen:1')
y = y + Line_height
App.screen.check(y, 'defg', 'F - test_undo_delete_text/screen:2')
y = y + Line_height
App.screen.check(y, 'xyz', 'F - test_undo_delete_text/screen:3')
end
function test_undo_restores_selection()
io.write('\ntest_undo_restores_selection')
-- display a line of text with some part selected
App.screen.init{width=80, height=80}
Lines = load_array{'abc'}
Line_width = 75
Cursor1 = {line=1, pos=1}
Selection1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
-- delete selected text
App.run_after_textinput('x')
check_eq(Lines[1].data, 'xbc', 'F - test_undo_restores_selection/baseline')
check_nil(Selection1.line, 'F - test_undo_restores_selection/baseline:selection')
-- undo
App.run_after_keychord('C-z')
App.run_after_keychord('C-z')
-- selection is restored
check_eq(Selection1.line, 1, 'F - test_undo_restores_selection/line')
check_eq(Selection1.pos, 2, 'F - test_undo_restores_selection/pos')
end