rspec-wait 0.0.10 → 1.0.0

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
  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