rspec-wait 0.0.8 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE.txt +17 -18
- data/README.md +143 -32
- data/lib/rspec/wait/handler.rb +25 -17
- data/lib/rspec/wait/proxy.rb +15 -3
- data/lib/rspec/wait/target.rb +23 -29
- data/lib/rspec/wait/version.rb +7 -0
- data/lib/rspec/wait.rb +33 -21
- data/lib/rspec-wait.rb +3 -0
- data/rspec-wait.gemspec +30 -14
- metadata +33 -54
- data/.gitignore +0 -15
- data/.rspec +0 -4
- data/.travis.yml +0 -33
- data/CHANGELOG.md +0 -33
- data/CONTRIBUTING.md +0 -48
- data/Gemfile +0 -3
- data/Rakefile +0 -6
- data/gemfiles/rspec_2_11.gemfile +0 -9
- data/gemfiles/rspec_2_12.gemfile +0 -9
- data/gemfiles/rspec_2_13.gemfile +0 -9
- data/gemfiles/rspec_2_14.gemfile +0 -9
- data/gemfiles/rspec_3_0.gemfile +0 -9
- data/gemfiles/rspec_3_1.gemfile +0 -9
- data/gemfiles/rspec_3_2.gemfile +0 -9
- data/gemfiles/rspec_3_3.gemfile +0 -9
- data/gemfiles/rspec_3_4.gemfile +0 -9
- data/lib/rspec/wait/error.rb +0 -7
- data/spec/spec_helper.rb +0 -6
- data/spec/wait_for_spec.rb +0 -162
- data/spec/wait_spec.rb +0 -176
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f3063b52ebd279697ad6513ff3086284b4de74646b923b26eac4063eda6a230d
|
4
|
+
data.tar.gz: a1e2a15ea600566d77c946bb53662907885a1b5491ef1f17bb7735352340b03d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c5675ecf53888f5e0a82de31a819be2e1ec2d051beade97169361344210dc067a4f9b84f8faf97f19b397d431fc6a215637fa5e3c7cf16e8830b5d81556c940
|
7
|
+
data.tar.gz: c0d8d730ead4d2dad8bbe3412c02357276b13734b2befe3c184aa5e62b1bedb680d66a561a76b99bb8c9debb1bc62f214591a2ddcd0d98cd346b585ab565a64f
|
data/LICENSE.txt
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
3
|
+
Copyright (c) 2014 Steve Richert
|
4
4
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
OF
|
22
|
-
|
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
|
6
|
-
[![Build Status](https://img.shields.io/
|
7
|
-
[![
|
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
|
-
###
|
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
|
31
|
-
|
32
|
-
|
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 "
|
49
|
-
wait_for
|
50
|
-
wait_for
|
51
|
-
wait_for
|
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
|
-
|
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
|
-
|
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
|
-
|
138
|
+
RSpec::Wait has three available configuration values:
|
83
139
|
|
84
|
-
|
85
|
-
|
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
|
-
|
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
|
-
|
164
|
+
### RSpec Metadata
|
96
165
|
|
97
|
-
|
98
|
-
|
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
|
-
|
183
|
+
### The `wait` Method
|
114
184
|
|
115
|
-
|
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
|
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
|
-
|
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:
|
data/lib/rspec/wait/handler.rb
CHANGED
@@ -1,34 +1,42 @@
|
|
1
|
-
|
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,
|
7
|
-
|
11
|
+
def handle_matcher(target, initial_matcher, message, &block)
|
12
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
sleep RSpec.configuration.wait_delay
|
17
|
-
retry
|
18
|
-
end
|
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)
|
19
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
|
20
30
|
end
|
21
|
-
rescue Timeout::Error
|
22
|
-
raise failure || TimeoutError
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
|
-
# From: https://github.com/rspec/rspec-expectations/blob/v3.
|
34
|
+
# From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/handler.rb#L46-L65
|
27
35
|
class PositiveHandler < RSpec::Expectations::PositiveExpectationHandler
|
28
36
|
extend Handler
|
29
37
|
end
|
30
38
|
|
31
|
-
# From: https://github.com/rspec/rspec-expectations/blob/v3.
|
39
|
+
# From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/handler.rb#L68-L95
|
32
40
|
class NegativeHandler < RSpec::Expectations::NegativeExpectationHandler
|
33
41
|
extend Handler
|
34
42
|
end
|
data/lib/rspec/wait/proxy.rb
CHANGED
@@ -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(
|
9
|
-
|
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
|
data/lib/rspec/wait/target.rb
CHANGED
@@ -1,47 +1,41 @@
|
|
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.
|
5
|
-
|
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
|
-
unless block
|
11
|
-
raise ArgumentError, "You must pass either an argument or a block to `wait_for`."
|
12
|
-
end
|
13
|
-
new(block, options)
|
14
|
-
elsif block
|
15
|
-
raise ArgumentError, "You cannot pass both an argument and a block to `wait_for`."
|
16
|
-
else
|
17
|
-
new(value, options)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# From: https://github.com/rspec/rspec-expectations/blob/v3.0.0/lib/rspec/expectations/expectation_target.rb#L25-L27
|
22
|
-
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 = {})
|
23
11
|
@wait_options = options
|
24
|
-
super(
|
12
|
+
super(block)
|
25
13
|
end
|
26
14
|
|
27
|
-
# From: https://github.com/rspec/rspec-expectations/blob/v3.
|
15
|
+
# From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/expectation_target.rb#L52-L55
|
28
16
|
def to(matcher = nil, message = nil, &block)
|
29
|
-
prevent_operator_matchers(:to
|
30
|
-
|
17
|
+
prevent_operator_matchers(:to) unless matcher
|
18
|
+
|
19
|
+
with_wait do
|
20
|
+
PositiveHandler.handle_matcher(@target, matcher, message, &block)
|
21
|
+
end
|
31
22
|
end
|
32
23
|
|
33
|
-
# From: https://github.com/rspec/rspec-expectations/blob/v3.
|
24
|
+
# From: https://github.com/rspec/rspec-expectations/blob/v3.4.0/lib/rspec/expectations/expectation_target.rb#L65-L68
|
34
25
|
def not_to(matcher = nil, message = nil, &block)
|
35
|
-
prevent_operator_matchers(:not_to
|
36
|
-
|
26
|
+
prevent_operator_matchers(:not_to) unless matcher
|
27
|
+
|
28
|
+
with_wait do
|
29
|
+
NegativeHandler.handle_matcher(@target, matcher, message, &block)
|
30
|
+
end
|
37
31
|
end
|
38
32
|
|
39
|
-
|
33
|
+
alias to_not not_to
|
40
34
|
|
41
35
|
private
|
42
36
|
|
43
|
-
def with_wait
|
44
|
-
Wait.with_wait(
|
37
|
+
def with_wait(&block)
|
38
|
+
Wait.with_wait(**@wait_options, &block)
|
45
39
|
end
|
46
40
|
end
|
47
41
|
end
|
data/lib/rspec/wait.rb
CHANGED
@@ -1,34 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rspec"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
require_relative "wait/handler"
|
6
|
+
require_relative "wait/proxy"
|
7
|
+
require_relative "wait/target"
|
8
|
+
require_relative "wait/version"
|
6
9
|
|
7
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.
|
8
13
|
module Wait
|
14
|
+
DEFAULT_TIMEOUT = 10.0
|
15
|
+
DEFAULT_DELAY = 0.1
|
16
|
+
DEFAULT_CLONE_MATCHER = false
|
17
|
+
|
9
18
|
module_function
|
10
19
|
|
11
|
-
# From: https://github.com/rspec/rspec-expectations/blob/v3.
|
12
|
-
def wait_for(
|
13
|
-
|
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)
|
14
26
|
end
|
15
27
|
|
16
|
-
def wait(
|
17
|
-
|
18
|
-
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)
|
19
30
|
end
|
20
31
|
|
21
|
-
def with_wait(
|
32
|
+
def with_wait(timeout: nil, delay: nil, clone_matcher: nil)
|
22
33
|
original_timeout = RSpec.configuration.wait_timeout
|
23
34
|
original_delay = RSpec.configuration.wait_delay
|
35
|
+
original_clone_matcher = RSpec.configuration.clone_wait_matcher
|
24
36
|
|
25
|
-
RSpec.configuration.wait_timeout =
|
26
|
-
RSpec.configuration.wait_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?
|
27
40
|
|
28
41
|
yield
|
29
42
|
ensure
|
30
43
|
RSpec.configuration.wait_timeout = original_timeout
|
31
44
|
RSpec.configuration.wait_delay = original_delay
|
45
|
+
RSpec.configuration.clone_wait_matcher = original_clone_matcher
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|
@@ -36,14 +50,12 @@ end
|
|
36
50
|
RSpec.configure do |config|
|
37
51
|
config.include(RSpec::Wait)
|
38
52
|
|
39
|
-
config.add_setting(:wait_timeout, default:
|
40
|
-
config.add_setting(:wait_delay, default:
|
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)
|
41
56
|
|
42
|
-
config.around do |example|
|
43
|
-
|
44
|
-
|
45
|
-
else
|
46
|
-
example.run
|
47
|
-
end
|
57
|
+
config.around(wait: {}) do |example|
|
58
|
+
options = example.metadata.fetch(:wait)
|
59
|
+
with_wait(**options) { example.run }
|
48
60
|
end
|
49
61
|
end
|
data/lib/rspec-wait.rb
ADDED
data/rspec-wait.gemspec
CHANGED
@@ -1,21 +1,37 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/rspec/wait/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |spec|
|
4
|
-
spec.name
|
5
|
-
spec.
|
6
|
+
spec.name = "rspec-wait"
|
7
|
+
spec.summary = "Wait for conditions in RSpec"
|
8
|
+
spec.description = "RSpec::Wait enables time-resilient expectations in your RSpec test suite."
|
9
|
+
spec.version = RSpec::Wait::VERSION
|
10
|
+
|
11
|
+
spec.author = "Steve Richert"
|
12
|
+
spec.email = "steve.richert@hey.com"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.homepage = "https://github.com/laserlemon/rspec-wait"
|
6
15
|
|
7
|
-
spec.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
16
|
+
spec.metadata = {
|
17
|
+
"allowed_push_host" => "https://rubygems.org",
|
18
|
+
"bug_tracker_uri" => "https://github.com/laserlemon/rspec-wait/issues",
|
19
|
+
"funding_uri" => "https://github.com/sponsors/laserlemon",
|
20
|
+
"homepage_uri" => "https://github.com/laserlemon/rspec-wait",
|
21
|
+
"rubygems_mfa_required" => "true",
|
22
|
+
"source_code_uri" => "https://github.com/laserlemon/rspec-wait",
|
23
|
+
}
|
13
24
|
|
14
|
-
spec.
|
15
|
-
spec.
|
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"
|
16
29
|
|
17
|
-
spec.
|
30
|
+
spec.files = Dir.glob([
|
31
|
+
"rspec-wait.gemspec",
|
32
|
+
"lib/**/*.rb",
|
33
|
+
"LICENSE.txt",
|
34
|
+
])
|
18
35
|
|
19
|
-
spec.
|
20
|
-
spec.add_development_dependency "rake", "~> 10.4"
|
36
|
+
spec.extra_rdoc_files = ["README.md"]
|
21
37
|
end
|