ttytest2 0.9.8 → 0.9.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,157 +1,157 @@
1
- # frozen_string_literal: true
2
-
3
- module TTYtest
4
- # Assertions for ttytest2.
5
- module Matchers
6
- # Asserts the contents of a single row match the value expected
7
- # @param [Integer] row_number the row (starting from 0) to test against
8
- # @param [String] expected the expected value of the row. Any trailing whitespace is ignored
9
- # @raise [MatchError] if the row doesn't match exactly
10
- def assert_row(row_number, expected)
11
- expected = expected.rstrip
12
- actual = row(row_number)
13
- return if actual == expected
14
-
15
- raise MatchError,
16
- "expected row #{row_number} to be #{expected.inspect} but got #{actual.inspect}\nEntire screen:\n#{self}"
17
- end
18
-
19
- # Asserts the contents of a single row contains the expected string at a specific position
20
- # @param [Integer] row_number the row (starting from 0) to test against
21
- # @param [Integer] column_start the column position to start comparing expected against
22
- # @param [Integer] columns_end the column position to end comparing expected against
23
- # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
24
- # @raise [MatchError] if the row doesn't match
25
- def assert_row_at(row_number, column_start, column_end, expected)
26
- expected = expected.rstrip
27
- actual = row(row_number)
28
- column_end += 1
29
- return if actual[column_start, column_end].eql?(expected)
30
-
31
- raise MatchError,
32
- "expected row #{row_number} to contain #{expected[column_start,
33
- column_end]} at #{column_start}-#{column_end} and got #{actual[column_start,
34
- column_end]}\nEntire screen:\n#{self}"
35
- end
36
-
37
- # Asserts the contents of a single row contains the value expected
38
- # @param [Integer] row_number the row (starting from 0) to test against
39
- # @param [String] expected the expected value contained in the row. Any trailing whitespace is ignored
40
- # @raise [MatchError] if the row doesn't match
41
- def assert_row_like(row_number, expected)
42
- expected = expected.rstrip
43
- actual = row(row_number)
44
- return if actual.include?(expected)
45
-
46
- raise MatchError,
47
- "expected row #{row_number} to be like #{expected.inspect} but got #{actual.inspect}\nEntire screen:\n#{self}"
48
- end
49
-
50
- # Asserts the contents of a single row starts with expected string
51
- # @param [Integer] row_number the row (starting from 0) to test against
52
- # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
53
- # @raise [MatchError] if the row doesn't match
54
- def assert_row_starts_with(row_number, expected)
55
- expected = expected.rstrip
56
- actual = row(row_number)
57
- return if actual.start_with?(expected)
58
-
59
- raise MatchError,
60
- "expected row #{row_number} to start with #{expected.inspect} and got #{actual.inspect}\nEntire screen:\n#{self}"
61
- end
62
-
63
- # Asserts the contents of a single row end with expected
64
- # @param [Integer] row_number the row (starting from 0) to test against
65
- # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
66
- # @raise [MatchError] if the row doesn't match
67
- def assert_row_ends_with(row_number, expected)
68
- expected = expected.rstrip
69
- actual = row(row_number)
70
- return if actual.end_with?(expected)
71
-
72
- raise MatchError,
73
- "expected row #{row_number} to end with #{expected.inspect} and got #{actual.inspect}\nEntire screen:\n#{self}"
74
- end
75
-
76
- # Asserts that the cursor is in the expected position
77
- # @param [Integer] x cursor x (row) position, starting from 0
78
- # @param [Integer] y cursor y (column) position, starting from 0
79
- # @raise [MatchError] if the cursor position doesn't match
80
- def assert_cursor_position(x, y)
81
- expected = [x, y]
82
- actual = [cursor_x, cursor_y]
83
- return if actual == expected
84
-
85
- raise MatchError,
86
- "expected cursor to be at #{expected.inspect} but was at #{actual.inspect}\nEntire screen:\n#{self}"
87
- end
88
-
89
- # @raise [MatchError] if the cursor is hidden
90
- def assert_cursor_visible
91
- return if cursor_visible?
92
-
93
- raise MatchError, "expected cursor to be visible was hidden\nEntire screen:\n#{self}"
94
- end
95
-
96
- # @raise [MatchError] if the cursor is visible
97
- def assert_cursor_hidden
98
- return if cursor_hidden?
99
-
100
- raise MatchError, "expected cursor to be hidden was visible\nEntire screen:\n#{self}"
101
- end
102
-
103
- # Asserts the full contents of the terminal
104
- # @param [String] expected the full expected contents of the terminal. Trailing whitespace on each line is ignored
105
- # @raise [MatchError] if the terminal doesn't match the expected content
106
- def assert_contents(expected)
107
- expected_rows = expected.split("\n")
108
- diff = []
109
- matched = true
110
- rows.each_with_index do |actual_row, index|
111
- expected_row = (expected_rows[index] || '').rstrip
112
- if actual_row != expected_row
113
- diff << "-#{expected_row}"
114
- diff << "+#{actual_row}"
115
- matched = false
116
- else
117
- diff << " #{actual_row}".rstrip
118
- end
119
- end
120
-
121
- return if matched
122
-
123
- raise MatchError,
124
- "screen did not match expected content:\n--- expected\n+++ actual\n#{diff.join("\n")}"
125
- end
126
- alias assert_matches assert_contents
127
-
128
- # Asserts the contents of the terminal at specified rows
129
- # @param [String] expected the expected contents of the terminal at specified rows. Trailing whitespace on each line is ignored
130
- # @raise [MatchError] if the terminal doesn't match the expected content
131
- def assert_contents_at(row_start, row_end, expected)
132
- expected_rows = expected.split("\n")
133
- diff = []
134
- matched = true
135
- row_end += 1 if row_end.zero?
136
-
137
- rows.slice(row_start, row_end).each_with_index do |actual_row, index|
138
- expected_row = (expected_rows[index] || '').rstrip
139
- if actual_row != expected_row
140
- diff << "-#{expected_row}"
141
- diff << "+#{actual_row}"
142
- matched = false
143
- else
144
- diff << " #{actual_row}".rstrip
145
- end
146
- end
147
-
148
- return if matched
149
-
150
- raise MatchError,
151
- "screen did not match expected content:\n--- expected\n+++ actual\n#{diff.join("\n")}"
152
- end
153
- alias assert_matches_at assert_contents_at
154
-
155
- METHODS = public_instance_methods
156
- end
157
- end
1
+ # frozen_string_literal: true
2
+
3
+ module TTYtest
4
+ # Assertions for ttytest2.
5
+ module Matchers
6
+ # Asserts the contents of a single row match the value expected
7
+ # @param [Integer] row_number the row (starting from 0) to test against
8
+ # @param [String] expected the expected value of the row. Any trailing whitespace is ignored
9
+ # @raise [MatchError] if the row doesn't match exactly
10
+ def assert_row(row_number, expected)
11
+ expected = expected.rstrip
12
+ actual = row(row_number)
13
+ return if actual == expected
14
+
15
+ raise MatchError,
16
+ "expected row #{row_number} to be #{expected.inspect} but got #{actual.inspect}\nEntire screen:\n#{self}"
17
+ end
18
+
19
+ # Asserts the contents of a single row contains the expected string at a specific position
20
+ # @param [Integer] row_number the row (starting from 0) to test against
21
+ # @param [Integer] column_start the column position to start comparing expected against
22
+ # @param [Integer] columns_end the column position to end comparing expected against
23
+ # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
24
+ # @raise [MatchError] if the row doesn't match
25
+ def assert_row_at(row_number, column_start, column_end, expected)
26
+ expected = expected.rstrip
27
+ actual = row(row_number)
28
+ column_end += 1
29
+ return if actual[column_start, column_end].eql?(expected)
30
+
31
+ raise MatchError,
32
+ "expected row #{row_number} to contain #{expected[column_start,
33
+ column_end]} at #{column_start}-#{column_end} and got #{actual[column_start,
34
+ column_end]}\nEntire screen:\n#{self}"
35
+ end
36
+
37
+ # Asserts the contents of a single row contains the value expected
38
+ # @param [Integer] row_number the row (starting from 0) to test against
39
+ # @param [String] expected the expected value contained in the row. Any trailing whitespace is ignored
40
+ # @raise [MatchError] if the row doesn't match
41
+ def assert_row_like(row_number, expected)
42
+ expected = expected.rstrip
43
+ actual = row(row_number)
44
+ return if actual.include?(expected)
45
+
46
+ raise MatchError,
47
+ "expected row #{row_number} to be like #{expected.inspect} but got #{actual.inspect}\nEntire screen:\n#{self}"
48
+ end
49
+
50
+ # Asserts the contents of a single row starts with expected string
51
+ # @param [Integer] row_number the row (starting from 0) to test against
52
+ # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
53
+ # @raise [MatchError] if the row doesn't match
54
+ def assert_row_starts_with(row_number, expected)
55
+ expected = expected.rstrip
56
+ actual = row(row_number)
57
+ return if actual.start_with?(expected)
58
+
59
+ raise MatchError,
60
+ "expected row #{row_number} to start with #{expected.inspect} and got #{actual.inspect}\nEntire screen:\n#{self}"
61
+ end
62
+
63
+ # Asserts the contents of a single row end with expected
64
+ # @param [Integer] row_number the row (starting from 0) to test against
65
+ # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
66
+ # @raise [MatchError] if the row doesn't match
67
+ def assert_row_ends_with(row_number, expected)
68
+ expected = expected.rstrip
69
+ actual = row(row_number)
70
+ return if actual.end_with?(expected)
71
+
72
+ raise MatchError,
73
+ "expected row #{row_number} to end with #{expected.inspect} and got #{actual.inspect}\nEntire screen:\n#{self}"
74
+ end
75
+
76
+ # Asserts that the cursor is in the expected position
77
+ # @param [Integer] x cursor x (row) position, starting from 0
78
+ # @param [Integer] y cursor y (column) position, starting from 0
79
+ # @raise [MatchError] if the cursor position doesn't match
80
+ def assert_cursor_position(x, y)
81
+ expected = [x, y]
82
+ actual = [cursor_x, cursor_y]
83
+ return if actual == expected
84
+
85
+ raise MatchError,
86
+ "expected cursor to be at #{expected.inspect} but was at #{actual.inspect}\nEntire screen:\n#{self}"
87
+ end
88
+
89
+ # @raise [MatchError] if the cursor is hidden
90
+ def assert_cursor_visible
91
+ return if cursor_visible?
92
+
93
+ raise MatchError, "expected cursor to be visible was hidden\nEntire screen:\n#{self}"
94
+ end
95
+
96
+ # @raise [MatchError] if the cursor is visible
97
+ def assert_cursor_hidden
98
+ return if cursor_hidden?
99
+
100
+ raise MatchError, "expected cursor to be hidden was visible\nEntire screen:\n#{self}"
101
+ end
102
+
103
+ # Asserts the full contents of the terminal
104
+ # @param [String] expected the full expected contents of the terminal. Trailing whitespace on each line is ignored
105
+ # @raise [MatchError] if the terminal doesn't match the expected content
106
+ def assert_contents(expected)
107
+ expected_rows = expected.split("\n")
108
+ diff = []
109
+ matched = true
110
+ rows.each_with_index do |actual_row, index|
111
+ expected_row = (expected_rows[index] || '').rstrip
112
+ if actual_row != expected_row
113
+ diff << "-#{expected_row}"
114
+ diff << "+#{actual_row}"
115
+ matched = false
116
+ else
117
+ diff << " #{actual_row}".rstrip
118
+ end
119
+ end
120
+
121
+ return if matched
122
+
123
+ raise MatchError,
124
+ "screen did not match expected content:\n--- expected\n+++ actual\n#{diff.join("\n")}"
125
+ end
126
+ alias assert_matches assert_contents
127
+
128
+ # Asserts the contents of the terminal at specified rows
129
+ # @param [String] expected the expected contents of the terminal at specified rows. Trailing whitespace on each line is ignored
130
+ # @raise [MatchError] if the terminal doesn't match the expected content
131
+ def assert_contents_at(row_start, row_end, expected)
132
+ expected_rows = expected.split("\n")
133
+ diff = []
134
+ matched = true
135
+ row_end += 1 if row_end.zero?
136
+
137
+ rows.slice(row_start, row_end).each_with_index do |actual_row, index|
138
+ expected_row = (expected_rows[index] || '').rstrip
139
+ if actual_row != expected_row
140
+ diff << "-#{expected_row}"
141
+ diff << "+#{actual_row}"
142
+ matched = false
143
+ else
144
+ diff << " #{actual_row}".rstrip
145
+ end
146
+ end
147
+
148
+ return if matched
149
+
150
+ raise MatchError,
151
+ "screen did not match expected content:\n--- expected\n+++ actual\n#{diff.join("\n")}"
152
+ end
153
+ alias assert_matches_at assert_contents_at
154
+
155
+ METHODS = public_instance_methods
156
+ end
157
+ end
@@ -1,139 +1,141 @@
1
- # frozen_string_literal: true
2
-
3
- require 'forwardable'
4
- require 'ttytest/matchers'
5
- require 'ttytest/capture'
6
-
7
- module TTYtest
8
- # @attr [Integer] max_wait_time the maximum amount of time (in seconds) to retry assertions before failing.
9
- class Terminal
10
- extend Forwardable
11
-
12
- attr_accessor :max_wait_time
13
-
14
- # @api private
15
- # @see TTYtest.new_terminal
16
- def initialize(driver_terminal, max_wait_time: nil)
17
- @driver_terminal = driver_terminal
18
- @max_wait_time = max_wait_time || TTYtest.default_max_wait_time
19
- end
20
-
21
- # @!method send_keys(*keys)
22
- # Simulate typing keys into the terminal. For canonical cli's/shells which read line by line.
23
- # @param [String] keys keys to send to the terminal
24
- # @!method send_keys_one_at_a_time(keys)
25
- # Simulate typing keys into the terminal. For noncanonical cli's/shells which read character by character.
26
- # @param [String] keys keys to send to the terminal
27
- # @!method send_newline
28
- # Simulate typing enter by sending newline character to the terminal.
29
- # @!method send_newlines
30
- # Simulates sending newline the specified number of times.
31
- # @param [Integer] number of times to send newline
32
- # @!method send_delete
33
- # Simulate typing the delete key in the terminal.
34
- # @!method send_deletes
35
- # Simulates typing delete the specified number of times.
36
- # @param [Integer] number of times to send delete
37
- # @!method send_backspace
38
- # Simulate typing the backspace key in the terminal.
39
- # @!method send_backspaces
40
- # Simulates typing backspace the specified number of times.
41
- # @param [Integer] number of times to send backspace
42
- # @!method send_left_arrow
43
- # Simulate typing the left arrow key in the terminal.
44
- # @!method send_left_arrows
45
- # Simulates typing left arrow the specified number of times.
46
- # @param [Integer] number of times to send left arrow
47
- # @!method send_right_arrow
48
- # Simulate typing the right arrow key in the terminal.
49
- # @!method send_right_arrows
50
- # Simulates typing right arrow the specified number of times.
51
- # @param [Integer] number of times to send right arrow
52
- # @!method send_down_arrow
53
- # Simulate typing the down arrow key in the terminal.
54
- # @!method send_down_arrows
55
- # Simulates typing the down arrow the specified number of times.
56
- # @param [Integer] number of times to send down arrow
57
- # @!method send_up_arrow
58
- # Simulate typing the up arrow key in the terminal.
59
- # @!method send_up_arrows
60
- # Simulates typing the up arrow the specified number of times.
61
- # @param [Integer] number of times to send up arrow
62
- # @!method send_keys_exact
63
- # Send tmux send-keys command to the terminal, such as DC or Enter, to simulate pressing that key in the terminal.
64
- # @!method send_home
65
- # Simulates typing in the Home key in the terminal.
66
- # @!method send_end
67
- # Simulates typing in the End key in the terminal.
68
- # @!method send_clear
69
- # Clears the screen in the terminal using ascii clear command.
70
- # @!method capture
71
- # Capture the current state of the terminal
72
- # @return [Capture] instantaneous state of the terminal when called
73
- def_delegators :@driver_terminal,
74
- :send_keys, :send_keys_one_at_a_time,
75
- :send_newline, :send_newlines,
76
- :send_delete, :send_deletes,
77
- :send_backspace, :send_backspaces,
78
- :send_left_arrow, :send_left_arrows, :send_right_arrow, :send_right_arrows,
79
- :send_down_arrow, :send_down_arrows, :send_up_arrow, :send_up_arrows,
80
- :send_keys_exact, :send_home, :send_end, :send_clear,
81
- :capture
82
-
83
- # @!method print
84
- # Prints the current state of the terminal to stdout. See capture to get the raw string.
85
- # @!method print_rows
86
- # Prints the current state of the terminal as an array to stdout. See rows to get the raw array.
87
- # @!method rows
88
- # @return [Array<String>]
89
- # @see Capture#rows
90
- # @!method row(row)
91
- # @return [String]
92
- # @see Capture#row
93
- # @!method width
94
- # @see Capture#width
95
- # @return [Integer]
96
- # @!method height
97
- # @see Capture#height
98
- # @return [Integer]
99
- # @!method cursor_x
100
- # @see Capture#cursor_x
101
- # @return [Integer]
102
- # @!method cursor_y
103
- # @see Capture#cursor_y
104
- # @return [Integer]
105
- # @!method cursor_visible?
106
- # @see Capture#cursor_visible?
107
- # @return [true,false]
108
- # @!method cursor_hidden?
109
- # @see Capture#cursor_hidden?
110
- # @return [true,false]
111
- def_delegators :capture, :print, :print_rows,
112
- :rows, :row,
113
- :width, :height,
114
- :cursor_x, :cursor_y,
115
- :cursor_visible?, :cursor_hidden?
116
-
117
- TTYtest::Matchers::METHODS.each do |matcher_name|
118
- define_method matcher_name do |*args|
119
- synchronize do
120
- capture.public_send(matcher_name, *args)
121
- end
122
- end
123
- end
124
-
125
- private
126
-
127
- def synchronize(seconds = max_wait_time)
128
- start_time = Time.now
129
- begin
130
- yield
131
- rescue MatchError => e
132
- raise e if (Time.now - start_time) >= seconds
133
-
134
- sleep 0.05
135
- retry
136
- end
137
- end
138
- end
139
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'ttytest/matchers'
5
+ require 'ttytest/capture'
6
+
7
+ module TTYtest
8
+ # @attr [Integer] max_wait_time the maximum amount of time (in seconds) to retry assertions before failing.
9
+ class Terminal
10
+ extend Forwardable
11
+
12
+ attr_accessor :max_wait_time
13
+
14
+ # @api private
15
+ # @see TTYtest.new_terminal
16
+ def initialize(driver_terminal, max_wait_time: nil)
17
+ @driver_terminal = driver_terminal
18
+ @max_wait_time = max_wait_time || TTYtest.default_max_wait_time
19
+ end
20
+
21
+ # @!method send_keys(*keys)
22
+ # Simulate typing keys into the terminal. For canonical cli's/shells which read line by line.
23
+ # @param [String] keys keys to send to the terminal
24
+ # @!method send_keys_one_at_a_time(keys)
25
+ # Simulate typing keys into the terminal. For noncanonical cli's/shells which read character by character.
26
+ # @param [String] keys keys to send to the terminal
27
+ # @!method send_newline
28
+ # Simulate typing enter by sending newline character to the terminal.
29
+ # @!method send_newlines
30
+ # Simulates sending newline the specified number of times.
31
+ # @param [Integer] number of times to send newline
32
+ # @!method send_delete
33
+ # Simulate typing the delete key in the terminal.
34
+ # @!method send_deletes
35
+ # Simulates typing delete the specified number of times.
36
+ # @param [Integer] number of times to send delete
37
+ # @!method send_backspace
38
+ # Simulate typing the backspace key in the terminal.
39
+ # @!method send_backspaces
40
+ # Simulates typing backspace the specified number of times.
41
+ # @param [Integer] number of times to send backspace
42
+ # @!method send_left_arrow
43
+ # Simulate typing the left arrow key in the terminal.
44
+ # @!method send_left_arrows
45
+ # Simulates typing left arrow the specified number of times.
46
+ # @param [Integer] number of times to send left arrow
47
+ # @!method send_right_arrow
48
+ # Simulate typing the right arrow key in the terminal.
49
+ # @!method send_right_arrows
50
+ # Simulates typing right arrow the specified number of times.
51
+ # @param [Integer] number of times to send right arrow
52
+ # @!method send_down_arrow
53
+ # Simulate typing the down arrow key in the terminal.
54
+ # @!method send_down_arrows
55
+ # Simulates typing the down arrow the specified number of times.
56
+ # @param [Integer] number of times to send down arrow
57
+ # @!method send_up_arrow
58
+ # Simulate typing the up arrow key in the terminal.
59
+ # @!method send_up_arrows
60
+ # Simulates typing the up arrow the specified number of times.
61
+ # @param [Integer] number of times to send up arrow
62
+ # @!method send_keys_exact
63
+ # Send tmux send-keys command to the terminal, such as DC or Enter, to simulate pressing that key in the terminal.
64
+ # @!method send_home
65
+ # Simulates typing in the Home key in the terminal.
66
+ # @!method send_end
67
+ # Simulates typing in the End key in the terminal.
68
+ # @!method send_clear
69
+ # Clears the screen in the terminal using ascii clear command.
70
+ # @!method send_escape
71
+ # Simulates typing in the Escape (ESC) key in the terminal.
72
+ # @!method capture
73
+ # Capture the current state of the terminal
74
+ # @return [Capture] instantaneous state of the terminal when called
75
+ def_delegators :@driver_terminal,
76
+ :send_keys, :send_keys_one_at_a_time,
77
+ :send_newline, :send_newlines,
78
+ :send_delete, :send_deletes,
79
+ :send_backspace, :send_backspaces,
80
+ :send_left_arrow, :send_left_arrows, :send_right_arrow, :send_right_arrows,
81
+ :send_down_arrow, :send_down_arrows, :send_up_arrow, :send_up_arrows,
82
+ :send_keys_exact, :send_home, :send_end, :send_clear, :send_escape,
83
+ :capture
84
+
85
+ # @!method print
86
+ # Prints the current state of the terminal to stdout. See capture to get the raw string.
87
+ # @!method print_rows
88
+ # Prints the current state of the terminal as an array to stdout. See rows to get the raw array.
89
+ # @!method rows
90
+ # @return [Array<String>]
91
+ # @see Capture#rows
92
+ # @!method row(row)
93
+ # @return [String]
94
+ # @see Capture#row
95
+ # @!method width
96
+ # @see Capture#width
97
+ # @return [Integer]
98
+ # @!method height
99
+ # @see Capture#height
100
+ # @return [Integer]
101
+ # @!method cursor_x
102
+ # @see Capture#cursor_x
103
+ # @return [Integer]
104
+ # @!method cursor_y
105
+ # @see Capture#cursor_y
106
+ # @return [Integer]
107
+ # @!method cursor_visible?
108
+ # @see Capture#cursor_visible?
109
+ # @return [true,false]
110
+ # @!method cursor_hidden?
111
+ # @see Capture#cursor_hidden?
112
+ # @return [true,false]
113
+ def_delegators :capture, :print, :print_rows,
114
+ :rows, :row,
115
+ :width, :height,
116
+ :cursor_x, :cursor_y,
117
+ :cursor_visible?, :cursor_hidden?
118
+
119
+ TTYtest::Matchers::METHODS.each do |matcher_name|
120
+ define_method matcher_name do |*args|
121
+ synchronize do
122
+ capture.public_send(matcher_name, *args)
123
+ end
124
+ end
125
+ end
126
+
127
+ private
128
+
129
+ def synchronize(seconds = max_wait_time)
130
+ start_time = Time.now
131
+ begin
132
+ yield
133
+ rescue MatchError => e
134
+ raise e if (Time.now - start_time) >= seconds
135
+
136
+ sleep 0.05
137
+ retry
138
+ end
139
+ end
140
+ end
141
+ end