rspec-expectations 2.10.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Changelog.md +24 -1
  2. data/README.md +36 -2
  3. data/features/built_in_matchers/be.feature +52 -14
  4. data/features/syntax_configuration.feature +68 -0
  5. data/lib/rspec/expectations.rb +2 -0
  6. data/lib/rspec/expectations/expectation_target.rb +52 -0
  7. data/lib/rspec/expectations/extensions.rb +0 -1
  8. data/lib/rspec/expectations/syntax.rb +105 -0
  9. data/lib/rspec/expectations/version.rb +1 -1
  10. data/lib/rspec/matchers.rb +12 -5
  11. data/lib/rspec/matchers/built_in/base_matcher.rb +16 -7
  12. data/lib/rspec/matchers/built_in/be.rb +27 -25
  13. data/lib/rspec/matchers/built_in/be_instance_of.rb +3 -5
  14. data/lib/rspec/matchers/built_in/be_kind_of.rb +3 -5
  15. data/lib/rspec/matchers/built_in/be_within.rb +17 -11
  16. data/lib/rspec/matchers/built_in/cover.rb +5 -6
  17. data/lib/rspec/matchers/built_in/eq.rb +4 -8
  18. data/lib/rspec/matchers/built_in/eql.rb +3 -5
  19. data/lib/rspec/matchers/built_in/equal.rb +6 -10
  20. data/lib/rspec/matchers/built_in/exist.rb +11 -13
  21. data/lib/rspec/matchers/built_in/include.rb +5 -6
  22. data/lib/rspec/matchers/built_in/match.rb +3 -4
  23. data/lib/rspec/matchers/built_in/match_array.rb +7 -14
  24. data/lib/rspec/matchers/built_in/start_and_end_with.rb +1 -3
  25. data/lib/rspec/matchers/built_in/yield.rb +2 -5
  26. data/lib/rspec/matchers/configuration.rb +66 -0
  27. data/spec/rspec/expectations/expectation_target_spec.rb +65 -0
  28. data/spec/rspec/expectations/extensions/kernel_spec.rb +22 -0
  29. data/spec/rspec/matchers/base_matcher_spec.rb +8 -6
  30. data/spec/rspec/matchers/be_spec.rb +2 -2
  31. data/spec/rspec/matchers/be_within_spec.rb +9 -1
  32. data/spec/rspec/matchers/configuration_spec.rb +160 -0
  33. data/spec/rspec/matchers/eq_spec.rb +16 -4
  34. data/spec/rspec/matchers/equal_spec.rb +7 -7
  35. data/spec/rspec/matchers/match_array_spec.rb +12 -0
  36. data/spec/rspec/matchers/yield_spec.rb +3 -3
  37. data/spec/support/in_sub_process.rb +31 -0
  38. metadata +16 -9
  39. data/lib/rspec/expectations/extensions/kernel.rb +0 -26
  40. data/lib/rspec/matchers/block_aliases.rb +0 -21
  41. data/spec/rspec/matchers/compatibility_spec.rb +0 -28
@@ -1,9 +1,7 @@
1
1
  module RSpec
2
2
  module Matchers
3
3
  module BuiltIn
4
- class StartAndEndWith
5
- include BaseMatcher
6
-
4
+ class StartAndEndWith < BaseMatcher
7
5
  def initialize(*expected)
8
6
  @expected = expected.length == 1 ? expected.first : expected
9
7
  end
@@ -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 do
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
- include BaseMatcher
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 false to be true")
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 true to be false")
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(ArgumentError, /must set an expected value using #of/)
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 == "eq 1"
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 == "\nexpected: \"1\"\n got: 1\n\n(compared using ==)\n"
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 == "\nexpected: value != 1\n got: 1\n\n(compared using ==)\n"
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