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.rb by avoiding tying in with the IO class in favor of creating a new object entirely to allow for more granular 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: Adopt, Child, Errstr, Interface, Lambda Classes: Interpreter, ProcessError
Constant Summary collapse
- DEFAULT_TIMEOUT =
30
- DEFAULT_FLUSH_BUFFER =
true
- DEFAULT_BUFFER_SIZE =
8192
- DEFAULT_CONSTRAIN =
false
- VERSION =
'2.0.2'
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, optionally taking further action based upon which, if any, match was found.
-
#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 = '', args = {}) ⇒ Expectr
constructor
Public: Initialize a new Expectr object.
-
#interact!(args = {}) ⇒ Object
Public: Allow direct control of the running process from 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 leave interact mode.
-
#puts(str = '') ⇒ Object
Public: Wraps Expectr#send, appending a newline to the end of the string.
Constructor Details
#initialize(cmd_args = '', args = {}) ⇒ Expectr
Public: Initialize a new Expectr object. Spawns a sub-process and attaches to STDIN and STDOUT for the new process.
cmd_args - This may be either a Hash containing arguments (described below)
or a String or File Object referencing the application to launch
(assuming Child interface). This argument, if not a Hash, will
be changed into the Hash { cmd: cmd_args }. This argument will
be merged with the args Hash, overriding any arguments
specified there.
This argument is kept around for the sake of backward
compatibility with extant Expectr scripts and may be deprecated
in the future. (default: {})
args - A Hash used to specify options for the instance. (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 characters.
(default: false)
:interface - Interface Object to use when instantiating the
new Expectr object. (default: Child)
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/expectr.rb', line 82 def initialize(cmd_args = '', args = {}) setup_instance (args) cmd_args = { cmd: cmd_args } unless cmd_args.is_a?(Hash) args.merge!(cmd_args) unless [:lambda, :adopt, :child].include?(args[:interface]) args[:interface] = :child end self.extend self.class.const_get(args[:interface].capitalize) init_interface(args) Thread.new { output_loop } end |
Instance Attribute Details
#buffer ⇒ Object (readonly)
Public: Returns the active buffer to match against
52 53 54 |
# File 'lib/expectr.rb', line 52 def buffer @buffer end |
#buffer_size ⇒ Object
Public: Gets/sets the number of bytes to use for the internal buffer
46 47 48 |
# File 'lib/expectr.rb', line 46 def buffer_size @buffer_size end |
#constrain ⇒ Object
Public: Gets/sets whether to constrain the buffer to the buffer size
48 49 50 |
# File 'lib/expectr.rb', line 48 def constrain @constrain end |
#discard ⇒ Object (readonly)
Public: Returns the buffer discarded by the latest call to Expectr#expect
54 55 56 |
# File 'lib/expectr.rb', line 54 def discard @discard end |
#flush_buffer ⇒ Object
Public: Gets/sets whether to flush program output to $stdout
44 45 46 |
# File 'lib/expectr.rb', line 44 def flush_buffer @flush_buffer end |
#pid ⇒ Object (readonly)
Public: Returns the PID of the running process
50 51 52 |
# File 'lib/expectr.rb', line 50 def pid @pid end |
#timeout ⇒ Object
Public: Gets/sets the number of seconds a call to Expectr#expect may last
42 43 44 |
# File 'lib/expectr.rb', line 42 def timeout @timeout end |
Instance Method Details
#clear_buffer! ⇒ Object
Public: Clear output buffer.
Returns nothing.
227 228 229 230 231 |
# File 'lib/expectr.rb', line 227 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, optionally taking further action based upon which, if any, match was found.
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
177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/expectr.rb', line 177 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.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/expectr.rb', line 207 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: Allow direct control of the running process from 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, calling #join on it if :blocking is true.
110 111 112 113 114 115 116 117 |
# File 'lib/expectr.rb', line 110 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 a boolean.
122 123 124 |
# File 'lib/expectr.rb', line 122 def interact? @interact end |
#leave! ⇒ Object
Public: Cause the current Expectr object to leave interact mode.
Returns nothing.
129 130 131 |
# File 'lib/expectr.rb', line 129 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.
138 139 140 |
# File 'lib/expectr.rb', line 138 def puts(str = '') send str + "\n" end |