rspec-expectations 2.99.2 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +14 -6
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/Changelog.md +63 -104
  5. data/License.txt +1 -0
  6. data/README.md +14 -8
  7. data/features/README.md +1 -2
  8. data/features/built_in_matchers/README.md +3 -0
  9. data/features/built_in_matchers/be.feature +44 -44
  10. data/features/built_in_matchers/be_within.feature +1 -1
  11. data/features/built_in_matchers/comparisons.feature +97 -0
  12. data/features/built_in_matchers/cover.feature +3 -3
  13. data/features/built_in_matchers/end_with.feature +3 -3
  14. data/features/built_in_matchers/equality.feature +20 -23
  15. data/features/built_in_matchers/exist.feature +5 -5
  16. data/features/built_in_matchers/expect_error.feature +14 -14
  17. data/features/built_in_matchers/include.feature +15 -15
  18. data/features/built_in_matchers/match.feature +4 -5
  19. data/features/built_in_matchers/match_array.feature +37 -0
  20. data/features/built_in_matchers/predicates.feature +30 -6
  21. data/features/built_in_matchers/respond_to.feature +4 -4
  22. data/features/built_in_matchers/satisfy.feature +2 -2
  23. data/features/built_in_matchers/start_with.feature +3 -3
  24. data/features/built_in_matchers/types.feature +6 -6
  25. data/features/custom_matchers/access_running_example.feature +3 -3
  26. data/features/custom_matchers/define_matcher.feature +6 -34
  27. data/features/custom_matchers/define_matcher_outside_rspec.feature +2 -2
  28. data/features/custom_matchers/define_matcher_with_fluent_interface.feature +1 -1
  29. data/features/customized_message.feature +18 -1
  30. data/features/diffing.feature +3 -3
  31. data/features/implicit_docstrings.feature +9 -9
  32. data/features/step_definitions/additional_cli_steps.rb +0 -10
  33. data/features/support/env.rb +10 -3
  34. data/features/test_frameworks/test_unit.feature +0 -40
  35. data/lib/rspec-expectations.rb +0 -5
  36. data/lib/rspec/expectations.rb +4 -18
  37. data/lib/rspec/expectations/expectation_target.rb +10 -77
  38. data/lib/rspec/expectations/extensions.rb +0 -1
  39. data/lib/rspec/expectations/handler.rb +1 -5
  40. data/lib/rspec/expectations/syntax.rb +25 -5
  41. data/lib/rspec/expectations/version.rb +1 -1
  42. data/lib/rspec/matchers.rb +7 -102
  43. data/lib/rspec/matchers/built_in/base_matcher.rb +10 -17
  44. data/lib/rspec/matchers/built_in/be.rb +5 -18
  45. data/lib/rspec/matchers/built_in/be_within.rb +2 -8
  46. data/lib/rspec/matchers/built_in/change.rb +1 -39
  47. data/lib/rspec/matchers/built_in/has.rb +7 -40
  48. data/lib/rspec/matchers/built_in/include.rb +1 -1
  49. data/lib/rspec/matchers/built_in/match_array.rb +1 -1
  50. data/lib/rspec/matchers/built_in/raise_error.rb +44 -23
  51. data/lib/rspec/matchers/built_in/respond_to.rb +1 -7
  52. data/lib/rspec/matchers/built_in/satisfy.rb +1 -7
  53. data/lib/rspec/matchers/built_in/throw_symbol.rb +2 -10
  54. data/lib/rspec/matchers/built_in/yield.rb +4 -25
  55. data/lib/rspec/matchers/compatibility.rb +2 -2
  56. data/lib/rspec/{expectations → matchers}/configuration.rb +9 -6
  57. data/lib/rspec/matchers/dsl.rb +2 -4
  58. data/lib/rspec/matchers/matcher.rb +163 -283
  59. data/lib/rspec/matchers/operator_matcher.rb +57 -71
  60. data/lib/rspec/matchers/pretty.rb +0 -4
  61. data/lib/rspec/matchers/test_unit_integration.rb +5 -22
  62. data/spec/rspec/expectations/expectation_target_spec.rb +0 -62
  63. data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -4
  64. data/spec/rspec/expectations_spec.rb +2 -43
  65. data/spec/rspec/matchers/base_matcher_spec.rb +12 -27
  66. data/spec/rspec/matchers/be_spec.rb +2 -71
  67. data/spec/rspec/matchers/change_spec.rb +1 -76
  68. data/spec/rspec/{expectations → matchers}/configuration_spec.rb +41 -21
  69. data/spec/rspec/matchers/description_generation_spec.rb +2 -21
  70. data/spec/rspec/matchers/equal_spec.rb +0 -26
  71. data/spec/rspec/matchers/has_spec.rb +0 -24
  72. data/spec/rspec/matchers/match_array_spec.rb +0 -13
  73. data/spec/rspec/matchers/matcher_spec.rb +325 -279
  74. data/spec/rspec/matchers/matchers_spec.rb +36 -0
  75. data/spec/rspec/matchers/operator_matcher_spec.rb +8 -27
  76. data/spec/rspec/matchers/raise_error_spec.rb +65 -209
  77. data/spec/rspec/matchers/yield_spec.rb +32 -9
  78. data/spec/spec_helper.rb +21 -6
  79. data/spec/support/classes.rb +7 -7
  80. data/spec/support/in_sub_process.rb +7 -8
  81. data/spec/support/shared_examples.rb +0 -42
  82. metadata +113 -84
  83. metadata.gz.sig +4 -0
  84. data/features/built_in_matchers/have.feature +0 -109
  85. data/features/built_in_matchers/operators.feature +0 -227
  86. data/lib/rspec/expectations/caller_filter.rb +0 -60
  87. data/lib/rspec/expectations/deprecation.rb +0 -27
  88. data/lib/rspec/expectations/extensions/array.rb +0 -9
  89. data/lib/rspec/matchers/be_close.rb +0 -12
  90. data/lib/rspec/matchers/built_in/have.rb +0 -273
  91. data/lib/rspec/matchers/differentiate_block_method_types.rb +0 -55
  92. data/lib/rspec/matchers/extensions/instance_eval_with_args.rb +0 -39
  93. data/lib/rspec/matchers/match_aliases.rb +0 -22
  94. data/spec/rspec/matchers/be_close_spec.rb +0 -25
  95. data/spec/rspec/matchers/differentiate_block_method_types_spec.rb +0 -39
  96. data/spec/rspec/matchers/have_spec.rb +0 -853
  97. data/spec/rspec/matchers/pretty_spec.rb +0 -23
  98. data/spec/support/helper_methods.rb +0 -42
@@ -193,8 +193,7 @@ end
193
193
 
194
194
  describe "expect { ... }.to change { block }" do
195
195
  o = SomethingExpected.new
196
- o.some_value = 1
197
- it_behaves_like "an RSpec matcher", :valid_value => lambda { o.some_value += 1 },
196
+ it_behaves_like "an RSpec matcher", :valid_value => lambda { o.some_value = 5 },
198
197
  :invalid_value => lambda { } do
199
198
  let(:matcher) { change { o.some_value } }
200
199
  end
@@ -248,80 +247,6 @@ describe "expect { ... }.not_to change { block }" do
248
247
  end
249
248
  end
250
249
 
251
- describe "expect { ... }.not_to change { }.from" do
252
- context 'when the value starts at the from value' do
253
- it 'passes when the value does not change' do
254
- k = 5
255
- expect { }.not_to change { k }.from(5)
256
- end
257
-
258
- it 'fails when the value does change' do
259
- expect {
260
- k = 5
261
- expect { k += 1 }.not_to change { k }.from(5)
262
- }.to fail_with(/but did change from 5 to 6/)
263
- end
264
-
265
- it 'does not issue a deprecation warning' do
266
- expect(RSpec.configuration.reporter).not_to receive(:deprecation)
267
- k = 5
268
- expect { }.not_to change { k }.from(5)
269
- end
270
- end
271
-
272
- context 'when the value starts at a different value' do
273
- before { allow_deprecation }
274
-
275
- it 'passes when the value does not change' do
276
- k = 6
277
- expect { }.not_to change { k }.from(5)
278
- end
279
-
280
- it 'passes when the value does change' do
281
- k = 6
282
- expect { k += 1 }.not_to change { k }.from(5)
283
- end
284
-
285
- it 'issues a deprecation warning' do
286
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 2, /#{Regexp.escape("expect { }.not_to change { }.from()")}/)
287
- k = 6
288
- expect { }.not_to change { k }.from(5)
289
- end
290
- end
291
- end
292
-
293
- describe "expect { ... }.not_to change { }.to" do
294
- it 'issues a deprecation warning' do
295
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /#{Regexp.escape("expect { }.not_to change { }.to()")}/)
296
- expect {
297
- }.not_to change { }.to(3)
298
- end
299
- end
300
-
301
- describe "expect { ... }.not_to change { }.by" do
302
- it 'issues a deprecation warning' do
303
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /#{Regexp.escape("expect { }.not_to change { }.by()")}/)
304
- expect {
305
- }.not_to change { }.by(3)
306
- end
307
- end
308
-
309
- describe "expect { ... }.not_to change { }.by_at_least" do
310
- it 'issues a deprecation warning' do
311
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /#{Regexp.escape("expect { }.not_to change { }.by_at_least()")}/)
312
- expect {
313
- }.not_to change { }.by_at_least(3)
314
- end
315
- end
316
-
317
- describe "expect { ... }.not_to change { }.by_at_most" do
318
- it 'issues a deprecation warning' do
319
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /#{Regexp.escape("expect { }.not_to change { }.by_at_most()")}/)
320
- expect {
321
- }.not_to change { }.by_at_most(3)
322
- end
323
- end
324
-
325
250
  describe "expect { ... }.to change(actual, message).by(expected)" do
326
251
  before(:each) do
327
252
  @instance = SomethingExpected.new
@@ -2,10 +2,10 @@ require 'spec_helper'
2
2
  require 'delegate'
3
3
 
4
4
  module RSpec
5
- module Expectations
5
+ module Matchers
6
6
  describe "RSpec::Matchers.configuration" do
7
7
  it 'returns a memoized configuration instance' do
8
- expect(RSpec::Matchers.configuration).to be_a(RSpec::Expectations::Configuration)
8
+ expect(RSpec::Matchers.configuration).to be_a(RSpec::Matchers::Configuration)
9
9
  expect(RSpec::Matchers.configuration).to be(RSpec::Matchers.configuration)
10
10
  end
11
11
  end
@@ -13,25 +13,6 @@ module RSpec
13
13
  describe Configuration do
14
14
  let(:config) { Configuration.new }
15
15
 
16
- context "when accessing it using the old 2.x const name" do
17
- it 'returns the new constant' do
18
- allow_deprecation
19
- expect(RSpec::Matchers::Configuration).to be(RSpec::Expectations::Configuration)
20
- end
21
-
22
- it 'issues a deprecation warning' do
23
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /RSpec::Matchers::Configuration/)
24
- RSpec::Matchers::Configuration
25
- end
26
-
27
- it 'allows other undefined constant to raise errors like normal' do
28
- expect_no_deprecation
29
- expect {
30
- RSpec::Matchers::FooBarBazz
31
- }.to raise_error(NameError, /RSpec::Matchers::FooBarBazz/)
32
- end
33
- end
34
-
35
16
  describe "#backtrace_formatter" do
36
17
  let(:original_backtrace) { %w[ clean-me/a.rb other/file.rb clean-me/b.rb ] }
37
18
  let(:cleaned_backtrace) { %w[ other/file.rb ] }
@@ -42,11 +23,14 @@ module RSpec
42
23
 
43
24
  before do
44
25
  @old_patterns = RSpec.configuration.backtrace_exclusion_patterns
26
+ @orig_full_backtrace = RSpec.configuration.full_backtrace?
27
+ RSpec.configuration.full_backtrace = false
45
28
  RSpec.configuration.backtrace_exclusion_patterns = [/clean-me/]
46
29
  end
47
30
 
48
31
  after do
49
32
  RSpec.configuration.backtrace_exclusion_patterns = @old_patterns
33
+ RSpec.configuration.full_backtrace = @orig_full_backtrace
50
34
  end
51
35
 
52
36
  it "defaults to rspec-core's backtrace formatter when rspec-core is loaded" do
@@ -124,6 +108,37 @@ module RSpec
124
108
  configure_syntax :expect
125
109
  end
126
110
 
111
+ describe "`:should` being enabled by default deprecation" do
112
+ before { configure_default_syntax }
113
+
114
+ it "warns when the should syntax is called by default" do
115
+ expected_arguments = [
116
+ /Using.*without explicitly enabling/,
117
+ {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"}
118
+ ]
119
+
120
+ expect(RSpec).to receive(:deprecate).with(*expected_arguments)
121
+ 3.should eq(3)
122
+ end
123
+
124
+ it "includes the call site in the deprecation warning by default" do
125
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
126
+ 3.should eq(3)
127
+ end
128
+
129
+ it "does not warn when only the should syntax is explicitly configured" do
130
+ configure_syntax(:should)
131
+ RSpec.should_not_receive(:deprecate)
132
+ 3.should eq(3)
133
+ end
134
+
135
+ it "does not warn when both the should and expect syntaxes are explicitly configured" do
136
+ configure_syntax([:should, :expect])
137
+ expect(RSpec).not_to receive(:deprecate)
138
+ 3.should eq(3)
139
+ end
140
+ end
141
+
127
142
  it 'can re-enable the :should syntax' do
128
143
  configure_syntax :expect
129
144
  configure_syntax [:should, :expect]
@@ -179,6 +194,10 @@ module RSpec
179
194
  end
180
195
  end
181
196
 
197
+ def configure_default_syntax
198
+ RSpec::Matchers.configuration.reset_syntaxes_to_default
199
+ end
200
+
182
201
  describe "configuring rspec-expectations directly" do
183
202
  it_behaves_like "configuring the expectation syntax" do
184
203
  def configure_syntax(syntax)
@@ -201,6 +220,7 @@ module RSpec
201
220
  end
202
221
  end
203
222
 
223
+
204
224
  def configured_syntax
205
225
  RSpec.configure do |rspec|
206
226
  rspec.expect_with :rspec do |c|
@@ -92,25 +92,6 @@ describe "Matchers should be able to generate their own descriptions" do
92
92
  expect(RSpec::Matchers.generated_description).to eq 'should have taste for "wine", "cheese"'
93
93
  end
94
94
 
95
- context "the deprecated collection cardinality matchers" do
96
- before { allow_deprecation }
97
-
98
- it "expect(...).to have n items" do
99
- expect(team).to have(3).players
100
- expect(RSpec::Matchers.generated_description).to eq "should have 3 players"
101
- end
102
-
103
- it "expect(...).to have at least n items" do
104
- expect(team).to have_at_least(2).players
105
- expect(RSpec::Matchers.generated_description).to eq "should have at least 2 players"
106
- end
107
-
108
- it "expect(...).to have at most n items" do
109
- expect(team).to have_at_most(4).players
110
- expect(RSpec::Matchers.generated_description).to eq "should have at most 4 players"
111
- end
112
- end
113
-
114
95
  it "expect(...).to include(x)" do
115
96
  expect([1,2,3]).to include(3)
116
97
  expect(RSpec::Matchers.generated_description).to eq "should include 3"
@@ -130,9 +111,9 @@ describe "Matchers should be able to generate their own descriptions" do
130
111
  expect(RSpec::Matchers.generated_description).to eq "should include description"
131
112
  end
132
113
 
133
- it "expect(array).not_to match_array [1,2,3]" do
114
+ it "expect(array).to match_array [1,2,3]" do
134
115
  expect([1,2,3]).to match_array [1,2,3]
135
- expect(RSpec::Matchers.generated_description).to eq "should contain exactly 1, 2, and 3"
116
+ expect(RSpec::Matchers.generated_description).to eq "should contain exactly 1, 2 and 3"
136
117
  end
137
118
 
138
119
  it "expect(...).to match" do
@@ -24,32 +24,6 @@ module RSpec
24
24
  expect(matcher.description).to eq "equal 1"
25
25
  end
26
26
 
27
- context "when the expected object is falsey in conditinal semantics" do
28
- it "describes itself with the expected object" do
29
- matcher = equal(nil)
30
- matcher.matches?(nil)
31
- expect(matcher.description).to eq "equal nil"
32
- end
33
- end
34
-
35
- context "when the expected object's #equal? always returns true" do
36
- let(:strange_string) do
37
- string = "foo"
38
-
39
- def string.equal?(other)
40
- true
41
- end
42
-
43
- string
44
- end
45
-
46
- it "describes itself with the expected object" do
47
- matcher = equal(strange_string)
48
- matcher.matches?(strange_string)
49
- expect(matcher.description).to eq 'equal "foo"'
50
- end
51
- end
52
-
53
27
  it "suggests the `eq` matcher on failure" do
54
28
  expected, actual = "1", "1"
55
29
  expect {
@@ -48,20 +48,6 @@ describe "expect(...).to have_sym(*args)" do
48
48
  }.to raise_error(NoMethodError)
49
49
  end
50
50
 
51
- it "warns of deprecation if #has_sym?(*args) is private" do
52
- klass = Class.new do
53
- def has_foo?
54
- true
55
- end
56
- private :has_foo?
57
-
58
- # prevents double deprecation
59
- def respond_to?(_); true; end
60
- end
61
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /matching with have_foo on private method/)
62
- expect(klass.new).to have_foo
63
- end
64
-
65
51
  it "reraises an exception thrown in #has_sym?(*args)" do
66
52
  o = Object.new
67
53
  def o.has_sym?(*args)
@@ -71,16 +57,6 @@ describe "expect(...).to have_sym(*args)" do
71
57
  expect(o).to have_sym(:foo)
72
58
  }.to raise_error("Funky exception")
73
59
  end
74
-
75
- it 'warns of deprecation when actual does not respond to #has_sym?' do
76
- foo_class = Class.new do
77
- def method_missing(method)
78
- return true if method == :has_foo?
79
- end
80
- end
81
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /Matching with have_foo on an object that doesn't respond to `has_foo\?`/)
82
- expect(foo_class.new).to have_foo
83
- end
84
60
  end
85
61
 
86
62
  describe "expect(...).not_to have_sym(*args)" do
@@ -47,19 +47,6 @@ describe "should =~ array", :uses_should do
47
47
  array.should =~ array
48
48
  end
49
49
  end
50
-
51
- context "when the array undefines `=~`" do
52
- it 'still works' do
53
- array_klass = Class.new(Array) { undef =~ }
54
- array = array_klass.new([1, 2])
55
-
56
- array.should =~ [1, 2]
57
-
58
- expect {
59
- array.should =~ [0, 1, 2]
60
- }.to fail_with(/expected collection contained/)
61
- end
62
- end
63
50
  end
64
51
 
65
52
  describe "should_not =~ [:with, :multiple, :args]", :uses_should do
@@ -1,15 +1,16 @@
1
+ # encoding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  class UnexpectedError < StandardError; end
4
5
  module MatcherHelperModule
5
6
  def self.included(base)
6
- base.module_eval do
7
+ base.module_exec do
7
8
  def included_method; end
8
9
  end
9
10
  end
10
11
 
11
12
  def self.extended(base)
12
- base.instance_eval do
13
+ base.instance_exec do
13
14
  def extended_method; end
14
15
  end
15
16
  end
@@ -21,6 +22,12 @@ end
21
22
 
22
23
  module RSpec::Matchers::DSL
23
24
  describe Matcher do
25
+ def new_matcher(name, *expected, &block)
26
+ RSpec::Matchers::DSL::Matcher.
27
+ new(name, block, *expected).
28
+ tap { |m| m.matcher_execution_context = self }
29
+ end
30
+
24
31
  it "can be stored aside and used later" do
25
32
  # Supports using rspec-expectation matchers as argument matchers in
26
33
  # rspec-mocks.
@@ -39,10 +46,10 @@ module RSpec::Matchers::DSL
39
46
 
40
47
  context "with an included module" do
41
48
  let(:matcher) do
42
- RSpec::Matchers::DSL::Matcher.new(:be_a_greeting) do
49
+ new_matcher(:be_a_greeting) do
43
50
  include MatcherHelperModule
44
51
  match { |actual| actual == greeting }
45
- end.for_expected
52
+ end
46
53
  end
47
54
 
48
55
  it "has access to the module's methods" do
@@ -58,64 +65,41 @@ module RSpec::Matchers::DSL
58
65
  end
59
66
 
60
67
  it 'allows multiple modules to be included at once' do
61
- m = RSpec::Matchers::DSL::Matcher.new(:multiple_modules) do
68
+ m = new_matcher(:multiple_modules) do
62
69
  include Enumerable, Comparable
63
- end.for_expected
70
+ end
64
71
  expect(m).to be_a(Enumerable)
65
72
  expect(m).to be_a(Comparable)
66
73
  end
67
74
  end
68
75
 
69
- context "matching blocks" do
70
- it 'warns when matching blocks by default' do
71
- matcher = RSpec::Matchers::DSL::Matcher.new(:not_supporting_blocks) do
72
- match { true }
73
- end.for_expected
74
-
75
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 2, /block expectation/)
76
- expect(3).to matcher
77
- expect { 3 }.to matcher
78
- end
79
-
80
- it 'does not when if it declares `supports_block_expectations`' do
81
- matcher = RSpec::Matchers::DSL::Matcher.new(:supporting_blocks) do
82
- match { true }
83
- supports_block_expectations
84
- end.for_expected
85
-
86
- expect_no_deprecation
87
- expect(3).to matcher
88
- expect { 3 }.to matcher
89
- end
90
- end
91
-
92
76
  context "without overrides" do
93
- before(:each) do
94
- @matcher = RSpec::Matchers::DSL::Matcher.new(:be_a_multiple_of) do |multiple|
77
+ let(:matcher) do
78
+ new_matcher(:be_a_multiple_of, 3) do |multiple|
95
79
  match do |actual|
96
80
  actual % multiple == 0
97
81
  end
98
- end.for_expected(3)
82
+ end
99
83
  end
100
84
 
101
85
  it "provides a default description" do
102
- expect(@matcher.description).to eq "be a multiple of 3"
86
+ expect(matcher.description).to eq "be a multiple of 3"
103
87
  end
104
88
 
105
89
  it "provides a default failure message for #should" do
106
- @matcher.matches?(8)
107
- expect(@matcher.failure_message_for_should).to eq "expected 8 to be a multiple of 3"
90
+ matcher.matches?(8)
91
+ expect(matcher.failure_message_for_should).to eq "expected 8 to be a multiple of 3"
108
92
  end
109
93
 
110
94
  it "provides a default failure message for #should_not" do
111
- @matcher.matches?(9)
112
- expect(@matcher.failure_message_for_should_not).to eq "expected 9 not to be a multiple of 3"
95
+ matcher.matches?(9)
96
+ expect(matcher.failure_message_for_should_not).to eq "expected 9 not to be a multiple of 3"
113
97
  end
114
98
  end
115
99
 
116
100
  context "with separate match logic for should and should not" do
117
101
  let(:matcher) do
118
- RSpec::Matchers::DSL::Matcher.new(:to_be_composed_of) do |a, b|
102
+ new_matcher(:to_be_composed_of, 7, 11) do |a, b|
119
103
  match_for_should do |actual|
120
104
  actual == a * b
121
105
  end
@@ -123,7 +107,7 @@ module RSpec::Matchers::DSL
123
107
  match_for_should_not do |actual|
124
108
  actual == a + b
125
109
  end
126
- end.for_expected(7, 11)
110
+ end
127
111
  end
128
112
 
129
113
  it "invokes the match_for_should block for #matches?" do
@@ -140,82 +124,194 @@ module RSpec::Matchers::DSL
140
124
  matcher.does_not_match?(77)
141
125
  expect(matcher.failure_message_for_should_not).to eq "expected 77 not to to be composed of 7 and 11"
142
126
  end
127
+
128
+ it 'can access helper methods from `match_for_should_not`' do
129
+ matcher = new_matcher(:be_foo) do
130
+ def foo
131
+ :foo
132
+ end
133
+
134
+ match_for_should_not do |actual|
135
+ actual != foo
136
+ end
137
+ end
138
+
139
+ expect(matcher.does_not_match?(:bar)).to be true
140
+ end
143
141
  end
144
142
 
145
143
  it "allows helper methods to be defined with #define_method to have access to matcher parameters" do
146
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) do |a, b|
144
+ matcher = new_matcher(:name, 3, 4) do |a, b|
147
145
  define_method(:sum) { a + b }
148
- end.for_expected(3,4)
146
+ end
149
147
 
150
148
  expect(matcher.sum).to eq 7
151
149
  end
152
150
 
153
151
  it "is not diffable by default" do
154
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) {}
152
+ matcher = new_matcher(:name) { }
155
153
  expect(matcher).not_to be_diffable
156
154
  end
157
155
 
158
156
  it "is diffable when told to be" do
159
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) { diffable }.for_expected
157
+ matcher = new_matcher(:name) { diffable }
160
158
  expect(matcher).to be_diffable
161
159
  end
162
160
 
163
- it "provides expected" do
164
- expect_no_deprecation
165
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) {}.for_expected('expected', 'strings')
166
- expect(matcher.expected).to eq %w[expected strings]
167
- end
161
+ it 'does not confuse the diffability of different matchers' do
162
+ # Necessary to guard against a regression that involved
163
+ # using a class variable to store the diffable state,
164
+ # which had the side effect of causing all custom matchers
165
+ # to share that state
166
+ m1 = new_matcher(:m1) { diffable }
167
+ m2 = new_matcher(:m2) { }
168
+ m3 = new_matcher(:m3) { diffable }
168
169
 
169
- it "provides expected as an array" do
170
- expect_no_deprecation
171
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) {}.for_expected('expected string')
172
- expect(matcher.expected_as_array).to eq ['expected string']
170
+ expect(m1).to be_diffable
171
+ expect(m2).not_to be_diffable
172
+ expect(m3).to be_diffable
173
173
  end
174
174
 
175
- it "warns of deprecation about expected when it's a single value" do
176
- expect_deprecation_with_call_site __FILE__, __LINE__ + 2
177
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) {}.for_expected('expected string')
175
+ it "provides expected" do
176
+ matcher = new_matcher(:name, "expected string") { }
178
177
  expect(matcher.expected).to eq ['expected string']
179
178
  end
180
179
 
181
- it "provides actual" do
182
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) do
180
+ it "provides actual when `match` is used" do
181
+ matcher = new_matcher(:name, 'expected string') do
183
182
  match {|actual|}
184
- end.for_expected('expected string')
183
+ end
185
184
 
186
185
  matcher.matches?('actual string')
187
186
 
188
187
  expect(matcher.actual).to eq 'actual string'
189
188
  end
190
189
 
191
- context "wrapping another expectation (should == ...)" do
192
- it "returns true if the wrapped expectation passes" do
193
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) do |expected|
190
+ it "provides actual when the `match` block accepts splat args" do
191
+ matcher = new_matcher(:actual) do
192
+ match { |*actual| actual == [5] }
193
+ end
194
+
195
+ expect(matcher.matches?(5)).to be true
196
+ expect(matcher.matches?(4)).to be false
197
+ end
198
+
199
+ it 'allows an early `return` to be used from a `match` block' do
200
+ matcher = new_matcher(:with_return, 5) do |expected|
201
+ match { |actual| return true if expected == actual }
202
+ end
203
+
204
+ expect(matcher.matches?(5)).to be true
205
+ expect(matcher.matches?(4)).to be_falsey
206
+ end
207
+
208
+ it 'provides actual when `match_unless_raises` is used' do
209
+ matcher = new_matcher(:name, 'expected string') do
210
+ match_unless_raises(SyntaxError) {|actual|}
211
+ end
212
+
213
+ matcher.matches?('actual string')
214
+
215
+ expect(matcher.actual).to eq 'actual string'
216
+ end
217
+
218
+ it 'allows an early `return` to be used from a `match_unless_raises` block' do
219
+ matcher = new_matcher(:with_return) do |expected|
220
+ match_unless_raises(ArgumentError) do |actual|
221
+ return actual if [true, false].include?(actual)
222
+ raise ArgumentError
223
+ end
224
+ end
225
+
226
+ expect(matcher.matches?(true)).to be true
227
+ # It should match even if it returns false, because no error was raised.
228
+ expect(matcher.matches?(false)).to be true
229
+ expect(matcher.matches?(4)).to be_falsey
230
+ end
231
+
232
+ it 'provides actual when `match_for_should_not` is used' do
233
+ matcher = new_matcher(:name, 'expected string') do
234
+ match_for_should_not {|actual|}
235
+ end
236
+
237
+ matcher.does_not_match?('actual string')
238
+
239
+ expect(matcher.actual).to eq 'actual string'
240
+ end
241
+
242
+ it 'allows an early `return` to be used from a `match_for_should_not` block' do
243
+ matcher = new_matcher(:with_return, 5) do |expected|
244
+ match_for_should_not { |actual| return true if expected != actual }
245
+ end
246
+
247
+ expect(matcher.does_not_match?(5)).to be_falsey
248
+ expect(matcher.does_not_match?(4)).to be true
249
+ end
250
+
251
+ context "wrapping another expectation (expect(...).to eq ...)" do
252
+ let(:matcher) do
253
+ new_matcher(:name, "value") do |expected|
194
254
  match do |actual|
195
255
  expect(actual).to eq expected
196
256
  end
197
- end.for_expected('value')
257
+ end
258
+ end
259
+
260
+ it "returns true if the wrapped expectation passes" do
198
261
  expect(matcher.matches?('value')).to be_truthy
199
262
  end
200
263
 
201
264
  it "returns false if the wrapped expectation fails" do
202
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) do |expected|
203
- match do |actual|
204
- expect(actual).to eq expected
205
- end
206
- end.for_expected('value')
207
265
  expect(matcher.matches?('other value')).to be_falsey
208
266
  end
267
+
268
+ it "can use the `include` matcher from a `match` block" do
269
+ RSpec::Matchers.define(:descend_from) do |mod|
270
+ match do |klass|
271
+ expect(klass.ancestors).to include(mod)
272
+ end
273
+ end
274
+
275
+ expect(Fixnum).to descend_from(Object)
276
+ expect(Fixnum).not_to descend_from(Array)
277
+
278
+ expect {
279
+ expect(Fixnum).to descend_from(Array)
280
+ }.to fail_with(/expected Fixnum to descend from Array/)
281
+
282
+ expect {
283
+ expect(Fixnum).not_to descend_from(Object)
284
+ }.to fail_with(/expected Fixnum not to descend from Object/)
285
+ end
286
+
287
+ it "can use the `match` matcher from a `match` block" do
288
+ RSpec::Matchers.define(:be_a_phone_number_string) do
289
+ match do |string|
290
+ expect(string).to match(/\A\d{3}\-\d{3}\-\d{4}\z/)
291
+ end
292
+ end
293
+
294
+ expect("206-123-1234").to be_a_phone_number_string
295
+ expect("foo").not_to be_a_phone_number_string
296
+
297
+ expect {
298
+ expect("foo").to be_a_phone_number_string
299
+ }.to fail_with(/expected "foo" to be a phone number string/)
300
+
301
+ expect {
302
+ expect("206-123-1234").not_to be_a_phone_number_string
303
+ }.to fail_with(/expected "206-123-1234" not to be a phone number string/)
304
+ end
209
305
  end
210
306
 
211
307
  context "with overrides" do
212
- before(:each) do
213
- @matcher = RSpec::Matchers::DSL::Matcher.new(:be_boolean) do |boolean|
308
+ let(:matcher) do
309
+ new_matcher(:be_boolean, true) do |boolean|
214
310
  match do |actual|
215
311
  actual
216
312
  end
217
- description do
218
- "be the boolean #{boolean}"
313
+ description do |actual|
314
+ "be the boolean #{boolean} (actual was #{actual})"
219
315
  end
220
316
  failure_message_for_should do |actual|
221
317
  "expected #{actual} to be the boolean #{boolean}"
@@ -223,108 +319,160 @@ module RSpec::Matchers::DSL
223
319
  failure_message_for_should_not do |actual|
224
320
  "expected #{actual} not to be the boolean #{boolean}"
225
321
  end
226
- end.for_expected(true)
322
+ end
227
323
  end
228
324
 
229
325
  it "does not hide result of match block when true" do
230
- expect(@matcher.matches?(true)).to be_truthy
326
+ expect(matcher.matches?(true)).to be_truthy
231
327
  end
232
328
 
233
329
  it "does not hide result of match block when false" do
234
- expect(@matcher.matches?(false)).to be_falsey
330
+ expect(matcher.matches?(false)).to be_falsey
235
331
  end
236
332
 
237
- it "overrides the description" do
238
- expect(@matcher.description).to eq "be the boolean true"
333
+ it "overrides the description (which yields `actual`)" do
334
+ matcher.matches?(true)
335
+ expect(matcher.description).to eq "be the boolean true (actual was true)"
239
336
  end
240
337
 
241
338
  it "overrides the failure message for #should" do
242
- @matcher.matches?(false)
243
- expect(@matcher.failure_message_for_should).to eq "expected false to be the boolean true"
339
+ matcher.matches?(false)
340
+ expect(matcher.failure_message_for_should).to eq "expected false to be the boolean true"
244
341
  end
245
342
 
246
343
  it "overrides the failure message for #should_not" do
247
- @matcher.matches?(true)
248
- expect(@matcher.failure_message_for_should_not).to eq "expected true not to be the boolean true"
344
+ matcher.matches?(true)
345
+ expect(matcher.failure_message_for_should_not).to eq "expected true not to be the boolean true"
346
+ end
347
+
348
+ it 'can access helper methods from `description`' do
349
+ matcher = new_matcher(:desc) do
350
+ def subdesc() "sub description" end
351
+ description { "Desc (#{subdesc})" }
352
+ end
353
+
354
+ expect(matcher.description).to eq("Desc (sub description)")
355
+ end
356
+
357
+ it 'can access helper methods from `failure_message_for_should`' do
358
+ matcher = new_matcher(:positive_failure_message) do
359
+ def helper() "helper" end
360
+ failure_message_for_should { helper }
361
+ end
362
+
363
+ expect(matcher.failure_message_for_should).to eq("helper")
364
+ end
365
+
366
+ it 'can access helper methods from `failure_message_for_should_not`' do
367
+ matcher = new_matcher(:negative_failure_message) do
368
+ def helper() "helper" end
369
+ failure_message_for_should_not { helper }
370
+ end
371
+
372
+ expect(matcher.failure_message_for_should_not).to eq("helper")
373
+ end
374
+
375
+ it 'can exit early with a `return` from `description` just like in a method' do
376
+ matcher = new_matcher(:desc) do
377
+ description { return "Desc" }
378
+ end
379
+
380
+ expect(matcher.description).to eq("Desc")
381
+ end
382
+
383
+ it 'can exit early with a `return` from `failure_message_for_should` just like in a method' do
384
+ matcher = new_matcher(:positive_failure_message) do
385
+ failure_message_for_should { return "msg" }
386
+ end
387
+
388
+ expect(matcher.failure_message_for_should).to eq("msg")
389
+ end
390
+
391
+ it 'can exit early with a `return` from `failure_message_for_should_not` just like in a method' do
392
+ matcher = new_matcher(:negative_failure_message) do
393
+ failure_message_for_should_not { return "msg" }
394
+ end
395
+
396
+ expect(matcher.failure_message_for_should_not).to eq("msg")
249
397
  end
250
398
  end
251
399
 
252
400
  context "#new" do
253
401
  it "passes matches? arg to match block" do
254
- matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) do
402
+ matcher = new_matcher(:ignore) do
255
403
  match do |actual|
256
404
  actual == 5
257
405
  end
258
- end.for_expected
406
+ end
259
407
  expect(matcher.matches?(5)).to be_truthy
260
408
  end
261
409
 
262
410
  it "exposes arg submitted through #new to matcher block" do
263
- matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) do |expected|
411
+ matcher = new_matcher(:ignore, 4) do |expected|
264
412
  match do |actual|
265
413
  actual > expected
266
414
  end
267
- end.for_expected(4)
415
+ end
268
416
  expect(matcher.matches?(5)).to be_truthy
269
417
  end
270
418
  end
271
419
 
272
420
  context "with no args" do
273
- before(:each) do
274
- @matcher = RSpec::Matchers::DSL::Matcher.new(:matcher_name) do
421
+ let(:matcher) do
422
+ new_matcher(:matcher_name) do
275
423
  match do |actual|
276
424
  actual == 5
277
425
  end
278
- end.for_expected
426
+ end
279
427
  end
280
428
 
281
429
  it "matches" do
282
- expect(@matcher.matches?(5)).to be_truthy
430
+ expect(matcher.matches?(5)).to be_truthy
283
431
  end
284
432
 
285
433
  it "describes" do
286
- expect(@matcher.description).to eq "matcher name"
434
+ expect(matcher.description).to eq "matcher name"
287
435
  end
288
436
  end
289
437
 
290
438
  context "with 1 arg" do
291
- before(:each) do
292
- @matcher = RSpec::Matchers::DSL::Matcher.new(:matcher_name) do |expected|
439
+ let(:matcher) do
440
+ new_matcher(:matcher_name, 1) do |expected|
293
441
  match do |actual|
294
442
  actual == 5 && expected == 1
295
443
  end
296
- end.for_expected(1)
444
+ end
297
445
  end
298
446
 
299
447
  it "matches" do
300
- expect(@matcher.matches?(5)).to be_truthy
448
+ expect(matcher.matches?(5)).to be_truthy
301
449
  end
302
450
 
303
451
  it "describes" do
304
- expect(@matcher.description).to eq "matcher name 1"
452
+ expect(matcher.description).to eq "matcher name 1"
305
453
  end
306
454
  end
307
455
 
308
456
  context "with multiple args" do
309
- before(:each) do
310
- @matcher = RSpec::Matchers::DSL::Matcher.new(:matcher_name) do |a,b,c,d|
457
+ let(:matcher) do
458
+ new_matcher(:matcher_name, 1, 2, 3, 4) do |a, b, c, d|
311
459
  match do |sum|
312
460
  a + b + c + d == sum
313
461
  end
314
- end.for_expected(1,2,3,4)
462
+ end
315
463
  end
316
464
 
317
465
  it "matches" do
318
- expect(@matcher.matches?(10)).to be_truthy
466
+ expect(matcher.matches?(10)).to be_truthy
319
467
  end
320
468
 
321
469
  it "describes" do
322
- expect(@matcher.description).to eq "matcher name 1, 2, 3, and 4"
470
+ expect(matcher.description).to eq "matcher name 1, 2, 3, and 4"
323
471
  end
324
472
  end
325
473
 
326
474
  it "supports helper methods" do
327
- matcher = RSpec::Matchers::DSL::Matcher.new(:be_similar_to) do |sample|
475
+ matcher = new_matcher(:be_similar_to, [1, 2, 3]) do |sample|
328
476
  match do |actual|
329
477
  similar?(sample, actual)
330
478
  end
@@ -332,159 +480,35 @@ module RSpec::Matchers::DSL
332
480
  def similar?(a, b)
333
481
  a.sort == b.sort
334
482
  end
335
- end.for_expected([1,2,3])
483
+ end
336
484
 
337
485
  expect(matcher.matches?([2,3,1])).to be_truthy
338
486
  end
339
487
 
340
488
  it "supports fluent interface" do
341
- matcher = RSpec::Matchers::DSL::Matcher.new(:first_word) do
489
+ matcher = new_matcher(:first_word) do
342
490
  def second_word
343
491
  self
344
492
  end
345
- end.for_expected
493
+ end
346
494
 
347
495
  expect(matcher.second_word).to eq matcher
348
496
  end
349
497
 
350
498
  it "treats method missing normally for undeclared methods" do
351
- matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) { }.for_expected
499
+ matcher = new_matcher(:ignore) { }
352
500
  expect { matcher.non_existent_method }.to raise_error(NoMethodError)
353
501
  end
354
502
 
355
503
  it "has access to other matchers" do
356
- matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) do |expected|
504
+ matcher = new_matcher(:ignore, 3) do |expected|
357
505
  match do |actual|
358
506
  extend RSpec::Matchers
359
507
  expect(actual).to eql(5 + expected)
360
508
  end
361
- end.for_expected(3)
362
-
363
- expect(matcher.matches?(8)).to be_truthy
364
- end
365
-
366
- shared_examples_for "accessing a singleton helper method" do
367
- before { allow_deprecation }
368
-
369
- it 'can access the helper method from `match`' do
370
- expect([2, 3]).to matcher.for_expected(5)
371
- expect([2, 3]).not_to matcher.for_expected(4)
372
- end
373
-
374
- it 'prints a deprecation warning when the helper method is accessed `match`' do
375
- expect(RSpec).to receive(:deprecate).with(/sum_of/, an_instance_of(Hash))
376
- matcher.for_expected(5).matches?([2, 3])
377
- end
378
-
379
- it 'includes the call site in the deprecation warning' do
380
- expect_deprecation_with_call_site(__FILE__, line)
381
- matcher.for_expected(5).matches?([2, 3])
382
- end
383
-
384
- it 'does not print a deprecation warning if the helper method is used as a macro' do
385
- expect(RSpec).not_to receive(:deprecate)
386
- matcher.for_expected(:use_as_macro).matches?([2, 3])
387
509
  end
388
- end
389
510
 
390
- context "when a module of helper methods is extended" do
391
- include_examples "accessing a singleton helper method" do
392
- let(:matcher) do
393
- RSpec::Matchers::DSL::Matcher.new(:sum_to) do |sum|
394
- extend Module.new {
395
- def sum_of(x, y) x + y end
396
- def define_match() match {} end
397
- }
398
-
399
- if sum == :use_as_macro
400
- define_match
401
- else
402
- match { |summands| sum_of(*summands) == sum }
403
- end
404
- end
405
- end
406
- let(:line) { __LINE__ - 4 }
407
- end
408
- end
409
-
410
- context "when a helper method is defined using `self.`" do
411
- include_examples "accessing a singleton helper method" do
412
- let(:matcher) do
413
- RSpec::Matchers::DSL::Matcher.new(:sum_to) do |sum|
414
- def self.sum_of(x, y) x + y end
415
- def self.define_match() match {} end
416
-
417
- if sum == :use_as_macro
418
- define_match
419
- else
420
- match { |summands| sum_of(*summands) == sum }
421
- end
422
- end
423
- end
424
- let(:line) { __LINE__ - 4 }
425
- end
426
- end
427
-
428
- shared_examples_for "accessing an instance helper method" do
429
- before { allow_deprecation }
430
-
431
- it 'can access the helper method from `match`' do
432
- expect([2, 3]).to matcher.for_expected(5)
433
- expect([2, 3]).not_to matcher.for_expected(4)
434
- end
435
-
436
- it 'does not print a deprecation warning when the helper method is accessed from `match`' do
437
- expect(RSpec).not_to receive(:deprecate)
438
- matcher.for_expected(5).matches?([2, 3])
439
- end
440
-
441
- it 'prints a deprecation warning if the helper method is used as a macro' do
442
- expect(RSpec).to receive(:deprecate).with(/define_match/, an_instance_of(Hash))
443
- matcher.for_expected(:use_as_macro).matches?([2, 3])
444
- end
445
-
446
- it 'includes the call site in the deprecation warning' do
447
- expect_deprecation_with_call_site(__FILE__, line)
448
- matcher.for_expected(:use_as_macro).matches?([2, 3])
449
- end
450
- end
451
-
452
- context "when a module of helper methods is included" do
453
- include_examples "accessing an instance helper method" do
454
- let(:matcher) do
455
- RSpec::Matchers::DSL::Matcher.new(:sum_to) do |sum|
456
- include Module.new {
457
- def sum_of(x, y) x + y end
458
- def define_match() match {} end
459
- }
460
-
461
- if sum == :use_as_macro
462
- define_match
463
- else
464
- match { |summands| sum_of(*summands) == sum }
465
- end
466
- end
467
- end
468
- let(:line) { __LINE__ - 6 }
469
- end
470
- end
471
-
472
- context "when a helper method is defined using `def foo`" do
473
- include_examples "accessing an instance helper method" do
474
- let(:matcher) do
475
- RSpec::Matchers::DSL::Matcher.new(:sum_to) do |sum|
476
- def sum_of(x, y) x + y end
477
- def define_match() match {} end
478
-
479
- if sum == :use_as_macro
480
- define_match
481
- else
482
- match { |summands| sum_of(*summands) == sum }
483
- end
484
- end
485
- end
486
- let(:line) { __LINE__ - 6 }
487
- end
511
+ expect(matcher.matches?(8)).to be_truthy
488
512
  end
489
513
 
490
514
  context 'when multiple instances of the same matcher are used in the same example' do
@@ -527,21 +551,19 @@ module RSpec::Matchers::DSL
527
551
 
528
552
  describe "#match_unless_raises" do
529
553
  context "with an assertion" do
530
- let(:mod) do
531
- Module.new do
532
- def assert_equal(a,b)
533
- a == b ? nil : (raise UnexpectedError.new("#{b} does not equal #{a}"))
534
- end
554
+ mod = Module.new do
555
+ def assert_equal(a,b)
556
+ raise UnexpectedError.new("#{b} does not equal #{a}") unless a == b
535
557
  end
536
558
  end
559
+
537
560
  let(:matcher) do
538
- m = mod
539
- RSpec::Matchers::DSL::Matcher.new :equal do |expected|
540
- include m
561
+ new_matcher(:equal, 4) do |expected|
562
+ include mod
541
563
  match_unless_raises UnexpectedError do
542
564
  assert_equal expected, actual
543
565
  end
544
- end.for_expected(4)
566
+ end
545
567
  end
546
568
 
547
569
  context "with passing assertion" do
@@ -564,37 +586,78 @@ module RSpec::Matchers::DSL
564
586
 
565
587
  context "with an unexpected error" do
566
588
  let(:matcher) do
567
- RSpec::Matchers::DSL::Matcher.new :foo do |expected|
589
+ new_matcher(:foo, :bar) do |expected|
568
590
  match_unless_raises SyntaxError do |actual|
569
591
  raise "unexpected exception"
570
592
  end
571
- end.for_expected(:bar)
593
+ end
572
594
  end
573
595
 
574
596
  it "raises the error" do
575
- expect do
597
+ expect {
576
598
  matcher.matches?(:bar)
577
- end.to raise_error("unexpected exception")
599
+ }.to raise_error("unexpected exception")
600
+ end
601
+ end
602
+
603
+ context "without a specified error class" do
604
+ let(:matcher) do
605
+ new_matcher(:foo) do
606
+ match_unless_raises do |actual|
607
+ raise Exception unless actual == 5
608
+ end
609
+ end
610
+ end
611
+
612
+ it 'passes if no error is raised' do
613
+ expect(matcher.matches?(5)).to be true
614
+ end
615
+
616
+ it 'fails if an exception is raised' do
617
+ expect(matcher.matches?(4)).to be false
578
618
  end
579
619
  end
580
620
 
581
621
  end
582
622
 
583
623
  it "can define chainable methods" do
584
- matcher = RSpec::Matchers::DSL::Matcher.new(:name) do
624
+ matcher = new_matcher(:name) do
625
+ chain(:expecting) do |expected_value|
626
+ @expected_value = expected_value
627
+ end
628
+ match { |actual| actual == @expected_value }
629
+ end
630
+
631
+ expect(matcher.expecting('value').matches?('value')).to be_truthy
632
+ expect(matcher.expecting('value').matches?('other value')).to be_falsey
633
+ end
634
+
635
+ it 'can use an early return from a `chain` block' do
636
+ matcher = new_matcher(:name) do
585
637
  chain(:expecting) do |expected_value|
586
638
  @expected_value = expected_value
639
+ return
587
640
  end
588
641
  match { |actual| actual == @expected_value }
589
- end.for_expected
642
+ end
590
643
 
591
644
  expect(matcher.expecting('value').matches?('value')).to be_truthy
592
645
  expect(matcher.expecting('value').matches?('other value')).to be_falsey
593
646
  end
594
647
 
648
+ it 'allows chainable methods to accept blocks' do
649
+ matcher = new_matcher(:name) do
650
+ chain(:for_block) { |&b| @block = b }
651
+ match { |value| @block.call == value }
652
+ end
653
+
654
+ expect(matcher.for_block { 5 }.matches?(5)).to be true
655
+ expect(matcher.for_block { 3 }.matches?(4)).to be false
656
+ end
657
+
595
658
  it "prevents name collisions on chainable methods from different matchers" do
596
- m1 = RSpec::Matchers::DSL::Matcher.new(:m1) { chain(:foo) { raise "foo in m1" } }.for_expected
597
- m2 = RSpec::Matchers::DSL::Matcher.new(:m2) { chain(:foo) { raise "foo in m2" } }.for_expected
659
+ m1 = new_matcher(:m1) { chain(:foo) { raise "foo in m1" } }
660
+ m2 = new_matcher(:m2) { chain(:foo) { raise "foo in m2" } }
598
661
 
599
662
  expect { m1.foo }.to raise_error("foo in m1")
600
663
  expect { m2.foo }.to raise_error("foo in m2")
@@ -614,47 +677,30 @@ module RSpec::Matchers::DSL
614
677
  expect(example).to __access_running_example
615
678
  end
616
679
 
680
+ it 'can get a method object for methods in the running example', :if => (RUBY_VERSION.to_f > 1.8) do
681
+ matcher = new_matcher(:get_method_object) { }
682
+ method = matcher.method(:a_method_in_the_example)
683
+ expect(method.call).to eq("method defined in the example")
684
+ end
685
+
686
+ it 'indicates that it responds to a method from the running example' do
687
+ matcher = new_matcher(:respond_to) { }
688
+ expect(matcher).to respond_to(:a_method_in_the_example)
689
+ expect(matcher).not_to respond_to(:a_method_not_in_the_example)
690
+ end
691
+
617
692
  it "raises NoMethodError for methods not in the running_example" do |example|
618
693
  RSpec::Matchers.define(:__raise_no_method_error) do
619
694
  match do |actual|
620
- a_method_not_in_the_example == "method defined in the example"
695
+ self.a_method_not_in_the_example == "method defined in the example"
621
696
  end
622
697
  end
623
698
 
624
- expect do
699
+ expect {
625
700
  expect(example).to __raise_no_method_error
626
- end.to raise_error(/RSpec::Matchers::DSL::Matcher/)
701
+ }.to raise_error(NoMethodError, /Spec::Matchers::DSL::Matcher __raise_no_method_error/)
627
702
  end
628
703
  end
629
704
 
630
- describe "#matcher_execution_context" do
631
- before { allow_deprecation }
632
-
633
- let(:matcher) do
634
- RSpec::Matchers::DSL::Matcher.new :foo do |expected|
635
- end.for_expected(:bar)
636
- end
637
-
638
- it 'can be set' do
639
- expect {
640
- matcher.matcher_execution_context = :the_context
641
- }.to change(matcher, :matcher_execution_context).to(:the_context)
642
- end
643
-
644
- it 'is the target of method_missing delegation' do
645
- matcher.matcher_execution_context = double(:abcd => "efg")
646
- expect(matcher.abcd).to eq("efg")
647
- end
648
-
649
- specify "the writer is deprecated" do
650
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /matcher_execution_context/)
651
- matcher.matcher_execution_context = :the_context
652
- end
653
-
654
- specify "the reader is deprecated" do
655
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /matcher_execution_context/)
656
- matcher.matcher_execution_context
657
- end
658
- end
659
705
  end
660
706
  end