rspec-expectations 3.0.0.beta2 → 3.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -2
  4. data/.yardopts +0 -1
  5. data/Changelog.md +115 -35
  6. data/README.md +2 -2
  7. data/lib/rspec/expectations.rb +13 -8
  8. data/lib/rspec/{matchers → expectations}/configuration.rb +38 -13
  9. data/lib/rspec/expectations/expectation_target.rb +72 -8
  10. data/lib/rspec/expectations/fail_with.rb +10 -52
  11. data/lib/rspec/expectations/handler.rb +9 -11
  12. data/lib/rspec/expectations/syntax.rb +37 -35
  13. data/lib/rspec/expectations/version.rb +1 -1
  14. data/lib/rspec/matchers.rb +60 -9
  15. data/lib/rspec/matchers/aliased_matcher.rb +6 -0
  16. data/lib/rspec/matchers/built_in.rb +9 -1
  17. data/lib/rspec/matchers/built_in/all.rb +78 -0
  18. data/lib/rspec/matchers/built_in/base_matcher.rb +39 -1
  19. data/lib/rspec/matchers/built_in/be.rb +117 -42
  20. data/lib/rspec/matchers/built_in/be_between.rb +22 -0
  21. data/lib/rspec/matchers/built_in/be_instance_of.rb +11 -3
  22. data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -0
  23. data/lib/rspec/matchers/built_in/be_within.rb +26 -6
  24. data/lib/rspec/matchers/built_in/change.rb +89 -13
  25. data/lib/rspec/matchers/built_in/compound.rb +19 -3
  26. data/lib/rspec/matchers/built_in/contain_exactly.rb +17 -6
  27. data/lib/rspec/matchers/built_in/cover.rb +3 -0
  28. data/lib/rspec/matchers/built_in/eq.rb +20 -5
  29. data/lib/rspec/matchers/built_in/eql.rb +15 -3
  30. data/lib/rspec/matchers/built_in/equal.rb +23 -6
  31. data/lib/rspec/matchers/built_in/exist.rb +74 -10
  32. data/lib/rspec/matchers/built_in/has.rb +58 -3
  33. data/lib/rspec/matchers/built_in/include.rb +16 -1
  34. data/lib/rspec/matchers/built_in/match.rb +14 -4
  35. data/lib/rspec/matchers/built_in/operators.rb +16 -0
  36. data/lib/rspec/matchers/built_in/output.rb +47 -5
  37. data/lib/rspec/matchers/built_in/raise_error.rb +40 -23
  38. data/lib/rspec/matchers/built_in/respond_to.rb +37 -16
  39. data/lib/rspec/matchers/built_in/satisfy.rb +15 -0
  40. data/lib/rspec/matchers/built_in/start_and_end_with.rb +29 -14
  41. data/lib/rspec/matchers/built_in/throw_symbol.rb +32 -3
  42. data/lib/rspec/matchers/built_in/yield.rb +148 -44
  43. data/lib/rspec/matchers/composable.rb +48 -7
  44. data/lib/rspec/matchers/dsl.rb +45 -17
  45. data/lib/rspec/matchers/generated_descriptions.rb +7 -0
  46. data/lib/rspec/matchers/matcher_delegator.rb +6 -2
  47. data/lib/rspec/matchers/pretty.rb +15 -19
  48. metadata +33 -236
  49. metadata.gz.sig +0 -0
  50. data/features/README.md +0 -48
  51. data/features/Upgrade.md +0 -53
  52. data/features/built_in_matchers/README.md +0 -96
  53. data/features/built_in_matchers/be.feature +0 -175
  54. data/features/built_in_matchers/be_within.feature +0 -48
  55. data/features/built_in_matchers/comparisons.feature +0 -97
  56. data/features/built_in_matchers/contain_exactly.feature +0 -46
  57. data/features/built_in_matchers/cover.feature +0 -47
  58. data/features/built_in_matchers/end_with.feature +0 -48
  59. data/features/built_in_matchers/equality.feature +0 -136
  60. data/features/built_in_matchers/exist.feature +0 -45
  61. data/features/built_in_matchers/expect_change.feature +0 -59
  62. data/features/built_in_matchers/expect_error.feature +0 -144
  63. data/features/built_in_matchers/include.feature +0 -126
  64. data/features/built_in_matchers/match.feature +0 -51
  65. data/features/built_in_matchers/output.feature +0 -70
  66. data/features/built_in_matchers/predicates.feature +0 -161
  67. data/features/built_in_matchers/respond_to.feature +0 -84
  68. data/features/built_in_matchers/satisfy.feature +0 -33
  69. data/features/built_in_matchers/start_with.feature +0 -48
  70. data/features/built_in_matchers/throw_symbol.feature +0 -91
  71. data/features/built_in_matchers/types.feature +0 -116
  72. data/features/built_in_matchers/yield.feature +0 -161
  73. data/features/composing_matchers.feature +0 -250
  74. data/features/compound_expectations.feature +0 -45
  75. data/features/custom_matchers/access_running_example.feature +0 -53
  76. data/features/custom_matchers/define_diffable_matcher.feature +0 -27
  77. data/features/custom_matchers/define_matcher.feature +0 -340
  78. data/features/custom_matchers/define_matcher_outside_rspec.feature +0 -34
  79. data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
  80. data/features/customized_message.feature +0 -39
  81. data/features/diffing.feature +0 -85
  82. data/features/implicit_docstrings.feature +0 -52
  83. data/features/step_definitions/additional_cli_steps.rb +0 -22
  84. data/features/support/env.rb +0 -21
  85. data/features/support/rubinius.rb +0 -6
  86. data/features/syntax_configuration.feature +0 -71
  87. data/features/test_frameworks/minitest.feature +0 -44
  88. data/lib/rspec-expectations.rb +0 -1
  89. data/lib/rspec/expectations/diff_presenter.rb +0 -141
  90. data/lib/rspec/expectations/differ.rb +0 -44
  91. data/lib/rspec/expectations/encoded_string.rb +0 -56
  92. data/spec/rspec/expectations/diff_presenter_spec.rb +0 -249
  93. data/spec/rspec/expectations/encoded_string_spec.rb +0 -74
  94. data/spec/rspec/expectations/expectation_target_spec.rb +0 -82
  95. data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
  96. data/spec/rspec/expectations/fail_with_spec.rb +0 -114
  97. data/spec/rspec/expectations/handler_spec.rb +0 -205
  98. data/spec/rspec/expectations/minitest_integration_spec.rb +0 -27
  99. data/spec/rspec/expectations/syntax_spec.rb +0 -89
  100. data/spec/rspec/expectations_spec.rb +0 -12
  101. data/spec/rspec/matchers/aliased_matcher_spec.rb +0 -48
  102. data/spec/rspec/matchers/aliases_spec.rb +0 -449
  103. data/spec/rspec/matchers/built_in/base_matcher_spec.rb +0 -83
  104. data/spec/rspec/matchers/built_in/be_between_spec.rb +0 -159
  105. data/spec/rspec/matchers/built_in/be_instance_of_spec.rb +0 -63
  106. data/spec/rspec/matchers/built_in/be_kind_of_spec.rb +0 -41
  107. data/spec/rspec/matchers/built_in/be_spec.rb +0 -592
  108. data/spec/rspec/matchers/built_in/be_within_spec.rb +0 -141
  109. data/spec/rspec/matchers/built_in/change_spec.rb +0 -808
  110. data/spec/rspec/matchers/built_in/compound_spec.rb +0 -292
  111. data/spec/rspec/matchers/built_in/contain_exactly_spec.rb +0 -441
  112. data/spec/rspec/matchers/built_in/cover_spec.rb +0 -69
  113. data/spec/rspec/matchers/built_in/eq_spec.rb +0 -156
  114. data/spec/rspec/matchers/built_in/eql_spec.rb +0 -41
  115. data/spec/rspec/matchers/built_in/equal_spec.rb +0 -106
  116. data/spec/rspec/matchers/built_in/exist_spec.rb +0 -124
  117. data/spec/rspec/matchers/built_in/has_spec.rb +0 -161
  118. data/spec/rspec/matchers/built_in/include_spec.rb +0 -540
  119. data/spec/rspec/matchers/built_in/match_spec.rb +0 -102
  120. data/spec/rspec/matchers/built_in/operators_spec.rb +0 -252
  121. data/spec/rspec/matchers/built_in/output_spec.rb +0 -165
  122. data/spec/rspec/matchers/built_in/raise_error_spec.rb +0 -461
  123. data/spec/rspec/matchers/built_in/respond_to_spec.rb +0 -292
  124. data/spec/rspec/matchers/built_in/satisfy_spec.rb +0 -44
  125. data/spec/rspec/matchers/built_in/start_and_end_with_spec.rb +0 -253
  126. data/spec/rspec/matchers/built_in/throw_symbol_spec.rb +0 -135
  127. data/spec/rspec/matchers/built_in/yield_spec.rb +0 -627
  128. data/spec/rspec/matchers/configuration_spec.rb +0 -213
  129. data/spec/rspec/matchers/description_generation_spec.rb +0 -191
  130. data/spec/rspec/matchers/dsl_spec.rb +0 -895
  131. data/spec/rspec/matchers/legacy_spec.rb +0 -101
  132. data/spec/rspec/matchers_spec.rb +0 -74
  133. data/spec/spec_helper.rb +0 -85
  134. data/spec/support/matchers.rb +0 -22
  135. data/spec/support/shared_examples.rb +0 -35
@@ -1,213 +0,0 @@
1
- require 'spec_helper'
2
- require 'delegate'
3
-
4
- module RSpec
5
- module Matchers
6
- describe "RSpec::Matchers.configuration" do
7
- it 'returns a memoized configuration instance' do
8
- expect(RSpec::Matchers.configuration).to be_a(RSpec::Matchers::Configuration)
9
- expect(RSpec::Matchers.configuration).to be(RSpec::Matchers.configuration)
10
- end
11
- end
12
-
13
- describe Configuration do
14
- let(:config) { Configuration.new }
15
-
16
- describe "#backtrace_formatter" do
17
- let(:original_backtrace) { %w[ clean-me/a.rb other/file.rb clean-me/b.rb ] }
18
- let(:cleaned_backtrace) { %w[ other/file.rb ] }
19
-
20
- let(:formatted_backtrace) do
21
- config.backtrace_formatter.format_backtrace(original_backtrace)
22
- end
23
-
24
- before do
25
- @old_patterns = RSpec.configuration.backtrace_exclusion_patterns
26
- @orig_full_backtrace = RSpec.configuration.full_backtrace?
27
- RSpec.configuration.full_backtrace = false
28
- RSpec.configuration.backtrace_exclusion_patterns = [/clean-me/]
29
- end
30
-
31
- after do
32
- RSpec.configuration.backtrace_exclusion_patterns = @old_patterns
33
- RSpec.configuration.full_backtrace = @orig_full_backtrace
34
- end
35
-
36
- it "defaults to rspec-core's backtrace formatter when rspec-core is loaded" do
37
- expect(config.backtrace_formatter).to be(RSpec::Core::BacktraceFormatter)
38
- expect(formatted_backtrace).to eq(cleaned_backtrace)
39
- end
40
-
41
- it "defaults to a null formatter when rspec-core is not loaded" do
42
- hide_const("RSpec::Core::BacktraceFormatter")
43
- expect(formatted_backtrace).to eq(original_backtrace)
44
- end
45
-
46
- it "can be set to another backtrace formatter" do
47
- config.backtrace_formatter = double(:format_backtrace => ['a'])
48
- expect(formatted_backtrace).to eq(['a'])
49
- end
50
- end
51
-
52
- context 'on an interpreter that does not provide BasicObject', :uses_should, :unless => defined?(::BasicObject) do
53
- before { RSpec::Expectations::Syntax.disable_should(Delegator) }
54
-
55
- let(:klass) do
56
- Class.new(SimpleDelegator) do
57
- def delegated?; true; end
58
- end
59
- end
60
-
61
- let(:instance) { klass.new(Object.new) }
62
-
63
- it 'provides a means to manually add it Delegator' do
64
- instance.should_not respond_to(:delegated?) # because #should is being delegated...
65
- config.add_should_and_should_not_to Delegator
66
- instance.should respond_to(:delegated?) # now it should work!
67
- end
68
- end
69
-
70
- shared_examples_for "configuring the expectation syntax" do
71
- before do
72
- @orig_syntax = RSpec::Matchers.configuration.syntax
73
- end
74
-
75
- after do
76
- configure_syntax(@orig_syntax)
77
- end
78
-
79
- it 'can limit the syntax to :should' do
80
- configure_syntax :should
81
- configured_syntax.should eq([:should])
82
-
83
- 3.should eq(3)
84
- 3.should_not eq(4)
85
- lambda { expect(6).to eq(6) }.should raise_error(NameError)
86
- end
87
-
88
- it 'is a no-op when configured to :should twice' do
89
- configure_syntax :should
90
- method_added_count = 0
91
- allow(Expectations::Syntax.default_should_host).to receive(:method_added) { method_added_count += 1 }
92
- configure_syntax :should
93
-
94
- method_added_count.should eq(0)
95
- end
96
-
97
- it 'can limit the syntax to :expect' do
98
- configure_syntax :expect
99
- expect(configured_syntax).to eq([:expect])
100
-
101
- expect(3).to eq(3)
102
- expect { 3.should eq(3) }.to raise_error(NameError)
103
- expect { 3.should_not eq(3) }.to raise_error(NameError)
104
- end
105
-
106
- it 'is a no-op when configured to :expect twice' do
107
- allow(RSpec::Matchers).to receive(:method_added).and_raise("no methods should be added here")
108
-
109
- configure_syntax :expect
110
- configure_syntax :expect
111
- end
112
-
113
- describe "`:should` being enabled by default deprecation" do
114
- before { configure_default_syntax }
115
-
116
- it "warns when the should syntax is called by default" do
117
- expected_arguments = [
118
- /Using.*without explicitly enabling/,
119
- {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"}
120
- ]
121
-
122
- expect(RSpec).to receive(:deprecate).with(*expected_arguments)
123
- 3.should eq(3)
124
- end
125
-
126
- it "includes the call site in the deprecation warning by default" do
127
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
128
- 3.should eq(3)
129
- end
130
-
131
- it "does not warn when only the should syntax is explicitly configured" do
132
- configure_syntax(:should)
133
- RSpec.should_not receive(:deprecate)
134
- 3.should eq(3)
135
- end
136
-
137
- it "does not warn when both the should and expect syntaxes are explicitly configured" do
138
- configure_syntax([:should, :expect])
139
- expect(RSpec).not_to receive(:deprecate)
140
- 3.should eq(3)
141
- end
142
- end
143
-
144
- it 'can re-enable the :should syntax' do
145
- configure_syntax :expect
146
- configure_syntax [:should, :expect]
147
- configured_syntax.should eq([:should, :expect])
148
-
149
- 3.should eq(3)
150
- 3.should_not eq(4)
151
- expect(3).to eq(3)
152
- end
153
-
154
- it 'can re-enable the :expect syntax' do
155
- configure_syntax :should
156
- configure_syntax [:should, :expect]
157
- configured_syntax.should eq([:should, :expect])
158
-
159
- 3.should eq(3)
160
- 3.should_not eq(4)
161
- expect(3).to eq(3)
162
- end
163
- end
164
-
165
- def configure_default_syntax
166
- RSpec::Matchers.configuration.reset_syntaxes_to_default
167
- end
168
-
169
- describe "configuring rspec-expectations directly" do
170
- it_behaves_like "configuring the expectation syntax" do
171
- def configure_syntax(syntax)
172
- RSpec::Matchers.configuration.syntax = syntax
173
- end
174
-
175
- def configured_syntax
176
- RSpec::Matchers.configuration.syntax
177
- end
178
- end
179
- end
180
-
181
- describe "configuring using the rspec-core config API" do
182
- it_behaves_like "configuring the expectation syntax" do
183
- def configure_syntax(syntax)
184
- RSpec.configure do |rspec|
185
- rspec.expect_with :rspec do |c|
186
- c.syntax = syntax
187
- end
188
- end
189
- end
190
-
191
-
192
- def configured_syntax
193
- RSpec.configure do |rspec|
194
- rspec.expect_with :rspec do |c|
195
- return c.syntax
196
- end
197
- end
198
- end
199
- end
200
- end
201
-
202
- it 'enables both syntaxes by default' do
203
- # This is kinda a hack, but since we want to enforce use of
204
- # the expect syntax within our specs here, we have modified the
205
- # config setting, which makes it hard to get at the original
206
- # default value. in spec_helper.rb we store the default value
207
- # in $default_expectation_syntax so we can use it here.
208
- expect($default_expectation_syntax).to contain_exactly(:expect, :should)
209
- end
210
- end
211
- end
212
- end
213
-
@@ -1,191 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Matchers should be able to generate their own descriptions" do
4
- after(:each) do
5
- RSpec::Matchers.clear_generated_description
6
- end
7
-
8
- it "expect(...).to eq expected" do
9
- expect("this").to eq "this"
10
- expect(RSpec::Matchers.generated_description).to eq "should eq \"this\""
11
- end
12
-
13
- it "expect(...).to not eq expected" do
14
- expect("this").not_to eq "that"
15
- expect(RSpec::Matchers.generated_description).to eq "should not eq \"that\""
16
- end
17
-
18
- it "expect(...).to be empty (arbitrary predicate)" do
19
- expect([]).to be_empty
20
- expect(RSpec::Matchers.generated_description).to eq "should be empty"
21
- end
22
-
23
- it "expect(...).to not be empty (arbitrary predicate)" do
24
- expect([1]).not_to be_empty
25
- expect(RSpec::Matchers.generated_description).to eq "should not be empty"
26
- end
27
-
28
- it "expect(...).to be truthy" do
29
- expect(true).to be_truthy
30
- expect(RSpec::Matchers.generated_description).to eq "should be truthy"
31
- end
32
-
33
- it "expect(...).to be falsey" do
34
- expect(false).to be_falsey
35
- expect(RSpec::Matchers.generated_description).to eq "should be falsey"
36
- end
37
-
38
- it "expect(...).to be nil" do
39
- expect(nil).to be_nil
40
- expect(RSpec::Matchers.generated_description).to eq "should be nil"
41
- end
42
-
43
- it "expect(...).to be > n" do
44
- expect(5).to be > 3
45
- expect(RSpec::Matchers.generated_description).to eq "should be > 3"
46
- end
47
-
48
- it "expect(...).to be between min and max" do
49
- expect(10).to be_between(0, 10)
50
- expect(RSpec::Matchers.generated_description).to eq "should be between 0 and 10 (inclusive)"
51
- end
52
-
53
- it "expect(...).to be exclusively between min and max" do
54
- expect(9).to be_between(0, 10).exclusive
55
- expect(RSpec::Matchers.generated_description).to eq "should be between 0 and 10 (exclusive)"
56
- end
57
-
58
- it "expect(...).to be predicate arg1, arg2 and arg3" do
59
- class Parent; end
60
- class Child < Parent
61
- def child_of?(*parents)
62
- parents.all? { |parent| self.is_a?(parent) }
63
- end
64
- end
65
- expect(Child.new).to be_a_child_of(Parent, Object)
66
- expect(RSpec::Matchers.generated_description).to eq "should be a child of Parent and Object"
67
- end
68
-
69
- it "expect(...).to equal" do
70
- expected = "expected"
71
- expect(expected).to equal(expected)
72
- expect(RSpec::Matchers.generated_description).to eq "should equal \"expected\""
73
- end
74
-
75
- it "expect(...).not_to equal" do
76
- expect(5).not_to equal(37)
77
- expect(RSpec::Matchers.generated_description).to eq "should not equal 37"
78
- end
79
-
80
- it "expect(...).to eql" do
81
- expect("string").to eql("string")
82
- expect(RSpec::Matchers.generated_description).to eq "should eql \"string\""
83
- end
84
-
85
- it "expect(...).not_to eql" do
86
- expect("a").not_to eql(:a)
87
- expect(RSpec::Matchers.generated_description).to eq "should not eql :a"
88
- end
89
-
90
- it "expect(...).to have_key" do
91
- expect({:a => "a"}).to have_key(:a)
92
- expect(RSpec::Matchers.generated_description).to eq "should have key :a"
93
- end
94
-
95
- it "expect(...).to have_some_method" do
96
- object = Object.new
97
- def object.has_eyes_closed?; true; end
98
-
99
- expect(object).to have_eyes_closed
100
- expect(RSpec::Matchers.generated_description).to eq 'should have eyes closed'
101
- end
102
-
103
- it "expect(...).to have_some_method(args*)" do
104
- object = Object.new
105
- def object.has_taste_for?(*args); true; end
106
-
107
- expect(object).to have_taste_for("wine", "cheese")
108
- expect(RSpec::Matchers.generated_description).to eq 'should have taste for "wine", "cheese"'
109
- end
110
-
111
- it "expect(...).to include(x)" do
112
- expect([1,2,3]).to include(3)
113
- expect(RSpec::Matchers.generated_description).to eq "should include 3"
114
- end
115
-
116
- it "expect(...).to include(x) when x responds to description but is not a matcher" do
117
- obj = double(:description => "description", :inspect => "inspect")
118
- expect([obj]).to include(obj)
119
- expect(RSpec::Matchers.generated_description).to eq "should include inspect"
120
- end
121
-
122
- it "expect(...).to include(x) when x responds to description and is a matcher" do
123
- matcher = double(:description => "description",
124
- :matches? => true,
125
- :failure_message => "")
126
- expect([matcher]).to include(matcher)
127
- expect(RSpec::Matchers.generated_description).to eq "should include (description)"
128
- end
129
-
130
- it "expect(array).to contain_exactly(1, 2, 3)" do
131
- expect([1,2,3]).to contain_exactly(1, 2, 3)
132
- expect(RSpec::Matchers.generated_description).to eq "should contain exactly 1, 2 and 3"
133
- end
134
-
135
- it "expect(...).to match" do
136
- expect("this string").to match(/this string/)
137
- expect(RSpec::Matchers.generated_description).to eq "should match /this string/"
138
- end
139
-
140
- it "expect(...).to raise_error" do
141
- expect { raise }.to raise_error
142
- expect(RSpec::Matchers.generated_description).to eq "should raise Exception"
143
- end
144
-
145
- it "expect(...).to raise_error with type" do
146
- expect { raise }.to raise_error(RuntimeError)
147
- expect(RSpec::Matchers.generated_description).to eq "should raise RuntimeError"
148
- end
149
-
150
- it "expect(...).to raise_error with type and message" do
151
- expect { raise "there was an error" }.to raise_error(RuntimeError, "there was an error")
152
- expect(RSpec::Matchers.generated_description).to eq "should raise RuntimeError with \"there was an error\""
153
- end
154
-
155
- it "expect(...).to respond_to" do
156
- expect([]).to respond_to(:insert)
157
- expect(RSpec::Matchers.generated_description).to eq "should respond to #insert"
158
- end
159
-
160
- it "expect(...).to throw symbol" do
161
- expect { throw :what_a_mess }.to throw_symbol
162
- expect(RSpec::Matchers.generated_description).to eq "should throw a Symbol"
163
- end
164
-
165
- it "expect(...).to throw symbol (with named symbol)" do
166
- expect { throw :what_a_mess }.to throw_symbol(:what_a_mess)
167
- expect(RSpec::Matchers.generated_description).to eq "should throw :what_a_mess"
168
- end
169
-
170
- def team
171
- Class.new do
172
- def players
173
- [1,2,3]
174
- end
175
- end.new
176
- end
177
- end
178
-
179
- describe "a Matcher with no description" do
180
- def matcher
181
- Class.new do
182
- def matches?(ignore); true; end
183
- def failure_message; ""; end
184
- end.new
185
- end
186
-
187
- it "provides a helpful message when used in a string-less example block" do
188
- expect(5).to matcher
189
- expect(RSpec::Matchers.generated_description).to match(/When you call.*description method/m)
190
- end
191
- end
@@ -1,895 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe "a matcher defined using the matcher DSL" do
5
- def question?
6
- :answer
7
- end
8
-
9
- def ok
10
- "ok"
11
- end
12
-
13
- it "supports calling custom matchers from within other custom matchers" do
14
- RSpec::Matchers.define :be_ok do
15
- match { |actual| actual == ok }
16
- end
17
-
18
- RSpec::Matchers.define :be_well do
19
- match { |actual| expect(actual).to be_ok }
20
- end
21
-
22
- expect(ok).to be_well
23
- end
24
-
25
- it "has access to methods available in the scope of the example" do
26
- RSpec::Matchers::define(:matcher_a) {}
27
- expect(matcher_a.question?).to eq(:answer)
28
- end
29
-
30
- it "raises when method is missing from local scope as well as matcher" do
31
- RSpec::Matchers::define(:matcher_b) {}
32
- expect { matcher_b.i_dont_exist }.to raise_error(NameError)
33
- end
34
-
35
- it "clears user instance variables between invocations" do
36
- RSpec::Matchers::define(:be_just_like) do |expected|
37
- match do |actual|
38
- @foo ||= expected
39
- @foo == actual
40
- end
41
- end
42
-
43
- expect(3).to be_just_like(3)
44
- expect(4).to be_just_like(4)
45
- end
46
-
47
- describe "#respond_to?" do
48
- it "returns true for methods in example scope" do
49
- RSpec::Matchers::define(:matcher_c) {}
50
- expect(matcher_c).to respond_to(:question?)
51
- end
52
-
53
- it "returns false for methods not defined in matcher or example scope" do
54
- RSpec::Matchers::define(:matcher_d) {}
55
- expect(matcher_d).not_to respond_to(:i_dont_exist)
56
- end
57
- end
58
- end
59
-
60
- class UnexpectedError < StandardError; end
61
- module MatcherHelperModule
62
- def self.included(base)
63
- base.module_exec do
64
- def included_method; end
65
- end
66
- end
67
-
68
- def self.extended(base)
69
- base.instance_exec do
70
- def extended_method; end
71
- end
72
- end
73
-
74
- def greeting
75
- "Hello, World"
76
- end
77
- end
78
-
79
- module RSpec::Matchers::DSL
80
- describe Matcher do
81
- def new_matcher(name, *expected, &block)
82
- RSpec::Matchers::DSL::Matcher.
83
- new(name, block, *expected).
84
- tap { |m| m.matcher_execution_context = self }
85
- end
86
-
87
- it_behaves_like "an RSpec matcher", :valid_value => 1, :invalid_value => 2 do
88
- let(:matcher) do
89
- new_matcher(:equal_to_1) do
90
- match { |v| v == 1 }
91
- end
92
- end
93
- end
94
-
95
- it "can be stored aside and used later" do
96
- # Supports using rspec-expectation matchers as argument matchers in
97
- # rspec-mocks.
98
- RSpec::Matchers.define :example_matcher do |expected|
99
- match do |actual|
100
- actual == expected
101
- end
102
- end
103
-
104
- m1 = example_matcher(1)
105
- m2 = example_matcher(2)
106
-
107
- expect(m1.matches?(1)).to be_truthy
108
- expect(m2.matches?(2)).to be_truthy
109
- end
110
-
111
- context 'using deprecated APIs' do
112
- before { allow_deprecation }
113
-
114
- describe "failure_message_for_should" do
115
- let(:matcher) do
116
- new_matcher(:foo) do
117
- match { false }
118
- failure_message_for_should { "failed" }
119
- end
120
- end
121
- line = __LINE__ - 3
122
-
123
- it 'defines the failure message for a positive expectation' do
124
- expect {
125
- expect(nil).to matcher
126
- }.to fail_with("failed")
127
- end
128
-
129
- it 'prints a deprecation warning' do
130
- expect_deprecation_with_call_site(__FILE__, line, /failure_message_for_should/)
131
- matcher
132
- end
133
- end
134
-
135
- describe "failure_message_for_should_not" do
136
- let(:matcher) do
137
- new_matcher(:foo) do
138
- match { true }
139
- failure_message_for_should_not { "failed" }
140
- end
141
- end
142
- line = __LINE__ - 3
143
-
144
- it 'defines the failure message for a negative expectation' do
145
- expect {
146
- expect(nil).not_to matcher
147
- }.to fail_with("failed")
148
- end
149
-
150
- it 'prints a deprecation warning' do
151
- expect_deprecation_with_call_site(__FILE__, line, /failure_message_for_should_not/)
152
- matcher
153
- end
154
- end
155
-
156
- describe "match_for_should" do
157
- let(:matcher) do
158
- new_matcher(:foo) do
159
- match_for_should { |arg| arg }
160
- end
161
- end
162
- line = __LINE__ - 3
163
-
164
- it 'defines the positive expectation match logic' do
165
- expect(true).to matcher
166
- expect { expect(false).to matcher }.to fail_with(/foo/)
167
- end
168
-
169
- it 'prints a deprecation warning' do
170
- expect_deprecation_with_call_site(__FILE__, line, /match_for_should/)
171
- matcher
172
- end
173
- end
174
-
175
- describe "match_for_should_not" do
176
- let(:matcher) do
177
- new_matcher(:foo) do
178
- match_for_should_not { |arg| !arg }
179
- end
180
- end
181
- line = __LINE__ - 3
182
-
183
- it 'defines the positive expectation match logic' do
184
- expect(false).not_to matcher
185
- expect { expect(true).not_to matcher }.to fail_with(/foo/)
186
- end
187
-
188
- it 'prints a deprecation warning' do
189
- expect_deprecation_with_call_site(__FILE__, line, /match_for_should_not/)
190
- matcher
191
- end
192
- end
193
- end
194
-
195
- context "with an included module" do
196
- let(:matcher) do
197
- new_matcher(:be_a_greeting) do
198
- include MatcherHelperModule
199
- match { |actual| actual == greeting }
200
- end
201
- end
202
-
203
- it "has access to the module's methods" do
204
- matcher.matches?("Hello, World")
205
- end
206
-
207
- it "runs the module's included hook" do
208
- expect(matcher).to respond_to(:included_method)
209
- end
210
-
211
- it "does not run the module's extended hook" do
212
- expect(matcher).not_to respond_to(:extended_method)
213
- end
214
-
215
- it 'allows multiple modules to be included at once' do
216
- m = new_matcher(:multiple_modules) do
217
- include Enumerable, Comparable
218
- end
219
- expect(m).to be_a(Enumerable)
220
- expect(m).to be_a(Comparable)
221
- end
222
- end
223
-
224
- context "without overrides" do
225
- let(:matcher) do
226
- new_matcher(:be_a_multiple_of, 3) do |multiple|
227
- match do |actual|
228
- actual % multiple == 0
229
- end
230
- end
231
- end
232
-
233
- it "provides a default description" do
234
- expect(matcher.description).to eq "be a multiple of 3"
235
- end
236
-
237
- it "provides a default positive expectation failure message" do
238
- matcher.matches?(8)
239
- expect(matcher.failure_message).to eq "expected 8 to be a multiple of 3"
240
- end
241
-
242
- it "provides a default negative expectation failure message" do
243
- matcher.matches?(9)
244
- expect(matcher.failure_message_when_negated).to eq "expected 9 not to be a multiple of 3"
245
- end
246
- end
247
-
248
- context "with separate match logic for positive and negative expectations" do
249
- let(:matcher) do
250
- new_matcher(:to_be_composed_of, 7, 11) do |a, b|
251
- match do |actual|
252
- actual == a * b
253
- end
254
-
255
- match_when_negated do |actual|
256
- actual == a + b
257
- end
258
- end
259
- end
260
-
261
- it "invokes the match block for #matches?" do
262
- expect(matcher.matches?(77)).to be_truthy
263
- expect(matcher.matches?(18)).to be_falsey
264
- end
265
-
266
- it "invokes the match_when_negated block for #does_not_match?" do
267
- expect(matcher.does_not_match?(77)).to be_falsey
268
- expect(matcher.does_not_match?(18)).to be_truthy
269
- end
270
-
271
- it "provides a default failure message for negative expectations" do
272
- matcher.does_not_match?(77)
273
- expect(matcher.failure_message_when_negated).to eq "expected 77 not to to be composed of 7 and 11"
274
- end
275
-
276
- it 'can access helper methods from `match_when_negated`' do
277
- matcher = new_matcher(:be_foo) do
278
- def foo
279
- :foo
280
- end
281
-
282
- match_when_negated do |actual|
283
- actual != foo
284
- end
285
- end
286
-
287
- expect(matcher.does_not_match?(:bar)).to be true
288
- end
289
- end
290
-
291
- it "allows helper methods to be defined with #define_method to have access to matcher parameters" do
292
- matcher = new_matcher(:name, 3, 4) do |a, b|
293
- define_method(:sum) { a + b }
294
- end
295
-
296
- expect(matcher.sum).to eq 7
297
- end
298
-
299
- it "is not diffable by default" do
300
- matcher = new_matcher(:name) { }
301
- expect(matcher).not_to be_diffable
302
- end
303
-
304
- it "is diffable when told to be" do
305
- matcher = new_matcher(:name) { diffable }
306
- expect(matcher).to be_diffable
307
- end
308
-
309
- it 'handles multiline string diffs' do
310
- actual = "LINE1\nline2\n"
311
- expected = "line1\nline2\n"
312
-
313
- matcher = new_matcher(:custom_match, expected) do
314
- match { |actual| actual == expected }
315
- diffable
316
- end
317
-
318
- diff = nil
319
- begin
320
- allow(RSpec::Matchers.configuration).to receive(:color?).and_return(false)
321
- expect(actual).to matcher
322
- rescue RSpec::Expectations::ExpectationNotMetError => e
323
- diff = e.message.sub(/\A.*Diff:/m, "Diff:").gsub(/^\s*/,'')
324
- end
325
-
326
- expect(diff).to eq "Diff:\n@@ -1,3 +1,3 @@\n-line1\n+LINE1\nline2\n"
327
- end
328
-
329
- it 'does not confuse the diffability of different matchers' do
330
- # Necessary to guard against a regression that involved
331
- # using a class variable to store the diffable state,
332
- # which had the side effect of causing all custom matchers
333
- # to share that state
334
- m1 = new_matcher(:m1) { diffable }
335
- m2 = new_matcher(:m2) { }
336
- m3 = new_matcher(:m3) { diffable }
337
-
338
- expect(m1).to be_diffable
339
- expect(m2).not_to be_diffable
340
- expect(m3).to be_diffable
341
- end
342
-
343
- it "provides expected" do
344
- matcher = new_matcher(:name, "expected string") { }
345
- expect(matcher.expected).to eq 'expected string'
346
- end
347
-
348
- it "provides expected when there is more than one argument" do
349
- matcher = new_matcher(:name, "expected string", "another arg") { }
350
- expect(matcher.expected).to eq ['expected string', "another arg"]
351
- end
352
-
353
- it "provides expected_as_array which returns an array regardless of expected" do
354
- matcher = new_matcher(:name, "expected string") { }
355
- expect(matcher.expected_as_array).to eq ['expected string']
356
- matcher = new_matcher(:name, "expected\nstring") { }
357
- expect(matcher.expected_as_array).to eq ["expected\nstring"]
358
- matcher = new_matcher(:name, "expected string", "another arg") { }
359
- expect(matcher.expected_as_array).to eq ['expected string', "another arg"]
360
- end
361
-
362
- it "provides actual when `match` is used" do
363
- matcher = new_matcher(:name, 'expected string') do
364
- match {|actual|}
365
- end
366
-
367
- matcher.matches?('actual string')
368
-
369
- expect(matcher.actual).to eq 'actual string'
370
- end
371
-
372
- it "provides actual when the `match` block accepts splat args" do
373
- matcher = new_matcher(:actual) do
374
- match { |*actual| actual == [5] }
375
- end
376
-
377
- expect(matcher.matches?(5)).to be true
378
- expect(matcher.matches?(4)).to be false
379
- end
380
-
381
- it 'allows an early `return` to be used from a `match` block' do
382
- matcher = new_matcher(:with_return, 5) do |expected|
383
- match { |actual| return true if expected == actual }
384
- end
385
-
386
- expect(matcher.matches?(5)).to be true
387
- expect(matcher.matches?(4)).to be_falsey
388
- end
389
-
390
- it 'provides actual when `match_unless_raises` is used' do
391
- matcher = new_matcher(:name, 'expected string') do
392
- match_unless_raises(SyntaxError) {|actual|}
393
- end
394
-
395
- matcher.matches?('actual string')
396
-
397
- expect(matcher.actual).to eq 'actual string'
398
- end
399
-
400
- it 'allows an early `return` to be used from a `match_unless_raises` block' do
401
- matcher = new_matcher(:with_return) do
402
- match_unless_raises(ArgumentError) do |actual|
403
- return actual if [true, false].include?(actual)
404
- raise ArgumentError
405
- end
406
- end
407
-
408
- expect(matcher.matches?(true)).to be true
409
- # It should match even if it returns false, because no error was raised.
410
- expect(matcher.matches?(false)).to be true
411
- expect(matcher.matches?(4)).to be_falsey
412
- end
413
-
414
- it 'provides actual when `match_when_negated` is used' do
415
- matcher = new_matcher(:name, 'expected string') do
416
- match_when_negated {|actual|}
417
- end
418
-
419
- matcher.does_not_match?('actual string')
420
-
421
- expect(matcher.actual).to eq 'actual string'
422
- end
423
-
424
- it 'allows an early `return` to be used from a `match_when_negated` block' do
425
- matcher = new_matcher(:with_return, 5) do |expected|
426
- match_when_negated { |actual| return true if expected != actual }
427
- end
428
-
429
- expect(matcher.does_not_match?(5)).to be_falsey
430
- expect(matcher.does_not_match?(4)).to be true
431
- end
432
-
433
- context "wrapping another expectation (expect(...).to eq ...)" do
434
- let(:matcher) do
435
- new_matcher(:name, "value") do |expected|
436
- match do |actual|
437
- expect(actual).to eq expected
438
- end
439
- end
440
- end
441
-
442
- it "returns true if the wrapped expectation passes" do
443
- expect(matcher.matches?('value')).to be_truthy
444
- end
445
-
446
- it "returns false if the wrapped expectation fails" do
447
- expect(matcher.matches?('other value')).to be_falsey
448
- end
449
-
450
- it "can use the `include` matcher from a `match` block" do
451
- RSpec::Matchers.define(:descend_from) do |mod|
452
- match do |klass|
453
- expect(klass.ancestors).to include(mod)
454
- end
455
- end
456
-
457
- expect(Fixnum).to descend_from(Object)
458
- expect(Fixnum).not_to descend_from(Array)
459
-
460
- expect {
461
- expect(Fixnum).to descend_from(Array)
462
- }.to fail_with(/expected Fixnum to descend from Array/)
463
-
464
- expect {
465
- expect(Fixnum).not_to descend_from(Object)
466
- }.to fail_with(/expected Fixnum not to descend from Object/)
467
- end
468
-
469
- it "can use the `match` matcher from a `match` block" do
470
- RSpec::Matchers.define(:be_a_phone_number_string) do
471
- match do |string|
472
- expect(string).to match(/\A\d{3}\-\d{3}\-\d{4}\z/)
473
- end
474
- end
475
-
476
- expect("206-123-1234").to be_a_phone_number_string
477
- expect("foo").not_to be_a_phone_number_string
478
-
479
- expect {
480
- expect("foo").to be_a_phone_number_string
481
- }.to fail_with(/expected "foo" to be a phone number string/)
482
-
483
- expect {
484
- expect("206-123-1234").not_to be_a_phone_number_string
485
- }.to fail_with(/expected "206-123-1234" not to be a phone number string/)
486
- end
487
- end
488
-
489
- context "with overrides" do
490
- let(:matcher) do
491
- new_matcher(:be_boolean, true) do |boolean|
492
- match do |actual|
493
- actual
494
- end
495
- description do |actual|
496
- "be the boolean #{boolean} (actual was #{actual})"
497
- end
498
- failure_message do |actual|
499
- "expected #{actual} to be the boolean #{boolean}"
500
- end
501
- failure_message_when_negated do |actual|
502
- "expected #{actual} not to be the boolean #{boolean}"
503
- end
504
- end
505
- end
506
-
507
- it "does not hide result of match block when true" do
508
- expect(matcher.matches?(true)).to be_truthy
509
- end
510
-
511
- it "does not hide result of match block when false" do
512
- expect(matcher.matches?(false)).to be_falsey
513
- end
514
-
515
- it "overrides the description (which yields `actual`)" do
516
- matcher.matches?(true)
517
- expect(matcher.description).to eq "be the boolean true (actual was true)"
518
- end
519
-
520
- it "overrides the failure message for positive expectations" do
521
- matcher.matches?(false)
522
- expect(matcher.failure_message).to eq "expected false to be the boolean true"
523
- end
524
-
525
- it "overrides the failure message for negative expectations" do
526
- matcher.matches?(true)
527
- expect(matcher.failure_message_when_negated).to eq "expected true not to be the boolean true"
528
- end
529
-
530
- it 'can access helper methods from `description`' do
531
- matcher = new_matcher(:desc) do
532
- def subdesc() "sub description" end
533
- description { "Desc (#{subdesc})" }
534
- end
535
-
536
- expect(matcher.description).to eq("Desc (sub description)")
537
- end
538
-
539
- it 'can access helper methods from `failure_message`' do
540
- matcher = new_matcher(:positive_failure_message) do
541
- def helper() "helper" end
542
- failure_message { helper }
543
- end
544
-
545
- expect(matcher.failure_message).to eq("helper")
546
- end
547
-
548
- it 'can access helper methods from `failure_message_when_negated`' do
549
- matcher = new_matcher(:negative_failure_message) do
550
- def helper() "helper" end
551
- failure_message_when_negated { helper }
552
- end
553
-
554
- expect(matcher.failure_message_when_negated).to eq("helper")
555
- end
556
-
557
- it 'can exit early with a `return` from `description` just like in a method' do
558
- matcher = new_matcher(:desc) do
559
- description { return "Desc" }
560
- end
561
-
562
- expect(matcher.description).to eq("Desc")
563
- end
564
-
565
- it 'can exit early with a `return` from `failure_message` just like in a method' do
566
- matcher = new_matcher(:positive_failure_message) do
567
- failure_message { return "msg" }
568
- end
569
-
570
- expect(matcher.failure_message).to eq("msg")
571
- end
572
-
573
- it 'can exit early with a `return` from `failure_message_when_negated` just like in a method' do
574
- matcher = new_matcher(:negative_failure_message) do
575
- failure_message_when_negated { return "msg" }
576
- end
577
-
578
- expect(matcher.failure_message_when_negated).to eq("msg")
579
- end
580
- end
581
-
582
- context "#new" do
583
- it "passes matches? arg to match block" do
584
- matcher = new_matcher(:ignore) do
585
- match do |actual|
586
- actual == 5
587
- end
588
- end
589
- expect(matcher.matches?(5)).to be_truthy
590
- end
591
-
592
- it "exposes arg submitted through #new to matcher block" do
593
- matcher = new_matcher(:ignore, 4) do |expected|
594
- match do |actual|
595
- actual > expected
596
- end
597
- end
598
- expect(matcher.matches?(5)).to be_truthy
599
- end
600
- end
601
-
602
- context "with no args" do
603
- let(:matcher) do
604
- new_matcher(:matcher_name) do
605
- match do |actual|
606
- actual == 5
607
- end
608
- end
609
- end
610
-
611
- it "matches" do
612
- expect(matcher.matches?(5)).to be_truthy
613
- end
614
-
615
- it "describes" do
616
- expect(matcher.description).to eq "matcher name"
617
- end
618
- end
619
-
620
- context "with 1 arg" do
621
- let(:matcher) do
622
- new_matcher(:matcher_name, 1) do |expected|
623
- match do |actual|
624
- actual == 5 && expected == 1
625
- end
626
- end
627
- end
628
-
629
- it "matches" do
630
- expect(matcher.matches?(5)).to be_truthy
631
- end
632
-
633
- it "describes" do
634
- expect(matcher.description).to eq "matcher name 1"
635
- end
636
- end
637
-
638
- context "with multiple args" do
639
- let(:matcher) do
640
- new_matcher(:matcher_name, 1, 2, 3, 4) do |a, b, c, d|
641
- match do |sum|
642
- a + b + c + d == sum
643
- end
644
- end
645
- end
646
-
647
- it "matches" do
648
- expect(matcher.matches?(10)).to be_truthy
649
- end
650
-
651
- it "describes" do
652
- expect(matcher.description).to eq "matcher name 1, 2, 3, and 4"
653
- end
654
- end
655
-
656
- it "supports helper methods" do
657
- matcher = new_matcher(:be_similar_to, [1, 2, 3]) do |sample|
658
- match do |actual|
659
- similar?(sample, actual)
660
- end
661
-
662
- def similar?(a, b)
663
- a.sort == b.sort
664
- end
665
- end
666
-
667
- expect(matcher.matches?([2,3,1])).to be_truthy
668
- end
669
-
670
- it "supports fluent interface" do
671
- matcher = new_matcher(:first_word) do
672
- def second_word
673
- self
674
- end
675
- end
676
-
677
- expect(matcher.second_word).to eq matcher
678
- end
679
-
680
- it "treats method missing normally for undeclared methods" do
681
- matcher = new_matcher(:ignore) { }
682
- expect { matcher.non_existent_method }.to raise_error(NoMethodError)
683
- end
684
-
685
- it "has access to other matchers" do
686
- matcher = new_matcher(:ignore, 3) do |expected|
687
- match do |actual|
688
- extend RSpec::Matchers
689
- expect(actual).to eql(5 + expected)
690
- end
691
- end
692
-
693
- expect(matcher.matches?(8)).to be_truthy
694
- end
695
-
696
- context 'when multiple instances of the same matcher are used in the same example' do
697
- RSpec::Matchers.define(:be_like_a) do |expected|
698
- match { |actual| actual == expected }
699
- description { "be like a #{expected}" }
700
- failure_message { "expected to be like a #{expected}" }
701
- failure_message_when_negated { "expected not to be like a #{expected}" }
702
- end
703
-
704
- # Note: these bugs were only exposed when creating both instances
705
- # first, then checking their descriptions/failure messages.
706
- #
707
- # That's why we eager-instantiate them here.
708
- let!(:moose) { be_like_a("moose") }
709
- let!(:horse) { be_like_a("horse") }
710
-
711
- it 'allows them to use the expected value in the description' do
712
- expect(horse.description).to eq("be like a horse")
713
- expect(moose.description).to eq("be like a moose")
714
- end
715
-
716
- it 'allows them to use the expected value in the positive failure message' do
717
- expect(moose.failure_message).to eq("expected to be like a moose")
718
- expect(horse.failure_message).to eq("expected to be like a horse")
719
- end
720
-
721
- it 'allows them to use the expected value in the negative failure message' do
722
- expect(moose.failure_message_when_negated).to eq("expected not to be like a moose")
723
- expect(horse.failure_message_when_negated).to eq("expected not to be like a horse")
724
- end
725
-
726
- it 'allows them to match separately' do
727
- expect("moose").to moose
728
- expect("horse").to horse
729
- expect("horse").not_to moose
730
- expect("moose").not_to horse
731
- end
732
- end
733
-
734
- describe "#match_unless_raises" do
735
- context "with an assertion" do
736
- mod = Module.new do
737
- def assert_equal(a,b)
738
- raise UnexpectedError.new("#{b} does not equal #{a}") unless a == b
739
- end
740
- end
741
-
742
- let(:matcher) do
743
- new_matcher(:equal, 4) do |expected|
744
- include mod
745
- match_unless_raises UnexpectedError do
746
- assert_equal expected, actual
747
- end
748
- end
749
- end
750
-
751
- context "with passing assertion" do
752
- it "passes" do
753
- expect(matcher.matches?(4)).to be_truthy
754
- end
755
- end
756
-
757
- context "with failing assertion" do
758
- it "fails" do
759
- expect(matcher.matches?(5)).to be_falsey
760
- end
761
-
762
- it "provides the raised exception" do
763
- matcher.matches?(5)
764
- expect(matcher.rescued_exception.message).to eq("5 does not equal 4")
765
- end
766
- end
767
- end
768
-
769
- context "with an unexpected error" do
770
- let(:matcher) do
771
- new_matcher(:foo, :bar) do |expected|
772
- match_unless_raises SyntaxError do |actual|
773
- raise "unexpected exception"
774
- end
775
- end
776
- end
777
-
778
- it "raises the error" do
779
- expect {
780
- matcher.matches?(:bar)
781
- }.to raise_error("unexpected exception")
782
- end
783
- end
784
-
785
- context "without a specified error class" do
786
- let(:matcher) do
787
- new_matcher(:foo) do
788
- match_unless_raises do |actual|
789
- raise Exception unless actual == 5
790
- end
791
- end
792
- end
793
-
794
- it 'passes if no error is raised' do
795
- expect(matcher.matches?(5)).to be true
796
- end
797
-
798
- it 'fails if an exception is raised' do
799
- expect(matcher.matches?(4)).to be false
800
- end
801
- end
802
-
803
- end
804
-
805
- it "can define chainable methods" do
806
- matcher = new_matcher(:name) do
807
- chain(:expecting) do |expected_value|
808
- @expected_value = expected_value
809
- end
810
- match { |actual| actual == @expected_value }
811
- end
812
-
813
- expect(matcher.expecting('value').matches?('value')).to be_truthy
814
- expect(matcher.expecting('value').matches?('other value')).to be_falsey
815
- end
816
-
817
- it 'can use an early return from a `chain` block' do
818
- matcher = new_matcher(:name) do
819
- chain(:expecting) do |expected_value|
820
- @expected_value = expected_value
821
- return
822
- end
823
- match { |actual| actual == @expected_value }
824
- end
825
-
826
- expect(matcher.expecting('value').matches?('value')).to be_truthy
827
- expect(matcher.expecting('value').matches?('other value')).to be_falsey
828
- end
829
-
830
- it 'allows chainable methods to accept blocks' do
831
- matcher = new_matcher(:name) do
832
- chain(:for_block) { |&b| @block = b }
833
- match { |value| @block.call == value }
834
- end
835
-
836
- expect(matcher.for_block { 5 }.matches?(5)).to be true
837
- expect(matcher.for_block { 3 }.matches?(4)).to be false
838
- end
839
-
840
- it "prevents name collisions on chainable methods from different matchers" do
841
- m1 = new_matcher(:m1) { chain(:foo) { raise "foo in m1" } }
842
- m2 = new_matcher(:m2) { chain(:foo) { raise "foo in m2" } }
843
-
844
- expect { m1.foo }.to raise_error("foo in m1")
845
- expect { m2.foo }.to raise_error("foo in m2")
846
- end
847
-
848
- context "defined using the dsl" do
849
- def a_method_in_the_example
850
- "method defined in the example"
851
- end
852
-
853
- it "can access methods in the running example" do |example|
854
- RSpec::Matchers.define(:__access_running_example) do
855
- match do |actual|
856
- a_method_in_the_example == "method defined in the example"
857
- end
858
- end
859
- expect(example).to __access_running_example
860
- end
861
-
862
- it 'can get a method object for methods in the running example', :if => (RUBY_VERSION.to_f > 1.8) do
863
- matcher = new_matcher(:get_method_object) { }
864
- method = matcher.method(:a_method_in_the_example)
865
- expect(method.call).to eq("method defined in the example")
866
- end
867
-
868
- it 'indicates that it responds to a method from the running example' do
869
- matcher = new_matcher(:respond_to) { }
870
- expect(matcher).to respond_to(:a_method_in_the_example)
871
- expect(matcher).not_to respond_to(:a_method_not_in_the_example)
872
- end
873
-
874
- it "raises NoMethodError for methods not in the running_example" do |example|
875
- RSpec::Matchers.define(:__raise_no_method_error) do
876
- match do |actual|
877
- self.a_method_not_in_the_example == "method defined in the example"
878
- end
879
- end
880
-
881
- expected_msg = "RSpec::Matchers::DSL::Matcher"
882
- expected_msg << " __raise_no_method_error" unless rbx?
883
-
884
- expect {
885
- expect(example).to __raise_no_method_error
886
- }.to raise_error(NoMethodError, /#{expected_msg}/)
887
- end
888
-
889
- def rbx?
890
- defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
891
- end
892
- end
893
-
894
- end
895
- end