rspec-wait 0.0.10 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51f26caeca0b3d18669805db3143077ac97f408e129fbd36c2bc8d5dac9bb709
4
- data.tar.gz: b7a60846e5c5459e75acb628f10e8daaf2a1276fbb15956d32a90dc64f9b5474
3
+ metadata.gz: d1e5feca07bca8e8ce594d6d548a4b4cd898e2366ce601c28ec6ddd152a47a01
4
+ data.tar.gz: eeab28ab6433f33f3c33eb83f2b1b086a403ae988950af63a4d963b595c76b63
5
5
  SHA512:
6
- metadata.gz: a8ff555f454d246bb4412ba9197e3bd3ddde4609cfe82d1fc0bff50578f9fe86e756b23fd208fa914da4dba49e7cb72cf307d9be334317a88b1833eb3313ab84
7
- data.tar.gz: 8ad28a71663a471032f65912731c3081bc96c84007385354312931595d126db14c9da0bf2139a63d8ec3f3eb707b495efb57932d681db949c0ac4eaa942e7c87
6
+ metadata.gz: f23e94176e14b0d5e03794e79f25cfc721a83cfd1f097c4902dea2a90974184fa9beefe4c4c2c1c7528c9a0a19bb38872421982c1bb98cfb9505d6ddf34c0373
7
+ data.tar.gz: 51cbbf77176c670bae9d7446cdfb2e90813f11ca4bd7de31608228197d7ba4bc2e0d6398a987da0f4342cbcd6791e9d7e09ef4f81e2ac2a338dd45957c715e89
data/LICENSE.txt CHANGED
@@ -1,22 +1,21 @@
1
- Copyright (c) 2014 Steve Richert
1
+ The MIT License (MIT)
2
2
 
3
- MIT License
3
+ Copyright (c) 2014 Steve Richert
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
12
11
 
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
15
14
 
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -2,11 +2,9 @@
2
2
 
3
3
  Wait for conditions in RSpec
4
4
 
5
- [![Gem Version](https://img.shields.io/gem/v/rspec-wait.svg?style=flat-square)](https://rubygems.org/gems/rspec-wait)
6
- [![Build Status](https://img.shields.io/travis/laserlemon/rspec-wait/master.svg?style=flat-square)](https://travis-ci.org/laserlemon/rspec-wait)
7
- [![Code Climate](https://img.shields.io/codeclimate/github/laserlemon/rspec-wait.svg?style=flat-square)](https://codeclimate.com/github/laserlemon/rspec-wait)
8
- [![Coverage Status](https://img.shields.io/codeclimate/coverage/github/laserlemon/rspec-wait.svg?style=flat-square)](https://codeclimate.com/github/laserlemon/rspec-wait)
9
- [![Dependency Status](https://img.shields.io/gemnasium/laserlemon/rspec-wait.svg?style=flat-square)](https://gemnasium.com/laserlemon/rspec-wait)
5
+ [![Gem Version](https://img.shields.io/gem/v/rspec-wait)](http://rubygems.org/gems/rspec-wait)
6
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/laserlemon/rspec-wait/rake.yml)](https://github.com/laserlemon/rspec-wait/actions/workflows/rake.yml)
7
+ [![License](https://img.shields.io/github/license/laserlemon/rspec-wait)](https://github.com/laserlemon/rspec-wait/blob/-/LICENSE.txt)
10
8
 
11
9
  ## Why does RSpec::Wait exist?
12
10
 
@@ -24,16 +22,15 @@ syntactic sugar that you already know and love.
24
22
 
25
23
  RSpec::Wait will keep trying until your assertion passes or times out.
26
24
 
27
- ### Example
25
+ ### Examples
28
26
 
29
27
  RSpec::Wait's `wait_for` assertions are nearly drop-in replacements for RSpec's
30
- `expect` assertions. The major difference is that the `wait_for` method only
31
- works with non-block matchers. However, `wait_for` will still accept a block
32
- because it may need to evaluate the content of that block multiple times while
33
- waiting.
28
+ `expect` assertions. The major difference is that the `wait_for` method
29
+ requires a block because it may need to evaluate the content of that block
30
+ multiple times while it's waiting.
34
31
 
35
32
  ```ruby
36
- describe Ticker do
33
+ RSpec.describe Ticker do
37
34
  subject(:ticker) { Ticker.new("foo") }
38
35
 
39
36
  describe "#start" do
@@ -41,21 +38,21 @@ describe Ticker do
41
38
  ticker.start
42
39
  end
43
40
 
44
- it "starts a blank tape" do
41
+ it "starts with a blank tape" do
45
42
  expect(ticker.tape).to eq("")
46
43
  end
47
44
 
48
- it "writes the message one letter at a time" do
49
- wait_for(ticker.tape).to eq("··-·")
50
- wait_for(ticker.tape).to eq("··-· ---")
51
- wait_for(ticker.tape).to eq("··-· --- ---")
45
+ it "sends the message in Morse code one letter at a time" do
46
+ wait_for { ticker.tape }.to eq("··-·")
47
+ wait_for { ticker.tape }.to eq("··-· ---")
48
+ wait_for { ticker.tape }.to eq("··-· --- ---")
52
49
  end
53
50
  end
54
51
  end
55
52
  ```
56
53
 
57
- This can be especially useful for testing user interfaces with tricky timing
58
- elements like JavaScript interactions or remote requests.
54
+ RSpec::Wait can be especially useful for testing user interfaces with tricky
55
+ timing elements like JavaScript interactions or remote requests.
59
56
 
60
57
  ```ruby
61
58
  feature "User Login" do
@@ -74,31 +71,117 @@ feature "User Login" do
74
71
  end
75
72
  ```
76
73
 
74
+ ## Compatibility
75
+
76
+ ### Ruby Support
77
+
78
+ RSpec::Wait is tested against all [non-EOL Ruby versions](https://www.ruby-lang.org/en/downloads/branches/),
79
+ which as of this writing are versions 3.1, 3.2, and 3.3. If you find that
80
+ RSpec::Wait does not work or [is not tested](https://github.com/laserlemon/rspec-wait/blob/-/.github/workflows/rake.yml)
81
+ for a maintained Ruby version, please [open an issue](https://github.com/laserlemon/rspec-wait/issues/new)
82
+ or pull request to add support.
83
+
84
+ Additionally, RSpec::Wait is tested against Ruby head to surface future
85
+ compatibility issues, but no guarantees are made that RSpec::Wait will
86
+ function as expected on Ruby head. Proceed with caution!
87
+
88
+ ### RSpec Support
89
+
90
+ RSpec::Wait is tested against several [versions of RSpec](https://rubygems.org/gems/rspec/versions),
91
+ which as of this writing are versions 3.4 through 3.13. If you find that
92
+ RSpec::Wait does not work or [is not tested](https://github.com/laserlemon/rspec-wait/blob/-/.github/workflows/rake.yml)
93
+ for a newer RSpec version, please [open an issue](https://github.com/laserlemon/rspec-wait/issues/new)
94
+ or pull request to add support.
95
+
96
+ Additionally, RSpec::Wait is tested against unbounded RSpec to surface future
97
+ compatibility issues, but no guarantees are made that RSpec::Wait will
98
+ function as expected on any RSpec version that's not explicitly [tested](https://github.com/laserlemon/rspec-wait/blob/-/.github/workflows/rake.yml).
99
+ Proceed with caution!
100
+
77
101
  ### Matchers
78
102
 
79
103
  RSpec::Wait ties into RSpec's internals so it can take full advantage of any
80
- non-block matcher that you would use with RSpec's own `expect` method.
104
+ matcher that you would use with RSpec's own `expect` method.
81
105
 
82
- ### Timeout
106
+ If you discover a matcher that works with `expect` but not with `wait_for`,
107
+ please [open an issue](https://github.com/laserlemon/rspec-wait/issues/new)
108
+ and I'd be happy to take a look!
83
109
 
84
- By default, RSpec::Wait will wait up to 10 seconds for an assertion to pass.
85
- That timeout value is configurable in three ways:
110
+ ## Installation
86
111
 
87
- #### RSpec Configuration
112
+ To get started with RSpec::Wait, simply add the dependency to your `Gemfile`
113
+ and `bundle install`:
114
+
115
+ ```ruby
116
+ gem "rspec-wait", "~> 1.0"
117
+ ```
118
+
119
+ If your codebase calls `Bundler.require` at boot time, you're all set and the
120
+ `wait_for` method is already available in your RSpec suite.
121
+
122
+ If you encounter the following error:
123
+
124
+ ```
125
+ NoMethodError:
126
+ undefined method `wait_for'
127
+ ```
128
+
129
+ You will need to explicitly require RSpec::Wait at boot time in your test
130
+ environment:
131
+
132
+ ```ruby
133
+ require "rspec/wait"
134
+ ```
135
+
136
+ ### Upgrading from v0
137
+
138
+ RSpec::Wait v1 is very similar in syntax to v0 but does have a few breaking
139
+ changes that you should be aware of when upgrading from any 0.x version:
140
+
141
+ 1. RSpec::Wait v1 requires Ruby 3.0 or greater and RSpec 3.4 or greater.
142
+ 2. The `wait_for` and `wait.for` methods no longer accept arguments, only
143
+ blocks.
144
+ 3. RSpec::Wait no longer uses Ruby's problematic `Timeout.timeout` method,
145
+ which means it will no longer raise a `RSpec::Wait::TimeoutError`.
146
+ RSpec::Wait v1 never interrupts the block given to `wait_for` mid-call
147
+ so make every effort to reasonably limit the block's individual call time.
148
+
149
+ ## Configuration
150
+
151
+ RSpec::Wait has three available configuration values:
152
+
153
+ - `wait_timeout` - The maximum amount of time (in seconds) that RSpec::Wait
154
+ will continue to retry a failing assertion. Default: `10.0`
155
+ - `wait_delay` - How long (in seconds) RSpec::Wait will pause between retries.
156
+ Default: `0.1`
157
+ - `clone_wait_matcher` - Whether each retry will `clone` the given RSpec
158
+ matcher instance for each evaluation. Set to `true` if you have trouble with
159
+ a matcher holding onto stale state. Default: `false`
160
+
161
+ RSpec::Wait configurations can be set in three ways:
162
+
163
+ - Globally via `RSpec.configure`
164
+ - Per example or context via RSpec metadata
165
+ - Per assertion via the `wait` method
166
+
167
+ ### Global Configuration
88
168
 
89
169
  ```ruby
90
170
  RSpec.configure do |config|
91
171
  config.wait_timeout = 3 # seconds
172
+ config.wait_delay = 0.5 # seconds
173
+ config.clone_wait_matcher = true
92
174
  end
93
175
  ```
94
176
 
95
- #### RSpec Metadata
177
+ ### RSpec Metadata
96
178
 
97
- The timeout can also be specified via options added to a spec's or context's
98
- `:wait` metadata:
179
+ Any of RSpec::Wait's three configurations can be set on a per-example or
180
+ per-context basis using `wait` metadata. Provide a hash containing any
181
+ number of shorthand keys and values for RSpec::Wait's configurations.
99
182
 
100
183
  ```ruby
101
- scenario "A user can log in successfully", wait: { timeout: 3 } do
184
+ scenario "A user can log in successfully", wait: { timeout: 3, delay: 0.5, clone_wait_matcher: true } do
102
185
  visit new_session_path
103
186
 
104
187
  fill_in "Email", with: "john@example.com"
@@ -110,9 +193,12 @@ scenario "A user can log in successfully", wait: { timeout: 3 } do
110
193
  end
111
194
  ```
112
195
 
113
- #### The `wait` Method
196
+ ### The `wait` Method
114
197
 
115
- On a per-assertion basis, the timeout value can be passed to the `wait` method.
198
+ And on a per-assertion basis, the `wait` method accepts a hash of shorthand
199
+ keys and values for RSpec::Wait's configurations. The `wait` method must be
200
+ chained to the `for` method and aside from the ability to set RSpec::Wait
201
+ configuration for the single assertion, it behaves identically to `wait_for`.
116
202
 
117
203
  ```ruby
118
204
  scenario "A user can log in successfully" do
@@ -122,12 +208,47 @@ scenario "A user can log in successfully" do
122
208
  fill_in "Password", with: "secret"
123
209
  click_button "Log In"
124
210
 
125
- wait(3.seconds).for { current_path }.to eq(account_path)
211
+ wait(timeout: 3).for { current_path }.to eq(account_path)
126
212
  expect(page).to have_content("Welcome back!")
127
213
  end
128
214
  ```
129
215
 
130
- ### Use with Cucumber
216
+ The `wait` method will also accept `timeout` as a positional argument for
217
+ improved readability:
218
+
219
+ ```ruby
220
+ wait(3.seconds).for { current_path }.to eq(account_path)
221
+ ```
222
+
223
+ ## Use with RuboCop
224
+
225
+ If you use `rubocop` and `rubocop-rspec` in your codebase, an RSpec example
226
+ with a single `wait_for` assertion may cause RuboCop to complain:
227
+
228
+ ```
229
+ RSpec/NoExpectationExample: No expectation found in this example.
230
+ ```
231
+
232
+ By default, RuboCop sees only `expect*` and `assert*` methods as expectations.
233
+ You can configure RuboCop to recognize `wait_for` and `wait.for` as
234
+ expectations (in addition to the defaults) in your RuboCop configuration:
235
+
236
+ ```yaml
237
+ RSpec/NoExpectationExample:
238
+ AllowedPatterns:
239
+ - ^assert_
240
+ - ^expect_
241
+ - ^wait(_for)?$
242
+ ```
243
+
244
+ Of course, you can always disable this cop entirely:
245
+
246
+ ```yaml
247
+ RSpec/NoExpectationExample:
248
+ Enabled: false
249
+ ```
250
+
251
+ ## Use with Cucumber
131
252
 
132
253
  To enable RSpec::Wait in your Cucumber step definitions, add the following to
133
254
  `features/support/env.rb`:
@@ -147,7 +268,7 @@ and [contribution](https://github.com/laserlemon/rspec-wait/graphs/contributors)
147
268
  from the Ruby community, especially the [authors and maintainers](https://github.com/rspec/rspec-core/graphs/contributors)
148
269
  of RSpec.
149
270
 
150
- **Thank you!**
271
+ **Thank you!** :yellow_heart:
151
272
 
152
273
  ## How can I help?
153
274
 
@@ -156,3 +277,6 @@ No contribution is too small.
156
277
 
157
278
  See RSpec::Wait's [contribution guidelines](CONTRIBUTING.md) for more
158
279
  information.
280
+
281
+ If you're enjoying RSpec::Wait, please consider [sponsoring](https://github.com/sponsors/laserlemon)
282
+ my [open source work](https://github.com/laserlemon)! :green_heart:
@@ -1,31 +1,42 @@
1
- require "timeout"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module RSpec
4
4
  module Wait
5
+ # The RSpec::Wait::Handler module is common functionality shared between
6
+ # the RSpec::Wait::PositiveHandler and RSpec::Wait::NegativeHandler classes
7
+ # defined below. The module overrides RSpec's handle_matcher method,
8
+ # allowing a block target to be repeatedly evaluated until the underlying
9
+ # matcher passes or the configured timeout elapses.
5
10
  module Handler
6
- def handle_matcher(target, *args, &block)
7
- failure = nil
11
+ def handle_matcher(target, initial_matcher, message, &block)
12
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
8
13
 
9
- Timeout.timeout(RSpec.configuration.wait_timeout) do
10
- begin
11
- actual = target.respond_to?(:call) ? target.call : target
12
- super(actual, *args, &block)
13
- rescue RSpec::Expectations::ExpectationNotMetError => failure
14
- sleep RSpec.configuration.wait_delay
15
- retry
14
+ begin
15
+ matcher = RSpec.configuration.clone_wait_matcher ? initial_matcher.clone : initial_matcher
16
+
17
+ if matcher.supports_block_expectations?
18
+ super(target, matcher, message, &block)
19
+ else
20
+ super(target.call, matcher, message, &block)
16
21
  end
22
+ rescue RSpec::Expectations::ExpectationNotMetError
23
+ raise if RSpec.world.wants_to_quit
24
+
25
+ elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
26
+ raise if elapsed_time > RSpec.configuration.wait_timeout
27
+
28
+ sleep RSpec.configuration.wait_delay
29
+ retry
17
30
  end
18
- rescue Timeout::Error
19
- raise failure || TimeoutError
20
31
  end
21
32
  end
22
33
 
23
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/handler.rb#L44-L63
34
+ # From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/handler.rb#L46-L65
24
35
  class PositiveHandler < RSpec::Expectations::PositiveExpectationHandler
25
36
  extend Handler
26
37
  end
27
38
 
28
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/handler.rb#L66-L93
39
+ # From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/handler.rb#L68-L95
29
40
  class NegativeHandler < RSpec::Expectations::NegativeExpectationHandler
30
41
  extend Handler
31
42
  end
@@ -1,12 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RSpec
2
4
  module Wait
5
+ # The RSpec::Wait::Proxy class is capable of creating a small container
6
+ # object for RSpec::Wait options, returned by the top-level wait method,
7
+ # which allows chaining wait and for methods for more expectations that
8
+ # read more naturally, like:
9
+ #
10
+ # wait(3.seconds).for { this }.to eq(that)
11
+ #
3
12
  class Proxy
4
- def initialize(options)
13
+ def initialize(**options)
5
14
  @options = options
6
15
  end
7
16
 
8
- def for(value = Target::UndefinedValue, &block)
9
- Target.for(value, block, @options)
17
+ def for(*args, &block)
18
+ raise ArgumentError, "The `wait.for` method only accepts a block." if args.any?
19
+ raise ArgumentError, "The `wait.for` method requires a block." unless block
20
+
21
+ Target.new(block, @options)
10
22
  end
11
23
  end
12
24
  end
@@ -1,41 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RSpec
2
4
  module Wait
5
+ # The RSpec::Wait::Target class inherits from RSpec's internal
6
+ # RSpec::Expectations::ExpectationTarget class and allows the inclusion of
7
+ # RSpec::Wait options via RSpec::Wait::Proxy.
3
8
  class Target < RSpec::Expectations::ExpectationTarget
4
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/expectation_target.rb#L22
5
- UndefinedValue = Module.new
6
-
7
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/expectation_target.rb#L30-L41
8
- def self.for(value, block, options = {})
9
- if UndefinedValue.equal?(value)
10
- raise ArgumentError, "You must pass either an argument or a block to `wait_for`." unless block
11
-
12
- new(block, options)
13
- elsif block
14
- raise ArgumentError, "You cannot pass both an argument and a block to `wait_for`."
15
- else
16
- warn "[DEPRECATION] As of rspec-wait version 1.0, " \
17
- "neither wait_for nor wait.for will accept an argument, only a block."
18
- new(value, options)
19
- end
20
- end
21
-
22
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/expectation_target.rb#L25-L27
23
- def initialize(target, options)
9
+ # From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/expectation_target.rb#L25-L27
10
+ def initialize(block, options = {})
24
11
  @wait_options = options
25
- super(target)
12
+ super(block)
26
13
  end
27
14
 
28
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/expectation_target.rb#L53-L54
15
+ # From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/expectation_target.rb#L52-L55
29
16
  def to(matcher = nil, message = nil, &block)
30
17
  prevent_operator_matchers(:to) unless matcher
18
+
31
19
  with_wait do
32
20
  PositiveHandler.handle_matcher(@target, matcher, message, &block)
33
21
  end
34
22
  end
35
23
 
36
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/expectation_target.rb#L66-L67
24
+ # From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/expectation_target.rb#L65-L68
37
25
  def not_to(matcher = nil, message = nil, &block)
38
26
  prevent_operator_matchers(:not_to) unless matcher
27
+
39
28
  with_wait do
40
29
  NegativeHandler.handle_matcher(@target, matcher, message, &block)
41
30
  end
@@ -46,7 +35,7 @@ module RSpec
46
35
  private
47
36
 
48
37
  def with_wait(&block)
49
- Wait.with_wait(@wait_options, &block)
38
+ Wait.with_wait(**@wait_options, &block)
50
39
  end
51
40
  end
52
41
  end
@@ -1,9 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RSpec
2
4
  module Wait
3
- VERSION = ::Gem::Version.new("0.0.10")
4
-
5
- def self.version
6
- VERSION
7
- end
5
+ VERSION = ::Gem::Version.new("1.0.0")
8
6
  end
9
7
  end
data/lib/rspec/wait.rb CHANGED
@@ -1,35 +1,48 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rspec"
2
- require "rspec/wait/error"
3
- require "rspec/wait/handler"
4
- require "rspec/wait/proxy"
5
- require "rspec/wait/target"
6
- require "rspec/wait/version"
4
+
5
+ require_relative "wait/handler"
6
+ require_relative "wait/proxy"
7
+ require_relative "wait/target"
8
+ require_relative "wait/version"
7
9
 
8
10
  module RSpec
11
+ # The RSpec::Wait module is included into RSpec's example environment, making
12
+ # the wait_for, wait, and with_wait methods available inside each spec.
9
13
  module Wait
14
+ DEFAULT_TIMEOUT = 10.0
15
+ DEFAULT_DELAY = 0.1
16
+ DEFAULT_CLONE_MATCHER = false
17
+
10
18
  module_function
11
19
 
12
- # From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/syntax.rb#L72-L74
13
- def wait_for(value = Target::UndefinedValue, &block)
14
- Target.for(value, block)
20
+ # From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/syntax.rb#L72-L74
21
+ def wait_for(*args, &block)
22
+ raise ArgumentError, "The `wait_for` method only accepts a block." if args.any?
23
+ raise ArgumentError, "The `wait_for` method requires a block." unless block
24
+
25
+ Target.new(block)
15
26
  end
16
27
 
17
- def wait(timeout = nil, options = {})
18
- options[:timeout] = timeout
19
- Proxy.new(options)
28
+ def wait(arg = nil, timeout: arg, delay: nil, clone_matcher: nil)
29
+ Proxy.new(timeout: timeout, delay: delay, clone_matcher: clone_matcher)
20
30
  end
21
31
 
22
- def with_wait(options)
32
+ def with_wait(timeout: nil, delay: nil, clone_matcher: nil)
23
33
  original_timeout = RSpec.configuration.wait_timeout
24
34
  original_delay = RSpec.configuration.wait_delay
35
+ original_clone_matcher = RSpec.configuration.clone_wait_matcher
25
36
 
26
- RSpec.configuration.wait_timeout = options[:timeout] if options[:timeout]
27
- RSpec.configuration.wait_delay = options[:delay] if options[:delay]
37
+ RSpec.configuration.wait_timeout = timeout unless timeout.nil?
38
+ RSpec.configuration.wait_delay = delay unless delay.nil?
39
+ RSpec.configuration.clone_wait_matcher = clone_matcher unless clone_matcher.nil?
28
40
 
29
41
  yield
30
42
  ensure
31
43
  RSpec.configuration.wait_timeout = original_timeout
32
44
  RSpec.configuration.wait_delay = original_delay
45
+ RSpec.configuration.clone_wait_matcher = original_clone_matcher
33
46
  end
34
47
  end
35
48
  end
@@ -37,14 +50,12 @@ end
37
50
  RSpec.configure do |config|
38
51
  config.include(RSpec::Wait)
39
52
 
40
- config.add_setting(:wait_timeout, default: 10)
41
- config.add_setting(:wait_delay, default: 0.1)
53
+ config.add_setting(:wait_timeout, default: RSpec::Wait::DEFAULT_TIMEOUT)
54
+ config.add_setting(:wait_delay, default: RSpec::Wait::DEFAULT_DELAY)
55
+ config.add_setting(:clone_wait_matcher, default: RSpec::Wait::DEFAULT_CLONE_MATCHER)
42
56
 
43
- config.around do |example|
44
- if (options = example.metadata[:wait])
45
- with_wait(options) { example.run }
46
- else
47
- example.run
48
- end
57
+ config.around(wait: {}) do |example|
58
+ options = example.metadata.fetch(:wait)
59
+ with_wait(**options) { example.run }
49
60
  end
50
61
  end
data/lib/rspec-wait.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rspec/wait"
data/rspec-wait.gemspec CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
22
22
  "source_code_uri" => "https://github.com/laserlemon/rspec-wait",
23
23
  }
24
24
 
25
- spec.required_ruby_version = ">= 2.2"
26
- spec.add_dependency "rspec", ">= 3.0"
27
- spec.add_development_dependency "bundler"
28
- spec.add_development_dependency "rake"
25
+ spec.required_ruby_version = ">= 3.0"
26
+ spec.add_dependency "rspec", ">= 3.4"
27
+ spec.add_development_dependency "bundler", ">= 2.0"
28
+ spec.add_development_dependency "rake", ">= 13.0"
29
29
 
30
30
  spec.files = Dir.glob([
31
31
  "rspec-wait.gemspec",
@@ -34,9 +34,4 @@ Gem::Specification.new do |spec|
34
34
  ])
35
35
 
36
36
  spec.extra_rdoc_files = ["README.md"]
37
-
38
- spec.post_install_message = <<-MSG
39
- [rspec-wait] RSpec::Wait 1.0 has arrived! Please upgrade for the latest and greatest.
40
- [rspec-wait] See what's changed here: https://github.com/laserlemon/rspec-wait/blob/-/CHANGELOG.md
41
- MSG
42
37
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-wait
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Richert
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-04-26 00:00:00.000000000 Z
10
+ date: 2024-05-31 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rspec
@@ -16,42 +15,42 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '3.0'
18
+ version: '3.4'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '3.0'
25
+ version: '3.4'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: bundler
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: '0'
32
+ version: '2.0'
34
33
  type: :development
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: '0'
39
+ version: '2.0'
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: rake
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - ">="
46
45
  - !ruby/object:Gem::Version
47
- version: '0'
46
+ version: '13.0'
48
47
  type: :development
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
- version: '0'
53
+ version: '13.0'
55
54
  description: RSpec::Wait enables time-resilient expectations in your RSpec test suite.
56
55
  email: steve.richert@hey.com
57
56
  executables: []
@@ -61,8 +60,8 @@ extra_rdoc_files:
61
60
  files:
62
61
  - LICENSE.txt
63
62
  - README.md
63
+ - lib/rspec-wait.rb
64
64
  - lib/rspec/wait.rb
65
- - lib/rspec/wait/error.rb
66
65
  - lib/rspec/wait/handler.rb
67
66
  - lib/rspec/wait/proxy.rb
68
67
  - lib/rspec/wait/target.rb
@@ -78,9 +77,6 @@ metadata:
78
77
  homepage_uri: https://github.com/laserlemon/rspec-wait
79
78
  rubygems_mfa_required: 'true'
80
79
  source_code_uri: https://github.com/laserlemon/rspec-wait
81
- post_install_message: |
82
- [rspec-wait] RSpec::Wait 1.0 has arrived! Please upgrade for the latest and greatest.
83
- [rspec-wait] See what's changed here: https://github.com/laserlemon/rspec-wait/blob/-/CHANGELOG.md
84
80
  rdoc_options: []
85
81
  require_paths:
86
82
  - lib
@@ -88,15 +84,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
84
  requirements:
89
85
  - - ">="
90
86
  - !ruby/object:Gem::Version
91
- version: '2.2'
87
+ version: '3.0'
92
88
  required_rubygems_version: !ruby/object:Gem::Requirement
93
89
  requirements:
94
90
  - - ">="
95
91
  - !ruby/object:Gem::Version
96
92
  version: '0'
97
93
  requirements: []
98
- rubygems_version: 3.4.10
99
- signing_key:
94
+ rubygems_version: 3.6.0.dev
100
95
  specification_version: 4
101
96
  summary: Wait for conditions in RSpec
102
97
  test_files: []
@@ -1,7 +0,0 @@
1
- module RSpec
2
- module Wait
3
- class Error < StandardError; end
4
-
5
- class TimeoutError < Error; end
6
- end
7
- end