ttytest2 1.2.0 → 1.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba5f1abfa44480c3955c2c0ff48e724ea09f060aa90417caa72cdcf2b15a29bc
4
- data.tar.gz: 904200415a856ad8e9b077ea30f5bc9dea085f966ec896e5e19d328b39039000
3
+ metadata.gz: 15e01162a84bf95dce1f5694dfc57daa77decd5c7136af567c469d4e2148daa6
4
+ data.tar.gz: e29d3aae969a70b6bb0ba1003a87b4da7e2b819c0e80595f6a9604b11c52f7a8
5
5
  SHA512:
6
- metadata.gz: 8d117e8a03132b3a0dd0c93bc0c8a864ffce023d286c98e495a7b8ddafccbdff49d7f2db49c864ceae9f88fd4529322294ec7c7b2e925806e7af721d94ba12e0
7
- data.tar.gz: 1809000f0fea428a053449c07b7b94ca93028dfe3c91d815f0d903bb052c48736f542edb2493cd4fde39bed3c0fa495adca1bd14afccbe186c4cdf9735f54cf5
6
+ metadata.gz: dd61cb3a8e293c928e1d3b5fcb3637273bd6a27a55ecae96ea737b1f0b6959df44c223aae366131175411320d0c185d3b3a339a128c519e43a4d75dbe8990147
7
+ data.tar.gz: 38a1a8dfa89b91b8209fb033fe2a7b3af161f4bfdc87dd07bc2f30154c1f925cf48b1c4697eef25a11773e1a65eb0422edd6811ffcef56559167709e85e63180
data/README.md CHANGED
@@ -196,8 +196,10 @@ Helper functions to make sending output easier! They use the methods above under
196
196
 
197
197
  * `send_newline` # simulate hitting enter, equivalent to @tty.send_keys(%(\n))
198
198
  * `send_newlines(number_of_times)` # equivalent to calling send_newline number_of_times
199
- * `send_enter` # alias for send_newline
200
- * `send_enters(number_of_times)` # alias for send_newlines
199
+
200
+ * `send_return` # simulate hitting enter, equivalent to @tty.send_keys(%(\r))
201
+ * `send_returns(number_of_times)` # equivalent to calling send_return number_of_times
202
+
201
203
 
202
204
  * `send_backspace` # simulate hitting backspace, equivalent to @tty.send_keys(TTYtest::BACKSPACE)
203
205
  * `send_backspaces(number_of_times)` # equivalent to calling send_backspace number_of_times
@@ -225,6 +227,9 @@ Helper functions to make sending output easier! They use the methods above under
225
227
  * `send_escape`
226
228
  * `send_escapes(number_of_times)`
227
229
 
230
+ * `send_tab`
231
+ * `send_tab(number_of_times)`
232
+
228
233
  ### F keys?
229
234
 
230
235
  Send F keys like F1, F2, etc. as shown below:
@@ -258,7 +263,7 @@ There are some commonly used keys available as constants to make interacting wit
258
263
  TTYtest::SHIFT_ENTER # \v
259
264
  TTYtest::FORM_FEED # \f or New Page NP
260
265
  TTYtest::CTRLL
261
- TTYtest::CARRIAGE_RETURN # \r
266
+ TTYtest::RETURN # \r
262
267
  TTYtest::CTRLU
263
268
  TTYtest::CTRLW
264
269
  TTYtest::ESCAPE # 27 decimal or ^[ or /033
@@ -278,7 +283,9 @@ There are some commonly used keys available as constants to make interacting wit
278
283
 
279
284
  ## Configurables
280
285
 
281
- Currently the only configuration for ttytest2 is max wait time.
286
+ There are 2 main configurations for ttytest2: max_wait_time, and use_return_for_newline.
287
+
288
+ ### Max wait time
282
289
 
283
290
  Max wait time represents the amount of time in seconds that ttytest2 will keep retrying an assertion before failing.
284
291
 
@@ -292,6 +299,24 @@ You can configure max wait time as shown below.
292
299
  @tty.assert_row(0, 'echo Hello, world') # this assertion would fail after 3 seconds
293
300
  ```
294
301
 
302
+ ### Use return for newline
303
+
304
+ Use return for newline tells ttytest2 to use return ('//r') instead of newline ('//n') for methods like send_line.
305
+
306
+ Some line readers may interpreter return and newline differently, so this can be useful in those cases.
307
+
308
+ You can still send newline via send_newline when this is enabled.
309
+
310
+ You can also send return by itself with send_return.
311
+
312
+ ``` ruby
313
+ @tty = TTYtest::new_terminal('', use_return_for_newline: true) # specified to use return in place of newline
314
+
315
+ @tty.send_line('hello, world!') # will have return sent after 'hello, world!'
316
+ @tty.use_return_for_newline = false
317
+ @tty.assert_row(0, 'echo Hello, world') # will have newline sent after 'echo Hello, world'
318
+ ```
319
+
295
320
  ## Troubleshooting
296
321
 
297
322
  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.
@@ -325,6 +350,8 @@ If you are using ttyest2 to test your CLI, using sh is easier than bash because
325
350
 
326
351
  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.
327
352
 
353
+ Most line readers use '\n' for newline, but some may interpret it differently and expect '\r'.
354
+
328
355
  ## Docker
329
356
 
330
357
  Easy to use from Docker. Add this to your dockerfile to get started.
@@ -9,7 +9,7 @@ module TTYtest
9
9
  class Capture
10
10
  include TTYtest::Assertions
11
11
 
12
- attr_reader :cursor_x, :cursor_y, :width, :height
12
+ attr_reader :cursor_x, :cursor_y, :width, :height, :max_wait_time, :use_return_for_newline
13
13
 
14
14
  # Used internally by drivers when called by {Terminal#capture}
15
15
  # @api private
@@ -16,7 +16,8 @@ module TTYtest
16
16
  SHIFT_ENTER = 11.chr # \v
17
17
  FORM_FEED = 12.chr # \f
18
18
  CTRLL = 12.chr
19
- CARRIAGE_RETURN = 13.chr # \r
19
+ CARRIAGE_RETURN = 13.chr # \r, left for backwards compat
20
+ RETURN = 13.chr # \r, same as CARRIAGE_RETURN
20
21
  CTRLU = 21.chr
21
22
  CTRLW = 23.chr
22
23
  ESCAPE = 27.chr # ^[ or /033 or /e
@@ -9,14 +9,15 @@ module TTYtest
9
9
  class Terminal
10
10
  extend Forwardable
11
11
 
12
- attr_accessor :max_wait_time
12
+ attr_accessor :max_wait_time, :use_return_for_newline
13
13
 
14
14
  # @api private
15
15
  # @see TTYtest.new_terminal, use this or other new_* methods instead.
16
16
  # Internal constructor.
17
- def initialize(driver_terminal)
17
+ def initialize(driver_terminal, max_wait_time, use_return_for_newline)
18
+ @max_wait_time = max_wait_time
19
+ @use_return_for_newline = use_return_for_newline
18
20
  @driver_terminal = driver_terminal
19
- @max_wait_time = TTYtest.default_max_wait_time
20
21
  end
21
22
 
22
23
  # @!method send_keys(*keys)
@@ -67,17 +68,21 @@ module TTYtest
67
68
  # @param [Integer] sleep_time the amount of time to sleep after sending the line
68
69
 
69
70
  # @!method send_newline
70
- # Simulate typing enter by sending newline character to the terminal.
71
+ # Simulate typing enter by sending newline (ALT + enter) character to the terminal.
72
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
71
73
 
72
74
  # @!method send_newlines(number_of_times)
73
- # Simulates sending newline the specified number of times.
75
+ # Simulates sending newline (ALT + enter) the specified number of times.
76
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
74
77
  # @param [Integer] number_of_times number of times to send newline
75
78
 
76
- # @!method send_enter
79
+ # @!method send_return
77
80
  # Simulate typing enter by sending newline character to the terminal.
81
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
78
82
 
79
- # @!method send_enters(number_of_times)
83
+ # @!method send_returns(number_of_times)
80
84
  # Simulates sending newline the specified number of times.
85
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
81
86
  # @param [Integer] number of times to send newline
82
87
 
83
88
  # @!method send_delete
@@ -142,6 +147,13 @@ module TTYtest
142
147
  # Simulates typing in the Escape (ESC) key in the terminal the specified number of times.
143
148
  # @param [Integer] number of times to send escape
144
149
 
150
+ # @!method send_tab
151
+ # Simulates typing in the Tab (\t) key in the terminal.
152
+
153
+ # @!method send_tabs(number_of_times)
154
+ # Simulates typing in the Tab (\t) key in the terminal the specified number of times.
155
+ # @param [Integer] number of times to send tab
156
+
145
157
  # @!method capture
146
158
  # Capture represents the current state of the terminal.
147
159
  # @return [Capture] The current state of the terminal when called
@@ -152,11 +164,13 @@ module TTYtest
152
164
  :send_line_exact, :send_lines_exact,
153
165
  :send_newline, :send_newlines,
154
166
  :send_enter, :send_enters,
167
+ :send_return, :send_returns,
155
168
  :send_delete, :send_deletes,
156
169
  :send_backspace, :send_backspaces,
157
170
  :send_left_arrow, :send_left_arrows, :send_right_arrow, :send_right_arrows,
158
171
  :send_down_arrow, :send_down_arrows, :send_up_arrow, :send_up_arrows,
159
172
  :send_keys_exact, :send_home, :send_end, :send_clear, :send_escape, :send_escapes,
173
+ :send_tab, :send_tabs,
160
174
  :capture
161
175
 
162
176
  # @!method print
@@ -31,21 +31,22 @@ module TTYtest
31
31
  @config_file_path = config_file_path
32
32
  end
33
33
 
34
- def new_terminal(cmd, width: 80, height: 24)
34
+ def new_terminal(cmd, width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
35
35
  cmd = "#{cmd}\n#{SLEEP_INFINITY}"
36
36
 
37
37
  session_name = "ttytest-#{SecureRandom.uuid}"
38
38
  tmux(*%W[-f #{@config_file_path} new-session -s #{session_name} -d -x #{width} -y #{height} #{cmd}])
39
- session = Session.new(self, session_name)
40
- Terminal.new(session)
39
+ session = Session.new(self, session_name, use_return_for_newline)
40
+ Terminal.new(session, max_wait_time, use_return_for_newline)
41
41
  end
42
42
 
43
43
  def new_default_sh_terminal
44
- new_terminal(%(PS1='$ ' /bin/sh), width: 80, height: 24)
44
+ new_terminal(%(PS1='$ ' /bin/sh), width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
45
45
  end
46
46
 
47
- def new_sh_terminal(width: 80, height: 24)
48
- new_terminal(%(PS1='$ ' /bin/sh), width: width, height: height)
47
+ def new_sh_terminal(width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
48
+ new_terminal(%(PS1='$ ' /bin/sh), width: width, height: height, max_wait_time: max_wait_time,
49
+ use_return_for_newline: use_return_for_newline)
49
50
  end
50
51
 
51
52
  # @api private
@@ -5,10 +5,11 @@ module TTYtest
5
5
  # represents a tmux session and how to send output to the current tmux session
6
6
  class Session
7
7
  # @api private
8
- def initialize(driver, name)
8
+ def initialize(driver, name, use_return_for_newline)
9
9
  @id = SecureRandom.uuid
10
10
  @driver = driver
11
11
  @name = name
12
+ @use_return_for_newline = use_return_for_newline
12
13
 
13
14
  ObjectSpace.define_finalizer(@id, proc {
14
15
  begin
@@ -58,6 +59,10 @@ module TTYtest
58
59
  # Send line to tmux, no need to worry about newline character
59
60
  def send_line(line)
60
61
  send_keys_one_at_a_time(line)
62
+ if @use_return_for_newline
63
+ send_return unless ['\n', '\r'].include?(line[-1])
64
+ return
65
+ end
61
66
  send_newline unless line[-1] == '\n'
62
67
  end
63
68
 
@@ -75,6 +80,10 @@ module TTYtest
75
80
 
76
81
  def send_line_exact(line)
77
82
  send_keys_exact(line)
83
+ if @use_return_for_newline
84
+ send_return unless ['\n', '\r'].include?(line[-1])
85
+ return
86
+ end
78
87
  send_newline unless line[-1] == '\n'
79
88
  end
80
89
 
@@ -100,7 +109,6 @@ module TTYtest
100
109
  def send_newline
101
110
  driver.tmux(*%W[send-keys -t #{name} -l], %(\n))
102
111
  end
103
- alias send_enter send_newline
104
112
 
105
113
  def send_newlines(number_of_times)
106
114
  while number_of_times.positive?
@@ -108,7 +116,17 @@ module TTYtest
108
116
  number_of_times -= 1
109
117
  end
110
118
  end
111
- alias send_enters send_newlines
119
+
120
+ def send_return
121
+ driver.tmux(*%W[send-keys -t #{name} -l], %(\r))
122
+ end
123
+
124
+ def send_returns(number_of_times)
125
+ while number_of_times.positive?
126
+ send_return
127
+ number_of_times -= 1
128
+ end
129
+ end
112
130
 
113
131
  def send_delete
114
132
  send_keys_exact(%(DC))
@@ -194,6 +212,10 @@ module TTYtest
194
212
 
195
213
  def send_clear
196
214
  send_keys_one_at_a_time(TTYtest::CLEAR)
215
+ if @use_return_for_newline
216
+ send_return
217
+ return
218
+ end
197
219
  send_newline
198
220
  end
199
221
 
@@ -208,6 +230,17 @@ module TTYtest
208
230
  end
209
231
  end
210
232
 
233
+ def send_tab
234
+ send_keys_exact(TTYtest::TAB)
235
+ end
236
+
237
+ def send_tabs(number_of_times)
238
+ while number_of_times.positive?
239
+ send_tab
240
+ number_of_times -= 1
241
+ end
242
+ end
243
+
211
244
  private
212
245
 
213
246
  attr_reader :driver, :name
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTYtest
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.0'
5
5
  end
data/lib/ttytest.rb CHANGED
@@ -16,30 +16,38 @@ module TTYtest
16
16
  # @param [String] command a valid shell command to run
17
17
  # @param [Integer] width width of the new terminal
18
18
  # @param [Integer] height height of the new terminal
19
+ # @param [Integer] max_wait_time max time to wait for screen to update before an assertion fails
20
+ # @param [bool] use_return_for_newline use return instead of newline for functions like send_line
19
21
  # @return [Terminal] a new terminal running the specified command
20
22
 
21
23
  # @!method new_default_sh_terminal
22
24
  # Create a new terminal using '/bin/sh' with width: 80 and height: 24.
23
25
  # Useful for Unixes.
26
+ # @return [Terminal] a new sh terminal
24
27
 
25
28
  # @!method new_sh_terminal(width: 80, height: 24)
26
29
  # Create a new terminal using '/bin/sh' with ability to set width and height.
27
30
  # Useful for Unixes.
31
+ # @param [Integer] max_wait_time max time to wait for screen to update before an assertion fails
32
+ # @param [bool] use_return_for_newline use return instead of newline for functions like send_line
33
+ # @return [Terminal] a new sh terminal with specified width and height
34
+
28
35
  def_delegators :driver
29
36
 
30
- def new_terminal(cmd, width: 80, height: 24, max_wait_time: 2)
31
- @max_wait_time = max_wait_time
32
- driver.new_terminal(cmd, width: width, height: height)
37
+ def new_terminal(cmd, width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
38
+ # @max_wait_time = max_wait_time
39
+ # @use_return_for_newline = use_return_for_newline
40
+ driver.new_terminal(cmd, width: width, height: height, max_wait_time: max_wait_time,
41
+ use_return_for_newline: use_return_for_newline)
33
42
  end
34
43
 
35
- def new_default_sh_terminal(max_wait_time: 2)
36
- @max_wait_time = max_wait_time
44
+ def new_default_sh_terminal
37
45
  driver.new_default_sh_terminal
38
46
  end
39
47
 
40
- def new_sh_terminal(width: 80, height: 24, max_wait_time: 2)
41
- @max_wait_time = max_wait_time
42
- driver.new_sh_terminal(width: width, height: height)
48
+ def new_sh_terminal(width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
49
+ driver.new_sh_terminal(width: width, height: height, max_wait_time: max_wait_time,
50
+ use_return_for_newline: use_return_for_newline)
43
51
  end
44
52
  end
45
53
 
data/notes.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  to push new version to github
2
- git tag v1.2.0
2
+ git tag v1.3.0
3
3
  git push origin --tags
4
4
 
5
5
  to push new version to rubygems.org
6
6
  gem build ttytest2.gemspec
7
- gem push ttytest2-1.2.0.gem
7
+ gem push ttytest2-1.3.0.gem
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: 1.2.0
4
+ version: 1.3.0
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-08-27 00:00:00.000000000 Z
11
+ date: 2025-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler