ttytest2 0.8.6 → 0.9.1

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: d5813f48d629bc3029c7c486652b5badcedbbac19b4c24946f50f8aa9df579c8
4
- data.tar.gz: 86adb037b39d0da7cdcc9920d71f1655e8864e0171ae3fabfcb7301774908102
3
+ metadata.gz: da8ddbaf4a49037e8dda3fb31986824c75819abbee94fb7954263c36a8e63414
4
+ data.tar.gz: 7091feb0fdac4857c1c0bf47a7c8158d8c90bd48d1ff321fec53aeab185443ec
5
5
  SHA512:
6
- metadata.gz: e6fe94d8ef4c818a94b487f01efee8ab8d2c1ed828b30679eed643e4388c9e77178d00c25e761881098b47512a51f696c597a82fabfa68d9e6a569ea52b0e15e
7
- data.tar.gz: 0ce32ed7e12445f1c9d4fee55ec2f9b5c27a3890c73a1a3a52b45c39c5c1931ebc08bcc6f04bf5e55d372a03b82e4b19a2ccfee4a487a427d52047d92f3fec84
6
+ metadata.gz: baab5b496e22d73a133084b2a4d58fc2fb83c95325c02227a50847adcbb876fe23f7a71e80efd69c12c2730aff64866222004db102b21613c4e4301455c15cd8
7
+ data.tar.gz: d66c05f581f565f33c9305ec9c484346790184d64ca5bdfb4b9718d95c22b842dbd2f689634548863f93cdcaced2dc94f4048dc66e6101dba8d2ef4f4856bae9
data/README.md CHANGED
@@ -20,22 +20,34 @@ It works by running commands inside a tmux session, capturing the pane, and comp
20
20
  The main way to use TTYtest is through assertions. When called on a `TTYtest::Terminal`, each of these will be retried (for up to 2 seconds).
21
21
 
22
22
  Available assertions:
23
- * `assert_row(row_number, expected_text)`
24
- * `assert_row_like(row_number, expected_text)`
25
- * `assert_row_starts_with(row_number, expected_text)`
26
- * `assert_row_ends_with(row_number, expected_text)`
27
- * `assert_cursor_position(x: x, y: y)`
28
- * `assert_cursor_visible`
29
- * `assert_cursor_hidden`
30
- * `assert_contents(lines_of_terminal)`
31
-
32
- ### Sending output
23
+ * specify row matches expected text exactly: `assert_row(row_number, expected_text) `
24
+ * specify expected position of expected text: `assert_row_at(row_number, column_start_position, column_end_position, expected_text)`
25
+ * specify row contains expected text: `assert_row_like(row_number, expected_text)`
26
+ * specify row starts with expected text: `assert_row_starts_with(row_number, expected_text)`
27
+ * specify row ends with expected text: `assert_row_ends_with(row_number, expected_text)`
28
+ * specify the current cursor position matches expected: `assert_cursor_position(x: x, y: y)`
29
+ * specify the cursor is currently visible: `assert_cursor_visible`
30
+ * specify the cursor is currently hidden: `assert_cursor_hidden`
31
+ * specify the contents of the entire terminal window: `assert_contents(lines_of_terminal)`
32
+
33
+ ### Sending Output
33
34
 
34
35
  You can send output to the terminal with the following calls.
35
36
 
36
- * `send_keys(output)`
37
+ * `send_keys(output) # for canonical shells/cli's (or multi-character keys for noncanonical shells/cli's)`
38
+ * `send_keys_one_at_a_time(output) # for noncanonical shells/cli's`
39
+ * `send_keys_exact(output) # for sending tmux specific keys (DC for delete, Escape for ESC, etc.)`
40
+
41
+ ### Output Helpers
42
+
43
+ Helper functions to make sending output easier! They use the methods above under 'Sending Output' section under the hood.
44
+
37
45
  * `send_newline # equivalent to @tty.send_keys(%(\n))`
38
- * `send_keys_one_at_a_time(output)`
46
+ * `send_newlines(number_of_times) # equivalent to calling send_newline number_of_times`
47
+ * `send_backspace # equivalent to @tty.send_keys(TTYtest::BACKSPACE)`
48
+ * `send_backspaces(number_of_times) # equivalent to calling send_backspace number_of_times`
49
+ * `send_delete # equivalent to calling send_keys_exact(%(DC))`
50
+ * `send_deletes # equivalent to calling send_delete number_of_times`
39
51
 
40
52
  ### Example Canonical CLI/Shell
41
53
 
@@ -80,6 +92,10 @@ require 'ttytest'
80
92
  @tty.send_keys_one_at_a_time('ps')
81
93
  @tty.assert_row_ends_with(0, 'ps')
82
94
  @tty.send_keys(TTYtest:NEWLINE) # can use constants instead
95
+
96
+ @tty.assert_row_starts_with(0, ENV['USER'])
97
+ @tty.assert_row_ends_with(0, '$')
98
+ @tty.send_newline # an alternative to the 2 above methods to send \n to the terminal
83
99
  ```
84
100
 
85
101
  ### Constants
@@ -88,7 +104,6 @@ There are some commonly used keys available as constants to make interacting wit
88
104
 
89
105
  ``` ruby
90
106
  TTYtest::BACKSPACE
91
- TTYtest::DELETE
92
107
  TTYtest::TAB
93
108
  TTYtest::CTRLF
94
109
  TTYtest::CTRLC
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'ttytest'
5
+
6
+ START_COL = 19
7
+
8
+ def assert_check_new_row(row)
9
+ @tty.assert_row_starts_with(row, "#{ENV['USER']}:")
10
+ @tty.assert_row_like(row, 'ncsh')
11
+ @tty.assert_row_ends_with(row, '$')
12
+ @tty.assert_cursor_position(START_COL, row)
13
+ end
14
+
15
+ @tty = TTYtest.new_terminal(%(PS1='$ ' ./bin/ncsh), width: 80, height: 24)
16
+
17
+ row = 0
18
+
19
+ # # # # Basic Tests # # # #
20
+ puts 'Starting basic tests'
21
+
22
+ @tty.assert_row_starts_with(row, 'ncsh: startup time: ')
23
+ row += 1
24
+
25
+ assert_check_new_row(row)
26
+ @tty.send_keys(%(ls))
27
+ @tty.assert_cursor_position(START_COL + 2, 1)
28
+ @tty.send_newline
29
+ @tty.assert_row_ends_with(row, 'ls')
30
+ row += 1
31
+ @tty.assert_row_starts_with(row, 'LICENSE')
32
+ row = 9
33
+
34
+ assert_check_new_row(row)
35
+ @tty.send_keys(%(echo hello))
36
+ @tty.send_newline
37
+ row += 1
38
+ @tty.assert_row(row, 'hello')
39
+ row += 1
40
+
41
+ assert_check_new_row(row)
42
+ @tty.send_keys(%(lss)) # send a bad command
43
+ @tty.send_newline
44
+ row += 1
45
+ @tty.assert_row(row, 'ncsh: Could not find command or directory: No such file or directory')
46
+ row += 1
47
+
48
+ puts 'Starting backspace tests'
49
+
50
+ # end of line backspace
51
+ assert_check_new_row(row)
52
+ @tty.send_keys(%(l))
53
+ @tty.send_backspace
54
+ assert_check_new_row(row)
55
+
56
+ # multiple end of line backspaces
57
+ @tty.send_keys(%(lsssss))
58
+ @tty.send_backspace
59
+ @tty.send_backspace
60
+ @tty.send_backspace
61
+ @tty.send_backspace
62
+ @tty.assert_row_ends_with(row, '$ ls')
63
+ @tty.send_backspace
64
+ @tty.send_backspace
65
+ @tty.send_keys(%(echo hello)) # make sure buffer is properly formed after backspaces
66
+ @tty.send_newline
67
+ row += 1
68
+ @tty.assert_row(row, 'hello')
69
+ row += 1
70
+
71
+ # midline backspace
72
+ assert_check_new_row(row)
73
+ @tty.send_keys(%(lsssss))
74
+ @tty.assert_cursor_position(START_COL + 6, row)
75
+ @tty.send_keys(TTYtest::LEFT_ARROW)
76
+ @tty.send_keys(TTYtest::LEFT_ARROW)
77
+ @tty.assert_cursor_position(START_COL + 4, row)
78
+ @tty.send_backspace
79
+ @tty.send_backspace
80
+ @tty.send_backspace
81
+ @tty.send_backspace
82
+ @tty.assert_cursor_position(START_COL, row)
83
+ @tty.assert_row_ends_with(row, '$ ss')
84
+ @tty.send_keys(TTYtest::RIGHT_ARROW)
85
+ @tty.send_keys(TTYtest::RIGHT_ARROW)
86
+ @tty.assert_cursor_position(START_COL + 2, row)
87
+ @tty.send_backspace
88
+ @tty.send_backspace
89
+ @tty.assert_cursor_position(START_COL, row)
90
+ @tty.send_keys(%(echo hello)) # make sure buffer is properly formed after backspaces
91
+ @tty.send_newline
92
+ row += 1
93
+ @tty.assert_row(row, 'hello')
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'ttytest'
5
+
6
+ START_COL = 19
7
+
8
+ def assert_check_new_row(row)
9
+ @tty.assert_row_starts_with(row, "#{ENV['USER']}:")
10
+ @tty.assert_row_like(row, 'ncsh')
11
+ @tty.assert_row_ends_with(row, '$')
12
+ @tty.assert_cursor_position(START_COL, row)
13
+ end
14
+
15
+ @tty = TTYtest.new_terminal(%(PS1='$ ' ./bin/ncsh), width: 80, height: 24)
16
+
17
+ row = 0
18
+
19
+ # # # # Basic Tests # # # #
20
+ puts 'Starting basic tests'
21
+
22
+ @tty.assert_row_starts_with(row, 'ncsh: startup time: ')
23
+ row += 1
24
+
25
+ assert_check_new_row(row)
26
+ @tty.send_keys_one_at_a_time(%(ls))
27
+ @tty.assert_cursor_position(START_COL + 2, 1)
28
+ @tty.send_newline
29
+ @tty.assert_row_ends_with(row, 'ls')
30
+ row += 1
31
+ @tty.assert_row_starts_with(row, 'LICENSE')
32
+ row = 9
33
+
34
+ assert_check_new_row(row)
35
+ @tty.send_keys_one_at_a_time(%(echo hello))
36
+ @tty.send_newline
37
+ row += 1
38
+ @tty.assert_row(row, 'hello')
39
+ row += 1
40
+
41
+ assert_check_new_row(row)
42
+ @tty.send_keys_one_at_a_time(%(lss)) # send a bad command
43
+ @tty.send_newline
44
+ row += 1
45
+ @tty.assert_row(row, 'ncsh: Could not find command or directory: No such file or directory')
46
+ row += 1
47
+
48
+ puts 'Starting backspace tests'
49
+
50
+ # end of line backspace
51
+ assert_check_new_row(row)
52
+ @tty.send_keys_one_at_a_time(%(l))
53
+ @tty.send_backspace
54
+ assert_check_new_row(row)
55
+
56
+ # multiple end of line backspaces
57
+ @tty.send_keys_one_at_a_time(%(lsssss))
58
+ @tty.send_backspace
59
+ @tty.send_backspace
60
+ @tty.send_backspace
61
+ @tty.send_backspace
62
+ @tty.assert_row_ends_with(row, '$ ls')
63
+ @tty.send_backspace
64
+ @tty.send_backspace
65
+ @tty.send_keys_one_at_a_time(%(echo hello)) # make sure buffer is properly formed after backspaces
66
+ @tty.send_newline
67
+ row += 1
68
+ @tty.assert_row(row, 'hello')
69
+ row += 1
70
+
71
+ # midline backspace
72
+ assert_check_new_row(row)
73
+ @tty.send_keys_one_at_a_time(%(lsssss))
74
+ @tty.assert_cursor_position(START_COL + 6, row)
75
+ @tty.send_keys(TTYtest::LEFT_ARROW)
76
+ @tty.send_keys(TTYtest::LEFT_ARROW)
77
+ @tty.assert_cursor_position(START_COL + 4, row)
78
+ @tty.send_backspace
79
+ @tty.send_backspace
80
+ @tty.send_backspace
81
+ @tty.send_backspace
82
+ @tty.assert_cursor_position(START_COL, row)
83
+ @tty.assert_row_ends_with(row, '$ ss')
84
+ @tty.send_keys(TTYtest::RIGHT_ARROW)
85
+ @tty.send_keys(TTYtest::RIGHT_ARROW)
86
+ @tty.assert_cursor_position(START_COL + 2, row)
87
+ @tty.send_backspace
88
+ @tty.send_backspace
89
+ @tty.assert_cursor_position(START_COL, row)
90
+ @tty.send_keys_one_at_a_time(%(echo hello)) # make sure buffer is properly formed after backspaces
91
+ @tty.send_newline
92
+ row += 1
93
+ @tty.assert_row(row, 'hello')
@@ -3,7 +3,6 @@
3
3
  # some constants that can be used with send_keys, just to help out people creating tests
4
4
  module TTYtest
5
5
  BACKSPACE = 127.chr
6
- DELETE = '^[[3~'
7
6
  TAB = 9.chr
8
7
  CTRLF = 6.chr
9
8
  CTRLC = 3.chr
@@ -3,10 +3,10 @@
3
3
  module TTYtest
4
4
  # Assertions for ttytest2.
5
5
  module Matchers
6
- # Asserts the contents of a single row
6
+ # Asserts the contents of a single row match the value expected
7
7
  # @param [Integer] row_number the row (starting from 0) to test against
8
8
  # @param [String] expected the expected value of the row. Any trailing whitespace is ignored
9
- # @raise [MatchError] if the row doesn't match
9
+ # @raise [MatchError] if the row doesn't match exactly
10
10
  def assert_row(row_number, expected)
11
11
  expected = expected.rstrip
12
12
  actual = row(row_number)
@@ -16,7 +16,25 @@ module TTYtest
16
16
  "expected row #{row_number} to be #{expected.inspect} but got #{actual.inspect}\nEntire screen:\n#{self}"
17
17
  end
18
18
 
19
- # Asserts the contents of a single row contains expected
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
20
38
  # @param [Integer] row_number the row (starting from 0) to test against
21
39
  # @param [String] expected the expected value contained in the row. Any trailing whitespace is ignored
22
40
  # @raise [MatchError] if the row doesn't match
@@ -29,7 +47,7 @@ module TTYtest
29
47
  "expected row #{row_number} to be like #{expected.inspect} but got #{actual.inspect}\nEntire screen:\n#{self}"
30
48
  end
31
49
 
32
- # Asserts the contents of a single row start with expected
50
+ # Asserts the contents of a single row starts with expected string
33
51
  # @param [Integer] row_number the row (starting from 0) to test against
34
52
  # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
35
53
  # @raise [MatchError] if the row doesn't match
@@ -21,13 +21,27 @@ module TTYtest
21
21
  # @!method send_keys(*keys)
22
22
  # Simulate typing keys into the terminal. For canonical cli's/shells which read line by line.
23
23
  # @param [String] keys keys to send to the terminal
24
- # @!method send_keys_one_at_a_time(*keys)
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_newline
28
+ # Simulate typing enter by sending newline character to the terminal.
29
+ # @!method send_delete
30
+ # Simulate typing the delete key in the terminal.
31
+ # @!method send_backspace
32
+ # Simulate typing the backspace key in the terminal.
33
+ # @!method send_keys_exact
34
+ # Send tmux send-keys command to the terminal, such as DC or Enter, to simulate pressing that key in the terminal.
27
35
  # @!method capture
28
36
  # Capture the current state of the terminal
29
37
  # @return [Capture] instantaneous state of the terminal when called
30
- def_delegators :@driver_terminal, :send_keys, :send_keys_one_at_a_time, :send_newline, :capture
38
+ def_delegators :@driver_terminal,
39
+ :send_keys, :send_keys_one_at_a_time,
40
+ :send_newline, :send_newlines,
41
+ :send_delete, :send_deletes,
42
+ :send_backspace, :send_backspaces,
43
+ :send_keys_exact,
44
+ :capture
31
45
 
32
46
  # @!method rows
33
47
  # @return [Array<String>]
@@ -38,10 +38,15 @@ module TTYtest
38
38
  )
39
39
  end
40
40
 
41
+ # Send the array of keys as a string literal to tmux.
42
+ # Will not be interpreted as send-keys values like Enter, Escape, DC for Delete, etc.
43
+ # @param [%w()] keys the keys to send to tmux
41
44
  def send_keys(*keys)
42
45
  driver.tmux(*%W[send-keys -t #{name} -l], *keys)
43
46
  end
44
47
 
48
+ # Send a string of keys one character at a time as literals to tmux.
49
+ # @param [String] keys the keys to send one at a time to tmux
45
50
  def send_keys_one_at_a_time(keys)
46
51
  keys.split('').each do |key|
47
52
  driver.tmux(*%W[send-keys -t #{name} -l], key)
@@ -52,6 +57,43 @@ module TTYtest
52
57
  driver.tmux(*%W[send-keys -t #{name} -l], %(\n))
53
58
  end
54
59
 
60
+ def send_newlines(number_of_times)
61
+ while number_of_times.positive?
62
+ send_newline
63
+ number_of_times -= 1
64
+ end
65
+ end
66
+
67
+ def send_delete
68
+ send_keys_exact(%(DC))
69
+ end
70
+
71
+ def send_deletes(number_of_times)
72
+ while number_of_times.positive?
73
+ send_delete
74
+ number_of_times -= 1
75
+ end
76
+ end
77
+
78
+ def send_backspace
79
+ send_keys_exact(%(BSpace))
80
+ end
81
+
82
+ def send_backspaces(number_of_times)
83
+ while number_of_times.positive?
84
+ send_backspace
85
+ number_of_times -= 1
86
+ end
87
+ end
88
+
89
+ # Useful to send send-keys commands to tmux without sending them as a string literal.
90
+ # So you can send Escape for escape key, DC for delete, etc.
91
+ # Uses the same key bindings as bind-key as well. C-c represents Ctrl + C keys, F1 is F1 key, etc.
92
+ # @param [String] keys the keys to send to tmux
93
+ def send_keys_exact(keys)
94
+ driver.tmux(*%W[send-keys -t #{name}], keys)
95
+ end
96
+
55
97
  private
56
98
 
57
99
  attr_reader :driver, :name
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTYtest
4
- VERSION = '0.8.6'
4
+ VERSION = '0.9.1'
5
5
  end
data/notes.txt CHANGED
@@ -1,7 +1,7 @@
1
- to push new version to github,
2
- git tag v0.8.6
1
+ to push new version to github
2
+ git tag v0.9.1
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-0.8.6.gem
7
+ gem push ttytest2-0.9.1.gem
data/ttytest2.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ['alexeski@gmail.com']
12
12
 
13
13
  spec.summary = 'ttytest2 is an integration test framework for interactive tty applications. Based on TTYtest!'
14
- spec.description = 'ttytest2 allows running shell and/or cli applications inside of tmux and then making assertions on the output.'
14
+ spec.description = 'ttytest2 allows running shell/cli applications inside of tmux and then making assertions on the output.'
15
15
  spec.homepage = 'https://github.com/a-eski/ttytest2'
16
16
  spec.license = 'MIT'
17
17
 
@@ -24,8 +24,8 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = '>= 3.2.3'
26
26
 
27
- spec.add_development_dependency 'bundler'
27
+ spec.add_development_dependency 'bundler', '~> 2.5'
28
28
  spec.add_development_dependency 'minitest', '~> 5.0'
29
29
  spec.add_development_dependency 'rake', '~> 13.0'
30
- spec.add_development_dependency 'yard'
30
+ spec.add_development_dependency 'yard', '~> 0.9'
31
31
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ttytest2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.6
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Eski
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-15 00:00:00.000000000 Z
11
+ date: 2024-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '2.5'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '2.5'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -56,18 +56,18 @@ dependencies:
56
56
  name: yard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '0.9'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
69
- description: ttytest2 allows running shell and/or cli applications inside of tmux
70
- and then making assertions on the output.
68
+ version: '0.9'
69
+ description: ttytest2 allows running shell/cli applications inside of tmux and then
70
+ making assertions on the output.
71
71
  email:
72
72
  - alexeski@gmail.com
73
73
  executables: []
@@ -79,6 +79,8 @@ files:
79
79
  - Gemfile
80
80
  - README.md
81
81
  - Rakefile
82
+ - examples/canonical_integration_tests.rb
83
+ - examples/noncanonical_integration_tests.rb
82
84
  - lib/ttytest.rb
83
85
  - lib/ttytest/capture.rb
84
86
  - lib/ttytest/constants.rb