rspec-expectations 3.0.0.beta2 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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