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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8e18de5f1c633f028730dd7600213ac9aa54f21
4
- data.tar.gz: 169e4f56eb8ace773989ca34e3a6bd101fd3b5bf
3
+ metadata.gz: 4eeffda32467a4dac65939c732f0f24e05343929
4
+ data.tar.gz: eff76f6f8b2df43792b0002901c4d9b01573208a
5
5
  SHA512:
6
- metadata.gz: 9d2aa3673096f3e9c1d5df8ecf08f1e27aa9661265be953b56d12eedbd1d154235166ec55c1c9acef28fa302c37ef5b36ef419d82cd2814113a0dade8d3eaac3
7
- data.tar.gz: f3da15d21ad66436057d4aa174546a8450d68825c9d0b145770c99b3ba8226138c2fdff3abe33d986a50be11f3216bdd7c359b4352d4d605fbe820512e5026be
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 = 1 }.to change { @x }.to_now eq 1
10
+ expect { @x -= [1] }.to change { @x }.not_to include 1
11
11
  ```
12
12
 
13
- or
13
+ Conversely, an example like this, which passes on rspec 3.0, would fail:
14
14
 
15
15
  ```ruby
16
- expect { @x = 1 }.to change { @x }.not_to eq 2
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
- ## Overriding default RSpec behavior
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::Matchers::ChangeToNow.override_to = true
34
+ RSpec::ChangeToNow.override_to = true
32
35
  ```
33
36
 
34
-
35
37
  ## Testing without preconditions
36
38
 
37
- There are a couple of ways to prevent precondition checks if you don't want them for a particular expectation:
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()` adds expectation of pre- and post-conditions for a change, but it is restricted only to object values. With `to_now`, you can write
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
- ## Additional Matchers Provided
104
+ Finally, *change_to_now* causes inferred pre-condition tests, to be explicitly reported. For example,
103
105
 
104
- This gem also provides some additional matchers as detailed below.
106
+ ```ruby
107
+ number = 2
108
+ expect {
109
+ number += 1
110
+ }.to change { number }.to_now 2
111
+ ```
105
112
 
106
- ### `negate(&block)`
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
- This gem also introduces the `negate` matcher, which negates an existing matcher. You can use it like so:
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
- expect(1).to negate(ne(1))
124
+ # spec_helper.rb
125
+ RSpec.configure { |c|.include RSpec::ChangeToNow::Matchers::DSL }
113
126
  ```
114
127
 
115
- 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).
128
+ * `negate(&block)` *(optional)*
116
129
 
117
- ### `detect(&block)`
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
- ```ruby
123
- list = []
124
- expect { list << 2 }.to change { list }.to detect(&:even?)
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
- This is the same as:
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
- ```ruby
130
- list = []
131
- expect { list << 2 }.to change { list }.to include satisfy(&:even?)
132
- ```
168
+ * `matcher_only(matcher)` *(optional)*
133
169
 
134
- A more interesting use might be:
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
- person = Person.create(name: 'Taylor')
138
- expect { person.siblings.create(name: 'Sam') }.to change {
139
- Person.all
140
- }.to_now detect { |person|
141
- person.name == 'Taylor'
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
- `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.
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::Matchers::ChangeToNow.override_to = true
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"
@@ -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
- return false if has_both_block_and_arguments?
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 an error if the matcher is not a matcher.
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 VerifyArgumentIsMatcher < MatcherDelegator
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, "expects a matcher as an argument but got: #{base_matcher.inspect}" unless Matchers.is_a_matcher?(base_matcher)
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
@@ -0,0 +1,6 @@
1
+ require 'rspec/change_to_now/matchers/detect'
2
+ require 'rspec/change_to_now/matchers/negate'
3
+ require 'rspec/change_to_now/matchers/matcher_only'
4
+ require 'rspec/change_to_now/matchers/as_matcher'
5
+ require 'rspec/change_to_now/matchers/dsl'
6
+
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module ChangeToNow
3
- VERSION = "1.1.0"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
@@ -1,115 +1,103 @@
1
1
  require 'rspec/change_to_now/version'
2
- require 'rspec/change_to_now/detect'
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::Matchers
9
- module ChangeToNowMatchers
10
- private
11
-
12
- # @private
13
- def negate(matcher)
14
- RSpec::Matchers::Negate.new(matcher)
15
- end
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
- # @private
18
- def verify_argument_is_matcher(matcher)
19
- RSpec::Matchers::VerifyArgumentIsMatcher.new(matcher)
20
- end
21
- end
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
- class BuiltIn::Change
24
- include ChangeToNowMatchers
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
- # @api public
43
- # Passes if +matcher+ passes on the result of the change block before the expectation block and fails after.
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
- # @api public
53
- alias_method :now_to, :to_now
43
+ # @api public
44
+ alias_method :not_now_to, :not_to_now
54
45
 
55
- # @api public
56
- alias_method :not_to, :not_to_now
46
+ # @api public
47
+ alias_method :to_not, :not_to_now
57
48
 
58
- # @api public
59
- alias_method :not_now_to, :not_to_now
49
+ # @api public
50
+ alias_method :to_not_now, :not_to_now
60
51
 
61
- # @api public
62
- alias_method :to_not, :not_to_now
52
+ # @private
53
+ alias_method :to_without_to_now, :to
63
54
 
64
- # @api public
65
- alias_method :to_not_now, :not_to_now
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
- # @private
68
- alias_method :to_without_to_now, :to
64
+ # @private
65
+ alias_method :to, :to_with_to_now
69
66
 
70
- # @private
71
- def to_with_to_now(expected)
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
- # @private
80
- alias_method :to, :to_with_to_now
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
- def to_now(matcher)
92
- RSpec::Matchers::BuiltIn::ChangeToValue.new(
93
- @change_details,
94
- verify_argument_is_matcher(matcher)
95
- ).from(@expected_before)
96
- end
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
- def not_to_now(matcher)
99
- RSpec::Matchers::BuiltIn::ChangeToValue.new(
100
- @change_details,
101
- negate(verify_argument_is_matcher(matcher))
102
- ).from(@expected_before)
103
- end
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
- def with_final_result(expected)
106
- to_without_to_now(expected)
90
+ def with_final_result(expected)
91
+ to_without_to_now(expected)
92
+ end
107
93
  end
108
94
  end
109
95
 
110
- class ChangeToNow
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 "raises an error when not passed a matcher" do
41
- number = 1
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 raise_error SyntaxError, /expects a matcher as an argument/
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 "raises an error when not passed a matcher" do
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 raise_error SyntaxError, /expects a matcher as an argument/
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::Matchers::ChangeToNow).to receive(:override_to).and_return(true)
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 '../spec_helper'
1
+ require_relative 'spec_helper'
2
2
 
3
- RSpec.describe "#detect matcher" do
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 fail_matching(%Q{can take arguments or a block but not both})
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 fail_matching(%Q{can take arguments or a block but not both})
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 '../spec_helper'
1
+ require_relative 'spec_helper'
2
2
 
3
- describe RSpec::Matchers::VerifyArgumentIsMatcher do
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 RSpec::Matchers::VerifyArgumentIsMatcher.new(eq 2)
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 RSpec::Matchers::VerifyArgumentIsMatcher.new(2)
16
- }.to raise_error SyntaxError, "expects a matcher as an argument but got: 2"
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 '../spec_helper'
1
+ require_relative 'spec_helper'
2
2
 
3
- RSpec.describe RSpec::Matchers::Negate do
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
@@ -17,4 +17,5 @@ end
17
17
  RSpec.configure do |config|
18
18
  config.run_all_when_everything_filtered = true
19
19
  config.order = 'random'
20
+ config.include RSpec::ChangeToNow::Matchers::DSL
20
21
  end
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.1.0
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/detect.rb
177
- - lib/rspec/change_to_now/negate.rb
178
- - lib/rspec/change_to_now/verify_argument_is_matcher.rb
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/detect_spec.rb
184
- - spec/rspec/negate_spec.rb
185
- - spec/rspec/verify_argument_is_matcher_spec.rb
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/detect_spec.rb
220
- - spec/rspec/negate_spec.rb
221
- - spec/rspec/verify_argument_is_matcher_spec.rb
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: