rspec-expectations 2.8.0 → 2.9.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.yardopts +3 -0
- data/Changelog.md +176 -0
- data/README.md +2 -13
- data/features/custom_matchers/access_running_example.feature +1 -1
- data/features/step_definitions/additional_cli_steps.rb +4 -4
- data/lib/rspec/expectations/fail_with.rb +3 -3
- data/lib/rspec/expectations/handler.rb +3 -5
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +387 -21
- data/lib/rspec/matchers/built_in.rb +33 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +58 -0
- data/lib/rspec/matchers/built_in/be.rb +183 -0
- data/lib/rspec/matchers/built_in/be_instance_of.rb +13 -0
- data/lib/rspec/matchers/built_in/be_kind_of.rb +13 -0
- data/lib/rspec/matchers/built_in/be_within.rb +39 -0
- data/lib/rspec/matchers/built_in/change.rb +132 -0
- data/lib/rspec/matchers/built_in/cover.rb +22 -0
- data/lib/rspec/matchers/built_in/eq.rb +26 -0
- data/lib/rspec/matchers/built_in/eql.rb +25 -0
- data/lib/rspec/matchers/built_in/equal.rb +48 -0
- data/lib/rspec/matchers/built_in/exist.rb +28 -0
- data/lib/rspec/matchers/built_in/has.rb +47 -0
- data/lib/rspec/matchers/built_in/have.rb +107 -0
- data/lib/rspec/matchers/built_in/include.rb +52 -0
- data/lib/rspec/matchers/built_in/match.rb +13 -0
- data/lib/rspec/matchers/built_in/match_array.rb +52 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +96 -0
- data/lib/rspec/matchers/built_in/respond_to.rb +73 -0
- data/lib/rspec/matchers/built_in/satisfy.rb +29 -0
- data/lib/rspec/matchers/built_in/throw_symbol.rb +93 -0
- data/lib/rspec/matchers/dsl.rb +1 -1
- data/lib/rspec/matchers/matcher.rb +263 -233
- data/lib/rspec/matchers/method_missing.rb +2 -2
- data/lib/rspec/matchers/operator_matcher.rb +19 -20
- data/spec/rspec/expectations/handler_spec.rb +1 -1
- data/spec/rspec/matchers/base_matcher_spec.rb +1 -2
- data/spec/rspec/matchers/change_spec.rb +3 -3
- data/spec/rspec/matchers/cover_spec.rb +46 -46
- data/spec/rspec/matchers/dsl_spec.rb +36 -3
- data/spec/rspec/matchers/have_spec.rb +2 -2
- data/spec/rspec/matchers/include_spec.rb +1 -1
- data/spec/rspec/matchers/matcher_spec.rb +319 -305
- data/spec/rspec/matchers/method_missing_spec.rb +1 -0
- data/spec/rspec/matchers/operator_matcher_spec.rb +2 -2
- data/spec/rspec/matchers/throw_symbol_spec.rb +103 -105
- metadata +93 -39
- data/lib/rspec/matchers/base_matcher.rb +0 -56
- data/lib/rspec/matchers/be.rb +0 -232
- data/lib/rspec/matchers/be_instance_of.rb +0 -24
- data/lib/rspec/matchers/be_kind_of.rb +0 -24
- data/lib/rspec/matchers/be_within.rb +0 -47
- data/lib/rspec/matchers/change.rb +0 -197
- data/lib/rspec/matchers/cover.rb +0 -36
- data/lib/rspec/matchers/eq.rb +0 -36
- data/lib/rspec/matchers/eql.rb +0 -35
- data/lib/rspec/matchers/equal.rb +0 -58
- data/lib/rspec/matchers/errors.rb +0 -5
- data/lib/rspec/matchers/exist.rb +0 -34
- data/lib/rspec/matchers/has.rb +0 -44
- data/lib/rspec/matchers/have.rb +0 -162
- data/lib/rspec/matchers/include.rb +0 -66
- data/lib/rspec/matchers/match.rb +0 -21
- data/lib/rspec/matchers/match_array.rb +0 -65
- data/lib/rspec/matchers/raise_error.rb +0 -116
- data/lib/rspec/matchers/respond_to.rb +0 -80
- data/lib/rspec/matchers/satisfy.rb +0 -46
- data/lib/rspec/matchers/throw_symbol.rb +0 -112
@@ -4,8 +4,8 @@ module RSpec
|
|
4
4
|
private
|
5
5
|
|
6
6
|
def method_missing(method, *args, &block)
|
7
|
-
return Matchers::BePredicate.new(method, *args, &block) if method.to_s =~ /^be_/
|
8
|
-
return Matchers::Has.new(method, *args, &block) if method.to_s =~ /^have_/
|
7
|
+
return Matchers::BuiltIn::BePredicate.new(method, *args, &block) if method.to_s =~ /^be_/
|
8
|
+
return Matchers::BuiltIn::Has.new(method, *args, &block) if method.to_s =~ /^have_/
|
9
9
|
super
|
10
10
|
end
|
11
11
|
end
|
@@ -34,7 +34,7 @@ module RSpec
|
|
34
34
|
define_method(negative_operator) do |expected|
|
35
35
|
opposite_should = ::RSpec::Matchers.last_should == :should ? :should_not : :should
|
36
36
|
raise "RSpec does not support `#{::RSpec::Matchers.last_should} #{negative_operator} expected`. " +
|
37
|
-
|
37
|
+
"Use `#{opposite_should} #{operator} expected` instead."
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -50,36 +50,35 @@ module RSpec
|
|
50
50
|
def description
|
51
51
|
"#{@operator} #{@expected.inspect}"
|
52
52
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
56
|
def eval_match(actual, operator, expected)
|
57
57
|
::RSpec::Matchers.last_matcher = self
|
58
58
|
@operator, @expected = operator, expected
|
59
59
|
__delegate_operator(actual, operator, expected)
|
60
60
|
end
|
61
|
-
|
62
61
|
end
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
module BuiltIn
|
64
|
+
class PositiveOperatorMatcher < OperatorMatcher
|
65
|
+
def __delegate_operator(actual, operator, expected)
|
66
|
+
if actual.__send__(operator, expected)
|
67
|
+
true
|
68
|
+
elsif ['==','===', '=~'].include?(operator)
|
69
|
+
fail_with_message("expected: #{expected.inspect}\n got: #{actual.inspect} (using #{operator})")
|
70
|
+
else
|
71
|
+
fail_with_message("expected: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
72
|
+
end
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
return fail_with_message("expected not: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
76
|
+
class NegativeOperatorMatcher < OperatorMatcher
|
77
|
+
def __delegate_operator(actual, operator, expected)
|
78
|
+
return false unless actual.__send__(operator, expected)
|
79
|
+
return fail_with_message("expected not: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
80
|
+
end
|
81
81
|
end
|
82
|
-
|
83
82
|
end
|
84
83
|
end
|
85
84
|
end
|
@@ -171,7 +171,7 @@ describe "should change { block }" do
|
|
171
171
|
it "warns if passed a block using do/end instead of {}" do
|
172
172
|
expect do
|
173
173
|
expect {}.to change do; end
|
174
|
-
end.to raise_error(
|
174
|
+
end.to raise_error(SyntaxError, /block passed to should or should_not/)
|
175
175
|
end
|
176
176
|
|
177
177
|
it "provides a #description" do
|
@@ -198,7 +198,7 @@ describe "should_not change { block }" do
|
|
198
198
|
it "warns if passed a block using do/end instead of {}" do
|
199
199
|
expect do
|
200
200
|
expect {}.to_not change do; end
|
201
|
-
end.to raise_error(
|
201
|
+
end.to raise_error(SyntaxError, /block passed to should or should_not/)
|
202
202
|
end
|
203
203
|
end
|
204
204
|
|
@@ -509,7 +509,7 @@ describe "should change{ block }.from(old).to(new)" do
|
|
509
509
|
end
|
510
510
|
end
|
511
511
|
|
512
|
-
describe RSpec::Matchers::Change do
|
512
|
+
describe RSpec::Matchers::BuiltIn::Change do
|
513
513
|
it "works when the receiver has implemented #send" do
|
514
514
|
@instance = SomethingExpected.new
|
515
515
|
@instance.some_value = "string"
|
@@ -1,65 +1,65 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
if (1..2).respond_to?(:cover?)
|
4
|
+
describe "should cover(expected)" do
|
5
|
+
context "for a range target" do
|
6
|
+
it "passes if target covers expected" do
|
7
|
+
(1..10).should cover(5)
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
it "fails if target does not cover expected" do
|
11
|
+
lambda {
|
12
|
+
(1..10).should cover(11)
|
13
|
+
}.should fail_with("expected 1..10 to cover 11")
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
describe "should cover(with, multiple, args)"
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
describe "should cover(with, multiple, args)" do
|
19
|
+
context "for a range target" do
|
20
|
+
it "passes if target covers all items" do
|
21
|
+
(1..10).should cover(4, 6)
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
it "fails if target does not cover any one of the items" do
|
25
|
+
lambda {
|
26
|
+
(1..10).should cover(4, 6, 11)
|
27
|
+
}.should fail_with("expected 1..10 to cover 4, 6, and 11")
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
29
|
-
end
|
30
31
|
|
31
|
-
describe "should_not cover(expected)"
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
describe "should_not cover(expected)" do
|
33
|
+
context "for a range target" do
|
34
|
+
it "passes if target does not cover expected" do
|
35
|
+
(1..10).should_not cover(11)
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
it "fails if target covers expected" do
|
39
|
+
lambda {
|
40
|
+
(1..10).should_not cover(5)
|
41
|
+
}.should fail_with("expected 1..10 not to cover 5")
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
|
-
end
|
44
45
|
|
45
|
-
describe "should_not cover(with, multiple, args)"
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
describe "should_not cover(with, multiple, args)" do
|
47
|
+
context "for a range target" do
|
48
|
+
it "passes if the target does not cover any of the expected" do
|
49
|
+
(1..10).should_not cover(11, 12, 13)
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
it "fails if the target covers all of the expected" do
|
53
|
+
expect {
|
54
|
+
(1..10).should_not cover(4, 6)
|
55
|
+
}.to fail_with("expected 1..10 not to cover 4 and 6")
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
it "fails if the target covers some (but not all) of the expected" do
|
59
|
+
expect {
|
60
|
+
(1..10).should_not cover(5, 11)
|
61
|
+
}.to fail_with("expected 1..10 not to cover 5 and 11")
|
62
|
+
end
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
64
|
-
|
65
|
-
|
@@ -1,8 +1,41 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
describe "a matcher defined using the matcher DSL" do
|
4
|
+
def question?
|
5
|
+
:answer
|
6
|
+
end
|
7
|
+
|
8
|
+
it "has access to methods available in the scope of the example" do
|
9
|
+
RSpec::Matchers::define(:ignore) {}
|
10
|
+
ignore.question?.should eq(:answer)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "raises when method is missing from local scope as well as matcher" do
|
14
|
+
RSpec::Matchers::define(:ignore) {}
|
15
|
+
expect { ignore.i_dont_exist }.to raise_error(NameError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "clears user instance variables between invocations" do
|
19
|
+
RSpec::Matchers::define(:be_just_like) do |expected|
|
20
|
+
match do |actual|
|
21
|
+
@foo ||= expected
|
22
|
+
@foo == actual
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
3.should be_just_like(3)
|
27
|
+
4.should be_just_like(4)
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#respond_to?" do
|
31
|
+
it "returns true for methods in example scope" do
|
32
|
+
RSpec::Matchers::define(:ignore) {}
|
33
|
+
ignore.should respond_to(:question?)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns false for methods not defined in matcher or example scope" do
|
37
|
+
RSpec::Matchers::define(:ignore) {}
|
38
|
+
ignore.should_not respond_to(:i_dont_exist)
|
6
39
|
end
|
7
40
|
end
|
8
41
|
end
|
@@ -390,7 +390,7 @@ EOF
|
|
390
390
|
end
|
391
391
|
end
|
392
392
|
|
393
|
-
describe RSpec::Matchers::Have, "for a collection owner that implements #send" do
|
393
|
+
describe RSpec::Matchers::BuiltIn::Have, "for a collection owner that implements #send" do
|
394
394
|
before(:each) do
|
395
395
|
@collection = Object.new
|
396
396
|
def @collection.floozles; [1,2] end
|
@@ -415,7 +415,7 @@ EOF
|
|
415
415
|
end
|
416
416
|
end
|
417
417
|
|
418
|
-
describe RSpec::Matchers::Have do
|
418
|
+
describe RSpec::Matchers::BuiltIn::Have do
|
419
419
|
it "has method_missing as private" do
|
420
420
|
described_class.private_instance_methods.should include_method(:method_missing)
|
421
421
|
end
|
@@ -133,7 +133,7 @@ describe "#include matcher" do
|
|
133
133
|
it "fails if the target includes all of the expected" do
|
134
134
|
expect {
|
135
135
|
"abc".should_not include("c", "a")
|
136
|
-
}.to fail_with(
|
136
|
+
}.to fail_with('expected "abc" not to include "c" and "a"')
|
137
137
|
end
|
138
138
|
|
139
139
|
it "fails if the target includes some (but not all) of the expected" do
|
@@ -19,402 +19,416 @@ module MatcherHelperModule
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
module RSpec
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end.for_expected
|
31
|
-
end
|
32
|
-
|
33
|
-
it "has access to the module's methods" do
|
34
|
-
matcher.matches?("Hello, World")
|
35
|
-
end
|
36
|
-
|
37
|
-
it "runs the module's included hook" do
|
38
|
-
matcher.should respond_to(:included_method)
|
39
|
-
end
|
40
|
-
|
41
|
-
it "does not run the module's extended hook" do
|
42
|
-
matcher.should_not respond_to(:extended_method)
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'allows multiple modules to be included at once' do
|
46
|
-
m = RSpec::Matchers::Matcher.new(:multiple_modules) do
|
47
|
-
include Enumerable, Comparable
|
48
|
-
end.for_expected
|
49
|
-
m.should be_a(Enumerable)
|
50
|
-
m.should be_a(Comparable)
|
22
|
+
module RSpec::Matchers::DSL
|
23
|
+
describe Matcher do
|
24
|
+
it "can be stored aside and used later" do
|
25
|
+
# Supports using rspec-expectation matchers as argument matchers in
|
26
|
+
# rspec-mocks.
|
27
|
+
RSpec::Matchers.define :example_matcher do |expected|
|
28
|
+
match do |actual|
|
29
|
+
actual == expected
|
51
30
|
end
|
52
31
|
end
|
53
32
|
|
54
|
-
|
55
|
-
|
56
|
-
@matcher = RSpec::Matchers::Matcher.new(:be_a_multiple_of) do |multiple|
|
57
|
-
match do |actual|
|
58
|
-
actual % multiple == 0
|
59
|
-
end
|
60
|
-
end.for_expected(3)
|
61
|
-
end
|
33
|
+
m1 = example_matcher(1)
|
34
|
+
m2 = example_matcher(2)
|
62
35
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
it "provides a default failure message for #should" do
|
68
|
-
@matcher.matches?(8)
|
69
|
-
@matcher.failure_message_for_should.should == "expected 8 to be a multiple of 3"
|
70
|
-
end
|
36
|
+
m1.matches?(1).should be_true
|
37
|
+
m2.matches?(2).should be_true
|
38
|
+
end
|
71
39
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
40
|
+
context "with an included module" do
|
41
|
+
let(:matcher) do
|
42
|
+
RSpec::Matchers::DSL::Matcher.new(:be_a_greeting) do
|
43
|
+
include MatcherHelperModule
|
44
|
+
match { |actual| actual == greeting }
|
45
|
+
end.for_expected
|
76
46
|
end
|
77
47
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
match_for_should do |actual|
|
82
|
-
actual == a * b
|
83
|
-
end
|
84
|
-
|
85
|
-
match_for_should_not do |actual|
|
86
|
-
actual == a + b
|
87
|
-
end
|
88
|
-
end.for_expected(7, 11)
|
89
|
-
end
|
90
|
-
|
91
|
-
it "invokes the match_for_should block for #matches?" do
|
92
|
-
matcher.matches?(77).should be_true
|
93
|
-
matcher.matches?(18).should be_false
|
94
|
-
end
|
95
|
-
|
96
|
-
it "invokes the match_for_should_not block for #does_not_match?" do
|
97
|
-
matcher.does_not_match?(77).should be_false
|
98
|
-
matcher.does_not_match?(18).should be_true
|
99
|
-
end
|
48
|
+
it "has access to the module's methods" do
|
49
|
+
matcher.matches?("Hello, World")
|
50
|
+
end
|
100
51
|
|
101
|
-
|
102
|
-
|
103
|
-
matcher.failure_message_for_should_not.should == "expected 77 not to to be composed of 7 and 11"
|
104
|
-
end
|
52
|
+
it "runs the module's included hook" do
|
53
|
+
matcher.should respond_to(:included_method)
|
105
54
|
end
|
106
55
|
|
107
|
-
it "
|
108
|
-
matcher
|
109
|
-
|
110
|
-
end.for_expected(3,4)
|
56
|
+
it "does not run the module's extended hook" do
|
57
|
+
matcher.should_not respond_to(:extended_method)
|
58
|
+
end
|
111
59
|
|
112
|
-
|
60
|
+
it 'allows multiple modules to be included at once' do
|
61
|
+
m = RSpec::Matchers::DSL::Matcher.new(:multiple_modules) do
|
62
|
+
include Enumerable, Comparable
|
63
|
+
end.for_expected
|
64
|
+
m.should be_a(Enumerable)
|
65
|
+
m.should be_a(Comparable)
|
113
66
|
end
|
67
|
+
end
|
114
68
|
|
115
|
-
|
116
|
-
|
117
|
-
matcher.
|
69
|
+
context "without overrides" do
|
70
|
+
before(:each) do
|
71
|
+
@matcher = RSpec::Matchers::DSL::Matcher.new(:be_a_multiple_of) do |multiple|
|
72
|
+
match do |actual|
|
73
|
+
actual % multiple == 0
|
74
|
+
end
|
75
|
+
end.for_expected(3)
|
118
76
|
end
|
119
77
|
|
120
|
-
it "
|
121
|
-
matcher
|
122
|
-
matcher.should be_diffable
|
78
|
+
it "provides a default description" do
|
79
|
+
@matcher.description.should == "be a multiple of 3"
|
123
80
|
end
|
124
81
|
|
125
|
-
it "provides
|
126
|
-
matcher
|
127
|
-
matcher.
|
82
|
+
it "provides a default failure message for #should" do
|
83
|
+
@matcher.matches?(8)
|
84
|
+
@matcher.failure_message_for_should.should == "expected 8 to be a multiple of 3"
|
128
85
|
end
|
129
86
|
|
130
|
-
it "provides
|
131
|
-
matcher
|
132
|
-
|
133
|
-
|
87
|
+
it "provides a default failure message for #should_not" do
|
88
|
+
@matcher.matches?(9)
|
89
|
+
@matcher.failure_message_for_should_not.should == "expected 9 not to be a multiple of 3"
|
90
|
+
end
|
91
|
+
end
|
134
92
|
|
135
|
-
|
93
|
+
context "with separate match logic for should and should not" do
|
94
|
+
let(:matcher) do
|
95
|
+
RSpec::Matchers::DSL::Matcher.new(:to_be_composed_of) do |a, b|
|
96
|
+
match_for_should do |actual|
|
97
|
+
actual == a * b
|
98
|
+
end
|
136
99
|
|
137
|
-
|
100
|
+
match_for_should_not do |actual|
|
101
|
+
actual == a + b
|
102
|
+
end
|
103
|
+
end.for_expected(7, 11)
|
138
104
|
end
|
139
105
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
actual.should == expected
|
145
|
-
end
|
146
|
-
end.for_expected('value')
|
147
|
-
matcher.matches?('value').should be_true
|
148
|
-
end
|
106
|
+
it "invokes the match_for_should block for #matches?" do
|
107
|
+
matcher.matches?(77).should be_true
|
108
|
+
matcher.matches?(18).should be_false
|
109
|
+
end
|
149
110
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
actual.should == expected
|
154
|
-
end
|
155
|
-
end.for_expected('value')
|
156
|
-
matcher.matches?('other value').should be_false
|
157
|
-
end
|
111
|
+
it "invokes the match_for_should_not block for #does_not_match?" do
|
112
|
+
matcher.does_not_match?(77).should be_false
|
113
|
+
matcher.does_not_match?(18).should be_true
|
158
114
|
end
|
159
115
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
166
|
-
description do
|
167
|
-
"be the boolean #{boolean}"
|
168
|
-
end
|
169
|
-
failure_message_for_should do |actual|
|
170
|
-
"expected #{actual} to be the boolean #{boolean}"
|
171
|
-
end
|
172
|
-
failure_message_for_should_not do |actual|
|
173
|
-
"expected #{actual} not to be the boolean #{boolean}"
|
174
|
-
end
|
175
|
-
end.for_expected(true)
|
176
|
-
end
|
116
|
+
it "provides a default failure message for #should_not" do
|
117
|
+
matcher.does_not_match?(77)
|
118
|
+
matcher.failure_message_for_should_not.should == "expected 77 not to to be composed of 7 and 11"
|
119
|
+
end
|
120
|
+
end
|
177
121
|
|
178
|
-
|
179
|
-
|
180
|
-
|
122
|
+
it "allows helper methods to be defined with #define_method to have access to matcher parameters" do
|
123
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) do |a, b|
|
124
|
+
define_method(:sum) { a + b }
|
125
|
+
end.for_expected(3,4)
|
181
126
|
|
182
|
-
|
183
|
-
|
184
|
-
end
|
127
|
+
matcher.sum.should == 7
|
128
|
+
end
|
185
129
|
|
186
|
-
|
187
|
-
|
188
|
-
|
130
|
+
it "is not diffable by default" do
|
131
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) {}
|
132
|
+
matcher.should_not be_diffable
|
133
|
+
end
|
189
134
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
135
|
+
it "is diffable when told to be" do
|
136
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) { diffable }.for_expected
|
137
|
+
matcher.should be_diffable
|
138
|
+
end
|
194
139
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
end
|
140
|
+
it "provides expected" do
|
141
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) {}.for_expected('expected string')
|
142
|
+
matcher.expected.should == ['expected string']
|
143
|
+
end
|
200
144
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
actual == 5
|
206
|
-
end
|
207
|
-
end.for_expected
|
208
|
-
matcher.matches?(5).should be_true
|
209
|
-
end
|
145
|
+
it "provides actual" do
|
146
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) do
|
147
|
+
match {|actual|}
|
148
|
+
end.for_expected('expected string')
|
210
149
|
|
211
|
-
|
212
|
-
matcher = RSpec::Matchers::Matcher.new(:ignore) do |expected|
|
213
|
-
match do |actual|
|
214
|
-
actual > expected
|
215
|
-
end
|
216
|
-
end.for_expected(4)
|
217
|
-
matcher.matches?(5).should be_true
|
218
|
-
end
|
219
|
-
end
|
150
|
+
matcher.matches?('actual string')
|
220
151
|
|
221
|
-
|
222
|
-
|
223
|
-
@matcher = RSpec::Matchers::Matcher.new(:matcher_name) do
|
224
|
-
match do |actual|
|
225
|
-
actual == 5
|
226
|
-
end
|
227
|
-
end.for_expected
|
228
|
-
end
|
152
|
+
matcher.actual.should == 'actual string'
|
153
|
+
end
|
229
154
|
|
230
|
-
|
231
|
-
|
232
|
-
|
155
|
+
context "wrapping another expectation (should == ...)" do
|
156
|
+
it "returns true if the wrapped expectation passes" do
|
157
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) do |expected|
|
158
|
+
match do |actual|
|
159
|
+
actual.should == expected
|
160
|
+
end
|
161
|
+
end.for_expected('value')
|
162
|
+
matcher.matches?('value').should be_true
|
163
|
+
end
|
233
164
|
|
234
|
-
|
235
|
-
|
236
|
-
|
165
|
+
it "returns false if the wrapped expectation fails" do
|
166
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) do |expected|
|
167
|
+
match do |actual|
|
168
|
+
actual.should == expected
|
169
|
+
end
|
170
|
+
end.for_expected('value')
|
171
|
+
matcher.matches?('other value').should be_false
|
237
172
|
end
|
173
|
+
end
|
238
174
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
175
|
+
context "with overrides" do
|
176
|
+
before(:each) do
|
177
|
+
@matcher = RSpec::Matchers::DSL::Matcher.new(:be_boolean) do |boolean|
|
178
|
+
match do |actual|
|
179
|
+
actual
|
180
|
+
end
|
181
|
+
description do
|
182
|
+
"be the boolean #{boolean}"
|
183
|
+
end
|
184
|
+
failure_message_for_should do |actual|
|
185
|
+
"expected #{actual} to be the boolean #{boolean}"
|
186
|
+
end
|
187
|
+
failure_message_for_should_not do |actual|
|
188
|
+
"expected #{actual} not to be the boolean #{boolean}"
|
189
|
+
end
|
190
|
+
end.for_expected(true)
|
191
|
+
end
|
247
192
|
|
248
|
-
|
249
|
-
|
250
|
-
|
193
|
+
it "does not hide result of match block when true" do
|
194
|
+
@matcher.matches?(true).should be_true
|
195
|
+
end
|
251
196
|
|
252
|
-
|
253
|
-
|
254
|
-
end
|
197
|
+
it "does not hide result of match block when false" do
|
198
|
+
@matcher.matches?(false).should be_false
|
255
199
|
end
|
256
200
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
match do |sum|
|
261
|
-
a + b + c + d == sum
|
262
|
-
end
|
263
|
-
end.for_expected(1,2,3,4)
|
264
|
-
end
|
201
|
+
it "overrides the description" do
|
202
|
+
@matcher.description.should == "be the boolean true"
|
203
|
+
end
|
265
204
|
|
266
|
-
|
267
|
-
|
268
|
-
|
205
|
+
it "overrides the failure message for #should" do
|
206
|
+
@matcher.matches?(false)
|
207
|
+
@matcher.failure_message_for_should.should == "expected false to be the boolean true"
|
208
|
+
end
|
269
209
|
|
270
|
-
|
271
|
-
|
272
|
-
|
210
|
+
it "overrides the failure message for #should_not" do
|
211
|
+
@matcher.matches?(true)
|
212
|
+
@matcher.failure_message_for_should_not.should == "expected true not to be the boolean true"
|
273
213
|
end
|
214
|
+
end
|
274
215
|
|
275
|
-
|
276
|
-
|
216
|
+
context "#new" do
|
217
|
+
it "passes matches? arg to match block" do
|
218
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) do
|
277
219
|
match do |actual|
|
278
|
-
|
220
|
+
actual == 5
|
279
221
|
end
|
222
|
+
end.for_expected
|
223
|
+
matcher.matches?(5).should be_true
|
224
|
+
end
|
280
225
|
|
281
|
-
|
282
|
-
|
226
|
+
it "exposes arg submitted through #new to matcher block" do
|
227
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) do |expected|
|
228
|
+
match do |actual|
|
229
|
+
actual > expected
|
283
230
|
end
|
284
|
-
end.for_expected(
|
285
|
-
|
286
|
-
matcher.matches?([2,3,1]).should be_true
|
231
|
+
end.for_expected(4)
|
232
|
+
matcher.matches?(5).should be_true
|
287
233
|
end
|
234
|
+
end
|
288
235
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
236
|
+
context "with no args" do
|
237
|
+
before(:each) do
|
238
|
+
@matcher = RSpec::Matchers::DSL::Matcher.new(:matcher_name) do
|
239
|
+
match do |actual|
|
240
|
+
actual == 5
|
293
241
|
end
|
294
242
|
end.for_expected
|
243
|
+
end
|
295
244
|
|
296
|
-
|
245
|
+
it "matches" do
|
246
|
+
@matcher.matches?(5).should be_true
|
297
247
|
end
|
298
248
|
|
299
|
-
it "
|
300
|
-
matcher
|
301
|
-
expect { matcher.non_existent_method }.to raise_error(NoMethodError)
|
249
|
+
it "describes" do
|
250
|
+
@matcher.description.should == "matcher name"
|
302
251
|
end
|
252
|
+
end
|
303
253
|
|
304
|
-
|
305
|
-
|
254
|
+
context "with 1 arg" do
|
255
|
+
before(:each) do
|
256
|
+
@matcher = RSpec::Matchers::DSL::Matcher.new(:matcher_name) do |expected|
|
306
257
|
match do |actual|
|
307
|
-
|
308
|
-
actual.should eql(5 + expected)
|
258
|
+
actual == 5 && expected == 1
|
309
259
|
end
|
310
|
-
end.for_expected(
|
260
|
+
end.for_expected(1)
|
261
|
+
end
|
311
262
|
|
312
|
-
|
263
|
+
it "matches" do
|
264
|
+
@matcher.matches?(5).should be_true
|
313
265
|
end
|
314
266
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
m = mod
|
326
|
-
RSpec::Matchers::Matcher.new :equal do |expected|
|
327
|
-
extend m
|
328
|
-
match_unless_raises UnexpectedError do
|
329
|
-
assert_equal expected, actual
|
330
|
-
end
|
331
|
-
end.for_expected(4)
|
267
|
+
it "describes" do
|
268
|
+
@matcher.description.should == "matcher name 1"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context "with multiple args" do
|
273
|
+
before(:each) do
|
274
|
+
@matcher = RSpec::Matchers::DSL::Matcher.new(:matcher_name) do |a,b,c,d|
|
275
|
+
match do |sum|
|
276
|
+
a + b + c + d == sum
|
332
277
|
end
|
278
|
+
end.for_expected(1,2,3,4)
|
279
|
+
end
|
280
|
+
|
281
|
+
it "matches" do
|
282
|
+
@matcher.matches?(10).should be_true
|
283
|
+
end
|
284
|
+
|
285
|
+
it "describes" do
|
286
|
+
@matcher.description.should == "matcher name 1, 2, 3, and 4"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
it "supports helper methods" do
|
291
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:be_similar_to) do |sample|
|
292
|
+
match do |actual|
|
293
|
+
similar?(sample, actual)
|
294
|
+
end
|
295
|
+
|
296
|
+
def similar?(a, b)
|
297
|
+
a.sort == b.sort
|
298
|
+
end
|
299
|
+
end.for_expected([1,2,3])
|
300
|
+
|
301
|
+
matcher.matches?([2,3,1]).should be_true
|
302
|
+
end
|
303
|
+
|
304
|
+
it "supports fluent interface" do
|
305
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:first_word) do
|
306
|
+
def second_word
|
307
|
+
self
|
308
|
+
end
|
309
|
+
end.for_expected
|
333
310
|
|
334
|
-
|
335
|
-
|
336
|
-
|
311
|
+
matcher.second_word.should == matcher
|
312
|
+
end
|
313
|
+
|
314
|
+
it "treats method missing normally for undeclared methods" do
|
315
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) { }.for_expected
|
316
|
+
expect { matcher.non_existent_method }.to raise_error(NoMethodError)
|
317
|
+
end
|
318
|
+
|
319
|
+
it "has access to other matchers" do
|
320
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:ignore) do |expected|
|
321
|
+
match do |actual|
|
322
|
+
extend RSpec::Matchers
|
323
|
+
actual.should eql(5 + expected)
|
324
|
+
end
|
325
|
+
end.for_expected(3)
|
326
|
+
|
327
|
+
matcher.matches?(8).should be_true
|
328
|
+
end
|
329
|
+
|
330
|
+
describe "#match_unless_raises" do
|
331
|
+
context "with an assertion" do
|
332
|
+
let(:mod) do
|
333
|
+
Module.new do
|
334
|
+
def assert_equal(a,b)
|
335
|
+
a == b ? nil : (raise UnexpectedError.new("#{b} does not equal #{a}"))
|
337
336
|
end
|
338
337
|
end
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
338
|
+
end
|
339
|
+
let(:matcher) do
|
340
|
+
m = mod
|
341
|
+
RSpec::Matchers::DSL::Matcher.new :equal do |expected|
|
342
|
+
extend m
|
343
|
+
match_unless_raises UnexpectedError do
|
344
|
+
assert_equal expected, actual
|
343
345
|
end
|
346
|
+
end.for_expected(4)
|
347
|
+
end
|
344
348
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
should eq("5 does not equal 4")
|
349
|
-
end
|
349
|
+
context "with passing assertion" do
|
350
|
+
it "passes" do
|
351
|
+
matcher.matches?(4).should be_true
|
350
352
|
end
|
351
353
|
end
|
352
354
|
|
353
|
-
context "with
|
354
|
-
|
355
|
-
|
356
|
-
match_unless_raises SyntaxError do |actual|
|
357
|
-
raise "unexpected exception"
|
358
|
-
end
|
359
|
-
end.for_expected(:bar)
|
355
|
+
context "with failing assertion" do
|
356
|
+
it "fails" do
|
357
|
+
matcher.matches?(5).should be_false
|
360
358
|
end
|
361
359
|
|
362
|
-
it "
|
363
|
-
|
364
|
-
|
365
|
-
|
360
|
+
it "provides the raised exception" do
|
361
|
+
matcher.matches?(5)
|
362
|
+
matcher.rescued_exception.message.
|
363
|
+
should eq("5 does not equal 4")
|
366
364
|
end
|
367
365
|
end
|
368
|
-
|
369
366
|
end
|
370
367
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
368
|
+
context "with an unexpected error" do
|
369
|
+
let(:matcher) do
|
370
|
+
RSpec::Matchers::DSL::Matcher.new :foo do |expected|
|
371
|
+
match_unless_raises SyntaxError do |actual|
|
372
|
+
raise "unexpected exception"
|
373
|
+
end
|
374
|
+
end.for_expected(:bar)
|
375
|
+
end
|
378
376
|
|
379
|
-
|
380
|
-
|
377
|
+
it "raises the error" do
|
378
|
+
expect do
|
379
|
+
matcher.matches?(:bar)
|
380
|
+
end.to raise_error("unexpected exception")
|
381
|
+
end
|
381
382
|
end
|
382
383
|
|
383
|
-
|
384
|
-
m1 = RSpec::Matchers::Matcher.new(:m1) { chain(:foo) { raise "foo in m1" } }.for_expected
|
385
|
-
m2 = RSpec::Matchers::Matcher.new(:m2) { chain(:foo) { raise "foo in m2" } }.for_expected
|
386
|
-
|
387
|
-
expect { m1.foo }.to raise_error("foo in m1")
|
388
|
-
expect { m2.foo }.to raise_error("foo in m2")
|
389
|
-
end
|
384
|
+
end
|
390
385
|
|
391
|
-
|
392
|
-
|
393
|
-
|
386
|
+
it "can define chainable methods" do
|
387
|
+
matcher = RSpec::Matchers::DSL::Matcher.new(:name) do
|
388
|
+
chain(:expecting) do |expected_value|
|
389
|
+
@expected_value = expected_value
|
394
390
|
end
|
391
|
+
match { |actual| actual == @expected_value }
|
392
|
+
end.for_expected
|
395
393
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
394
|
+
matcher.expecting('value').matches?('value').should be_true
|
395
|
+
matcher.expecting('value').matches?('other value').should be_false
|
396
|
+
end
|
397
|
+
|
398
|
+
it "prevents name collisions on chainable methods from different matchers" do
|
399
|
+
m1 = RSpec::Matchers::DSL::Matcher.new(:m1) { chain(:foo) { raise "foo in m1" } }.for_expected
|
400
|
+
m2 = RSpec::Matchers::DSL::Matcher.new(:m2) { chain(:foo) { raise "foo in m2" } }.for_expected
|
401
|
+
|
402
|
+
expect { m1.foo }.to raise_error("foo in m1")
|
403
|
+
expect { m2.foo }.to raise_error("foo in m2")
|
404
|
+
end
|
405
|
+
|
406
|
+
context "defined using the dsl" do
|
407
|
+
def a_method_in_the_example
|
408
|
+
"method defined in the example"
|
409
|
+
end
|
410
|
+
|
411
|
+
it "can access methods in the running example" do
|
412
|
+
RSpec::Matchers.define(:__access_running_example) do
|
413
|
+
match do |actual|
|
414
|
+
a_method_in_the_example == "method defined in the example"
|
401
415
|
end
|
402
|
-
example.should __access_running_example
|
403
416
|
end
|
417
|
+
example.should __access_running_example
|
418
|
+
end
|
404
419
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
end
|
420
|
+
it "raises NoMethodError for methods not in the running_example" do
|
421
|
+
RSpec::Matchers.define(:__raise_no_method_error) do
|
422
|
+
match do |actual|
|
423
|
+
a_method_not_in_the_example == "method defined in the example"
|
410
424
|
end
|
411
|
-
|
412
|
-
expect do
|
413
|
-
example.should __raise_no_method_error
|
414
|
-
end.to raise_error(/RSpec::Matchers::Matcher/)
|
415
425
|
end
|
426
|
+
|
427
|
+
expect do
|
428
|
+
example.should __raise_no_method_error
|
429
|
+
end.to raise_error(/RSpec::Matchers::DSL::Matcher/)
|
416
430
|
end
|
417
|
-
|
418
431
|
end
|
432
|
+
|
419
433
|
end
|
420
434
|
end
|