729 lines
13 KiB
Text
729 lines
13 KiB
Text
# Copyright 2022 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Unit-test Term, the testsuite's terminal implementation that is used to test
|
|
# the TUI.
|
|
|
|
tuiterm_env
|
|
|
|
# Validate the cursor position.
|
|
#
|
|
# EXPECTED_CUR_COL and EXPECTED_CUR_ROW are the expected cursor column and row
|
|
# positions.
|
|
|
|
proc check_cursor_position { test expected_cur_col expected_cur_row } {
|
|
with_test_prefix $test {
|
|
gdb_assert {$expected_cur_col == ${Term::_cur_col}} "column"
|
|
gdb_assert {$expected_cur_row == ${Term::_cur_row}} "row"
|
|
}
|
|
}
|
|
|
|
# Validate the terminal contents and cursor position.
|
|
#
|
|
# EXPECTED_CONTENTS must be a list of strings, one element for each terminal
|
|
# line.
|
|
#
|
|
# EXPECTED_CUR_COL and EXPECTED_CUR_ROW are passed to check_cursor_position.
|
|
|
|
proc check { test expected_contents expected_cur_col expected_cur_row } {
|
|
with_test_prefix $test {
|
|
# Check term contents.
|
|
set regexp "^"
|
|
|
|
foreach line $expected_contents {
|
|
append regexp $line
|
|
append regexp "\n"
|
|
}
|
|
|
|
append regexp "$"
|
|
Term::check_contents "contents" $regexp
|
|
}
|
|
|
|
check_cursor_position $test $expected_cur_col $expected_cur_row
|
|
}
|
|
|
|
proc setup_terminal { cols rows } {
|
|
setenv TERM ansi
|
|
Term::_setup $rows $cols
|
|
}
|
|
|
|
# Most tests are fine with a small terminal. This proc initializes the terminal
|
|
# with 8 columns and 4 rows, with the following content:
|
|
#
|
|
# abcdefgh
|
|
# ijklmnop
|
|
# qrstuvwx
|
|
# yz01234
|
|
#
|
|
# The bottom right cell is left blank: trying to write to it using _insert
|
|
# would move the cursor past the screen, causing a scroll, but scrolling is
|
|
# not implemented at the moment.
|
|
|
|
proc setup_small {} {
|
|
setup_terminal 8 4
|
|
|
|
Term::_insert "abcdefgh"
|
|
Term::_insert "ijklmnop"
|
|
Term::_insert "qrstuvwx"
|
|
Term::_insert "yz01234"
|
|
|
|
check "check after setup" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 7 3
|
|
}
|
|
|
|
# Some tests require a larger terminal. This proc initializes the terminal with
|
|
# 80 columns and 25 rows, but leaves the content empty.
|
|
|
|
proc setup_large {} {
|
|
setup_terminal 80 25
|
|
}
|
|
|
|
# Each proc below tests a control character or sequence individually.
|
|
|
|
proc test_backspace {} {
|
|
# Note: the backspace (BS) control character only moves the cursor left,
|
|
# it does not delete characters.
|
|
|
|
Term::_move_cursor 1 2
|
|
|
|
Term::_ctl_0x08
|
|
check "backspace one" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 2
|
|
|
|
# Cursor should not move if it is already at column 0.
|
|
Term::_ctl_0x08
|
|
check "backspace 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 2
|
|
}
|
|
|
|
proc test_linefeed { } {
|
|
Term::_move_cursor 1 2
|
|
Term::_ctl_0x0a
|
|
check "linefeed" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 1 3
|
|
}
|
|
|
|
proc test_carriage_return { } {
|
|
Term::_move_cursor 1 2
|
|
Term::_ctl_0x0d
|
|
check "carriage return 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 2
|
|
|
|
Term::_ctl_0x0d
|
|
check "carriage return 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 2
|
|
}
|
|
|
|
proc test_insert_characters { } {
|
|
Term::_move_cursor 1 2
|
|
|
|
Term::_csi_@
|
|
check "insert characters 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"q rstuvw"
|
|
"yz01234 "
|
|
} 1 2
|
|
|
|
Term::_csi_@ 20
|
|
check "insert characters 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"q "
|
|
"yz01234 "
|
|
} 1 2
|
|
|
|
Term::_move_cursor 0 1
|
|
Term::_csi_@ 6
|
|
check "insert characters 3" {
|
|
"abcdefgh"
|
|
" ij"
|
|
"q "
|
|
"yz01234 "
|
|
} 0 1
|
|
}
|
|
|
|
proc test_pan_down { } {
|
|
Term::_move_cursor 1 2
|
|
Term::_csi_S
|
|
check "pan down, default arg" {
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
" "
|
|
} 1 2
|
|
|
|
Term::_csi_S 2
|
|
check "pan down, explicit arg" {
|
|
"yz01234 "
|
|
" "
|
|
" "
|
|
" "
|
|
} 1 2
|
|
|
|
Term::_csi_S 100
|
|
check "pan down, excessive arg" {
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
} 1 2
|
|
}
|
|
|
|
proc test_pan_up { } {
|
|
Term::_move_cursor 1 2
|
|
Term::_csi_T
|
|
check "pan down, default arg" {
|
|
" "
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
} 1 2
|
|
|
|
Term::_csi_T 2
|
|
check "pan down, explicit arg" {
|
|
" "
|
|
" "
|
|
" "
|
|
"abcdefgh"
|
|
} 1 2
|
|
|
|
Term::_csi_T 100
|
|
check "pan down, excessive arg" {
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
} 1 2
|
|
}
|
|
|
|
proc test_cursor_up { } {
|
|
Term::_move_cursor 2 3
|
|
|
|
Term::_csi_A
|
|
check "cursor up 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 2
|
|
|
|
Term::_csi_A 2
|
|
check "cursor up 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 0
|
|
|
|
Term::_csi_A 1
|
|
check "cursor up 3" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 0
|
|
}
|
|
|
|
proc test_cursor_down { } {
|
|
Term::_move_cursor 1 0
|
|
|
|
Term::_csi_B
|
|
check "cursor down 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 1 1
|
|
|
|
Term::_csi_B 2
|
|
check "cursor down 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 1 3
|
|
|
|
Term::_csi_B 1
|
|
check "cursor down 3" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 1 3
|
|
}
|
|
|
|
proc test_cursor_forward { } {
|
|
Term::_move_cursor 0 1
|
|
|
|
Term::_csi_C
|
|
check "cursor forward 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 1 1
|
|
|
|
Term::_csi_C 6
|
|
check "cursor forward 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 7 1
|
|
|
|
Term::_csi_C 1
|
|
check "cursor forward 3" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 7 1
|
|
}
|
|
|
|
proc test_cursor_backward { } {
|
|
Term::_move_cursor 7 1
|
|
|
|
Term::_csi_D
|
|
check "cursor backward 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 6 1
|
|
|
|
Term::_csi_D 6
|
|
check "cursor backward 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 1
|
|
|
|
Term::_csi_D 1
|
|
check "cursor backward 3" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 1
|
|
}
|
|
|
|
proc test_cursor_next_line { } {
|
|
Term::_move_cursor 2 0
|
|
|
|
Term::_csi_E
|
|
check "cursor next line 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 1
|
|
|
|
Term::_move_cursor 2 1
|
|
Term::_csi_E 2
|
|
check "cursor next line 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 3
|
|
|
|
Term::_move_cursor 2 3
|
|
Term::_csi_E 1
|
|
check "cursor next line 3" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 3
|
|
}
|
|
|
|
proc test_cursor_previous_line { } {
|
|
Term::_move_cursor 2 3
|
|
|
|
Term::_csi_F
|
|
check "cursor previous line 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 2
|
|
|
|
Term::_move_cursor 2 2
|
|
Term::_csi_F 2
|
|
check "cursor previous line 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 0
|
|
|
|
Term::_move_cursor 2 0
|
|
Term::_csi_F 1
|
|
check "cursor previous line 3" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 0
|
|
}
|
|
|
|
proc test_horizontal_absolute { } {
|
|
Term::_move_cursor 2 2
|
|
Term::_csi_G
|
|
check "cursor horizontal absolute 1" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 0 2
|
|
|
|
Term::_move_cursor 2 2
|
|
Term::_csi_G 4
|
|
check "cursor horizontal absolute 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 3 2
|
|
}
|
|
|
|
proc test_cursor_position { } {
|
|
Term::_move_cursor 1 1
|
|
|
|
Term::_csi_H 3 5
|
|
check "cursor horizontal absolute 2" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 4 2
|
|
}
|
|
|
|
proc test_cursor_horizontal_forward_tabulation { } {
|
|
Term::_move_cursor 5 2
|
|
Term::_csi_I
|
|
check_cursor_position "default param" 8 2
|
|
|
|
Term::_csi_I 2
|
|
check_cursor_position "explicit param" 24 2
|
|
|
|
Term::_move_cursor 77 2
|
|
Term::_csi_I 5
|
|
check_cursor_position "try to go past the end" 79 2
|
|
}
|
|
|
|
proc test_erase_in_display { } {
|
|
Term::_move_cursor 5 2
|
|
Term::_csi_J
|
|
check "erase in display, cursor to end with default param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstu "
|
|
" "
|
|
} 5 2
|
|
|
|
Term::_move_cursor 3 2
|
|
Term::_csi_J 0
|
|
check "erase in display, cursor to end with explicit param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrs "
|
|
" "
|
|
} 3 2
|
|
|
|
Term::_move_cursor 2 1
|
|
Term::_csi_J 1
|
|
check "erase in display, beginning to cursor" {
|
|
" "
|
|
" lmnop"
|
|
"qrs "
|
|
" "
|
|
} 2 1
|
|
|
|
Term::_move_cursor 5 1
|
|
Term::_csi_J 2
|
|
check "erase in display, entire display" {
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
} 5 1
|
|
}
|
|
|
|
proc test_erase_in_line { } {
|
|
Term::_move_cursor 5 2
|
|
Term::_csi_K
|
|
check "erase in line, cursor to end with default param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstu "
|
|
"yz01234 "
|
|
} 5 2
|
|
|
|
Term::_move_cursor 3 2
|
|
Term::_csi_K 0
|
|
check "erase in line, cursor to end with explicit param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrs "
|
|
"yz01234 "
|
|
} 3 2
|
|
|
|
Term::_move_cursor 3 1
|
|
Term::_csi_K 1
|
|
check "erase in line, beginning to cursor" {
|
|
"abcdefgh"
|
|
" mnop"
|
|
"qrs "
|
|
"yz01234 "
|
|
} 3 1
|
|
|
|
Term::_move_cursor 3 0
|
|
Term::_csi_K 2
|
|
check "erase in line, entire line" {
|
|
" "
|
|
" mnop"
|
|
"qrs "
|
|
"yz01234 "
|
|
} 3 0
|
|
}
|
|
|
|
proc test_delete_line { } {
|
|
Term::_move_cursor 3 2
|
|
Term::_csi_M
|
|
check "delete line, default param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"yz01234 "
|
|
" "
|
|
} 3 2
|
|
|
|
Term::_move_cursor 3 0
|
|
Term::_csi_M 2
|
|
check "delete line, explicit param" {
|
|
"yz01234 "
|
|
" "
|
|
" "
|
|
" "
|
|
} 3 0
|
|
}
|
|
|
|
proc test_delete_character { } {
|
|
Term::_move_cursor 2 1
|
|
|
|
Term::_csi_P
|
|
check "delete character, default param" {
|
|
"abcdefgh"
|
|
"ijlmnop "
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 1
|
|
|
|
Term::_csi_P 3
|
|
check "delete character, explicit param" {
|
|
"abcdefgh"
|
|
"ijop "
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 1
|
|
|
|
Term::_csi_P 12
|
|
check "delete character, more than number of columns" {
|
|
"abcdefgh"
|
|
"ij "
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 1
|
|
}
|
|
|
|
proc test_erase_character { } {
|
|
Term::_move_cursor 3 2
|
|
Term::_csi_X
|
|
check "erase character, default param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrs uvwx"
|
|
"yz01234 "
|
|
} 3 2
|
|
|
|
Term::_move_cursor 1 3
|
|
Term::_csi_X 4
|
|
check "erase character, explicit param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrs uvwx"
|
|
"y 34 "
|
|
} 1 3
|
|
}
|
|
|
|
proc test_cursor_backward_tabulation { } {
|
|
Term::_move_cursor 77 2
|
|
Term::_csi_Z
|
|
check_cursor_position "default param" 72 2
|
|
|
|
Term::_csi_Z 2
|
|
check_cursor_position "explicit param" 56 2
|
|
|
|
Term::_move_cursor 6 2
|
|
Term::_csi_Z 12
|
|
check_cursor_position "try to go past the beginning" 0 2
|
|
}
|
|
|
|
proc test_repeat { } {
|
|
Term::_move_cursor 2 1
|
|
set Term::_last_char X
|
|
|
|
Term::_csi_b 3
|
|
check "repeat" {
|
|
"abcdefgh"
|
|
"ijXXXnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 5 1
|
|
}
|
|
|
|
proc test_vertical_line_position_absolute { } {
|
|
Term::_move_cursor 2 1
|
|
|
|
Term::_csi_d
|
|
check "default param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 0
|
|
|
|
Term::_csi_d 3
|
|
check "explicit param" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 2
|
|
|
|
Term::_csi_d 100
|
|
check "try to move off-display" {
|
|
"abcdefgh"
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
"yz01234 "
|
|
} 2 3
|
|
}
|
|
|
|
proc test_insert_line { } {
|
|
Term::_move_cursor 2 1
|
|
Term::_csi_L
|
|
check "insert line, default param" {
|
|
"abcdefgh"
|
|
" "
|
|
"ijklmnop"
|
|
"qrstuvwx"
|
|
} 2 1
|
|
|
|
Term::_move_cursor 2 0
|
|
Term::_csi_L 2
|
|
check "insert line, explicit param" {
|
|
" "
|
|
" "
|
|
"abcdefgh"
|
|
" "
|
|
} 2 0
|
|
|
|
Term::_csi_L 12
|
|
check "insert line, insert more lines than display has" {
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
} 2 0
|
|
}
|
|
|
|
# Run proc TEST_PROC_NAME with a "small" terminal.
|
|
|
|
proc run_one_test_small { test_proc_name } {
|
|
save_vars { env(TERM) stty_init } {
|
|
setup_small
|
|
eval $test_proc_name
|
|
}
|
|
}
|
|
|
|
# Run proc TEST_PROC_NAME with a "large" terminal.
|
|
|
|
proc run_one_test_large { test_proc_name } {
|
|
save_vars { env(TERM) stty_init } {
|
|
setup_large
|
|
eval $test_proc_name
|
|
}
|
|
}
|
|
|
|
foreach_with_prefix test {
|
|
test_backspace
|
|
test_linefeed
|
|
test_carriage_return
|
|
test_insert_characters
|
|
test_cursor_up
|
|
test_cursor_down
|
|
test_cursor_forward
|
|
test_cursor_backward
|
|
test_cursor_next_line
|
|
test_cursor_previous_line
|
|
test_horizontal_absolute
|
|
test_cursor_position
|
|
test_erase_in_display
|
|
test_erase_in_line
|
|
test_delete_line
|
|
test_delete_character
|
|
test_erase_character
|
|
test_repeat
|
|
test_vertical_line_position_absolute
|
|
test_insert_line
|
|
test_pan_up
|
|
test_pan_down
|
|
} {
|
|
run_one_test_small $test
|
|
}
|
|
|
|
foreach_with_prefix test {
|
|
test_cursor_horizontal_forward_tabulation
|
|
test_cursor_backward_tabulation
|
|
} {
|
|
run_one_test_large $test
|
|
}
|