expect-pty 0.5.3 → 0.6.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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -0
  3. data/README.md +28 -19
  4. data/docs/API.md +88 -0
  5. data/docs/MIGRATION.md +15 -0
  6. data/lib/expect/cleanup.rb +33 -0
  7. data/lib/expect/configuration.rb +87 -66
  8. data/lib/expect/interaction.rb +226 -209
  9. data/lib/expect/logging.rb +157 -156
  10. data/lib/expect/matcher.rb +30 -29
  11. data/lib/expect/pattern.rb +8 -2
  12. data/lib/expect/pattern_list.rb +35 -5
  13. data/lib/expect/redactor.rb +11 -4
  14. data/lib/expect/relay.rb +97 -73
  15. data/lib/expect/relay_writer.rb +2 -1
  16. data/lib/expect/result.rb +32 -8
  17. data/lib/expect/session.rb +508 -0
  18. data/lib/expect/session_resources.rb +10 -2
  19. data/lib/expect/terminal.rb +78 -78
  20. data/lib/expect/version.rb +1 -1
  21. data/lib/expect.rb +333 -520
  22. data/sig/expect.rbs +355 -0
  23. metadata +13 -106
  24. data/.rubocop.yml +0 -66
  25. data/CONTRIBUTING.md +0 -29
  26. data/Gemfile +0 -28
  27. data/Rakefile +0 -38
  28. data/benchmark/matching.rb +0 -98
  29. data/benchmark/redactor.rb +0 -64
  30. data/benchmark/relay.rb +0 -48
  31. data/benchmark/scaling.rb +0 -70
  32. data/benchmark/send_slow.rb +0 -41
  33. data/benchmark/support.rb +0 -114
  34. data/docs/COMPATIBILITY.md +0 -98
  35. data/docs/INTERNAL_CONTRACTS.md +0 -154
  36. data/docs/PERFORMANCE.md +0 -165
  37. data/docs/RELEASING.md +0 -84
  38. data/docs/VERIFICATION.md +0 -456
  39. data/examples/dialogue.rb +0 -30
  40. data/examples/kibitz/README.md +0 -81
  41. data/examples/kibitz/kibitz.rb +0 -142
  42. data/examples/kibitz/test_kibitz.rb +0 -37
  43. data/examples/ssh_auto.rb +0 -94
  44. data/examples/ssh_interact.rb +0 -159
  45. data/examples/ssh_login.rb +0 -64
  46. data/expect-pty.gemspec +0 -33
  47. data/script/ci +0 -121
  48. data/script/release.rb +0 -319
  49. data/test/buffer_accounting_test.rb +0 -83
  50. data/test/cleanup_test.rb +0 -251
  51. data/test/compare_upstream.rb +0 -157
  52. data/test/configuration_test.rb +0 -133
  53. data/test/deadline_test.rb +0 -237
  54. data/test/diagnostics_test.rb +0 -353
  55. data/test/edge_case_test.rb +0 -262
  56. data/test/fixtures/ssh_scripts/01_identity.sh +0 -4
  57. data/test/fixtures/ssh_scripts/02_output.sh +0 -5
  58. data/test/fixtures/ssh_scripts/03_delayed.sh +0 -6
  59. data/test/fixtures/ssh_scripts/04_failure.sh +0 -2
  60. data/test/fixtures/ssh_scripts/05_recovery.sh +0 -3
  61. data/test/initialization_failure_test.rb +0 -92
  62. data/test/integration/README.md +0 -109
  63. data/test/integration/ssh_scripts.rb +0 -94
  64. data/test/interact_test.rb +0 -253
  65. data/test/interconnect_test.rb +0 -425
  66. data/test/io_test.rb +0 -321
  67. data/test/kibitz_test.rb +0 -45
  68. data/test/lifecycle_contract_test.rb +0 -71
  69. data/test/literal_scan_test.rb +0 -97
  70. data/test/matching_test.rb +0 -211
  71. data/test/multi_session_test.rb +0 -66
  72. data/test/ownership_sequence_test.rb +0 -208
  73. data/test/pattern_offset_test.rb +0 -43
  74. data/test/process_interruption_test.rb +0 -296
  75. data/test/process_test.rb +0 -291
  76. data/test/redactor_test.rb +0 -183
  77. data/test/relay_recovery_test.rb +0 -451
  78. data/test/relay_reentrancy_test.rb +0 -159
  79. data/test/release_test.rb +0 -375
  80. data/test/ruby_api_test.rb +0 -515
  81. data/test/scan_reuse_test.rb +0 -109
  82. data/test/script_logging_test.rb +0 -124
  83. data/test/support/interact_probe.rb +0 -125
  84. data/test/support/kibitz_probe.rb +0 -177
  85. data/test/support/script_probe.rb +0 -158
  86. data/test/terminal_cleanup_test.rb +0 -349
  87. data/test/test_helper.rb +0 -58
  88. data/test/timeout_test.rb +0 -289
  89. data/test/write_contract_test.rb +0 -105
data/sig/expect.rbs ADDED
@@ -0,0 +1,355 @@
1
+ # Public interface for Ruby 3.4+. Internal Session/Matcher/Relay are intentionally omitted.
2
+ class Expect
3
+ type duration = Numeric | String
4
+ type pattern = String | Regexp | :eof | :timeout
5
+ type result_error = :eof | :timeout | Exception | nil
6
+ type log_target = _Writer | _LogCallback
7
+ type result_fields = { number: Integer?, error: result_error, match: String?, before: String?, after: String?, session: Expect?, captures: Array[String?] }
8
+ type event = { event: Symbol, level: Symbol, pid: Integer?, fd: Integer?, message: String }
9
+ type diagnostic_target = _Writer | _Logger | _DiagnosticCallback
10
+
11
+ interface _LogCallback
12
+ def call: (String) -> untyped
13
+ end
14
+
15
+ interface _DiagnosticCallback
16
+ def call: (event) -> untyped
17
+ end
18
+
19
+ interface _Writer
20
+ def write: (String) -> Integer
21
+ end
22
+
23
+ interface _Path
24
+ def to_path: () -> String
25
+ end
26
+
27
+ interface _Logger
28
+ def info: (String) -> untyped
29
+ def debug: (String) -> untyped
30
+ end
31
+
32
+ VERSION: String
33
+ CONTINUE: :continue
34
+ CONTINUE_WITHOUT_RESET: :continue_without_reset
35
+
36
+ class SpawnError < StandardError
37
+ end
38
+ class ReentrancyError < StandardError
39
+ end
40
+ class WriteTimeout < IOError
41
+ attr_reader bytes_written: Integer
42
+ def initialize: (?String message, ?bytes_written: Integer) -> void
43
+ end
44
+
45
+ def initialize: (
46
+ *String command,
47
+ ?env: Hash[String, String?],
48
+ ?chdir: String?,
49
+ ?diagnostic_output: diagnostic_target?,
50
+ ?timeout: duration?,
51
+ ?write_timeout: duration?,
52
+ ?buffer_limit: Integer?,
53
+ ?debug_level: Integer,
54
+ ?raw_pty: untyped,
55
+ ?preserve_buffer: untyped,
56
+ ?log_stdout: untyped,
57
+ ?log_listeners: untyped,
58
+ ?raw_terminal: untyped,
59
+ ?reset_timeout_on_read: untyped,
60
+ ?graceful_close: untyped
61
+ ) -> void
62
+ def self.spawn: (
63
+ *String command,
64
+ ?env: Hash[String, String?],
65
+ ?chdir: String?,
66
+ ?diagnostic_output: diagnostic_target?,
67
+ ?timeout: duration?,
68
+ ?write_timeout: duration?,
69
+ ?buffer_limit: Integer?,
70
+ ?debug_level: Integer,
71
+ ?raw_pty: untyped,
72
+ ?preserve_buffer: untyped,
73
+ ?log_stdout: untyped,
74
+ ?log_listeners: untyped,
75
+ ?raw_terminal: untyped,
76
+ ?reset_timeout_on_read: untyped,
77
+ ?graceful_close: untyped
78
+ ) -> Expect
79
+ | [A] (
80
+ *String command,
81
+ ?env: Hash[String, String?],
82
+ ?chdir: String?,
83
+ ?diagnostic_output: diagnostic_target?,
84
+ ?timeout: duration?,
85
+ ?write_timeout: duration?,
86
+ ?buffer_limit: Integer?,
87
+ ?debug_level: Integer,
88
+ ?raw_pty: untyped,
89
+ ?preserve_buffer: untyped,
90
+ ?log_stdout: untyped,
91
+ ?log_listeners: untyped,
92
+ ?raw_terminal: untyped,
93
+ ?reset_timeout_on_read: untyped,
94
+ ?graceful_close: untyped
95
+ ) { (Expect) -> A } -> A
96
+ def self.open: (
97
+ IO io,
98
+ ?writer: IO,
99
+ ?own: bool,
100
+ ?diagnostic_output: diagnostic_target?,
101
+ ?timeout: duration?,
102
+ ?write_timeout: duration?,
103
+ ?buffer_limit: Integer?,
104
+ ?debug_level: Integer,
105
+ ?raw_pty: untyped,
106
+ ?preserve_buffer: untyped,
107
+ ?log_stdout: untyped,
108
+ ?log_listeners: untyped,
109
+ ?raw_terminal: untyped,
110
+ ?reset_timeout_on_read: untyped,
111
+ ?graceful_close: untyped
112
+ ) -> Expect
113
+ | [A] (
114
+ IO io,
115
+ ?writer: IO,
116
+ ?own: bool,
117
+ ?diagnostic_output: diagnostic_target?,
118
+ ?timeout: duration?,
119
+ ?write_timeout: duration?,
120
+ ?buffer_limit: Integer?,
121
+ ?debug_level: Integer,
122
+ ?raw_pty: untyped,
123
+ ?preserve_buffer: untyped,
124
+ ?log_stdout: untyped,
125
+ ?log_listeners: untyped,
126
+ ?raw_terminal: untyped,
127
+ ?reset_timeout_on_read: untyped,
128
+ ?graceful_close: untyped
129
+ ) { (Expect) -> A } -> A
130
+ def self.configure: (
131
+ ?timeout: duration?,
132
+ ?write_timeout: duration?,
133
+ ?buffer_limit: Integer?,
134
+ ?debug_level: Integer,
135
+ ?raw_pty: untyped,
136
+ ?preserve_buffer: untyped,
137
+ ?log_stdout: untyped,
138
+ ?log_listeners: untyped,
139
+ ?raw_terminal: untyped,
140
+ ?reset_timeout_on_read: untyped,
141
+ ?graceful_close: untyped
142
+ ) ?{ (Configuration) -> untyped } -> Configuration
143
+ def self.configuration: () -> Configuration
144
+ def self.continue: (?reset_timeout: bool) -> (:continue | :continue_without_reset)
145
+ def self.monotonic: () -> Float
146
+ def self.duration: (duration?) -> Float?
147
+ def self.readable_sessions: (*Expect sessions, ?timeout: duration?) -> Array[Expect]
148
+ def self.interconnect: (*Expect sessions, ?timeout: duration?) -> Expect?
149
+ def self.expect: (
150
+ *pattern patterns,
151
+ ?from: (Expect | Array[Expect]),
152
+ ?timeout: duration?,
153
+ ?deadline: duration?
154
+ ) ?{ (PatternList) -> untyped } -> Result
155
+ def expect: (*pattern patterns, ?timeout: duration?, ?deadline: duration?) ?{ (PatternList) -> untyped } -> Result
156
+ def continue: (?reset_timeout: bool) -> (:continue | :continue_without_reset)
157
+ def after: () -> String?
158
+ def before: () -> String?
159
+ def match: () -> String?
160
+ def alive?: () -> bool
161
+ def closed?: () -> bool
162
+ def eof?: () -> bool
163
+ def tty?: () -> bool
164
+ def pending_output?: () -> bool
165
+ def buffer: () -> String
166
+ def clear_buffer: () -> String
167
+ def buffer_discarded_bytes: () -> Integer
168
+ def captures: () -> Array[String?]
169
+ def command: () -> Array[String]?
170
+ def diagnostic_output: () -> diagnostic_target?
171
+ def error: () -> result_error
172
+ def exit_code: () -> Integer?
173
+ def fileno: () -> Integer?
174
+ def pid: () -> Integer?
175
+ def match_number: () -> Integer?
176
+ def last_result: () -> Result?
177
+ def listeners: () -> Array[_Writer]
178
+ def log_output: () -> log_target?
179
+ def slave: () -> IO?
180
+ def tty_name: () -> String?
181
+ def to_io: () -> IO
182
+ def writer: () -> IO
183
+ def process_status: () -> Process::Status?
184
+ def winsize: () -> [Integer, Integer]
185
+ def inspect: () -> String
186
+ def close: (?graceful: bool) -> nil
187
+ def soft_close: (?timeout: duration?, ?term_timeout: duration) -> Process::Status?
188
+ def hard_close: (?timeout: duration) -> Process::Status?
189
+ def wait: (?timeout: duration?) -> Process::Status?
190
+ def write: (*untyped objects) -> Integer
191
+ def send_slow: (*untyped objects, delay: duration) -> Integer
192
+ def puts: (*untyped objects) -> nil
193
+ def <<: (untyped object) -> Expect
194
+ def spawn: (*String command, ?env: Hash[String, String?], ?chdir: String?) -> Expect
195
+ def on_sequence: ((String | Regexp | :eof) sequence) ?{ () -> untyped } -> Expect
196
+ def redact: (*String secrets) -> Expect
197
+ def interact: (?input: (IO | Expect), ?escape: (String | Regexp)?, ?output: _Writer?, ?timeout: duration?) -> Expect?
198
+ def stty: (*String modes) -> String
199
+ def log_to: (?(log_target | String | _Path) target, ?mode: String) ?{ (String) -> untyped } -> log_target
200
+ def write_log: (*untyped objects) -> untyped
201
+ def timeout: () -> Float?
202
+ def timeout=: (duration? value) -> void
203
+ def write_timeout: () -> Float?
204
+ def write_timeout=: (duration? value) -> void
205
+ def buffer_limit: () -> Integer?
206
+ def buffer_limit=: (Integer? value) -> void
207
+ def debug_level: () -> Integer
208
+ def debug_level=: (Integer value) -> void
209
+
210
+ def raw_pty=: (untyped value) -> void
211
+ def raw_pty?: () -> bool
212
+
213
+ def preserve_buffer=: (untyped value) -> void
214
+ def preserve_buffer?: () -> bool
215
+
216
+ def log_stdout=: (untyped value) -> void
217
+ def log_stdout?: () -> bool
218
+
219
+ def log_listeners=: (untyped value) -> void
220
+ def log_listeners?: () -> bool
221
+
222
+ def raw_terminal=: (untyped value) -> void
223
+ def raw_terminal?: () -> bool
224
+
225
+ def reset_timeout_on_read=: (untyped value) -> void
226
+ def reset_timeout_on_read?: () -> bool
227
+
228
+ def graceful_close=: (untyped value) -> void
229
+ def graceful_close?: () -> bool
230
+ def buffer=: (String value) -> void
231
+ def diagnostic_output=: (diagnostic_target? value) -> void
232
+ def log_output=: (log_target? value) -> void
233
+ def listeners=: (Array[_Writer] value) -> void
234
+ def winsize=: ([Integer, Integer] value) -> void
235
+
236
+ class Configuration
237
+ def initialize: (
238
+ ?timeout: duration?,
239
+ ?write_timeout: duration?,
240
+ ?buffer_limit: Integer?,
241
+ ?debug_level: Integer,
242
+ ?raw_pty: untyped,
243
+ ?preserve_buffer: untyped,
244
+ ?log_stdout: untyped,
245
+ ?log_listeners: untyped,
246
+ ?raw_terminal: untyped,
247
+ ?reset_timeout_on_read: untyped,
248
+ ?graceful_close: untyped
249
+ ) -> void
250
+ def timeout: () -> Float?
251
+ def timeout=: (duration?) -> Float?
252
+ def write_timeout: () -> Float?
253
+ def write_timeout=: (duration?) -> Float?
254
+ def buffer_limit: () -> Integer?
255
+ def buffer_limit=: (Integer?) -> Integer?
256
+ def debug_level: () -> Integer
257
+ def debug_level=: (Integer) -> Integer
258
+
259
+ def raw_pty=: (untyped) -> bool
260
+ def raw_pty?: () -> bool
261
+
262
+ def preserve_buffer=: (untyped) -> bool
263
+ def preserve_buffer?: () -> bool
264
+
265
+ def log_stdout=: (untyped) -> bool
266
+ def log_stdout?: () -> bool
267
+
268
+ def log_listeners=: (untyped) -> bool
269
+ def log_listeners?: () -> bool
270
+
271
+ def raw_terminal=: (untyped) -> bool
272
+ def raw_terminal?: () -> bool
273
+
274
+ def reset_timeout_on_read=: (untyped) -> bool
275
+ def reset_timeout_on_read?: () -> bool
276
+
277
+ def graceful_close=: (untyped) -> bool
278
+ def graceful_close?: () -> bool
279
+ def to_h: () -> Hash[Symbol, untyped]
280
+ end
281
+
282
+ class Result < Data
283
+ def self.new: (
284
+ ?number: Integer?,
285
+ ?error: result_error,
286
+ ?match: String?,
287
+ ?before: String?,
288
+ ?after: String?,
289
+ ?session: Expect?,
290
+ ?captures: Array[String?]
291
+ ) -> Result
292
+ | (?Integer?, ?result_error, ?String?, ?String?, ?String?, ?Expect?, ?Array[String?]) -> Result
293
+ def self.[]: (
294
+ ?number: Integer?,
295
+ ?error: result_error,
296
+ ?match: String?,
297
+ ?before: String?,
298
+ ?after: String?,
299
+ ?session: Expect?,
300
+ ?captures: Array[String?]
301
+ ) -> Result
302
+ | (?Integer?, ?result_error, ?String?, ?String?, ?String?, ?Expect?, ?Array[String?]) -> Result
303
+ def self.members: () -> Array[Symbol]
304
+ def self.inspect: () -> String
305
+ def members: () -> Array[Symbol]
306
+ attr_reader number: Integer?
307
+ attr_reader error: result_error
308
+ attr_reader match: String?
309
+ attr_reader before: String?
310
+ attr_reader after: String?
311
+ attr_reader session: Expect?
312
+ attr_reader captures: Array[String?]
313
+ def initialize: (
314
+ ?number: Integer?,
315
+ ?error: result_error,
316
+ ?match: String?,
317
+ ?before: String?,
318
+ ?after: String?,
319
+ ?session: Expect?,
320
+ ?captures: Array[String?]
321
+ ) -> void
322
+ def matched?: () -> bool
323
+ def timeout?: () -> bool
324
+ def eof?: () -> bool
325
+ def deconstruct: () -> [Integer?, result_error, String?, String?, String?, Expect?, Array[String?]]
326
+ def with: (
327
+ ?number: Integer?,
328
+ ?error: result_error,
329
+ ?match: String?,
330
+ ?before: String?,
331
+ ?after: String?,
332
+ ?session: Expect?,
333
+ ?captures: Array[String?]
334
+ ) -> Result
335
+ def to_h: () -> result_fields
336
+ | [K, V] () { (Symbol, untyped) -> [K, V] } -> Hash[K, V]
337
+ def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, untyped]
338
+ end
339
+
340
+ class PatternList
341
+ def initialize: (?(Expect | Array[Expect]) sessions, ?Array[pattern] patterns) -> void
342
+ def on: ((String | Regexp) value, ?from: (Expect | Array[Expect])) ?{ (Expect) -> untyped } -> PatternList
343
+ def eof: (?from: (Expect | Array[Expect])) ?{ (Expect) -> untyped } -> PatternList
344
+ def timeout: () ?{ (Array[Expect]) -> untyped } -> PatternList
345
+ end
346
+
347
+ class Redactor
348
+ def self.redact: (String data, Array[String] patterns, ?replacement: String) -> String
349
+ def initialize: (Array[String] patterns, ?replacement: String) -> void
350
+ def patterns=: (Array[String]) -> void
351
+ def append: (String) -> String
352
+ def finish: (?partial: bool) -> String
353
+ def inspect: () -> String
354
+ end
355
+ end
metadata CHANGED
@@ -1,26 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expect-pty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - expect-pty contributors
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-09-27 00:00:00.000000000 Z
10
+ date: 2026-10-01 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: forwardable
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
18
  version: '1.3'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '1.3'
26
26
  - !ruby/object:Gem::Dependency
@@ -30,9 +30,6 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: '0.6'
33
- - - "<"
34
- - !ruby/object:Gem::Version
35
- version: '1.0'
36
33
  type: :runtime
37
34
  prerelease: false
38
35
  version_requirements: !ruby/object:Gem::Requirement
@@ -40,29 +37,6 @@ dependencies:
40
37
  - - ">="
41
38
  - !ruby/object:Gem::Version
42
39
  version: '0.6'
43
- - - "<"
44
- - !ruby/object:Gem::Version
45
- version: '1.0'
46
- - !ruby/object:Gem::Dependency
47
- name: io-wait
48
- requirement: !ruby/object:Gem::Requirement
49
- requirements:
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- version: '0.3'
53
- - - "<"
54
- - !ruby/object:Gem::Version
55
- version: '1.0'
56
- type: :runtime
57
- prerelease: false
58
- version_requirements: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: '0.3'
63
- - - "<"
64
- - !ruby/object:Gem::Version
65
- version: '1.0'
66
40
  - !ruby/object:Gem::Dependency
67
41
  name: shellwords
68
42
  requirement: !ruby/object:Gem::Requirement
@@ -70,9 +44,6 @@ dependencies:
70
44
  - - ">="
71
45
  - !ruby/object:Gem::Version
72
46
  version: '0.1'
73
- - - "<"
74
- - !ruby/object:Gem::Version
75
- version: '1.0'
76
47
  type: :runtime
77
48
  prerelease: false
78
49
  version_requirements: !ruby/object:Gem::Requirement
@@ -80,21 +51,18 @@ dependencies:
80
51
  - - ">="
81
52
  - !ruby/object:Gem::Version
82
53
  version: '0.1'
83
- - - "<"
84
- - !ruby/object:Gem::Version
85
- version: '1.0'
86
54
  - !ruby/object:Gem::Dependency
87
55
  name: stringio
88
56
  requirement: !ruby/object:Gem::Requirement
89
57
  requirements:
90
- - - "~>"
58
+ - - ">="
91
59
  - !ruby/object:Gem::Version
92
60
  version: '3.0'
93
61
  type: :runtime
94
62
  prerelease: false
95
63
  version_requirements: !ruby/object:Gem::Requirement
96
64
  requirements:
97
- - - "~>"
65
+ - - ">="
98
66
  - !ruby/object:Gem::Version
99
67
  version: '3.0'
100
68
  description: Automate interactive programs with exact and regexp matching, Ruby blocks,
@@ -103,33 +71,13 @@ executables: []
103
71
  extensions: []
104
72
  extra_rdoc_files: []
105
73
  files:
106
- - ".rubocop.yml"
107
74
  - CHANGELOG.md
108
- - CONTRIBUTING.md
109
- - Gemfile
110
75
  - LICENSE
111
76
  - README.md
112
- - Rakefile
113
- - benchmark/matching.rb
114
- - benchmark/redactor.rb
115
- - benchmark/relay.rb
116
- - benchmark/scaling.rb
117
- - benchmark/send_slow.rb
118
- - benchmark/support.rb
119
- - docs/COMPATIBILITY.md
120
- - docs/INTERNAL_CONTRACTS.md
121
- - docs/PERFORMANCE.md
122
- - docs/RELEASING.md
123
- - docs/VERIFICATION.md
124
- - examples/dialogue.rb
125
- - examples/kibitz/README.md
126
- - examples/kibitz/kibitz.rb
127
- - examples/kibitz/test_kibitz.rb
128
- - examples/ssh_auto.rb
129
- - examples/ssh_interact.rb
130
- - examples/ssh_login.rb
131
- - expect-pty.gemspec
77
+ - docs/API.md
78
+ - docs/MIGRATION.md
132
79
  - lib/expect.rb
80
+ - lib/expect/cleanup.rb
133
81
  - lib/expect/configuration.rb
134
82
  - lib/expect/interaction.rb
135
83
  - lib/expect/logging.rb
@@ -141,52 +89,11 @@ files:
141
89
  - lib/expect/relay.rb
142
90
  - lib/expect/relay_writer.rb
143
91
  - lib/expect/result.rb
92
+ - lib/expect/session.rb
144
93
  - lib/expect/session_resources.rb
145
94
  - lib/expect/terminal.rb
146
95
  - lib/expect/version.rb
147
- - script/ci
148
- - script/release.rb
149
- - test/buffer_accounting_test.rb
150
- - test/cleanup_test.rb
151
- - test/compare_upstream.rb
152
- - test/configuration_test.rb
153
- - test/deadline_test.rb
154
- - test/diagnostics_test.rb
155
- - test/edge_case_test.rb
156
- - test/fixtures/ssh_scripts/01_identity.sh
157
- - test/fixtures/ssh_scripts/02_output.sh
158
- - test/fixtures/ssh_scripts/03_delayed.sh
159
- - test/fixtures/ssh_scripts/04_failure.sh
160
- - test/fixtures/ssh_scripts/05_recovery.sh
161
- - test/initialization_failure_test.rb
162
- - test/integration/README.md
163
- - test/integration/ssh_scripts.rb
164
- - test/interact_test.rb
165
- - test/interconnect_test.rb
166
- - test/io_test.rb
167
- - test/kibitz_test.rb
168
- - test/lifecycle_contract_test.rb
169
- - test/literal_scan_test.rb
170
- - test/matching_test.rb
171
- - test/multi_session_test.rb
172
- - test/ownership_sequence_test.rb
173
- - test/pattern_offset_test.rb
174
- - test/process_interruption_test.rb
175
- - test/process_test.rb
176
- - test/redactor_test.rb
177
- - test/relay_recovery_test.rb
178
- - test/relay_reentrancy_test.rb
179
- - test/release_test.rb
180
- - test/ruby_api_test.rb
181
- - test/scan_reuse_test.rb
182
- - test/script_logging_test.rb
183
- - test/support/interact_probe.rb
184
- - test/support/kibitz_probe.rb
185
- - test/support/script_probe.rb
186
- - test/terminal_cleanup_test.rb
187
- - test/test_helper.rb
188
- - test/timeout_test.rb
189
- - test/write_contract_test.rb
96
+ - sig/expect.rbs
190
97
  homepage: https://github.com/gatework/expect-ruby
191
98
  licenses:
192
99
  - MIT
@@ -202,14 +109,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
202
109
  requirements:
203
110
  - - ">="
204
111
  - !ruby/object:Gem::Version
205
- version: '3.2'
112
+ version: '3.4'
206
113
  required_rubygems_version: !ruby/object:Gem::Requirement
207
114
  requirements:
208
115
  - - ">="
209
116
  - !ruby/object:Gem::Version
210
117
  version: '0'
211
118
  requirements: []
212
- rubygems_version: 4.0.12
119
+ rubygems_version: 4.0.16
213
120
  specification_version: 4
214
121
  summary: Ruby PTY automation with the Expect.pm interaction model
215
122
  test_files: []
data/.rubocop.yml DELETED
@@ -1,66 +0,0 @@
1
- AllCops:
2
- TargetRubyVersion: 3.2
3
- NewCops: enable
4
- SuggestExtensions: false
5
- Exclude:
6
- - "pkg/**/*"
7
- - "tmp/**/*"
8
- - "vendor/**/*"
9
-
10
- # 宽松但有限的规模门槛覆盖生产代码;测试和基准的场景编排不按方法长度及 ABC 计数。
11
- # 需要更高分支复杂度的协议状态机仅在对应方法说明豁免原因。
12
- Metrics/AbcSize:
13
- Max: 120
14
- Exclude:
15
- - "test/**/*"
16
- - "benchmark/**/*"
17
-
18
- Metrics/BlockLength:
19
- Max: 80
20
-
21
- Metrics/BlockNesting:
22
- Max: 4
23
- Exclude:
24
- - "test/**/*"
25
-
26
- Metrics/ClassLength:
27
- Max: 500
28
-
29
- Metrics/MethodLength:
30
- Max: 80
31
- Exclude:
32
- - "test/**/*"
33
- - "benchmark/**/*"
34
-
35
- Metrics/ModuleLength:
36
- Max: 250
37
-
38
- Metrics/ParameterLists:
39
- Max: 6
40
- CountKeywordArgs: false
41
-
42
- Metrics/CyclomaticComplexity:
43
- Max: 13
44
- Exclude:
45
- - "test/**/*"
46
-
47
- Metrics/PerceivedComplexity:
48
- Max: 13
49
- Exclude:
50
- - "test/**/*"
51
-
52
- Style/StringLiterals:
53
- EnforcedStyle: double_quotes
54
-
55
- Style/StringLiteralsInInterpolation:
56
- EnforcedStyle: double_quotes
57
-
58
- Style/Documentation:
59
- Exclude:
60
- - "test/**/*"
61
-
62
- Naming/RescuedExceptionsVariableName:
63
- PreferredName: error
64
-
65
- Layout/LineLength:
66
- Max: 120
data/CONTRIBUTING.md DELETED
@@ -1,29 +0,0 @@
1
- # 参与贡献
2
-
3
- 欢迎中文或英文 issue 和 PR。库的公共 API 名称和错误信息使用英文;库内的责任划分、复杂生命周期和协议解释使用中文,RuboCop
4
- 等工具指令保持原格式。文档以现有文件的语言为准,示例中的可编辑命令保持直接清晰。
5
-
6
- ## 本地检查
7
-
8
- 需要 Ruby 3.2+ 和 Linux/macOS。安装依赖后运行:
9
-
10
- ```sh
11
- bundle install
12
- bundle exec rake # RuboCop 和默认测试
13
- script/ci # 另含示例、Gem 构建及隔离安装验证
14
- ```
15
-
16
- 修改转接或匹配时,先运行对应的 `test/*_test.rb`,再运行 `bundle exec rake`。默认测试不需要 SSH;真实 SSH
17
- 集成测试的环境要求见 [测试说明](test/integration/README.md)。发布操作和历史验证分别见 [发布说明](docs/RELEASING.md)
18
- 与 [验证记录](docs/VERIFICATION.md)。
19
-
20
- RuboCop 对生产代码保留有限的长度、ABC、嵌套、参数数量和分支复杂度门槛。测试及基准的场景编排豁免方法长度与 ABC
21
- 计数;协议状态机的分支豁免只放在对应方法,并注明原因。阈值用于提示复核,职责拆分仍应保持状态归属和异常恢复逻辑完整。
22
-
23
- ## 提交问题或改动
24
-
25
- 问题报告请附 Ruby
26
- 版本、操作系统、最小复现代码、预期与实际结果,以及必要的异常信息;日志中请删去凭据和会话敏感内容。修复行为缺陷时,先加入能在旧实现复现问题的回归测试。涉及缓冲、转义、背压或进程清理的改动,请对照 [内部状态与数据归属](docs/INTERNAL_CONTRACTS.md)
27
- ,说明超时、EOF 和失败后的恢复行为。
28
-
29
- PR 请说明行为变化、运行过的命令及结果。不要把本机生成的 `tmp/`、日志或凭据加入提交。
data/Gemfile DELETED
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
- gemspec
5
-
6
- group :development, :test do
7
- gem "minitest", "~> 5.0", require: false
8
- # RuboCop 的依赖也必须支持最低 Ruby 版本。
9
- gem "parallel", "~> 1.27", require: false
10
- gem "rake", "~> 13.0", require: false
11
- # 固定已审阅的规则集,避免不同 CI 环境自动启用新 cop 改变发布门槛。
12
- gem "rubocop", "= 1.89.0", require: false
13
-
14
- # 测试、示例和发布工具直接使用的标准库 gem,不依赖其他开发工具间接引入。
15
- gem "digest", require: false
16
- gem "etc", require: false
17
- gem "fileutils", require: false
18
- gem "json", require: false
19
- gem "logger", require: false
20
- gem "net-http", require: false
21
- gem "open3", require: false
22
- gem "optparse", require: false
23
- gem "securerandom", require: false
24
- gem "tempfile", require: false
25
- gem "time", require: false
26
- gem "timeout", require: false
27
- gem "tmpdir", require: false
28
- end