rspec-mocks 2.5.0 → 2.6.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.travis.yml +7 -0
  2. data/Gemfile +13 -12
  3. data/Guardfile +3 -3
  4. data/README.md +2 -0
  5. data/features/.nav +4 -0
  6. data/features/Changelog.md +12 -0
  7. data/features/README.markdown +44 -4
  8. data/features/message_expectations/any_instance.feature +19 -0
  9. data/features/message_expectations/block_local_expectations.feature.pending +2 -2
  10. data/features/message_expectations/expect_message.feature +3 -3
  11. data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +3 -3
  12. data/features/method_stubs/README.md +32 -24
  13. data/features/method_stubs/any_instance.feature +23 -0
  14. data/features/method_stubs/as_null_object.feature +36 -0
  15. data/features/method_stubs/simple_return_value.feature +2 -2
  16. data/features/method_stubs/stub_chain.feature +13 -6
  17. data/features/method_stubs/stub_implementation.feature +1 -1
  18. data/features/method_stubs/to_ary.feature +45 -0
  19. data/features/outside_rspec/configuration.feature +3 -3
  20. data/features/outside_rspec/standalone.feature +2 -2
  21. data/features/step_definitions/additional_cli_steps.rb +4 -0
  22. data/features/support/env.rb +5 -1
  23. data/lib/rspec/mocks.rb +2 -1
  24. data/lib/rspec/mocks/any_instance.rb +246 -0
  25. data/lib/rspec/mocks/extensions/psych.rb +23 -0
  26. data/lib/rspec/mocks/framework.rb +1 -0
  27. data/lib/rspec/mocks/message_expectation.rb +7 -4
  28. data/lib/rspec/mocks/methods.rb +1 -1
  29. data/lib/rspec/mocks/mock.rb +2 -2
  30. data/lib/rspec/mocks/serialization.rb +5 -3
  31. data/lib/rspec/mocks/space.rb +1 -1
  32. data/lib/rspec/mocks/version.rb +1 -1
  33. data/spec/rspec/mocks/and_yield_spec.rb +3 -3
  34. data/spec/rspec/mocks/any_instance_spec.rb +578 -0
  35. data/spec/rspec/mocks/any_number_of_times_spec.rb +22 -28
  36. data/spec/rspec/mocks/at_least_spec.rb +6 -0
  37. data/spec/rspec/mocks/at_most_spec.rb +6 -0
  38. data/spec/rspec/mocks/bug_report_10263_spec.rb +12 -14
  39. data/spec/rspec/mocks/bug_report_7611_spec.rb +2 -4
  40. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +45 -46
  41. data/spec/rspec/mocks/nil_expectation_warning_spec.rb +1 -2
  42. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +119 -122
  43. data/spec/rspec/mocks/precise_counts_spec.rb +6 -0
  44. data/spec/rspec/mocks/serialization_spec.rb +21 -3
  45. data/spec/rspec/mocks/stub_chain_spec.rb +72 -37
  46. data/spec/rspec/mocks/stub_spec.rb +64 -61
  47. data/spec/rspec/mocks/to_ary_spec.rb +31 -0
  48. metadata +32 -15
  49. data/spec/rspec/mocks/bug_report_7805_spec.rb +0 -22
  50. data/spec/rspec/mocks/bug_report_8302_spec.rb +0 -26
@@ -0,0 +1,7 @@
1
+ script: "rake"
2
+ rvm:
3
+ - 1.8.6
4
+ - 1.8.7
5
+ - 1.9.1
6
+ - 1.9.2
7
+ - ree
data/Gemfile CHANGED
@@ -6,29 +6,31 @@ source "http://rubygems.org"
6
6
  if File.exist?(library_path)
7
7
  gem lib, :path => library_path
8
8
  else
9
- gem lib
9
+ gem lib, :git => "git://github.com/rspec/#{lib}.git"
10
10
  end
11
11
  end
12
12
 
13
13
  ### dev dependencies
14
14
  gem "rake", "0.8.7"
15
- gem "cucumber", "0.9.4"
16
- gem "aruba", "0.2.2"
17
- gem "rcov", "0.9.9"
15
+ # gem "cucumber", "~> 0.10.2"
16
+ # gem "aruba", :git => "git://github.com/aslakhellesoy/aruba"
17
+ gem "rcov", "0.9.9", :platforms => :mri
18
18
  gem "relish", "0.2.0"
19
19
  gem "guard-rspec", "0.1.9"
20
20
  gem "growl", "1.0.3"
21
- gem "ZenTest", "~> 4.4.2"
21
+ gem "nokogiri", "1.4.4"
22
22
 
23
- if RUBY_PLATFORM =~ /darwin/
24
- gem "autotest-fsevent", "~> 0.2.4"
25
- gem "autotest-growl", "~> 0.2.9"
23
+ platforms :mri_18 do
24
+ gem 'ruby-debug'
26
25
  end
27
26
 
28
- gem "ruby-debug", :platforms => :ruby_18
29
- gem "ruby-debug19", "~> 0.11.6", :platforms => :ruby_19
27
+ platforms :mri_19 do
28
+ gem 'linecache19', '0.5.11' # 0.5.12 cannot install on 1.9.1, and 0.5.11 appears to work with both 1.9.1 & 1.9.2
29
+ gem 'ruby-debug19'
30
+ gem 'ruby-debug-base19', RUBY_VERSION == '1.9.1' ? '0.11.23' : '~> 0.11.24'
31
+ end
30
32
 
31
- platforms :ruby_18, :ruby_19 do
33
+ platforms :mri_18, :mri_19 do
32
34
  gem "rb-fsevent", "~> 0.3.9"
33
35
  gem "ruby-prof", "~> 0.9.2"
34
36
  end
@@ -36,4 +38,3 @@ end
36
38
  platforms :jruby do
37
39
  gem "jruby-openssl"
38
40
  end
39
-
data/Guardfile CHANGED
@@ -2,7 +2,7 @@
2
2
  # More info at http://github.com/guard/guard#readme
3
3
 
4
4
  guard 'rspec', :version => 2 do
5
- watch('^spec/(.*)_spec.rb')
6
- watch('^lib/(.*)\.rb') { "spec" }
7
- watch('^spec/spec_helper.rb') { "spec" }
5
+ watch(/^spec\/(.*)_spec.rb/)
6
+ watch(/^lib\/(.*)\.rb/) { "spec" }
7
+ watch(/^spec\/spec_helper.rb/) { "spec" }
8
8
  end
data/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  rspec-mocks provides a test-double framework for rspec including support
4
4
  for method stubs, fakes, and message expectations.
5
5
 
6
+ [![build status](http://travis-ci.org/rspec/rspec-mocks.png)](http://travis-ci.org/rspec/rspec-mocks)
7
+
6
8
  ## Documentation
7
9
 
8
10
  The [Cucumber features](http://relishapp.com/rspec/rspec-mocks) are the
@@ -4,8 +4,12 @@
4
4
  - simple_return_value.feature
5
5
  - stub_implementation.feature
6
6
  - stub_chain.feature
7
+ - any_instance.feature
8
+ - as_null_object.feature
9
+ - to_ary.feature
7
10
  - message_expectations:
8
11
  - expect_message.feature
12
+ - any_instance.feature
9
13
  - block_local_expectations.feature.pending
10
14
  - warn_when_expectation_is_set_on_nil.feature
11
15
  - outside_rspec:
@@ -1,3 +1,15 @@
1
+ ### 2.6.0.rc2 / 2011-04-18
2
+
3
+ [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.5.0...v2.6.1.rc2)
4
+
5
+ * Enhancements
6
+ * Add support for any_instance.stub and any_instance.should_receive (Sidu
7
+ Ponnappa and Andy Lindeman)
8
+
9
+ * Bug fixes
10
+ * fix bug in which multiple chains with shared messages ending in hashes
11
+ failed to return the correct value
12
+
1
13
  ### 2.5.0 / 2011-02-05
2
14
 
3
15
  [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.4.0...v2.5.0)
@@ -1,10 +1,46 @@
1
- rspec-mocks is used to create dynamic "doubles", which stand in for real
2
- objects in examples. You can stub return values and/or set message
3
- expectations:
1
+ rspec-mocks helps to control the context in a code example by letting you set
2
+ known return values, fake implementations of methods, and even expectations
3
+ that specific messages are received by an object.
4
+
5
+ You can do these three things on test doubles that rspec-mocks creates for you
6
+ on the fly, or you can do them on objects that are part of your system.
7
+
8
+ ## Messages and Methods
9
+
10
+ _Message_ and _method_ are metaphors that we use somewhat interchangeably, but
11
+ they are subtly different. In Object Oriented Programming, objects communicate
12
+ by sending _messages_ to one another. When an object receives a message, it
13
+ invokes a _method_ with the same name as the message.
14
+
15
+ ## Test Doubles
16
+
17
+ A test double is an object that stands in for another object in your system
18
+ during a code example. Use the `double` method to create one:
19
+
20
+ double_account = double("Account")
21
+
22
+ You can also use the `mock` and `stub` methods to create test doubles, however
23
+ these methods are there for backward compatibility only and will likely be
24
+ deprecated and then removed from future versions.
25
+
26
+ ## Method Stubs
27
+
28
+ A method stub is an instruction to an object (real or test double) to return a
29
+ known value in response to a message:
30
+
31
+ die.stub(:roll) { 3 }
32
+
33
+ This tells the `die` object to return the value `3` when it receives the `roll`
34
+ message.
35
+
36
+ ## Message Expectations
37
+
38
+ A message expectation is an expectation that an object should receive a
39
+ specific message during the course of a code example:
4
40
 
5
41
  describe Account do
6
42
  context "when closed" do
7
- it "logs an account closed message" do
43
+ it "logs an 'account closed' message" do
8
44
  logger = double()
9
45
  account = Account.new
10
46
  account.logger = logger
@@ -16,6 +52,10 @@ expectations:
16
52
  end
17
53
  end
18
54
 
55
+ This example specifies that the `account` object sends the `logger` the
56
+ `account_closed` message (with itself as an argument) when it receives the
57
+ `close` message.
58
+
19
59
  ## Issues
20
60
 
21
61
  The documentation for rspec-mocks is a work in progress. We'll be adding
@@ -0,0 +1,19 @@
1
+ Feature: expect a message on any instance of a class
2
+
3
+ Use `any_instance.should_receive` to set an expectation that one (and only
4
+ one) instance of a class receives a message before the example is completed.
5
+
6
+ Scenario: expect a message on any instance of a class
7
+ Given a file named "example_spec.rb" with:
8
+ """
9
+ describe "any_instance.should_receive" do
10
+ it "verifies that one instance of the class receives the message" do
11
+ Object.any_instance.should_receive(:foo).and_return(:return_value)
12
+
13
+ o = Object.new
14
+ o.foo.should eq(:return_value)
15
+ end
16
+ end
17
+ """
18
+ When I run `rspec example_spec.rb`
19
+ Then the examples should all pass
@@ -30,7 +30,7 @@ Feature: block local expectations
30
30
  end
31
31
  end
32
32
  """
33
- When I run "rspec ./spec/account_spec.rb"
33
+ When I run `rspec spec/account_spec.rb`
34
34
  Then the output should contain "1 example, 0 failures"
35
35
 
36
36
  Scenario: failing example
@@ -51,5 +51,5 @@ Feature: block local expectations
51
51
  end
52
52
  """
53
53
 
54
- When I run "rspec ./spec/account_spec.rb"
54
+ When I run `rspec spec/account_spec.rb`
55
55
  Then the output should contain "1 example, 1 failure"
@@ -32,7 +32,7 @@ Feature: expect a message
32
32
  end
33
33
  end
34
34
  """
35
- When I run "rspec spec/account_spec.rb"
35
+ When I run `rspec spec/account_spec.rb`
36
36
  Then the output should contain "1 example, 0 failures"
37
37
 
38
38
  Scenario: expect a message with an argument
@@ -64,7 +64,7 @@ Feature: expect a message
64
64
  end
65
65
  end
66
66
  """
67
- When I run "rspec spec/account_spec.rb"
67
+ When I run `rspec spec/account_spec.rb`
68
68
  Then the output should contain "1 example, 0 failures"
69
69
 
70
70
  Scenario: provide a return value
@@ -90,5 +90,5 @@ Feature: expect a message
90
90
  end
91
91
  end
92
92
  """
93
- When I run "rspec message_expectation_spec.rb"
93
+ When I run `rspec message_expectation_spec.rb`
94
94
  Then the output should contain "2 examples, 0 failures"
@@ -11,7 +11,7 @@ Feature: warn when expectation is set on nil
11
11
  end
12
12
  end
13
13
  """
14
- When I run "rspec ./example_spec.rb"
14
+ When I run `rspec example_spec.rb`
15
15
  Then the output should contain "An expectation of :foo was set on nil"
16
16
 
17
17
  Scenario: allow
@@ -26,7 +26,7 @@ Feature: warn when expectation is set on nil
26
26
  end
27
27
  end
28
28
  """
29
- When I run "rspec ./example_spec.rb"
29
+ When I run `rspec example_spec.rb`
30
30
  Then the output should not contain "An expectation"
31
31
 
32
32
  Scenario: allow in one example, but not on another
@@ -45,6 +45,6 @@ Feature: warn when expectation is set on nil
45
45
  end
46
46
  end
47
47
  """
48
- When I run "rspec ./example_spec.rb"
48
+ When I run `rspec example_spec.rb`
49
49
  Then the output should contain "An expectation of :bar"
50
50
  And the output should not contain "An expectation of :foo"
@@ -1,39 +1,47 @@
1
- ### Basics
1
+ ### Stub return values
2
2
 
3
- # create a double
4
- obj = double()
3
+ obj.stub(:message).and_return('this is the value to return')
4
+ obj.stub(:message) { 'this is the value to return' }
5
5
 
6
- # stub a method
7
- obj.stub(:message) # returns obj
6
+ These two forms are somewhat interchangeable. The difference is that the
7
+ argument to `and_return` is evaluated immediately, whereas the block contents
8
+ are evaluated lazily when the `obj` receives the `message` message.
8
9
 
9
- # specify a return value
10
- obj.stub(:message) { 'this is the value to return' }
10
+ The block format is generally preferred as it is more terse and more consistent
11
+ with other forms described below, but lazy evaluation can be confusing because
12
+ things aren't evaluated in the order in which they are declared.
13
+
14
+ ### Fake implementation
15
+
16
+ obj.stub(:message) do |arg1, arg2|
17
+ # set expectations about the args in this block
18
+ # and/or set a return value
19
+ end
20
+
21
+ ### Raising/Throwing
22
+
23
+ obj.stub(:message).and_raise("this error")
24
+ obj.stub(:message).and_throw(:this_symbol)
25
+
26
+ You can also use the block format, for consistency with other stubs:
27
+
28
+ obj.stub(:message) { raise "this error" }
29
+ obj.stub(:message) { throw :this_symbol }
11
30
 
12
31
  ### Argument constraints
13
32
 
14
33
  #### Explicit arguments
15
34
 
16
- obj.stub(:message).with('an argument')
17
- obj.stub(:message).with('more_than', 'one_argument')
35
+ obj.stub(:message).with('an argument') { ... }
36
+ obj.stub(:message).with('more_than', 'one_argument') { ... }
18
37
 
19
38
  #### Argument matchers
20
39
 
21
- obj.stub(:message).with(anything())
22
- obj.stub(:message).with(an_instance_of(Money))
23
- obj.stub(:message).with(hash_including(:a => 'b'))
40
+ obj.stub(:message).with(anything()) { ... }
41
+ obj.stub(:message).with(an_instance_of(Money)) { ... }
42
+ obj.stub(:message).with(hash_including(:a => 'b')) { ... }
24
43
 
25
44
  #### Regular expressions
26
45
 
27
- obj.stub(:message).with(/abc/)
28
-
29
- ### Raising/Throwing
46
+ obj.stub(:message).with(/abc/) { ... }
30
47
 
31
- obj.stub(:message) { raise "this error" }
32
- obj.stub(:message) { throw :this_symbol }
33
-
34
- ### Arbitrary handling
35
-
36
- obj.stub(:message) do |arg1, arg2|
37
- # set expectations about the args in this block
38
- # and set a return value
39
- end
@@ -0,0 +1,23 @@
1
+ Feature: stub on any instance of a class
2
+
3
+ Use `any_instance.stub` on a class to tell any instance of that class to
4
+ return a value (or values) in response to a given message. If no instance
5
+ receives the message, nothing happens.
6
+
7
+ Messages can be stubbed on any class, including those in Ruby's core library.
8
+
9
+ Scenario: simple any_instance stub with a single return value
10
+ Given a file named "example_spec.rb" with:
11
+ """
12
+ describe "any_instance.stub" do
13
+ it "returns the specified value on any instance of the class" do
14
+ Object.any_instance.stub(:foo).and_return(:return_value)
15
+
16
+ o = Object.new
17
+ o.foo.should eq(:return_value)
18
+ end
19
+ end
20
+ """
21
+ When I run `rspec example_spec.rb`
22
+ Then the examples should all pass
23
+
@@ -0,0 +1,36 @@
1
+ Feature: as_null_object
2
+
3
+ Use the `as_null_object` method to ignore any messages that aren't explicitly
4
+ set as stubs or message expectations.
5
+
6
+ EXCEPTION: `to_ary` will raise a NoMethodError unless explicitly stubbed in
7
+ order to support `flatten` on an Array containing a double.
8
+
9
+ Scenario: double acting as_null_object
10
+ Given a file named "as_null_object_spec.rb" with:
11
+ """
12
+ describe "a double with as_null_object called" do
13
+ let(:null_object) { double('null object').as_null_object }
14
+
15
+ it "responds to any method that is not defined" do
16
+ null_object.should respond_to(:an_undefined_method)
17
+ end
18
+
19
+ it "allows explicit stubs" do
20
+ null_object.stub(:foo) { "bar" }
21
+ null_object.foo.should eq("bar")
22
+ end
23
+
24
+ it "allows explicit expectations" do
25
+ null_object.should_receive(:something)
26
+ null_object.something
27
+ end
28
+
29
+ it "supports Array#flatten" do
30
+ null_object = double('foo')
31
+ [null_object].flatten.should eq([null_object])
32
+ end
33
+ end
34
+ """
35
+ When I run `rspec as_null_object_spec.rb`
36
+ Then the examples should all pass
@@ -20,7 +20,7 @@ Feature: stub with a simple return value
20
20
  end
21
21
  end
22
22
  """
23
- When I run "rspec example_spec.rb"
23
+ When I run `rspec example_spec.rb`
24
24
  Then the output should contain "0 failures"
25
25
 
26
26
  Scenario: single return value
@@ -51,5 +51,5 @@ Feature: stub with a simple return value
51
51
  end
52
52
  end
53
53
  """
54
- When I run "rspec example_spec.rb"
54
+ When I run `rspec example_spec.rb`
55
55
  Then the output should contain "0 failures"
@@ -1,9 +1,9 @@
1
1
  Feature: stub a chain of methods
2
2
 
3
- The `stub_chain` method lets you to stub a chain of methods in one statement.
4
- Method chains are considered a design smell, but it's not really the method
5
- chain that is the problem - it's the dependency chain represented by a chain
6
- of messages to different objects:
3
+ Use the `stub_chain` method to stub a chain of two or more methods in one
4
+ statement. Method chains are considered a design smell, but it's not really
5
+ the method chain itself that is the problem - it's the dependency chain
6
+ represented by a chain of messages to different objects:
7
7
 
8
8
  foo.get_bar.get_baz
9
9
 
@@ -32,6 +32,13 @@ Feature: stub a chain of methods
32
32
  end
33
33
  end
34
34
 
35
+ context "given a hash at the end" do
36
+ it "returns the correct value" do
37
+ subject.stub_chain(:one, :two, :three => :four)
38
+ subject.one.two.three.should eq(:four)
39
+ end
40
+ end
41
+
35
42
  context "given a string of methods separated by dots" do
36
43
  it "returns the correct value" do
37
44
  subject.stub_chain("one.two.three").and_return(:four)
@@ -40,5 +47,5 @@ Feature: stub a chain of methods
40
47
  end
41
48
  end
42
49
  """
43
- When I run "rspec stub_chain_spec.rb"
44
- Then the output should contain "2 examples, 0 failures"
50
+ When I run `rspec stub_chain_spec.rb`
51
+ Then the examples should all pass
@@ -22,5 +22,5 @@ Feature: stub with substitute implementation
22
22
  end
23
23
  end
24
24
  """
25
- When I run "rspec ./stub_implementation_spec.rb"
25
+ When I run `rspec stub_implementation_spec.rb`
26
26
  Then the output should contain "1 example, 0 failures"