expect-pty 0.5.3 → 0.7.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 +4 -4
- data/CHANGELOG.md +55 -1
- data/README.md +122 -130
- data/docs/API.md +113 -0
- data/docs/MIGRATION.md +68 -0
- data/lib/expect/cleanup.rb +34 -0
- data/lib/expect/interaction.rb +228 -210
- data/lib/expect/logging.rb +117 -162
- data/lib/expect/matcher.rb +42 -38
- data/lib/expect/pattern.rb +10 -3
- data/lib/expect/pattern_list.rb +39 -9
- data/lib/expect/redactor.rb +12 -5
- data/lib/expect/relay.rb +106 -81
- data/lib/expect/relay_writer.rb +7 -5
- data/lib/expect/result.rb +33 -9
- data/lib/expect/session.rb +554 -0
- data/lib/expect/session_resources.rb +19 -18
- data/lib/expect/version.rb +2 -2
- data/lib/expect.rb +68 -578
- data/sig/expect.rbs +279 -0
- metadata +14 -123
- data/.rubocop.yml +0 -66
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -28
- data/Rakefile +0 -38
- data/benchmark/matching.rb +0 -98
- data/benchmark/redactor.rb +0 -64
- data/benchmark/relay.rb +0 -48
- data/benchmark/scaling.rb +0 -70
- data/benchmark/send_slow.rb +0 -41
- data/benchmark/support.rb +0 -114
- data/docs/COMPATIBILITY.md +0 -98
- data/docs/INTERNAL_CONTRACTS.md +0 -154
- data/docs/PERFORMANCE.md +0 -165
- data/docs/RELEASING.md +0 -84
- data/docs/VERIFICATION.md +0 -456
- data/examples/dialogue.rb +0 -30
- data/examples/kibitz/README.md +0 -81
- data/examples/kibitz/kibitz.rb +0 -142
- data/examples/kibitz/test_kibitz.rb +0 -37
- data/examples/ssh_auto.rb +0 -94
- data/examples/ssh_interact.rb +0 -159
- data/examples/ssh_login.rb +0 -64
- data/expect-pty.gemspec +0 -33
- data/lib/expect/configuration.rb +0 -122
- data/lib/expect/terminal.rb +0 -102
- data/script/ci +0 -121
- data/script/release.rb +0 -319
- data/test/buffer_accounting_test.rb +0 -83
- data/test/cleanup_test.rb +0 -251
- data/test/compare_upstream.rb +0 -157
- data/test/configuration_test.rb +0 -133
- data/test/deadline_test.rb +0 -237
- data/test/diagnostics_test.rb +0 -353
- data/test/edge_case_test.rb +0 -262
- data/test/fixtures/ssh_scripts/01_identity.sh +0 -4
- data/test/fixtures/ssh_scripts/02_output.sh +0 -5
- data/test/fixtures/ssh_scripts/03_delayed.sh +0 -6
- data/test/fixtures/ssh_scripts/04_failure.sh +0 -2
- data/test/fixtures/ssh_scripts/05_recovery.sh +0 -3
- data/test/initialization_failure_test.rb +0 -92
- data/test/integration/README.md +0 -109
- data/test/integration/ssh_scripts.rb +0 -94
- data/test/interact_test.rb +0 -253
- data/test/interconnect_test.rb +0 -425
- data/test/io_test.rb +0 -321
- data/test/kibitz_test.rb +0 -45
- data/test/lifecycle_contract_test.rb +0 -71
- data/test/literal_scan_test.rb +0 -97
- data/test/matching_test.rb +0 -211
- data/test/multi_session_test.rb +0 -66
- data/test/ownership_sequence_test.rb +0 -208
- data/test/pattern_offset_test.rb +0 -43
- data/test/process_interruption_test.rb +0 -296
- data/test/process_test.rb +0 -291
- data/test/redactor_test.rb +0 -183
- data/test/relay_recovery_test.rb +0 -451
- data/test/relay_reentrancy_test.rb +0 -159
- data/test/release_test.rb +0 -375
- data/test/ruby_api_test.rb +0 -515
- data/test/scan_reuse_test.rb +0 -109
- data/test/script_logging_test.rb +0 -124
- data/test/support/interact_probe.rb +0 -125
- data/test/support/kibitz_probe.rb +0 -177
- data/test/support/script_probe.rb +0 -158
- data/test/terminal_cleanup_test.rb +0 -349
- data/test/test_helper.rb +0 -58
- data/test/timeout_test.rb +0 -289
- data/test/write_contract_test.rb +0 -105
data/sig/expect.rbs
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Public Session API; internal matching and relay protocols are documented with @api private.
|
|
2
|
+
module Expect
|
|
3
|
+
type duration = Numeric | String
|
|
4
|
+
type pattern = String | Regexp | :eof | :timeout
|
|
5
|
+
type result_error = :eof | :timeout | Exception | nil
|
|
6
|
+
type result_fields = { number: Integer?, error: result_error, match: String?, before: String?, after: String?, session: Session?, captures: Array[String?] }
|
|
7
|
+
type diagnostic_event = { event: Symbol, pid: Integer?, fd: Integer?, message: String }
|
|
8
|
+
|
|
9
|
+
interface _Writer
|
|
10
|
+
def write: (String) -> Integer
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
interface _Logger
|
|
14
|
+
def add: (Integer, diagnostic_event, String) -> untyped
|
|
15
|
+
|
|
16
|
+
def debug?: () -> bool
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
VERSION: String
|
|
20
|
+
CONTINUE: :continue
|
|
21
|
+
CONTINUE_WITHOUT_RESET: :continue_without_reset
|
|
22
|
+
|
|
23
|
+
class SpawnError < StandardError
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class ReentrancyError < StandardError
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class WriteTimeout < IOError
|
|
30
|
+
attr_reader bytes_written: Integer
|
|
31
|
+
|
|
32
|
+
def initialize: (?String message, ?bytes_written: Integer) -> void
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.spawn: (
|
|
36
|
+
*String command, ?env: Hash[String, String?], ?chdir: String?, ?raw: bool, ?graceful: bool,
|
|
37
|
+
?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
|
|
38
|
+
?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
|
|
39
|
+
) -> Session
|
|
40
|
+
| [A] (
|
|
41
|
+
*String command, ?env: Hash[String, String?], ?chdir: String?, ?raw: bool, ?graceful: bool,
|
|
42
|
+
?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
|
|
43
|
+
?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
|
|
44
|
+
) { (Session) -> A } -> A
|
|
45
|
+
|
|
46
|
+
def self.open: (
|
|
47
|
+
IO io, ?writer: IO, ?own: bool, ?graceful: bool,
|
|
48
|
+
?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
|
|
49
|
+
?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
|
|
50
|
+
) -> Session
|
|
51
|
+
| [A] (
|
|
52
|
+
IO io, ?writer: IO, ?own: bool, ?graceful: bool,
|
|
53
|
+
?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
|
|
54
|
+
?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
|
|
55
|
+
) { (Session) -> A } -> A
|
|
56
|
+
|
|
57
|
+
def self.continue: (?reset_timeout: bool) -> (:continue | :continue_without_reset)
|
|
58
|
+
|
|
59
|
+
def self.monotonic: () -> Float
|
|
60
|
+
|
|
61
|
+
def self.duration: (duration?) -> Float?
|
|
62
|
+
|
|
63
|
+
def self.readable_sessions: (*Session sessions, ?timeout: duration?) -> Array[Session]
|
|
64
|
+
|
|
65
|
+
def self.interconnect: (*Session sessions, ?timeout: duration?) -> Session?
|
|
66
|
+
|
|
67
|
+
def self.expect: (
|
|
68
|
+
*pattern patterns, ?from: (Session | Array[Session]), ?timeout: duration?, ?deadline: duration?,
|
|
69
|
+
?consume: bool, ?reset_timeout_on_read: bool
|
|
70
|
+
) ?{ (PatternList) -> untyped } -> Result
|
|
71
|
+
|
|
72
|
+
class Session
|
|
73
|
+
def initialize: (
|
|
74
|
+
?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
|
|
75
|
+
?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
|
|
76
|
+
) -> void
|
|
77
|
+
|
|
78
|
+
def spawn: (*String command, ?env: Hash[String, String?], ?chdir: String?, ?raw: bool) -> Session
|
|
79
|
+
|
|
80
|
+
def expect: (
|
|
81
|
+
*pattern patterns, ?timeout: duration?, ?deadline: duration?, ?consume: bool, ?reset_timeout_on_read: bool
|
|
82
|
+
) ?{ (PatternList) -> untyped } -> Result
|
|
83
|
+
|
|
84
|
+
def after: () -> String?
|
|
85
|
+
|
|
86
|
+
def before: () -> String?
|
|
87
|
+
|
|
88
|
+
def match: () -> String?
|
|
89
|
+
|
|
90
|
+
def alive?: () -> bool
|
|
91
|
+
|
|
92
|
+
def closed?: () -> bool
|
|
93
|
+
|
|
94
|
+
def eof?: () -> bool
|
|
95
|
+
|
|
96
|
+
def tty?: () -> bool
|
|
97
|
+
|
|
98
|
+
def pending_output?: () -> bool
|
|
99
|
+
|
|
100
|
+
def buffer: () -> String
|
|
101
|
+
|
|
102
|
+
def buffer=: (String value) -> void
|
|
103
|
+
|
|
104
|
+
def clear_buffer: () -> String
|
|
105
|
+
|
|
106
|
+
def buffer_discarded_bytes: () -> Integer
|
|
107
|
+
|
|
108
|
+
def captures: () -> Array[String?]
|
|
109
|
+
|
|
110
|
+
def command: () -> Array[String]?
|
|
111
|
+
|
|
112
|
+
def error: () -> result_error
|
|
113
|
+
|
|
114
|
+
def exit_code: () -> Integer?
|
|
115
|
+
|
|
116
|
+
def fileno: () -> Integer?
|
|
117
|
+
|
|
118
|
+
def pid: () -> Integer?
|
|
119
|
+
|
|
120
|
+
def match_number: () -> Integer?
|
|
121
|
+
|
|
122
|
+
def last_result: () -> Result?
|
|
123
|
+
|
|
124
|
+
def slave: () -> IO?
|
|
125
|
+
|
|
126
|
+
def tty_name: () -> String?
|
|
127
|
+
|
|
128
|
+
def to_io: () -> IO
|
|
129
|
+
|
|
130
|
+
def writer: () -> IO
|
|
131
|
+
|
|
132
|
+
def process_status: () -> Process::Status?
|
|
133
|
+
|
|
134
|
+
def inspect: () -> String
|
|
135
|
+
|
|
136
|
+
def close: (?graceful: bool) -> nil
|
|
137
|
+
|
|
138
|
+
def soft_close: (?timeout: duration?, ?term_timeout: duration) -> Process::Status?
|
|
139
|
+
|
|
140
|
+
def hard_close: (?timeout: duration) -> Process::Status?
|
|
141
|
+
|
|
142
|
+
def wait: (?timeout: duration?) -> Process::Status?
|
|
143
|
+
|
|
144
|
+
def write: (*untyped objects) -> Integer
|
|
145
|
+
|
|
146
|
+
def send_slow: (*untyped objects, delay: duration) -> Integer
|
|
147
|
+
|
|
148
|
+
def puts: (*untyped objects) -> nil
|
|
149
|
+
|
|
150
|
+
def <<: (untyped object) -> Session
|
|
151
|
+
|
|
152
|
+
def on_sequence: ((String | Regexp | :eof) sequence) ?{ () -> untyped } -> Session
|
|
153
|
+
|
|
154
|
+
def redact: (*String secrets) -> Session
|
|
155
|
+
|
|
156
|
+
def interact: (?input: (IO | Session), ?escape: (String | Regexp)?, ?output: _Writer?, ?timeout: duration?, ?raw: bool) -> Session?
|
|
157
|
+
|
|
158
|
+
def timeout: () -> Float?
|
|
159
|
+
|
|
160
|
+
def timeout=: (duration? value) -> void
|
|
161
|
+
|
|
162
|
+
def write_timeout: () -> Float?
|
|
163
|
+
|
|
164
|
+
def write_timeout=: (duration? value) -> void
|
|
165
|
+
|
|
166
|
+
def buffer_limit: () -> Integer?
|
|
167
|
+
|
|
168
|
+
def buffer_limit=: (Integer? value) -> void
|
|
169
|
+
|
|
170
|
+
def logger: () -> _Logger?
|
|
171
|
+
|
|
172
|
+
def logger=: (_Logger? value) -> void
|
|
173
|
+
|
|
174
|
+
def transcript: () -> _Writer?
|
|
175
|
+
|
|
176
|
+
def transcript=: (_Writer? value) -> void
|
|
177
|
+
|
|
178
|
+
def outputs: () -> Array[_Writer]
|
|
179
|
+
|
|
180
|
+
def outputs=: (Array[_Writer] value) -> void
|
|
181
|
+
|
|
182
|
+
def write_transcript: (*untyped objects) -> nil
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
class Result < Data
|
|
186
|
+
def self.new: (
|
|
187
|
+
?number: Integer?,
|
|
188
|
+
?error: result_error,
|
|
189
|
+
?match: String?,
|
|
190
|
+
?before: String?,
|
|
191
|
+
?after: String?,
|
|
192
|
+
?session: Session?,
|
|
193
|
+
?captures: Array[String?]
|
|
194
|
+
) -> Result
|
|
195
|
+
| (?Integer?, ?result_error, ?String?, ?String?, ?String?, ?Session?, ?Array[String?]) -> Result
|
|
196
|
+
|
|
197
|
+
def self.[]: (
|
|
198
|
+
?number: Integer?,
|
|
199
|
+
?error: result_error,
|
|
200
|
+
?match: String?,
|
|
201
|
+
?before: String?,
|
|
202
|
+
?after: String?,
|
|
203
|
+
?session: Session?,
|
|
204
|
+
?captures: Array[String?]
|
|
205
|
+
) -> Result
|
|
206
|
+
| (?Integer?, ?result_error, ?String?, ?String?, ?String?, ?Session?, ?Array[String?]) -> Result
|
|
207
|
+
|
|
208
|
+
def self.members: () -> Array[Symbol]
|
|
209
|
+
|
|
210
|
+
def self.inspect: () -> String
|
|
211
|
+
|
|
212
|
+
def members: () -> Array[Symbol]
|
|
213
|
+
|
|
214
|
+
attr_reader number: Integer?
|
|
215
|
+
attr_reader error: result_error
|
|
216
|
+
attr_reader match: String?
|
|
217
|
+
attr_reader before: String?
|
|
218
|
+
attr_reader after: String?
|
|
219
|
+
attr_reader session: Session?
|
|
220
|
+
attr_reader captures: Array[String?]
|
|
221
|
+
|
|
222
|
+
def initialize: (
|
|
223
|
+
?number: Integer?,
|
|
224
|
+
?error: result_error,
|
|
225
|
+
?match: String?,
|
|
226
|
+
?before: String?,
|
|
227
|
+
?after: String?,
|
|
228
|
+
?session: Session?,
|
|
229
|
+
?captures: Array[String?]
|
|
230
|
+
) -> void
|
|
231
|
+
|
|
232
|
+
def matched?: () -> bool
|
|
233
|
+
|
|
234
|
+
def timeout?: () -> bool
|
|
235
|
+
|
|
236
|
+
def eof?: () -> bool
|
|
237
|
+
|
|
238
|
+
def deconstruct: () -> [Integer?, result_error, String?, String?, String?, Session?, Array[String?]]
|
|
239
|
+
|
|
240
|
+
def with: (
|
|
241
|
+
?number: Integer?,
|
|
242
|
+
?error: result_error,
|
|
243
|
+
?match: String?,
|
|
244
|
+
?before: String?,
|
|
245
|
+
?after: String?,
|
|
246
|
+
?session: Session?,
|
|
247
|
+
?captures: Array[String?]
|
|
248
|
+
) -> Result
|
|
249
|
+
|
|
250
|
+
def to_h: () -> result_fields
|
|
251
|
+
| [K, V] () { (Symbol, untyped) -> [K, V] } -> Hash[K, V]
|
|
252
|
+
|
|
253
|
+
def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, untyped]
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
class PatternList
|
|
257
|
+
def initialize: (?(Session | Array[Session]) sessions, ?Array[pattern] patterns) -> void
|
|
258
|
+
|
|
259
|
+
def on: ((String | Regexp) value, ?from: (Session | Array[Session])) ?{ (Session) -> untyped } -> PatternList
|
|
260
|
+
|
|
261
|
+
def eof: (?from: (Session | Array[Session])) ?{ (Session) -> untyped } -> PatternList
|
|
262
|
+
|
|
263
|
+
def timeout: () ?{ (Array[Session]) -> untyped } -> PatternList
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
class Redactor
|
|
267
|
+
def self.redact: (String data, Array[String] patterns, ?replacement: String) -> String
|
|
268
|
+
|
|
269
|
+
def initialize: (Array[String] patterns, ?replacement: String) -> void
|
|
270
|
+
|
|
271
|
+
def patterns=: (Array[String]) -> void
|
|
272
|
+
|
|
273
|
+
def append: (String) -> String
|
|
274
|
+
|
|
275
|
+
def finish: (?partial: bool) -> String
|
|
276
|
+
|
|
277
|
+
def inspect: () -> String
|
|
278
|
+
end
|
|
279
|
+
end
|
metadata
CHANGED
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: expect-pty
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- expect-pty contributors
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-10-01 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
-
name: forwardable
|
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
|
15
|
-
requirements:
|
|
16
|
-
- - "~>"
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '1.3'
|
|
19
|
-
type: :runtime
|
|
20
|
-
prerelease: false
|
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
-
requirements:
|
|
23
|
-
- - "~>"
|
|
24
|
-
- !ruby/object:Gem::Version
|
|
25
|
-
version: '1.3'
|
|
26
12
|
- !ruby/object:Gem::Dependency
|
|
27
13
|
name: io-console
|
|
28
14
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -30,9 +16,6 @@ dependencies:
|
|
|
30
16
|
- - ">="
|
|
31
17
|
- !ruby/object:Gem::Version
|
|
32
18
|
version: '0.6'
|
|
33
|
-
- - "<"
|
|
34
|
-
- !ruby/object:Gem::Version
|
|
35
|
-
version: '1.0'
|
|
36
19
|
type: :runtime
|
|
37
20
|
prerelease: false
|
|
38
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -40,61 +23,32 @@ dependencies:
|
|
|
40
23
|
- - ">="
|
|
41
24
|
- !ruby/object:Gem::Version
|
|
42
25
|
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
26
|
- !ruby/object:Gem::Dependency
|
|
67
|
-
name:
|
|
27
|
+
name: logger
|
|
68
28
|
requirement: !ruby/object:Gem::Requirement
|
|
69
29
|
requirements:
|
|
70
30
|
- - ">="
|
|
71
31
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '
|
|
73
|
-
- - "<"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '1.0'
|
|
32
|
+
version: '1.6'
|
|
76
33
|
type: :runtime
|
|
77
34
|
prerelease: false
|
|
78
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
36
|
requirements:
|
|
80
37
|
- - ">="
|
|
81
38
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
83
|
-
- - "<"
|
|
84
|
-
- !ruby/object:Gem::Version
|
|
85
|
-
version: '1.0'
|
|
39
|
+
version: '1.6'
|
|
86
40
|
- !ruby/object:Gem::Dependency
|
|
87
41
|
name: stringio
|
|
88
42
|
requirement: !ruby/object:Gem::Requirement
|
|
89
43
|
requirements:
|
|
90
|
-
- - "
|
|
44
|
+
- - ">="
|
|
91
45
|
- !ruby/object:Gem::Version
|
|
92
46
|
version: '3.0'
|
|
93
47
|
type: :runtime
|
|
94
48
|
prerelease: false
|
|
95
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
96
50
|
requirements:
|
|
97
|
-
- - "
|
|
51
|
+
- - ">="
|
|
98
52
|
- !ruby/object:Gem::Version
|
|
99
53
|
version: '3.0'
|
|
100
54
|
description: Automate interactive programs with exact and regexp matching, Ruby blocks,
|
|
@@ -103,34 +57,13 @@ executables: []
|
|
|
103
57
|
extensions: []
|
|
104
58
|
extra_rdoc_files: []
|
|
105
59
|
files:
|
|
106
|
-
- ".rubocop.yml"
|
|
107
60
|
- CHANGELOG.md
|
|
108
|
-
- CONTRIBUTING.md
|
|
109
|
-
- Gemfile
|
|
110
61
|
- LICENSE
|
|
111
62
|
- README.md
|
|
112
|
-
-
|
|
113
|
-
-
|
|
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
|
|
63
|
+
- docs/API.md
|
|
64
|
+
- docs/MIGRATION.md
|
|
132
65
|
- lib/expect.rb
|
|
133
|
-
- lib/expect/
|
|
66
|
+
- lib/expect/cleanup.rb
|
|
134
67
|
- lib/expect/interaction.rb
|
|
135
68
|
- lib/expect/logging.rb
|
|
136
69
|
- lib/expect/matcher.rb
|
|
@@ -141,52 +74,10 @@ files:
|
|
|
141
74
|
- lib/expect/relay.rb
|
|
142
75
|
- lib/expect/relay_writer.rb
|
|
143
76
|
- lib/expect/result.rb
|
|
77
|
+
- lib/expect/session.rb
|
|
144
78
|
- lib/expect/session_resources.rb
|
|
145
|
-
- lib/expect/terminal.rb
|
|
146
79
|
- lib/expect/version.rb
|
|
147
|
-
-
|
|
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
|
|
80
|
+
- sig/expect.rbs
|
|
190
81
|
homepage: https://github.com/gatework/expect-ruby
|
|
191
82
|
licenses:
|
|
192
83
|
- MIT
|
|
@@ -202,14 +93,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
202
93
|
requirements:
|
|
203
94
|
- - ">="
|
|
204
95
|
- !ruby/object:Gem::Version
|
|
205
|
-
version: '3.
|
|
96
|
+
version: '3.4'
|
|
206
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
98
|
requirements:
|
|
208
99
|
- - ">="
|
|
209
100
|
- !ruby/object:Gem::Version
|
|
210
101
|
version: '0'
|
|
211
102
|
requirements: []
|
|
212
|
-
rubygems_version: 4.0.
|
|
103
|
+
rubygems_version: 4.0.16
|
|
213
104
|
specification_version: 4
|
|
214
105
|
summary: Ruby PTY automation with the Expect.pm interaction model
|
|
215
106
|
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
|
data/Rakefile
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rake/testtask"
|
|
4
|
-
|
|
5
|
-
Rake::TestTask.new do |task|
|
|
6
|
-
task.libs << "test"
|
|
7
|
-
task.pattern = "test/**/*_test.rb"
|
|
8
|
-
task.warning = true
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
desc "Check Ruby style and common mistakes"
|
|
12
|
-
task :lint do
|
|
13
|
-
ruby "-S", "rubocop"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
task default: %i[lint test]
|
|
17
|
-
|
|
18
|
-
namespace :test do
|
|
19
|
-
desc "Log in over SSH and verify multiple scripts and persisted logs (opt-in)"
|
|
20
|
-
task :ssh do
|
|
21
|
-
ruby "test/integration/ssh_scripts.rb"
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
desc "Log in over SSH and verify real PTY interact handoff (opt-in)"
|
|
25
|
-
task :ssh_interact do
|
|
26
|
-
ruby "examples/ssh_interact.rb", "--auto"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
desc "Automatically log into local SSH and run read-only macOS checks"
|
|
30
|
-
task :ssh_auto do
|
|
31
|
-
ruby "examples/ssh_auto.rb", "--no-interact"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
desc "Run the local two-terminal kibitz scenarios and save logs (no SSH required)"
|
|
35
|
-
task :kibitz do
|
|
36
|
-
ruby "examples/kibitz/test_kibitz.rb"
|
|
37
|
-
end
|
|
38
|
-
end
|