ttytest2 0.9.11 → 0.9.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +66 -73
- data/examples/integration_tests.rb +790 -0
- data/lib/ttytest/terminal.rb +5 -0
- data/lib/ttytest/tmux/session.rb +14 -1
- data/lib/ttytest/version.rb +1 -1
- data/notes.txt +2 -2
- metadata +3 -4
- data/examples/canonical_integration_tests.rb +0 -85
- data/examples/noncanonical_integration_tests.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0509fd299994f0f61a308fe4f8fce559d9cd0f55d095ebac9e46a4889088d289'
|
4
|
+
data.tar.gz: 42db9936a321bce77fb11dbea796fd083291fac9c3bf3cc0611714815b3dca07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c118f0b7542d4bcef07ec07a4df564e345d6fdcc76357c342a42a3b0ee6e48c1d2b5a75c2299b2f6d3c46f2ccf4f06f1bfd1fd565b73966cf0ae942f48cd312
|
7
|
+
data.tar.gz: 3130e6923dbd0513e545fd19636828790488adaeaeab416fb42bdb6ab934c226bf028356b0beaf8054592e81e7eb19c602069dba4dbd993d21ee24ad2f5ba7d4
|
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
ttytest2 is an acceptance test framework for interactive console applications. It's like [capybara](https://github.com/teamcapybara/capybara) for the terminal.
|
4
4
|
|
5
|
-
|
5
|
+
ttytest2 is a fork and a drop-in replacement for [ttytest](https://github.com/jhawthorn/ttytest), because I had some features I needed for my own project.
|
6
6
|
|
7
|
-
It works by running commands inside a tmux session, capturing the pane, and comparing the content.
|
7
|
+
It works by running commands inside a tmux session, capturing the pane, and comparing the content to your assertions.
|
8
8
|
|
9
9
|
The assertions will wait a specified amount of time (default 2 seconds) for the expected content to appear.
|
10
10
|
|
@@ -14,17 +14,16 @@ The assertions will wait a specified amount of time (default 2 seconds) for the
|
|
14
14
|
|
15
15
|
1. [Minimum Requirements](#minimum-requirements)
|
16
16
|
2. [Usage](#usage)
|
17
|
-
3. [Example
|
18
|
-
4. [
|
19
|
-
5. [
|
20
|
-
6. [Output](#output)
|
21
|
-
7. [
|
22
|
-
8. [
|
23
|
-
9. [
|
24
|
-
10. [
|
25
|
-
11. [
|
26
|
-
12. [
|
27
|
-
13. [License](#license)
|
17
|
+
3. [Simple Example](#simple-example)
|
18
|
+
4. [Assertions](#assertions)
|
19
|
+
5. [Output](#output)
|
20
|
+
6. [Output Helpers](#output-helpers)
|
21
|
+
7. [Troubleshooting](#troubleshooting)
|
22
|
+
8. [Constants](#constants)
|
23
|
+
9. [Tips](#tips)
|
24
|
+
10. [Docker](#docker)
|
25
|
+
11. [Contributing](#contributing)
|
26
|
+
12. [License](#license)
|
28
27
|
|
29
28
|
## Minimum Requirements
|
30
29
|
|
@@ -33,29 +32,25 @@ The assertions will wait a specified amount of time (default 2 seconds) for the
|
|
33
32
|
|
34
33
|
## Usage
|
35
34
|
|
36
|
-
More documentation available at [ttytest2 docs](https://www.rubydoc.info/gems/ttytest2).
|
35
|
+
* More documentation available at [ttytest2 docs](https://www.rubydoc.info/gems/ttytest2).
|
36
|
+
* There are more examples in the examples folder.
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
### Example for Canonical CLI or Shell
|
41
|
-
|
42
|
-
Most people should use send_keys, if you are writing or working with a noncanonical shell/CLI, you will probably know it! Most shell/CLI applications are canonical.
|
38
|
+
### Simple Example
|
43
39
|
|
44
40
|
``` ruby
|
45
41
|
require 'ttytest'
|
46
|
-
|
47
|
-
@tty = TTYtest.new_terminal(%{PS1='$ ' /bin/sh}, width: 80, height: 24)
|
42
|
+
@tty = TTYtest.new_terminal(%(PS1='$ ' /bin/sh), width: 80, height: 7)
|
48
43
|
@tty.assert_row(0, '$')
|
49
|
-
@tty.assert_cursor_position(
|
44
|
+
@tty.assert_cursor_position(2, 0)
|
50
45
|
|
51
|
-
@tty.
|
46
|
+
@tty.send_line('echo "Hello, world"'))
|
52
47
|
|
53
|
-
@tty.assert_contents
|
54
|
-
$ echo "Hello, world"
|
55
|
-
Hello, world
|
56
|
-
$
|
48
|
+
@tty.assert_contents <<~TTY
|
49
|
+
$ echo "Hello, world"
|
50
|
+
Hello, world
|
51
|
+
$
|
57
52
|
TTY
|
58
|
-
@tty.assert_cursor_position(
|
53
|
+
@tty.assert_cursor_position(2, 2)
|
59
54
|
|
60
55
|
@tty.assert_contents_at(0, 0, '$ echo "Hello, world"')
|
61
56
|
|
@@ -64,44 +59,20 @@ TTY
|
|
64
59
|
@tty.assert_row_starts_with(1, 'Hello')
|
65
60
|
@tty.assert_row_ends_with(1, ', world')
|
66
61
|
|
67
|
-
@tty.print_rows #
|
68
|
-
|
69
|
-
@tty.print # prints out the contents of the terminal
|
70
|
-
```
|
71
|
-
|
72
|
-
### Example for Noncanonical CLI or Shell
|
73
|
-
|
74
|
-
If you are working with a noncanonical shell, you need to use send_keys_one_at_a_time to have your shell/CLI process the input correctly.
|
75
|
-
|
76
|
-
Also useful if you need to send input one character at a time for whatever reason.
|
77
|
-
|
78
|
-
'Multi-character' characters like '\n' need to be sent with send-keys, though.
|
79
|
-
|
80
|
-
``` ruby
|
81
|
-
require 'ttytest'
|
82
|
-
|
83
|
-
@tty = TTYtest.new_terminal(%{PS1='$ ' /bin/noncanonical-sh}, width: 80, height: 24)
|
84
|
-
@tty.assert_row_starts_with(0, ENV['USER'])
|
85
|
-
@tty.assert_row_ends_with(0, '$')
|
86
|
-
|
87
|
-
@tty.send_keys_one_at_a_time('ls')
|
88
|
-
@tty.assert_row_ends_with(0, 'ls')
|
89
|
-
@tty.send_newline # builtins for common outputs line newline
|
62
|
+
@tty.print_rows # prints out the contents of the terminal as an array:
|
63
|
+
# ["$ echo \"Hello, world\"", "Hello, world", "$", "", "", "", ""]
|
90
64
|
|
91
|
-
@tty.
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
@tty.assert_row_starts_with(2, ENV['USER'])
|
96
|
-
@tty.assert_row_ends_with(2, '$')
|
97
|
-
@tty.send_newline
|
98
|
-
|
99
|
-
puts "\n#{@tty.capture}" # prints out the contents of the terminal, equivalent to @tty.print
|
65
|
+
@tty.print # prints out the contents of the terminal:
|
66
|
+
# $ echo "Hello, world"
|
67
|
+
# Hello, world
|
68
|
+
# $
|
100
69
|
```
|
101
70
|
|
102
71
|
### Assertions
|
103
72
|
|
104
|
-
The main way to use TTYtest is through assertions.
|
73
|
+
The main way to use TTYtest is through assertions.
|
74
|
+
|
75
|
+
Assertions will be retried for up to 2 seconds when called through TTYtest::Terminal.
|
105
76
|
|
106
77
|
Available assertions:
|
107
78
|
|
@@ -110,6 +81,7 @@ Available assertions:
|
|
110
81
|
* `assert_row_like(row_number, expected_text)`
|
111
82
|
* `assert_row_starts_with(row_number, expected_text)`
|
112
83
|
* `assert_row_ends_with(row_number, expected_text)`
|
84
|
+
* `assert_row_regexp(row_number, regexp_str)`
|
113
85
|
* `assert_cursor_position(x: x, y: y)`
|
114
86
|
* `assert_cursor_visible`
|
115
87
|
* `assert_cursor_hidden`
|
@@ -120,19 +92,23 @@ Available assertions:
|
|
120
92
|
|
121
93
|
You can send output to the terminal with the following calls.
|
122
94
|
|
123
|
-
|
124
|
-
|
125
|
-
* `
|
95
|
+
Note: Most of the time send_line has the best ergonomics.
|
96
|
+
|
97
|
+
* `send_line(line)`: simulate typing in a command in the terminal and hitting enter!
|
98
|
+
* `send_line_then_sleep(line, sleep_time)`: simulate typing in a command in the terminal and hitting enter, then wait for sleep_time seconds.
|
99
|
+
* `send_keys(output)`: for canonical shells/CLI's (or multi-character keys for noncanonical shells/CLI's).
|
100
|
+
* `send_keys_one_at_a_time(output)`: for noncanonical shells/CLI's.
|
101
|
+
* `send_keys_exact(output)`: for sending tmux specific keys (any supported send-keys arguments like: DC for delete, Escape for ESC, etc.)
|
126
102
|
|
127
103
|
### Output Helpers
|
128
104
|
|
129
105
|
Helper functions to make sending output easier! They use the methods above under 'Sending Output' section under the hood.
|
130
106
|
|
131
|
-
* `send_newline` # equivalent to @tty.send_keys(%(\n))
|
107
|
+
* `send_newline` # simulate hitting enter, equivalent to @tty.send_keys(%(\n))
|
132
108
|
* `send_newlines(number_of_times)` # equivalent to calling send_newline number_of_times
|
133
|
-
* `send_backspace` # equivalent to @tty.send_keys(TTYtest::BACKSPACE)
|
109
|
+
* `send_backspace` # simulate hitting backspace, equivalent to @tty.send_keys(TTYtest::BACKSPACE)
|
134
110
|
* `send_backspaces(number_of_times)` # equivalent to calling send_backspace number_of_times
|
135
|
-
* `send_delete` # equivalent to calling send_keys_exact(%(DC))
|
111
|
+
* `send_delete` # simulate hitting delete, equivalent to calling send_keys_exact(%(DC))
|
136
112
|
* `send_deletes` # equivalent to calling send_delete number_of_times
|
137
113
|
* `send_right_arrow`
|
138
114
|
* `send_right_arrows(number_of_times)`
|
@@ -180,15 +156,26 @@ You can configure max wait time as shown below.
|
|
180
156
|
You can use the method rows to get all rows of the terminal as an array, of use the method capture to get the contents of the terminal window. This can be useful when troubleshooting.
|
181
157
|
|
182
158
|
``` ruby
|
183
|
-
@tty = TTYtest
|
159
|
+
@tty = TTYtest.new_terminal(%(PS1='$ ' /bin/sh), width: 80, height: 7)
|
160
|
+
@tty.send_line('echo "Hello, world"'))
|
184
161
|
|
185
162
|
# you can use @tty.rows to access the entire pane, split by line into an array.
|
186
|
-
|
187
|
-
|
163
|
+
@tty.print_rows # prints out the contents of the terminal as an array:
|
164
|
+
# ["$ echo \"Hello, world\"", "Hello, world", "$", "", "", "", ""]
|
165
|
+
|
166
|
+
# if you want to programatically access the rows, you can do so using @tty.rows
|
167
|
+
p @tty.rows # is equivalent to above statement @tty.print_rows
|
168
|
+
|
169
|
+
|
188
170
|
|
189
171
|
# you can use @tty.capture to access the entire pane.
|
190
|
-
|
191
|
-
|
172
|
+
@tty.print # prints out the contents of the terminal:
|
173
|
+
# $ echo "Hello, world"
|
174
|
+
# Hello, world
|
175
|
+
# $
|
176
|
+
|
177
|
+
# if you want to programatically access the entire pane, you can do so using @tty.capture
|
178
|
+
p "\n#{@tty.capture}" # is equivalent to above statement @tty.print
|
192
179
|
```
|
193
180
|
|
194
181
|
### Constants
|
@@ -196,6 +183,8 @@ p "\n#{@tty.capture}" # prints out the contents of the terminal
|
|
196
183
|
There are some commonly used keys available as constants to make interacting with your shell/CLI easy.
|
197
184
|
|
198
185
|
``` ruby
|
186
|
+
TTYtest::CTRLA
|
187
|
+
TTYtest::CTRLB
|
199
188
|
TTYtest::CTRLC
|
200
189
|
TTYtest::CTRLD
|
201
190
|
TTYtest::CTRLF
|
@@ -205,8 +194,12 @@ There are some commonly used keys available as constants to make interacting wit
|
|
205
194
|
TTYtest::NEWLINE # \n
|
206
195
|
TTYtest::VERTICAL_TAB
|
207
196
|
TTYtest::FORM_FEED # \f or New Page NP
|
197
|
+
TTYtest::CTRLL
|
208
198
|
TTYtest::CARRIAGE_RETURN # \r
|
199
|
+
TTYtest::CTRLU
|
200
|
+
TTYtest::CTRLW
|
209
201
|
TTYtest::ESCAPE # 27 decimal or ^[ or /033
|
202
|
+
TTYtest::CTRL_
|
210
203
|
TTYtest::DELETE
|
211
204
|
|
212
205
|
TTYtest::UP_ARROW
|
@@ -222,7 +215,7 @@ There are some commonly used keys available as constants to make interacting wit
|
|
222
215
|
|
223
216
|
### Tips
|
224
217
|
|
225
|
-
If you are using ttyest2 to test your CLI, using sh is easier than bash because you don't have to worry about user, current working directory, etc. as shown in the examples
|
218
|
+
If you are using ttyest2 to test your CLI, using sh is easier than bash because you don't have to worry about user, current working directory, etc. as shown in the examples.
|
226
219
|
|
227
220
|
If you are using ttytest2 to test your shell, using assertions like assert_row_like, assert_row_starts_with, and assert_row_ends_with are going to be extremely helpful, especially if trying to test your shell in different environments or using a docker container.
|
228
221
|
|
@@ -0,0 +1,790 @@
|
|
1
|
+
# !/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# this is from my personal project, ncsh.
|
5
|
+
# it is an example of integration/acceptance tests using ttytest2.
|
6
|
+
# ncsh is a noncanonical shell which I use ttytest2 to integration test.
|
7
|
+
|
8
|
+
require 'ttytest'
|
9
|
+
|
10
|
+
START_COL = 20
|
11
|
+
WC_C_LENGTH = '225'
|
12
|
+
SLEEP_TIME = 0.2
|
13
|
+
LS_LINES = 3
|
14
|
+
LS_ITEMS = 19
|
15
|
+
LS_FIRST_ITEM = 'CMakeLists.txt'
|
16
|
+
TAB_AUTOCOMPLETE_ROWS = 10
|
17
|
+
|
18
|
+
def assert_check_new_row(row)
|
19
|
+
@tty.assert_row_starts_with(row, "#{ENV['USER']} ")
|
20
|
+
@tty.assert_row_like(row, 'ncsh')
|
21
|
+
@tty.assert_row_ends_with(row, ' ❱ ')
|
22
|
+
@tty.assert_cursor_position(START_COL, row)
|
23
|
+
end
|
24
|
+
|
25
|
+
def starting_tests(test)
|
26
|
+
puts "===== Starting #{test} tests ====="
|
27
|
+
end
|
28
|
+
|
29
|
+
def z_database_new_test(row)
|
30
|
+
@tty.assert_row(row, 'Error opening z database file: No such file or directory')
|
31
|
+
row += 1
|
32
|
+
@tty.assert_row(row, 'Trying to create z database file.')
|
33
|
+
row += 1
|
34
|
+
@tty.assert_row(row, 'Created z database file.')
|
35
|
+
row += 1
|
36
|
+
puts 'New z database test passed'
|
37
|
+
row
|
38
|
+
end
|
39
|
+
|
40
|
+
def startup_test(row)
|
41
|
+
@tty.assert_row_starts_with(row, 'ncsh: startup time: ')
|
42
|
+
row += 1
|
43
|
+
puts 'Startup time test passed'
|
44
|
+
row
|
45
|
+
end
|
46
|
+
|
47
|
+
def newline_sanity_test(row)
|
48
|
+
assert_check_new_row(row)
|
49
|
+
@tty.send_newline
|
50
|
+
row += 1
|
51
|
+
assert_check_new_row(row)
|
52
|
+
@tty.send_newline
|
53
|
+
row += 1
|
54
|
+
puts 'Newline sanity test passed'
|
55
|
+
row
|
56
|
+
end
|
57
|
+
|
58
|
+
def empty_line_arrow_check(row)
|
59
|
+
@tty.send_left_arrow
|
60
|
+
assert_check_new_row(row)
|
61
|
+
@tty.send_right_arrow
|
62
|
+
assert_check_new_row(row)
|
63
|
+
end
|
64
|
+
|
65
|
+
def empty_line_sanity_test(row)
|
66
|
+
assert_check_new_row(row)
|
67
|
+
empty_line_arrow_check(row)
|
68
|
+
@tty.send_backspace
|
69
|
+
assert_check_new_row(row)
|
70
|
+
@tty.send_delete
|
71
|
+
assert_check_new_row(row)
|
72
|
+
puts 'Empty line sanity test passed'
|
73
|
+
row
|
74
|
+
end
|
75
|
+
|
76
|
+
def startup_tests(row, run_z_database_new_tests)
|
77
|
+
starting_tests 'startup tests'
|
78
|
+
|
79
|
+
row = z_database_new_test row if run_z_database_new_tests
|
80
|
+
row = startup_test row
|
81
|
+
row = newline_sanity_test row
|
82
|
+
|
83
|
+
empty_line_sanity_test row
|
84
|
+
end
|
85
|
+
|
86
|
+
def basic_ls_test(row)
|
87
|
+
assert_check_new_row(row)
|
88
|
+
@tty.send_keys_one_at_a_time(%(ls))
|
89
|
+
@tty.assert_cursor_position(START_COL + 2, row)
|
90
|
+
@tty.send_newline
|
91
|
+
@tty.assert_row_ends_with(row, 'ls')
|
92
|
+
row += 1
|
93
|
+
@tty.assert_row_starts_with(row, LS_FIRST_ITEM)
|
94
|
+
row += LS_LINES
|
95
|
+
puts 'Basic input (ls) test passed'
|
96
|
+
row
|
97
|
+
end
|
98
|
+
|
99
|
+
def basic_bad_command_test(row)
|
100
|
+
assert_check_new_row(row)
|
101
|
+
@tty.send_keys_one_at_a_time(%(lss)) # send a bad command
|
102
|
+
@tty.assert_cursor_position(START_COL + 3, row)
|
103
|
+
@tty.send_newline
|
104
|
+
@tty.assert_row_ends_with(row, 'lss')
|
105
|
+
row += 1
|
106
|
+
@tty.assert_row(row, 'ncsh: Could not find command or directory: No such file or directory')
|
107
|
+
row += 1
|
108
|
+
puts 'Bad command test passed'
|
109
|
+
row
|
110
|
+
end
|
111
|
+
|
112
|
+
def basic_tests(row)
|
113
|
+
starting_tests 'basic'
|
114
|
+
|
115
|
+
row = basic_ls_test row
|
116
|
+
basic_bad_command_test row
|
117
|
+
end
|
118
|
+
|
119
|
+
def home_and_end_tests(row)
|
120
|
+
starting_tests 'home and end'
|
121
|
+
|
122
|
+
assert_check_new_row(row)
|
123
|
+
@tty.send_keys_one_at_a_time(%(ss))
|
124
|
+
@tty.send_home
|
125
|
+
@tty.assert_cursor_position(START_COL, row)
|
126
|
+
@tty.send_end
|
127
|
+
@tty.assert_cursor_position(START_COL + 2, row)
|
128
|
+
@tty.send_backspaces(2)
|
129
|
+
|
130
|
+
puts 'Home and End tests passed'
|
131
|
+
row
|
132
|
+
end
|
133
|
+
|
134
|
+
def end_of_line_backspace_test(row)
|
135
|
+
assert_check_new_row(row)
|
136
|
+
@tty.send_keys_one_at_a_time(%(l))
|
137
|
+
@tty.send_backspace
|
138
|
+
assert_check_new_row(row)
|
139
|
+
puts 'End of line backspace test passed'
|
140
|
+
row
|
141
|
+
end
|
142
|
+
|
143
|
+
def multiple_end_of_line_backspace_test(row)
|
144
|
+
@tty.send_keys_one_at_a_time(%(lsssss))
|
145
|
+
@tty.assert_row_ends_with(row, %(lsssss))
|
146
|
+
@tty.send_backspaces(4)
|
147
|
+
@tty.assert_row_ends_with(row, 'ls')
|
148
|
+
@tty.send_backspaces(2)
|
149
|
+
assert_check_new_row(row)
|
150
|
+
@tty.send_keys_one_at_a_time(%(echo hello)) # make sure buffer is properly formed after backspaces
|
151
|
+
@tty.send_backspace
|
152
|
+
@tty.send_keys_one_at_a_time(%(o))
|
153
|
+
@tty.send_newline
|
154
|
+
row += 1
|
155
|
+
@tty.assert_row(row, 'hello')
|
156
|
+
row += 1
|
157
|
+
puts 'Multiple end of line backspace test passed'
|
158
|
+
row
|
159
|
+
end
|
160
|
+
|
161
|
+
def midline_backspace_test(row)
|
162
|
+
assert_check_new_row(row)
|
163
|
+
@tty.send_keys_one_at_a_time(%(lsssss))
|
164
|
+
@tty.assert_cursor_position(START_COL + 6, row)
|
165
|
+
@tty.send_left_arrows(2)
|
166
|
+
@tty.assert_cursor_position(START_COL + 4, row)
|
167
|
+
@tty.send_backspaces(4)
|
168
|
+
@tty.assert_cursor_position(START_COL, row)
|
169
|
+
@tty.assert_row_ends_with(row, 'ss')
|
170
|
+
@tty.send_right_arrows(2)
|
171
|
+
@tty.assert_cursor_position(START_COL + 2, row)
|
172
|
+
@tty.send_backspaces(2)
|
173
|
+
@tty.assert_cursor_position(START_COL, row)
|
174
|
+
@tty.send_keys_one_at_a_time(%(echo hello)) # make sure buffer is properly formed after backspaces
|
175
|
+
@tty.send_newline
|
176
|
+
row += 1
|
177
|
+
@tty.assert_row(row, 'hello')
|
178
|
+
row += 1
|
179
|
+
puts 'Midline backspace test passed'
|
180
|
+
row
|
181
|
+
end
|
182
|
+
|
183
|
+
def backspace_tests(row)
|
184
|
+
starting_tests 'backspace'
|
185
|
+
|
186
|
+
row = end_of_line_backspace_test row
|
187
|
+
row = multiple_end_of_line_backspace_test row
|
188
|
+
|
189
|
+
midline_backspace_test row
|
190
|
+
end
|
191
|
+
|
192
|
+
def end_of_line_delete_test(row)
|
193
|
+
assert_check_new_row(row)
|
194
|
+
@tty.send_keys_one_at_a_time('s')
|
195
|
+
@tty.assert_cursor_position(START_COL + 1, row)
|
196
|
+
@tty.send_left_arrow
|
197
|
+
@tty.assert_cursor_position(START_COL, row)
|
198
|
+
@tty.send_delete
|
199
|
+
assert_check_new_row(row)
|
200
|
+
puts 'End of line delete test passed'
|
201
|
+
row
|
202
|
+
end
|
203
|
+
|
204
|
+
def midline_delete_test(row)
|
205
|
+
assert_check_new_row(row)
|
206
|
+
@tty.send_keys_one_at_a_time(%(lssss))
|
207
|
+
@tty.assert_cursor_position(START_COL + 5, row)
|
208
|
+
@tty.send_left_arrows(4)
|
209
|
+
@tty.assert_cursor_position(START_COL + 1, row)
|
210
|
+
@tty.send_delete
|
211
|
+
@tty.assert_cursor_position(START_COL + 1, row)
|
212
|
+
@tty.send_deletes(3)
|
213
|
+
@tty.send_left_arrow
|
214
|
+
@tty.send_delete
|
215
|
+
assert_check_new_row(row)
|
216
|
+
@tty.send_keys_one_at_a_time(%(echo hello))
|
217
|
+
@tty.send_newline
|
218
|
+
row += 1
|
219
|
+
@tty.assert_row(row, 'hello')
|
220
|
+
row += 1
|
221
|
+
puts 'Midline delete test passed'
|
222
|
+
row
|
223
|
+
end
|
224
|
+
|
225
|
+
def delete_tests(row)
|
226
|
+
starting_tests 'delete'
|
227
|
+
|
228
|
+
row = end_of_line_delete_test row
|
229
|
+
midline_delete_test row
|
230
|
+
end
|
231
|
+
|
232
|
+
def pipe_test(row)
|
233
|
+
assert_check_new_row(row)
|
234
|
+
@tty.send_keys_one_at_a_time(%(ls | wc -c))
|
235
|
+
@tty.send_newline
|
236
|
+
row += 1
|
237
|
+
@tty.assert_row_ends_with(row, WC_C_LENGTH)
|
238
|
+
row += 1
|
239
|
+
puts 'Simple pipe test passed'
|
240
|
+
row
|
241
|
+
end
|
242
|
+
|
243
|
+
def multiple_pipes_test(row)
|
244
|
+
assert_check_new_row(row)
|
245
|
+
@tty.send_keys_one_at_a_time(%(ls | sort | wc -c))
|
246
|
+
@tty.send_newline
|
247
|
+
row += 1
|
248
|
+
@tty.assert_row_ends_with(row, WC_C_LENGTH)
|
249
|
+
row += 1
|
250
|
+
puts 'Multiple pipes test passed'
|
251
|
+
row
|
252
|
+
end
|
253
|
+
|
254
|
+
def pipe_tests(row)
|
255
|
+
starting_tests 'pipe'
|
256
|
+
|
257
|
+
row = pipe_test row
|
258
|
+
multiple_pipes_test row
|
259
|
+
end
|
260
|
+
|
261
|
+
def basic_history_test(row)
|
262
|
+
assert_check_new_row(row)
|
263
|
+
@tty.send_up_arrow
|
264
|
+
@tty.assert_row_ends_with(row, 'ls | sort | wc -c')
|
265
|
+
@tty.send_up_arrow
|
266
|
+
@tty.assert_row_ends_with(row, 'ls | wc -c')
|
267
|
+
@tty.send_down_arrow
|
268
|
+
@tty.assert_row_ends_with(row, 'ls | sort | wc -c')
|
269
|
+
@tty.send_newline
|
270
|
+
row += 1
|
271
|
+
@tty.assert_row_ends_with(row, WC_C_LENGTH)
|
272
|
+
row += 1
|
273
|
+
puts 'Basic history test passed'
|
274
|
+
row
|
275
|
+
end
|
276
|
+
|
277
|
+
def history_delete_test(row)
|
278
|
+
assert_check_new_row(row)
|
279
|
+
@tty.send_up_arrow
|
280
|
+
@tty.assert_row_ends_with(row, 'ls | sort | wc -c')
|
281
|
+
@tty.send_left_arrows(12)
|
282
|
+
@tty.send_deletes(7)
|
283
|
+
@tty.send_newline
|
284
|
+
row += 1
|
285
|
+
@tty.assert_row_ends_with(row, WC_C_LENGTH)
|
286
|
+
row += 1
|
287
|
+
puts 'History delete test passed'
|
288
|
+
row
|
289
|
+
end
|
290
|
+
|
291
|
+
def history_backspace_test(row)
|
292
|
+
# TODO: implementation
|
293
|
+
puts 'History backspace test passed'
|
294
|
+
row
|
295
|
+
end
|
296
|
+
|
297
|
+
def history_clear_test(row)
|
298
|
+
# TODO: implementation
|
299
|
+
puts 'History clear test passed'
|
300
|
+
row
|
301
|
+
end
|
302
|
+
|
303
|
+
def history_tests(row)
|
304
|
+
starting_tests 'history'
|
305
|
+
|
306
|
+
row = basic_history_test row
|
307
|
+
# row =
|
308
|
+
history_delete_test row
|
309
|
+
# row = history_backspace_test
|
310
|
+
# history_clear_test
|
311
|
+
end
|
312
|
+
|
313
|
+
def basic_stdout_redirection_test(row)
|
314
|
+
assert_check_new_row(row)
|
315
|
+
@tty.send_keys_one_at_a_time(%(ls > t.txt))
|
316
|
+
@tty.send_newline
|
317
|
+
sleep SLEEP_TIME
|
318
|
+
row += 1
|
319
|
+
assert_check_new_row(row)
|
320
|
+
@tty.send_keys_one_at_a_time(%(head -1 t.txt))
|
321
|
+
@tty.send_newline
|
322
|
+
sleep SLEEP_TIME
|
323
|
+
row += 1
|
324
|
+
@tty.assert_row_starts_with(row, LS_FIRST_ITEM)
|
325
|
+
row += 1
|
326
|
+
assert_check_new_row(row)
|
327
|
+
@tty.send_keys_one_at_a_time(%(rm t.txt))
|
328
|
+
@tty.send_newline
|
329
|
+
row += 1
|
330
|
+
puts 'Basic output redirection test passed'
|
331
|
+
row
|
332
|
+
end
|
333
|
+
|
334
|
+
def piped_stdout_redirection_test(row)
|
335
|
+
assert_check_new_row(row)
|
336
|
+
@tty.send_keys_one_at_a_time(%(ls | sort -r > t2.txt))
|
337
|
+
@tty.assert_row_ends_with(row, %(ls | sort -r > t2.txt))
|
338
|
+
@tty.send_newline
|
339
|
+
sleep SLEEP_TIME
|
340
|
+
row += 1
|
341
|
+
assert_check_new_row(row)
|
342
|
+
@tty.send_keys_one_at_a_time(%(head -1 t2.txt))
|
343
|
+
@tty.assert_row_ends_with(row, %(head -1 t2.txt))
|
344
|
+
@tty.send_newline
|
345
|
+
sleep SLEEP_TIME
|
346
|
+
row += 1
|
347
|
+
@tty.assert_row_starts_with(row, 'tests_z.sh')
|
348
|
+
row += 1
|
349
|
+
assert_check_new_row(row)
|
350
|
+
@tty.send_keys_one_at_a_time(%(rm t2.txt))
|
351
|
+
@tty.send_newline
|
352
|
+
row += 1
|
353
|
+
puts 'Piped output redirection test passed'
|
354
|
+
row
|
355
|
+
end
|
356
|
+
|
357
|
+
def multiple_piped_stdout_redirection_test(row)
|
358
|
+
assert_check_new_row(row)
|
359
|
+
@tty.send_keys_one_at_a_time(%(ls | sort | wc -c > t3.txt))
|
360
|
+
@tty.assert_row_ends_with(row, %(ls | sort | wc -c > t3.txt))
|
361
|
+
@tty.send_newline
|
362
|
+
sleep SLEEP_TIME
|
363
|
+
row += 1
|
364
|
+
assert_check_new_row(row)
|
365
|
+
@tty.send_keys_one_at_a_time(%(head -1 t3.txt))
|
366
|
+
@tty.assert_row_ends_with(row, %(head -1 t3.txt))
|
367
|
+
@tty.send_newline
|
368
|
+
sleep SLEEP_TIME
|
369
|
+
row += 1
|
370
|
+
@tty.assert_row_starts_with(row, (WC_C_LENGTH.to_i + 't3.txt'.length + 1).to_s)
|
371
|
+
row += 1
|
372
|
+
assert_check_new_row(row)
|
373
|
+
@tty.send_keys_one_at_a_time(%(rm t3.txt))
|
374
|
+
@tty.send_newline
|
375
|
+
row += 1
|
376
|
+
puts 'Multiple piped output redirection test passed'
|
377
|
+
row
|
378
|
+
end
|
379
|
+
|
380
|
+
def stdout_redirection_tests(row)
|
381
|
+
starting_tests 'stdout redirection'
|
382
|
+
|
383
|
+
row = basic_stdout_redirection_test row
|
384
|
+
row = piped_stdout_redirection_test row
|
385
|
+
multiple_piped_stdout_redirection_test row
|
386
|
+
end
|
387
|
+
|
388
|
+
def z_add_tests(row)
|
389
|
+
starting_tests 'z_add'
|
390
|
+
assert_check_new_row(row)
|
391
|
+
@tty.send_keys_one_at_a_time(%(z add ~/.config\n))
|
392
|
+
row += 1
|
393
|
+
@tty.assert_row_ends_with(row, %(Added new entry to z database.))
|
394
|
+
row += 1
|
395
|
+
@tty.send_keys_one_at_a_time(%(z add ~/.config\n))
|
396
|
+
row += 1
|
397
|
+
@tty.assert_row_ends_with(row, 'Entry already exists in z database.')
|
398
|
+
row += 1
|
399
|
+
puts 'z add tests passed'
|
400
|
+
row
|
401
|
+
end
|
402
|
+
|
403
|
+
def basic_stdin_redirection_test(row)
|
404
|
+
assert_check_new_row(row)
|
405
|
+
@tty.send_keys_one_at_a_time(%(ls > t.txt))
|
406
|
+
@tty.send_newline
|
407
|
+
sleep SLEEP_TIME
|
408
|
+
row += 1
|
409
|
+
assert_check_new_row(row)
|
410
|
+
@tty.send_keys_one_at_a_time(%(sort < t.txt))
|
411
|
+
@tty.send_newline
|
412
|
+
sleep SLEEP_TIME
|
413
|
+
row += 1
|
414
|
+
@tty.assert_row_starts_with(row, LS_FIRST_ITEM)
|
415
|
+
row += LS_ITEMS
|
416
|
+
assert_check_new_row(row)
|
417
|
+
@tty.send_keys_one_at_a_time(%(rm t.txt))
|
418
|
+
@tty.send_newline
|
419
|
+
row += 1
|
420
|
+
puts 'Basic input redirection test passed'
|
421
|
+
row
|
422
|
+
end
|
423
|
+
|
424
|
+
def piped_stdin_redirection_test(row)
|
425
|
+
assert_check_new_row(row)
|
426
|
+
@tty.send_keys_one_at_a_time(%(ls > t2.txt))
|
427
|
+
@tty.assert_row_ends_with(row, %(ls > t2.txt))
|
428
|
+
@tty.send_newline
|
429
|
+
sleep SLEEP_TIME
|
430
|
+
row += 1
|
431
|
+
assert_check_new_row(row)
|
432
|
+
@tty.send_keys_one_at_a_time(%(sort | wc -c < t2.txt))
|
433
|
+
@tty.assert_row_ends_with(row, %(sort | wc -c < t2.txt))
|
434
|
+
@tty.send_newline
|
435
|
+
sleep SLEEP_TIME
|
436
|
+
row += 1
|
437
|
+
@tty.assert_row_starts_with(row, (WC_C_LENGTH.to_i + 't2.txt'.length + 1).to_s)
|
438
|
+
row += 1
|
439
|
+
assert_check_new_row(row)
|
440
|
+
@tty.send_keys_one_at_a_time(%(rm t2.txt))
|
441
|
+
@tty.send_newline
|
442
|
+
row += 1
|
443
|
+
puts 'Piped input redirection test passed'
|
444
|
+
row
|
445
|
+
end
|
446
|
+
|
447
|
+
def multiple_piped_stdin_redirection_test(row)
|
448
|
+
assert_check_new_row(row)
|
449
|
+
@tty.send_keys_one_at_a_time(%(ls > t3.txt))
|
450
|
+
@tty.assert_row_ends_with(row, %(ls > t3.txt))
|
451
|
+
@tty.send_newline
|
452
|
+
sleep SLEEP_TIME
|
453
|
+
row += 1
|
454
|
+
@tty.send_keys_one_at_a_time(%(sort | head -1 | wc -l < t3.txt))
|
455
|
+
@tty.assert_row_ends_with(row, %(sort | head -1 | wc -l < t3.txt))
|
456
|
+
@tty.send_newline
|
457
|
+
sleep SLEEP_TIME
|
458
|
+
row += 1
|
459
|
+
@tty.assert_row(row, '1')
|
460
|
+
row += 1
|
461
|
+
assert_check_new_row(row)
|
462
|
+
@tty.send_keys_one_at_a_time(%(rm t3.txt))
|
463
|
+
@tty.send_newline
|
464
|
+
row += 1
|
465
|
+
puts 'Multiple piped input redirection test passed'
|
466
|
+
row
|
467
|
+
end
|
468
|
+
|
469
|
+
def stdin_redirection_tests(row)
|
470
|
+
starting_tests 'stdin redirection'
|
471
|
+
|
472
|
+
row = basic_stdin_redirection_test row
|
473
|
+
row = piped_stdin_redirection_test row
|
474
|
+
multiple_piped_stdin_redirection_test row
|
475
|
+
end
|
476
|
+
|
477
|
+
def basic_autocompletion_test(row)
|
478
|
+
assert_check_new_row(row)
|
479
|
+
@tty.send_keys_one_at_a_time(%(l))
|
480
|
+
@tty.send_right_arrow
|
481
|
+
@tty.assert_row_ends_with(row, %(ls))
|
482
|
+
@tty.send_backspaces(2)
|
483
|
+
|
484
|
+
puts 'Basic autocompletion test passed'
|
485
|
+
row
|
486
|
+
end
|
487
|
+
|
488
|
+
def backspace_and_delete_autocompletion_test(row)
|
489
|
+
assert_check_new_row(row)
|
490
|
+
@tty.send_keys_one_at_a_time(%(ls |))
|
491
|
+
@tty.send_right_arrow
|
492
|
+
@tty.assert_row_ends_with(row, %(ls | sort))
|
493
|
+
|
494
|
+
@tty.send_left_arrows(6)
|
495
|
+
@tty.send_deletes(6)
|
496
|
+
@tty.send_keys_one_at_a_time(%(|))
|
497
|
+
@tty.send_right_arrow
|
498
|
+
@tty.assert_row_ends_with(row, %(ls | sort))
|
499
|
+
|
500
|
+
@tty.send_keys_one_at_a_time(%( |))
|
501
|
+
@tty.send_right_arrow
|
502
|
+
@tty.assert_row_ends_with(row, %(ls | sort | wc -c))
|
503
|
+
@tty.send_newline
|
504
|
+
row += 1
|
505
|
+
@tty.assert_row(row, WC_C_LENGTH)
|
506
|
+
row += 1
|
507
|
+
|
508
|
+
puts 'Backspace and delete autocompletion test passed'
|
509
|
+
row
|
510
|
+
end
|
511
|
+
|
512
|
+
def autocompletion_tests(row)
|
513
|
+
starting_tests 'autocompletion'
|
514
|
+
|
515
|
+
row = basic_autocompletion_test row
|
516
|
+
backspace_and_delete_autocompletion_test row
|
517
|
+
end
|
518
|
+
|
519
|
+
def help_test(row)
|
520
|
+
assert_check_new_row(row)
|
521
|
+
@tty.send_keys_one_at_a_time(%(help\n))
|
522
|
+
row += 1
|
523
|
+
@tty.assert_contents_at row, row + 6, <<~TERM
|
524
|
+
ncsh by Alex Eski: help
|
525
|
+
|
526
|
+
Builtin Commands {command} {args}
|
527
|
+
q: To exit, type q, exit, or quit and press enter. You can also use Ctrl+D to exit.
|
528
|
+
cd/z: You can change directory with cd or z.
|
529
|
+
echo: You can write things to the screen using echo.
|
530
|
+
history: You can see your command history using the history command.
|
531
|
+
alex /shells/ncsh ❱
|
532
|
+
TERM
|
533
|
+
row += 7
|
534
|
+
puts 'Help test passed'
|
535
|
+
row
|
536
|
+
end
|
537
|
+
|
538
|
+
def basic_echo_test(row)
|
539
|
+
assert_check_new_row(row)
|
540
|
+
@tty.send_keys_one_at_a_time(%(echo hello))
|
541
|
+
@tty.assert_cursor_position(START_COL + 10, row)
|
542
|
+
@tty.send_newline
|
543
|
+
@tty.assert_row_ends_with(row, 'echo hello')
|
544
|
+
row += 1
|
545
|
+
@tty.assert_row(row, 'hello')
|
546
|
+
row += 1
|
547
|
+
puts 'echo hello test passed'
|
548
|
+
row
|
549
|
+
end
|
550
|
+
|
551
|
+
def builtin_tests(row)
|
552
|
+
starting_tests 'builtin'
|
553
|
+
|
554
|
+
row = help_test row
|
555
|
+
basic_echo_test row
|
556
|
+
end
|
557
|
+
|
558
|
+
def delete_line_tests(row)
|
559
|
+
starting_tests 'delete line'
|
560
|
+
assert_check_new_row(row)
|
561
|
+
@tty.send_keys_one_at_a_time(%(ls | sort ))
|
562
|
+
@tty.send_keys_exact(TTYtest::CTRLU)
|
563
|
+
assert_check_new_row(row)
|
564
|
+
@tty.send_keys_exact(TTYtest::CTRLU)
|
565
|
+
puts 'Delete line test passed'
|
566
|
+
row
|
567
|
+
end
|
568
|
+
|
569
|
+
def delete_word_tests(row)
|
570
|
+
starting_tests 'delete word'
|
571
|
+
assert_check_new_row(row)
|
572
|
+
@tty.send_keys_one_at_a_time(%(ls | sort ))
|
573
|
+
@tty.send_keys(TTYtest::CTRLW)
|
574
|
+
@tty.assert_row_ends_with(row, %(ls | sort))
|
575
|
+
@tty.send_keys(TTYtest::CTRLW)
|
576
|
+
@tty.assert_row_ends_with(row, %(ls |))
|
577
|
+
@tty.send_keys(TTYtest::CTRLW)
|
578
|
+
@tty.assert_row_ends_with(row, %(ls))
|
579
|
+
@tty.send_keys(TTYtest::CTRLW)
|
580
|
+
puts 'Delete word test passed'
|
581
|
+
row
|
582
|
+
end
|
583
|
+
|
584
|
+
def tab_out_autocompletion_test(row)
|
585
|
+
assert_check_new_row(row)
|
586
|
+
@tty.send_keys_one_at_a_time(%(ls))
|
587
|
+
@tty.send_keys(TTYtest::TAB)
|
588
|
+
row += 1
|
589
|
+
@tty.assert_row_ends_with(row, %(ls > t.txt))
|
590
|
+
@tty.send_keys(TTYtest::TAB)
|
591
|
+
row += TAB_AUTOCOMPLETE_ROWS
|
592
|
+
assert_check_new_row(row)
|
593
|
+
|
594
|
+
puts 'Tab out of autocompletion test passed'
|
595
|
+
row
|
596
|
+
end
|
597
|
+
|
598
|
+
def arrows_move_tab_autocompletion_test(row)
|
599
|
+
assert_check_new_row(row)
|
600
|
+
@tty.send_keys_one_at_a_time(%(ls))
|
601
|
+
@tty.send_keys(TTYtest::TAB)
|
602
|
+
row += 1
|
603
|
+
cursor_x_before = @tty.cursor_x
|
604
|
+
cursor_y_before = @tty.cursor_y
|
605
|
+
@tty.send_up_arrow
|
606
|
+
@tty.assert_cursor_position(cursor_x_before, cursor_y_before)
|
607
|
+
@tty.send_down_arrow
|
608
|
+
@tty.assert_cursor_position(cursor_x_before, cursor_y_before + 1)
|
609
|
+
@tty.send_down_arrows(TAB_AUTOCOMPLETE_ROWS + 1)
|
610
|
+
@tty.assert_cursor_position(cursor_x_before, cursor_y_before + 8)
|
611
|
+
@tty.send_keys(TTYtest::TAB)
|
612
|
+
row += TAB_AUTOCOMPLETE_ROWS
|
613
|
+
|
614
|
+
puts 'Arrows autocompletion test passed'
|
615
|
+
row
|
616
|
+
end
|
617
|
+
|
618
|
+
def select_tab_autocompletion_test(row)
|
619
|
+
assert_check_new_row(row)
|
620
|
+
@tty.send_keys_one_at_a_time(%(ls))
|
621
|
+
@tty.send_keys(TTYtest::TAB)
|
622
|
+
row += 1
|
623
|
+
@tty.send_down_arrows(5)
|
624
|
+
@tty.send_newline
|
625
|
+
row += TAB_AUTOCOMPLETE_ROWS + 1
|
626
|
+
@tty.assert_row_ends_with(row, WC_C_LENGTH)
|
627
|
+
row += 1
|
628
|
+
|
629
|
+
puts 'Select tab autocompletion test passed'
|
630
|
+
row
|
631
|
+
end
|
632
|
+
|
633
|
+
def tab_autocompletion_tests(row)
|
634
|
+
starting_tests 'tab autocompletion'
|
635
|
+
|
636
|
+
row = tab_out_autocompletion_test row
|
637
|
+
row = arrows_move_tab_autocompletion_test row
|
638
|
+
select_tab_autocompletion_test row
|
639
|
+
end
|
640
|
+
|
641
|
+
def assert_check_syntax_error(row, input)
|
642
|
+
assert_check_new_row(row)
|
643
|
+
@tty.send_keys_one_at_a_time(input)
|
644
|
+
@tty.send_newline
|
645
|
+
row += 1
|
646
|
+
@tty.assert_row_starts_with(row, 'ncsh: Invalid syntax:')
|
647
|
+
row += 1
|
648
|
+
row
|
649
|
+
end
|
650
|
+
|
651
|
+
def operators_invalid_syntax_first_position_test(row)
|
652
|
+
# tries sending operator as only character to ensure invalid syntax is shown to user
|
653
|
+
row = assert_check_syntax_error(row, '|') # pipe
|
654
|
+
row = assert_check_syntax_error(row, '>') # output redirection
|
655
|
+
row = assert_check_syntax_error(row, '>>') # output redirection append
|
656
|
+
row = assert_check_syntax_error(row, '<') # input redirection
|
657
|
+
row = assert_check_syntax_error(row, '2>') # error redirection
|
658
|
+
row = assert_check_syntax_error(row, '2>>') # error redirection append
|
659
|
+
row = assert_check_syntax_error(row, '&>') # output and error redirection
|
660
|
+
row = assert_check_syntax_error(row, '&>>') # output and error redirection append
|
661
|
+
row = assert_check_syntax_error(row, '&') # background job
|
662
|
+
puts 'Invalid syntax in first position test passed'
|
663
|
+
row
|
664
|
+
end
|
665
|
+
|
666
|
+
def operators_invalid_syntax_last_position_test(row)
|
667
|
+
row = assert_check_syntax_error(row, 'ls |') # pipe
|
668
|
+
row = assert_check_syntax_error(row, 'ls >') # output redirection
|
669
|
+
row = assert_check_syntax_error(row, 'ls >>') # output redirection append
|
670
|
+
row = assert_check_syntax_error(row, 'sort <') # input redirection
|
671
|
+
row = assert_check_syntax_error(row, 'ls 2>') # error redirection
|
672
|
+
row = assert_check_syntax_error(row, 'ls 2>>') # error redirection append
|
673
|
+
row = assert_check_syntax_error(row, 'ls &>') # output and error redirection
|
674
|
+
row = assert_check_syntax_error(row, 'ls &>>') # output and error redirection append
|
675
|
+
puts 'Invalid syntax in last position test passed'
|
676
|
+
row
|
677
|
+
end
|
678
|
+
|
679
|
+
# invalid operator usage to ensure invalid syntax is shown to user
|
680
|
+
def syntax_error_tests(row)
|
681
|
+
starting_tests 'syntax errors'
|
682
|
+
|
683
|
+
row = operators_invalid_syntax_first_position_test row
|
684
|
+
operators_invalid_syntax_last_position_test row
|
685
|
+
end
|
686
|
+
|
687
|
+
def basic_stderr_redirection_test(row)
|
688
|
+
assert_check_new_row(row)
|
689
|
+
@tty.send_keys_one_at_a_time(%(lss 2> t4.txt))
|
690
|
+
@tty.send_newline
|
691
|
+
sleep SLEEP_TIME
|
692
|
+
row += 1
|
693
|
+
@tty.send_keys_one_at_a_time(%(cat t4.txt))
|
694
|
+
@tty.send_newline
|
695
|
+
row += 1
|
696
|
+
@tty.assert_row_ends_with(row, 'No such file or directory')
|
697
|
+
row += 1
|
698
|
+
@tty.send_keys_one_at_a_time(%(rm t4.txt))
|
699
|
+
@tty.send_newline
|
700
|
+
row += 1
|
701
|
+
|
702
|
+
puts 'Basic stderr redirection test passed'
|
703
|
+
row
|
704
|
+
end
|
705
|
+
|
706
|
+
def stderr_redirection_tests(row)
|
707
|
+
starting_tests 'sterr redirection'
|
708
|
+
|
709
|
+
basic_stderr_redirection_test row
|
710
|
+
end
|
711
|
+
|
712
|
+
def basic_stdout_and_stderr_redirection_stderr_test(row)
|
713
|
+
assert_check_new_row(row)
|
714
|
+
@tty.send_keys_one_at_a_time(%(lss &> t4.txt))
|
715
|
+
@tty.send_newline
|
716
|
+
sleep SLEEP_TIME
|
717
|
+
row += 1
|
718
|
+
@tty.send_keys_one_at_a_time(%(cat t4.txt))
|
719
|
+
@tty.send_newline
|
720
|
+
row += 1
|
721
|
+
@tty.assert_row_ends_with(row, 'No such file or directory')
|
722
|
+
row += 1
|
723
|
+
@tty.send_keys_one_at_a_time(%(rm t4.txt))
|
724
|
+
@tty.send_newline
|
725
|
+
row += 1
|
726
|
+
|
727
|
+
puts 'Basic stdout and stderr redirection stderr test passed'
|
728
|
+
row
|
729
|
+
end
|
730
|
+
|
731
|
+
def basic_stdout_and_stderr_redirection_stdout_test(row)
|
732
|
+
assert_check_new_row(row)
|
733
|
+
@tty.send_keys_one_at_a_time(%(ls &> t4.txt))
|
734
|
+
@tty.send_newline
|
735
|
+
sleep SLEEP_TIME
|
736
|
+
row += 1
|
737
|
+
@tty.send_keys_one_at_a_time(%(cat t4.txt | head -1))
|
738
|
+
@tty.send_newline
|
739
|
+
row += 1
|
740
|
+
@tty.assert_row_ends_with(row, LS_FIRST_ITEM)
|
741
|
+
row += 1
|
742
|
+
@tty.send_keys_one_at_a_time(%(rm t4.txt))
|
743
|
+
@tty.send_newline
|
744
|
+
row += 1
|
745
|
+
|
746
|
+
puts 'Basic stdout and stderr redirection stdout test passed'
|
747
|
+
row
|
748
|
+
end
|
749
|
+
|
750
|
+
def stdout_and_stderr_redirection_tests(row)
|
751
|
+
starting_tests 'stdout and sterr redirection'
|
752
|
+
|
753
|
+
row = basic_stdout_and_stderr_redirection_stderr_test row
|
754
|
+
basic_stdout_and_stderr_redirection_stdout_test row
|
755
|
+
end
|
756
|
+
|
757
|
+
row = 0
|
758
|
+
@tty = TTYtest.new_terminal(%(PS1='$ ' ./bin/ncsh), width: 120, height: 120)
|
759
|
+
|
760
|
+
row = startup_tests(row, true)
|
761
|
+
row = basic_tests row
|
762
|
+
row = home_and_end_tests row
|
763
|
+
row = backspace_tests row
|
764
|
+
row = delete_tests row
|
765
|
+
row = pipe_tests row
|
766
|
+
row = history_tests row
|
767
|
+
row = stdout_redirection_tests row
|
768
|
+
row = z_add_tests row
|
769
|
+
row = stdin_redirection_tests row
|
770
|
+
row = autocompletion_tests row
|
771
|
+
row = builtin_tests row
|
772
|
+
row = delete_line_tests row
|
773
|
+
row = delete_word_tests row
|
774
|
+
tab_autocompletion_tests row
|
775
|
+
@tty.send_keys_exact(%(quit))
|
776
|
+
@tty.send_newline
|
777
|
+
|
778
|
+
row = 0
|
779
|
+
@tty = TTYtest.new_terminal(%(PS1='$ ' ./bin/ncsh), width: 180, height: 150)
|
780
|
+
row = startup_tests(row, false)
|
781
|
+
row = syntax_error_tests row
|
782
|
+
row = stderr_redirection_tests row
|
783
|
+
stdout_and_stderr_redirection_tests row
|
784
|
+
|
785
|
+
# troubleshooting
|
786
|
+
# @tty.print
|
787
|
+
# @tty.print_rows
|
788
|
+
# p @tty.to_s
|
789
|
+
|
790
|
+
puts 'All tests passed!'
|
data/lib/ttytest/terminal.rb
CHANGED
@@ -24,6 +24,10 @@ module TTYtest
|
|
24
24
|
# @!method send_keys_one_at_a_time(keys)
|
25
25
|
# Simulate typing keys into the terminal. For noncanonical cli's/shells which read character by character.
|
26
26
|
# @param [String] keys keys to send to the terminal
|
27
|
+
# @!method send_line(line)
|
28
|
+
# Simulate sending a line to the terminal and hitting enter.
|
29
|
+
# @!method send_line_then_sleep(line, sleep_time)
|
30
|
+
# Simulate sending a line to the terminal and hitting enter, then wait for the sleep_time.
|
27
31
|
# @!method send_newline
|
28
32
|
# Simulate typing enter by sending newline character to the terminal.
|
29
33
|
# @!method send_newlines
|
@@ -74,6 +78,7 @@ module TTYtest
|
|
74
78
|
# @return [Capture] instantaneous state of the terminal when called
|
75
79
|
def_delegators :@driver_terminal,
|
76
80
|
:send_keys, :send_keys_one_at_a_time,
|
81
|
+
:send_line, :send_line_then_sleep,
|
77
82
|
:send_newline, :send_newlines,
|
78
83
|
:send_delete, :send_deletes,
|
79
84
|
:send_backspace, :send_backspaces,
|
data/lib/ttytest/tmux/session.rb
CHANGED
@@ -13,7 +13,8 @@ module TTYtest
|
|
13
13
|
ObjectSpace.define_finalizer(@id, proc {
|
14
14
|
begin
|
15
15
|
driver.tmux(*%W[kill-session -t #{name}])
|
16
|
-
rescue ThreadError => _e # final session always throws
|
16
|
+
rescue ThreadError => _e # final session always throws during testing (running rake),
|
17
|
+
# throws error 'ThreadError can't alloc new'
|
17
18
|
end
|
18
19
|
})
|
19
20
|
end
|
@@ -54,6 +55,18 @@ module TTYtest
|
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
58
|
+
# Send line to tmux, no need to worry about newline character
|
59
|
+
def send_line(line)
|
60
|
+
send_keys_one_at_a_time(line)
|
61
|
+
send_newline unless line[-1] == '\n'
|
62
|
+
end
|
63
|
+
|
64
|
+
# Send line then sleep for sleep_time
|
65
|
+
def send_line_then_sleep(line, sleep_time)
|
66
|
+
send_line(line)
|
67
|
+
sleep sleep_time
|
68
|
+
end
|
69
|
+
|
57
70
|
def send_newline
|
58
71
|
driver.tmux(*%W[send-keys -t #{name} -l], %(\n))
|
59
72
|
end
|
data/lib/ttytest/version.rb
CHANGED
data/notes.txt
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ttytest2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Eski
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-01-
|
11
|
+
date: 2025-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,8 +94,7 @@ files:
|
|
94
94
|
- Gemfile
|
95
95
|
- README.md
|
96
96
|
- Rakefile
|
97
|
-
- examples/
|
98
|
-
- examples/noncanonical_integration_tests.rb
|
97
|
+
- examples/integration_tests.rb
|
99
98
|
- lib/ttytest.rb
|
100
99
|
- lib/ttytest/capture.rb
|
101
100
|
- lib/ttytest/constants.rb
|
@@ -1,85 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# example testing a noncanonical shell, ncsh
|
5
|
-
|
6
|
-
require 'ttytest'
|
7
|
-
|
8
|
-
START_COL = 19
|
9
|
-
|
10
|
-
def assert_check_new_row(row)
|
11
|
-
@tty.assert_row_starts_with(row, "#{ENV['USER']}:")
|
12
|
-
@tty.assert_row_like(row, 'ncsh')
|
13
|
-
@tty.assert_row_ends_with(row, '$')
|
14
|
-
@tty.assert_cursor_position(START_COL, row)
|
15
|
-
end
|
16
|
-
|
17
|
-
@tty = TTYtest.new_terminal(%(PS1='$ ' ./bin/ncsh), width: 80, height: 24)
|
18
|
-
|
19
|
-
row = 0
|
20
|
-
|
21
|
-
# # # # Basic Tests # # # #
|
22
|
-
puts 'Starting basic tests'
|
23
|
-
|
24
|
-
@tty.assert_row_starts_with(row, 'ncsh: startup time: ')
|
25
|
-
row += 1
|
26
|
-
|
27
|
-
assert_check_new_row(row)
|
28
|
-
@tty.send_keys(%(ls))
|
29
|
-
@tty.assert_cursor_position(START_COL + 2, 1)
|
30
|
-
@tty.send_newline
|
31
|
-
@tty.assert_row_ends_with(row, 'ls')
|
32
|
-
row += 1
|
33
|
-
@tty.assert_row_starts_with(row, 'LICENSE')
|
34
|
-
row = 9
|
35
|
-
|
36
|
-
assert_check_new_row(row)
|
37
|
-
@tty.send_keys(%(echo hello))
|
38
|
-
@tty.send_newline
|
39
|
-
row += 1
|
40
|
-
@tty.assert_row(row, 'hello')
|
41
|
-
row += 1
|
42
|
-
|
43
|
-
assert_check_new_row(row)
|
44
|
-
@tty.send_keys(%(lss)) # send a bad command
|
45
|
-
@tty.send_newline
|
46
|
-
row += 1
|
47
|
-
@tty.assert_row(row, 'ncsh: Could not find command or directory: No such file or directory')
|
48
|
-
row += 1
|
49
|
-
|
50
|
-
puts 'Starting backspace tests'
|
51
|
-
|
52
|
-
# end of line backspace
|
53
|
-
assert_check_new_row(row)
|
54
|
-
@tty.send_keys(%(l))
|
55
|
-
@tty.send_backspace
|
56
|
-
assert_check_new_row(row)
|
57
|
-
|
58
|
-
# multiple end of line backspaces
|
59
|
-
@tty.send_keys(%(lsssss))
|
60
|
-
@tty.send_backspaces(4)
|
61
|
-
@tty.assert_row_ends_with(row, 'ls')
|
62
|
-
@tty.send_backspaces(2)
|
63
|
-
@tty.send_keys(%(echo hello)) # make sure buffer is properly formed after backspaces
|
64
|
-
@tty.send_newline
|
65
|
-
row += 1
|
66
|
-
@tty.assert_row(row, 'hello')
|
67
|
-
row += 1
|
68
|
-
|
69
|
-
# midline backspace
|
70
|
-
assert_check_new_row(row)
|
71
|
-
@tty.send_keys(%(lsssss))
|
72
|
-
@tty.assert_cursor_position(START_COL + 6, row)
|
73
|
-
@tty.send_left_arrows(2)
|
74
|
-
@tty.assert_cursor_position(START_COL + 4, row)
|
75
|
-
@tty.send_backspaces(4)
|
76
|
-
@tty.assert_cursor_position(START_COL, row)
|
77
|
-
@tty.assert_row_ends_with(row, '$ ss')
|
78
|
-
@tty.send_right_arrows(2)
|
79
|
-
@tty.assert_cursor_position(START_COL + 2, row)
|
80
|
-
@tty.send_backspaces(2)
|
81
|
-
@tty.assert_cursor_position(START_COL, row)
|
82
|
-
@tty.send_keys(%(echo hello)) # make sure buffer is properly formed after backspaces
|
83
|
-
@tty.send_newline
|
84
|
-
row += 1
|
85
|
-
@tty.assert_row(row, 'hello')
|
@@ -1,80 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# example testing a canonical shell called shl
|
5
|
-
|
6
|
-
require 'ttytest'
|
7
|
-
|
8
|
-
START_COL = 19
|
9
|
-
|
10
|
-
def assert_check_new_row(row)
|
11
|
-
@tty.assert_row_starts_with(row, "#{ENV['USER']}:")
|
12
|
-
@tty.assert_row_like(row, 'shl')
|
13
|
-
@tty.assert_row_ends_with(row, '$')
|
14
|
-
@tty.assert_cursor_position(START_COL, row)
|
15
|
-
end
|
16
|
-
|
17
|
-
@tty = TTYtest.new_terminal(%(PS1='$ ' ./bin/shl), width: 80, height: 24)
|
18
|
-
|
19
|
-
row = 0
|
20
|
-
|
21
|
-
@tty.assert_row_starts_with(row, 'shl: startup time: ')
|
22
|
-
row += 1
|
23
|
-
|
24
|
-
assert_check_new_row(row)
|
25
|
-
@tty.send_keys_one_at_a_time(%(ls))
|
26
|
-
@tty.assert_cursor_position(START_COL + 2, 1)
|
27
|
-
@tty.send_newline
|
28
|
-
@tty.assert_row_ends_with(row, 'ls')
|
29
|
-
row += 1
|
30
|
-
@tty.assert_row_starts_with(row, 'LICENSE')
|
31
|
-
row = 9
|
32
|
-
|
33
|
-
assert_check_new_row(row)
|
34
|
-
@tty.send_keys_one_at_a_time(%(echo hello))
|
35
|
-
@tty.send_newline
|
36
|
-
row += 1
|
37
|
-
@tty.assert_row(row, 'hello')
|
38
|
-
row += 1
|
39
|
-
|
40
|
-
assert_check_new_row(row)
|
41
|
-
@tty.send_keys_one_at_a_time(%(lss)) # send a bad command
|
42
|
-
@tty.send_newline
|
43
|
-
row += 1
|
44
|
-
@tty.assert_row(row, 'shl: Could not find command or directory: No such file or directory')
|
45
|
-
row += 1
|
46
|
-
|
47
|
-
# end of line backspace
|
48
|
-
assert_check_new_row(row)
|
49
|
-
@tty.send_keys_one_at_a_time(%(l))
|
50
|
-
@tty.send_backspace
|
51
|
-
assert_check_new_row(row)
|
52
|
-
|
53
|
-
# multiple end of line backspaces
|
54
|
-
@tty.send_keys_one_at_a_time(%(lsssss))
|
55
|
-
@tty.send_backspaces(4)
|
56
|
-
@tty.assert_row_ends_with(row, '$ ls')
|
57
|
-
@tty.send_backspaces(2)
|
58
|
-
@tty.send_keys_one_at_a_time(%(echo hello)) # make sure buffer is properly formed after backspaces
|
59
|
-
@tty.send_newline
|
60
|
-
row += 1
|
61
|
-
@tty.assert_row(row, 'hello')
|
62
|
-
row += 1
|
63
|
-
|
64
|
-
# midline backspace
|
65
|
-
assert_check_new_row(row)
|
66
|
-
@tty.send_keys_one_at_a_time(%(lsssss))
|
67
|
-
@tty.assert_cursor_position(START_COL + 6, row)
|
68
|
-
@tty.send_left_arrows(2)
|
69
|
-
@tty.assert_cursor_position(START_COL + 4, row)
|
70
|
-
@tty.send_backspaces(4)
|
71
|
-
@tty.assert_cursor_position(START_COL, row)
|
72
|
-
@tty.assert_row_ends_with(row, '$ ss')
|
73
|
-
@tty.send_right_arrows(2)
|
74
|
-
@tty.assert_cursor_position(START_COL + 2, row)
|
75
|
-
@tty.send_backspaces(2)
|
76
|
-
@tty.assert_cursor_position(START_COL, row)
|
77
|
-
@tty.send_keys_one_at_a_time(%(echo hello)) # make sure buffer is properly formed after backspaces
|
78
|
-
@tty.send_newline
|
79
|
-
row += 1
|
80
|
-
@tty.assert_row(row, 'hello')
|