waiter_ 0.0.1 → 1.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd0325695fdeaf22e3e8d68315874f9f4dbaeb83
4
- data.tar.gz: 16016830d0702876aa84c58755dfcb415b2384a7
3
+ metadata.gz: 6e268b47f92c2f681a1574ce1fe621c31a391fed
4
+ data.tar.gz: e5361387d097b61bd4a7cb16690c3e56c69579b5
5
5
  SHA512:
6
- metadata.gz: e44261b1a34d9e14053a2dc6b557f00d4fe75a9ac416073c7faf3494b59c1ac2353c975a9e9043e13e8b0bcc68b9959d927e58b161ae2d6fca37f973f9f74880
7
- data.tar.gz: 42c81f41bf86dcbb66d4f29f4a181f4fa5c01192b6dd8a6f45f229ff9abf3dcd4e1e8189b888df8280a03141e34b5e0161a9190c3bf6b0d8bc0a484d95106f70
6
+ metadata.gz: a3a8c53b6dc3e0173a4d839eed61ae4ff286c23fe9556a0a5e3737d087fcb14c58dc4c9b9604eff16e5da52159aac0b4147efcbe5bebd53b40a5ce6c021a814f
7
+ data.tar.gz: 01dde6fe0567b1af0abb61c6caaec4bfac818715ca7ddd69929b22bbb734b98a8c73736c4b333451f2ff259a4ae16b5f02ce6a0296945e28cb04f926f2ea13bd
data/README.md CHANGED
@@ -7,7 +7,7 @@ A simple wait/polling gem.
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'waiter', git: 'git@github.atl.pdrop.net:dmcneil/waiter.git'
10
+ gem 'waiter_'
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -19,29 +19,30 @@ And then execute:
19
19
  Just `include Waiter` and the following APIs will be available.
20
20
 
21
21
  ```ruby
22
- wait('foo').to eq 'foo' # Will pass.
23
- wait('foo').to eq 'bar' # Will throw exception.
24
- wait('foo').to_not eq 'bar' # Will pass.
25
- wait('foo').to_not eq 'foo' # Will fail.
22
+ wait.for('foo').to eq 'foo' # Will pass.
23
+ wait.for('foo').to eq 'bar' # Will throw exception.
24
+ wait.for('foo').to_not eq 'bar' # Will pass.
25
+ wait.for('foo').to_not eq 'foo' # Will fail.
26
26
  ```
27
27
 
28
28
  To adjust the timeout/polling, simple chain methods are supported.
29
29
 
30
- The *for* method accepts an Integer and adjusts the timeout. Use the *every* method with an Integer to adjust the polling time.
30
+ The *up_to* method accepts an Integer and adjusts the timeout.
31
+ Use the *every* method with an Integer to adjust the polling time.
31
32
 
32
33
  ```ruby
33
34
  # Wait for 30 seconds, polling every 2 second.
34
- wait('foo').every(2).for(30).to eq 'foo'
35
+ wait.every(2).up_to(30).for('foo').to eq 'foo'
35
36
  ```
36
37
 
37
38
  You do *not* have to use both methods, you can adjust one or the other. They can also be used in any order.
38
39
 
39
40
  ```ruby
40
41
  # Wait for 30 seconds, using the default 1 second poll.
41
- wait('foo').for(30).to eq 'foo'
42
+ wait.for('foo').up_to(30).to eq 'foo'
42
43
 
43
44
  # Wait for the default 15 seconds, polling every 5 seconds.
44
- wait('foo').every(5).to eq 'foo'
45
+ wait.for('foo').every(5).to eq 'foo'
45
46
  ```
46
47
 
47
48
  You can also pass a block to be evaluated, using *until*, until it is true.
@@ -49,8 +50,7 @@ You can also pass a block to be evaluated, using *until*, until it is true.
49
50
  ```ruby
50
51
  wait.until { true == true }
51
52
 
52
- wait.every(5).for(30).until {
53
+ wait.every(5).up_to(30).until {
53
54
  true == true
54
55
  }
55
56
  ```
56
-
@@ -0,0 +1,4 @@
1
+ module Waiter
2
+ class TimeoutError < StandardError
3
+ end
4
+ end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Waiter
2
- VERSION = '0.0.1'
2
+ VERSION = '1.0.2'
3
3
  end
data/lib/waiter.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'rspec/expectations'
2
2
 
3
+ require_relative 'timeout_error'
4
+
3
5
  module Waiter
4
6
  # Wrapper for RSpec expectations that allows waiting/polling.
5
7
  #
@@ -7,20 +9,20 @@ module Waiter
7
9
  #
8
10
  # @example
9
11
  #
10
- # wait('foo').to eq 'foo' # Will pass.
11
- # wait('foo').to eq 'bar' # Will throw exception.
12
- # wait('foo').to_not eq 'bar' # Will pass.
13
- # wait('foo').to_not eq 'foo' # Will fail.
12
+ # wait.for('foo').to eq 'foo' # Will pass.
13
+ # wait.for('foo').to eq 'bar' # Will throw exception.
14
+ # wait.for('foo').to_not eq 'bar' # Will pass.
15
+ # wait.for('foo').to_not eq 'foo' # Will fail.
14
16
  #
15
17
  # To adjust the timeout/polling, simple chain methods are supported.
16
18
  #
17
- # The *for* method accepts an Integer and adjusts the timeout.
19
+ # The *up_to* method accepts an Integer and adjusts the timeout.
18
20
  # Use the *every* method with an Integer to adjust the polling time.
19
21
  #
20
22
  # @example
21
23
  #
22
24
  # # Wait for 30 seconds, polling every 2 second.
23
- # wait('foo').every(2).for(30).to eq 'foo'
25
+ # wait.every(2).up_to(30).for('foo').to eq 'foo'
24
26
  #
25
27
  # You do *not* have to use both methods, you can adjust one or the other.
26
28
  # They can also be used in any order.
@@ -28,10 +30,10 @@ module Waiter
28
30
  # @example
29
31
  #
30
32
  # # Wait for 30 seconds, using the default 1 second poll.
31
- # wait('foo').for(30).to eq 'foo'
33
+ # wait.for('foo').up_to(30).to eq 'foo'
32
34
  #
33
35
  # # Wait for the default 15 seconds, polling every 5 seconds.
34
- # wait('foo').every(5).to eq 'foo'
36
+ # wait.for('foo').every(5).to eq 'foo'
35
37
  #
36
38
  # You can also pass a block to be evaluated, using *until*, until it is true.
37
39
  #
@@ -39,40 +41,72 @@ module Waiter
39
41
  #
40
42
  # wait.until { true == true }
41
43
  #
42
- # wait.every(5).for(30).until {
44
+ # wait.every(5).up_to(30).until {
43
45
  # true == true
44
46
  # }
45
47
  #
46
48
  # @author Derek McNeil <dmcneil@pindrop.com>
47
- def wait(value=true, &block)
48
- WaitExpectationTarget.for(value, block)
49
+ def wait(opts = {}, &block)
50
+ ChainableWait.new(opts)
49
51
  end
50
52
 
51
- alias_method :wait_for, :wait
52
-
53
- class WaitExpectationTarget < RSpec::Expectations::ExpectationTarget
53
+ class ChainableWait
54
54
  attr_reader :target
55
55
  attr_accessor :timeout, :polling, :message
56
56
 
57
57
  DEFAULT_TIMEOUT = 15
58
58
  DEFAULT_POLLING = 1
59
59
 
60
- def initialize(value)
61
- @target = value
62
- @timeout = DEFAULT_TIMEOUT
63
- @polling = DEFAULT_POLLING
60
+ def initialize(opts = {})
61
+ @timeout = opts[:timeout] || DEFAULT_TIMEOUT
62
+ @polling = opts[:polling] || DEFAULT_POLLING
63
+ @failure_message = opts[:failure_message] || build_error
64
+ end
65
+
66
+ def for(value = nil, &block)
67
+ if value
68
+ @target = value
69
+ elsif block_given?
70
+ @target = block
71
+ end
72
+
73
+ self
74
+ end
75
+
76
+ def up_to(seconds)
77
+ @timeout = seconds
78
+ self
79
+ end
80
+
81
+ def every(seconds)
82
+ @polling = seconds
83
+ self
84
+ end
85
+ alias_method :polling_every, :every
86
+
87
+ def to(matcher = nil, &block)
88
+ WaitExpectationTarget.new(@target).to(self, matcher, &block)
64
89
  end
65
90
 
66
- def wait(message=nil, &block)
91
+ def not_to(matcher = nil, &block)
92
+ WaitExpectationTarget.new(@target).not_to(self, matcher, &block)
93
+ end
94
+ alias_method :to_not, :not_to
95
+
96
+ def until(&block)
67
97
  unless @timeout > @polling
68
98
  raise ArgumentError, 'Timeout must be a higher value than polling.'
69
99
  end
70
100
 
71
- @message = message || default_failure_message
101
+ current_timeout = @timeout
102
+
103
+ while current_timeout > 0 && current_timeout > @polling
104
+ trap('SIGINT') { break }
72
105
 
73
- while @timeout > 0 && @timeout > @polling
74
106
  @result = begin
75
107
  block.call
108
+ rescue SystemExit, Interrupt
109
+ break
76
110
  rescue Exception => error
77
111
  @error = error
78
112
  false
@@ -80,52 +114,64 @@ module Waiter
80
114
 
81
115
  break if @result
82
116
  sleep @polling
83
- @timeout = @timeout - @polling
117
+ current_timeout = current_timeout - @polling
84
118
  end
85
119
 
86
120
  unless @result
87
121
  if @error
88
- @error.message.prepend @message
122
+ @error = Waiter::TimeoutError.new(build_error(@error))
89
123
  else
90
- @error = RuntimeError.new @message
124
+ @error = Waiter::TimeoutError.new(build_error)
91
125
  end
92
126
 
93
127
  raise @error
94
128
  end
95
129
  end
96
130
 
97
- alias_method :until, :wait
98
-
99
- def every(seconds)
100
- @polling = seconds
101
- self
102
- end
131
+ private
103
132
 
104
- def for(seconds)
105
- @timeout = seconds
106
- self
133
+ def build_error(error = nil)
134
+ [
135
+ "Timed out after waiting for #{@timeout}s.",
136
+ "Polled for #{@polling}s.",
137
+ error
138
+ ].join("\n")
107
139
  end
140
+ end
108
141
 
109
- def to(matcher=nil, message=nil, &block)
142
+ class WaitExpectationTarget < RSpec::Expectations::ExpectationTarget
143
+ def to(waiter, matcher = nil, &block)
110
144
  prevent_operator_matchers(:to) unless matcher
111
- wait(message) do
112
- RSpec::Expectations::PositiveExpectationHandler.handle_matcher(target, matcher, message, &block)
145
+ waiter.until do
146
+ target = handle_target(waiter.target)
147
+ RSpec::Expectations::PositiveExpectationHandler.handle_matcher(target,
148
+ matcher,
149
+ &block)
150
+
151
+ return target
113
152
  end
114
- @target
115
153
  end
116
154
 
117
- def not_to(matcher=nil, message=nil, &block)
155
+ def not_to(waiter, matcher = nil, &block)
118
156
  prevent_operator_matchers(:not_to) unless matcher
119
- wait(message) do
120
- RSpec::Expectations::NegativeExpectationHandler.handle_matcher(target, matcher, message, &block)
157
+ waiter.until do
158
+ target = handle_target(waiter.target)
159
+ RSpec::Expectations::NegativeExpectationHandler.handle_matcher(target,
160
+ matcher,
161
+ &block)
162
+
163
+ return target
121
164
  end
122
- @target
123
165
  end
124
166
 
125
- alias_method :to_not, :not_to
167
+ private
126
168
 
127
- def default_failure_message
128
- "Timed out after waiting for #{@timeout} seconds, polling every #{@polling} second.\n"
169
+ def handle_target(target)
170
+ if target.respond_to?(:call)
171
+ target.call
172
+ else
173
+ target
174
+ end
129
175
  end
130
176
  end
131
177
  end
data/waiter.gemspec CHANGED
@@ -15,6 +15,8 @@ Gem::Specification.new do |spec|
15
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
16
  spec.require_paths = ['lib']
17
17
 
18
+ spec.add_dependency 'rspec-expectations', '~> 3.5.0'
19
+
18
20
  spec.add_development_dependency 'bundler', '~> 1.12'
19
21
  spec.add_development_dependency 'rake', '~> 10.0'
20
22
  spec.add_development_dependency 'rspec', '~> 3.0'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waiter_
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek McNeil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-14 00:00:00.000000000 Z
11
+ date: 2017-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec-expectations
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.5.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.5.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -64,6 +78,7 @@ files:
64
78
  - Gemfile
65
79
  - README.md
66
80
  - Rakefile
81
+ - lib/timeout_error.rb
67
82
  - lib/version.rb
68
83
  - lib/waiter.rb
69
84
  - waiter.gemspec
@@ -86,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
101
  version: '0'
87
102
  requirements: []
88
103
  rubyforge_project:
89
- rubygems_version: 2.4.5.1
104
+ rubygems_version: 2.5.1
90
105
  signing_key:
91
106
  specification_version: 4
92
107
  summary: A simple polling gem.