rspec-mocks 2.5.0 → 2.6.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.
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"