rspec-wait 0.0.10 → 1.0.0.rc1

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: f3063b52ebd279697ad6513ff3086284b4de74646b923b26eac4063eda6a230d
4
+ data.tar.gz: a1e2a15ea600566d77c946bb53662907885a1b5491ef1f17bb7735352340b03d
5
5
  SHA512:
6
- metadata.gz: a8ff555f454d246bb4412ba9197e3bd3ddde4609cfe82d1fc0bff50578f9fe86e756b23fd208fa914da4dba49e7cb72cf307d9be334317a88b1833eb3313ab84
7
- data.tar.gz: 8ad28a71663a471032f65912731c3081bc96c84007385354312931595d126db14c9da0bf2139a63d8ec3f3eb707b495efb57932d681db949c0ac4eaa942e7c87
6
+ metadata.gz: 8c5675ecf53888f5e0a82de31a819be2e1ec2d051beade97169361344210dc067a4f9b84f8faf97f19b397d431fc6a215637fa5e3c7cf16e8830b5d81556c940
7
+ data.tar.gz: c0d8d730ead4d2dad8bbe3412c02357276b13734b2befe3c184aa5e62b1bedb680d66a561a76b99bb8c9debb1bc62f214591a2ddcd0d98cd346b585ab565a64f
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,104 @@ 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.
105
+
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!
109
+
110
+ ## Installation
111
+
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
+ ## Configuration
81
137
 
82
- ### Timeout
138
+ RSpec::Wait has three available configuration values:
83
139
 
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:
140
+ - `wait_timeout` - The maximum amount of time (in seconds) that RSpec::Wait
141
+ will continue to retry a failing assertion. Default: `10.0`
142
+ - `wait_delay` - How long (in seconds) RSpec::Wait will pause between retries.
143
+ Default: `0.1`
144
+ - `clone_wait_matcher` - Whether each retry will `clone` the given RSpec
145
+ matcher instance for each evaluation. Set to `true` if you have trouble with
146
+ a matcher holding onto stale state. Default: `false`
86
147
 
87
- #### RSpec Configuration
148
+ RSpec::Wait configurations can be set in three ways:
149
+
150
+ - Globally via `RSpec.configure`
151
+ - Per example or context via RSpec metadata
152
+ - Per assertion via the `wait` method
153
+
154
+ ### Global Configuration
88
155
 
89
156
  ```ruby
90
157
  RSpec.configure do |config|
91
158
  config.wait_timeout = 3 # seconds
159
+ config.wait_delay = 0.5 # seconds
160
+ config.clone_wait_matcher = true
92
161
  end
93
162
  ```
94
163
 
95
- #### RSpec Metadata
164
+ ### RSpec Metadata
96
165
 
97
- The timeout can also be specified via options added to a spec's or context's
98
- `:wait` metadata:
166
+ Any of RSpec::Wait's three configurations can be set on a per-example or
167
+ per-context basis using `wait` metadata. Provide a hash containing any
168
+ number of shorthand keys and values for RSpec::Wait's configurations.
99
169
 
100
170
  ```ruby
101
- scenario "A user can log in successfully", wait: { timeout: 3 } do
171
+ scenario "A user can log in successfully", wait: { timeout: 3, delay: 0.5, clone_wait_matcher: true } do
102
172
  visit new_session_path
103
173
 
104
174
  fill_in "Email", with: "john@example.com"
@@ -110,9 +180,12 @@ scenario "A user can log in successfully", wait: { timeout: 3 } do
110
180
  end
111
181
  ```
112
182
 
113
- #### The `wait` Method
183
+ ### The `wait` Method
114
184
 
115
- On a per-assertion basis, the timeout value can be passed to the `wait` method.
185
+ And on a per-assertion basis, the `wait` method accepts a hash of shorthand
186
+ keys and values for RSpec::Wait's configurations. The `wait` method must be
187
+ chained to the `for` method and aside from the ability to set RSpec::Wait
188
+ configuration for the single assertion, it behaves identically to `wait_for`.
116
189
 
117
190
  ```ruby
118
191
  scenario "A user can log in successfully" do
@@ -122,12 +195,47 @@ scenario "A user can log in successfully" do
122
195
  fill_in "Password", with: "secret"
123
196
  click_button "Log In"
124
197
 
125
- wait(3.seconds).for { current_path }.to eq(account_path)
198
+ wait(timeout: 3).for { current_path }.to eq(account_path)
126
199
  expect(page).to have_content("Welcome back!")
127
200
  end
128
201
  ```
129
202
 
130
- ### Use with Cucumber
203
+ The `wait` method will also accept `timeout` as a positional argument for
204
+ improved readability:
205
+
206
+ ```ruby
207
+ wait(3.seconds).for { current_path }.to eq(account_path)
208
+ ```
209
+
210
+ ## Use with RuboCop
211
+
212
+ If you use `rubocop` and `rubocop-rspec` in your codebase, an RSpec example
213
+ with a single `wait_for` assertion may cause RuboCop to complain:
214
+
215
+ ```
216
+ RSpec/NoExpectationExample: No expectation found in this example.
217
+ ```
218
+
219
+ By default, RuboCop sees only `expect*` and `assert*` methods as expectations.
220
+ You can configure RuboCop to recognize `wait_for` and `wait.for` as
221
+ expectations (in addition to the defaults) in your RuboCop configuration:
222
+
223
+ ```yaml
224
+ RSpec/NoExpectationExample:
225
+ AllowedPatterns:
226
+ - ^assert_
227
+ - ^expect_
228
+ - ^wait(_for)?$
229
+ ```
230
+
231
+ Of course, you can always disable this cop entirely:
232
+
233
+ ```yaml
234
+ RSpec/NoExpectationExample:
235
+ Enabled: false
236
+ ```
237
+
238
+ ## Use with Cucumber
131
239
 
132
240
  To enable RSpec::Wait in your Cucumber step definitions, add the following to
133
241
  `features/support/env.rb`:
@@ -147,7 +255,7 @@ and [contribution](https://github.com/laserlemon/rspec-wait/graphs/contributors)
147
255
  from the Ruby community, especially the [authors and maintainers](https://github.com/rspec/rspec-core/graphs/contributors)
148
256
  of RSpec.
149
257
 
150
- **Thank you!**
258
+ **Thank you!** :yellow_heart:
151
259
 
152
260
  ## How can I help?
153
261
 
@@ -156,3 +264,6 @@ No contribution is too small.
156
264
 
157
265
  See RSpec::Wait's [contribution guidelines](CONTRIBUTING.md) for more
158
266
  information.
267
+
268
+ If you're enjoying RSpec::Wait, please consider [sponsoring](https://github.com/sponsors/laserlemon)
269
+ 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.rc1")
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,14 @@
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.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Richert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-26 00:00:00.000000000 Z
11
+ date: 2024-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '3.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '3.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '13.0'
55
55
  description: RSpec::Wait enables time-resilient expectations in your RSpec test suite.
56
56
  email: steve.richert@hey.com
57
57
  executables: []
@@ -61,8 +61,8 @@ extra_rdoc_files:
61
61
  files:
62
62
  - LICENSE.txt
63
63
  - README.md
64
+ - lib/rspec-wait.rb
64
65
  - lib/rspec/wait.rb
65
- - lib/rspec/wait/error.rb
66
66
  - lib/rspec/wait/handler.rb
67
67
  - lib/rspec/wait/proxy.rb
68
68
  - lib/rspec/wait/target.rb
@@ -78,9 +78,7 @@ metadata:
78
78
  homepage_uri: https://github.com/laserlemon/rspec-wait
79
79
  rubygems_mfa_required: 'true'
80
80
  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
81
+ post_install_message:
84
82
  rdoc_options: []
85
83
  require_paths:
86
84
  - lib
@@ -88,12 +86,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
86
  requirements:
89
87
  - - ">="
90
88
  - !ruby/object:Gem::Version
91
- version: '2.2'
89
+ version: '3.0'
92
90
  required_rubygems_version: !ruby/object:Gem::Requirement
93
91
  requirements:
94
- - - ">="
92
+ - - ">"
95
93
  - !ruby/object:Gem::Version
96
- version: '0'
94
+ version: 1.3.1
97
95
  requirements: []
98
96
  rubygems_version: 3.4.10
99
97
  signing_key:
@@ -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