rspec-change_to_now 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +7 -0
- data/README.md +81 -38
- data/features/change_to_now.feature +1 -1
- data/features/matcher_only.feature +30 -0
- data/features/negate.feature +2 -0
- data/lib/rspec/change_to_now/matchers/as_matcher.rb +18 -0
- data/lib/rspec/change_to_now/{detect.rb → matchers/detect.rb} +3 -15
- data/lib/rspec/change_to_now/matchers/dsl.rb +36 -0
- data/lib/rspec/change_to_now/{verify_argument_is_matcher.rb → matchers/matcher_only.rb} +4 -4
- data/lib/rspec/change_to_now/{negate.rb → matchers/negate.rb} +3 -12
- data/lib/rspec/change_to_now/matchers.rb +6 -0
- data/lib/rspec/change_to_now/version.rb +1 -1
- data/lib/rspec/change_to_now.rb +74 -86
- data/spec/rspec/change_to_now_spec.rb +7 -7
- data/spec/rspec/matchers/as_matcher_spec.rb +19 -0
- data/spec/rspec/{detect_spec.rb → matchers/detect_spec.rb} +4 -4
- data/spec/rspec/{verify_argument_is_matcher_spec.rb → matchers/matcher_only_spec.rb} +5 -5
- data/spec/rspec/{negate_spec.rb → matchers/negate_spec.rb} +2 -2
- data/spec/rspec/matchers/spec_helper.rb +1 -0
- data/spec/spec_helper.rb +1 -0
- metadata +19 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4eeffda32467a4dac65939c732f0f24e05343929
|
4
|
+
data.tar.gz: eff76f6f8b2df43792b0002901c4d9b01573208a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66ec9926632f994937265a25ba33b030b9c5fdb3efadd0faebce537193ee0f231991c5e02a39ecaadbc913b1a696ebc763ff385b07668e844974e86a1b660ff6
|
7
|
+
data.tar.gz: b7dc9700659f0fec207f1d109c5376e1d6ee9def50e229cec9fd12b7776044b28d6f2afb903e57bb9d8a8a843f40fac28a9a4f56e6e0f87a6df44d543ef4358e
|
data/Changelog.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
### 1.2.0
|
2
|
+
|
3
|
+
* Make it easy to include `negate` and `matcher_only` matchers.
|
4
|
+
* Move `RSpec::Matchers::ChangeToNow.override_to` setting to `RSpec::ChangeToNow.override_to`
|
5
|
+
* When passed both arguments and a block, `detect` will raise a `SyntaxError` instead of `ExpectationNotMet`
|
6
|
+
* When passed an object that is not a matcher, `to_now` will behave like `to`, albeit reporting precondition failures.
|
7
|
+
|
1
8
|
### 1.1.0
|
2
9
|
|
3
10
|
* Add `with_final_result` matcher that doesn't do precondition test
|
data/README.md
CHANGED
@@ -4,37 +4,39 @@ RSpec::ChangeTo adds the `to_now` and `not_to_now` methods to `change` matcher t
|
|
4
4
|
|
5
5
|
## Usage
|
6
6
|
|
7
|
-
Use the `to_now` and `not_to_now` (or `not_to`, for short) methods to make assertions about the effect of an rspec `change` block:
|
7
|
+
Use the `to_now` and `not_to_now` (or `not_to`, for short) methods to make assertions about the effect of an rspec `change` block rather than just the final state:
|
8
8
|
|
9
9
|
```ruby
|
10
|
-
expect { @x
|
10
|
+
expect { @x -= [1] }.to change { @x }.not_to include 1
|
11
11
|
```
|
12
12
|
|
13
|
-
|
13
|
+
Conversely, an example like this, which passes on rspec 3.0, would fail:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
|
16
|
+
@x = [1]
|
17
|
+
expect { @x << 1 }.to change { @x }.to_now include 1
|
17
18
|
```
|
18
19
|
|
19
|
-
The method `to_now` will check both that the matcher *does not* match prior to the change and that it *does* match after the change. The method `not_to_now` (`not_to` for short) will do the opposite, ensuring that the matcher matches prior to the change, and fails only after the change. All methods will ensure that a change actually takes place.
|
20
|
-
|
21
20
|
Also supported are aliases for those who don't want to split their infinitives and for those who would like to differently split them:
|
22
21
|
|
23
22
|
* `to_now` can also be called as `now_to`
|
24
23
|
* `not_to_now` can also be called `not_to`, `to_not`, `to_not_now` and `not_now_to`
|
25
24
|
|
26
|
-
##
|
25
|
+
## How *exactly* does it work?
|
26
|
+
|
27
|
+
The method `to_now` will check both that the expected value *does not* match prior to the change and that it *does* match after the change. The method `not_to_now` (`not_to` for short) will do the opposite, ensuring that the expected value does matche prior to the change, and fails only after the change. Both methods will ensure that a change actually takes place.
|
28
|
+
|
29
|
+
## Globally overriding default RSpec behavior for `to` with `to_now`
|
27
30
|
|
28
31
|
You can force the rspec `change` matcher to always use `to_now` instead of `to` by setting:
|
29
32
|
|
30
33
|
```ruby
|
31
|
-
RSpec::
|
34
|
+
RSpec::ChangeToNow.override_to = true
|
32
35
|
```
|
33
36
|
|
34
|
-
|
35
37
|
## Testing without preconditions
|
36
38
|
|
37
|
-
|
39
|
+
While I'd assert that in most conditions, the automatic precondition checks introduced by `to_now` would be helpful, you may find yourself wanting to disable them for some expectations. Here are a couple of ways to prevent precondition checks:
|
38
40
|
|
39
41
|
1. Use `with_final_result` instead of `to_now` to check your results. e.g.
|
40
42
|
|
@@ -76,7 +78,7 @@ And require it as:
|
|
76
78
|
|
77
79
|
## Why is this useful?
|
78
80
|
|
79
|
-
`change { }.from().to()`
|
81
|
+
When passed object values as expectations, `change { }.from().to()` fails as if it has pre- and post-condition checks. However, when a passed matcher to `to`, it will not check the inverse condition prior to the change. With `to_now`, you can write:
|
80
82
|
|
81
83
|
```ruby
|
82
84
|
list = []
|
@@ -99,50 +101,91 @@ While that may not seem like a big deal, the real values comes in more complex s
|
|
99
101
|
|
100
102
|
Arguably, I should be injecting some dependencies here instead of relying on globals, but Rails code doesn't always look like that. I'm looking forward to playing around with this and seeing if it really helps simplify specs. I'd love to hear your feedback.
|
101
103
|
|
102
|
-
|
104
|
+
Finally, *change_to_now* causes inferred pre-condition tests, to be explicitly reported. For example,
|
103
105
|
|
104
|
-
|
106
|
+
```ruby
|
107
|
+
number = 2
|
108
|
+
expect {
|
109
|
+
number += 1
|
110
|
+
}.to change { number }.to_now 2
|
111
|
+
```
|
105
112
|
|
106
|
-
|
113
|
+
will report:
|
114
|
+
|
115
|
+
expected result to have initially passed ~(match 2), but was 2
|
116
|
+
|
117
|
+
If set up *change_to_now* to_now to globally override `change {}. to`, then even `to` will report this way.
|
107
118
|
|
108
|
-
|
119
|
+
## Additional Matchers Provided: *negate*, *detect*, *matcher_only* and *as_matcher*
|
109
120
|
|
121
|
+
This gem also provides some additional matchers as detailed below. Only the `detect` matcher is automatically added to the rspec DSL when `rspec/change_to_now` is required. To get the other matchers, add this line to your `spec_helper.rb`:
|
110
122
|
|
111
123
|
```ruby
|
112
|
-
|
124
|
+
# spec_helper.rb
|
125
|
+
RSpec.configure { |c|.include RSpec::ChangeToNow::Matchers::DSL }
|
113
126
|
```
|
114
127
|
|
115
|
-
|
128
|
+
* `negate(&block)` *(optional)*
|
116
129
|
|
117
|
-
|
130
|
+
This gem also introduces the `negate` matcher, which negates an existing matcher. You can use it like so:
|
118
131
|
|
119
|
-
This gem also adds the `detect` matcher, which behaves like the `include` matcher when passed a `satisfy` matcher created using the given block. You can use it like so:
|
120
132
|
|
133
|
+
```ruby
|
134
|
+
expect(1).to negate(ne(1))
|
135
|
+
```
|
136
|
+
|
137
|
+
While it doesn't read every well, it serves an internal purpose, allowing a very simple implementation of `to_now` using composable matcher inputs to the `from` and `to` methods as [added in rspec 3.0](http://myronmars.to/n/dev-blog/2014/01/new-in-rspec-3-composable-matchers).
|
138
|
+
|
139
|
+
* `detect(&block)`
|
121
140
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
141
|
+
The `detect` matcher behaves like the `include` matcher when passed a `satisfy` matcher created using the given block. You can use it like so:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
list = []
|
145
|
+
expect { list << 2 }.to change { list }.to detect(&:even?)
|
146
|
+
```
|
147
|
+
|
148
|
+
This is the same as:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
list = []
|
152
|
+
expect { list << 2 }.to change { list }.to include satisfy(&:even?)
|
153
|
+
```
|
154
|
+
|
155
|
+
A more interesting use might be:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
person = Person.create(name: 'Taylor')
|
159
|
+
expect { person.siblings.create(name: 'Sam') }.to change {
|
160
|
+
Person.all
|
161
|
+
}.to_now detect { |person|
|
162
|
+
person.name == 'Taylor'
|
163
|
+
}
|
164
|
+
```
|
126
165
|
|
127
|
-
|
166
|
+
`detect` behaves exactly like `include` when it is not passed a block and will raise an exception if passed both expected items/matchers and a block.
|
128
167
|
|
129
|
-
|
130
|
-
list = []
|
131
|
-
expect { list << 2 }.to change { list }.to include satisfy(&:even?)
|
132
|
-
```
|
168
|
+
* `matcher_only(matcher)` *(optional)*
|
133
169
|
|
134
|
-
|
170
|
+
The `match_only` matcher just passes the given matcher through unless it is not a matcher, in which case it raises a syntax error. While this would pass:
|
135
171
|
|
136
|
-
```ruby
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
172
|
+
```ruby
|
173
|
+
expect(1).to matcher_only(eq(1))
|
174
|
+
```
|
175
|
+
|
176
|
+
this would fail with a syntax error:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
expect(1).to matcher_only(1)
|
180
|
+
```
|
181
|
+
|
182
|
+
* `as_matcher(expected)` *(optional)*
|
144
183
|
|
145
|
-
`
|
184
|
+
The `as_matcher` matcher just passes the given matcher through unless it is not a matcher, in which case it returns a new matcher created using `match(expected)`. So, for example, this would work:
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
expect(1).to as_matcher(1)
|
188
|
+
```
|
146
189
|
|
147
190
|
## Contributing
|
148
191
|
|
@@ -46,7 +46,7 @@ Feature: expecting a matcher to change
|
|
46
46
|
Scenario: overriding RSpec `change { }.to` to behave like `change { }.to_now`
|
47
47
|
Given a file named "example_spec.rb" with:
|
48
48
|
"""ruby
|
49
|
-
RSpec::
|
49
|
+
RSpec::ChangeToNow.override_to = true
|
50
50
|
|
51
51
|
describe "adding one" do
|
52
52
|
it "adds one" do
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Feature: matcher-only matcher
|
2
|
+
|
3
|
+
Scenario: when the argument is a matcher
|
4
|
+
Given a file named "example_spec.rb" with:
|
5
|
+
"""ruby
|
6
|
+
include RSpec::ChangeToNow::Matchers::DSL
|
7
|
+
|
8
|
+
describe "when passed a matcher" do
|
9
|
+
it "just passes the matcher through" do
|
10
|
+
expect(2).to matcher_only(eq 2)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
"""
|
14
|
+
When I run rspec
|
15
|
+
Then the examples should all pass
|
16
|
+
|
17
|
+
Scenario: when the argument is not a matcher
|
18
|
+
Given a file named "example_spec.rb" with:
|
19
|
+
"""ruby
|
20
|
+
include RSpec::ChangeToNow::Matchers::DSL
|
21
|
+
|
22
|
+
describe "when passed a non-matcher object" do
|
23
|
+
it "reports a syntax error" do
|
24
|
+
expect(2).to matcher_only(2)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
"""
|
28
|
+
When I run rspec
|
29
|
+
Then the output should contain "SyntaxError"
|
30
|
+
And the output should contain "expected a matcher as an argument but got: 2"
|
data/features/negate.feature
CHANGED
@@ -3,6 +3,7 @@ Feature: negating a matcher
|
|
3
3
|
Scenario: when the matcher is negated
|
4
4
|
Given a file named "example_spec.rb" with:
|
5
5
|
"""ruby
|
6
|
+
include RSpec::ChangeToNow::Matchers::DSL
|
6
7
|
|
7
8
|
describe "testing equality" do
|
8
9
|
it "is the same as negated inequality" do
|
@@ -16,6 +17,7 @@ Feature: negating a matcher
|
|
16
17
|
Scenario: failures are correctly reported
|
17
18
|
Given a file named "example_spec.rb" with:
|
18
19
|
"""ruby
|
20
|
+
include RSpec::ChangeToNow::Matchers::DSL
|
19
21
|
|
20
22
|
describe "testing equality" do
|
21
23
|
it "fails if the the negated matcher does match" do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'rspec/expectations'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module ChangeToNow::Matchers
|
6
|
+
# Decorator that wraps a matcher and raises a syntax error if the matcher is not a matcher.
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class AsMatcher < RSpec::Matchers::MatcherDelegator
|
10
|
+
include RSpec::Matchers::Composable
|
11
|
+
|
12
|
+
def initialize(expected)
|
13
|
+
expected = RSpec::Matchers::BuiltIn::Match.new(expected) unless RSpec::Matchers.is_a_matcher?(expected)
|
14
|
+
super(expected)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'rspec/core'
|
2
2
|
require 'rspec/expectations'
|
3
3
|
|
4
|
-
module RSpec
|
4
|
+
module RSpec::ChangeToNow
|
5
5
|
module Matchers
|
6
6
|
# @api private
|
7
7
|
# Provides the implementation for `detect`.
|
8
8
|
# Not intended to be instantiated directly.
|
9
|
-
class Detect < BuiltIn::Include
|
9
|
+
class Detect < RSpec::Matchers::BuiltIn::Include
|
10
10
|
def initialize(*expected, &block)
|
11
11
|
if @block = block
|
12
12
|
block_matcher = RSpec::Matchers::BuiltIn::Satisfy.new(&block)
|
@@ -70,7 +70,7 @@ module RSpec
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def handle_arguments_for_match(actual)
|
73
|
-
|
73
|
+
raise SyntaxError, block_and_arguments_together_failure_message if has_both_block_and_arguments?
|
74
74
|
original_actual = actual
|
75
75
|
actual = actual.to_a if @block && actual.is_a?(Hash)
|
76
76
|
value = yield(actual)
|
@@ -78,17 +78,5 @@ module RSpec
|
|
78
78
|
value
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
82
|
-
# If given a block, passes if the block returns a truthy value for any of the actual items or for the key-value pair is the actual item list is a hash.
|
83
|
-
# Without a block, it behaves identically to +include+.
|
84
|
-
# +expected+ must be empty if a block is provided.
|
85
|
-
#
|
86
|
-
# @example
|
87
|
-
# expect([2]).to detect(&:even?)
|
88
|
-
# expect({a: 2}).to detect { |k,v| v.even? }
|
89
|
-
# expect([1]).to detect 1
|
90
|
-
def detect(*expected, &block)
|
91
|
-
Detect.new(*expected, &block)
|
92
|
-
end
|
93
81
|
end
|
94
82
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RSpec::ChangeToNow::Matchers::DSL
|
2
|
+
# @api public
|
3
|
+
# Returns a new matcher that fails with a syntax error if +matcher+ is not a matcher but otherwise behaves just like +matcher+.
|
4
|
+
def matcher_only(matcher)
|
5
|
+
RSpec::ChangeToNow::Matchers::MatcherOnly.new(matcher)
|
6
|
+
end
|
7
|
+
|
8
|
+
# @api public
|
9
|
+
# Returns a matcher that behaves like the inverse of +matcher+.
|
10
|
+
def negate(matcher)
|
11
|
+
RSpec::ChangeToNow::Matchers::Negate.new(matcher)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @api public
|
15
|
+
# Returns a matcher that behaves like the +matcher+ if passed a matcher, otherwise like match(+matcher+)
|
16
|
+
def as_matcher(expected)
|
17
|
+
RSpec::ChangeToNow::Matchers::AsMatcher.new(expected)
|
18
|
+
end
|
19
|
+
|
20
|
+
module Detect
|
21
|
+
# @api public
|
22
|
+
# If given a block, passes if the block returns a truthy value for any of the actual items or for the key-value pair is the actual item list is a hash.
|
23
|
+
# Without a block, it behaves identically to +include+.
|
24
|
+
# +expected+ must be empty if a block is provided.
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# expect([2]).to detect(&:even?)
|
28
|
+
# expect({a: 2}).to detect { |k,v| v.even? }
|
29
|
+
# expect([1]).to detect 1
|
30
|
+
def detect(*expected, &block)
|
31
|
+
RSpec::ChangeToNow::Matchers::Detect.new(*expected, &block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
include Detect
|
36
|
+
end
|
@@ -2,14 +2,14 @@ require 'rspec/core'
|
|
2
2
|
require 'rspec/expectations'
|
3
3
|
|
4
4
|
module RSpec
|
5
|
-
module Matchers
|
6
|
-
# Decorator that wraps a matcher and raises
|
5
|
+
module ChangeToNow::Matchers
|
6
|
+
# Decorator that wraps a matcher and raises a syntax error if the matcher is not a matcher.
|
7
7
|
#
|
8
8
|
# @api private
|
9
|
-
class
|
9
|
+
class MatcherOnly < RSpec::Matchers::MatcherDelegator
|
10
10
|
# Forward messages on to the wrapped matcher, first verifying that this really is a matcher.
|
11
11
|
def method_missing(method, *args)
|
12
|
-
raise SyntaxError, "
|
12
|
+
raise SyntaxError, "expected a matcher as an argument but got: #{base_matcher.inspect}" unless Matchers.is_a_matcher?(base_matcher)
|
13
13
|
base_matcher.send(method, *args)
|
14
14
|
end
|
15
15
|
|
@@ -2,13 +2,13 @@ require 'rspec/core'
|
|
2
2
|
require 'rspec/expectations'
|
3
3
|
|
4
4
|
module RSpec
|
5
|
-
module Matchers
|
5
|
+
module ChangeToNow::Matchers
|
6
6
|
# @api private
|
7
7
|
# Provides the implementation for `negate`.
|
8
8
|
# Not intended to be instantiated directly.
|
9
9
|
class Negate
|
10
|
-
include Composable
|
11
|
-
include Pretty
|
10
|
+
include RSpec::Matchers::Composable
|
11
|
+
include RSpec::Matchers::Pretty
|
12
12
|
|
13
13
|
def initialize(matcher)
|
14
14
|
@matcher = matcher
|
@@ -58,14 +58,5 @@ module RSpec
|
|
58
58
|
@matcher.supports_block_expectations?
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
62
|
-
# Passes if provided +matcher+ fails and vice-versa.
|
63
|
-
#
|
64
|
-
# @example
|
65
|
-
# expect([1]).to negate(eq(2))
|
66
|
-
# expect([1]).not_to negate(eq(1))
|
67
|
-
def negate(matcher)
|
68
|
-
Negate.new(matcher)
|
69
|
-
end
|
70
61
|
end
|
71
62
|
end
|
data/lib/rspec/change_to_now.rb
CHANGED
@@ -1,115 +1,103 @@
|
|
1
1
|
require 'rspec/change_to_now/version'
|
2
|
-
require 'rspec/change_to_now/
|
3
|
-
require 'rspec/change_to_now/negate'
|
4
|
-
require 'rspec/change_to_now/verify_argument_is_matcher'
|
2
|
+
require 'rspec/change_to_now/matchers'
|
5
3
|
require 'rspec/core'
|
6
4
|
require 'rspec/expectations'
|
7
5
|
|
8
|
-
module RSpec
|
9
|
-
module
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
module RSpec
|
7
|
+
module Matchers::BuiltIn
|
8
|
+
class Change
|
9
|
+
include RSpec::ChangeToNow::Matchers::DSL
|
10
|
+
|
11
|
+
# @api public
|
12
|
+
# Passes if +matcher+ fails on the result of the change block before the expectation block and passes after.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# expect({ @x = 1 }.to change { @x }.to_now eq 1
|
16
|
+
#
|
17
|
+
# In implementation, this is identical to
|
18
|
+
# change {}.to eq { }`
|
19
|
+
# is the same as
|
20
|
+
# change {}.to_now eq(1)
|
21
|
+
# change {}.from(negate(eq(1))).to(eq(1))
|
22
|
+
def to_now(matcher)
|
23
|
+
RSpec::Matchers::BuiltIn::ChangeToValue.new(@change_details, as_matcher(matcher)).
|
24
|
+
from(negate(as_matcher(matcher)))
|
25
|
+
end
|
16
26
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
27
|
+
# @api public
|
28
|
+
# Passes if +matcher+ passes on the result of the change block before the expectation block and fails after.
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# expect({ @x = 1 }.to change { @x }.not_to_now eq 1
|
32
|
+
def not_to_now(matcher)
|
33
|
+
RSpec::Matchers::BuiltIn::ChangeToValue.new(@change_details, negate(as_matcher(matcher))).
|
34
|
+
from(as_matcher(matcher))
|
35
|
+
end
|
22
36
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# @api public
|
27
|
-
# Passes if +matcher+ fails on the result of the change block before the expectation block and passes after.
|
28
|
-
#
|
29
|
-
# @example
|
30
|
-
# expect({ @x = 1 }.to change { @x }.to_now eq 1
|
31
|
-
#
|
32
|
-
# In implementation, this is identical to
|
33
|
-
# change {}.to eq { }`
|
34
|
-
# is the same as
|
35
|
-
# change {}.to_now eq(1)
|
36
|
-
# change {}.from(negate(eq(1))).to(eq(1))
|
37
|
-
def to_now(matcher)
|
38
|
-
RSpec::Matchers::BuiltIn::ChangeToValue.new(@change_details, verify_argument_is_matcher(matcher)).
|
39
|
-
from(negate(verify_argument_is_matcher(matcher)))
|
40
|
-
end
|
37
|
+
# @api public
|
38
|
+
alias_method :now_to, :to_now
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
# @example
|
46
|
-
# expect({ @x = 1 }.to change { @x }.not_to_now eq 1
|
47
|
-
def not_to_now(matcher)
|
48
|
-
RSpec::Matchers::BuiltIn::ChangeToValue.new(@change_details, negate(verify_argument_is_matcher(matcher))).
|
49
|
-
from(verify_argument_is_matcher(matcher))
|
50
|
-
end
|
40
|
+
# @api public
|
41
|
+
alias_method :not_to, :not_to_now
|
51
42
|
|
52
|
-
|
53
|
-
|
43
|
+
# @api public
|
44
|
+
alias_method :not_now_to, :not_to_now
|
54
45
|
|
55
|
-
|
56
|
-
|
46
|
+
# @api public
|
47
|
+
alias_method :to_not, :not_to_now
|
57
48
|
|
58
|
-
|
59
|
-
|
49
|
+
# @api public
|
50
|
+
alias_method :to_not_now, :not_to_now
|
60
51
|
|
61
|
-
|
62
|
-
|
52
|
+
# @private
|
53
|
+
alias_method :to_without_to_now, :to
|
63
54
|
|
64
|
-
|
65
|
-
|
55
|
+
# @private
|
56
|
+
def to_with_to_now(expected)
|
57
|
+
if RSpec::ChangeToNow.override_to && RSpec::Matchers.is_a_matcher?(expected)
|
58
|
+
to_now(expected)
|
59
|
+
else
|
60
|
+
to_without_to_now(expected)
|
61
|
+
end
|
62
|
+
end
|
66
63
|
|
67
|
-
|
68
|
-
|
64
|
+
# @private
|
65
|
+
alias_method :to, :to_with_to_now
|
69
66
|
|
70
|
-
|
71
|
-
|
72
|
-
if RSpec::Matchers::ChangeToNow.override_to && RSpec::Matchers.is_a_matcher?(expected)
|
73
|
-
to_now(expected)
|
74
|
-
else
|
67
|
+
# @api public
|
68
|
+
def with_final_result(expected)
|
75
69
|
to_without_to_now(expected)
|
76
70
|
end
|
77
71
|
end
|
78
72
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
# @api public
|
83
|
-
def with_final_result(expected)
|
84
|
-
to_without_to_now(expected)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
class BuiltIn::ChangeFromValue
|
89
|
-
include ChangeToNowMatchers
|
73
|
+
class ChangeFromValue
|
74
|
+
include RSpec::ChangeToNow::Matchers::DSL
|
90
75
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
76
|
+
def to_now(matcher)
|
77
|
+
RSpec::Matchers::BuiltIn::ChangeToValue.new(
|
78
|
+
@change_details,
|
79
|
+
matcher_only(matcher)
|
80
|
+
).from(@expected_before)
|
81
|
+
end
|
97
82
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
83
|
+
def not_to_now(matcher)
|
84
|
+
RSpec::Matchers::BuiltIn::ChangeToValue.new(
|
85
|
+
@change_details,
|
86
|
+
negate(matcher_only(matcher))
|
87
|
+
).from(@expected_before)
|
88
|
+
end
|
104
89
|
|
105
|
-
|
106
|
-
|
90
|
+
def with_final_result(expected)
|
91
|
+
to_without_to_now(expected)
|
92
|
+
end
|
107
93
|
end
|
108
94
|
end
|
109
95
|
|
110
|
-
|
96
|
+
module ChangeToNow
|
111
97
|
class << self
|
112
98
|
attr_accessor :override_to
|
113
99
|
end
|
114
100
|
end
|
115
101
|
end
|
102
|
+
|
103
|
+
RSpec.configure { |c| c.include RSpec::ChangeToNow::Matchers::DSL::Detect } if RSpec.respond_to?(:configure)
|
@@ -37,13 +37,13 @@ module RSpec
|
|
37
37
|
}.to change { number }.to_now eq 2
|
38
38
|
}.to fail_matching("expected result to have initially been ~(eq 2), but was 2")
|
39
39
|
end
|
40
|
-
it "
|
41
|
-
number =
|
40
|
+
it "reports an error about the precondition if passed a non-matcher object" do
|
41
|
+
number = 2
|
42
42
|
expect {
|
43
43
|
expect {
|
44
44
|
number += 1
|
45
|
-
}.to change { }.to_now 2
|
46
|
-
}.to
|
45
|
+
}.to change { number }.to_now 2
|
46
|
+
}.to fail_matching("expected result to have initially been ~(match 2), but was 2")
|
47
47
|
end
|
48
48
|
|
49
49
|
describe "after #from" do
|
@@ -112,13 +112,13 @@ module RSpec
|
|
112
112
|
}.to change { number }.not_to_now satisfy(&:even?)
|
113
113
|
}.to fail_matching("expected result to have changed to ~(satisfy block), but is now 4")
|
114
114
|
end
|
115
|
-
it "
|
115
|
+
it "reports an error about the precondition if passed a non-matcher object" do
|
116
116
|
number = 1
|
117
117
|
expect {
|
118
118
|
expect {
|
119
119
|
number += 1
|
120
120
|
}.to change { }.not_to_now 2
|
121
|
-
}.to
|
121
|
+
}.to fail_matching("expected result to have initially been match 2, but was nil")
|
122
122
|
end
|
123
123
|
|
124
124
|
describe "after #from" do
|
@@ -224,7 +224,7 @@ module RSpec
|
|
224
224
|
|
225
225
|
describe "when #to has been overridden by the configuration setting" do
|
226
226
|
before do
|
227
|
-
allow(RSpec::
|
227
|
+
allow(RSpec::ChangeToNow).to receive(:override_to).and_return(true)
|
228
228
|
end
|
229
229
|
|
230
230
|
it "fails when the final expectation is already met" do
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe "as_matcher" do
|
4
|
+
describe "when the argument is a matcher" do
|
5
|
+
it "delegates to the matcher" do
|
6
|
+
expect {
|
7
|
+
expect(1).to as_matcher(eq 2)
|
8
|
+
}.to fail_matching(/expected: 2.*got: 1/m)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "when the argument is not a matcher" do
|
13
|
+
it "uses the default matcher" do
|
14
|
+
expect {
|
15
|
+
expect(1).to as_matcher(2)
|
16
|
+
}.to fail_matching(/expected 1 to match 2/m)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
describe "detect" do
|
4
4
|
describe "expect(...).to detect(&with_block)" do
|
5
5
|
context "for an array target" do
|
6
6
|
it "passes if target detects expected" do
|
@@ -57,7 +57,7 @@ RSpec.describe "#detect matcher" do
|
|
57
57
|
it "fails with a message" do
|
58
58
|
expect {
|
59
59
|
expect([0, 1]).to detect(0) { true }
|
60
|
-
}.to
|
60
|
+
}.to raise_error SyntaxError, "detect can take arguments or a block but not both"
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -65,7 +65,7 @@ RSpec.describe "#detect matcher" do
|
|
65
65
|
it "fails with a message" do
|
66
66
|
expect {
|
67
67
|
expect([0, 1]).not_to detect(0) { true }
|
68
|
-
}.to
|
68
|
+
}.to raise_error SyntaxError, "detect can take arguments or a block but not both"
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe "matcher_only" do
|
4
4
|
describe "when the argument is a matcher" do
|
5
5
|
it "delegates to the matcher" do
|
6
6
|
expect {
|
7
|
-
expect(1).to
|
7
|
+
expect(1).to matcher_only(eq 2)
|
8
8
|
}.to fail_matching(/expected: 2.*got: 1/m)
|
9
9
|
end
|
10
10
|
end
|
@@ -12,8 +12,8 @@ describe RSpec::Matchers::VerifyArgumentIsMatcher do
|
|
12
12
|
describe "when the argument is not a matcher" do
|
13
13
|
it "raises a syntax error when the matcher is evaluated" do
|
14
14
|
expect {
|
15
|
-
expect(1).to
|
16
|
-
}.to raise_error SyntaxError, "
|
15
|
+
expect(1).to matcher_only(2)
|
16
|
+
}.to raise_error SyntaxError, "expected a matcher as an argument but got: 2"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
describe "negate" do
|
4
4
|
describe "with literal expectations" do
|
5
5
|
describe "when not negated" do
|
6
6
|
describe "when the original matcher provides :does_not_match?" do
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-change_to_now
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew S. Brown
|
@@ -169,20 +169,26 @@ files:
|
|
169
169
|
- cucumber.yml
|
170
170
|
- features/change_to_now.feature
|
171
171
|
- features/detect.feature
|
172
|
+
- features/matcher_only.feature
|
172
173
|
- features/negate.feature
|
173
174
|
- features/step_definitions/additional_cli_steps.rb
|
174
175
|
- features/support/env.rb
|
175
176
|
- lib/rspec/change_to_now.rb
|
176
|
-
- lib/rspec/change_to_now/
|
177
|
-
- lib/rspec/change_to_now/
|
178
|
-
- lib/rspec/change_to_now/
|
177
|
+
- lib/rspec/change_to_now/matchers.rb
|
178
|
+
- lib/rspec/change_to_now/matchers/as_matcher.rb
|
179
|
+
- lib/rspec/change_to_now/matchers/detect.rb
|
180
|
+
- lib/rspec/change_to_now/matchers/dsl.rb
|
181
|
+
- lib/rspec/change_to_now/matchers/matcher_only.rb
|
182
|
+
- lib/rspec/change_to_now/matchers/negate.rb
|
179
183
|
- lib/rspec/change_to_now/version.rb
|
180
184
|
- rspec-change_to_now.gemspec
|
181
185
|
- script/test_all
|
182
186
|
- spec/rspec/change_to_now_spec.rb
|
183
|
-
- spec/rspec/
|
184
|
-
- spec/rspec/
|
185
|
-
- spec/rspec/
|
187
|
+
- spec/rspec/matchers/as_matcher_spec.rb
|
188
|
+
- spec/rspec/matchers/detect_spec.rb
|
189
|
+
- spec/rspec/matchers/matcher_only_spec.rb
|
190
|
+
- spec/rspec/matchers/negate_spec.rb
|
191
|
+
- spec/rspec/matchers/spec_helper.rb
|
186
192
|
- spec/spec_helper.rb
|
187
193
|
- spec/support/matchers.rb
|
188
194
|
homepage: https://github.com/dontfidget/rspec-change_to_now
|
@@ -212,13 +218,16 @@ summary: Provides "change_to_now" method formally part of rspec-core
|
|
212
218
|
test_files:
|
213
219
|
- features/change_to_now.feature
|
214
220
|
- features/detect.feature
|
221
|
+
- features/matcher_only.feature
|
215
222
|
- features/negate.feature
|
216
223
|
- features/step_definitions/additional_cli_steps.rb
|
217
224
|
- features/support/env.rb
|
218
225
|
- spec/rspec/change_to_now_spec.rb
|
219
|
-
- spec/rspec/
|
220
|
-
- spec/rspec/
|
221
|
-
- spec/rspec/
|
226
|
+
- spec/rspec/matchers/as_matcher_spec.rb
|
227
|
+
- spec/rspec/matchers/detect_spec.rb
|
228
|
+
- spec/rspec/matchers/matcher_only_spec.rb
|
229
|
+
- spec/rspec/matchers/negate_spec.rb
|
230
|
+
- spec/rspec/matchers/spec_helper.rb
|
222
231
|
- spec/spec_helper.rb
|
223
232
|
- spec/support/matchers.rb
|
224
233
|
has_rdoc:
|