Class: Expectr
- Inherits:
-
Object
- Object
- Expectr
- Defined in:
- lib/expectr.rb,
lib/expectr/adopt.rb,
lib/expectr/child.rb,
lib/expectr/error.rb,
lib/expectr/errstr.rb,
lib/expectr/lambda.rb,
lib/expectr/version.rb,
lib/expectr/interface.rb,
lib/expectr/interpreter.rb
Overview
Public: Expectr is an API to the functionality of Expect (see expect.nist.gov) implemented in ruby.
Expectr contrasts with Ruby’s built-in Expect class by avoiding tying in with the IO class, instead creating a new object entirely to allow for more grainular control over the execution and display of the program being run.
Examples
# SSH Login to another machine
exp = Expectr.new('ssh [email protected]')
exp.expect("Password:")
exp.send('password')
exp.interact!(blocking: true)
# See if a web server is running on the local host, react accordingly
exp = Expectr.new('netstat -ntl|grep ":80 " && echo "WEB"', timeout: 1)
if exp.expeect("WEB")
# Do stuff if we see 'WEB' in the output
else
# Do other stuff
end
Defined Under Namespace
Modules: Errstr, Interface Classes: Adopt, Child, Interpreter, Lambda, ProcessError
Constant Summary collapse
- DEFAULT_TIMEOUT =
30
- DEFAULT_FLUSH_BUFFER =
true
- DEFAULT_BUFFER_SIZE =
8192
- DEFAULT_CONSTRAIN =
false
- VERSION =
'2.0.0'
Instance Attribute Summary collapse
-
#buffer ⇒ Object
readonly
Public: Returns the active buffer to match against.
-
#buffer_size ⇒ Object
Public: Gets/sets the number of bytes to use for the internal buffer.
-
#constrain ⇒ Object
Public: Gets/sets whether to constrain the buffer to the buffer size.
-
#discard ⇒ Object
readonly
Public: Returns the buffer discarded by the latest call to Expectr#expect.
-
#flush_buffer ⇒ Object
Public: Gets/sets whether to flush program output to $stdout.
-
#pid ⇒ Object
readonly
Public: Returns the PID of the running process.
-
#timeout ⇒ Object
Public: Gets/sets the number of seconds a call to Expectr#expect may last.
Instance Method Summary collapse
-
#clear_buffer! ⇒ Object
Public: Clear output buffer.
-
#expect(pattern, recoverable = false) ⇒ Object
Public: Begin a countdown and search for a given String or Regexp in the output buffer.
-
#expect_procmap(pattern_map) ⇒ Object
Public: Begin a countdown and search for any of multiple possible patterns, performing designated actions upon success/failure.
-
#initialize(cmd = '', args = {}) ⇒ Expectr
constructor
Public: Initialize a new Expectr object.
-
#interact!(args = {}) ⇒ Object
Public: Relinquish control of the running process to the controlling terminal, acting as a pass-through for the life of the process (or until the leave! method is called).
-
#interact? ⇒ Boolean
Public: Report whether or not current Expectr object is in interact mode.
-
#leave! ⇒ Object
Public: Cause the current Expectr object to drop out of interact mode.
-
#puts(str = '') ⇒ Object
Public: Wraps Expectr#send, appending a newline to the end of the string.
Constructor Details
#initialize(cmd = '', args = {}) ⇒ Expectr
Public: Initialize a new Expectr object. Spawns a sub-process and attaches to STDIN and STDOUT for the new process.
cmd - A String or File referencing the application to launch (default: ”) args - A Hash used to specify options for the new object (default: {}):
:timeout - Number of seconds that a call to Expectr#expect has
to complete (default: 30)
:flush_buffer - Whether to flush output of the process to the
console (default: true)
:buffer_size - Number of bytes to attempt to read from sub-process
at a time. If :constrain is true, this will be the
maximum size of the internal buffer as well.
(default: 8192)
:constrain - Whether to constrain the internal buffer from the
sub-process to :buffer_size (default: false)
:interface - Interface Object to use when instantiating the new
Expectr object. (default: Child)
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/expectr.rb', line 74 def initialize(cmd = '', args = {}) setup_instance (args) case args[:interface] when :lambda interface = call_lambda_interface(args) when :adopt interface = call_adopt_interface(args) else interface = call_child_interface(cmd) end interface.init_instance.each do |spec| ->(name, func) { define_singleton_method(name, func.call) }.call(*spec) end Thread.new { output_loop } end |
Instance Attribute Details
#buffer ⇒ Object (readonly)
Public: Returns the active buffer to match against
53 54 55 |
# File 'lib/expectr.rb', line 53 def buffer @buffer end |
#buffer_size ⇒ Object
Public: Gets/sets the number of bytes to use for the internal buffer
47 48 49 |
# File 'lib/expectr.rb', line 47 def buffer_size @buffer_size end |
#constrain ⇒ Object
Public: Gets/sets whether to constrain the buffer to the buffer size
49 50 51 |
# File 'lib/expectr.rb', line 49 def constrain @constrain end |
#discard ⇒ Object (readonly)
Public: Returns the buffer discarded by the latest call to Expectr#expect
55 56 57 |
# File 'lib/expectr.rb', line 55 def discard @discard end |
#flush_buffer ⇒ Object
Public: Gets/sets whether to flush program output to $stdout
45 46 47 |
# File 'lib/expectr.rb', line 45 def flush_buffer @flush_buffer end |
#pid ⇒ Object (readonly)
Public: Returns the PID of the running process
51 52 53 |
# File 'lib/expectr.rb', line 51 def pid @pid end |
#timeout ⇒ Object
Public: Gets/sets the number of seconds a call to Expectr#expect may last
43 44 45 |
# File 'lib/expectr.rb', line 43 def timeout @timeout end |
Instance Method Details
#clear_buffer! ⇒ Object
Public: Clear output buffer
Returns nothing.
221 222 223 224 225 |
# File 'lib/expectr.rb', line 221 def clear_buffer! @out_mutex.synchronize do @buffer.clear end end |
#expect(pattern, recoverable = false) ⇒ Object
Public: Begin a countdown and search for a given String or Regexp in the output buffer.
pattern - Object String or Regexp representing pattern for which to
search, or a Hash containing pattern -> Proc mappings to be
used in cases where multiple potential patterns should map
to distinct actions.
recoverable - Denotes whether failing to match the pattern should cause the
method to raise an exception (default: false)
Examples
exp.expect("this should exist")
# => MatchData
exp.expect("this should exist") do
# ...
end
exp.expect(/not there/)
# Raises Timeout::Error
exp.expect(/not there/, true)
# => nil
hash = { "First possibility" => -> { puts "option a" },
"Second possibility" => -> { puts "option b" },
default: => -> { puts "called on timeout" } }
exp.expect(hash)
Returns a MatchData object once a match is found if no block is given Yields the MatchData object representing the match Raises TypeError if something other than a String or Regexp is given Raises Timeout::Error if a match isn’t found in time, unless recoverable
171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/expectr.rb', line 171 def expect(pattern, recoverable = false) return expect_procmap(pattern) if pattern.is_a?(Hash) match = nil pattern = Regexp.new(Regexp.quote(pattern)) if pattern.is_a?(String) unless pattern.is_a?(Regexp) raise(TypeError, Errstr::EXPECT_WRONG_TYPE) end match = watch_match(pattern, recoverable) block_given? ? yield(match) : match end |
#expect_procmap(pattern_map) ⇒ Object
Public: Begin a countdown and search for any of multiple possible patterns, performing designated actions upon success/failure.
pattern_map - Hash containing mappings between Strings or Regexps and
procedure objects. Additionally, an optional action,
designated by :default or :timeout may be provided to specify
an action to take upon failure.
Examples
exp.expect_procmap({
"option 1" => -> { puts "action 1" },
/option 2/ => -> { puts "action 2" },
:default => -> { puts "default" }
})
Calls the procedure associated with the pattern provided.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/expectr.rb', line 201 def expect_procmap(pattern_map) pattern_map, pattern, recoverable = process_procmap(pattern_map) match = nil match = watch_match(pattern, recoverable) pattern_map.each do |s,p| if s.is_a?(Regexp) return p.call if s.match(match.to_s) end end pattern_map[:default].call unless pattern_map[:default].nil? pattern_map[:timeout].call unless pattern_map[:timeout].nil? nil end |
#interact!(args = {}) ⇒ Object
Public: Relinquish control of the running process to the controlling terminal, acting as a pass-through for the life of the process (or until the leave! method is called).
args - A Hash used to specify options to be used for interaction (default:
{}):
:flush_buffer - explicitly set @flush_buffer to the value specified
:blocking - Whether to block on this call or allow code
execution to continue (default: false)
Returns the interaction Thread
105 106 107 108 109 110 111 112 |
# File 'lib/expectr.rb', line 105 def interact!(args = {}) if @interact raise(ProcessError, Errstr::ALREADY_INTERACT) end @flush_buffer = args[:flush_buffer].nil? ? true : args[:flush_buffer] args[:blocking] ? interact_thread.join : interact_thread end |
#interact? ⇒ Boolean
Public: Report whether or not current Expectr object is in interact mode
Returns true or false
117 118 119 |
# File 'lib/expectr.rb', line 117 def interact? @interact end |
#leave! ⇒ Object
Public: Cause the current Expectr object to drop out of interact mode
Returns nothing.
124 125 126 |
# File 'lib/expectr.rb', line 124 def leave! @interact=false end |
#puts(str = '') ⇒ Object
Public: Wraps Expectr#send, appending a newline to the end of the string
str - String to be sent to the active process (default: ”)
Returns nothing.
133 134 135 |
# File 'lib/expectr.rb', line 133 def puts(str = '') send str + "\n" end |