parley 0.2.0 → 0.2.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.
data/README.md CHANGED
@@ -1,13 +1,15 @@
1
- parley
2
- ======
1
+ # Parley
3
2
 
4
- An Expect-like gem for Ruby
3
+ ## Introduction
4
+
5
+ An expect-like module for Ruby modled after Perl's Expect.pm
5
6
 
6
7
  Parley is an implementation of an expect-like API. It is designed to
7
- help port away from Perl Expect based applications. The name "expect"
8
- is already well established in ruby. Those of you who have wrestled
9
- with the interactive, text-mode, APIs of the world will appreciate the
10
- meaning of the word:
8
+ help port away from Perl Expect based applications.
9
+
10
+ The name "expect"
11
+ is already well established in ruby and varients of that name are in use by several gems.
12
+ "parley" was chosen as alternative to yet another expect-varient.
11
13
 
12
14
  From http://www.thefreedictionary.com/parley "A discussion or conference, especially one between enemies over terms of truce or other matters."
13
15
 
@@ -15,116 +17,142 @@ See http://www.nist.gov/el/msid/expect.cfm for references to the original Expect
15
17
 
16
18
  See http://search.cpan.org/~rgiersig/Expect-1.21/Expect.pod for information on Expect.pm
17
19
 
18
- = Parley
19
- An expect-like module for Ruby modled after Perl's Expect.pm
20
+ ## Duck Type Compatibility
20
21
 
21
- Parley is a module that can be used with any class, like PTY, IO or
22
- StringIO that responds_to?() :eof?, and either :read_nonblock(maxread)
23
- or :getc.
22
+ Parley is a module that can be used with any class, like `PTY`, `IO` or
23
+ `StringIO` that responds to `eof()`, and either `read_nonblock(maxread)`
24
+ or `getc()`.
24
25
 
25
- If the class also responds to :select, then Parley will be able to wait
26
+ If the instance is valid for use with `Kernel.select()`, then Parley will be able to wait
26
27
  for additional input to arrive.
27
28
 
28
- == parley method arguments
29
+ ## Parley method arguments
30
+
31
+ The `parley()` method is called with two arguments:
32
+
33
+ * an optional timeout in seconds, which may be 0 to indicate immediate timeout or `nil` to indicate no timeout
34
+ * additional arguments are arrays, each array containing a pattern and an action.
35
+
36
+ A call to parley with no arguments should read data until `eof?` and return `:eof`.
29
37
 
30
- The parley() method is called with two arguments:
31
38
 
32
- * a timeout in seconds, which may be zero to indicate no timeout
33
- * an array of arrays, each array contains a pattern and an action.
39
+ ### Each pattern is either:
34
40
 
35
- Each pattern is either:
41
+ * a `RegExp` to match input data
42
+ * the symbol `:timeout` to match the timeout condition from select()
43
+ * the symbol `:eof` to match the eof?() condition
36
44
 
37
- * a RegExp to match input data
38
- * the symbol :timeout to match the timeout condition from select()
39
- * the symbol :eof to match the eof?() condition
45
+ If an action `responds_to?(:call)`, such as a `lambda{|m| code}`
46
+ then the action is called with `MatchData` as an argument.
47
+ In the case of `:timeout` or `:eof`, `MatchData` is from `matching:`
40
48
 
41
- If an action responds_to?(:call), such as a lambda{|m| code}
42
- then the action is called with MatchData as an argument.
43
- In the case of :timeout or :eof, MatchData is from matching:
44
- input_buffer =~ /.*/
49
+ input_buffer =~ /.*/
45
50
 
46
- == Examples of Usage
51
+ ## Examples of Usage
52
+
53
+ ### Standard ruby expect vs. equivalent parley usage
54
+
55
+ In their simplest forms, the two are very similar:
56
+
57
+ * Expect takes a Regexp and an optional timeout
58
+ parameter. The method is either given a block that receives MatchData or it returns `MatchData`.
59
+
60
+ * Parley takes an optional `Numeric` timeout as the first argument and a variable
61
+ number of arrays, each containing a pattern and an action.
47
62
 
48
- === Standard ruby expect vs. equivalent parley usage
49
63
  Standard Ruby expect:
50
- require 'expect'
51
64
 
52
- ...
53
- input.expect(/pattern/, 10) {|matchdata| code}
65
+ require 'expect'
66
+ ...
67
+ input.expect(/pattern/, 10) {|matchdata| code} # wait up to 10 seconds
68
+ input.expect(/pattern/, 0) {|matchdata| code} # no waiting
69
+ input.expect(/pattern/) {|matchdata| code} # wait for a very long time
54
70
 
55
71
  Parley:
56
- require 'parley'
57
-
58
- ...
59
- input.parley(10, [[/pattern/, lambda{|matchdata| code}]])
60
-
61
- === Telnet login using /usr/bin/telnet
62
- require 'parley'
63
- input, output, process_id = PTY.spawn("/usr/bin/telnet localhost")
64
- output.puts '' # hit return to make sure we get some output
65
- result = input.parley(30, [ # allow 30 seconds to login
66
- [ /ogin:/, lambda{|m| output.puts 'username'; :continue} ],
67
- [ /ssword:/, lambda{|m| output.puts 'my-secret-password'; :continue} ],
68
- [ /refused/i, "connection refused" ],
69
- [ :timeout, "timed out" ],
70
- [ :eof, "command output closed" ],
71
- [ /\$/, true ] # some string that only appears in the shell prompt
72
- ])
73
- if result == true
74
- puts "Successful login"
75
- output.puts "date" # This is the important command we had to run
76
- else
77
- puts "Login failed because: #{result}"
78
- end
79
- # We can keep running commands.
80
- input.close
81
- output.close
82
- id, exit_status = Process.wait2(process_id)
83
-
84
- === Run your telnet script against canned input
85
- require 'parley'
86
- class StringIO
87
- include Parley
88
- end
89
- input = StringIO.new("login: password: prompt$\n", "r")
90
- output = StringIO.new("", "w")
91
- output.puts '' # Note: no effect in this example
92
- result = input.parley(30, [ # Note: timeout has no effect for StringIO
93
- # XXX check these example patterns against need for anchoring with ^ and/or $
94
- [ /ogin:/, lambda{|m| output.puts 'username'; :continue} ],
95
- [ /ssword:/, lambda{|m| output.puts 'my-secret-password'; :continue} ],
96
- [ :timeout, "timed out" ],
97
- [ :eof, "command output closed" ],
98
- [ /\$/, true ] # some string that only appears in the shell prompt
99
- ])
100
- if result == true
101
- puts "Successful login"
102
- output.puts "exit"
103
- else
104
- puts "Login failed because: #{result}"
105
- end
106
- input.close
107
- output.close
108
- id, exit_status = Process.wait2(process_id)
109
-
110
- === Handle a timeout condition
111
- require 'parley'
112
- read, write, pid = PTY.spawn("ruby -e 'sleep 20'")
113
- result = read.parley(5, ["timeout, :timeout])
114
- if result == :timeout
115
- puts "Program timed-out as expected"
116
- else
117
- puts "Error, timeout did not happen!"
118
- end
119
-
120
- == Known Issues
121
-
122
- * :reset_timeout from IO::parley() doesn't have the desired effect, it isn't re-establishing the timeout.
123
- * need to generatate adequte documentation. See test/test_parley.rb for now
72
+
73
+ require 'parley'
74
+
75
+ ...
76
+ input.extend Parley # needed if input is not a subclass of IO
77
+ ...
78
+ input.parley(10, [/pattern/, lambda{|matchdata| code}]) # wait up to 10 seconds
79
+ input.parley(0, [/pattern/, lambda{|matchdata| code}]) # no waiting
80
+ input.parley(nil, [/pattern/, lambda{|matchdata| code}]) # wait forever
81
+ input.parley([/pattern/, lambda{|matchdata| code}]) # wait forever
82
+
83
+ ## Telnet login using /usr/bin/telnet
84
+ See the examples directory for a use of Net::Telnet instead of PTY.spawn(...
85
+
86
+ require 'parley'
87
+ input, output, process_id = PTY.spawn("/usr/bin/telnet localhost")
88
+ output.puts '' # hit return to make sure we get some output
89
+ result = input.parley(30, [ # allow 30 seconds to login
90
+ [ /ogin:/, lambda{|m| output.puts 'username'; :continue} ],
91
+ [ /ssword:/, lambda{|m| output.puts 'my-secret-password'; :continue} ],
92
+ [ /refused/i, "connection refused" ],
93
+ [ :timeout, "timed out" ],
94
+ [ :eof, "command output closed" ],
95
+ [ /\$/, true ] # some string that only appears in the shell prompt
96
+ ])
97
+ if result == true
98
+ puts "Successful login"
99
+ output.puts "date" # This is the important command we had to run
100
+ else
101
+ puts "Login failed because: #{result}"
102
+ end
103
+ # We can keep running commands.
104
+ input.close
105
+ output.close
106
+ id, exit_status = Process.wait2(process_id)
107
+
108
+ ### Run your telnet script against canned input
109
+
110
+ require 'parley'
111
+ class StringIO
112
+ include Parley # or use "input.extend Parley"
113
+ end
114
+ input = StringIO.new("login: password: prompt$\n", "r")
115
+ output = StringIO.new("", "w")
116
+ output.puts '' # Note: no effect in this example
117
+ result = input.parley(30, [ # Note: timeout has no effect for StringIO
118
+ # XXX check these example patterns against need for anchoring with ^ and/or $
119
+ [ /ogin:/, lambda{|m| output.puts 'username'; :continue} ],
120
+ [ /ssword:/, lambda{|m| output.puts 'my-secret-password'; :continue} ],
121
+ [ :timeout, "timed out" ],
122
+ [ :eof, "command output closed" ],
123
+ [ /\$/, true ] # some string that only appears in the shell prompt
124
+ ])
125
+ if result == true
126
+ puts "Successful login"
127
+ output.puts "exit"
128
+ else
129
+ puts "Login failed because: #{result}"
130
+ end
131
+ input.close
132
+ output.close
133
+ id, exit_status = Process.wait2(process_id)
134
+
135
+ ### Handle a timeout condition
136
+
137
+ require 'parley'
138
+ read, write, pid = PTY.spawn("ruby -e 'sleep 20'")
139
+ result = read.parley(5, ["timeout, :timeout])
140
+ if result == :timeout
141
+ puts "Program timed-out as expected"
142
+ else
143
+ puts "Error, timeout did not happen!"
144
+ end
145
+
146
+ ## Known Issues
147
+
148
+ * *FIXED!* `:reset_timeout` from IO::parley() doesn't have the desired effect, it isn't re-establishing the timeout.
149
+ * *FIXED!* need to generatate adequte documentation. See `test/test_parley.rb` for now
124
150
  * line oriented reading option
125
- * Finer grain greediness control beyond read_nonblock(maxlen)
151
+ * Finer grain greediness control beyond `read_nonblock(maxlen)`
152
+
153
+ ## Contributing to parley
154
+ --
126
155
 
127
- == Contributing to parley
128
156
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
129
157
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
130
158
  * Fork the project.
@@ -133,7 +161,7 @@ Parley:
133
161
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
134
162
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
135
163
 
136
- == Copyright
164
+ ## Copyright
137
165
 
138
- Copyright (c) 2013 Ben Stoltz.
166
+ Copyright © 2013 Ben Stoltz.
139
167
  See LICENSE.txt for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby -w
2
+ # Ported from Don Libes' example for tcl expect: expect_timed-read
3
+ # read a complete line from stdin
4
+ # aborting after the number of seconds (given as an argument)
5
+ require 'parley'
6
+
7
+ STDIN.parley ARGV[0].to_i, [/^(.*)\n/, lambda{|m| puts m}], [:timeout, nil]
@@ -1,6 +1,75 @@
1
1
 
2
2
  require 'pty'
3
3
 
4
+ # The Parley module is generally used to wrestle with the informal, interactive, text-mode,
5
+ # APIs of the world.
6
+ #
7
+ # Parley is an implementation of an expect-like API. It is designed to
8
+ # help port away from Perl Expect based applications.
9
+ # Parley was chosen as a name as an alternative to the various "expect" like
10
+ # names already in use by other implementations.
11
+ #
12
+ # The {definition of "parley"}[http://www.thefreedictionary.com/parley] used
13
+ # here is: "A discussion or conference, especially one between enemies over
14
+ # terms of truce or other matters."
15
+ #
16
+ # See {the original Expect site at NIST}[http://www.nist.gov/el/msid/expect.cfm] for
17
+ # references to the original Expect language based on Tcl.
18
+ #
19
+ # See the {Perl Expect.pm module}[http://search.cpan.org/~rgiersig/Expect-1.21/Expect.pod].
20
+ #
21
+ # === Compatibility
22
+ # Parley can be used with any class, like PTY, IO or
23
+ # StringIO that responds_to?() :eof?, and either :read_nonblock(maxread) or :getc.
24
+ #
25
+ # If the class also responds to :select, ala IO##select, then Parley will be able to wait
26
+ # for additional input to arrive.
27
+ #
28
+ # === Monkey Patching
29
+ # require 'parley' will automatcially add parley() and support methods to the IO class
30
+ #
31
+ # Author:: Ben Stoltz (mailto:gem-parley@lzrd.com)
32
+ # Copyright:: Copyright (c) 2013 Benjamin Stoltz
33
+ # License:: See LICENSE.txt distributed with this file
34
+ #
35
+ # == Examples
36
+ # === Standard ruby expect vs. equivalent parley usage
37
+ # Standard Ruby expect:
38
+ # require 'expect'
39
+ #
40
+ # ...
41
+ # input.expect(/pattern/, 10) {|matchdata| code}
42
+ #
43
+ # Parley:
44
+ # require 'parley'
45
+ #
46
+ # ...
47
+ # input.parley(10, [/pattern/, lambda{|matchdata| code}])
48
+ #
49
+ # === Telnet login using /usr/bin/telnet
50
+ # require 'parley'
51
+ # input, output, process_id = PTY.spawn("/usr/bin/telnet localhost")
52
+ # output.puts '' # hit return to make sure we get some output
53
+ # result = input.parley(30, # allow 30 seconds to login
54
+ # [ /ogin:/, lambda{|m| output.puts 'username'; :continue} ],
55
+ # [ /ssword:/, lambda{|m| output.puts 'my-secret-password'; :continue} ],
56
+ # [ /refused/i, "connection refused" ],
57
+ # [ :timeout, "timed out" ],
58
+ # [ :eof, "command output closed" ],
59
+ # [ /\$/, true ] # some string that only appears in the shell prompt
60
+ # ])
61
+ # if result == true
62
+ # puts "Successful login"
63
+ # output.puts "date" # This is the important command we had to run
64
+ # else
65
+ # puts "Login failed because: #{result}"
66
+ # end
67
+ # # We can keep running commands.
68
+ # input.close
69
+ # output.close
70
+ # id, exit_status = Process.wait2(process_id)
71
+ #
72
+
4
73
  module Parley
5
74
  # Internal: used to set input data that has been received, but not yet matched
6
75
  #--
@@ -11,7 +80,8 @@ module Parley
11
80
  @unused_buf = v
12
81
  end
13
82
 
14
- # holds the remaining input read from +read_nonblock()+ or +getc()+ but not yet used
83
+ # holds the remaining input read from +read_nonblock()+ or +getc()+ but not
84
+ # yet used
15
85
  def unused_buf
16
86
  @unused_buf = nil unless defined? @unused_buf
17
87
  @unused_buf
@@ -42,37 +112,56 @@ module Parley
42
112
  @parley_maxread
43
113
  end
44
114
 
45
- # Match patterns and conditions and take corresponding actions until an action
46
- # returns a value not equal to +:continue+ or +:reset_timeout+
115
+ # Collect data, from an IO-like object while matching
116
+ # match patterns and conditions (i.e. EOF and Timeout) and take corresponding
117
+ # actions until an action returns a value not equal to +:continue+ or
118
+ # +:reset_timeout+
119
+ #
120
+ # The parley() method is called with two arguments:
121
+ #
122
+ # +timeout_seconds+ specifies the amount of time before the +:timeout+
123
+ # condition is presented to the pattern/action list.
124
+ #
125
+ # a variable number of arrays, each array contains a pattern and an action.
47
126
  #
48
- # +timeout_seconds+ specifies the amount of time before the +:timeout+ condition
49
- # is presented to the pattern/action list.
127
+ # * +timeout_seconds+ = nil disables timeout.
128
+ # * +timeout_seconds+ <= 0 times out immediately as soon as no data is present
129
+ # * +timeout_seconds+ > 0 times out seconds after parley was called unless
130
+ # timer is reset by an action returning :reset_timeout
50
131
  #
51
- # If +timeout_seconds+ is less than or equal to zero, then +:timeout+
52
- # immediately as soon as there is no more data available.
132
+ # A pattern is either:
133
+ # * a RegExp to match input data
134
+ # * the symbol :timeout to match the timeout condition from select()
135
+ # * the symbol :eof to match the eof?() condition
53
136
  #
54
- # XXX bad. output could spew forever and we want to stop by deadline.
137
+ # If an action responds_to?(:call), such as a lambda{|m| code}
138
+ # then the action is called with MatchData as an argument.
139
+ # In the case of :timeout or :eof, MatchData is from matching:
55
140
  #
56
- # If +timeout_seconds+ is nil, then no +:timeout+ condition will be generated.
141
+ # input_buffer =~ /.*/
57
142
  #
58
143
  # A action returning the value +:reset_timeout+ will +:continue+ and reset
59
144
  # the timeout deadline to a value of +Time.now+ + +timeout_seconds+
145
+ #
60
146
  def parley (timeout_seconds, *actions)
61
- @pvout.print "parley,#{__LINE__}: timeout_seconds=#{timeout_seconds}\n" if parley_verbose
62
- if (timeout_seconds == nil)
147
+ @pvout.puts "parley: timeout_seconds=#{timeout_seconds}" if parley_verbose
148
+ case timeout_seconds
149
+ when NilClass
63
150
  deadline = nil
64
- else
151
+ when Numeric
65
152
  deadline = Time.now + timeout_seconds
153
+ else
154
+ raise "Invalid timeout parameter: #{timeout_seconds.inspect}"
66
155
  end
67
156
  buf = ''
68
- unused_buf = '' if not unused_buf
157
+ unused_buf ||= ''
69
158
 
70
159
  # XXX Compatible hack. There are changes coming w.r.t. respond_to? for
71
160
  # protected methods. Just do a simple poll, and see if it works.
72
161
  begin
73
162
  result = IO.select([self], [], [], 0)
74
163
  has_select = true;
75
- rescue Exception
164
+ rescue Exception # NoMethodError and ArgumentError are common
76
165
  has_select = false;
77
166
  end
78
167
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "parley"
8
- s.version = "0.2.0"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ben Stoltz"]
12
- s.date = "2013-02-28"
12
+ s.date = "2013-03-14"
13
13
  s.description = "An expect-like gem, modeled after Perl's Expect.pm"
14
14
  s.email = "stoltz@lzrd.com"
15
15
  s.extra_rdoc_files = [
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  "README.md",
24
24
  "Rakefile",
25
25
  "VERSION",
26
+ "examples/parley_timed-read",
26
27
  "lib/parley.rb",
27
28
  "parley.gemspec",
28
29
  "test/helper.rb",
@@ -10,8 +10,9 @@ end
10
10
  require 'test/unit'
11
11
  # require 'shoulda'
12
12
 
13
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
14
+ #$LOAD_PATH.unshift(File.dirname(__FILE__))
15
+
15
16
  require 'parley'
16
17
 
17
18
  class Test::Unit::TestCase
@@ -29,12 +29,113 @@ class TestIO < Test::Unit::TestCase
29
29
  # no teardown required
30
30
  end
31
31
 
32
- def test_timeout
32
+ def test_timeout_positive
33
33
  read, write, pid = PTY.spawn('/bin/sleep 20')
34
34
  result = read.parley(5, [:timeout, :timeout])
35
35
  assert(result == :timeout, "** ERROR result = #{result}")
36
36
  end
37
37
 
38
+ # Negative timeout behaves like zero since that time is already passed.
39
+ def test_negative_timeout
40
+ sleep_seconds = 5
41
+ read, write, pid = PTY.spawn("/bin/sleep #{sleep_seconds}")
42
+ start_time = Time.now
43
+ result = read.parley(-1, [:timeout, :timeout])
44
+ delta_t = Time.now - start_time
45
+ assert(result == :timeout, "** ERROR result = #{result}")
46
+ assert(delta_t < sleep_seconds/2,
47
+ "Immediate timeout did not happen: delta_t = #{delta_t}")
48
+ end
49
+
50
+ # Zero timeout results in immediate :timeout if no data available
51
+ def test_zero_timeout
52
+ sleep_seconds = 10
53
+ read, write, pid = PTY.spawn("/bin/sleep #{sleep_seconds}")
54
+ start_time = Time.now
55
+ result = read.parley(0, [:timeout, :timeout], [:eof, :eof])
56
+ end_time = Time.now
57
+ delta_t = (end_time - start_time)
58
+ assert(result == :timeout, "** ERROR result = #{result}")
59
+ assert(delta_t < (sleep_seconds/2.0),
60
+ "Test ended too late: delta_t(#{delta_t}) >= #{sleep_seconds/2.0}")
61
+ end
62
+
63
+ =begin
64
+ # This syntax is not final or implemented yet
65
+ def test_multiple_spawned_commands
66
+ total = 0
67
+ count = 0
68
+
69
+ commands1 = []
70
+ (1..5).each do |i|
71
+ # push [read, write, pid] onto commands
72
+ commands1 << PTY.spawn("sleep 3; echo N=#{i}; sleep 2")
73
+ end
74
+ pattern_action_1 = [
75
+ /N=(\d+)/, # find this pattern in output of all commands
76
+ lambda do |m, r, w|
77
+ total += m[1].to_i
78
+ count += 1
79
+ :continue; # we don't want to terminate the expect call
80
+ end
81
+ ]
82
+
83
+ commands2 = []
84
+ (6..10).each do |i|
85
+ # push [read, write, pid] onto commands
86
+ commands2 << PTY.spawn("sleep 3; echo X=#{i}; sleep 2")
87
+ end
88
+ pattern_action_2 = [
89
+ /X=(\d+)/, # find this pattern in output of all commands
90
+ lambda do |m, r, w|
91
+ total += m[1].to_i
92
+ count += 1
93
+ :continue; # we don't want to terminate the expect call
94
+ end
95
+ ]
96
+
97
+ result = total / (count * 1.0)
98
+
99
+ sum = 0
100
+ (1..10).each do |i|
101
+ sum += i
102
+ end
103
+ avg = sum/10.0
104
+
105
+ parley_multiple(15,
106
+ [commands1, pattern_action_1],
107
+ [commands2, pattern_action_2])
108
+
109
+ assert(avg == result, "Error avg(#{avg}) != result(#{result}))")
110
+ end
111
+ =end
112
+
113
+ def test_nil_timeout
114
+ sleep_seconds = 10
115
+ read, write, pid = PTY.spawn("/bin/sleep #{sleep_seconds}")
116
+ start_time = Time.now
117
+ result = read.parley(nil, [:timeout, :timeout], [:eof, :eof])
118
+ delta_t = Time.now - start_time
119
+ assert(result == :eof, "** ERROR result = #{result}")
120
+ assert(delta_t >= sleep_seconds - 1,
121
+ "Test ended too quickly: delta_t = #{delta_t}")
122
+ end
123
+
124
+ =begin
125
+ # Alternate API, no timeout: parley([pattern, action], ...)
126
+ # timeout_seconds defaults to nil which means "no timeout"
127
+ def test_missing_timeout
128
+ sleep_seconds = 10
129
+ read, write, pid = PTY.spawn("/bin/sleep #{sleep_seconds}")
130
+ start_time = Time.now
131
+ result = read.parley([:timeout, :timeout], [:eof, :eof])
132
+ delta_t = Time.now - start_time
133
+ assert(result == :eof, "** ERROR result = #{result}")
134
+ assert(delta_t >= sleep_seconds - 1,
135
+ "Test ended too quickly: delta_t = #{delta_t}")
136
+ end
137
+ =end
138
+
38
139
  def test_single_match
39
140
  sin = StringIO.new(@text)
40
141
  result = sin.parley(0,
@@ -45,6 +146,7 @@ class TestIO < Test::Unit::TestCase
45
146
  assert(result == "just apple", "Invalid result(#{result})")
46
147
  end
47
148
 
149
+
48
150
  def test_eof_constant
49
151
  io = File.new("/dev/null", "r")
50
152
  result = io.parley(20, [:eof, :eof])
@@ -307,15 +409,15 @@ class TestIO < Test::Unit::TestCase
307
409
  [
308
410
  :timeout,
309
411
  lambda do |m|
310
- sin.puts ""
311
- @n_to_reset += 1
312
- puts "Resetting timeout #{@n_to_reset}"
313
- if @n_to_reset > 2
314
- sin.puts "exit"
315
- "Timeout"
316
- else
317
- :reset_timeout
318
- end
412
+ sin.puts ""
413
+ @n_to_reset += 1
414
+ puts "Resetting timeout #{@n_to_reset}"
415
+ if @n_to_reset > 2
416
+ sin.puts "exit"
417
+ "Timeout"
418
+ else
419
+ :reset_timeout
420
+ end
319
421
  end
320
422
  ])
321
423
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-28 00:00:00.000000000 Z
12
+ date: 2013-03-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rdoc
@@ -73,6 +73,7 @@ files:
73
73
  - README.md
74
74
  - Rakefile
75
75
  - VERSION
76
+ - examples/parley_timed-read
76
77
  - lib/parley.rb
77
78
  - parley.gemspec
78
79
  - test/helper.rb
@@ -92,7 +93,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
93
  version: '0'
93
94
  segments:
94
95
  - 0
95
- hash: -3112653461861631076
96
+ hash: -3261750928245830476
96
97
  required_rubygems_version: !ruby/object:Gem::Requirement
97
98
  none: false
98
99
  requirements: