rspec-expectations 3.0.0.beta1 → 3.0.0.beta2
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.tar.gz.sig +2 -2
- data/.yardopts +1 -0
- data/Changelog.md +138 -0
- data/README.md +75 -8
- data/features/README.md +2 -2
- data/features/built_in_matchers/README.md +12 -9
- data/features/built_in_matchers/comparisons.feature +2 -2
- data/features/built_in_matchers/contain_exactly.feature +46 -0
- data/features/built_in_matchers/expect_change.feature +2 -2
- data/features/built_in_matchers/include.feature +0 -48
- data/features/built_in_matchers/output.feature +70 -0
- data/features/composing_matchers.feature +250 -0
- data/features/compound_expectations.feature +45 -0
- data/features/custom_matchers/access_running_example.feature +1 -1
- data/features/custom_matchers/define_matcher.feature +6 -6
- data/features/custom_matchers/define_matcher_outside_rspec.feature +4 -8
- data/features/test_frameworks/{test_unit.feature → minitest.feature} +11 -11
- data/lib/rspec/expectations.rb +31 -42
- data/lib/rspec/expectations/diff_presenter.rb +141 -0
- data/lib/rspec/expectations/differ.rb +22 -132
- data/lib/rspec/expectations/encoded_string.rb +56 -0
- data/lib/rspec/expectations/expectation_target.rb +0 -30
- data/lib/rspec/expectations/fail_with.rb +2 -2
- data/lib/rspec/expectations/handler.rb +128 -31
- data/lib/rspec/expectations/minitest_integration.rb +16 -0
- data/lib/rspec/expectations/syntax.rb +4 -58
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +298 -60
- data/lib/rspec/matchers/aliased_matcher.rb +35 -0
- data/lib/rspec/matchers/built_in.rb +37 -33
- data/lib/rspec/matchers/built_in/base_matcher.rb +25 -15
- data/lib/rspec/matchers/built_in/be.rb +23 -31
- data/lib/rspec/matchers/built_in/be_between.rb +55 -0
- data/lib/rspec/matchers/built_in/be_within.rb +15 -11
- data/lib/rspec/matchers/built_in/change.rb +198 -81
- data/lib/rspec/matchers/built_in/compound.rb +106 -0
- data/lib/rspec/matchers/built_in/contain_exactly.rb +245 -0
- data/lib/rspec/matchers/built_in/eq.rb +43 -4
- data/lib/rspec/matchers/built_in/eql.rb +2 -2
- data/lib/rspec/matchers/built_in/equal.rb +35 -18
- data/lib/rspec/matchers/built_in/has.rb +16 -15
- data/lib/rspec/matchers/built_in/include.rb +45 -23
- data/lib/rspec/matchers/built_in/match.rb +6 -3
- data/lib/rspec/matchers/built_in/operators.rb +103 -0
- data/lib/rspec/matchers/built_in/output.rb +108 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +9 -15
- data/lib/rspec/matchers/built_in/respond_to.rb +5 -4
- data/lib/rspec/matchers/built_in/satisfy.rb +4 -3
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +37 -16
- data/lib/rspec/matchers/built_in/throw_symbol.rb +6 -5
- data/lib/rspec/matchers/built_in/yield.rb +31 -29
- data/lib/rspec/matchers/composable.rb +138 -0
- data/lib/rspec/matchers/dsl.rb +330 -0
- data/lib/rspec/matchers/generated_descriptions.rb +6 -6
- data/lib/rspec/matchers/matcher_delegator.rb +33 -0
- data/lib/rspec/matchers/pretty.rb +13 -2
- data/spec/rspec/expectations/{differ_spec.rb → diff_presenter_spec.rb} +56 -36
- data/spec/rspec/expectations/encoded_string_spec.rb +74 -0
- data/spec/rspec/expectations/extensions/kernel_spec.rb +11 -11
- data/spec/rspec/expectations/fail_with_spec.rb +8 -8
- data/spec/rspec/expectations/handler_spec.rb +27 -49
- data/spec/rspec/expectations/minitest_integration_spec.rb +27 -0
- data/spec/rspec/expectations/syntax_spec.rb +17 -67
- data/spec/rspec/expectations_spec.rb +7 -52
- data/spec/rspec/matchers/aliased_matcher_spec.rb +48 -0
- data/spec/rspec/matchers/aliases_spec.rb +449 -0
- data/spec/rspec/matchers/{base_matcher_spec.rb → built_in/base_matcher_spec.rb} +24 -3
- data/spec/rspec/matchers/built_in/be_between_spec.rb +159 -0
- data/spec/rspec/matchers/{be_instance_of_spec.rb → built_in/be_instance_of_spec.rb} +0 -0
- data/spec/rspec/matchers/{be_kind_of_spec.rb → built_in/be_kind_of_spec.rb} +0 -0
- data/spec/rspec/matchers/{be_spec.rb → built_in/be_spec.rb} +76 -32
- data/spec/rspec/matchers/{be_within_spec.rb → built_in/be_within_spec.rb} +6 -2
- data/spec/rspec/matchers/{change_spec.rb → built_in/change_spec.rb} +310 -69
- data/spec/rspec/matchers/built_in/compound_spec.rb +292 -0
- data/spec/rspec/matchers/built_in/contain_exactly_spec.rb +441 -0
- data/spec/rspec/matchers/{cover_spec.rb → built_in/cover_spec.rb} +0 -0
- data/spec/rspec/matchers/built_in/eq_spec.rb +156 -0
- data/spec/rspec/matchers/{eql_spec.rb → built_in/eql_spec.rb} +2 -2
- data/spec/rspec/matchers/built_in/equal_spec.rb +106 -0
- data/spec/rspec/matchers/{exist_spec.rb → built_in/exist_spec.rb} +1 -1
- data/spec/rspec/matchers/{has_spec.rb → built_in/has_spec.rb} +39 -0
- data/spec/rspec/matchers/{include_spec.rb → built_in/include_spec.rb} +118 -109
- data/spec/rspec/matchers/{match_spec.rb → built_in/match_spec.rb} +30 -2
- data/spec/rspec/matchers/{operator_matcher_spec.rb → built_in/operators_spec.rb} +26 -26
- data/spec/rspec/matchers/built_in/output_spec.rb +165 -0
- data/spec/rspec/matchers/{raise_error_spec.rb → built_in/raise_error_spec.rb} +81 -11
- data/spec/rspec/matchers/{respond_to_spec.rb → built_in/respond_to_spec.rb} +0 -0
- data/spec/rspec/matchers/{satisfy_spec.rb → built_in/satisfy_spec.rb} +0 -0
- data/spec/rspec/matchers/{start_with_end_with_spec.rb → built_in/start_and_end_with_spec.rb} +82 -15
- data/spec/rspec/matchers/{throw_symbol_spec.rb → built_in/throw_symbol_spec.rb} +29 -10
- data/spec/rspec/matchers/{yield_spec.rb → built_in/yield_spec.rb} +90 -0
- data/spec/rspec/matchers/configuration_spec.rb +7 -39
- data/spec/rspec/matchers/description_generation_spec.rb +22 -6
- data/spec/rspec/matchers/dsl_spec.rb +838 -0
- data/spec/rspec/matchers/legacy_spec.rb +101 -0
- data/spec/rspec/matchers_spec.rb +74 -0
- data/spec/spec_helper.rb +35 -21
- data/spec/support/shared_examples.rb +26 -4
- metadata +172 -116
- metadata.gz.sig +3 -4
- checksums.yaml +0 -15
- checksums.yaml.gz.sig +0 -0
- data/features/built_in_matchers/match_array.feature +0 -37
- data/lib/rspec/expectations/errors.rb +0 -9
- data/lib/rspec/expectations/extensions.rb +0 -1
- data/lib/rspec/expectations/extensions/object.rb +0 -29
- data/lib/rspec/matchers/built_in/match_array.rb +0 -51
- data/lib/rspec/matchers/compatibility.rb +0 -14
- data/lib/rspec/matchers/matcher.rb +0 -301
- data/lib/rspec/matchers/method_missing.rb +0 -12
- data/lib/rspec/matchers/operator_matcher.rb +0 -99
- data/lib/rspec/matchers/test_unit_integration.rb +0 -11
- data/spec/rspec/matchers/eq_spec.rb +0 -60
- data/spec/rspec/matchers/equal_spec.rb +0 -78
- data/spec/rspec/matchers/include_matcher_integration_spec.rb +0 -30
- data/spec/rspec/matchers/match_array_spec.rb +0 -194
- data/spec/rspec/matchers/matcher_spec.rb +0 -706
- data/spec/rspec/matchers/matchers_spec.rb +0 -36
- data/spec/rspec/matchers/method_missing_spec.rb +0 -28
- data/spec/support/classes.rb +0 -56
- data/spec/support/in_sub_process.rb +0 -37
- data/spec/support/ruby_version.rb +0 -10
File without changes
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'date'
|
3
|
+
require 'complex'
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
module Matchers
|
7
|
+
describe "eq" do
|
8
|
+
it_behaves_like "an RSpec matcher", :valid_value => 1, :invalid_value => 2 do
|
9
|
+
let(:matcher) { eq(1) }
|
10
|
+
end
|
11
|
+
|
12
|
+
it "is diffable" do
|
13
|
+
expect(eq(1)).to be_diffable
|
14
|
+
end
|
15
|
+
|
16
|
+
it "matches when actual == expected" do
|
17
|
+
expect(1).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "does not match when actual != expected" do
|
21
|
+
expect(1).not_to eq(2)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "compares by sending == to actual (not expected)" do
|
25
|
+
called = false
|
26
|
+
actual = Class.new do
|
27
|
+
define_method :== do |other|
|
28
|
+
called = true
|
29
|
+
end
|
30
|
+
end.new
|
31
|
+
|
32
|
+
expect(actual).to eq :anything # to trigger the matches? method
|
33
|
+
expect(called).to be_truthy
|
34
|
+
end
|
35
|
+
|
36
|
+
it "describes itself" do
|
37
|
+
matcher = eq(1)
|
38
|
+
matcher.matches?(1)
|
39
|
+
expect(matcher.description).to eq "eq 1"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "provides message, expected and actual on #failure_message" do
|
43
|
+
matcher = eq("1")
|
44
|
+
matcher.matches?(1)
|
45
|
+
expect(matcher.failure_message).to eq "\nexpected: \"1\"\n got: 1\n\n(compared using ==)\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "provides message, expected and actual on #negative_failure_message" do
|
49
|
+
matcher = eq(1)
|
50
|
+
matcher.matches?(1)
|
51
|
+
expect(matcher.failure_message_when_negated).to eq "\nexpected: value != 1\n got: 1\n\n(compared using ==)\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'fails properly when the actual is an array of multiline strings' do
|
55
|
+
expect {
|
56
|
+
expect(["a\nb", "c\nd"]).to eq([])
|
57
|
+
}.to fail_matching("expected: []")
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#description' do
|
61
|
+
[
|
62
|
+
[nil, 'eq nil'],
|
63
|
+
[true, 'eq true'],
|
64
|
+
[false, 'eq false'],
|
65
|
+
[:symbol, 'eq :symbol'],
|
66
|
+
[1, 'eq 1'],
|
67
|
+
[1.2, 'eq 1.2'],
|
68
|
+
[Complex(1, 2), "eq #{Complex(1, 2).inspect}"],
|
69
|
+
['foo', 'eq "foo"'],
|
70
|
+
[/regex/, 'eq /regex/'],
|
71
|
+
[['foo'], 'eq ["foo"]'],
|
72
|
+
[{:foo => :bar}, 'eq {:foo=>:bar}'],
|
73
|
+
[Class, 'eq Class'],
|
74
|
+
[RSpec, 'eq RSpec'],
|
75
|
+
[Date.new(2014, 1, 1), "eq #{Date.new(2014, 1, 1).inspect}"],
|
76
|
+
[Time.utc(2014, 1, 1), "eq #{Time.utc(2014, 1, 1).inspect}"],
|
77
|
+
].each do |expected, expected_description|
|
78
|
+
context "with #{expected.inspect}" do
|
79
|
+
it "is \"#{expected_description}\"" do
|
80
|
+
expect(eq(expected).description).to eq expected_description
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with object' do
|
86
|
+
it 'matches with "^eq #<Object:0x[0-9a-f]*>$"' do
|
87
|
+
expect(eq(Object.new).description).to match(/^eq #<Object:0x[0-9a-f]*>$/)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "Time Equality" do
|
93
|
+
RSpec::Matchers.define :a_string_with_differing_output do
|
94
|
+
match do |string|
|
95
|
+
time_strings = /expected: (.+)\n.*got: (.+)$/.match(string).captures
|
96
|
+
time_strings.uniq.count == 2
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
RSpec::Matchers.define :a_string_with_identical_output do
|
101
|
+
match do |string|
|
102
|
+
time_strings = /expected: value != (.+)\n.*got: (.+)$/.match(string).captures
|
103
|
+
time_strings.uniq.count == 1
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'with Time objects' do
|
108
|
+
let(:time1) { Time.utc(1969, 12, 31, 19, 01, 40, 101) }
|
109
|
+
let(:time2) { Time.utc(1969, 12, 31, 19, 01, 40, 102) }
|
110
|
+
|
111
|
+
it 'produces different output for Times differing by milliseconds' do
|
112
|
+
expect {
|
113
|
+
expect(time1).to eq(time2)
|
114
|
+
}.to fail_with(a_string_with_differing_output)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'with DateTime objects' do
|
119
|
+
let(:date1) { DateTime.new(2000, 1, 1, 1, 1, Rational(1, 10)) }
|
120
|
+
let(:date2) { DateTime.new(2000, 1, 1, 1, 1, Rational(2, 10)) }
|
121
|
+
|
122
|
+
it 'produces different output for DateTimes differing by milliseconds' do
|
123
|
+
expect {
|
124
|
+
expect(date1).to eq(date2)
|
125
|
+
}.to fail_with(a_string_with_differing_output)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'does not not assume DateTime is defined since you need to require `date` to make it available' do
|
129
|
+
hide_const('DateTime')
|
130
|
+
expect {
|
131
|
+
expect(5).to eq(4)
|
132
|
+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'fails with identical output when the DateTimes are exactly the same' do
|
136
|
+
expect {
|
137
|
+
expect(date1).to_not eq(date1)
|
138
|
+
}.to fail_with(a_string_with_identical_output)
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'when ActiveSupport is loaded' do
|
142
|
+
it "uses a custom format to ensure the output is different when DateTimes differ" do
|
143
|
+
stub_const("ActiveSupport", Module.new)
|
144
|
+
allow(date1).to receive(:inspect).and_return("Timestamp")
|
145
|
+
allow(date2).to receive(:inspect).and_return("Timestamp")
|
146
|
+
|
147
|
+
expect {
|
148
|
+
expect(date1).to eq(date2)
|
149
|
+
}.to fail_with(a_string_with_differing_output)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -28,13 +28,13 @@ module RSpec
|
|
28
28
|
it "provides message, expected and actual on #failure_message" do
|
29
29
|
matcher = eql("1")
|
30
30
|
matcher.matches?(1)
|
31
|
-
expect(matcher.
|
31
|
+
expect(matcher.failure_message).to eq "\nexpected: \"1\"\n got: 1\n\n(compared using eql?)\n"
|
32
32
|
end
|
33
33
|
|
34
34
|
it "provides message, expected and actual on #negative_failure_message" do
|
35
35
|
matcher = eql(1)
|
36
36
|
matcher.matches?(1)
|
37
|
-
expect(matcher.
|
37
|
+
expect(matcher.failure_message_when_negated).to eq "\nexpected: value != 1\n got: 1\n\n(compared using eql?)\n"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module RSpec
|
3
|
+
module Matchers
|
4
|
+
describe "equal" do
|
5
|
+
it_behaves_like "an RSpec matcher", :valid_value => :a, :invalid_value => :b do
|
6
|
+
let(:matcher) { equal(:a) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def inspect_object(o)
|
10
|
+
"#<#{o.class}:#{o.object_id}> => #{o.inspect}"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "matches when actual.equal?(expected)" do
|
14
|
+
expect(1).to equal(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "does not match when !actual.equal?(expected)" do
|
18
|
+
expect("1").not_to equal("1")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "describes itself" do
|
22
|
+
matcher = equal(1)
|
23
|
+
matcher.matches?(1)
|
24
|
+
expect(matcher.description).to eq "equal 1"
|
25
|
+
end
|
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
|
+
it "prints a special message for `false`" do
|
54
|
+
expected, actual = false, "1"
|
55
|
+
expect {
|
56
|
+
expect(actual).to equal(expected)
|
57
|
+
}.to fail_with "\nexpected false\n got #{inspect_object(actual)}\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "prints a special message for `true`" do
|
61
|
+
expected, actual = true, "1"
|
62
|
+
expect {
|
63
|
+
expect(actual).to equal(expected)
|
64
|
+
}.to fail_with "\nexpected true\n got #{inspect_object(actual)}\n"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "prints a special message for `nil`" do
|
68
|
+
expected, actual = nil, "1"
|
69
|
+
expect {
|
70
|
+
expect(actual).to equal(expected)
|
71
|
+
}.to fail_with "\nexpected nil\n got #{inspect_object(actual)}\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
it "suggests the `eq` matcher on failure" do
|
75
|
+
expected, actual = "1", "1"
|
76
|
+
expect {
|
77
|
+
expect(actual).to equal(expected)
|
78
|
+
}.to fail_with <<-MESSAGE
|
79
|
+
|
80
|
+
expected #{inspect_object(expected)}
|
81
|
+
got #{inspect_object(actual)}
|
82
|
+
|
83
|
+
Compared using equal?, which compares object identity,
|
84
|
+
but expected and actual are not the same object. Use
|
85
|
+
`expect(actual).to eq(expected)` if you don't care about
|
86
|
+
object identity in this example.
|
87
|
+
|
88
|
+
MESSAGE
|
89
|
+
end
|
90
|
+
|
91
|
+
it "provides message on #negative_failure_message" do
|
92
|
+
expected = actual = "1"
|
93
|
+
matcher = equal(expected)
|
94
|
+
matcher.matches?(actual)
|
95
|
+
expect(matcher.failure_message_when_negated).to eq <<-MESSAGE
|
96
|
+
|
97
|
+
expected not #{inspect_object(expected)}
|
98
|
+
got #{inspect_object(actual)}
|
99
|
+
|
100
|
+
Compared using equal?, which compares object identity.
|
101
|
+
|
102
|
+
MESSAGE
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -117,7 +117,7 @@ describe "exist matcher" do
|
|
117
117
|
|
118
118
|
it 'passes any provided arguments to the call to #exist?' do
|
119
119
|
object = double
|
120
|
-
object.
|
120
|
+
expect(object).to receive(:exist?).with(:foo, :bar) { true }
|
121
121
|
|
122
122
|
expect(object).to exist(:foo, :bar)
|
123
123
|
end
|
@@ -16,6 +16,34 @@ describe "expect(...).to have_sym(*args)" do
|
|
16
16
|
}.to fail_with("expected #has_key?(:a) to return true, got false")
|
17
17
|
end
|
18
18
|
|
19
|
+
obj_with_block_method = Object.new
|
20
|
+
def obj_with_block_method.has_some_stuff?; yield; end
|
21
|
+
|
22
|
+
it 'forwards the given `{ }` block on to the `has_xyz?` method' do
|
23
|
+
expect(obj_with_block_method).to have_some_stuff { true }
|
24
|
+
expect(obj_with_block_method).to_not have_some_stuff { false }
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'forwards the given `do..end` block on to the `has_xyz?` method' do
|
28
|
+
expect(obj_with_block_method).to have_some_stuff do
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
expect(obj_with_block_method).to_not have_some_stuff do
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'favors a curly brace block over a do...end one since it binds to the matcher method' do
|
38
|
+
expect(obj_with_block_method).to have_some_stuff { true } do
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
expect(obj_with_block_method).not_to have_some_stuff { false } do
|
43
|
+
true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
19
47
|
it 'does not include any args in the failure message if no args were given to the matcher' do
|
20
48
|
o = Object.new
|
21
49
|
def o.has_some_stuff?; false; end
|
@@ -57,6 +85,17 @@ describe "expect(...).to have_sym(*args)" do
|
|
57
85
|
expect(o).to have_sym(:foo)
|
58
86
|
}.to raise_error("Funky exception")
|
59
87
|
end
|
88
|
+
|
89
|
+
it 'allows composable aliases to be defined' do
|
90
|
+
RSpec::Matchers.alias_matcher :an_object_having_sym, :have_sym
|
91
|
+
o = Object.new
|
92
|
+
def o.has_sym?(sym); sym == :foo; end
|
93
|
+
|
94
|
+
expect(o).to an_object_having_sym(:foo)
|
95
|
+
expect(o).not_to an_object_having_sym(:bar)
|
96
|
+
|
97
|
+
expect(an_object_having_sym(:foo).description).to eq("an object having sym :foo")
|
98
|
+
end
|
60
99
|
end
|
61
100
|
|
62
101
|
describe "expect(...).not_to have_sym(*args)" do
|
@@ -69,13 +69,13 @@ describe "#include matcher" do
|
|
69
69
|
it "fails if target does not include expected" do
|
70
70
|
expect {
|
71
71
|
expect({:key => 'value'}).to include(:other)
|
72
|
-
}.to fail_matching(%Q|expected {:key=>"value"} to include :other|)
|
72
|
+
}.to fail_matching(%Q|expected {:key => "value"} to include :other|)
|
73
73
|
end
|
74
74
|
|
75
75
|
it "fails if target doesn't have a key and we expect nil" do
|
76
76
|
expect {
|
77
77
|
expect({}).to include(:something => nil)
|
78
|
-
}.to fail_matching(%Q|expected {} to include {:something=>nil}|)
|
78
|
+
}.to fail_matching(%Q|expected {} to include {:something => nil}|)
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'works even when an entry in the hash overrides #send' do
|
@@ -132,7 +132,7 @@ describe "#include matcher" do
|
|
132
132
|
it 'fails if target is missing any item as a key' do
|
133
133
|
expect {
|
134
134
|
expect({:key => 'value'}).to include(:key, :other)
|
135
|
-
}.to fail_matching(%Q|expected {:key=>"value"} to include :key and :other|)
|
135
|
+
}.to fail_matching(%Q|expected {:key => "value"} to include :key and :other|)
|
136
136
|
end
|
137
137
|
end
|
138
138
|
end
|
@@ -182,7 +182,7 @@ describe "#include matcher" do
|
|
182
182
|
it "fails if target includes expected key" do
|
183
183
|
expect {
|
184
184
|
expect({:key => 'value'}).not_to include(:key)
|
185
|
-
}.to fail_matching(%Q|expected {:key=>"value"} not to include :key|)
|
185
|
+
}.to fail_matching(%Q|expected {:key => "value"} not to include :key|)
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
@@ -215,13 +215,13 @@ describe "#include matcher" do
|
|
215
215
|
it "fails if the target includes all of the expected keys" do
|
216
216
|
expect {
|
217
217
|
expect({ :a => 1, :b => 2 }).not_to include(:a, :b)
|
218
|
-
}.to fail_matching(%Q|expected #{
|
218
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 2} not to include :a and :b|)
|
219
219
|
end
|
220
220
|
|
221
221
|
it "fails if the target includes some (but not all) of the expected keys" do
|
222
222
|
expect {
|
223
223
|
expect({ :a => 1, :b => 2 }).not_to include(:d, :b)
|
224
|
-
}.to fail_matching(%Q|expected #{
|
224
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 2} not to include :d and :b|)
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
@@ -257,13 +257,13 @@ describe "#include matcher" do
|
|
257
257
|
it "fails if target has a different value for key" do
|
258
258
|
expect {
|
259
259
|
expect({:key => 'different'}).to include(:key => 'value')
|
260
|
-
}.to fail_matching(%Q|expected {:key=>"different"} to include {:key=>"value"}|)
|
260
|
+
}.to fail_matching(%Q|expected {:key => "different"} to include {:key => "value"}|)
|
261
261
|
end
|
262
262
|
|
263
263
|
it "fails if target has a different key" do
|
264
264
|
expect {
|
265
265
|
expect({:other => 'value'}).to include(:key => 'value')
|
266
|
-
}.to fail_matching(%Q|expected {:other=>"value"} to include {:key=>"value"}|)
|
266
|
+
}.to fail_matching(%Q|expected {:other => "value"} to include {:key => "value"}|)
|
267
267
|
end
|
268
268
|
end
|
269
269
|
|
@@ -271,7 +271,7 @@ describe "#include matcher" do
|
|
271
271
|
it "fails if the target does not contain the given hash" do
|
272
272
|
expect {
|
273
273
|
expect(['a', 'b']).to include(:key => 'value')
|
274
|
-
}.to fail_matching(%q|expected ["a", "b"] to include {:key=>"value"}|)
|
274
|
+
}.to fail_matching(%q|expected ["a", "b"] to include {:key => "value"}|)
|
275
275
|
end
|
276
276
|
|
277
277
|
it "passes if the target contains the given hash" do
|
@@ -285,13 +285,13 @@ describe "#include matcher" do
|
|
285
285
|
it "fails if target includes the key/value pair" do
|
286
286
|
expect {
|
287
287
|
expect({:key => 'value'}).not_to include(:key => 'value')
|
288
|
-
}.to fail_matching(%Q|expected {:key=>"value"} not to include {:key=>"value"}|)
|
288
|
+
}.to fail_matching(%Q|expected {:key => "value"} not to include {:key => "value"}|)
|
289
289
|
end
|
290
290
|
|
291
291
|
it "fails if target includes the key/value pair among others" do
|
292
292
|
expect {
|
293
293
|
expect({:key => 'value', :other => 'different'}).not_to include(:key => 'value')
|
294
|
-
}.to fail_matching(%Q|expected #{
|
294
|
+
}.to fail_matching(%Q|expected #{hash_inspect :key => "value", :other => "different"} not to include {:key => "value"}|)
|
295
295
|
end
|
296
296
|
|
297
297
|
it "passes if target has a different value for key" do
|
@@ -311,7 +311,7 @@ describe "#include matcher" do
|
|
311
311
|
it "fails if the target contains the given hash" do
|
312
312
|
expect {
|
313
313
|
expect(['a', { :key => 'value' } ]).not_to include(:key => 'value')
|
314
|
-
}.to fail_matching(%Q|expected ["a", {:key=>"value"}] not to include {:key=>"value"}|)
|
314
|
+
}.to fail_matching(%Q|expected ["a", {:key => "value"}] not to include {:key => "value"}|)
|
315
315
|
end
|
316
316
|
end
|
317
317
|
end
|
@@ -329,25 +329,25 @@ describe "#include matcher" do
|
|
329
329
|
it "fails if target has a different value for one of the keys" do
|
330
330
|
expect {
|
331
331
|
expect({:a => 1, :b => 2}).to include(:a => 2, :b => 2)
|
332
|
-
}.to fail_matching(%Q|expected #{
|
332
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 2} to include #{hash_inspect :a => 2, :b => 2}|)
|
333
333
|
end
|
334
334
|
|
335
335
|
it "fails if target has a different value for both of the keys" do
|
336
336
|
expect {
|
337
337
|
expect({:a => 1, :b => 1}).to include(:a => 2, :b => 2)
|
338
|
-
}.to fail_matching(%Q|expected #{
|
338
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 1} to include #{hash_inspect :a => 2, :b => 2}|)
|
339
339
|
end
|
340
340
|
|
341
341
|
it "fails if target lacks one of the keys" do
|
342
342
|
expect {
|
343
343
|
expect({:a => 1, :b => 1}).to include(:a => 1, :c => 1)
|
344
|
-
}.to fail_matching(%Q|expected #{
|
344
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 1} to include #{hash_inspect :a => 1, :c => 1}|)
|
345
345
|
end
|
346
346
|
|
347
347
|
it "fails if target lacks both of the keys" do
|
348
348
|
expect {
|
349
349
|
expect({:a => 1, :b => 1}).to include(:c => 1, :d => 1)
|
350
|
-
}.to fail_matching(%Q|expected #{
|
350
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 1} to include #{hash_inspect :c => 1, :d => 1}|)
|
351
351
|
end
|
352
352
|
end
|
353
353
|
|
@@ -355,7 +355,7 @@ describe "#include matcher" do
|
|
355
355
|
it "fails if the target does not contain the given hash" do
|
356
356
|
expect {
|
357
357
|
expect(['a', 'b']).to include(:a => 1, :b => 1)
|
358
|
-
}.to fail_matching(%Q|expected ["a", "b"] to include #{
|
358
|
+
}.to fail_matching(%Q|expected ["a", "b"] to include #{hash_inspect :a => 1, :b => 1}|)
|
359
359
|
end
|
360
360
|
|
361
361
|
it "passes if the target contains the given hash" do
|
@@ -369,20 +369,20 @@ describe "#include matcher" do
|
|
369
369
|
it "fails if target includes the key/value pairs" do
|
370
370
|
expect {
|
371
371
|
expect({:a => 1, :b => 2}).not_to include(:a => 1, :b => 2)
|
372
|
-
}.to fail_matching(%Q|expected #{
|
372
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 2} not to include #{hash_inspect :a => 1, :b => 2}|)
|
373
373
|
end
|
374
374
|
|
375
375
|
it "fails if target includes the key/value pairs among others" do
|
376
376
|
hash = {:a => 1, :b => 2, :c => 3}
|
377
377
|
expect {
|
378
378
|
expect(hash).not_to include(:a => 1, :b => 2)
|
379
|
-
}.to fail_matching(%Q|expected #{
|
379
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 2, :c => 3} not to include #{hash_inspect :a => 1, :b => 2}|)
|
380
380
|
end
|
381
381
|
|
382
382
|
it "fails if target has a different value for one of the keys" do
|
383
383
|
expect {
|
384
384
|
expect({:a => 1, :b => 2}).not_to include(:a => 2, :b => 2)
|
385
|
-
}.to fail_matching(%Q|expected #{
|
385
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 2} not to include #{hash_inspect :a => 2, :b => 2}|)
|
386
386
|
end
|
387
387
|
|
388
388
|
it "passes if target has a different value for both of the keys" do
|
@@ -392,7 +392,7 @@ describe "#include matcher" do
|
|
392
392
|
it "fails if target lacks one of the keys" do
|
393
393
|
expect {
|
394
394
|
expect({:a => 1, :b => 1}).not_to include(:a => 1, :c => 1)
|
395
|
-
}.to fail_matching(%Q|expected #{
|
395
|
+
}.to fail_matching(%Q|expected #{hash_inspect :a => 1, :b => 1} not to include #{hash_inspect :a => 1, :c => 1}|)
|
396
396
|
end
|
397
397
|
|
398
398
|
it "passes if target lacks both of the keys" do
|
@@ -408,124 +408,133 @@ describe "#include matcher" do
|
|
408
408
|
it "fails if the target contains the given hash" do
|
409
409
|
expect {
|
410
410
|
expect(['a', { :a => 1, :b => 2 } ]).not_to include(:a => 1, :b => 2)
|
411
|
-
}.to fail_matching(%Q|expected
|
411
|
+
}.to fail_matching(%Q|expected ["a", #{hash_inspect :a => 1, :b => 2}] not to include #{hash_inspect :a => 1, :b => 2}|)
|
412
412
|
end
|
413
413
|
end
|
414
414
|
end
|
415
|
-
end
|
416
|
-
|
417
|
-
RSpec::Matchers.define :a_string_containing do |expected|
|
418
|
-
match do |actual|
|
419
|
-
actual.include?(expected)
|
420
|
-
end
|
421
415
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
416
|
+
describe "Composing matchers with `include`" do
|
417
|
+
RSpec::Matchers.define :a_string_containing do |expected|
|
418
|
+
match do |actual|
|
419
|
+
actual.include?(expected)
|
420
|
+
end
|
426
421
|
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
expect(['foo', 'bar', 'baz']).to include(a_string_containing("ar"))
|
422
|
+
description do
|
423
|
+
"a string containing '#{expected}'"
|
424
|
+
end
|
431
425
|
end
|
432
426
|
|
433
|
-
|
434
|
-
|
435
|
-
expect([
|
436
|
-
|
437
|
-
end
|
427
|
+
describe "expect(array).to include(matcher)" do
|
428
|
+
it "passes when the matcher matches one of the values" do
|
429
|
+
expect([10, 20, 30]).to include( a_value_within(5).of(24) )
|
430
|
+
end
|
438
431
|
|
439
|
-
|
440
|
-
|
441
|
-
expect(
|
442
|
-
|
443
|
-
expect(e.message).not_to match(/diff/i)
|
444
|
-
}
|
445
|
-
end
|
432
|
+
it 'provides a description' do
|
433
|
+
description = include( a_value_within(5).of(24) ).description
|
434
|
+
expect(description).to eq("include (a value within 5 of 24)")
|
435
|
+
end
|
446
436
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
end
|
437
|
+
it 'fails with a clear message when the matcher matches none of the values' do
|
438
|
+
expect {
|
439
|
+
expect([10, 30]).to include( a_value_within(5).of(24) )
|
440
|
+
}.to fail_with("expected [10, 30] to include (a value within 5 of 24)")
|
452
441
|
end
|
453
442
|
|
454
|
-
|
443
|
+
it 'works with comparison matchers' do
|
444
|
+
expect {
|
445
|
+
expect([100, 200]).to include(a_value < 90)
|
446
|
+
}.to fail_with("expected [100, 200] to include (a value < 90)")
|
455
447
|
|
456
|
-
|
457
|
-
|
458
|
-
}.to fail_matching("expected [#{domain.new("rspec.info").inspect}] to include")
|
459
|
-
end
|
448
|
+
expect([100, 200]).to include(a_value > 150)
|
449
|
+
end
|
460
450
|
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
451
|
+
it 'does not treat an object that only implements #matches? as a matcher' do
|
452
|
+
domain = Struct.new(:domain) do
|
453
|
+
def matches?(url)
|
454
|
+
URI(url).host == self.domain
|
455
|
+
end
|
465
456
|
end
|
466
457
|
|
467
|
-
|
468
|
-
(actual % @expected).zero?
|
469
|
-
end
|
458
|
+
expect([domain.new("rspec.info")]).to include(domain.new("rspec.info"))
|
470
459
|
|
471
|
-
|
472
|
-
"
|
473
|
-
|
460
|
+
expect {
|
461
|
+
expect([domain.new("rspec.info")]).to include(domain.new("foo.com"))
|
462
|
+
}.to fail_matching("expected [#{domain.new("rspec.info").inspect}] to include")
|
474
463
|
end
|
464
|
+
end
|
475
465
|
|
476
|
-
|
477
|
-
|
466
|
+
describe "expect(array).to include(multiple, matcher, arguments)" do
|
467
|
+
it "passes if target includes items satisfying all matchers" do
|
468
|
+
expect(['foo', 'bar', 'baz']).to include(a_string_containing("ar"), a_string_containing('oo'))
|
469
|
+
end
|
478
470
|
|
479
|
-
|
480
|
-
expect
|
481
|
-
|
471
|
+
it "fails if target does not include an item satisfying any one of the items" do
|
472
|
+
expect {
|
473
|
+
expect(['foo', 'bar', 'baz']).to include(a_string_containing("ar"), a_string_containing("abc"))
|
474
|
+
}.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} to include (a string containing 'ar') and (a string containing 'abc')|)
|
475
|
+
end
|
476
|
+
end
|
482
477
|
|
483
|
-
|
478
|
+
describe "expect(hash).to include(key => matcher)" do
|
479
|
+
it "passes when the matcher matches" do
|
480
|
+
expect(:a => 12).to include(:a => a_value_within(3).of(10))
|
481
|
+
end
|
484
482
|
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
end
|
490
|
-
end
|
483
|
+
it 'provides a description' do
|
484
|
+
description = include(:a => a_value_within(3).of(10)).description
|
485
|
+
expect(description).to eq("include {:a => (a value within 3 of 10)}")
|
486
|
+
end
|
491
487
|
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
488
|
+
it "fails with a clear message when the matcher does not match" do
|
489
|
+
expect {
|
490
|
+
expect(:a => 15).to include(:a => a_value_within(3).of(10))
|
491
|
+
}.to fail_matching("expected {:a => 15} to include {:a => (a value within 3 of 10)}")
|
492
|
+
end
|
496
493
|
end
|
497
494
|
|
498
|
-
|
499
|
-
|
500
|
-
expect(
|
501
|
-
|
502
|
-
end
|
495
|
+
describe "expect(hash).to include(key_matcher)" do
|
496
|
+
it "passes when the matcher matches a key", :if => (RUBY_VERSION.to_f > 1.8) do
|
497
|
+
expect(:drink => "water", :food => "bread").to include(a_string_matching(/foo/))
|
498
|
+
end
|
503
499
|
|
504
|
-
|
505
|
-
|
506
|
-
expect(
|
507
|
-
|
508
|
-
|
509
|
-
|
500
|
+
it 'provides a description' do
|
501
|
+
description = include(a_string_matching(/foo/)).description
|
502
|
+
expect(description).to eq("include (a string matching /foo/)")
|
503
|
+
end
|
504
|
+
|
505
|
+
it 'fails with a clear message when the matcher does not match', :if => (RUBY_VERSION.to_f > 1.8) do
|
506
|
+
expect {
|
507
|
+
expect(:drink => "water", :food => "bread").to include(a_string_matching(/bar/))
|
508
|
+
}.to fail_matching('expected {:drink => "water", :food => "bread"} to include (a string matching /bar/)')
|
509
|
+
end
|
510
510
|
end
|
511
|
-
end
|
512
|
-
end
|
513
511
|
|
514
|
-
describe "expect(
|
515
|
-
|
516
|
-
|
517
|
-
|
512
|
+
describe "expect(array).not_to include(multiple, matcher, arguments)" do
|
513
|
+
it "passes if none of the target values satisfies any of the matchers" do
|
514
|
+
expect(['foo', 'bar', 'baz']).not_to include(a_string_containing("gh"), a_string_containing('de'))
|
515
|
+
end
|
518
516
|
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
517
|
+
it 'fails if all of the matchers are satisfied by one of the target values' do
|
518
|
+
expect {
|
519
|
+
expect(['foo', 'bar', 'baz']).not_to include(a_string_containing("ar"), a_string_containing('az'))
|
520
|
+
}.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} not to include (a string containing 'ar') and (a string containing 'az')|)
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'fails if the some (but not all) of the matchers are satisifed' do
|
524
|
+
expect {
|
525
|
+
expect(['foo', 'bar', 'baz']).not_to include(a_string_containing("ar"), a_string_containing('bz'))
|
526
|
+
}.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} not to include (a string containing 'ar') and (a string containing 'bz')|)
|
527
|
+
end
|
528
|
+
end
|
523
529
|
end
|
524
530
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
531
|
+
include RSpec::Matchers::Pretty
|
532
|
+
# We have to use Hash#inspect in examples that have multi-entry
|
533
|
+
# hashes because the #inspect output on 1.8.7 is non-deterministic
|
534
|
+
# due to the fact that hashes are not ordered. So we can't simply
|
535
|
+
# put a literal string for what we expect because it varies.
|
536
|
+
def hash_inspect(hash)
|
537
|
+
improve_hash_formatting(hash.inspect)
|
529
538
|
end
|
530
539
|
end
|
531
540
|
|