ttytest2 0.9.6 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,130 +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 if column_end.positive?
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
- METHODS = public_instance_methods
129
- end
130
- 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,133 +1,139 @@
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 capture
65
- # Capture the current state of the terminal
66
- # @return [Capture] instantaneous state of the terminal when called
67
- # @!method print
68
- # Prints the current state of the terminal to stdout. See capture to get the raw string.
69
- # @!method print_rows
70
- # Prints the current state of the terminal as an array to stdout. See rows to get the raw array.
71
- def_delegators :@driver_terminal,
72
- :send_keys, :send_keys_one_at_a_time,
73
- :send_newline, :send_newlines,
74
- :send_delete, :send_deletes,
75
- :send_backspace, :send_backspaces,
76
- :send_left_arrow, :send_left_arrows, :send_right_arrow, :send_right_arrows,
77
- :send_down_arrow, :send_down_arrows, :send_up_arrow, :send_up_arrows,
78
- :send_keys_exact, :send_home, :send_end, :send_clear,
79
- :capture
80
-
81
- # @!method rows
82
- # @return [Array<String>]
83
- # @see Capture#rows
84
- # @!method row(row)
85
- # @return [String]
86
- # @see Capture#row
87
- # @!method width
88
- # @see Capture#width
89
- # @return [Integer]
90
- # @!method height
91
- # @see Capture#height
92
- # @return [Integer]
93
- # @!method cursor_x
94
- # @see Capture#cursor_x
95
- # @return [Integer]
96
- # @!method cursor_y
97
- # @see Capture#cursor_y
98
- # @return [Integer]
99
- # @!method cursor_visible?
100
- # @see Capture#cursor_visible?
101
- # @return [true,false]
102
- # @!method cursor_hidden?
103
- # @see Capture#cursor_hidden?
104
- # @return [true,false]
105
- def_delegators :capture, :print, :print_rows,
106
- :rows, :row,
107
- :width, :height,
108
- :cursor_x, :cursor_y,
109
- :cursor_visible?, :cursor_hidden?
110
-
111
- TTYtest::Matchers::METHODS.each do |matcher_name|
112
- define_method matcher_name do |*args|
113
- synchronize do
114
- capture.public_send(matcher_name, *args)
115
- end
116
- end
117
- end
118
-
119
- private
120
-
121
- def synchronize(seconds = max_wait_time)
122
- start_time = Time.now
123
- begin
124
- yield
125
- rescue MatchError => e
126
- raise e if (Time.now - start_time) >= seconds
127
-
128
- sleep 0.05
129
- retry
130
- end
131
- end
132
- end
133
- 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 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