rspec-expectations 2.10.0 → 2.11.0
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/Changelog.md +24 -1
- data/README.md +36 -2
- data/features/built_in_matchers/be.feature +52 -14
- data/features/syntax_configuration.feature +68 -0
- data/lib/rspec/expectations.rb +2 -0
- data/lib/rspec/expectations/expectation_target.rb +52 -0
- data/lib/rspec/expectations/extensions.rb +0 -1
- data/lib/rspec/expectations/syntax.rb +105 -0
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +12 -5
- data/lib/rspec/matchers/built_in/base_matcher.rb +16 -7
- data/lib/rspec/matchers/built_in/be.rb +27 -25
- data/lib/rspec/matchers/built_in/be_instance_of.rb +3 -5
- data/lib/rspec/matchers/built_in/be_kind_of.rb +3 -5
- data/lib/rspec/matchers/built_in/be_within.rb +17 -11
- data/lib/rspec/matchers/built_in/cover.rb +5 -6
- data/lib/rspec/matchers/built_in/eq.rb +4 -8
- data/lib/rspec/matchers/built_in/eql.rb +3 -5
- data/lib/rspec/matchers/built_in/equal.rb +6 -10
- data/lib/rspec/matchers/built_in/exist.rb +11 -13
- data/lib/rspec/matchers/built_in/include.rb +5 -6
- data/lib/rspec/matchers/built_in/match.rb +3 -4
- data/lib/rspec/matchers/built_in/match_array.rb +7 -14
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +1 -3
- data/lib/rspec/matchers/built_in/yield.rb +2 -5
- data/lib/rspec/matchers/configuration.rb +66 -0
- data/spec/rspec/expectations/expectation_target_spec.rb +65 -0
- data/spec/rspec/expectations/extensions/kernel_spec.rb +22 -0
- data/spec/rspec/matchers/base_matcher_spec.rb +8 -6
- data/spec/rspec/matchers/be_spec.rb +2 -2
- data/spec/rspec/matchers/be_within_spec.rb +9 -1
- data/spec/rspec/matchers/configuration_spec.rb +160 -0
- data/spec/rspec/matchers/eq_spec.rb +16 -4
- data/spec/rspec/matchers/equal_spec.rb +7 -7
- data/spec/rspec/matchers/match_array_spec.rb +12 -0
- data/spec/rspec/matchers/yield_spec.rb +3 -3
- data/spec/support/in_sub_process.rb +31 -0
- metadata +16 -9
- data/lib/rspec/expectations/extensions/kernel.rb +0 -26
- data/lib/rspec/matchers/block_aliases.rb +0 -21
- data/spec/rspec/matchers/compatibility_spec.rb +0 -28
@@ -64,9 +64,7 @@ module RSpec
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
class YieldControl
|
68
|
-
include BaseMatcher
|
69
|
-
|
67
|
+
class YieldControl < BaseMatcher
|
70
68
|
def matches?(block)
|
71
69
|
probe = YieldProbe.probe(block)
|
72
70
|
probe.yielded_once?(:yield_control)
|
@@ -81,8 +79,7 @@ module RSpec
|
|
81
79
|
end
|
82
80
|
end
|
83
81
|
|
84
|
-
class YieldWithNoArgs
|
85
|
-
include BaseMatcher
|
82
|
+
class YieldWithNoArgs < BaseMatcher
|
86
83
|
|
87
84
|
def matches?(block)
|
88
85
|
@probe = YieldProbe.probe(block)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rspec/expectations/syntax'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Matchers
|
5
|
+
# Provides configuration options for rspec-expectations.
|
6
|
+
class Configuration
|
7
|
+
# Configures the supported syntax.
|
8
|
+
# @param [Array<Symbol>, Symbol] values the syntaxes to enable
|
9
|
+
# @example
|
10
|
+
# RSpec.configure do |rspec|
|
11
|
+
# rspec.expect_with :rspec do |c|
|
12
|
+
# c.syntax = :should
|
13
|
+
# # or
|
14
|
+
# c.syntax = :expect
|
15
|
+
# # or
|
16
|
+
# c.syntax = [:should, :expect]
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
def syntax=(values)
|
20
|
+
if Array(values).include?(:expect)
|
21
|
+
Expectations::Syntax.enable_expect
|
22
|
+
else
|
23
|
+
Expectations::Syntax.disable_expect
|
24
|
+
end
|
25
|
+
|
26
|
+
if Array(values).include?(:should)
|
27
|
+
Expectations::Syntax.enable_should
|
28
|
+
else
|
29
|
+
Expectations::Syntax.disable_should
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# The list of configured syntaxes.
|
34
|
+
# @return [Array<Symbol>] the list of configured syntaxes.
|
35
|
+
def syntax
|
36
|
+
syntaxes = []
|
37
|
+
syntaxes << :should if Expectations::Syntax.should_enabled?
|
38
|
+
syntaxes << :expect if Expectations::Syntax.expect_enabled?
|
39
|
+
syntaxes
|
40
|
+
end
|
41
|
+
|
42
|
+
# Adds `should` and `should_not` to the given classes
|
43
|
+
# or modules. This can be used to ensure `should` works
|
44
|
+
# properly on things like proxy objects (particular
|
45
|
+
# `Delegator`-subclassed objects on 1.8).
|
46
|
+
#
|
47
|
+
# @param [Array<Module>] modules the list of classes or modules
|
48
|
+
# to add `should` and `should_not` to.
|
49
|
+
def add_should_and_should_not_to(*modules)
|
50
|
+
modules.each do |mod|
|
51
|
+
Expectations::Syntax.enable_should(mod)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# The configuration object
|
57
|
+
# @return [RSpec::Matchers::Configuration] the configuration object
|
58
|
+
def self.configuration
|
59
|
+
@configuration ||= Configuration.new
|
60
|
+
end
|
61
|
+
|
62
|
+
# set default syntax
|
63
|
+
configuration.syntax = [:expect, :should]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Expectations
|
5
|
+
# so our examples below can set expectations about the target
|
6
|
+
ExpectationTarget.send(:attr_reader, :target)
|
7
|
+
|
8
|
+
describe ExpectationTarget do
|
9
|
+
context 'when constructed via #expect' do
|
10
|
+
it 'constructs a new instance targetting the given argument' do
|
11
|
+
expect(7).target.should eq(7)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'constructs a new instance targetting the given block' do
|
15
|
+
block = lambda {}
|
16
|
+
expect(&block).target.should be(block)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'raises an ArgumentError when given an argument and a block' do
|
20
|
+
lambda { expect(7) { } }.should raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'raises an ArgumentError when given neither an argument nor a block' do
|
24
|
+
lambda { expect }.should raise_error(ArgumentError)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can be passed nil' do
|
28
|
+
expect(nil).target.should be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'passes a valid positive expectation' do
|
32
|
+
expect(5).to eq(5)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'passes a valid negative expectation' do
|
36
|
+
expect(5).to_not eq(4)
|
37
|
+
expect(5).not_to eq(4)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'fails an invalid positive expectation' do
|
41
|
+
lambda { expect(5).to eq(4) }.should fail_with(/expected: 4.*got: 5/m)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'fails an invalid negative expectation' do
|
45
|
+
message = /expected 5 not to be a kind of Fixnum/
|
46
|
+
lambda { expect(5).to_not be_a(Fixnum) }.should fail_with(message)
|
47
|
+
lambda { expect(5).not_to be_a(Fixnum) }.should fail_with(message)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'does not support operator matchers from #to' do
|
51
|
+
expect {
|
52
|
+
expect(3).to == 3
|
53
|
+
}.to raise_error(ArgumentError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'does not support operator matchers from #not_to' do
|
57
|
+
expect {
|
58
|
+
expect(3).not_to == 4
|
59
|
+
}.to raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -20,6 +20,28 @@ describe Object, "#should" do
|
|
20
20
|
@target.should @matcher
|
21
21
|
}.should fail_with("the failure message")
|
22
22
|
end
|
23
|
+
|
24
|
+
context "on interpretters that have BasicObject", :if => defined?(BasicObject) do
|
25
|
+
let(:proxy_class) do
|
26
|
+
Class.new(BasicObject) do
|
27
|
+
def initialize(target)
|
28
|
+
@target = target
|
29
|
+
end
|
30
|
+
|
31
|
+
def proxied?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(name, *args)
|
36
|
+
@target.send(name, *args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'works properly on BasicObject-subclassed proxy objects' do
|
42
|
+
proxy_class.new(Object.new).should be_proxied
|
43
|
+
end
|
44
|
+
end
|
23
45
|
end
|
24
46
|
|
25
47
|
describe Object, "#should_not" do
|
@@ -2,9 +2,7 @@ module RSpec::Matchers::BuiltIn
|
|
2
2
|
describe BaseMatcher do
|
3
3
|
describe "#match_unless_raises" do
|
4
4
|
let(:matcher) do
|
5
|
-
Class.new
|
6
|
-
include BaseMatcher
|
7
|
-
end.new
|
5
|
+
Class.new(BaseMatcher).new
|
8
6
|
end
|
9
7
|
|
10
8
|
it "returns true if there are no errors" do
|
@@ -41,12 +39,16 @@ module RSpec::Matchers::BuiltIn
|
|
41
39
|
|
42
40
|
describe "#==" do
|
43
41
|
it "responds the same way as matches?" do
|
44
|
-
matcher = Class.new do
|
45
|
-
|
42
|
+
matcher = Class.new(BaseMatcher) do
|
43
|
+
def initialize(expected)
|
44
|
+
@expected = expected
|
45
|
+
end
|
46
|
+
|
46
47
|
def matches?(actual)
|
47
|
-
actual == expected
|
48
|
+
(@actual = actual) == @expected
|
48
49
|
end
|
49
50
|
end
|
51
|
+
|
50
52
|
matcher.new(3).matches?(3).should be_true
|
51
53
|
matcher.new(3).should eq(3)
|
52
54
|
|
@@ -237,7 +237,7 @@ describe "should be_true" do
|
|
237
237
|
it "fails when actual equal?(false)" do
|
238
238
|
lambda {
|
239
239
|
false.should be_true
|
240
|
-
}.should fail_with("expected
|
240
|
+
}.should fail_with("expected: true value\n got: false")
|
241
241
|
end
|
242
242
|
end
|
243
243
|
|
@@ -253,7 +253,7 @@ describe "should be_false" do
|
|
253
253
|
it "fails when actual equal?(true)" do
|
254
254
|
lambda {
|
255
255
|
true.should be_false
|
256
|
-
}.should fail_with("expected
|
256
|
+
}.should fail_with("expected: false value\n got: true")
|
257
257
|
end
|
258
258
|
end
|
259
259
|
|
@@ -57,7 +57,15 @@ module RSpec
|
|
57
57
|
|
58
58
|
it "raises an error if no expected value is given" do
|
59
59
|
matcher = be_within(0.5)
|
60
|
-
expect { matcher.matches?(5.1) }.to raise_error(
|
60
|
+
expect { matcher.matches?(5.1) }.to raise_error(
|
61
|
+
ArgumentError, /must set an expected value using #of/
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises an error if the actual value is not of a Numeric type" do
|
66
|
+
expect { be_within(0.1).of(0).matches?(nil) }.to raise_error(
|
67
|
+
ArgumentError, /The actual value \(nil\) must be of a `Numeric` type/
|
68
|
+
)
|
61
69
|
end
|
62
70
|
end
|
63
71
|
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'delegate'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Matchers
|
6
|
+
describe ".configuration" do
|
7
|
+
it 'returns a memoized configuration instance' do
|
8
|
+
RSpec::Matchers.configuration.should be_a(RSpec::Matchers::Configuration)
|
9
|
+
RSpec::Matchers.configuration.should be(RSpec::Matchers.configuration)
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'on an interpreter that does not provide BasicObject', :unless => defined?(::BasicObject) do
|
13
|
+
before { RSpec::Expectations::Syntax.disable_should(Delegator) }
|
14
|
+
|
15
|
+
let(:klass) do
|
16
|
+
Class.new(SimpleDelegator) do
|
17
|
+
def delegated?; true; end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:instance) { klass.new(Object.new) }
|
22
|
+
|
23
|
+
it 'provides a means to manually add it Delegator' do
|
24
|
+
instance.should_not respond_to(:delegated?) # because #should is being delegated...
|
25
|
+
RSpec::Matchers.configuration.add_should_and_should_not_to Delegator
|
26
|
+
instance.should respond_to(:delegated?) # now it should work!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
shared_examples_for "configuring the expectation syntax" do
|
32
|
+
# We want a sandboxed method that ensures that we wind up with
|
33
|
+
# both syntaxes properly enabled when the example ends.
|
34
|
+
#
|
35
|
+
# On platforms that fork, using a sub process is the easiest,
|
36
|
+
# most robust way to achieve that.
|
37
|
+
#
|
38
|
+
# On jRuby we just re-enable both syntaxes at the end of the example;
|
39
|
+
# however, this is a generally inferior approach because it depends on
|
40
|
+
# the code-under-test working properly; if it doesn't work properly,
|
41
|
+
# it could leave things in a "broken" state where tons of other examples fail.
|
42
|
+
if RUBY_PLATFORM == "java"
|
43
|
+
def sandboxed
|
44
|
+
yield
|
45
|
+
ensure
|
46
|
+
configure_syntax([:should, :expect])
|
47
|
+
end
|
48
|
+
else
|
49
|
+
include InSubProcess
|
50
|
+
alias sandboxed in_sub_process
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'is configured to :should and :expect by default' do
|
54
|
+
configured_syntax.should eq([:should, :expect])
|
55
|
+
|
56
|
+
3.should eq(3)
|
57
|
+
3.should_not eq(4)
|
58
|
+
expect(3).to eq(3)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'can limit the syntax to :should' do
|
62
|
+
sandboxed do
|
63
|
+
configure_syntax :should
|
64
|
+
configured_syntax.should eq([:should])
|
65
|
+
|
66
|
+
3.should eq(3)
|
67
|
+
3.should_not eq(4)
|
68
|
+
lambda { expect(6).to eq(6) }.should raise_error(NameError)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'is a no-op when configured to :should twice' do
|
73
|
+
sandboxed do
|
74
|
+
::Kernel.stub(:method_added).and_raise("no methods should be added here")
|
75
|
+
|
76
|
+
configure_syntax :should
|
77
|
+
configure_syntax :should
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'can limit the syntax to :expect' do
|
82
|
+
sandboxed do
|
83
|
+
configure_syntax :expect
|
84
|
+
expect(configured_syntax).to eq([:expect])
|
85
|
+
|
86
|
+
expect(3).to eq(3)
|
87
|
+
expect { 3.should eq(3) }.to raise_error(NameError)
|
88
|
+
expect { 3.should_not eq(3) }.to raise_error(NameError)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'is a no-op when configured to :expect twice' do
|
93
|
+
sandboxed do
|
94
|
+
RSpec::Matchers.stub(:method_added).and_raise("no methods should be added here")
|
95
|
+
|
96
|
+
configure_syntax :expect
|
97
|
+
configure_syntax :expect
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'can re-enable the :should syntax' do
|
102
|
+
sandboxed do
|
103
|
+
configure_syntax :expect
|
104
|
+
configure_syntax [:should, :expect]
|
105
|
+
configured_syntax.should eq([:should, :expect])
|
106
|
+
|
107
|
+
3.should eq(3)
|
108
|
+
3.should_not eq(4)
|
109
|
+
expect(3).to eq(3)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'can re-enable the :expect syntax' do
|
114
|
+
sandboxed do
|
115
|
+
configure_syntax :should
|
116
|
+
configure_syntax [:should, :expect]
|
117
|
+
configured_syntax.should eq([:should, :expect])
|
118
|
+
|
119
|
+
3.should eq(3)
|
120
|
+
3.should_not eq(4)
|
121
|
+
expect(3).to eq(3)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "configuring rspec-expectations directly" do
|
127
|
+
it_behaves_like "configuring the expectation syntax" do
|
128
|
+
def configure_syntax(syntax)
|
129
|
+
RSpec::Matchers.configuration.syntax = syntax
|
130
|
+
end
|
131
|
+
|
132
|
+
def configured_syntax
|
133
|
+
RSpec::Matchers.configuration.syntax
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "configuring using the rspec-core config API" do
|
139
|
+
it_behaves_like "configuring the expectation syntax" do
|
140
|
+
def configure_syntax(syntax)
|
141
|
+
RSpec.configure do |rspec|
|
142
|
+
rspec.expect_with :rspec do |c|
|
143
|
+
c.syntax = syntax
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def configured_syntax
|
149
|
+
RSpec.configure do |rspec|
|
150
|
+
rspec.expect_with :rspec do |c|
|
151
|
+
return c.syntax
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
@@ -14,23 +14,35 @@ module RSpec
|
|
14
14
|
it "does not match when actual != expected" do
|
15
15
|
1.should_not eq(2)
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
|
+
it "compares by sending == to actual (not expected)" do
|
19
|
+
called = false
|
20
|
+
actual = Class.new do
|
21
|
+
define_method :== do |other|
|
22
|
+
called = true
|
23
|
+
end
|
24
|
+
end.new
|
25
|
+
|
26
|
+
actual.should eq :anything # to trigger the matches? method
|
27
|
+
called.should be_true
|
28
|
+
end
|
29
|
+
|
18
30
|
it "describes itself" do
|
19
31
|
matcher = eq(1)
|
20
32
|
matcher.matches?(1)
|
21
|
-
matcher.description.should
|
33
|
+
matcher.description.should eq "eq 1"
|
22
34
|
end
|
23
35
|
|
24
36
|
it "provides message, expected and actual on #failure_message" do
|
25
37
|
matcher = eq("1")
|
26
38
|
matcher.matches?(1)
|
27
|
-
matcher.failure_message_for_should.should
|
39
|
+
matcher.failure_message_for_should.should eq "\nexpected: \"1\"\n got: 1\n\n(compared using ==)\n"
|
28
40
|
end
|
29
41
|
|
30
42
|
it "provides message, expected and actual on #negative_failure_message" do
|
31
43
|
matcher = eq(1)
|
32
44
|
matcher.matches?(1)
|
33
|
-
matcher.failure_message_for_should_not.should
|
45
|
+
matcher.failure_message_for_should_not.should eq "\nexpected: value != 1\n got: 1\n\n(compared using ==)\n"
|
34
46
|
end
|
35
47
|
end
|
36
48
|
end
|