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