rspec-wait 0.0.8 → 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 +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
|
-
[](https://codeclimate.com/github/laserlemon/rspec-wait)
|
9
|
-
[](https://gemnasium.com/laserlemon/rspec-wait)
|
5
|
+
[](http://rubygems.org/gems/rspec-wait)
|
6
|
+
[](https://github.com/laserlemon/rspec-wait/actions/workflows/rake.yml)
|
7
|
+
[](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
|