rspec-mocks-2.14.3/0000755000004100000410000000000012202216237014054 5ustar www-datawww-datarspec-mocks-2.14.3/Changelog.md0000644000004100000410000003526512202216237016300 0ustar www-datawww-data### 2.14.3 / 2013-08-08 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.2...v2.14.3) Bug Fixes: * Fix stubbing some instance methods for classes whose hierarchy includes a prepended Module (Bradley Schaefer) ### 2.14.2 / 2013-07-30 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.1...v2.14.2) Bug Fixes: * Fix `as_null_object` doubles so that they return `nil` from `to_ary` (Jon Rowe). * Fix regression in 2.14 that made `stub!` (with an implicit receiver) return a test double rather than stub a method (Myron Marston). ### 2.14.1 / 2013-07-07 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0...v2.14.1) Bug Fixes: * Restore `double.as_null_object` behavior from 2.13 and earlier: a double's nullness persisted between examples in earlier examples. While this is not an intended use case (test doubles are meant to live for only one example), we don't want to break behavior users rely on in a minor relase. This will be deprecated in 2.99 and removed in 3.0. (Myron Marston) ### 2.14.0 / 2013-07-06 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0.rc1...v2.14.0) Enhancements: * Document test spies in the readme. (Adarsh Pandit) * Add an `array_including` matcher. (Sam Phippen) * Add a syntax-agnostic API for mocking or stubbing a method. This is intended for use by libraries such as rspec-rails that need to mock or stub a method, and work regardless of the syntax the user has configured (Paul Annesley, Myron Marston and Sam Phippen). Bug Fixes: * Fix `double` so that it sets up passed stubs correctly regardless of the configured syntax (Paul Annesley). * Allow a block implementation to be used in combination with `and_yield`, `and_raise`, `and_return` or `and_throw`. This got fixed in 2.13.1 but failed to get merged into master for the 2.14.0.rc1 release (Myron Marston). * `Marshal.dump` does not unnecessarily duplicate objects when rspec-mocks has not been fully initialized. This could cause errors when using `spork` or similar preloading gems (Andy Lindeman). ### 2.14.0.rc1 / 2013-05-27 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.14.0.rc1) Enhancements: * Refactor internals so that the mock proxy methods and state are held outside of the mocked object rather than inside it. This paves the way for future syntax enhancements and removes the need for some hacky work arounds for `any_instance` dup'ing and `YAML` serialization, among other things. Note that the code now relies upon `__id__` returning a unique, consistent value for any object you want to mock or stub (Myron Marston). * Add support for test spies. This allows you to verify a message was received afterwards using the `have_received` matcher. Note that you must first stub the method or use a null double. (Joe Ferris and Joël Quenneville) * Make `at_least` and `at_most` style receive expectations print that they were expecting at least or at most some number of calls, rather than just the number of calls given in the expectation (Sam Phippen) * Make `with` style receive expectations print the args they were expecting, and the args that they got (Sam Phippen) * Fix some warnings seen under ruby 2.0.0p0 (Sam Phippen). * Add a new `:expect` syntax for message expectations (Myron Marston and Sam Phippen). Bug fixes * Fix `any_instance` so that a frozen object can be `dup`'d when methods have been stubbed on that type using `any_instance` (Jon Rowe). * Fix `and_call_original` so that it properly raises an `ArgumentError` when the wrong number of args are passed (Jon Rowe). * Fix `double` on 1.9.2 so you can wrap them in an Array using `Array(my_double)` (Jon Rowe). * Fix `stub_const` and `hide_const` to handle constants that redefine `send` (Sam Phippen). * Fix `Marshal.dump` extension so that it correctly handles nil. (Luke Imhoff, Jon Rowe) * Fix isolation of `allow_message_expectations_on_nil` (Jon Rowe) * Use inspect to format actual arguments on expectations in failure messages (#280, Ben Langfeld) * Protect against improperly initialised test doubles (#293) (Joseph Shraibman and Jon Rowe) Deprecations * Deprecate `stub` and `mock` as aliases for `double`. `double` is the best term for creating a test double, and it reduces confusion to have only one term (Michi Huber). * Deprecate `stub!` and `unstub!` in favor of `stub` and `unstub` (Jon Rowe). * Deprecate `at_least(0).times` and `any_number_of_times` (Michi Huber). ### 2.13.1 / 2013-04-06 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.13.1) Bug fixes * Allow a block implementation to be used in combination with `and_yield`, `and_raise`, `and_return` or `and_throw` (Myron Marston). ### 2.13.0 / 2013-02-23 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.2...v2.13.0) Bug fixes * Fix bug that caused weird behavior when a method that had previously been stubbed with multiple return values (e.g. `obj.stub(:foo).and_return(1, 2)`) was later mocked with a single return value (e.g. `obj.should_receive(:foo).once.and_return(1)`). (Myron Marston) * Fix bug related to a mock expectation for a method that already had multiple stubs with different `with` constraints. Previously, the first stub was used, even though it may not have matched the passed args. The fix defers this decision until the message is received so that the proper stub response can be chosen based on the passed arguments (Myron Marston). * Do not call `nil?` extra times on a mocked object, in case `nil?` itself is expected a set number of times (Myron Marston). * Fix `missing_default_stub_error` message so array args are handled properly (Myron Marston). * Explicitly disallow `any_instance.unstub!` (Ryan Jones). * Fix `any_instance` stubbing so that it works with `Delegator` subclasses (Myron Marston). * Fix `and_call_original` so that it works with `Delegator` subclasses (Myron Marston). * Fix `any_instance.should_not_receive` when `any_instance.should_receive` is used on the same class in the same example. Previously it would wrongly report a failure even when the message was not received (Myron Marston). ### 2.12.2 / 2013-01-27 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.1...v.2.12.2) Bug fixes * Fix `and_call_original` to work properly for methods defined on a module extended onto an object instance (Myron Marston). * Fix `stub_const` with an undefined constnat name to work properly with constant strings that are prefixed with `::` -- and edge case I missed in the bug fix in the 2.12.1 release (Myron Marston). * Ensure method visibility on a partial mock is restored after reseting method stubs, even on a singleton module (created via `extend self`) when the method visibility differs between the instance and singleton versions (Andy Lindeman). ### 2.12.1 / 2012-12-21 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.0...v2.12.1) Bug fixes * Fix `any_instance` to support `and_call_original`. (Myron Marston) * Properly restore stubbed aliased methods on rubies that report the incorrect owner (Myron Marston and Andy Lindeman). * Fix `hide_const` and `stub_const` with a defined constnat name to work properly with constant strings that are prefixed with `::` (Myron Marston). ### 2.12.0 / 2012-11-12 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.3...v2.12.0) Enhancements * `and_raise` can accept an exception class and message, more closely matching `Kernel#raise` (e.g., `foo.stub(:bar).and_raise(RuntimeError, "message")`) (Bas Vodde) * Add `and_call_original`, which will delegate the message to the original method (Myron Marston). Deprecations: * Add deprecation warning when using `and_return` with `should_not_receive` (Neha Kumari) ### 2.11.3 / 2012-09-19 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.2...v2.11.3) Bug fixes * Fix `:transfer_nested_constants` option of `stub_const` so that it doesn't blow up when there are inherited constants. (Myron Marston) * `any_instance` stubs can be used on classes that override `Object#method`. (Andy Lindeman) * Methods stubbed with `any_instance` are unstubbed after the test finishes. (Andy Lindeman) * Fix confusing error message when calling a mocked class method an extra time with the wrong arguments (Myron Marston). ### 2.11.2 / 2012-08-11 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.1...v2.11.2) Bug fixes * Don't modify `dup` on classes that don't support `dup` (David Chelimsky) * Fix `any_instance` so that it works properly with methods defined on a superclass. (Daniel Eguzkiza) * Fix `stub_const` so that it works properly for nested constants that share a name with a top-level constant (e.g. "MyGem::Hash"). (Myron Marston) ### 2.11.1 / 2012-07-09 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.0...v2.11.1) Bug fixes * Fix `should_receive` so that when it is called on an `as_null_object` double with no implementation, and there is a previous explicit stub for the same method, the explicit stub remains (rather than being overriden with the null object implementation--`return self`). (Myron Marston) ### 2.11.0 / 2012-07-07 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.1...v2.11.0) Enhancements * Expose ArgumentListMatcher as a formal API * supports use by 3rd party mock frameworks like Surrogate * Add `stub_const` API to stub constants for the duration of an example (Myron Marston). Bug fixes * Fix regression of edge case behavior. `double.should_receive(:foo) { a }` was causing a NoMethodError when `double.stub(:foo).and_return(a, b)` had been setup before (Myron Marston). * Infinite loop generated by using `any_instance` and `dup`. (Sidu Ponnappa @kaiwren) * `double.should_receive(:foo).at_least(:once).and_return(a)` always returns a even if `:foo` is already stubbed. * Prevent infinite loop when interpolating a null double into a string as an integer (`"%i" % double.as_null_object`). (Myron Marston) * Fix `should_receive` so that null object behavior (e.g. returning self) is preserved if no implementation is given (Myron Marston). * Fix `and_raise` so that it raises `RuntimeError` rather than `Exception` by default, just like ruby does. (Andrew Marshall) ### 2.10.1 / 2012-05-05 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.0...v2.10.1) Bug fixes * fix regression of edge case behavior (https://github.com/rspec/rspec-mocks/issues/132) * fixed failure of `object.should_receive(:message).at_least(0).times.and_return value` * fixed failure of `object.should_not_receive(:message).and_return value` ### 2.10.0 / 2012-05-03 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.9.0...v2.10.0) Bug fixes * fail fast when an `exactly` or `at_most` expectation is exceeded ### 2.9.0 / 2012-03-17 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0...v2.9.0) Enhancements * Support order constraints across objects (preethiramdev) Bug fixes * Allow a `as_null_object` to be passed to `with` * Pass proc to block passed to stub (Aubrey Rhodes) * Initialize child message expectation args to match any args (#109 - preethiramdev) ### 2.8.0 / 2012-01-04 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc2...v2.8.0) No changes for this release. Just releasing with the other rspec gems. ### 2.8.0.rc2 / 2011-12-19 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc1...v2.8.0.rc2) No changes for this release. Just releasing with the other rspec gems. ### 2.8.0.rc1 / 2011-11-06 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.7.0...v2.8.0.rc1) Enhancements * Eliminate Ruby warnings (Matijs van Zuijlen) ### 2.7.0 / 2011-10-16 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.6.0...v2.7.0) Enhancements * Use `__send__` rather than `send` (alextk) * Add support for `any_instance.stub_chain` (Sidu Ponnappa) * Add support for `any_instance` argument matching based on `with` (Sidu Ponnappa and Andy Lindeman) Changes * Check for `failure_message_for_should` or `failure_message` instead of `description` to detect a matcher (Tibor Claassen) Bug fixes * pass a hash to `any_instance.stub`. (Justin Ko) * allow `to_ary` to be called without raising `NoMethodError` (Mikhail Dieterle) * `any_instance` properly restores private methods (Sidu Ponnappa) ### 2.6.0 / 2011-05-12 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.5.0...v2.6.0) Enhancements * Add support for `any_instance.stub` and `any_instance.should_receive` (Sidu Ponnappa and Andy Lindeman) Bug fixes * fix bug in which multiple chains with shared messages ending in hashes failed to return the correct value ### 2.5.0 / 2011-02-05 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.4.0...v2.5.0) Bug fixes * message expectation counts now work in combination with a stub (Damian Nurzynski) * fix failure message when message received with incorrect args (Josep M. Bach) ### 2.4.0 / 2011-01-02 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.3.0...v2.4.0) No functional changes in this release, which was made to align with the rspec-core-2.4.0 release. ### 2.3.0 / 2010-12-12 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.2.0...v2.3.0) Bug fixes * Fix our Marshal extension so that it does not interfere with objects that have their own `@mock_proxy` instance variable. (Myron Marston) ### 2.2.0 / 2010-11-28 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.1.0...v2.2.0) Enhancements * Added "rspec/mocks/standalone" for exploring the rspec-mocks in irb. Bug fix * Eliminate warning on splat args without parens (Gioele Barabucci) * Fix bug where `obj.should_receive(:foo).with(stub.as_null_object)` would pass with a false positive. ### 2.1.0 / 2010-11-07 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.1...v2.1.0) Bug fixes * Fix serialization of stubbed object (Josep M Bach) ### 2.0.0 / 2010-10-10 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0) ### 2.0.0.rc / 2010-10-05 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0.rc) Enhancements * support passing a block to an expectation block (Nicolas Braem) * `obj.should_receive(:msg) {|&block| ... }` Bug fixes * Fix YAML serialization of stub (Myron Marston) * Fix rdoc rake task (Hans de Graaff) ### 2.0.0.beta.22 / 2010-09-12 [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.20...v2.0.0.beta.22) Bug fixes * fixed regression that broke `obj.stub_chain(:a, :b => :c)` * fixed regression that broke `obj.stub_chain(:a, :b) { :c }` * `respond_to?` always returns true when using `as_null_object` rspec-mocks-2.14.3/License.txt0000644000004100000410000000216212202216237016200 0ustar www-datawww-data(The MIT License) Copyright (c) 2006 David Chelimsky, The RSpec Development Team Copyright (c) 2005 Steven Baker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rspec-mocks-2.14.3/README.md0000644000004100000410000002453512202216237015344 0ustar www-datawww-data# RSpec Mocks [![Build Status](https://secure.travis-ci.org/rspec/rspec-mocks.png?branch=master)](http://travis-ci.org/rspec/rspec-mocks) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.png)](https://codeclimate.com/github/rspec/rspec-mocks) rspec-mocks is a test-double framework for rspec with support for method stubs, fakes, and message expectations on generated test-doubles and real objects alike. ## Install gem install rspec # for rspec-core, rspec-expectations, rspec-mocks gem install rspec-mocks # for rspec-mocks only ## Test Doubles A Test Double is an object that stands in for a real object in a test. RSpec creates test doubles that support method stubs and message expectations. ```ruby book = double("book") ``` ## Method Stubs A method stub is an implementation that returns a pre-determined value. Method stubs can be declared on test doubles or real objects using the same syntax. rspec-mocks supports 3 forms for declaring method stubs: ```ruby book.stub(:title) { "The RSpec Book" } book.stub(:title => "The RSpec Book") book.stub(:title).and_return("The RSpec Book") ``` You can also use this shortcut, which creates a test double and declares a method stub in one statement: ```ruby book = double("book", :title => "The RSpec Book") ``` The first argument is a name, which is used for documentation and appears in failure messages. If you don't care about the name, you can leave it out, making the combined instantiation/stub declaration very terse: ```ruby double(:foo => 'bar') ``` This is particularly nice when providing a list of test doubles to a method that iterates through them: ```ruby order.calculate_total_price(double(:price => 1.99),double(:price => 2.99)) ``` ## Consecutive return values When a stub might be invoked more than once, you can provide additional arguments to `and_return`. The invocations cycle through the list. The last value is returned for any subsequent invocations: ```ruby die.stub(:roll).and_return(1,2,3) die.roll # => 1 die.roll # => 2 die.roll # => 3 die.roll # => 3 die.roll # => 3 ``` To return an array in a single invocation, declare an array: ```ruby team.stub(:players).and_return([stub(:name => "David")]) ``` ## Message Expectations A message expectation is an expectation that the test double will receive a message some time before the example ends. If the message is received, the expectation is satisfied. If not, the example fails. ```ruby validator = double("validator") validator.should_receive(:validate).with("02134") zipcode = Zipcode.new("02134", validator) zipcode.valid? ``` ## Nomenclature ### Mock Objects and Test Stubs The names Mock Object and Test Stub suggest specialized Test Doubles. i.e. a Test Stub is a Test Double that only supports method stubs, and a Mock Object is a Test Double that supports message expectations and method stubs. There is a lot of overlapping nomenclature here, and there are many variations of these patterns (fakes, spies, etc). Keep in mind that most of the time we're talking about method-level concepts that are variations of method stubs and message expectations, and we're applying to them to _one_ generic kind of object: a Test Double. ### Test-Specific Extension a.k.a. Partial Stub/Mock, a Test-Specific Extension is an extension of a real object in a system that is instrumented with test-double like behaviour in the context of a test. This technique is very common in Ruby because we often see class objects acting as global namespaces for methods. For example, in Rails: ```ruby person = double("person") Person.stub(:find) { person } ``` In this case we're instrumenting Person to return the person object we've defined whenever it receives the `find` message. We can also set a message expectation so that the example fails if `find` is not called: ```ruby person = double("person") Person.should_receive(:find) { person } ``` We can do this with any object in a system because rspec-mocks adds the `stub` and `should_receive` methods to every object, including class objects. When we use either, RSpec replaces the method we're stubbing or mocking with its own test-double-like method. At the end of the example, RSpec verifies any message expectations, and then restores the original methods. ## Expecting Arguments ```ruby double.should_receive(:msg).with(*args) double.should_not_receive(:msg).with(*args) ``` You can set multiple expectations for the same message if you need to: ```ruby double.should_receive(:msg).with("A", 1, 3) double.should_receive(:msg).with("B", 2, 4) ``` ## Argument Matchers Arguments that are passed to `with` are compared with actual arguments received using ==. In cases in which you want to specify things about the arguments rather than the arguments themselves, you can use any of the matchers that ship with rspec-expectations. They don't all make syntactic sense (they were primarily designed for use with RSpec::Expectations), but you are free to create your own custom RSpec::Matchers. rspec-mocks also adds some keyword Symbols that you can use to specify certain kinds of arguments: ```ruby double.should_receive(:msg).with(no_args()) double.should_receive(:msg).with(any_args()) double.should_receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric double.should_receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false double.should_receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp double.should_receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all double.should_receive(:msg).with(1, duck_type(:abs, :div), "b") #2nd argument can be object that responds to #abs and #div ``` ## Receive Counts ```ruby double.should_receive(:msg).once double.should_receive(:msg).twice double.should_receive(:msg).exactly(n).times double.should_receive(:msg).at_least(:once) double.should_receive(:msg).at_least(:twice) double.should_receive(:msg).at_least(n).times double.should_receive(:msg).at_most(:once) double.should_receive(:msg).at_most(:twice) double.should_receive(:msg).at_most(n).times double.should_receive(:msg).any_number_of_times ``` ## Ordering ```ruby double.should_receive(:msg).ordered double.should_receive(:other_msg).ordered #This will fail if the messages are received out of order ``` This can include the same message with different arguments: ```ruby double.should_receive(:msg).with("A", 1, 3).ordered double.should_receive(:msg).with("B", 2, 4).ordered ``` ## Setting Responses Whether you are setting a message expectation or a method stub, you can tell the object precisely how to respond. The most generic way is to pass a block to `stub` or `should_receive`: ```ruby double.should_receive(:msg) { value } ``` When the double receives the `msg` message, it evaluates the block and returns the result. ```ruby double.should_receive(:msg).and_return(value) double.should_receive(:msg).exactly(3).times.and_return(value1, value2, value3) # returns value1 the first time, value2 the second, etc double.should_receive(:msg).and_raise(error) #error can be an instantiated object or a class #if it is a class, it must be instantiable with no args double.should_receive(:msg).and_throw(:msg) double.should_receive(:msg).and_yield(values,to,yield) double.should_receive(:msg).and_yield(values,to,yield).and_yield(some,other,values,this,time) # for methods that yield to a block multiple times ``` Any of these responses can be applied to a stub as well ```ruby double.stub(:msg).and_return(value) double.stub(:msg).and_return(value1, value2, value3) double.stub(:msg).and_raise(error) double.stub(:msg).and_throw(:msg) double.stub(:msg).and_yield(values,to,yield) double.stub(:msg).and_yield(values,to,yield).and_yield(some,other,values,this,time) ``` ## Arbitrary Handling Once in a while you'll find that the available expectations don't solve the particular problem you are trying to solve. Imagine that you expect the message to come with an Array argument that has a specific length, but you don't care what is in it. You could do this: ```ruby double.should_receive(:msg) do |arg| arg.size.should eq(7) end ``` If the method being stubbed itself takes a block, and you need to yield to it in some special way, you can use this: ```ruby double.should_receive(:msg) do |&arg| begin arg.call ensure # cleanup end end ``` ## Delegating to the Original Implementation When working with a partial mock object, you may occasionally want to set a message expecation without interfering with how the object responds to the message. You can use `and_call_original` to achieve this: ```ruby Person.should_receive(:find).and_call_original Person.find # => executes the original find method and returns the result ``` ## Combining Expectation Details Combining the message name with specific arguments, receive counts and responses you can get quite a bit of detail in your expectations: ```ruby double.should_receive(:<<).with("illegal value").once.and_raise(ArgumentError) ``` While this is a good thing when you really need it, you probably don't really need it! Take care to specify only the things that matter to the behavior of your code. ## Stubbing and Hiding Constants See the [mutating constants README](https://github.com/rspec/rspec-mocks/blob/master/features/mutating_constants/README.md) for info on this feature. ## Use `before(:each)`, not `before(:all)` Stubs in `before(:all)` are not supported. The reason is that all stubs and mocks get cleared out after each example, so any stub that is set in `before(:all)` would work in the first example that happens to run in that group, but not for any others. Instead of `before(:all)`, use `before(:each)`. ## Further Reading There are many different viewpoints about the meaning of mocks and stubs. If you are interested in learning more, here is some recommended reading: * Mock Objects: http://www.mockobjects.com/ * Endo-Testing: http://www.mockobjects.com/files/endotesting.pdf * Mock Roles, Not Objects: http://www.mockobjects.com/files/mockrolesnotobjects.pdf * Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html * Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html ## Also see * [http://github.com/rspec/rspec](http://github.com/rspec/rspec) * [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core) * [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations) rspec-mocks-2.14.3/features/0000755000004100000410000000000012202216237015672 5ustar www-datawww-datarspec-mocks-2.14.3/features/mutating_constants/0000755000004100000410000000000012202216237021616 5ustar www-datawww-datarspec-mocks-2.14.3/features/mutating_constants/hiding_defined_constant.feature0000644000004100000410000000340112202216237030022 0ustar www-datawww-dataFeature: Hide Defined Constant Use `hide_const` to remove a constant for the duration of a test. Scenario: Hide top-level constant Given a file named "hide_const_spec.rb" with: """ruby FOO = 7 describe "hiding FOO" do it "can hide FOO" do hide_const("FOO") expect { FOO }.to raise_error(NameError) end it "restores the hidden constant when the example completes" do FOO.should eq(7) end end """ When I run `rspec hide_const_spec.rb` Then the examples should all pass Scenario: Hide nested constant Given a file named "hide_const_spec.rb" with: """ruby module MyGem class SomeClass FOO = 7 end end module MyGem describe SomeClass do it "hides the nested constant when it is fully qualified" do hide_const("MyGem::SomeClass::FOO") expect { SomeClass::FOO }.to raise_error(NameError) end it "restores the hidden constant when the example completes" do MyGem::SomeClass::FOO.should eq(7) end end end """ When I run `rspec hide_const_spec.rb` Then the examples should all pass Scenario: Hiding undefined constant Given a file named "hide_const_spec.rb" with: """ describe "hiding UNDEFINED_CONSTANT" do it "has no effect" do hide_const("UNDEFINED_CONSTANT") expect { UNDEFINED_CONSTANT }.to raise_error(NameError) end it "is still undefined after the example completes" do expect { UNDEFINED_CONSTANT }.to raise_error(NameError) end end """ When I run `rspec hide_const_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/mutating_constants/stub_undefined_constant.feature0000644000004100000410000000310212202216237030076 0ustar www-datawww-dataFeature: Stub Undefined Constant Use `stub_const` to stub constants. When the constant is not already defined, all the necessary intermediary modules will be dynamically created. When the example completes, the intermediary module constants will be removed to return the constant state to how it started. Scenario: Stub top-level constant Given a file named "stub_const_spec.rb" with: """ruby describe "stubbing FOO" do it "can stub undefined constant FOO" do stub_const("FOO", 5) FOO.should eq(5) end it "undefines the constant when the example completes" do expect { FOO }.to raise_error(NameError) end end """ When I run `rspec stub_const_spec.rb` Then the examples should all pass Scenario: Stub nested constant Given a file named "stub_const_spec.rb" with: """ruby module MyGem class SomeClass end end module MyGem describe SomeClass do it "can stub an arbitrarily deep constant that is undefined" do defined?(SomeClass::A).should be_false stub_const("MyGem::SomeClass::A::B::C", 3) SomeClass::A::B::C.should eq(3) SomeClass::A.should be_a(Module) end it 'undefines the intermediary constants that were dynamically created' do defined?(SomeClass).should be_true defined?(SomeClass::A).should be_false end end end """ When I run `rspec stub_const_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/mutating_constants/README.md0000644000004100000410000000404312202216237023076 0ustar www-datawww-data## Mutating Constants ### Stubbing Support is provided for stubbing constants. Like with method stubs, the stubbed constants will be restored to their original state when an example completes. ``` ruby stub_const("Foo", fake_foo) Foo # => fake_foo ``` Stubbed constant names must be fully qualified; the current module nesting is not considered. ``` ruby module MyGem class SomeClass; end end module MyGem describe "Something" do let(:fake_class) { Class.new } it "accidentally stubs the wrong constant" do # this stubs ::SomeClass (in the top-level namespace), # not MyGem::SomeClass like you probably mean. stub_const("SomeClass", fake_class) end it "stubs the right constant" do stub_const("MyGem::SomeClass", fake_class) end end end ``` When you stub a constant that is a module or a class, nested constants on the original module or class are not transferred by default, but you can use the `:transfer_nested_constants` option to tell rspec-mocks to transfer them: ``` ruby class CardDeck SUITS = [:Spades, :Diamonds, :Clubs, :Hearts] NUM_CARDS = 52 end fake_class = Class.new stub_const("CardDeck", fake_class) CardDeck # => fake_class CardDeck::SUITS # => raises uninitialized constant error CardDeck::NUM_CARDS # => raises uninitialized constant error stub_const("CardDeck", fake_class, :transfer_nested_constants => true) CardDeck::SUITS # => [:Spades, :Diamonds, :Clubs, :Hearts] CardDeck::NUM_CARDS # => 52 stub_const("CardDeck", fake_class, :transfer_nested_constants => [:SUITS]) CardDeck::SUITS # => [:Spades, :Diamonds, :Clubs, :Hearts] CardDeck::NUM_CARDS # => raises uninitialized constant error ``` ### Hiding Support is also provided for hiding constants. Hiding a constant temporarily removes it; it is restored to its original value after the test completes. ```ruby FOO = 42 hide_const("FOO") FOO => NameError: uninitialized constant FOO ``` Like stubbed constants, names must be fully qualified. Hiding constants that are already undefined has no effect. ```ruby hide_const("NO_OP") ``` rspec-mocks-2.14.3/features/mutating_constants/stub_defined_constant.feature0000644000004100000410000000430012202216237027534 0ustar www-datawww-dataFeature: Stub Defined Constant Use `stub_const` to stub constants. When the constant is already defined, the stubbed value will replace the original value for the duration of the example. Scenario: Stub top-level constant Given a file named "stub_const_spec.rb" with: """ruby FOO = 7 describe "stubbing FOO" do it "can stub FOO with a different value" do stub_const("FOO", 5) FOO.should eq(5) end it "restores the stubbed constant when the example completes" do FOO.should eq(7) end end """ When I run `rspec stub_const_spec.rb` Then the examples should all pass Scenario: Stub nested constant Given a file named "stub_const_spec.rb" with: """ruby module MyGem class SomeClass FOO = 7 end end module MyGem describe SomeClass do it "stubs the nested constant when it is fully qualified" do stub_const("MyGem::SomeClass::FOO", 5) SomeClass::FOO.should eq(5) end end end """ When I run `rspec stub_const_spec.rb` Then the examples should all pass Scenario: Transfer nested constants Given a file named "stub_const_spec.rb" with: """ruby module MyGem class SomeClass FOO = 7 end end module MyGem describe SomeClass do let(:fake_class) { Class.new } it "does not transfer nested constants by default" do stub_const("MyGem::SomeClass", fake_class) expect { SomeClass::FOO }.to raise_error(NameError) end it "transfers nested constants when using :transfer_nested_constants => true" do stub_const("MyGem::SomeClass", fake_class, :transfer_nested_constants => true) SomeClass::FOO.should eq(7) end it "can specify a list of nested constants to transfer" do stub_const("MyGem::SomeClass", fake_class, :transfer_nested_constants => [:FOO]) SomeClass::FOO.should eq(7) end end end """ When I run `rspec stub_const_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/method_stubs/0000755000004100000410000000000012202216237020372 5ustar www-datawww-datarspec-mocks-2.14.3/features/method_stubs/simple_return_value_with_allow.feature0000644000004100000410000000300312202216237030260 0ustar www-datawww-dataFeature: allow with a simple return value Use the `allow` method with the `receive` matcher on a test double or a real object to tell the object to return a value (or values) in response to a given message. Nothing happens if the message is never received. Scenario: stub with no return value Given a file named "example_spec.rb" with: """ruby describe "a stub with no return value specified" do let(:collaborator) { double("collaborator") } it "returns nil" do allow(collaborator).to receive(:message) expect(collaborator.message).to be(nil) end end """ When I run `rspec example_spec.rb` Then the examples should all pass Scenario: stubs with return values Given a file named "example_spec.rb" with: """ruby describe "a stub with a return value" do context "specified in a block" do it "returns the specified value" do collaborator = double("collaborator") allow(collaborator).to receive(:message) { :value } expect(collaborator.message).to eq(:value) end end context "specified with #and_return" do it "returns the specified value" do collaborator = double("collaborator") allow(collaborator).to receive(:message).and_return(:value) expect(collaborator.message).to eq(:value) end end end """ When I run `rspec example_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/method_stubs/to_ary.feature0000644000004100000410000000300712202216237023244 0ustar www-datawww-dataFeature: double handling to_ary Ruby implicitly sends `to_ary` to all of the objects in an `Array` when the array receives `flatten`: [obj].flatten # => obj.to_ary If `to_ary` raises a `NoMethodError`, Ruby sees that the object can not be coerced into an array and moves on to the next object. To support this, an RSpec double will raise a NoMethodError when it receives `to_ary` _even if it is set `as_null_object`_, unless `to_ary` is explicitly stubbed. Scenario: double receiving to_ary Given a file named "example.rb" with: """ruby describe "#to_ary" do shared_examples "to_ary" do it "can be overridden with a stub" do obj.stub(:to_ary) { :non_nil_value } obj.to_ary.should be(:non_nil_value) end it "supports Array#flatten" do obj = double('foo') [obj].flatten.should eq([obj]) end end context "sent to a double as_null_object" do let(:obj) { double('obj').as_null_object } include_examples "to_ary" it "returns nil" do expect( obj.to_ary ).to eq nil end end context "sent to a double without as_null_object" do let(:obj) { double('obj') } include_examples "to_ary" it "raises a NoMethodError" do expect { obj.to_ary }.to raise_error(NoMethodError) end end end """ When I run `rspec example.rb` Then the examples should all pass rspec-mocks-2.14.3/features/method_stubs/stub_implementation.feature0000644000004100000410000000261312202216237026033 0ustar www-datawww-dataFeature: stub with substitute implementation You can stub an implementation of a method (a.k.a. fake) by passing a block to the `stub` method. Scenario: stub implementation using `expect` syntax Given a file named "stub_implementation_spec.rb" with: """ruby describe "a stubbed implementation" do it "works" do object = Object.new allow(object).to receive(:foo) do |arg| if arg == :this "got this" elsif arg == :that "got that" end end expect(object.foo(:this)).to eq("got this") expect(object.foo(:that)).to eq("got that") end end """ When I run `rspec stub_implementation_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: stub implementation using `should` syntax Given a file named "stub_implementation_spec.rb" with: """ruby describe "a stubbed implementation" do it "works" do object = Object.new object.stub(:foo) do |arg| if arg == :this "got this" elsif arg == :that "got that" end end object.foo(:this).should eq("got this") object.foo(:that).should eq("got that") end end """ When I run `rspec stub_implementation_spec.rb` Then the output should contain "1 example, 0 failures" rspec-mocks-2.14.3/features/method_stubs/README.md0000644000004100000410000000436712202216237021663 0ustar www-datawww-data### Stub return values # create a double obj = double() # specify a return value using `:expect` syntax allow(obj).to receive(:message) { :value } allow(obj).to receive(:message).and_return(:value) # specify a return value using `:should` syntax obj.stub(:message) { :value } obj.stub(:message => :value) obj.stub(:message).and_return(:value) These forms are somewhat interchangeable. The difference is that the block contents are evaluated lazily when the `obj` receives the `message` message, whereas the others are evaluated as they are read. ### Fake implementation allow(obj).to receive(:message) do |arg1, arg2| # set expectations about the args in this block # and/or return value end obj.stub(:message) do |arg1, arg2| # set expectations about the args in this block # and/or return a value end ### Raising/Throwing allow(obj).to receive(:message).and_raise("this error") allow(obj).to receive(:message).and_throw(:this_symbol) obj.stub(:message).and_raise("this error") obj.stub(:message).and_throw(:this_symbol) You can also use the block format: allow(obj).to receive(:message) { raise "this error" } allow(obj).to receive(:message) { throw :this_symbol } obj.stub(:message) { raise "this error" } obj.stub(:message) { throw :this_symbol } ### Argument constraints #### Explicit arguments allow(obj).to receive(:message).with('an argument') { ... } obj.stub(:message).with('an argument') { ... } obj.stub(:message).with('more_than', 'one_argument') { ... } #### Argument matchers allow(obj).to receive(:message).with(anything()) { ... } allow(obj).to receive(:message).with(an_instance_of(Money)) { ... } allow(obj).to receive(:message).with(hash_including(:a => 'b')) { ... } allow(obj).to receive(:message).with(array_including(1,2,3)) { ... } # or allow(obj).to receive(:message).with(array_including([1,2,3])) { ... } obj.stub(:message).with(anything()) { ... } obj.stub(:message).with(an_instance_of(Money)) { ... } obj.stub(:message).with(hash_including(:a => 'b')) { ... } #### Regular expressions allow(obj).to receive(:message).with(/abc/) { ... } obj.stub(:message).with(/abc/) { ... } rspec-mocks-2.14.3/features/method_stubs/stub_chain.feature0000644000004100000410000000345612202216237024076 0ustar www-datawww-dataFeature: stub a chain of methods Use the `stub_chain` method to stub a chain of two or more methods in one statement. Method chains are considered a design smell, but it's not really the method chain itself that is the problem - it's the dependency chain represented by a chain of messages to different objects: foo.get_bar.get_baz This is a Law of Demeter violation if `get_bar` returns an object other than `foo`, and `get_baz` returns yet another object. Fluent interfaces look similar from a caller's perspective, but don't represent a dependency chain (the caller depends only on the object it is calling). Consider this common example from Ruby on Rails: Article.recent.by(current_user) The `recent` and `by` methods return the same object, so this is not a Law of Demeter violation. Scenario: stub a chain of methods Given a file named "stub_chain_spec.rb" with: """ruby describe "stubbing a chain of methods" do subject { Object.new } context "given symbols representing methods" do it "returns the correct value" do subject.stub_chain(:one, :two, :three).and_return(:four) subject.one.two.three.should eq(:four) end end context "given a hash at the end" do it "returns the correct value" do subject.stub_chain(:one, :two, :three => :four) subject.one.two.three.should eq(:four) end end context "given a string of methods separated by dots" do it "returns the correct value" do subject.stub_chain("one.two.three").and_return(:four) subject.one.two.three.should eq(:four) end end end """ When I run `rspec stub_chain_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/method_stubs/as_null_object.feature0000644000004100000410000000247012202216237024735 0ustar www-datawww-dataFeature: as_null_object Use the `as_null_object` method to ignore any messages that aren't explicitly set as stubs or message expectations. EXCEPTION: `to_ary` will raise a NoMethodError unless explicitly stubbed in order to support `flatten` on an Array containing a double. Scenario: double acting as_null_object Given a file named "as_null_object_spec.rb" with: """ruby describe "a double with as_null_object called" do let(:null_object) { double('null object').as_null_object } it "responds to any method that is not defined" do null_object.should respond_to(:an_undefined_method) end it "allows explicit stubs using expect syntax" do allow(null_object).to receive(:foo) { "bar" } expect(null_object.foo).to eq("bar") end it "allows explicit stubs using should syntax" do null_object.stub(:foo) { "bar" } null_object.foo.should eq("bar") end it "allows explicit expectations" do null_object.should_receive(:something) null_object.something end it "supports Array#flatten" do [null_object].flatten.should eq([null_object]) end end """ When I run `rspec as_null_object_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/method_stubs/any_instance.feature0000644000004100000410000001061212202216237024422 0ustar www-datawww-dataFeature: stub on any instance of a class Use `any_instance.stub` on a class to tell any instance of that class to return a value (or values) in response to a given message. If no instance receives the message, nothing happens. Messages can be stubbed on any class, including those in Ruby's core library. Note: You can use `allow_any_instance_of` when you don't have a reference to the object that receives a message in your test. For more information, see the message_expectations/allow_any_instance_of feature. Scenario: any_instance stub with a single return value Given a file named "example_spec.rb" with: """ruby describe "any_instance.stub" do it "returns the specified value on any instance of the class" do Object.any_instance.stub(:foo).and_return(:return_value) o = Object.new o.foo.should eq(:return_value) end end """ When I run `rspec example_spec.rb` Then the examples should all pass Scenario: any_instance stub with a hash Given a file named "example_spec.rb" with: """ruby describe "any_instance.stub" do context "with a hash" do it "returns the hash values on any instance of the class" do Object.any_instance.stub(:foo => 'foo', :bar => 'bar') o = Object.new o.foo.should eq('foo') o.bar.should eq('bar') end end end """ When I run `rspec example_spec.rb` Then the examples should all pass Scenario: any_instance stub with specific arguments matchers Given a file named "example_spec.rb" with: """ruby describe "any_instance.stub" do context "with arguments" do it "returns the stubbed value when arguments match" do Object.any_instance.stub(:foo).with(:param_one, :param_two).and_return(:result_one) Object.any_instance.stub(:foo).with(:param_three, :param_four).and_return(:result_two) o = Object.new o.foo(:param_one, :param_two).should eq(:result_one) o.foo(:param_three, :param_four).should eq(:result_two) end end end """ When I run `rspec example_spec.rb` Then the examples should all pass Scenario: any_instance unstub Given a file named "example_spec.rb" with: """ruby describe "any_instance.unstub" do it "unstubs a stubbed method" do class Object def foo :foo end end Object.any_instance.stub(:foo) Object.any_instance.unstub(:foo) Object.new.foo.should eq(:foo) end end """ When I run `rspec example_spec.rb` Then the examples should all pass Scenario: any_instance unstub Given a file named "example_spec.rb" with: """ruby describe "any_instance.unstub" do context "with both an expectation and a stub already set" do it "only removes the stub" do class Object def foo :foo end end Object.any_instance.should_receive(:foo).and_return(:bar) Object.any_instance.stub(:foo) Object.any_instance.unstub(:foo) Object.new.foo.should eq(:bar) end end end """ When I run `rspec example_spec.rb` Then the examples should all pass Scenario: stub a chain of methods an any instance Given a file named "stub_chain_spec.rb" with: """ruby describe "stubbing a chain of methods" do context "given symbols representing methods" do it "returns the correct value" do Object.any_instance.stub_chain(:one, :two, :three).and_return(:four) Object.new.one.two.three.should eq(:four) end end context "given a hash at the end" do it "returns the correct value" do Object.any_instance.stub_chain(:one, :two, :three => :four) Object.new.one.two.three.should eq(:four) end end context "given a string of methods separated by dots" do it "returns the correct value" do Object.any_instance.stub_chain("one.two.three").and_return(:four) Object.new.one.two.three.should eq(:four) end end end """ When I run `rspec stub_chain_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/method_stubs/simple_return_value_with_stub.feature0000644000004100000410000000424412202216237030127 0ustar www-datawww-dataFeature: stub with a simple return value Use the `stub` method on a test double or a real object to tell the object to return a value (or values) in response to a given message. Nothing happens if the message is never received. Scenario: stub with no return value Given a file named "example_spec.rb" with: """ruby describe "a stub with no return value specified" do let(:collaborator) { double("collaborator") } it "returns nil" do collaborator.stub(:message) collaborator.message.should be(nil) end end """ When I run `rspec example_spec.rb` Then the examples should all pass Scenario: stubs with return values Given a file named "example_spec.rb" with: """ruby describe "a stub with a return value" do context "specified in a block" do it "returns the specified value" do collaborator = double("collaborator") collaborator.stub(:message) { :value } collaborator.message.should eq(:value) end end context "specified with #and_return" do it "returns the specified value" do collaborator = double("collaborator") collaborator.stub(:message).and_return(:value) collaborator.message.should eq(:value) end end context "specified with a hash passed to #stub" do it "returns the specified value" do collaborator = double("collaborator") collaborator.stub(:message_1 => :value_1, :message_2 => :value_2) collaborator.message_1.should eq(:value_1) collaborator.message_2.should eq(:value_2) end end context "specified with a hash passed to #double" do it "returns the specified value" do collaborator = double("collaborator", :message_1 => :value_1, :message_2 => :value_2 ) collaborator.message_1.should eq(:value_1) collaborator.message_2.should eq(:value_2) end end end """ When I run `rspec example_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/Upgrade.md0000644000004100000410000000072112202216237017603 0ustar www-datawww-data## rspec-mocks-2.6 ### `any_instance` Set method stubs and message expectations on any instance of a class: class Foo; end Foo.any_instance.stub(:bar) { 'bar' } Foo.new.bar # => 'bar' ## rspec-mocks-2.2 ### `require "rspec/mocks/standalone"` Sets up top-level environment to explore rspec-mocks. Mostly useful in irb: $ irb > require 'rspec/mocks/standalone' > foo = double() > foo.stub(:bar) { :baz } > foo.bar => :baz rspec-mocks-2.14.3/features/test_frameworks/0000755000004100000410000000000012202216237021111 5ustar www-datawww-datarspec-mocks-2.14.3/features/test_frameworks/test_unit.feature0000644000004100000410000000272412202216237024511 0ustar www-datawww-dataFeature: Test::Unit integration rspec-mocks is a stand-alone gem that can be used without the rest of RSpec. If you like the way Test::Unit (or MiniTest) organizes tests, but prefer RSpec's approach to mocking/stubbing/doubles etc, you can have both. The one downside is that failures are reported as errors with MiniTest. Scenario: use rspec/mocks with Test::Unit Given a file named "rspec_mocks_test.rb" with: """ruby require 'test/unit' require 'rspec/mocks' class RSpecMocksTest < Test::Unit::TestCase def setup RSpec::Mocks.setup(Object) RSpec::Mocks.setup(self) end def test_passing_expectation obj = Object.new expect(obj).to receive(:message) obj.message end def test_failing_expectation obj = Object.new expect(obj).to_not receive(:message) obj.message end def test_with_deprecation_warning obj = Object.new obj.stub(:old_message) { RSpec.deprecate(:old_message, :replacement => :message) } obj.old_message end end """ When I run `ruby rspec_mocks_test.rb` Then the output should contain "3 tests, 0 assertions, 0 failures, 1 errors" or "3 tests, 0 assertions, 1 failures, 0 errors" And the output should contain "expected: 0 times with any arguments" And the output should contain "old_message is deprecated. Use message instead." rspec-mocks-2.14.3/features/README.md0000644000004100000410000000455212202216237017157 0ustar www-datawww-datarspec-mocks helps to control the context in a code example by letting you set known return values, fake implementations of methods, and even expectations that specific messages are received by an object. You can do these three things on test doubles that rspec-mocks creates for you on the fly, or you can do them on objects that are part of your system. ## Messages and Methods _Message_ and _method_ are metaphors that we use somewhat interchangeably, but they are subtly different. In Object Oriented Programming, objects communicate by sending _messages_ to one another. When an object receives a message, it invokes a _method_ with the same name as the message. ## Test Doubles A test double is an object that stands in for another object in your system during a code example. Use the `double` method to create one: double_account = double("Account") You can also use the `mock` and `stub` methods to create test doubles, however these methods are there for backward compatibility only and will likely be deprecated and then removed from future versions. ## Method Stubs A method stub is an instruction to an object (real or test double) to return a known value in response to a message: die.stub(:roll) { 3 } This tells the `die` object to return the value `3` when it receives the `roll` message. ## Message Expectations A message expectation is an expectation that an object should receive a specific message during the course of a code example: describe Account do context "when closed" do it "logs an 'account closed' message" do logger = double() account = Account.new account.logger = logger logger.should_receive(:account_closed).with(account) account.close end end end This example specifies that the `account` object sends the `logger` the `account_closed` message (with itself as an argument) when it receives the `close` message. ## Issues The documentation for rspec-mocks is a work in progress. We'll be adding Cucumber features over time, and clarifying existing ones. If you have specific features you'd like to see added, find the existing documentation incomplete or confusing, or, better yet, wish to write a missing Cucumber feature yourself, please [submit an issue](http://github.com/rspec/rspec-mocks/issues) or a [pull request](http://github.com/rspec/rspec-mocks). rspec-mocks-2.14.3/features/spies/0000755000004100000410000000000012202216237017015 5ustar www-datawww-datarspec-mocks-2.14.3/features/spies/spy_partial_mock_method.feature0000644000004100000410000000214312202216237025272 0ustar www-datawww-dataFeature: Spy on a stubbed method on a partial mock You can also use `have_received` to verify that a stubbed method was invoked on a partial mock. Scenario: verify a stubbed method Given a file named "verified_spy_spec.rb" with: """ruby describe "have_received" do it "passes when the expectation is met" do invitation = Object.new invitation.stub(:deliver => true) invitation.deliver invitation.should have_received(:deliver) end end """ When I run `rspec verified_spy_spec.rb` Then the examples should all pass Scenario: fail to verify a stubbed method Given a file named "failed_spy_spec.rb" with: """ruby describe "have_received" do it "fails when the expectation is not met" do invitation = Object.new invitation.stub(:deliver => true) invitation.should have_received(:deliver) end end """ When I run `rspec failed_spy_spec.rb` Then the output should contain "expected: 1 time" And the output should contain "received: 0 times" rspec-mocks-2.14.3/features/spies/spy_unstubbed_method.feature0000644000004100000410000000113312202216237024616 0ustar www-datawww-dataFeature: Spy on an unstubbed method Using have_received on an unstubbed method will never pass, so rspec-mocks issues a helpful error message. Scenario: fail to verify a stubbed method Given a file named "failed_spy_spec.rb" with: """ruby describe "have_received" do it "raises a helpful error for unstubbed methods" do object = Object.new object.object_id object.should have_received(:object_id) end end """ When I run `rspec failed_spy_spec.rb` Then the output should contain "that method has not been stubbed" rspec-mocks-2.14.3/features/spies/spy_pure_mock_method.feature0000644000004100000410000000535312202216237024617 0ustar www-datawww-dataFeature: Spy on a stubbed method on a pure mock You can use `have_received` to verify that a stubbed method was invoked, rather than setting an expectation for it to be invoked beforehand. Scenario: verify a stubbed method Given a file named "verified_spy_spec.rb" with: """ruby describe "have_received" do it "passes when the expectation is met" do invitation = double('invitation', :deliver => true) invitation.deliver invitation.should have_received(:deliver) end end """ When I run `rspec verified_spy_spec.rb` Then the examples should all pass Scenario: verify a stubbed method with message expectations Given a file named "verified_message_expectations_spec.rb" with: """ruby describe "have_received" do it "passes when the expectation is met" do invitation = double('invitation', :deliver => true) 2.times { invitation.deliver(:expected, :arguments) } invitation.should have_received(:deliver). with(:expected, :arguments). twice end end """ When I run `rspec verified_message_expectations_spec.rb` Then the examples should all pass Scenario: fail to verify a stubbed method Given a file named "failed_spy_spec.rb" with: """ruby describe "have_received" do it "fails when the expectation is not met" do invitation = double('invitation', :deliver => true) invitation.should have_received(:deliver) end end """ When I run `rspec failed_spy_spec.rb` Then the output should contain "expected: 1 time" And the output should contain "received: 0 times" Scenario: fail to verify message expectations Given a file named "failed_message_expectations_spec.rb" with: """ruby describe "have_received" do it "fails when the arguments are different" do invitation = double('invitation', :deliver => true) invitation.deliver(:unexpected) invitation.should have_received(:deliver).with(:expected, :arguments) end end """ When I run `rspec failed_message_expectations_spec.rb` Then the output should contain "expected: (:expected, :arguments)" And the output should contain "got: (:unexpected)" Scenario: generate a spy message Given a file named "spy_message_spec.rb" with: """ruby describe "have_received" do subject(:invitation) { double('invitation', :deliver => true) } before { invitation.deliver } it { should have_received(:deliver) } end """ When I run `rspec --format documentation spy_message_spec.rb` Then the output should contain "should have received deliver" rspec-mocks-2.14.3/features/argument_matchers/0000755000004100000410000000000012202216237021402 5ustar www-datawww-datarspec-mocks-2.14.3/features/argument_matchers/README.md0000644000004100000410000000125012202216237022657 0ustar www-datawww-data### Introduction Argument matchers can be used: * In stubs to constrain the scope of the stubbed method obj.stub(:foo).with(:bar) do |arg| #do something for :bar end obj.stub(:foo).with(:baz) do |arg| #do something for :baz end * In expectations to validate the arguments that should be received in a method call #create a double obj = double() #expect a message with given args obj.should_receive(:message).with('an argument') If more control is needed, one can use a block obj.should_receive(:message) do |arg1, arg2| # set expectations about the args in this block # and optionally set a return value endrspec-mocks-2.14.3/features/argument_matchers/general_matchers.feature0000644000004100000410000000517612202216237026273 0ustar www-datawww-dataFeature: General matchers The `anything`, `any_args`, and `no_args` matchers can be used to require the method to have arguments (or not) without constraining the details of the argument, such as its type, pattern or value. The `anything` matcher only reflects a single argument, while the `any_args` matcher matches any arity. Scenario: anything argument matcher Given a file named "stub_anything_args_spec.rb" with: """ruby describe "stubbed anything() args spec" do it "works" do object = Object.new object.stub(:foo).with(anything) do "anything" end object.foo(1).should eq("anything") object.foo(:that).should eq("anything") end end """ When I run `rspec stub_anything_args_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: any_args argument matcher Given a file named "stub_any_args_spec.rb" with: """ruby describe "stubbed any_args() args spec" do it "works" do object = Object.new object.stub(:foo).with(any_args) do "anything" end object.foo(1).should eq("anything") object.foo(:that).should eq("anything") object.foo.should eq("anything") end end """ When I run `rspec stub_any_args_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: no_args argument matcher Given a file named "stub_no_args_spec.rb" with: """ruby describe "stubbed no_args() args spec" do it "works for no args" do object = Object.new object.stub(:foo).with(no_args) do "nothing" end object.stub(:foo).with(anything) do "something" end object.foo(:that).should eq("something") object.foo.should eq("nothing") end end """ When I run `rspec stub_no_args_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: no_args argument matcher for expectations Given a file named "stub_no_args_expectations_spec.rb" with: """ruby describe "stubbed no_args() args spec for expectations" do it "works for no args" do object = Object.new object.should_receive(:foo).with(no_args) object.foo end it "fails for args" do object = Object.new object.should_receive(:foo).with(no_args) object.foo(:bar) end end """ When I run `rspec stub_no_args_expectations_spec.rb` Then the output should contain "2 examples, 1 failure"rspec-mocks-2.14.3/features/argument_matchers/type_matchers.feature0000644000004100000410000000153212202216237025627 0ustar www-datawww-dataFeature: stub with argument constraints You can further specify the behavior by constraining the type, format and/or number of arguments with the `#with()` method chained off of `#stub()` Scenario: an_instance_of argument matcher Given a file named "stub_an_instance_of_args_spec.rb" with: """ruby describe "stubbed an_instance_of() args spec" do it "works" do object = Object.new object.stub(:foo).with(an_instance_of(Symbol)) do "symbol" end object.stub(:foo).with(an_instance_of(String)) do "string" end object.foo("bar").should eq("string") object.foo(:that).should eq("symbol") end end """ When I run `rspec stub_an_instance_of_args_spec.rb` Then the output should contain "1 example, 0 failures"rspec-mocks-2.14.3/features/argument_matchers/explicit.feature0000644000004100000410000000335012202216237024601 0ustar www-datawww-dataFeature: explicit arguments Allows you to explicitly specify the argument values Scenario: explicit arguments Given a file named "stub_explicit_args_spec.rb" with: """ruby describe "stubbed explicit arguments" do it "works on stubs" do object = Object.new object.stub(:foo).with(:this) do |arg| "got this" end object.stub(:foo).with(:that) do |arg| "got that" end object.foo(:this).should eq("got this") object.foo(:that).should eq("got that") end it "works on doubles and expectations" do object = double('foo') object.should_receive(:bar).with(:foo) object.bar(:foo) end end """ When I run `rspec stub_explicit_args_spec.rb` Then the output should contain "2 examples, 0 failures" Scenario: explicit arguments with multiple arities Given a file named "stub_multiple_explicit_args_spec.rb" with: """ruby describe "stubbed multiple explicit arguments" do it "works on stubs" do object = Object.new object.stub(:foo).with(:this) do |arg| "got this" end object.stub(:foo).with(:this, :that) do |arg1, arg2| "got this and that" end object.foo(:this).should eq("got this") object.foo(:this, :that).should eq("got this and that") end it "works on mocks" do object = double('foo') object.should_receive(:foo).with(:this, :that) object.foo(:this, :that) end end """ When I run `rspec stub_multiple_explicit_args_spec.rb` Then the output should contain "2 examples, 0 failures"rspec-mocks-2.14.3/features/step_definitions/0000755000004100000410000000000012202216237021240 5ustar www-datawww-datarspec-mocks-2.14.3/features/step_definitions/additional_cli_steps.rb0000644000004100000410000000071512202216237025745 0ustar www-datawww-dataThen /^the example(?:s)? should(?: all)? pass$/ do step %q{the output should contain "0 failures"} step %q{the exit status should be 0} end # Useful for when the output is slightly different on different versions of ruby Then /^the output should contain "([^"]*)" or "([^"]*)"$/ do |string1, string2| unless [string1, string2].any? { |s| all_output =~ regexp(s) } fail %Q{Neither "#{string1}" or "#{string2}" were found in:\n#{all_output}} end end rspec-mocks-2.14.3/features/outside_rspec/0000755000004100000410000000000012202216237020542 5ustar www-datawww-datarspec-mocks-2.14.3/features/outside_rspec/standalone.feature0000644000004100000410000000177412202216237024260 0ustar www-datawww-dataFeature: standalone require "rspec/mocks/standalone" to expose the mock framework outside the RSpec environment. This is especially useful for exploring rspec-mocks in irb. Scenario: method stub outside rspec Given a file named "example.rb" with: """ruby require "rspec/mocks/standalone" greeter = double("greeter") greeter.stub(:say_hi) { "Hello!" } puts greeter.say_hi """ When I run `ruby example.rb` Then the output should contain "Hello!" Scenario: message expectation outside rspec Given a file named "example.rb" with: """ruby require "rspec/mocks/standalone" greeter = double("greeter") greeter.should_receive(:say_hi) RSpec::Mocks.verify """ When I run `ruby example.rb` Then the output should contain "RSpec::Mocks::MockExpectationError" And the output should contain "say_hi(any args)" And the output should contain "expected: 1 time" And the output should contain "received: 0 times" rspec-mocks-2.14.3/features/outside_rspec/configuration.feature0000644000004100000410000000313312202216237024766 0ustar www-datawww-dataFeature: configure any test framework to use rspec-mocks Test frameworks that want to use rspec-mocks can use RSpec::Mocks::setup(self) to hook into rspec-mocks. Doing so adds the following: To the object passed to setup: double # creates a test double mock # creates a test double stub # creates a test double To every object in the system: should_receive should_not_receive stub NOTICE: the stub() method that is added to the object passed to setup is not the same stub() method that is added to every other object. Scenario: RSpec::Mocks::setup(object) adds double, mock, and stub methods to the submitted object Given a file named "foo.rb" with: """ruby require 'rspec/mocks' class CodeExample def init RSpec::Mocks::setup(self) end end example = CodeExample.new example.init puts example.respond_to?(:double) puts example.respond_to?(:mock) puts example.respond_to?(:stub) """ When I run `ruby foo.rb` Then the output should contain "true" But the output should not contain "false" Scenario: RSpec::Mocks::setup(anything) adds methods to Object Given a file named "foo.rb" with: """ruby require 'rspec/mocks' RSpec::Mocks::setup(Object.new) obj = Object.new puts obj.respond_to?(:should_receive) puts obj.respond_to?(:should_not_receive) puts obj.respond_to?(:stub) """ When I run `ruby foo.rb` Then the output should contain "true" But the output should not contain "false" rspec-mocks-2.14.3/features/Scope.md0000644000004100000410000000114012202216237017261 0ustar www-datawww-dataDoubles, stubs, and message expectations are all cleaned out after each example. This ensures that each example can be run in isolation, and in any order. ### `before(:each)` It is perfectly fine to set up doubles, stubs, and message expectations in a `before(:each)` hook, as that hook is executed in the scope of the example: before(:each) do @account = double('account') end ### Do not create doubles, stubs, or message expectations in `before(:all)` If you do, they'll get cleaned out after the first example, and you will be very confused as to what's going on in the second example. rspec-mocks-2.14.3/features/support/0000755000004100000410000000000012202216237017406 5ustar www-datawww-datarspec-mocks-2.14.3/features/support/env.rb0000644000004100000410000000055012202216237020523 0ustar www-datawww-datarequire 'aruba/cucumber' require 'rspec/expectations' Before do RUBY_PLATFORM =~ /java/ ? @aruba_timeout_seconds = 60 : @aruba_timeout_seconds = 5 end Aruba.configure do |config| config.before_cmd do |cmd| set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived end end if RUBY_PLATFORM == 'java' rspec-mocks-2.14.3/features/support/rubinius.rb0000644000004100000410000000034112202216237021571 0ustar www-datawww-data# Required until https://github.com/rubinius/rubinius/issues/2430 is resolved ENV['RBXOPT'] = "#{ENV["RBXOPT"]} -Xcompiler.no_rbc" Around "@unsupported-on-rbx" do |scenario, block| block.call unless defined?(Rubinius) end rspec-mocks-2.14.3/features/message_expectations/0000755000004100000410000000000012202216237022104 5ustar www-datawww-datarspec-mocks-2.14.3/features/message_expectations/expect_message_using_expect.feature0000644000004100000410000000626612202216237031244 0ustar www-datawww-dataFeature: expect message using `expect` Use `expect(object).to receive(:message)` to set an expectation that `object` should receive the message `:message` before the example is completed. Note: You can use `expect_any_instance_of` when you don't have a reference to the object that receives a message in your test. For more information, see the message_expectations/expect_any_instance_of feature. Scenario: expect a message Given a file named "spec/account_spec.rb" with: """ruby require "account" describe Account do context "when closed" do it "logs an account closed message" do logger = double("logger") account = Account.new logger expect(logger).to receive(:account_closed) account.close end end end """ And a file named "lib/account.rb" with: """ruby Account = Struct.new(:logger) do def close logger.account_closed end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: expect a message with an argument Given a file named "spec/account_spec.rb" with: """ruby require "account" describe Account do context "when closed" do it "logs an account closed message" do logger = double("logger") account = Account.new logger expect(logger).to receive(:account_closed).with(account) account.close end end end """ And a file named "lib/account.rb" with: """ruby Account = Struct.new(:logger) do def close logger.account_closed(self) end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: provide a return value Given a file named "spec/message_expectation_spec.rb" with: """ruby describe "a message expectation with a return value" do context "specified in a block" do it "returns the specified value" do object = double("object") expect(object).to receive(:message) { :return_value } object.message.should eq(:return_value) end end context "specified with and_return" do it "returns the specified value" do object = double("object") expect(object).to receive(:message).and_return(:return_value) object.message.should eq(:return_value) end end end """ When I run `rspec spec/message_expectation_spec.rb` Then the output should contain "2 examples, 0 failures" Scenario: expect a specific number of calls Given a file named "spec/message_count_spec.rb" with: """ruby describe "a message expectation with a count" do it "passes if the expected number of calls happen" do string = "hi" expect(string).to receive(:length).exactly(3).times 3.times { string.length } end end """ When I run `rspec spec/message_count_spec.rb` Then the output should contain "1 example, 0 failures" rspec-mocks-2.14.3/features/message_expectations/call_original.feature0000644000004100000410000000124712202216237026264 0ustar www-datawww-dataFeature: Calling the original method You can use `and_call_original` on the fluent interface to "pass through" the received message to the original method. Scenario: expect a message Given a file named "call_original_spec.rb" with: """ruby class Addition def self.two_plus_two 4 end end describe "and_call_original" do it "delegates the message to the original implementation" do Addition.should_receive(:two_plus_two).and_call_original Addition.two_plus_two.should eq(4) end end """ When I run `rspec call_original_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/message_expectations/README.md0000644000004100000410000000372112202216237023366 0ustar www-datawww-data### Basics # create a double obj = double() # expect a message obj.should_receive(:message) # specify a return value obj.should_receive(:message) { :value } obj.should_receive(:message => :value) obj.should_receive(:message).and_return(:value) These forms are somewhat interchangeable. The difference is that the block contents are evaluated lazily when the `obj` receives the `message` message, whereas the others are evaluated as they are read. ### Fake implementation obj.should_receive(:message) do |arg1, arg2| # set expectations about the args in this block # and set a return value end ### Using the original implementation obj.should_receive(:message).and_call_original ### Raising/Throwing obj.should_receive(:message).and_raise("this error") obj.should_receive(:message).and_throw(:this_symbol) You can also use the block format: obj.should_receive(:message) { raise "this error" } obj.should_receive(:message) { throw :this_symbol } ### Argument constraints #### Explicit arguments obj.should_receive(:message).with('an argument') obj.should_receive(:message).with('more_than', 'one_argument') #### Argument matchers obj.should_receive(:message).with(anything()) obj.should_receive(:message).with(an_instance_of(Money)) obj.should_receive(:message).with(hash_including(:a => 'b')) #### Regular expressions obj.should_receive(:message).with(/abc/) ### Counts obj.should_receive(:message).once obj.should_receive(:message).twice obj.should_receive(:message).exactly(3).times obj.should_receive(:message).at_least(:once) obj.should_receive(:message).at_least(:twice) obj.should_receive(:message).at_least(n).times obj.should_receive(:message).at_most(:once) obj.should_receive(:message).at_most(:twice) obj.should_receive(:message).at_most(n).times ### Ordering obj.should_receive(:one).ordered obj.should_receive(:two).ordered rspec-mocks-2.14.3/features/message_expectations/block_local_expectations.feature.pending0000644000004100000410000000275712202216237032151 0ustar www-datawww-dataFeature: block local expectations Background: Given a file named "lib/account.rb" with: """ class Account def self.create yield new end def opening_balance(amount, currency) end end """ Scenario: passing example Given a file named "spec/account_spec.rb" with: """ require 'account' describe "account DSL" do it "it succeeds when the block local receives the given call" do account = double("Account") Account.should_receive(:create).and_yield(account) do |account| account.should_receive(:opening_balance).with(100, :USD) end Account.create do |account| account.opening_balance 100, :USD end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: failing example Given a file named "spec/account_spec.rb" with: """ require 'account' describe "account DSL" do it "fails when the block local does not receive the expected call" do Account.should_receive(:create).and_yield do |account| account.should_receive(:opening_balance).with(100, :USD) end Account.create do |account| # opening_balance is not called here end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 1 failure"rspec-mocks-2.14.3/features/message_expectations/warn_when_expectation_is_set_on_nil.feature0000644000004100000410000000274312202216237032766 0ustar www-datawww-dataFeature: warn when expectation is set on nil Scenario: nil instance variable Given a file named "example_spec.rb" with: """ruby RSpec.configure {|c| c.mock_with :rspec} describe "something" do it "does something" do @i_do_not_exist.should_receive(:foo) @i_do_not_exist.foo end end """ When I run `rspec example_spec.rb` Then the output should contain "An expectation of :foo was set on nil" Scenario: allow Given a file named "example_spec.rb" with: """ruby RSpec.configure {|c| c.mock_with :rspec} describe "something" do it "does something" do allow_message_expectations_on_nil nil.should_receive(:foo) nil.foo end end """ When I run `rspec example_spec.rb` Then the output should not contain "An expectation" Scenario: allow in one example, but not on another Given a file named "example_spec.rb" with: """ruby RSpec.configure {|c| c.mock_with :rspec} describe "something" do it "does something (foo)" do allow_message_expectations_on_nil nil.should_receive(:foo) nil.foo end it "does something (bar)" do nil.should_receive(:bar) nil.bar end end """ When I run `rspec example_spec.rb` Then the output should contain "An expectation of :bar" And the output should not contain "An expectation of :foo" rspec-mocks-2.14.3/features/message_expectations/expect_any_instance_of.feature0000644000004100000410000000202212202216237030164 0ustar www-datawww-dataFeature: expect a message on any instance of a class Use `expect_any_instance_of(Class).to receive` to set an expectation that one (and only one) instance of a class receives a message before the example is completed. The spec will fail if no instance receives a message. Scenario: expect a message on any instance of a class Given a file named "example_spec.rb" with: """ruby describe "expect_any_instance_of" do before do expect_any_instance_of(Object).to receive(:foo).and_return(:return_value) end it "verifies that one instance of the class receives the message" do o = Object.new expect(o.foo).to eq(:return_value) end it "fails unless an instance receives that message" do o = Object.new end end """ When I run `rspec example_spec.rb` Then the output should contain "2 examples, 1 failure" And the output should contain "1) expect_any_instance_of fails unless an instance receives that message" rspec-mocks-2.14.3/features/message_expectations/any_instance.feature0000644000004100000410000000137212202216237026137 0ustar www-datawww-dataFeature: expect a message on any instance of a class Use `any_instance.should_receive` to set an expectation that one (and only one) instance of a class receives a message before the example is completed. The spec will fail if no instance receives a message. Scenario: expect a message on any instance of a class Given a file named "example_spec.rb" with: """ruby describe "any_instance.should_receive" do it "verifies that one instance of the class receives the message" do Object.any_instance.should_receive(:foo).and_return(:return_value) o = Object.new o.foo.should eq(:return_value) end end """ When I run `rspec example_spec.rb` Then the examples should all passrspec-mocks-2.14.3/features/message_expectations/expect_message_using_should_receive.feature0000644000004100000410000000643412202216237032751 0ustar www-datawww-dataFeature: expect message using `should_receive` Use `object.should_receive(:message)` to set an expectation that `object` should receive the message `:message` before the example is completed. Background: Given a file named "spec/spec_helper.rb" with: """ruby RSpec.configure do |config| config.mock_with :rspec do |mocks| mocks.syntax = :should end end """ Scenario: expect a message Given a file named "spec/account_spec.rb" with: """ruby require "account" require "spec_helper" describe Account do context "when closed" do it "logs an account closed message" do logger = double("logger") account = Account.new logger logger.should_receive(:account_closed) account.close end end end """ And a file named "lib/account.rb" with: """ruby Account = Struct.new(:logger) do def close logger.account_closed end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: expect a message with an argument Given a file named "spec/account_spec.rb" with: """ruby require "account" require "spec_helper" describe Account do context "when closed" do it "logs an account closed message" do logger = double("logger") account = Account.new logger logger.should_receive(:account_closed).with(account) account.close end end end """ And a file named "lib/account.rb" with: """ruby Account = Struct.new(:logger) do def close logger.account_closed(self) end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: provide a return value Given a file named "spec/message_expectation_spec.rb" with: """ruby require "spec_helper" describe "a message expectation with a return value" do context "specified in a block" do it "returns the specified value" do object = double("object") object.should_receive(:message) { :return_value } object.message.should eq(:return_value) end end context "specified with and_return" do it "returns the specified value" do object = double("object") object.should_receive(:message).and_return(:return_value) object.message.should eq(:return_value) end end end """ When I run `rspec spec/message_expectation_spec.rb` Then the output should contain "2 examples, 0 failures" Scenario: expect a specific number of calls Given a file named "spec/message_count_spec.rb" with: """ruby require "spec_helper" describe "a message expectation with a count" do it "passes if the expected number of calls happen" do string = "hi" string.should_receive(:length).exactly(3).times 3.times { string.length } end end """ When I run `rspec spec/message_count_spec.rb` Then the output should contain "1 example, 0 failures" rspec-mocks-2.14.3/features/message_expectations/allow_any_instance_of.feature0000644000004100000410000000157012202216237030021 0ustar www-datawww-dataFeature: allow a message on any instance of a class Use `allow_any_instance_of(Class).to receive` when you want to configure how instances of the given class respond to a message without setting an expectation that the message will be received. Scenario: allowing a message on any instance of a class Given a file named "example_spec.rb" with: """ruby describe "any_instance.should_receive" do before do allow_any_instance_of(Object).to receive(:foo).and_return(:return_value) end it "allows any instance of the class to receive the message" do o = Object.new expect(o.foo).to eq(:return_value) end it "passes even if no instances receive that message" do o = Object.new end end """ When I run `rspec example_spec.rb` Then the examples should all pass rspec-mocks-2.14.3/features/message_expectations/receive_counts.feature0000644000004100000410000001223312202216237026477 0ustar www-datawww-dataFeature: receive counts Scenario: expect a message once Given a file named "spec/account_spec.rb" with: """ruby class Account attr_accessor :logger def open logger.account_opened end end describe Account do context "when opened" do it "logger#account_opened was called once" do logger = double("logger") account = Account.new account.logger = logger logger.should_receive(:account_opened).once account.open end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: expect a message twice Given a file named "spec/account_spec.rb" with: """ruby class Account attr_accessor :logger def open logger.account_opened end end describe Account do context "when opened" do it "logger#account_opened was called once" do logger = double("logger") account = Account.new account.logger = logger logger.should_receive(:account_opened).twice account.open account.open end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: expect a message 3 times Given a file named "spec/account_spec.rb" with: """ruby class Account attr_accessor :logger def open logger.account_opened end end describe Account do context "when opened" do it "logger#account_opened was called once" do logger = double("logger") account = Account.new account.logger = logger logger.should_receive(:account_opened).exactly(3).times account.open account.open account.open end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: expect a message at least (:once) Given a file named "spec/account_spec.rb" with: """ruby class Account attr_accessor :logger def open logger.account_opened end end describe Account do context "when opened" do it "logger#account_opened was called once" do logger = double("logger") account = Account.new account.logger = logger logger.should_receive(:account_opened).at_least(:once) account.open end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: expect a message at least (n) times Given a file named "spec/account_spec.rb" with: """ruby class Account attr_accessor :logger def open logger.account_opened end end describe Account do context "when opened" do it "logger#account_opened was called once" do logger = double("logger") account = Account.new account.logger = logger logger.should_receive(:account_opened).at_least(3).times # Note that I am calling method under test 4 times # and I specified it to be called at least 3 times account.open account.open account.open account.open end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" Scenario: expect a message at most (:once) Given a file named "spec/account_spec.rb" with: """ruby class Account attr_accessor :logger def open logger.account_opened end end describe Account do context "when opened" do it "logger#account_opened was called once" do logger = double("logger") account = Account.new account.logger = logger logger.should_receive(:account_opened).at_most(:once) account.open account.open end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "expected: at most 1 time" And the output should contain "received: 2 times" Scenario: expect a message at most (n) times Given a file named "spec/account_spec.rb" with: """ruby class Account attr_accessor :logger def open logger.account_opened end end describe Account do context "when opened" do it "logger#account_opened was called once" do logger = double("logger") account = Account.new account.logger = logger logger.should_receive(:account_opened).at_most(2).times account.open account.open end end end """ When I run `rspec spec/account_spec.rb` Then the output should contain "1 example, 0 failures" rspec-mocks-2.14.3/spec/0000755000004100000410000000000012202216237015006 5ustar www-datawww-datarspec-mocks-2.14.3/spec/spec_helper.rb0000644000004100000410000000230712202216237017626 0ustar www-datawww-datarequire 'yaml' begin require 'psych' rescue LoadError end RSpec::Matchers.define :include_method do |expected| match do |actual| actual.map { |m| m.to_s }.include?(expected.to_s) end end module VerifyAndResetHelpers def verify(object) RSpec::Mocks.proxy_for(object).verify end def reset(object) RSpec::Mocks.proxy_for(object).reset end end RSpec.configure do |config| config.mock_with :rspec config.color_enabled = true config.order = :random config.run_all_when_everything_filtered = true config.treat_symbols_as_metadata_keys_with_true_values = true config.filter_run_including :focus config.expect_with :rspec do |expectations| expectations.syntax = :expect end old_verbose = nil config.before(:each, :silence_warnings) do old_verbose = $VERBOSE $VERBOSE = nil end config.after(:each, :silence_warnings) do $VERBOSE = old_verbose end config.include VerifyAndResetHelpers end shared_context "with syntax" do |syntax| orig_syntax = nil before(:all) do orig_syntax = RSpec::Mocks.configuration.syntax RSpec::Mocks.configuration.syntax = syntax end after(:all) do RSpec::Mocks.configuration.syntax = orig_syntax end end rspec-mocks-2.14.3/spec/rspec/0000755000004100000410000000000012202216237016122 5ustar www-datawww-datarspec-mocks-2.14.3/spec/rspec/mocks/0000755000004100000410000000000012202216237017236 5ustar www-datawww-datarspec-mocks-2.14.3/spec/rspec/mocks/once_counts_spec.rb0000644000004100000410000000261312202216237023116 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "#once" do before(:each) do @double = double end it "passes when called once" do @double.should_receive(:do_something).once @double.do_something verify @double end it "passes when called once with specified args" do @double.should_receive(:do_something).once.with("a", "b", "c") @double.do_something("a", "b", "c") verify @double end it "passes when called once with unspecified args" do @double.should_receive(:do_something).once @double.do_something("a", "b", "c") verify @double end it "fails when called with wrong args" do @double.should_receive(:do_something).once.with("a", "b", "c") expect { @double.do_something("d", "e", "f") }.to raise_error(RSpec::Mocks::MockExpectationError) reset @double end it "fails fast when called twice" do @double.should_receive(:do_something).once @double.do_something expect { @double.do_something }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails when not called" do @double.should_receive(:do_something).once expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb0000644000004100000410000000553612202216237027553 0ustar www-datawww-datarequire 'spec_helper' module RSpec::Mocks describe "PartialMockUsingMocksDirectly" do let(:klass) do Class.new do module MethodMissing remove_method :method_missing rescue nil def method_missing(m, *a, &b) if m == :captured_by_method_missing "response generated by method missing" else super(m, *a, &b) end end end extend MethodMissing include MethodMissing def existing_method :original_value end end end let(:obj) { klass.new } # See http://rubyforge.org/tracker/index.php?func=detail&aid=10263&group_id=797&atid=3149 # specify "should clear expectations on verify" do # obj.should_receive(:msg) # obj.msg # verify obj # expect { # obj.msg # }.to raise_error(NoMethodError) # # end it "fails when expected message is not received" do obj.should_receive(:msg) expect { verify obj }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails when message is received with incorrect args" do obj.should_receive(:msg).with(:correct_arg) expect { obj.msg(:incorrect_arg) }.to raise_error(RSpec::Mocks::MockExpectationError) obj.msg(:correct_arg) end it "passes when expected message is received" do obj.should_receive(:msg) obj.msg verify obj end it "passes when message is received with correct args" do obj.should_receive(:msg).with(:correct_arg) obj.msg(:correct_arg) verify obj end it "restores the original method if it existed" do expect(obj.existing_method).to equal(:original_value) obj.should_receive(:existing_method).and_return(:mock_value) expect(obj.existing_method).to equal(:mock_value) verify obj expect(obj.existing_method).to equal(:original_value) end context "with an instance method handled by method_missing" do it "restores the original behavior" do expect(obj.captured_by_method_missing).to eq("response generated by method missing") obj.stub(:captured_by_method_missing) { "foo" } expect(obj.captured_by_method_missing).to eq("foo") reset obj expect(obj.captured_by_method_missing).to eq("response generated by method missing") end end context "with a class method handled by method_missing" do it "restores the original behavior" do expect(klass.captured_by_method_missing).to eq("response generated by method missing") klass.stub(:captured_by_method_missing) { "foo" } expect(klass.captured_by_method_missing).to eq("foo") reset klass expect(klass.captured_by_method_missing).to eq("response generated by method missing") end end end end rspec-mocks-2.14.3/spec/rspec/mocks/combining_implementation_instructions_spec.rb0000644000004100000410000001434612202216237030503 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "Combining implementation instructions" do it 'can combine and_yield and and_return' do dbl = double dbl.stub(:foo).and_yield(5).and_return(3) expect { |b| expect(dbl.foo(&b)).to eq(3) }.to yield_with_args(5) end describe "combining and_yield, a block implementation and and_return" do def verify_combined_implementation dbl = double (yield dbl).and_yield(5).and_return(3) expect { |b| expect(dbl.foo(:arg, &b)).to eq(3) }.to yield_with_args(5) expect(@block_called).to be_true end it 'works when passing a block to `stub`' do verify_combined_implementation do |dbl| dbl.stub(:foo) { @block_called = true } end end it 'works when passing a block to `with`' do verify_combined_implementation do |dbl| dbl.stub(:foo).with(:arg) { @block_called = true } end end it 'works when passing a block to `exactly`' do verify_combined_implementation do |dbl| dbl.should_receive(:foo).exactly(:once) { @block_called = true } end end it 'works when passing a block to `at_least`' do verify_combined_implementation do |dbl| dbl.should_receive(:foo).at_least(:once) { @block_called = true } end end it 'works when passing a block to `at_most`' do verify_combined_implementation do |dbl| dbl.should_receive(:foo).at_most(:once) { @block_called = true } end end it 'works when passing a block to `times`' do verify_combined_implementation do |dbl| dbl.should_receive(:foo).exactly(1).times { @block_called = true } end end it 'works when passing a block to `any_number_of_times`' do verify_combined_implementation do |dbl| dbl.should_receive(:foo).any_number_of_times { @block_called = true } end end it 'works when passing a block to `once`' do verify_combined_implementation do |dbl| dbl.should_receive(:foo).once { @block_called = true } end end it 'works when passing a block to `twice`' do the_double = nil verify_combined_implementation do |dbl| the_double = dbl dbl.should_receive(:foo).twice { @block_called = true } end the_double.foo { |a| } # to ensure it is called twice end it 'works when passing a block to `ordered`' do verify_combined_implementation do |dbl| dbl.should_receive(:foo).ordered { @block_called = true } end end end it 'can combine and_yield and and_return with a block' do dbl = double dbl.stub(:foo).and_yield(5).and_return { :return } expect { |b| expect(dbl.foo(&b)).to eq(:return) }.to yield_with_args(5) end it 'can combine and_yield and and_raise' do dbl = double dbl.stub(:foo).and_yield(5).and_raise("boom") expect { |b| expect { dbl.foo(&b) }.to raise_error("boom") }.to yield_with_args(5) end it 'can combine and_yield, a block implementation and and_raise' do dbl = double block_called = false dbl.stub(:foo) { block_called = true }.and_yield(5).and_raise("boom") expect { |b| expect { dbl.foo(&b) }.to raise_error("boom") }.to yield_with_args(5) expect(block_called).to be_true end it 'can combine and_yield and and_throw' do dbl = double dbl.stub(:foo).and_yield(5).and_throw(:bar) expect { |b| expect { dbl.foo(&b) }.to throw_symbol(:bar) }.to yield_with_args(5) end it 'can combine and_yield, a block implementation and and_throw' do dbl = double block_called = false dbl.stub(:foo) { block_called = true }.and_yield(5).and_throw(:bar) expect { |b| expect { dbl.foo(&b) }.to throw_symbol(:bar) }.to yield_with_args(5) expect(block_called).to be_true end it 'returns `nil` from all terminal actions to discourage further configuration' do expect(double.stub(:foo).and_return(1)).to be_nil expect(double.stub(:foo).and_raise("boom")).to be_nil expect(double.stub(:foo).and_throw(:foo)).to be_nil end it 'allows the terminal action to be overriden' do dbl = double stubbed_double = dbl.stub(:foo) stubbed_double.and_return(1) expect(dbl.foo).to eq(1) stubbed_double.and_return(3) expect(dbl.foo).to eq(3) stubbed_double.and_raise("boom") expect { dbl.foo }.to raise_error("boom") stubbed_double.and_throw(:bar) expect { dbl.foo }.to throw_symbol(:bar) end it 'allows the inner implementation block to be overriden' do dbl = double stubbed_double = dbl.stub(:foo) stubbed_double.with(:arg) { :with_block } expect(dbl.foo(:arg)).to eq(:with_block) stubbed_double.at_least(:once) { :at_least_block } expect(dbl.foo(:arg)).to eq(:at_least_block) end it 'can combine and_call_original, with, and_return' do obj = Struct.new(:value).new('original') obj.stub(:value).and_call_original obj.stub(:value).with(:arg).and_return('value') expect(obj.value).to eq 'original' expect(obj.value(:arg)).to eq 'value' end it 'raises an error if `and_call_original` is followed by any other instructions' do dbl = [1, 2, 3] stubbed = dbl.stub(:size) stubbed.and_call_original msg_fragment = /cannot be modified further/ expect { stubbed.and_yield }.to raise_error(msg_fragment) expect { stubbed.and_return(1) }.to raise_error(msg_fragment) expect { stubbed.and_raise("a") }.to raise_error(msg_fragment) expect { stubbed.and_throw(:bar) }.to raise_error(msg_fragment) expect { stubbed.once { } }.to raise_error(msg_fragment) expect(dbl.size).to eq(3) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/partial_mock_spec.rb0000644000004100000410000001343612202216237023251 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "using a Partial Mock," do let(:object) { Object.new } it "names the class in the failure message" do object.should_receive(:foo) expect do verify object end.to raise_error(RSpec::Mocks::MockExpectationError, /\(#\).foo/) end it "names the class in the failure message when expectation is on class" do Object.should_receive(:foo) expect { verify Object }.to raise_error(RSpec::Mocks::MockExpectationError, //) end it "does not conflict with @options in the object" do object.instance_eval { @options = Object.new } object.should_receive(:blah) object.blah end it "should_not_receive mocks out the method" do object.should_not_receive(:fuhbar) expect { object.fuhbar }.to raise_error( RSpec::Mocks::MockExpectationError, /expected\: 0 times with any arguments\n received\: 1 time/ ) end it "should_not_receive returns a negative message expectation" do expect(object.should_not_receive(:foobar)).to be_negative end it "should_receive mocks out the method" do object.should_receive(:foobar).with(:test_param).and_return(1) expect(object.foobar(:test_param)).to equal(1) end it "should_receive handles a hash" do object.should_receive(:foobar).with(:key => "value").and_return(1) expect(object.foobar(:key => "value")).to equal(1) end it "should_receive handles an inner hash" do hash = {:a => {:key => "value"}} object.should_receive(:foobar).with(:key => "value").and_return(1) expect(object.foobar(hash[:a])).to equal(1) end it "should_receive returns a positive message expectation" do expect(object.should_receive(:foobar)).not_to be_negative object.foobar end it "should_receive verifies method was called" do object.should_receive(:foobar).with(:test_param).and_return(1) expect { verify object }.to raise_error(RSpec::Mocks::MockExpectationError) end it "should_receive also takes a String argument" do object.should_receive('foobar') object.foobar end it "should_not_receive also takes a String argument" do object.should_not_receive('foobar') expect { object.foobar }.to raise_error(RSpec::Mocks::MockExpectationError) end it "uses reports nil in the error message" do allow_message_expectations_on_nil _nil = nil _nil.should_receive(:foobar) expect { verify _nil }.to raise_error( RSpec::Mocks::MockExpectationError, %Q|(nil).foobar(any args)\n expected: 1 time with any arguments\n received: 0 times with any arguments| ) end it "includes the class name in the error when mocking a class method that is called an extra time with the wrong args" do klass = Class.new do def self.inspect "MyClass" end end klass.should_receive(:bar).with(1) klass.bar(1) expect { klass.bar(2) }.to raise_error(RSpec::Mocks::MockExpectationError, /MyClass/) end end describe "Using a partial mock on a proxy object", :if => defined?(::BasicObject) do let(:proxy_class) do Class.new(::BasicObject) do def initialize(target) @target = target end def proxied? true end def method_missing(*a) @target.send(*a) end end end let(:wrapped_object) { Object.new } let(:proxy) { proxy_class.new(wrapped_object) } it 'works properly' do proxy.should_receive(:proxied?).and_return(false) expect(proxy).not_to be_proxied end it 'does not confuse the proxy and the proxied object' do proxy.stub(:foo).and_return(:proxy_foo) wrapped_object.stub(:foo).and_return(:wrapped_foo) expect(proxy.foo).to eq(:proxy_foo) expect(wrapped_object.foo).to eq(:wrapped_foo) end end describe "Partially mocking an object that defines ==, after another mock has been defined" do before(:each) do double("existing mock", :foo => :foo) end let(:klass) do Class.new do attr_reader :val def initialize(val) @val = val end def ==(other) @val == other.val end end end it "does not raise an error when stubbing the object" do o = klass.new :foo expect { o.stub(:bar) }.not_to raise_error end end describe "Method visibility when using partial mocks" do let(:klass) do Class.new do def public_method private_method protected_method end protected def protected_method; end private def private_method; end end end let(:object) { klass.new } it 'keeps public methods public' do object.should_receive(:public_method) expect(object.public_methods).to include_method(:public_method) object.public_method end it 'keeps private methods private' do object.should_receive(:private_method) expect(object.private_methods).to include_method(:private_method) object.public_method end it 'keeps protected methods protected' do object.should_receive(:protected_method) expect(object.protected_methods).to include_method(:protected_method) object.public_method end end end end rspec-mocks-2.14.3/spec/rspec/mocks/and_call_original_spec.rb0000644000004100000410000002001512202216237024214 0ustar www-datawww-datarequire 'spec_helper' require 'delegate' describe "and_call_original" do context "on a partial mock object" do let(:klass) do Class.new do def meth_1 :original end def meth_2(x) yield x, :additional_yielded_arg end def self.new_instance new end end end let(:instance) { klass.new } it 'passes the received message through to the original method' do instance.should_receive(:meth_1).and_call_original expect(instance.meth_1).to eq(:original) end it 'passes args and blocks through to the original method' do instance.should_receive(:meth_2).and_call_original value = instance.meth_2(:submitted_arg) { |a, b| [a, b] } expect(value).to eq([:submitted_arg, :additional_yielded_arg]) end it 'errors when you pass through the wrong number of args' do instance.stub(:meth_1).and_call_original instance.stub(:meth_2).and_call_original expect { instance.meth_1 :a }.to raise_error ArgumentError expect { instance.meth_2 {} }.to raise_error ArgumentError expect { instance.meth_2(:a, :b) {} }.to raise_error ArgumentError end context "for singleton methods" do it 'works' do def instance.foo; :bar; end instance.should_receive(:foo).and_call_original expect(instance.foo).to eq(:bar) end it 'works for SimpleDelegator subclasses', :if => (RUBY_VERSION.to_f > 1.8) do instance = Class.new(SimpleDelegator).new(1) def instance.foo; :bar; end instance.should_receive(:foo).and_call_original expect(instance.foo).to eq(:bar) end end it 'works for methods added through an extended module' do instance.extend Module.new { def foo; :bar; end } instance.should_receive(:foo).and_call_original expect(instance.foo).to eq(:bar) end it "works for method added through an extended module onto a class's ancestor" do sub_sub_klass = Class.new(Class.new(klass)) klass.extend Module.new { def foo; :bar; end } sub_sub_klass.should_receive(:foo).and_call_original expect(sub_sub_klass.foo).to eq(:bar) end it "finds the method on the most direct ancestor even if the method " + "is available on more distant ancestors" do klass.extend Module.new { def foo; :klass_bar; end } sub_klass = Class.new(klass) sub_klass.extend Module.new { def foo; :sub_klass_bar; end } sub_klass.should_receive(:foo).and_call_original expect(sub_klass.foo).to eq(:sub_klass_bar) end context 'when using any_instance' do it 'works for instance methods defined on the class' do klass.any_instance.should_receive(:meth_1).and_call_original expect(klass.new.meth_1).to eq(:original) end it 'works for instance methods defined on the superclass of the class' do subclass = Class.new(klass) subclass.any_instance.should_receive(:meth_1).and_call_original expect(subclass.new.meth_1).to eq(:original) end it 'works when mocking the method on one class and calling the method on an instance of a subclass' do klass.any_instance.should_receive(:meth_1).and_call_original expect(Class.new(klass).new.meth_1).to eq(:original) end end if RUBY_VERSION.to_f > 1.8 it 'works for class methods defined on a superclass' do subclass = Class.new(klass) subclass.should_receive(:new_instance).and_call_original expect(subclass.new_instance).to be_a(subclass) end it 'works for class methods defined on a grandparent class' do sub_subclass = Class.new(Class.new(klass)) sub_subclass.should_receive(:new_instance).and_call_original expect(sub_subclass.new_instance).to be_a(sub_subclass) end else it 'attempts to work for class methods defined on a superclass but ' + 'executes the method with `self` as the superclass' do ::Kernel.stub(:warn) subclass = Class.new(klass) subclass.should_receive(:new_instance).and_call_original expect(subclass.new_instance).to be_an_instance_of(klass) end it 'prints a warning to notify users that `self` will not be correct' do subclass = Class.new(klass) ::Kernel.should_receive(:warn).with(/may not work correctly/) subclass.should_receive(:new_instance).and_call_original subclass.new_instance end end it 'works for class methods defined on the Class class' do klass.should_receive(:new).and_call_original expect(klass.new).to be_an_instance_of(klass) end it "works for instance methods defined on the object's class's superclass" do subclass = Class.new(klass) inst = subclass.new inst.should_receive(:meth_1).and_call_original expect(inst.meth_1).to eq(:original) end it 'works for aliased methods' do klass = Class.new do class << self alias alternate_new new end end klass.should_receive(:alternate_new).and_call_original expect(klass.alternate_new).to be_an_instance_of(klass) end context 'on an object that defines method_missing' do before do klass.class_eval do private def method_missing(name, *args) if name.to_s == "greet_jack" "Hello, jack" else super end end end end it 'works when the method_missing definition handles the message' do instance.should_receive(:greet_jack).and_call_original expect(instance.greet_jack).to eq("Hello, jack") end it 'works for an any_instance partial mock' do klass.any_instance.should_receive(:greet_jack).and_call_original expect(instance.greet_jack).to eq("Hello, jack") end it 'raises an error for an unhandled message for an any_instance partial mock' do klass.any_instance.should_receive(:not_a_handled_message).and_call_original expect { instance.not_a_handled_message }.to raise_error(NameError, /not_a_handled_message/) end it 'raises an error on invocation if method_missing does not handle the message' do instance.should_receive(:not_a_handled_message).and_call_original # Note: it should raise a NoMethodError (and usually does), but # due to a weird rspec-expectations issue (see #183) it sometimes # raises a `NameError` when a `be_xxx` predicate matcher has been # recently used. `NameError` is the superclass of `NoMethodError` # so this example will pass regardless. # If/when we solve the rspec-expectations issue, this can (and should) # be changed to `NoMethodError`. expect { instance.not_a_handled_message }.to raise_error(NameError, /not_a_handled_message/) end end end context "on a partial mock object that overrides #method" do let(:request_klass) do Struct.new(:method, :url) do def perform :the_response end def self.method :some_method end end end let(:request) { request_klass.new(:get, "http://foo.com/bar") } it 'still works even though #method has been overriden' do request.should_receive(:perform).and_call_original expect(request.perform).to eq(:the_response) end it 'works for a singleton method' do def request.perform :a_response end request.should_receive(:perform).and_call_original expect(request.perform).to eq(:a_response) end end context "on a pure mock object" do let(:instance) { double } it 'raises an error even if the mock object responds to the message' do expect(instance.to_s).to be_a(String) mock_expectation = instance.should_receive(:to_s) instance.to_s # to satisfy the expectation expect { mock_expectation.and_call_original }.to raise_error(/and_call_original.*partial mock/i) end end end rspec-mocks-2.14.3/spec/rspec/mocks/nil_expectation_warning_spec.rb0000644000004100000410000000414512202216237025513 0ustar www-datawww-datarequire 'spec_helper' def remove_last_describe_from_world RSpec::world.example_groups.pop end def empty_example_group RSpec::Core::ExampleGroup.describe(Object, 'Empty Behaviour Group') { } remove_last_describe_from_world end module RSpec module Mocks describe "an expectation set on nil" do it "issues a warning with file and line number information" do expected_warning = %r%An expectation of :foo was set on nil. Called from #{__FILE__}:#{__LINE__+3}(:in .+)?. Use allow_message_expectations_on_nil to disable warnings.% Kernel.should_receive(:warn).with(expected_warning) nil.should_receive(:foo) nil.foo end it "issues a warning when the expectation is negative" do Kernel.should_receive(:warn) nil.should_not_receive(:foo) end it "does not issue a warning when expectations are set to be allowed" do allow_message_expectations_on_nil Kernel.should_not_receive(:warn) nil.should_receive(:foo) nil.should_not_receive(:bar) nil.foo end it 'does not call #nil? on a double extra times' do dbl = double dbl.should_receive(:nil?).once.and_return(false) dbl.nil? end end describe "#allow_message_expectations_on_nil" do it "does not affect subsequent examples" do example_group = ::RSpec::Core::ExampleGroup.describe reporter = ::RSpec.configuration.reporter example_group.it("when called in one example that doesn't end up setting an expectation on nil") do allow_message_expectations_on_nil end example_group.it("should not effect the next example ran") do Kernel.should_receive(:warn) nil.should_receive(:foo) nil.foo end expect(example_group.run reporter).to eq true end it 'doesnt error when marshalled' do allow_message_expectations_on_nil expect(Marshal.dump(nil)).to eq Marshal.dump_without_mocks(nil) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/instance_method_stasher_spec.rb0000644000004100000410000000324712202216237025500 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe InstanceMethodStasher do class ExampleClass def hello :hello_defined_on_class end end def singleton_class_for(obj) class << obj; self; end end it "stashes the current implementation of an instance method so it can be temporarily replaced" do obj = Object.new def obj.hello; :hello_defined_on_singleton_class; end; stashed_method = InstanceMethodStasher.new(singleton_class_for(obj), :hello) stashed_method.stash def obj.hello; :overridden_hello; end expect(obj.hello).to eql :overridden_hello stashed_method.restore expect(obj.hello).to eql :hello_defined_on_singleton_class end it "stashes private instance methods" do obj = Object.new def obj.hello; :hello_defined_on_singleton_class; end; singleton_class_for(obj).__send__(:private, :hello) stashed_method = InstanceMethodStasher.new(singleton_class_for(obj), :hello) stashed_method.stash def obj.hello; :overridden_hello; end stashed_method.restore expect(obj.send(:hello)).to eql :hello_defined_on_singleton_class end it "only stashes methods directly defined on the given class, not its ancestors" do obj = ExampleClass.new stashed_method = InstanceMethodStasher.new(singleton_class_for(obj), :hello) stashed_method.stash def obj.hello; :overridden_hello; end; expect(obj.hello).to eql :overridden_hello stashed_method.restore expect(obj.hello).to eql :overridden_hello end end end end rspec-mocks-2.14.3/spec/rspec/mocks/stubbed_message_expectations_spec.rb0000644000004100000410000000361012202216237026517 0ustar www-datawww-datarequire 'spec_helper' describe "expection set on previously stubbed method" do it "fails if message is not received after expectation is set" do double = double(:msg => nil) double.msg double.should_receive(:msg) expect { verify double }.to raise_error(RSpec::Mocks::MockExpectationError) end it "outputs arguments of similar calls" do double = double('double', :foo => true) double.should_receive(:foo).with('first') double.foo('second') double.foo('third') expect { verify double }.to raise_error(%Q|Double "double" received :foo with unexpected arguments\n expected: ("first")\n got: ("second"), ("third")|) reset double end context "with argument constraint on stub" do it "matches any args if no arg constraint set on expectation" do double = double("mock") double.stub(:foo).with(3).and_return("stub") double.should_receive(:foo).at_least(:once).and_return("expectation") double.foo verify double end it "matches specific args set on expectation" do double = double("mock") double.stub(:foo).with(3).and_return("stub") double.should_receive(:foo).at_least(:once).with(4).and_return("expectation") double.foo(4) verify double end it "fails if expectation's arg constraint is not met" do double = double("mock") double.stub(:foo).with(3).and_return("stub") double.should_receive(:foo).at_least(:once).with(4).and_return("expectation") double.foo(3) expect { verify double }.to raise_error(/expected: \(4\)\s+got: \(3\)/) end it 'distinguishes between individual values and arrays properly' do dbl = double dbl.stub(:foo).with('a', ['b']) expect { dbl.foo(['a'], 'b') }.to raise_error { |e| expect(e.message).to include('expected: ("a", ["b"])', 'got: (["a"], "b")') } end end end rspec-mocks-2.14.3/spec/rspec/mocks/test_double_spec.rb0000644000004100000410000000376012202216237023114 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe TestDouble do before(:all) do Module.class_eval do private def use; end end end after(:all) do Module.class_eval do undef use end end it 'can be extended onto a module to make it a pure test double that can mock private methods' do double = Module.new double.stub(:use) expect { double.use }.to raise_error(/private method `use' called/) double = Module.new { TestDouble.extend_onto(self) } double.should_receive(:use).and_return(:ok) expect(double.use).to be(:ok) end it 'sets the test double name when a name is passed' do double = Module.new { TestDouble.extend_onto(self, "MyDouble") } expect { double.foo }.to raise_error(/Mock "MyDouble" received/) end [[:should, :expect], [:expect], [:should]].each do |syntax| context "with syntax #{syntax.inspect}" do include_context "with syntax", syntax it 'stubs the methods passed in the stubs hash' do double = Module.new do TestDouble.extend_onto(self, "MyDouble", :a => 5, :b => 10) end expect(double.a).to eq(5) expect(double.b).to eq(10) end end end it 'indicates what type of test double it is in error messages' do double = Module.new do TestDouble.extend_onto(self, "A", :__declared_as => "ModuleMock") end expect { double.foo }.to raise_error(/ModuleMock "A"/) end it 'is declared as a mock by default' do double = Module.new { TestDouble.extend_onto(self) } expect { double.foo }.to raise_error(/Mock received/) end it 'warns of deprecation of :null_object => true' do RSpec.should_receive :deprecate double = Class.new { TestDouble.extend_onto self, 'name', :null_object => true } end end end end rspec-mocks-2.14.3/spec/rspec/mocks/any_instance_spec.rb0000644000004100000410000011325712202216237023261 0ustar www-datawww-datarequire 'spec_helper' require 'delegate' module RSpec module Mocks describe "#any_instance" do class CustomErrorForAnyInstanceSpec < StandardError;end let(:klass) do Class.new do def existing_method; :existing_method_return_value; end def existing_method_with_arguments(arg_one, arg_two = nil); :existing_method_with_arguments_return_value; end def another_existing_method; end private def private_method; :private_method_return_value; end end end let(:existing_method_return_value){ :existing_method_return_value } context "invocation order" do context "#stub" do it "raises an error if 'stub' follows 'with'" do expect { klass.any_instance.with("1").stub(:foo) }.to raise_error(NoMethodError) end it "raises an error if 'with' follows 'and_return'" do expect { klass.any_instance.stub(:foo).and_return(1).with("1") }.to raise_error(NoMethodError) end it "raises an error if 'with' follows 'and_raise'" do expect { klass.any_instance.stub(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError) end it "raises an error if 'with' follows 'and_yield'" do expect { klass.any_instance.stub(:foo).and_yield(1).with("1") }.to raise_error(NoMethodError) end end context "#stub_chain" do it "raises an error if 'stub_chain' follows 'any_instance'" do expect { klass.any_instance.and_return("1").stub_chain(:foo, :bar) }.to raise_error(NoMethodError) end end context "#should_receive" do it "raises an error if 'should_receive' follows 'with'" do expect { klass.any_instance.with("1").should_receive(:foo) }.to raise_error(NoMethodError) end it "raises an error if 'with' follows 'and_return'" do pending "see Github issue #42" expect { klass.any_instance.should_receive(:foo).and_return(1).with("1") }.to raise_error(NoMethodError) end it "raises an error if 'with' follows 'and_raise'" do pending "see Github issue #42" expect { klass.any_instance.should_receive(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError) end end end context "with #stub" do it "does not suppress an exception when a method that doesn't exist is invoked" do klass.any_instance.stub(:foo) expect { klass.new.bar }.to raise_error(NoMethodError) end context 'multiple methods' do it "allows multiple methods to be stubbed in a single invocation" do klass.any_instance.stub(:foo => 'foo', :bar => 'bar') instance = klass.new expect(instance.foo).to eq('foo') expect(instance.bar).to eq('bar') end it "adheres to the contract of multiple method stubbing withou any instance" do expect(Object.new.stub(:foo => 'foo', :bar => 'bar')).to eq(:foo => 'foo', :bar => 'bar') expect(klass.any_instance.stub(:foo => 'foo', :bar => 'bar')).to eq(:foo => 'foo', :bar => 'bar') end context "allows a chain of methods to be stubbed using #stub_chain" do it "given symbols representing the methods" do klass.any_instance.stub_chain(:one, :two, :three).and_return(:four) expect(klass.new.one.two.three).to eq(:four) end it "given a hash as the last argument uses the value as the expected return value" do klass.any_instance.stub_chain(:one, :two, :three => :four) expect(klass.new.one.two.three).to eq(:four) end it "given a string of '.' separated method names representing the chain" do klass.any_instance.stub_chain('one.two.three').and_return(:four) expect(klass.new.one.two.three).to eq(:four) end end end context "behaves as 'every instance'" do it "stubs every instance in the spec" do klass.any_instance.stub(:foo).and_return(result = Object.new) expect(klass.new.foo).to eq(result) expect(klass.new.foo).to eq(result) end it "stubs instance created before any_instance was called" do instance = klass.new klass.any_instance.stub(:foo).and_return(result = Object.new) expect(instance.foo).to eq(result) end it 'handles freeze and duplication correctly' do String.any_instance.stub(:any_method) foo = 'foo'.freeze expect(foo.dup.concat 'bar').to eq 'foobar' end end context "with argument matching" do before do klass.any_instance.stub(:foo).with(:param_one, :param_two).and_return(:result_one) klass.any_instance.stub(:foo).with(:param_three, :param_four).and_return(:result_two) end it "returns the stubbed value when arguments match" do instance = klass.new expect(instance.foo(:param_one, :param_two)).to eq(:result_one) expect(instance.foo(:param_three, :param_four)).to eq(:result_two) end it "fails the spec with an expectation error when the arguments do not match" do expect do klass.new.foo(:param_one, :param_three) end.to(raise_error(RSpec::Mocks::MockExpectationError)) end end context "with multiple stubs" do before do klass.any_instance.stub(:foo).and_return(1) klass.any_instance.stub(:bar).and_return(2) end it "stubs a method" do instance = klass.new expect(instance.foo).to eq(1) expect(instance.bar).to eq(2) end it "returns the same value for calls on different instances" do expect(klass.new.foo).to eq(klass.new.foo) expect(klass.new.bar).to eq(klass.new.bar) end end context "with #and_return" do it "stubs a method that doesn't exist" do klass.any_instance.stub(:foo).and_return(1) expect(klass.new.foo).to eq(1) end it "stubs a method that exists" do klass.any_instance.stub(:existing_method).and_return(1) expect(klass.new.existing_method).to eq(1) end it "returns the same object for calls on different instances" do return_value = Object.new klass.any_instance.stub(:foo).and_return(return_value) expect(klass.new.foo).to be(return_value) expect(klass.new.foo).to be(return_value) end end context "with #and_yield" do it "yields the value specified" do yielded_value = Object.new klass.any_instance.stub(:foo).and_yield(yielded_value) klass.new.foo{|value| expect(value).to be(yielded_value)} end end context 'with #and_call_original and competing #with' do let(:klass) { Struct.new(:a_method) } it 'can combine and_call_original, with, and_return' do allow_any_instance_of(klass).to receive(:a_method).and_call_original allow_any_instance_of(klass).to receive(:a_method).with(:arg).and_return('value') expect(klass.new('org').a_method).to eq 'org' expect(klass.new.a_method(:arg)).to eq 'value' end it 'can combine and_call_original, with, and_return (old syntax)' do klass.any_instance.stub(:a_method).and_call_original klass.any_instance.stub(:a_method).with(:arg).and_return('value') expect(klass.new('org').a_method).to eq 'org' expect(klass.new.a_method(:arg)).to eq 'value' end end context "with #and_raise" do it "stubs a method that doesn't exist" do klass.any_instance.stub(:foo).and_raise(CustomErrorForAnyInstanceSpec) expect { klass.new.foo}.to raise_error(CustomErrorForAnyInstanceSpec) end it "stubs a method that exists" do klass.any_instance.stub(:existing_method).and_raise(CustomErrorForAnyInstanceSpec) expect { klass.new.existing_method}.to raise_error(CustomErrorForAnyInstanceSpec) end end context "with a block" do it "stubs a method" do klass.any_instance.stub(:foo) { 1 } expect(klass.new.foo).to eq(1) end it "returns the same computed value for calls on different instances" do klass.any_instance.stub(:foo) { 1 + 2 } expect(klass.new.foo).to eq(klass.new.foo) end end context "core ruby objects" do it "works uniformly across *everything*" do Object.any_instance.stub(:foo).and_return(1) expect(Object.new.foo).to eq(1) end it "works with the non-standard constructor []" do Array.any_instance.stub(:foo).and_return(1) expect([].foo).to eq(1) end it "works with the non-standard constructor {}" do Hash.any_instance.stub(:foo).and_return(1) expect({}.foo).to eq(1) end it "works with the non-standard constructor \"\"" do String.any_instance.stub(:foo).and_return(1) expect("".foo).to eq(1) end it "works with the non-standard constructor \'\'" do String.any_instance.stub(:foo).and_return(1) expect(''.foo).to eq(1) end it "works with the non-standard constructor module" do Module.any_instance.stub(:foo).and_return(1) module RSpec::SampleRspecTestModule;end expect(RSpec::SampleRspecTestModule.foo).to eq(1) end it "works with the non-standard constructor class" do Class.any_instance.stub(:foo).and_return(1) class RSpec::SampleRspecTestClass;end expect(RSpec::SampleRspecTestClass.foo).to eq(1) end end end context "with #stub!" do it "raises with a message instructing the user to use stub instead" do expect do klass.any_instance.stub!(:foo) end.to raise_error(/Use stub instead/) end end context "with #unstub!" do it "raises with a message instructing the user to use unstub instead" do expect do klass.any_instance.unstub!(:foo) end.to raise_error(/Use unstub instead/) end end context "unstub implementation" do it "replaces the stubbed method with the original method" do klass.any_instance.stub(:existing_method) klass.any_instance.unstub(:existing_method) expect(klass.new.existing_method).to eq(:existing_method_return_value) end it "removes all stubs with the supplied method name" do klass.any_instance.stub(:existing_method).with(1) klass.any_instance.stub(:existing_method).with(2) klass.any_instance.unstub(:existing_method) expect(klass.new.existing_method).to eq(:existing_method_return_value) end it "does not remove any expectations with the same method name" do klass.any_instance.should_receive(:existing_method_with_arguments).with(3).and_return(:three) klass.any_instance.stub(:existing_method_with_arguments).with(1) klass.any_instance.stub(:existing_method_with_arguments).with(2) klass.any_instance.unstub(:existing_method_with_arguments) expect(klass.new.existing_method_with_arguments(3)).to eq(:three) end it "raises a MockExpectationError if the method has not been stubbed" do expect { klass.any_instance.unstub(:existing_method) }.to raise_error(RSpec::Mocks::MockExpectationError, 'The method `existing_method` was not stubbed or was already unstubbed') end end context "with #should_not_receive" do it "fails if the method is called" do klass.any_instance.should_not_receive(:existing_method) expect { klass.new.existing_method }.to raise_error(RSpec::Mocks::MockExpectationError) end it "passes if no method is called" do expect { klass.any_instance.should_not_receive(:existing_method) }.to_not raise_error end it "passes if only a different method is called" do klass.any_instance.should_not_receive(:existing_method) expect { klass.new.another_existing_method }.to_not raise_error end context "with constraints" do it "fails if the method is called with the specified parameters" do klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two) expect { klass.new.existing_method_with_arguments(:argument_one, :argument_two) }.to raise_error(RSpec::Mocks::MockExpectationError) end it "passes if the method is called with different parameters" do klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two) expect { klass.new.existing_method_with_arguments(:argument_three, :argument_four) }.to_not raise_error end end context 'when used in combination with should_receive' do it 'passes if only the expected message is received' do klass.any_instance.should_receive(:foo) klass.any_instance.should_not_receive(:bar) klass.new.foo RSpec::Mocks.space.verify_all end end it "prevents confusing double-negative expressions involving `never`" do expect { klass.any_instance.should_not_receive(:not_expected).never }.to raise_error(/trying to negate it again/) end end context "with #should_receive" do let(:foo_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: foo' } let(:existing_method_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: existing_method' } context "with an expectation is set on a method which does not exist" do it "returns the expected value" do klass.any_instance.should_receive(:foo).and_return(1) expect(klass.new.foo(1)).to eq(1) end it "fails if an instance is created but no invocation occurs" do expect do klass.any_instance.should_receive(:foo) klass.new RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails if no instance is created" do expect do klass.any_instance.should_receive(:foo).and_return(1) RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails if no instance is created and there are multiple expectations" do expect do klass.any_instance.should_receive(:foo) klass.any_instance.should_receive(:bar) RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: bar, foo') end it "allows expectations on instances to take priority" do klass.any_instance.should_receive(:foo) klass.new.foo instance = klass.new instance.should_receive(:foo).and_return(result = Object.new) expect(instance.foo).to eq(result) end context "behaves as 'exactly one instance'" do it "passes if subsequent invocations do not receive that message" do klass.any_instance.should_receive(:foo) klass.new.foo klass.new end it "fails if the method is invoked on a second instance" do instance_one = klass.new instance_two = klass.new expect do klass.any_instance.should_receive(:foo) instance_one.foo instance_two.foo end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'foo' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}") end end context "normal expectations on the class object" do it "fail when unfulfilled" do expect do klass.any_instance.should_receive(:foo) klass.should_receive(:woot) klass.new.foo RSpec::Mocks.space.verify_all end.to(raise_error(RSpec::Mocks::MockExpectationError) do |error| expect(error.message).not_to eq(existing_method_expectation_error_message) end) end it "pass when expectations are met" do klass.any_instance.should_receive(:foo) klass.should_receive(:woot).and_return(result = Object.new) klass.new.foo expect(klass.woot).to eq(result) end end end context "with an expectation is set on a method that exists" do it "returns the expected value" do klass.any_instance.should_receive(:existing_method).and_return(1) expect(klass.new.existing_method(1)).to eq(1) end it "fails if an instance is created but no invocation occurs" do expect do klass.any_instance.should_receive(:existing_method) klass.new RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) end it "fails if no instance is created" do expect do klass.any_instance.should_receive(:existing_method) RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) end it "fails if no instance is created and there are multiple expectations" do expect do klass.any_instance.should_receive(:existing_method) klass.any_instance.should_receive(:another_existing_method) RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: another_existing_method, existing_method') end context "after any one instance has received a message" do it "passes if subsequent invocations do not receive that message" do klass.any_instance.should_receive(:existing_method) klass.new.existing_method klass.new end it "fails if the method is invoked on a second instance" do instance_one = klass.new instance_two = klass.new expect do klass.any_instance.should_receive(:existing_method) instance_one.existing_method instance_two.existing_method end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'existing_method' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}") end end end it 'works with a BasicObject subclass that mixes in Kernel', :if => defined?(BasicObject) do klass = Class.new(BasicObject) do include ::Kernel def foo; end end klass.any_instance.should_receive(:foo) klass.new.foo end it 'works with a SimpleDelegator subclass', :if => (RUBY_VERSION.to_f > 1.8) do klass = Class.new(SimpleDelegator) do def foo; end end klass.any_instance.should_receive(:foo) klass.new(Object.new).foo end context "with argument matching" do before do klass.any_instance.should_receive(:foo).with(:param_one, :param_two).and_return(:result_one) klass.any_instance.should_receive(:foo).with(:param_three, :param_four).and_return(:result_two) end it "returns the expected value when arguments match" do instance = klass.new expect(instance.foo(:param_one, :param_two)).to eq(:result_one) expect(instance.foo(:param_three, :param_four)).to eq(:result_two) end it "fails when the arguments match but different instances are used" do instances = Array.new(2) { klass.new } expect do expect(instances[0].foo(:param_one, :param_two)).to eq(:result_one) expect(instances[1].foo(:param_three, :param_four)).to eq(:result_two) end.to raise_error(RSpec::Mocks::MockExpectationError) # ignore the fact that should_receive expectations were not met instances.each { |instance| reset instance } end it "is not affected by the invocation of existing methods on other instances" do expect(klass.new.existing_method_with_arguments(:param_one, :param_two)).to eq(:existing_method_with_arguments_return_value) instance = klass.new expect(instance.foo(:param_one, :param_two)).to eq(:result_one) expect(instance.foo(:param_three, :param_four)).to eq(:result_two) end it "fails when arguments do not match" do instance = klass.new expect do instance.foo(:param_one, :param_three) end.to raise_error(RSpec::Mocks::MockExpectationError) # ignore the fact that should_receive expectations were not met reset instance end end context "message count" do context "the 'once' constraint" do it "passes for one invocation" do klass.any_instance.should_receive(:foo).once klass.new.foo end it "fails when no instances are declared" do expect do klass.any_instance.should_receive(:foo).once RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails when an instance is declared but there are no invocations" do expect do klass.any_instance.should_receive(:foo).once klass.new RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails for more than one invocation" do expect do klass.any_instance.should_receive(:foo).once instance = klass.new 2.times { instance.foo } verify instance end.to raise_error(RSpec::Mocks::MockExpectationError) end end context "the 'twice' constraint" do it "passes for two invocations" do klass.any_instance.should_receive(:foo).twice instance = klass.new 2.times { instance.foo } end it "fails for more than two invocations" do expect do klass.any_instance.should_receive(:foo).twice instance = klass.new 3.times { instance.foo } verify instance end.to raise_error(RSpec::Mocks::MockExpectationError) end end context "the 'exactly(n)' constraint" do it "passes for n invocations where n = 3" do klass.any_instance.should_receive(:foo).exactly(3).times instance = klass.new 3.times { instance.foo } end it "fails for n invocations where n < 3" do expect do klass.any_instance.should_receive(:foo).exactly(3).times instance = klass.new 2.times { instance.foo } verify instance end.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails for n invocations where n > 3" do expect do klass.any_instance.should_receive(:foo).exactly(3).times instance = klass.new 4.times { instance.foo } verify instance end.to raise_error(RSpec::Mocks::MockExpectationError) end end context "the 'at_least(n)' constraint" do it "passes for n invocations where n = 3" do klass.any_instance.should_receive(:foo).at_least(3).times instance = klass.new 3.times { instance.foo } end it "fails for n invocations where n < 3" do expect do klass.any_instance.should_receive(:foo).at_least(3).times instance = klass.new 2.times { instance.foo } verify instance end.to raise_error(RSpec::Mocks::MockExpectationError) end it "passes for n invocations where n > 3" do klass.any_instance.should_receive(:foo).at_least(3).times instance = klass.new 4.times { instance.foo } end end context "the 'at_most(n)' constraint" do it "passes for n invocations where n = 3" do klass.any_instance.should_receive(:foo).at_most(3).times instance = klass.new 3.times { instance.foo } end it "passes for n invocations where n < 3" do klass.any_instance.should_receive(:foo).at_most(3).times instance = klass.new 2.times { instance.foo } end it "fails for n invocations where n > 3" do expect do klass.any_instance.should_receive(:foo).at_most(3).times instance = klass.new 4.times { instance.foo } verify instance end.to raise_error(RSpec::Mocks::MockExpectationError) end end context "the 'never' constraint" do it "passes for 0 invocations" do klass.any_instance.should_receive(:foo).never RSpec::Mocks.space.verify_all end it "fails on the first invocation" do expect do klass.any_instance.should_receive(:foo).never klass.new.foo end.to raise_error(RSpec::Mocks::MockExpectationError) end context "when combined with other expectations" do it "passes when the other expecations are met" do klass.any_instance.should_receive(:foo).never klass.any_instance.should_receive(:existing_method).and_return(5) expect(klass.new.existing_method).to eq(5) end it "fails when the other expecations are not met" do expect do klass.any_instance.should_receive(:foo).never klass.any_instance.should_receive(:existing_method).and_return(5) RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) end end end context "the 'any_number_of_times' constraint" do it "passes for 0 invocations" do klass.any_instance.should_receive(:foo).any_number_of_times verify klass.new end it "passes for a non-zero number of invocations" do allow(RSpec).to receive(:deprecate).with("any_number_of_times", :replacement => "stub") klass.any_instance.should_receive(:foo).any_number_of_times instance = klass.new instance.foo verify instance end it "does not interfere with other expectations" do klass.any_instance.should_receive(:foo).any_number_of_times klass.any_instance.should_receive(:existing_method).and_return(5) expect(klass.new.existing_method).to eq(5) end context "when combined with other expectations" do it "passes when the other expecations are met" do klass.any_instance.should_receive(:foo).any_number_of_times klass.any_instance.should_receive(:existing_method).and_return(5) expect(klass.new.existing_method).to eq(5) end it "fails when the other expecations are not met" do expect do klass.any_instance.should_receive(:foo).any_number_of_times klass.any_instance.should_receive(:existing_method).and_return(5) RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) end end end end end context "when resetting post-verification" do let(:space) { RSpec::Mocks.space } context "existing method" do before(:each) do klass.any_instance # to force it to be tracked end context "with stubbing" do context "public methods" do before(:each) do klass.any_instance.stub(:existing_method).and_return(1) expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_true end it "restores the class to its original state after each example when no instance is created" do space.verify_all expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_false expect(klass.new.existing_method).to eq(existing_method_return_value) end it "restores the class to its original state after each example when one instance is created" do klass.new.existing_method space.verify_all expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_false expect(klass.new.existing_method).to eq(existing_method_return_value) end it "restores the class to its original state after each example when more than one instance is created" do klass.new.existing_method klass.new.existing_method space.verify_all expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_false expect(klass.new.existing_method).to eq(existing_method_return_value) end end context "private methods" do before :each do klass.any_instance.stub(:private_method).and_return(:something) space.verify_all end it "cleans up the backed up method" do expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_false end it "restores a stubbed private method after the spec is run" do expect(klass.private_method_defined?(:private_method)).to be_true end it "ensures that the restored method behaves as it originally did" do expect(klass.new.send(:private_method)).to eq(:private_method_return_value) end end end context "with expectations" do context "private methods" do before :each do klass.any_instance.should_receive(:private_method).and_return(:something) klass.new.private_method space.verify_all end it "cleans up the backed up method" do expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_false end it "restores a stubbed private method after the spec is run" do expect(klass.private_method_defined?(:private_method)).to be_true end it "ensures that the restored method behaves as it originally did" do expect(klass.new.send(:private_method)).to eq(:private_method_return_value) end end context "ensures that the subsequent specs do not see expectations set in previous specs" do context "when the instance created after the expectation is set" do it "first spec" do klass.any_instance.should_receive(:existing_method).and_return(Object.new) klass.new.existing_method end it "second spec" do expect(klass.new.existing_method).to eq(existing_method_return_value) end end context "when the instance created before the expectation is set" do before :each do @instance = klass.new end it "first spec" do klass.any_instance.should_receive(:existing_method).and_return(Object.new) @instance.existing_method end it "second spec" do expect(@instance.existing_method).to eq(existing_method_return_value) end end end it "ensures that the next spec does not see that expectation" do klass.any_instance.should_receive(:existing_method).and_return(Object.new) klass.new.existing_method space.verify_all expect(klass.new.existing_method).to eq(existing_method_return_value) end end end context "with multiple calls to any_instance in the same example" do it "does not prevent the change from being rolled back" do klass.any_instance.stub(:existing_method).and_return(false) klass.any_instance.stub(:existing_method).and_return(true) RSpec::Mocks.space.verify_all expect(klass.new).to respond_to(:existing_method) expect(klass.new.existing_method).to eq(existing_method_return_value) end end it "adds an class to the current space when #any_instance is invoked" do expect { klass.any_instance }.to change { space.any_instance_recorders.size }.by(1) end it "adds an instance to the current space when stubbed method is invoked" do klass.any_instance.stub(:foo) instance = klass.new instance.foo expect(RSpec::Mocks.space.proxies.keys).to include(instance.object_id) end end context 'when used in conjunction with a `dup`' do it "doesn't cause an infinite loop" do pending "This intermittently fails on JRuby" if RUBY_PLATFORM == 'java' Object.any_instance.stub(:some_method) o = Object.new o.some_method expect { o.dup.some_method }.to_not raise_error end it "doesn't bomb if the object doesn't support `dup`" do klass = Class.new do undef_method :dup end klass.any_instance end it "doesn't fail when dup accepts parameters" do klass = Class.new do def dup(funky_option) end end klass.any_instance expect { klass.new.dup('Dup dup dup') }.to_not raise_error end end context "when directed at a method defined on a superclass" do let(:sub_klass) { Class.new(klass) } it "stubs the method correctly" do klass.any_instance.stub(:existing_method).and_return("foo") expect(sub_klass.new.existing_method).to eq "foo" end it "mocks the method correctly" do instance_one = sub_klass.new instance_two = sub_klass.new expect do klass.any_instance.should_receive(:existing_method) instance_one.existing_method instance_two.existing_method end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'existing_method' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}") end end context "when a class overrides Object#method" do let(:http_request_class) { Struct.new(:method, :uri) } it "stubs the method correctly" do http_request_class.any_instance.stub(:existing_method).and_return("foo") expect(http_request_class.new.existing_method).to eq "foo" end it "mocks the method correctly" do http_request_class.any_instance.should_receive(:existing_method).and_return("foo") expect(http_request_class.new.existing_method).to eq "foo" end end context "when used after the test has finished" do it "restores the original behavior of a stubbed method" do klass.any_instance.stub(:existing_method).and_return(:stubbed_return_value) instance = klass.new expect(instance.existing_method).to eq :stubbed_return_value RSpec::Mocks.verify expect(instance.existing_method).to eq :existing_method_return_value end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_496_spec.rb0000644000004100000410000000042512202216237023350 0ustar www-datawww-datarequire 'spec_helper' module BugReport496 describe "a message expectation on a base class object" do class BaseClass end class SubClass < BaseClass end it "is received" do BaseClass.should_receive(:new).once SubClass.new end end end rspec-mocks-2.14.3/spec/rspec/mocks/mock_spec.rb0000644000004100000410000007213512202216237021536 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe Mock do before(:each) { @double = double("test double") } after(:each) { reset @double } it "has method_missing as private" do expect(RSpec::Mocks::Mock.private_instance_methods).to include_method(:method_missing) end it "does not respond_to? method_missing (because it's private)" do expect(RSpec::Mocks::Mock.new).not_to respond_to(:method_missing) end it "reports line number of expectation of unreceived message" do expected_error_line = __LINE__; @double.should_receive(:wont_happen).with("x", 3) begin verify @double violated rescue RSpec::Mocks::MockExpectationError => e # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line expect(e.backtrace[0]).to match(/#{File.basename(__FILE__)}:#{expected_error_line}/) end end it "reports line number of expectation of unreceived message after #should_receive after similar stub" do @double.stub(:wont_happen) expected_error_line = __LINE__; @double.should_receive(:wont_happen).with("x", 3) begin verify @double violated rescue RSpec::Mocks::MockExpectationError => e # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line expect(e.backtrace[0]).to match(/#{File.basename(__FILE__)}:#{expected_error_line}/) end end it "passes when not receiving message specified as not to be received" do @double.should_not_receive(:not_expected) verify @double end it "prevents confusing double-negative expressions involving `never`" do expect { @double.should_not_receive(:not_expected).never }.to raise_error(/trying to negate it again/) end def expect_and_return_warning expect(RSpec).to receive(:deprecate).with(/`and_return` on a negative message expectation/) end it "warns when `should_not_receive().and_return` is used" do expect_and_return_warning @double.should_not_receive(:foo).and_return(1) end it "warns when `should_receive().never.and_return` is used" do expect_and_return_warning @double.should_receive(:foo).never.and_return(1) end it "warns when `expect().not_to receive().and_return` is used" do expect_and_return_warning expect(@double).not_to receive(:foo).and_return(1) end it "warns when `expect().to receive().never.and_return` is used" do expect_and_return_warning expect(@double).to receive(:foo).never.and_return(1) end it "passes when receiving message specified as not to be received with different args" do @double.should_not_receive(:message).with("unwanted text") @double.should_receive(:message).with("other text") @double.message "other text" verify @double end it "fails when receiving message specified as not to be received" do @double.should_not_receive(:not_expected) expect { @double.not_expected violated }.to raise_error( RSpec::Mocks::MockExpectationError, %Q|(Double "test double").not_expected(no args)\n expected: 0 times with any arguments\n received: 1 time| ) end it "fails when receiving message specified as not to be received with args" do @double.should_not_receive(:not_expected).with("unexpected text") expect { @double.not_expected("unexpected text") violated }.to raise_error( RSpec::Mocks::MockExpectationError, %Q|(Double "test double").not_expected("unexpected text")\n expected: 0 times with arguments: ("unexpected text")\n received: 1 time with arguments: ("unexpected text")| ) end it "fails when array arguments do not match" do @double.should_not_receive(:not_expected).with(["do not want"]) expect { @double.not_expected(["do not want"]) violated }.to raise_error( RSpec::Mocks::MockExpectationError, %Q|(Double "test double").not_expected(["do not want"])\n expected: 0 times with arguments: (["do not want"])\n received: 1 time with arguments: (["do not want"])| ) end it "passes when receiving message specified as not to be received with wrong args" do @double.should_not_receive(:not_expected).with("unexpected text") @double.not_expected "really unexpected text" verify @double @double.should_receive(:not_expected).with("unexpected text").never @double.not_expected "really unexpected text" verify @double end it "allows block to calculate return values" do @double.should_receive(:something).with("a","b","c").and_return { |a,b,c| c+b+a } expect(@double.something("a","b","c")).to eq "cba" verify @double end it "allows parameter as return value" do @double.should_receive(:something).with("a","b","c").and_return("booh") expect(@double.something("a","b","c")).to eq "booh" verify @double end it "returns the previously stubbed value if no return value is set" do @double.stub(:something).with("a","b","c").and_return(:stubbed_value) @double.should_receive(:something).with("a","b","c") expect(@double.something("a","b","c")).to eq :stubbed_value verify @double end it "returns nil if no return value is set and there is no previously stubbed value" do @double.should_receive(:something).with("a","b","c") expect(@double.something("a","b","c")).to be_nil verify @double end it "raises exception if args don't match when method called" do @double.should_receive(:something).with("a","b","c").and_return("booh") expect { @double.something("a","d","c") violated }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n expected: (\"a\", \"b\", \"c\")\n got: (\"a\", \"d\", \"c\")") end describe "even when a similar expectation with different arguments exist" do it "raises exception if args don't match when method called, correctly reporting the offending arguments" do @double.should_receive(:something).with("a","b","c").once @double.should_receive(:something).with("z","x","c").once expect { @double.something("a","b","c") @double.something("z","x","g") }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n expected: (\"z\", \"x\", \"c\")\n got: (\"z\", \"x\", \"g\")") end end it "raises exception if args don't match when method called even when the method is stubbed" do @double.stub(:something) @double.should_receive(:something).with("a","b","c") expect { @double.something("a","d","c") verify @double }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n expected: (\"a\", \"b\", \"c\")\n got: (\"a\", \"d\", \"c\")") end it "raises exception if args don't match when method called even when using null_object" do @double = double("test double").as_null_object @double.should_receive(:something).with("a","b","c") expect { @double.something("a","d","c") verify @double }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n expected: (\"a\", \"b\", \"c\")\n got: (\"a\", \"d\", \"c\")") end describe 'with a method that has a default argument' do it "raises an exception if the arguments don't match when the method is called, correctly reporting the offending arguments" do def @double.method_with_default_argument(arg={}); end @double.should_receive(:method_with_default_argument).with({}) expect { @double.method_with_default_argument(nil) verify @double }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :method_with_default_argument with unexpected arguments\n expected: ({})\n got: (nil)") end end it "fails if unexpected method called" do expect { @double.something("a","b","c") violated }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received unexpected message :something with (\"a\", \"b\", \"c\")") end it "uses block for expectation if provided" do @double.should_receive(:something) do | a, b | expect(a).to eq "a" expect(b).to eq "b" "booh" end expect(@double.something("a", "b")).to eq "booh" verify @double end it "fails if expectation block fails" do @double.should_receive(:something) do |bool| expect(bool).to be_true end expect { @double.something false }.to raise_error(RSpec::Expectations::ExpectationNotMetError) end it "is wrappable in an array" do expect( Array(@double) ).to eq([@double]) end it "is wrappable in an array when a null object" do expect( Array(@double.as_null_object) ).to eq [@double] end it "responds to to_ary as a null object" do expect(@double.as_null_object.to_ary).to eq nil end it "responds to to_a as a null object" do if RUBY_VERSION.to_f > 1.8 expect(@double.as_null_object.to_a).to eq nil else expect(@double.as_null_object.to_a).to eq [@double] end end it "passes proc to expectation block without an argument" do @double.should_receive(:foo) { |&block| expect(block.call).to eq(:bar) } @double.foo { :bar } end context "with Ruby > 1.8.6", :unless => RUBY_VERSION.to_s == '1.8.6' do it "passes proc to expectation block without an argument" do # We eval this because Ruby 1.8.6's syntax parser barfs on { |&block| ... } # and prevents the entire spec suite from running. eval("@double.should_receive(:foo) {|&block| expect(block.call).to eq(:bar)}") @double.foo { :bar } end it "passes proc to expectation block with an argument" do eval("@double.should_receive(:foo) {|arg, &block| expect(block.call).to eq(:bar)}") @double.foo(:arg) { :bar } end it "passes proc to stub block without an argurment" do eval("@double.stub(:foo) {|&block| expect(block.call).to eq(:bar)}") @double.foo { :bar } end it "passes proc to stub block with an argument" do eval("@double.stub(:foo) {|arg, &block| expect(block.call).to eq(:bar)}") @double.foo(:arg) { :bar } end end it "fails right away when method defined as never is received" do @double.should_receive(:not_expected).never expect { @double.not_expected }. to raise_error(RSpec::Mocks::MockExpectationError, %Q|(Double "test double").not_expected(no args)\n expected: 0 times with any arguments\n received: 1 time| ) end it "raises RuntimeError by default" do @double.should_receive(:something).and_raise expect { @double.something }.to raise_error(RuntimeError) end it "raises RuntimeError with a message by default" do @double.should_receive(:something).and_raise("error message") expect { @double.something }.to raise_error(RuntimeError, "error message") end it "raises an exception of a given type without an error message" do @double.should_receive(:something).and_raise(StandardError) expect { @double.something }.to raise_error(StandardError) end it "raises an exception of a given type with a message" do @double.should_receive(:something).and_raise(RuntimeError, "error message") expect { @double.something }.to raise_error(RuntimeError, "error message") end it "raises a given instance of an exception" do @double.should_receive(:something).and_raise(RuntimeError.new("error message")) expect { @double.something }.to raise_error(RuntimeError, "error message") end class OutOfGas < StandardError attr_reader :amount, :units def initialize(amount, units) @amount = amount @units = units end end it "raises a given instance of an exception with arguments other than the standard 'message'" do @double.should_receive(:something).and_raise(OutOfGas.new(2, :oz)) begin @double.something fail "OutOfGas was not raised" rescue OutOfGas => e expect(e.amount).to eq 2 expect(e.units).to eq :oz end end it "does not raise when told to if args dont match" do @double.should_receive(:something).with(2).and_raise(RuntimeError) expect { @double.something 1 }.to raise_error(RSpec::Mocks::MockExpectationError) end it "throws when told to" do @double.should_receive(:something).and_throw(:blech) expect { @double.something }.to throw_symbol(:blech) end it "ignores args on any args" do @double.should_receive(:something).at_least(:once).with(any_args) @double.something @double.something 1 @double.something "a", 2 @double.something [], {}, "joe", 7 verify @double end it "fails on no args if any args received" do @double.should_receive(:something).with(no_args()) expect { @double.something 1 }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n expected: (no args)\n got: (1)") end it "fails when args are expected but none are received" do @double.should_receive(:something).with(1) expect { @double.something }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n expected: (1)\n got: (no args)") end it "returns value from block by default" do @double.stub(:method_that_yields).and_yield value = @double.method_that_yields { :returned_obj } expect(value).to eq :returned_obj verify @double end it "yields 0 args to blocks that take a variable number of arguments" do @double.should_receive(:yield_back).with(no_args()).once.and_yield a = nil @double.yield_back {|*x| a = x} expect(a).to eq [] verify @double end it "yields 0 args multiple times to blocks that take a variable number of arguments" do @double.should_receive(:yield_back).once.with(no_args()).once.and_yield. and_yield b = [] @double.yield_back {|*a| b << a} expect(b).to eq [ [], [] ] verify @double end it "yields one arg to blocks that take a variable number of arguments" do @double.should_receive(:yield_back).with(no_args()).once.and_yield(99) a = nil @double.yield_back {|*x| a = x} expect(a).to eq [99] verify @double end it "yields one arg 3 times consecutively to blocks that take a variable number of arguments" do @double.should_receive(:yield_back).once.with(no_args()).once.and_yield(99). and_yield(43). and_yield("something fruity") b = [] @double.yield_back {|*a| b << a} expect(b).to eq [[99], [43], ["something fruity"]] verify @double end it "yields many args to blocks that take a variable number of arguments" do @double.should_receive(:yield_back).with(no_args()).once.and_yield(99, 27, "go") a = nil @double.yield_back {|*x| a = x} expect(a).to eq [99, 27, "go"] verify @double end it "yields many args 3 times consecutively to blocks that take a variable number of arguments" do @double.should_receive(:yield_back).once.with(no_args()).once.and_yield(99, :green, "go"). and_yield("wait", :amber). and_yield("stop", 12, :red) b = [] @double.yield_back {|*a| b << a} expect(b).to eq [[99, :green, "go"], ["wait", :amber], ["stop", 12, :red]] verify @double end it "yields single value" do @double.should_receive(:yield_back).with(no_args()).once.and_yield(99) a = nil @double.yield_back {|x| a = x} expect(a).to eq 99 verify @double end it "yields single value 3 times consecutively" do @double.should_receive(:yield_back).once.with(no_args()).once.and_yield(99). and_yield(43). and_yield("something fruity") b = [] @double.yield_back {|a| b << a} expect(b).to eq [99, 43, "something fruity"] verify @double end it "yields two values" do @double.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup') a, b = nil @double.yield_back {|x,y| a=x; b=y} expect(a).to eq 'wha' expect(b).to eq 'zup' verify @double end it "yields two values 3 times consecutively" do @double.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup'). and_yield('not', 'down'). and_yield(14, 65) c = [] @double.yield_back {|a,b| c << [a, b]} expect(c).to eq [['wha', 'zup'], ['not', 'down'], [14, 65]] verify @double end it "fails when calling yielding method with wrong arity" do @double.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup') expect { @double.yield_back {|a|} }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" yielded |\"wha\", \"zup\"| to block with arity of 1") end it "fails when calling yielding method consecutively with wrong arity" do @double.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup'). and_yield('down'). and_yield(14, 65) expect { c = [] @double.yield_back {|a,b| c << [a, b]} }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" yielded |\"down\"| to block with arity of 2") end it "fails when calling yielding method without block" do @double.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup') expect { @double.yield_back }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" asked to yield |[\"wha\", \"zup\"]| but no block was passed") end it "is able to double send" do @double.should_receive(:send).with(any_args) @double.send 'hi' verify @double end it "is able to raise from method calling yielding double" do @double.should_receive(:yield_me).and_yield 44 expect { @double.yield_me do |x| raise "Bang" end }.to raise_error(StandardError, "Bang") verify @double end it "clears expectations after verify" do @double.should_receive(:foobar) @double.foobar verify @double expect { @double.foobar }.to raise_error(RSpec::Mocks::MockExpectationError, %q|Double "test double" received unexpected message :foobar with (no args)|) end it "restores objects to their original state on rspec_reset" do double = double("this is a double") double.should_receive(:blah) reset double verify double #should throw if reset didn't work end it "works even after method_missing starts raising NameErrors instead of NoMethodErrors" do # Object#method_missing throws either NameErrors or NoMethodErrors. # # On a fresh ruby program Object#method_missing: # * raises a NoMethodError when called directly # * raises a NameError when called indirectly # # Once Object#method_missing has been called at least once (on any object) # it starts behaving differently: # * raises a NameError when called directly # * raises a NameError when called indirectly # # There was a bug in Mock#method_missing that relied on the fact # that calling Object#method_missing directly raises a NoMethodError. # This example tests that the bug doesn't exist anymore. # Ensures that method_missing always raises NameErrors. a_method_that_doesnt_exist rescue @double.should_receive(:foobar) @double.foobar verify @double expect { @double.foobar }.to raise_error(RSpec::Mocks::MockExpectationError) end it "temporarily replaces a method stub on a double" do @double.stub(:msg).and_return(:stub_value) @double.should_receive(:msg).with(:arg).and_return(:double_value) expect(@double.msg(:arg)).to equal(:double_value) expect(@double.msg).to equal(:stub_value) expect(@double.msg).to equal(:stub_value) verify @double end it "does not require a different signature to replace a method stub" do @double.stub(:msg).and_return(:stub_value) @double.should_receive(:msg).and_return(:double_value) expect(@double.msg(:arg)).to equal(:double_value) expect(@double.msg).to equal(:stub_value) expect(@double.msg).to equal(:stub_value) verify @double end it "raises an error when a previously stubbed method has a negative expectation" do @double.stub(:msg).and_return(:stub_value) @double.should_not_receive(:msg) expect { @double.msg(:arg) }.to raise_error(RSpec::Mocks::MockExpectationError) end it "temporarily replaces a method stub on a non-double" do non_double = Object.new non_double.stub(:msg).and_return(:stub_value) non_double.should_receive(:msg).with(:arg).and_return(:double_value) expect(non_double.msg(:arg)).to equal(:double_value) expect(non_double.msg).to equal(:stub_value) expect(non_double.msg).to equal(:stub_value) verify non_double end it "returns the stubbed value when no new value specified" do @double.stub(:msg).and_return(:stub_value) @double.should_receive(:msg) expect(@double.msg).to equal(:stub_value) verify @double end it "returns the stubbed value when stubbed with args and no new value specified" do @double.stub(:msg).with(:arg).and_return(:stub_value) @double.should_receive(:msg).with(:arg) expect(@double.msg(:arg)).to equal(:stub_value) verify @double end it "does not mess with the stub's yielded values when also doubleed" do @double.stub(:yield_back).and_yield(:stub_value) @double.should_receive(:yield_back).and_yield(:double_value) @double.yield_back{|v| expect(v).to eq :double_value } @double.yield_back{|v| expect(v).to eq :stub_value } verify @double end it "can yield multiple times when told to do so" do @double.stub(:foo).and_yield(:stub_value) @double.should_receive(:foo).and_yield(:first_yield).and_yield(:second_yield) expect { |b| @double.foo(&b) }.to yield_successive_args(:first_yield, :second_yield) expect { |b| @double.foo(&b) }.to yield_with_args(:stub_value) verify @double end it "assigns stub return values" do double = RSpec::Mocks::Mock.new('name', :message => :response) expect(double.message).to eq :response end end describe "a double message receiving a block" do before(:each) do @double = double("double") @calls = 0 end def add_call @calls = @calls + 1 end it "calls the block after #should_receive" do @double.should_receive(:foo) { add_call } @double.foo expect(@calls).to eq 1 end it "calls the block after #should_receive after a similar stub" do @double.stub(:foo).and_return(:bar) @double.should_receive(:foo) { add_call } @double.foo expect(@calls).to eq 1 end it "calls the block after #once" do @double.should_receive(:foo).once { add_call } @double.foo expect(@calls).to eq 1 end it "calls the block after #twice" do @double.should_receive(:foo).twice { add_call } @double.foo @double.foo expect(@calls).to eq 2 end it "calls the block after #times" do @double.should_receive(:foo).exactly(10).times { add_call } (1..10).each { @double.foo } expect(@calls).to eq 10 end it "calls the block after #any_number_of_times" do expect(RSpec).to receive(:deprecate).with("any_number_of_times", :replacement => "stub") @double.should_receive(:foo).any_number_of_times { add_call } (1..7).each { @double.foo } expect(@calls).to eq 7 end it "calls the block after #ordered" do @double.should_receive(:foo).ordered { add_call } @double.should_receive(:bar).ordered { add_call } @double.foo @double.bar expect(@calls).to eq 2 end end describe 'string representation generated by #to_s' do it 'does not contain < because that might lead to invalid HTML in some situations' do double = double("Dog") valid_html_str = "#{double}" expect(valid_html_str).not_to include('<') end end describe "string representation generated by #to_str" do it "looks the same as #to_s" do double = double("Foo") expect(double.to_str).to eq double.to_s end end describe "double created with no name" do it "does not use a name in a failure message" do double = double() expect {double.foo}.to raise_error(/Double received/) end it "does respond to initially stubbed methods" do double = double(:foo => "woo", :bar => "car") expect(double.foo).to eq "woo" expect(double.bar).to eq "car" end end describe "==" do it "sends '== self' to the comparison object" do first = double('first') second = double('second') first.should_receive(:==).with(second) second == first end end describe "with" do before { @double = double('double') } context "with args" do context "with matching args" do it "passes" do @double.should_receive(:foo).with('bar') @double.foo('bar') end end context "with non-matching args" do it "fails" do @double.should_receive(:foo).with('bar') expect do @double.foo('baz') end.to raise_error reset @double end end context "with non-matching doubles" do it "fails" do d1 = double('1') d2 = double('2') @double.should_receive(:foo).with(d1) expect do @double.foo(d2) end.to raise_error reset @double end end context "with non-matching doubles as_null_object" do it "fails" do d1 = double('1').as_null_object d2 = double('2').as_null_object @double.should_receive(:foo).with(d1) expect do @double.foo(d2) end.to raise_error reset @double end end end context "with a block" do context "with matching args" do it "returns the result of the block" do @double.should_receive(:foo).with('bar') { 'baz' } expect(@double.foo('bar')).to eq('baz') end end context "with non-matching args" do it "fails" do @double.should_receive(:foo).with('bar') { 'baz' } expect do expect(@double.foo('wrong')).to eq('baz') end.to raise_error(/received :foo with unexpected arguments/) reset @double end end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/serialization_spec.rb0000644000004100000410000000472012202216237023455 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "Serialization of mocked objects" do class SerializableObject < Struct.new(:foo, :bar); end def self.with_yaml_loaded(&block) context 'with YAML loaded' do module_eval(&block) end end def self.without_yaml_loaded(&block) context 'without YAML loaded' do before do # We can't really unload yaml, but we can fake it here... hide_const("YAML") Struct.class_eval do alias __old_to_yaml to_yaml undef to_yaml end end module_eval(&block) after do Struct.class_eval do alias to_yaml __old_to_yaml undef __old_to_yaml end end end end let(:serializable_object) { RSpec::Mocks::SerializableObject.new(7, "something") } def set_stub serializable_object.stub(:bazz => 5) end shared_examples_for 'normal YAML serialization' do it 'serializes to yaml the same with and without stubbing, using #to_yaml' do expect { set_stub }.to_not change { serializable_object.to_yaml } end it 'serializes to yaml the same with and without stubbing, using YAML.dump' do expect { set_stub }.to_not change { ::YAML.dump(serializable_object) } end end with_yaml_loaded do compiled_with_psych = begin require 'psych' true rescue LoadError false end if compiled_with_psych context 'using Syck as the YAML engine' do before(:each) { ::YAML::ENGINE.yamler = 'syck' } it_behaves_like 'normal YAML serialization' end context 'using Psych as the YAML engine' do before(:each) { ::YAML::ENGINE.yamler = 'psych' } it_behaves_like 'normal YAML serialization' end else it_behaves_like 'normal YAML serialization' end end without_yaml_loaded do it 'does not add #to_yaml to the stubbed object' do expect(serializable_object).not_to respond_to(:to_yaml) set_stub expect(serializable_object).not_to respond_to(:to_yaml) end end it 'marshals the same with and without stubbing' do expect { set_stub }.to_not change { Marshal.dump(serializable_object) } end end end end rspec-mocks-2.14.3/spec/rspec/mocks/hash_including_matcher_spec.rb0000644000004100000410000000604012202216237025257 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks module ArgumentMatchers describe HashIncludingMatcher do it "describes itself properly" do expect(HashIncludingMatcher.new(:a => 1).description).to eq "hash_including(:a=>1)" end describe "passing" do it "matches the same hash" do expect(hash_including(:a => 1)).to eq({:a => 1}) end it "matches a hash with extra stuff" do expect(hash_including(:a => 1)).to eq({:a => 1, :b => 2}) end describe "when matching against other matchers" do it "matches an int against anything()" do expect(hash_including(:a => anything, :b => 2)).to eq({:a => 1, :b => 2}) end it "matches a string against anything()" do expect(hash_including(:a => anything, :b => 2)).to eq({:a => "1", :b => 2}) end end describe "when passed only keys or keys mixed with key/value pairs" do it "matches if the key is present" do expect(hash_including(:a)).to eq({:a => 1, :b => 2}) end it "matches if more keys are present" do expect(hash_including(:a, :b)).to eq({:a => 1, :b => 2, :c => 3}) end it "matches a string against a given key" do expect(hash_including(:a)).to eq({:a => "1", :b => 2}) end it "matches if passed one key and one key/value pair" do expect(hash_including(:a, :b => 2)).to eq({:a => 1, :b => 2}) end it "matches if passed many keys and one key/value pair" do expect(hash_including(:a, :b, :c => 3)).to eq({:a => 1, :b => 2, :c => 3, :d => 4}) end it "matches if passed many keys and many key/value pairs" do expect(hash_including(:a, :b, :c => 3, :e => 5)).to eq({:a => 1, :b => 2, :c => 3, :d => 4, :e => 5}) end end end describe "failing" do it "does not match a non-hash" do expect(hash_including(:a => 1)).not_to eq 1 end it "does not match a hash with a missing key" do expect(hash_including(:a => 1)).not_to eq(:b => 2) end it "does not match a hash with a missing key" do expect(hash_including(:a)).not_to eq(:b => 2) end it "does not match an empty hash with a given key" do expect(hash_including(:a)).not_to eq({}) end it "does not match a hash with a missing key when one pair is matching" do expect(hash_including(:a, :b => 2)).not_to eq(:b => 2) end it "does not match a hash with an incorrect value" do expect(hash_including(:a => 1, :b => 2)).not_to eq(:a => 1, :b => 3) end it "does not match when values are nil but keys are different" do expect(hash_including(:a => nil)).not_to eq(:b => nil) end end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/double_spec.rb0000644000004100000410000000116612202216237022053 0ustar www-datawww-datarequire "spec_helper" describe "double" do it "is an alias for stub and mock" do expect(double()).to be_a(RSpec::Mocks::Mock) end it "uses 'Double' in failure messages" do double = double('name') expect {double.foo}.to raise_error(/Double "name" received/) end describe "deprecated aliases" do it "warns if #stub is used" do expect(RSpec).to receive(:deprecate).with("stub", :replacement => "double") stub("TestDouble") end it "warns if #mock is used" do expect(RSpec).to receive(:deprecate).with("mock", :replacement => "double") mock("TestDouble") end end end rspec-mocks-2.14.3/spec/rspec/mocks/stub_implementation_spec.rb0000644000004100000410000000426712202216237024670 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "stub implementation" do describe "with no args" do it "execs the block when called" do obj = double() obj.stub(:foo) { :bar } expect(obj.foo).to eq :bar end end describe "with one arg" do it "execs the block with that arg when called" do obj = double() obj.stub(:foo) {|given| given} expect(obj.foo(:bar)).to eq :bar end end describe "with variable args" do it "execs the block when called" do obj = double() obj.stub(:foo) {|*given| given.first} expect(obj.foo(:bar)).to eq :bar end end end describe "unstub implementation" do it "replaces the stubbed method with the original method" do obj = Object.new def obj.foo; :original; end obj.stub(:foo) obj.unstub(:foo) expect(obj.foo).to eq :original end it "removes all stubs with the supplied method name" do obj = Object.new def obj.foo; :original; end obj.stub(:foo).with(1) obj.stub(:foo).with(2) obj.unstub(:foo) expect(obj.foo).to eq :original end it "does not remove any expectations with the same method name" do obj = Object.new def obj.foo; :original; end obj.should_receive(:foo).with(3).and_return(:three) obj.stub(:foo).with(1) obj.stub(:foo).with(2) obj.unstub(:foo) expect(obj.foo(3)).to eq :three end it "restores the correct implementations when stubbed and unstubbed on a parent and child class" do parent = Class.new child = Class.new(parent) parent.stub(:new) child.stub(:new) parent.unstub(:new) child.unstub(:new) expect(parent.new).to be_an_instance_of parent expect(child.new).to be_an_instance_of child end it "raises a MockExpectationError if the method has not been stubbed" do obj = Object.new expect { obj.unstub(:foo) }.to raise_error(RSpec::Mocks::MockExpectationError) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/null_object_mock_spec.rb0000644000004100000410000000732312202216237024113 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "a double _not_ acting as a null object" do before(:each) do @double = double('non-null object') end it "says it does not respond to messages it doesn't understand" do expect(@double).not_to respond_to(:foo) end it "says it responds to messages it does understand" do @double.stub(:foo) expect(@double).to respond_to(:foo) end it "raises an error when interpolated in a string as an integer" do # Not sure why, but 1.9.2 (but not JRuby --1.9) raises a different # error than 1.8.7 and 1.9.3... expected_error = (RUBY_VERSION == '1.9.2' && RUBY_PLATFORM !~ /java/) ? RSpec::Mocks::MockExpectationError : TypeError expect { "%i" % @double }.to raise_error(expected_error) end end describe "a double acting as a null object" do before(:each) do @double = double('null object').as_null_object end it "says it responds to everything" do expect(@double).to respond_to(:any_message_it_gets) end it "allows explicit stubs" do @double.stub(:foo) { "bar" } expect(@double.foo).to eq("bar") end it "allows explicit expectation" do @double.should_receive(:something) @double.something end it 'continues to return self from an explicit expectation' do @double.should_receive(:bar) expect(@double.foo.bar).to be(@double) end it 'returns an explicitly stubbed value from an expectation with no implementation' do @double.stub(:foo => "bar") @double.should_receive(:foo) expect(@double.foo).to eq("bar") end it "fails verification when explicit exception not met" do expect { @double.should_receive(:something) verify @double }.to raise_error(RSpec::Mocks::MockExpectationError) end it "ignores unexpected methods" do @double.random_call("a", "d", "c") verify @double end it "allows expected message with different args first" do @double.should_receive(:message).with(:expected_arg) @double.message(:unexpected_arg) @double.message(:expected_arg) end it "allows expected message with different args second" do @double.should_receive(:message).with(:expected_arg) @double.message(:expected_arg) @double.message(:unexpected_arg) end it "can be interpolated in a string as an integer" do # This form of string interpolation calls # @double.to_int.to_int.to_int...etc until it gets an integer, # and thus gets stuck in an infinite loop unless our double # returns an int value from #to_int. expect(("%i" % @double)).to eq("0") end it "preserves its nullness to subsequent examples to " + "maintain compatibility with <= 2.13" do RSpec::Mocks.teardown expect(@double).to be_null_object expect { @double.some.long.message.chain }.not_to raise_error end end describe "#as_null_object" do it "sets the object to null_object" do obj = double('anything').as_null_object expect(obj).to be_null_object end end describe "#null_object?" do it "defaults to false" do obj = double('anything') expect(obj).not_to be_null_object end end describe "when using the :expect syntax" do include_context "with syntax", :expect it 'still supports null object doubles' do obj = double("foo").as_null_object expect(obj.foo.bar.bazz).to be(obj) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_830_spec.rb0000644000004100000410000000064212202216237023341 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe 'Calling a method that catches StandardError' do class Foo def self.foo bar rescue StandardError end end it 'still reports mock failures' do Foo.should_not_receive :bar expect { Foo.foo }.to raise_error(RSpec::Mocks::MockExpectationError) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/precise_counts_spec.rb0000644000004100000410000000415312202216237023625 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "PreciseCounts" do before(:each) do @double = double("test double") end it "fails when exactly n times method is called less than n times" do @double.should_receive(:do_something).exactly(3).times @double.do_something @double.do_something expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails fast when exactly n times method is called more than n times" do @double.should_receive(:do_something).exactly(3).times @double.do_something @double.do_something @double.do_something expect { @double.do_something }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails when exactly n times method is never called" do @double.should_receive(:do_something).exactly(3).times expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError) end it "passes if exactly n times method is called exactly n times" do @double.should_receive(:do_something).exactly(3).times @double.do_something @double.do_something @double.do_something verify @double end it "returns the value given by a block when the exactly once method is called" do @double.should_receive(:to_s).exactly(:once) { "testing" } expect(@double.to_s).to eq "testing" verify @double end it "passes mutiple calls with different args" do @double.should_receive(:do_something).once.with(1) @double.should_receive(:do_something).once.with(2) @double.do_something(1) @double.do_something(2) verify @double end it "passes multiple calls with different args and counts" do @double.should_receive(:do_something).twice.with(1) @double.should_receive(:do_something).once.with(2) @double.do_something(1) @double.do_something(2) @double.do_something(1) verify @double end end end end rspec-mocks-2.14.3/spec/rspec/mocks/argument_expectation_spec.rb0000644000004100000410000000215212202216237025022 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe ArgumentListMatcher do let(:argument_expectation) { RSpec::Mocks::ArgumentListMatcher.new } let(:obj) { double("matcher") } it "considers an object that responds to #matches? and #failure_message_for_should to be a matcher" do obj.stub(:matches?) obj.stub(:failure_message_for_should) expect(argument_expectation.send(:is_matcher?, obj)).to be_true end it "considers an object that responds to #matches? and #failure_message to be a matcher for backward compatibility" do obj.stub(:matches?) obj.stub(:failure_message) expect(argument_expectation.send(:is_matcher?, obj)).to be_true end it "does NOT consider an object that only responds to #matches? to be a matcher" do obj.stub(:matches?) expect(argument_expectation.send(:is_matcher?, obj)).to be_false end it "does not consider a null object to be a matcher" do obj.as_null_object expect(argument_expectation.send(:is_matcher?, obj)).to be_false end end end end rspec-mocks-2.14.3/spec/rspec/mocks/mock_ordering_spec.rb0000644000004100000410000000625412202216237023426 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "ordering" do before { @double = double("test double") } after { reset @double } it "passes when messages are received in order" do @double.should_receive(:one).ordered @double.should_receive(:two).ordered @double.should_receive(:three).ordered @double.one @double.two @double.three end it "passes when messages are received in order across objects" do a = double("a") b = double("b") a.should_receive(:one).ordered b.should_receive(:two).ordered a.should_receive(:three).ordered a.one b.two a.three end it "fails when messages are received out of order (2nd message 1st)" do @double.should_receive(:one).ordered @double.should_receive(:two).ordered expect { @double.two }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :two out of order") end it "fails when messages are received out of order (3rd message 1st)" do @double.should_receive(:one).ordered @double.should_receive(:two).ordered @double.should_receive(:three).ordered @double.one expect { @double.three }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :three out of order") end it "fails when messages are received out of order (3rd message 2nd)" do @double.should_receive(:one).ordered @double.should_receive(:two).ordered @double.should_receive(:three).ordered @double.one expect { @double.three }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :three out of order") end it "fails when messages are out of order across objects" do a = double("test double") b = double("another test double") a.should_receive(:one).ordered b.should_receive(:two).ordered a.should_receive(:three).ordered a.one expect { a.three }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :three out of order") reset a reset b end it "ignores order of non ordered messages" do @double.should_receive(:ignored_0) @double.should_receive(:ordered_1).ordered @double.should_receive(:ignored_1) @double.should_receive(:ordered_2).ordered @double.should_receive(:ignored_2) @double.should_receive(:ignored_3) @double.should_receive(:ordered_3).ordered @double.should_receive(:ignored_4) @double.ignored_3 @double.ordered_1 @double.ignored_0 @double.ordered_2 @double.ignored_4 @double.ignored_2 @double.ordered_3 @double.ignored_1 verify @double end it "supports duplicate messages" do @double.should_receive(:a).ordered @double.should_receive(:b).ordered @double.should_receive(:a).ordered @double.a @double.b @double.a end end end end rspec-mocks-2.14.3/spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb0000644000004100000410000000436512202216237027414 0ustar www-datawww-datarequire "spec_helper" module RSpec module Mocks describe ".allow_message" do let(:subject) { Object.new } it "sets up basic message allowance" do expect { ::RSpec::Mocks.allow_message(subject, :basic) }.to change { subject.respond_to?(:basic) }.to(true) expect(subject.basic).to eq(nil) end it "sets up message allowance with params and return value" do expect { ::RSpec::Mocks.allow_message(subject, :x).with(:in).and_return(:out) }.to change { subject.respond_to?(:x) }.to(true) expect(subject.x(:in)).to eq(:out) end it "supports block implementations" do ::RSpec::Mocks.allow_message(subject, :message) { :value } expect(subject.message).to eq(:value) end it "does not set an expectation that the message will be received" do ::RSpec::Mocks.allow_message(subject, :message) expect { verify subject }.not_to raise_error end end describe ".expect_message" do let(:subject) { Object.new } it "sets up basic message expectation, verifies as uncalled" do expect { ::RSpec::Mocks.expect_message(subject, :basic) }.to change { subject.respond_to?(:basic) }.to(true) expect { verify subject }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails if never is specified and the message is called" do expect { ::RSpec::Mocks.expect_message(subject, :foo).never subject.foo }.to raise_error(/expected.*0 times/) end it "sets up basic message expectation, verifies as called" do ::RSpec::Mocks.expect_message(subject, :basic) subject.basic verify subject end it "sets up message expectation with params and return value" do ::RSpec::Mocks.expect_message(subject, :msg).with(:in).and_return(:out) expect(subject.msg(:in)).to eq(:out) verify subject end it "accepts a block implementation for the expected message" do ::RSpec::Mocks.expect_message(subject, :msg) { :value } expect(subject.msg).to eq(:value) verify subject end end end end rspec-mocks-2.14.3/spec/rspec/mocks/stub_chain_spec.rb0000644000004100000410000001301112202216237022710 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "A chained method stub" do let(:object) { Object.new } context "with one method in chain" do context "using and_return" do it "returns expected value from chaining only one method call" do object.stub_chain(:msg1).and_return(:return_value) expect(object.msg1).to equal(:return_value) end end context "using a block" do it "returns the correct value" do object.stub_chain(:msg1) { :return_value } expect(object.msg1).to equal(:return_value) end end context "using a hash" do it "returns the value of the key/value pair" do object.stub_chain(:msg1 => :return_value) expect(object.msg1).to equal(:return_value) end end end context "with two methods in chain" do context "using and_return" do it "returns expected value from chaining two method calls" do object.stub_chain(:msg1, :msg2).and_return(:return_value) expect(object.msg1.msg2).to equal(:return_value) end end context "using a block" do it "returns the correct value" do object.stub_chain(:msg1, :msg2) { :return_value } expect(object.msg1.msg2).to equal(:return_value) end end context "using a hash" do it "returns the value of the key/value pair" do object.stub_chain(:msg1, :msg2 => :return_value) expect(object.msg1.msg2).to equal(:return_value) end end end context "with four methods in chain" do context "using and_return" do it "returns expected value from chaining two method calls" do object.stub_chain(:msg1, :msg2, :msg3, :msg4).and_return(:return_value) expect(object.msg1.msg2.msg3.msg4).to equal(:return_value) end end context "using a block" do it "returns the correct value" do object.stub_chain(:msg1, :msg2, :msg3, :msg4) { :return_value } expect(object.msg1.msg2.msg3.msg4).to equal(:return_value) end end context "using a hash" do it "returns the value of the key/value pair" do object.stub_chain(:msg1, :msg2, :msg3, :msg4 => :return_value) expect(object.msg1.msg2.msg3.msg4).to equal(:return_value) end end context "using a hash with a string key" do it "returns the value of the key/value pair" do object.stub_chain("msg1.msg2.msg3.msg4" => :return_value) expect(object.msg1.msg2.msg3.msg4).to equal(:return_value) end end end it "returns expected value from chaining four method calls" do object.stub_chain(:msg1, :msg2, :msg3, :msg4).and_return(:return_value) expect(object.msg1.msg2.msg3.msg4).to equal(:return_value) end context "with messages shared across multiple chains" do context "using and_return" do context "starting with the same message" do it "returns expected value" do object.stub_chain(:msg1, :msg2, :msg3).and_return(:first) object.stub_chain(:msg1, :msg2, :msg4).and_return(:second) expect(object.msg1.msg2.msg3).to equal(:first) expect(object.msg1.msg2.msg4).to equal(:second) end end context "starting with the different messages" do it "returns expected value" do object.stub_chain(:msg1, :msg2, :msg3).and_return(:first) object.stub_chain(:msg4, :msg2, :msg3).and_return(:second) expect(object.msg1.msg2.msg3).to equal(:first) expect(object.msg4.msg2.msg3).to equal(:second) end end end context "using => value" do context "starting with the same message" do it "returns expected value" do object.stub_chain(:msg1, :msg2, :msg3 => :first) object.stub_chain(:msg1, :msg2, :msg4 => :second) expect(object.msg1.msg2.msg3).to equal(:first) expect(object.msg1.msg2.msg4).to equal(:second) end end context "starting with different messages" do it "returns expected value" do object.stub_chain(:msg1, :msg2, :msg3 => :first) object.stub_chain(:msg4, :msg2, :msg3 => :second) expect(object.msg1.msg2.msg3).to equal(:first) expect(object.msg4.msg2.msg3).to equal(:second) end end end end it "returns expected value when chain is a dot separated string, like stub_chain('msg1.msg2.msg3')" do object.stub_chain("msg1.msg2.msg3").and_return(:return_value) expect(object.msg1.msg2.msg3).to equal(:return_value) end it "returns expected value from two chains with shared messages at the beginning" do object.stub_chain(:msg1, :msg2, :msg3, :msg4).and_return(:first) object.stub_chain(:msg1, :msg2, :msg3, :msg5).and_return(:second) expect(object.msg1.msg2.msg3.msg4).to equal(:first) expect(object.msg1.msg2.msg3.msg5).to equal(:second) end it "handles private instance methods (like Object#select) in the middle of a chain" do object.stub_chain(:msg1, :select, :msg3 => 'answer') expect(object.msg1.select.msg3).to eq 'answer' end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_11545_spec.rb0000644000004100000410000000127112202216237023505 0ustar www-datawww-datarequire 'spec_helper' class LiarLiarPantsOnFire def respond_to?(message, incl_private=false) true end def self.respond_to?(message, incl_private=false) true end end describe 'should_receive' do before(:each) do @liar = LiarLiarPantsOnFire.new end it "works when object lies about responding to a method" do @liar.should_receive(:something) @liar.something end it 'works when class lies about responding to a method' do LiarLiarPantsOnFire.should_receive(:something) LiarLiarPantsOnFire.something end it 'cleans up after itself' do expect((class << LiarLiarPantsOnFire; self; end).instance_methods).not_to include("something") end end rspec-mocks-2.14.3/spec/rspec/mocks/options_hash_spec.rb0000644000004100000410000000204112202216237023270 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "calling :should_receive with an options hash" do it "reports the file and line submitted with :expected_from" do begin mock = RSpec::Mocks::Mock.new("a mock") mock.should_receive(:message, :expected_from => "/path/to/blah.ext:37") verify mock rescue Exception => e ensure expect(e.backtrace.to_s).to match(/\/path\/to\/blah.ext:37/m) end end it "uses the message supplied with :message" do expect { m = RSpec::Mocks::Mock.new("a mock") m.should_receive(:message, :message => "recebi nada") verify m }.to raise_error("recebi nada") end it "uses the message supplied with :message after a similar stub" do expect { m = RSpec::Mocks::Mock.new("a mock") m.stub(:message) m.should_receive(:message, :message => "from mock") verify m }.to raise_error("from mock") end end end end rspec-mocks-2.14.3/spec/rspec/mocks/multiple_return_value_spec.rb0000644000004100000410000001113012202216237025217 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "a double stubbed with multiple return values" do let(:a_double) { double } before do a_double.stub(:foo).and_return(:val_1, nil) end it 'can still set a message expectation with a single return value' do a_double.should_receive(:foo).once.and_return(:val_1) expect(a_double.foo).to eq(:val_1) end end describe "a message expectation with multiple return values and no specified count" do before(:each) do @double = double @return_values = [1,2,3] @double.should_receive(:do_something).and_return(@return_values[0],@return_values[1],@return_values[2]) end it "returns values in order" do expect(@double.do_something).to eq @return_values[0] expect(@double.do_something).to eq @return_values[1] expect(@double.do_something).to eq @return_values[2] verify @double end it "falls back to a previously stubbed value" do @double.stub :do_something => :stub_result expect(@double.do_something).to eq @return_values[0] expect(@double.do_something).to eq @return_values[1] expect(@double.do_something).to eq @return_values[2] expect(@double.do_something).to eq :stub_result end it "fails when there are too few calls (if there is no stub)" do @double.do_something @double.do_something expect { verify @double }.to raise_error end it "fails when there are too many calls (if there is no stub)" do @double.do_something @double.do_something @double.do_something @double.do_something expect { verify @double }.to raise_error end end describe "a message expectation with multiple return values with a specified count equal to the number of values" do before(:each) do @double = double @return_values = [1,2,3] @double.should_receive(:do_something).exactly(3).times.and_return(@return_values[0],@return_values[1],@return_values[2]) end it "returns values in order to consecutive calls" do expect(@double.do_something).to eq @return_values[0] expect(@double.do_something).to eq @return_values[1] expect(@double.do_something).to eq @return_values[2] verify @double end end describe "a message expectation with multiple return values specifying at_least less than the number of values" do before(:each) do @double = double @double.should_receive(:do_something).at_least(:twice).with(no_args).and_return(11, 22) end it "uses the last return value for subsequent calls" do expect(@double.do_something).to equal(11) expect(@double.do_something).to equal(22) expect(@double.do_something).to equal(22) verify @double end it "fails when called less than the specified number" do expect(@double.do_something).to equal(11) expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError) end context "when method is stubbed too" do before { @double.stub(:do_something).and_return :stub_result } it "uses the last value for subsequent calls" do expect(@double.do_something).to equal(11) expect(@double.do_something).to equal(22) expect(@double.do_something).to equal(22) verify @double end it "fails when called less than the specified number" do expect(@double.do_something).to equal(11) expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError) end end end describe "a message expectation with multiple return values with a specified count larger than the number of values" do before(:each) do @double = RSpec::Mocks::Mock.new("double") @double.should_receive(:do_something).exactly(3).times.and_return(11, 22) end it "uses the last return value for subsequent calls" do expect(@double.do_something).to equal(11) expect(@double.do_something).to equal(22) expect(@double.do_something).to equal(22) verify @double end it "fails when called less than the specified number" do @double.do_something @double.do_something expect { verify @double }.to raise_error end it "fails fast when called greater than the specified number" do @double.do_something @double.do_something @double.do_something expect { @double.do_something }.to raise_error end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_600_spec.rb0000644000004100000410000000103512202216237023331 0ustar www-datawww-datarequire 'spec_helper' module BugReport600 describe "stubbing a class method" do class ExampleClass def self.method_that_uses_define_method define_method "defined_method" do |attributes| load_address(address, attributes) end end end it "works" do ExampleClass.should_receive(:define_method).with("defined_method") ExampleClass.method_that_uses_define_method end it "restores the original method" do ExampleClass.method_that_uses_define_method end end end rspec-mocks-2.14.3/spec/rspec/mocks/any_instance/0000755000004100000410000000000012202216237021711 5ustar www-datawww-datarspec-mocks-2.14.3/spec/rspec/mocks/any_instance/message_chains_spec.rb0000644000004100000410000000271312202216237026224 0ustar www-datawww-datarequire 'spec_helper' describe RSpec::Mocks::AnyInstance::MessageChains do let(:chains) { RSpec::Mocks::AnyInstance::MessageChains.new } let(:stub_chain) { RSpec::Mocks::AnyInstance::StubChain.new } let(:expectation_chain) { RSpec::Mocks::AnyInstance::PositiveExpectationChain.new } it "knows if a method does not have an expectation set on it" do chains.add(:method_name, stub_chain) expect(chains.has_expectation?(:method_name)).to be_false end it "knows if a method has an expectation set on it" do chains.add(:method_name, stub_chain) chains.add(:method_name, expectation_chain) expect(chains.has_expectation?(:method_name)).to be_true end it "can remove all stub chains" do chains.add(:method_name, stub_chain) chains.add(:method_name, expectation_chain) chains.add(:method_name, RSpec::Mocks::AnyInstance::StubChain.new) chains.remove_stub_chains_for!(:method_name) expect(chains[:method_name]).to eq([expectation_chain]) end context "creating stub chains" do it "understands how to add a stub chain for a method" do chains.add(:method_name, stub_chain) expect(chains[:method_name]).to eq([stub_chain]) end it "allows multiple stub chains for a method" do chains.add(:method_name, stub_chain) chains.add(:method_name, another_stub_chain = RSpec::Mocks::AnyInstance::StubChain.new) expect(chains[:method_name]).to eq([stub_chain, another_stub_chain]) end end end rspec-mocks-2.14.3/spec/rspec/mocks/and_yield_spec.rb0000644000004100000410000000767312202216237022542 0ustar www-datawww-datarequire 'spec_helper' describe RSpec::Mocks::Mock do let(:obj) { double } describe "#and_yield" do context 'when the method double has been constrained by `with`' do it 'uses the default stub if the provided args do not match' do obj.stub(:foo) { 15 } obj.stub(:foo).with(:yield).and_yield # should_receive is required to trigger the bug: # https://github.com/rspec/rspec-mocks/issues/127 obj.should_receive(:foo) expect(obj.foo(:dont_yield)).to eq(15) end end context "with eval context as block argument" do it "evaluates the supplied block as it is read" do evaluated = false obj.stub(:method_that_accepts_a_block).and_yield do |eval_context| evaluated = true end expect(evaluated).to be_true end it "passes an eval context object to the supplied block" do obj.stub(:method_that_accepts_a_block).and_yield do |eval_context| expect(eval_context).not_to be_nil end end it "evaluates the block passed to the stubbed method in the context of the supplied eval context" do expected_eval_context = nil actual_eval_context = nil obj.stub(:method_that_accepts_a_block).and_yield do |eval_context| expected_eval_context = eval_context end obj.method_that_accepts_a_block do actual_eval_context = self end expect(actual_eval_context).to equal(expected_eval_context) end context "and no yielded arguments" do it "passes when expectations set on the eval context are met" do configured_eval_context = nil obj.stub(:method_that_accepts_a_block).and_yield do |eval_context| configured_eval_context = eval_context configured_eval_context.should_receive(:foo) end obj.method_that_accepts_a_block do foo end verify configured_eval_context end it "fails when expectations set on the eval context are not met" do configured_eval_context = nil obj.stub(:method_that_accepts_a_block).and_yield do |eval_context| configured_eval_context = eval_context configured_eval_context.should_receive(:foo) end obj.method_that_accepts_a_block do # foo is not called here end expect { verify configured_eval_context }.to raise_error(RSpec::Mocks::MockExpectationError) end end context "and yielded arguments" do it "passes when expectations set on the eval context and yielded arguments are met" do configured_eval_context = nil yielded_arg = Object.new obj.stub(:method_that_accepts_a_block).and_yield(yielded_arg) do |eval_context| configured_eval_context = eval_context configured_eval_context.should_receive(:foo) yielded_arg.should_receive(:bar) end obj.method_that_accepts_a_block do |obj| obj.bar foo end verify configured_eval_context verify yielded_arg end it "fails when expectations set on the eval context and yielded arguments are not met" do configured_eval_context = nil yielded_arg = Object.new obj.stub(:method_that_accepts_a_block).and_yield(yielded_arg) do |eval_context| configured_eval_context = eval_context configured_eval_context.should_receive(:foo) yielded_arg.should_receive(:bar) end obj.method_that_accepts_a_block do |obj| # obj.bar is not called here # foo is not called here end expect { verify configured_eval_context }.to raise_error(RSpec::Mocks::MockExpectationError) expect { verify yielded_arg }.to raise_error(RSpec::Mocks::MockExpectationError) end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/to_ary_spec.rb0000644000004100000410000000234712202216237022100 0ustar www-datawww-datarequire "spec_helper" describe "a double receiving to_ary" do shared_examples "to_ary" do it "can be overridden with a stub" do obj.stub(:to_ary) { :non_nil_value } expect(obj.to_ary).to be(:non_nil_value) end it "responds when overriden" do obj.stub(:to_ary) { :non_nil_value } expect(obj).to respond_to(:to_ary) end it "supports Array#flatten" do obj = double('foo') expect([obj].flatten).to eq([obj]) end end context "double as_null_object" do let(:obj) { double('obj').as_null_object } include_examples "to_ary" it "does respond to to_ary" do expect(obj).to respond_to(:to_ary) end it "does respond to to_a" do expect(obj).to respond_to(:to_a) end it "returns nil" do expect(obj.to_ary).to eq nil end end context "double without as_null_object" do let(:obj) { double('obj') } include_examples "to_ary" it "doesn't respond to to_ary" do expect(obj).not_to respond_to(:to_ary) end it "doesn't respond to to_a", :if => ( RUBY_VERSION.to_f > 1.8 ) do expect(obj).not_to respond_to(:to_a) end it "raises " do expect { obj.to_ary }.to raise_error(NoMethodError) end end end rspec-mocks-2.14.3/spec/rspec/mocks/at_most_spec.rb0000644000004100000410000000532112202216237022244 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "at_most" do before(:each) do @double = double end it "passes when at_most(n) is called exactly n times" do @double.should_receive(:do_something).at_most(2).times @double.do_something @double.do_something verify @double end it "passes when at_most(n) is called less than n times" do @double.should_receive(:do_something).at_most(2).times @double.do_something verify @double end it "passes when at_most(n) is never called" do @double.should_receive(:do_something).at_most(2).times verify @double end it "passes when at_most(:once) is called once" do @double.should_receive(:do_something).at_most(:once) @double.do_something verify @double end it "passes when at_most(:once) is never called" do @double.should_receive(:do_something).at_most(:once) verify @double end it "passes when at_most(:twice) is called once" do @double.should_receive(:do_something).at_most(:twice) @double.do_something verify @double end it "passes when at_most(:twice) is called twice" do @double.should_receive(:do_something).at_most(:twice) @double.do_something @double.do_something verify @double end it "passes when at_most(:twice) is never called" do @double.should_receive(:do_something).at_most(:twice) verify @double end it "returns the value given by a block when at_most(:once) method is called" do @double.should_receive(:to_s).at_most(:once) { "testing" } expect(@double.to_s).to eq "testing" verify @double end it "fails fast when at_most(n) times method is called n plus 1 times" do @double.should_receive(:do_something).at_most(2).times @double.do_something @double.do_something expect { @double.do_something }.to raise_error(/expected: at most 2 times.*received: 3 times/m) end it "fails fast when at_most(:once) and is called twice" do @double.should_receive(:do_something).at_most(:once) @double.do_something expect { @double.do_something }.to raise_error(/expected: at most 1 time.*received: 2 times/m) end it "fails fast when at_most(:twice) and is called three times" do @double.should_receive(:do_something).at_most(:twice) @double.do_something @double.do_something expect { @double.do_something }.to raise_error(/expected: at most 2 times.*received: 3 times/m) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/matchers/0000755000004100000410000000000012202216237021044 5ustar www-datawww-datarspec-mocks-2.14.3/spec/rspec/mocks/matchers/have_received_spec.rb0000644000004100000410000002265712202216237025210 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe Matchers::HaveReceived do describe "expect(...).to have_received" do it 'passes when the double has received the given message' do dbl = double_with_met_expectation(:expected_method) expect(dbl).to have_received(:expected_method) end it 'passes when a null object has received the given message' do dbl = null_object_with_met_expectation(:expected_method) expect(dbl).to have_received(:expected_method) end it 'fails when the double has not received the given message' do dbl = double_with_unmet_expectation(:expected_method) expect { expect(dbl).to have_received(:expected_method) }.to raise_error(/expected: 1 time/) end it 'fails when a null object has not received the given message' do dbl = double.as_null_object expect { expect(dbl).to have_received(:expected_method) }.to raise_error(/expected: 1 time/) end it 'fails when the method has not been previously stubbed' do dbl = double expect { expect(dbl).to have_received(:expected_method) }.to raise_error(/method has not been stubbed/) end it 'fails when the method has been mocked' do dbl = double dbl.should_receive(:expected_method) dbl.expected_method expect { expect(dbl).to have_received(:expected_method) }.to raise_error(/method has been mocked instead of stubbed/) end it 'resets expectations on class methods when mocks are reset' do dbl = Object dbl.stub(:expected_method) dbl.expected_method reset dbl dbl.stub(:expected_method) expect { expect(dbl).to have_received(:expected_method) }.to raise_error(/0 times/) end context "with" do it 'passes when the given args match the args used with the message' do dbl = double_with_met_expectation(:expected_method, :expected, :args) expect(dbl).to have_received(:expected_method).with(:expected, :args) end it 'fails when the given args do not match the args used with the message' do dbl = double_with_met_expectation(:expected_method, :expected, :args) expect { expect(dbl).to have_received(:expected_method).with(:unexpected, :args) }.to raise_error(/with unexpected arguments/) end end it 'generates a useful description' do matcher = have_received(:expected_method).with(:expected_args).once expect(matcher.description).to eq 'have received expected_method(:expected_args) 1 time' end context "counts" do let(:dbl) { double(:expected_method => nil) } before do dbl.expected_method dbl.expected_method dbl.expected_method end context "exactly" do it 'passes when the message was received the given number of times' do expect(dbl).to have_received(:expected_method).exactly(3).times end it 'fails when the message was received more times' do expect { expect(dbl).to have_received(:expected_method).exactly(2).times }.to raise_error(/expected: 2 times.*received: 3 times/m) end it 'fails when the message was received fewer times' do expect { expect(dbl).to have_received(:expected_method).exactly(4).times }.to raise_error(/expected: 4 times.*received: 3 times/m) end end context 'at_least' do it 'passes when the message was received the given number of times' do expect(dbl).to have_received(:expected_method).at_least(3).times end it 'passes when the message was received more times' do expect(dbl).to have_received(:expected_method).at_least(2).times end it 'fails when the message was received fewer times' do expect { expect(dbl).to have_received(:expected_method).at_least(4).times }.to raise_error(/expected: at least 4 times.*received: 3 times/m) end end context 'at_most' do it 'passes when the message was received the given number of times' do expect(dbl).to have_received(:expected_method).at_most(3).times end it 'passes when the message was received fewer times' do expect(dbl).to have_received(:expected_method).at_most(4).times end it 'fails when the message was received more times' do expect { expect(dbl).to have_received(:expected_method).at_most(2).times }.to raise_error(/expected: at most 2 times.*received: 3 times/m) end end context 'once' do it 'passes when the message was received once' do dbl = double(:expected_method => nil) dbl.expected_method expect(dbl).to have_received(:expected_method).once end it 'fails when the message was never received' do dbl = double(:expected_method => nil) expect { expect(dbl).to have_received(:expected_method).once }.to raise_error(/expected: 1 time.*received: 0 times/m) end it 'fails when the message was received twice' do dbl = double(:expected_method => nil) dbl.expected_method dbl.expected_method expect { expect(dbl).to have_received(:expected_method).once }.to raise_error(/expected: 1 time.*received: 2 times/m) end end context 'twice' do it 'passes when the message was received twice' do dbl = double(:expected_method => nil) dbl.expected_method dbl.expected_method expect(dbl).to have_received(:expected_method).twice end it 'fails when the message was received once' do dbl = double(:expected_method => nil) dbl.expected_method expect { expect(dbl).to have_received(:expected_method).twice }.to raise_error(/expected: 2 times.*received: 1 time/m) end it 'fails when the message was received thrice' do dbl = double(:expected_method => nil) dbl.expected_method dbl.expected_method dbl.expected_method expect { expect(dbl).to have_received(:expected_method).twice }.to raise_error(/expected: 2 times.*received: 3 times/m) end end end end describe "expect(...).not_to have_received" do it 'passes when the double has not received the given message' do dbl = double_with_unmet_expectation(:expected_method) expect(dbl).not_to have_received(:expected_method) end it 'fails when the double has received the given message' do dbl = double_with_met_expectation(:expected_method) expect { expect(dbl).not_to have_received(:expected_method) }.to raise_error(/expected: 0 times.*received: 1 time/m) end it 'fails when the method has not been previously stubbed' do dbl = double expect { expect(dbl).not_to have_received(:expected_method) }.to raise_error(/method has not been stubbed/) end context "with" do it 'passes when the given args do not match the args used with the message' do dbl = double_with_met_expectation(:expected_method, :expected, :args) expect(dbl).not_to have_received(:expected_method).with(:unexpected, :args) end it 'fails when the given args match the args used with the message' do dbl = double_with_met_expectation(:expected_method, :expected, :args) expect { expect(dbl).not_to have_received(:expected_method).with(:expected, :args) }.to raise_error(/expected: 0 times.*received: 1 time/m) # TODO: better message end end %w(exactly at_least at_most times once twice).each do |constraint| it "does not allow #{constraint} to be used because it creates confusion" do dbl = double_with_unmet_expectation(:expected_method) expect { expect(dbl).not_to have_received(:expected_method).send(constraint) }.to raise_error(/can't use #{constraint} when negative/) end end end def double_with_met_expectation(method_name, *args) double = double_with_unmet_expectation(method_name) meet_expectation(double, method_name, *args) end def null_object_with_met_expectation(method_name, *args) meet_expectation(double.as_null_object, method_name, *args) end def meet_expectation(double, method_name, *args) double.send(method_name, *args) double end def double_with_unmet_expectation(method_name) double('double', method_name => true) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/matchers/receive_spec.rb0000644000004100000410000002354212202216237024033 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe Matchers::Receive do include_context "with syntax", :expect def verify_all ::RSpec::Mocks.space.verify_all end shared_examples_for "a receive matcher" do |*options| it 'allows the caller to configure how the subject responds' do wrapped.to receive(:foo).and_return(5) expect(receiver.foo).to eq(5) end it 'allows the caller to constrain the received arguments' do wrapped.to receive(:foo).with(:a) receiver.foo(:a) expect { receiver.foo(:b) }.to raise_error(/received :foo with unexpected arguments/) end it 'allows a `do...end` block implementation to be provided' do wrapped.to receive(:foo) do 4 end expect(receiver.foo).to eq(4) end it 'allows a `{ ... }` block implementation to be provided' do wrapped.to receive(:foo) { 5 } expect(receiver.foo).to eq(5) end it 'gives precedence to a `{ ... }` block when both forms are provided ' + 'since that form actually binds to `receive`' do wrapped.to receive(:foo) { :curly } do :do_end end expect(receiver.foo).to eq(:curly) end it 'does not support other matchers', :unless => options.include?(:allow_other_matchers) do expect { wrapped.to eq(3) }.to raise_error(UnsupportedMatcherError) end end shared_examples_for "an expect syntax allowance" do |*options| include_examples "a receive matcher", *options it 'does not expect the message to be received' do wrapped.to receive(:foo) expect { verify_all }.not_to raise_error end end shared_examples_for "an expect syntax negative allowance" do it 'is disabled since this expression is confusing' do expect { wrapped.not_to receive(:foo) }.to raise_error(/not_to receive` is not supported/) expect { wrapped.to_not receive(:foo) }.to raise_error(/to_not receive` is not supported/) end end shared_examples_for "an expect syntax expectation" do |*options| include_examples "a receive matcher", *options it 'sets up a message expectation that passes if the message is received' do wrapped.to receive(:foo) receiver.foo verify_all end it 'sets up a message expectation that fails if the message is not received' do wrapped.to receive(:foo) expect { verify_all }.to raise_error(RSpec::Mocks::MockExpectationError) end it "reports the line number of expectation of unreceived message", :pending => options.include?(:does_not_report_line_num) do expected_error_line = __LINE__; wrapped.to receive(:foo) expect { verify_all }.to raise_error { |e| expect(e.backtrace.first).to match(/#{File.basename(__FILE__)}:#{expected_error_line}/) } end end shared_examples_for "an expect syntax negative expectation" do it 'sets up a negaive message expectation that passes if the message is not received' do wrapped.not_to receive(:foo) verify_all end it 'sets up a negative message expectation that fails if the message is received' do wrapped.not_to receive(:foo) expect { receiver.foo }.to raise_error(/expected: 0 times.*received: 1 time/m) end it 'supports `to_not` as an alias for `not_to`' do wrapped.to_not receive(:foo) expect { receiver.foo }.to raise_error(/expected: 0 times.*received: 1 time/m) end it 'allows the caller to constrain the received arguments' do wrapped.not_to receive(:foo).with(:a) def receiver.method_missing(*a); end # a poor man's stub... expect { receiver.foo(:b) }.not_to raise_error expect { receiver.foo(:a) }.to raise_error(/expected: 0 times.*received: 1 time/m) end it 'prevents confusing double-negative expressions involving `never`' do expect { wrapped.not_to receive(:foo).never }.to raise_error(/trying to negate it again/) expect { wrapped.to_not receive(:foo).never }.to raise_error(/trying to negate it again/) end end describe "allow(...).to receive" do include_examples "an expect syntax allowance" do let(:receiver) { double } let(:wrapped) { allow(receiver) } end end describe "allow(...).not_to receive" do include_examples "an expect syntax negative allowance" do let(:wrapped) { allow(double) } end end describe "allow_any_instance_of(...).to receive" do include_examples "an expect syntax allowance" do let(:klass) { Class.new } let(:wrapped) { allow_any_instance_of(klass) } let(:receiver) { klass.new } end end describe "allow_any_instance_of(...).not_to receive" do include_examples "an expect syntax negative allowance" do let(:wrapped) { allow_any_instance_of(Class.new) } end end describe "expect(...).to receive" do include_examples "an expect syntax expectation", :allow_other_matchers do let(:receiver) { double } let(:wrapped) { expect(receiver) } end end describe "expect_any_instance_of(...).to receive" do include_examples "an expect syntax expectation", :does_not_report_line_num do let(:klass) { Class.new } let(:wrapped) { expect_any_instance_of(klass) } let(:receiver) { klass.new } end end describe "expect(...).not_to receive" do include_examples "an expect syntax negative expectation" do let(:receiver) { double } let(:wrapped) { expect(receiver) } end end describe "expect_any_instance_of(...).not_to receive" do include_examples "an expect syntax negative expectation" do let(:klass) { Class.new } let(:wrapped) { expect_any_instance_of(klass) } let(:receiver) { klass.new } end end shared_examples "using rspec-mocks in another test framework" do it 'can use the `expect` syntax' do dbl = double framework.new.instance_eval do expect(dbl).to receive(:foo).and_return(3) end expect(dbl.foo).to eq(3) end it 'expects the method to be called when `expect` is used' do dbl = double framework.new.instance_eval do expect(dbl).to receive(:foo) end expect { verify dbl }.to raise_error(RSpec::Mocks::MockExpectationError) end it 'supports `expect(...).not_to receive`' do dbl = double framework.new.instance_eval do expect(dbl).not_to receive(:foo) end expect { dbl.foo }.to raise_error(RSpec::Mocks::MockExpectationError) end it 'supports `expect(...).to_not receive`' do dbl = double framework.new.instance_eval do expect(dbl).to_not receive(:foo) end expect { dbl.foo }.to raise_error(RSpec::Mocks::MockExpectationError) end end context "when used in a test framework without rspec-expectations" do let(:framework) do Class.new do include RSpec::Mocks::ExampleMethods def eq(value) double("MyMatcher") end end end include_examples "using rspec-mocks in another test framework" it 'cannot use `expect` with another matcher' do expect { framework.new.instance_eval do expect(3).to eq(3) end }.to raise_error(/only the `receive` matcher is supported/) end it 'can toggle the available syntax' do expect(framework.new).to respond_to(:expect) RSpec::Mocks.configuration.syntax = :should expect(framework.new).not_to respond_to(:expect) RSpec::Mocks.configuration.syntax = :expect expect(framework.new).to respond_to(:expect) end after { RSpec::Mocks.configuration.syntax = :expect } end context "when rspec-expectations is included in the test framework first" do before do # the examples here assume `expect` is define in RSpec::Matchers... expect(RSpec::Matchers.method_defined?(:expect)).to be_true end let(:framework) do Class.new do include RSpec::Matchers include RSpec::Mocks::ExampleMethods end end include_examples "using rspec-mocks in another test framework" it 'can use `expect` with any matcher' do framework.new.instance_eval do expect(3).to eq(3) end end end context "when rspec-expectations is included in the test framework last" do before do # the examples here assume `expect` is define in RSpec::Matchers... expect(RSpec::Matchers.method_defined?(:expect)).to be_true end let(:framework) do Class.new do include RSpec::Mocks::ExampleMethods include RSpec::Matchers end end include_examples "using rspec-mocks in another test framework" it 'can use `expect` with any matcher' do framework.new.instance_eval do expect(3).to eq(3) end end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_7611_spec.rb0000644000004100000410000000042212202216237023421 0ustar www-datawww-datarequire 'spec_helper' module Bug7611 describe "A Partial Mock" do class Foo; end class Bar < Foo; end it "respects subclasses" do Foo.stub(:new).and_return(Object.new) end it "should" do expect(Bar.new.class).to eq Bar end end end rspec-mocks-2.14.3/spec/rspec/mocks/passing_argument_matchers_spec.rb0000644000004100000410000001124312202216237026032 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "Passing argument matchers" do before(:each) do @double = double('double') Kernel.stub(:warn) end after(:each) do verify @double end context "handling argument matchers" do it "accepts true as boolean()" do @double.should_receive(:random_call).with(boolean()) @double.random_call(true) end it "accepts false as boolean()" do @double.should_receive(:random_call).with(boolean()) @double.random_call(false) end it "accepts fixnum as kind_of(Numeric)" do @double.should_receive(:random_call).with(kind_of(Numeric)) @double.random_call(1) end it "accepts float as an_instance_of(Numeric)" do @double.should_receive(:random_call).with(kind_of(Numeric)) @double.random_call(1.5) end it "accepts fixnum as instance_of(Fixnum)" do @double.should_receive(:random_call).with(instance_of(Fixnum)) @double.random_call(1) end it "does NOT accept fixnum as instance_of(Numeric)" do @double.should_not_receive(:random_call).with(instance_of(Numeric)) @double.random_call(1) end it "does NOT accept float as instance_of(Numeric)" do @double.should_not_receive(:random_call).with(instance_of(Numeric)) @double.random_call(1.5) end it "accepts string as anything()" do @double.should_receive(:random_call).with("a", anything(), "c") @double.random_call("a", "whatever", "c") end it "matches duck type with one method" do @double.should_receive(:random_call).with(duck_type(:length)) @double.random_call([]) end it "matches duck type with two methods" do @double.should_receive(:random_call).with(duck_type(:abs, :div)) @double.random_call(1) end it "matches no args against any_args()" do @double.should_receive(:random_call).with(any_args) @double.random_call() end it "matches one arg against any_args()" do @double.should_receive(:random_call).with(any_args) @double.random_call("a string") end it "matches no args against no_args()" do @double.should_receive(:random_call).with(no_args) @double.random_call() end it "matches hash with hash_including same hash" do @double.should_receive(:random_call).with(hash_including(:a => 1)) @double.random_call(:a => 1) end end context "handling block matchers" do it "matches arguments against RSpec expectations" do @double.should_receive(:random_call).with {|arg1, arg2, arr, *rest| expect(arg1).to eq 5 expect(arg2).to have_at_least(3).characters expect(arg2).to have_at_most(10).characters expect(arr.map {|i| i * 2}).to eq [2,4,6] expect(rest).to eq [:fee, "fi", 4] } @double.random_call 5, "hello", [1,2,3], :fee, "fi", 4 end it "does not eval the block as the return value" do eval_count = 0 @double.should_receive(:msg).with {|a| eval_count += 1} @double.msg(:ignore) expect(eval_count).to eq(1) end end context "handling non-matcher arguments" do it "matches non special symbol (can be removed when deprecated symbols are removed)" do @double.should_receive(:random_call).with(:some_symbol) @double.random_call(:some_symbol) end it "matches string against regexp" do @double.should_receive(:random_call).with(/bcd/) @double.random_call("abcde") end it "matches regexp against regexp" do @double.should_receive(:random_call).with(/bcd/) @double.random_call(/bcd/) end it "matches against a hash submitted and received by value" do @double.should_receive(:random_call).with(:a => "a", :b => "b") @double.random_call(:a => "a", :b => "b") end it "matches against a hash submitted by reference and received by value" do opts = {:a => "a", :b => "b"} @double.should_receive(:random_call).with(opts) @double.random_call(:a => "a", :b => "b") end it "matches against a hash submitted by value and received by reference" do opts = {:a => "a", :b => "b"} @double.should_receive(:random_call).with(:a => "a", :b => "b") @double.random_call(opts) end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/record_messages_spec.rb0000644000004100000410000000155512202216237023750 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "a mock" do before(:each) do @mock = double("mock").as_null_object end it "answers false for received_message? when no messages received" do expect(@mock.received_message?(:message)).to be_false end it "answers true for received_message? when message received" do @mock.message expect(@mock.received_message?(:message)).to be_true end it "answers true for received_message? when message received with correct args" do @mock.message 1,2,3 expect(@mock.received_message?(:message, 1,2,3)).to be_true end it "answers false for received_message? when message received with incorrect args" do @mock.message 1,2,3 expect(@mock.received_message?(:message, 1,2)).to be_false end end end end rspec-mocks-2.14.3/spec/rspec/mocks/mutate_const_spec.rb0000644000004100000410000004657012202216237023316 0ustar www-datawww-datarequire 'spec_helper' TOP_LEVEL_VALUE_CONST = 7 class TestClass M = :m N = :n class Nested class NestedEvenMore end end end class TestClassThatDefinesSend C = :c def self.send end end class TestSubClass < TestClass P = :p end module RSpec module Mocks describe "Constant Mutating" do include RSpec::Mocks::RecursiveConstMethods def reset_rspec_mocks ::RSpec::Mocks.space.reset_all end shared_context "constant example methods" do |const_name| define_method :const do recursive_const_get(const_name) end define_method :parent_const do recursive_const_get("Object::" + const_name.sub(/(::)?[^:]+\z/, '')) end define_method :last_const_part do const_name.split('::').last end end shared_examples_for "loaded constant stubbing" do |const_name| include_context "constant example methods", const_name let!(:original_const_value) { const } after { change_const_value_to(original_const_value) } def change_const_value_to(value) parent_const.__send__(:remove_const, last_const_part) parent_const.const_set(last_const_part, value) end it 'allows it to be stubbed' do expect(const).not_to eq(7) stub_const(const_name, 7) expect(const).to eq(7) end it 'resets it to its original value when rspec clears its mocks' do original_value = const expect(original_value).not_to eq(:a) stub_const(const_name, :a) reset_rspec_mocks expect(const).to be(original_value) end it 'returns the stubbed value' do expect(stub_const(const_name, 7)).to eq(7) end end shared_examples_for "loaded constant hiding" do |const_name| before do expect(recursive_const_defined?(const_name)).to be_true end it 'allows it to be hidden' do hide_const(const_name) expect(recursive_const_defined?(const_name)).to be_false end it 'resets the constant when rspec clear its mocks' do hide_const(const_name) reset_rspec_mocks expect(recursive_const_defined?(const_name)).to be_true end it 'returns nil' do expect(hide_const(const_name)).to be_nil end end shared_examples_for "unloaded constant stubbing" do |const_name| include_context "constant example methods", const_name before do expect(recursive_const_defined?(const_name)).to be_false end it 'allows it to be stubbed' do stub_const(const_name, 7) expect(const).to eq(7) end it 'removes the constant when rspec clears its mocks' do stub_const(const_name, 7) reset_rspec_mocks expect(recursive_const_defined?(const_name)).to be_false end it 'returns the stubbed value' do expect(stub_const(const_name, 7)).to eq(7) end it 'ignores the :transfer_nested_constants option if passed' do stub = Module.new stub_const(const_name, stub, :transfer_nested_constants => true) expect(stub.constants).to eq([]) end end shared_examples_for "unloaded constant hiding" do |const_name| include_context "constant example methods", const_name before do expect(recursive_const_defined?(const_name)).to be_false end it 'allows it to be hidden, though the operation has no effect' do hide_const(const_name) expect(recursive_const_defined?(const_name)).to be_false end it 'remains undefined after rspec clears its mocks' do hide_const(const_name) reset_rspec_mocks expect(recursive_const_defined?(const_name)).to be_false end it 'returns nil' do expect(hide_const(const_name)).to be_nil end end describe "#hide_const" do context "for a loaded constant nested in a module that redefines `send`" do it_behaves_like "loaded constant hiding", "TestClassThatDefinesSend::C" end context 'for a loaded nested constant' do it_behaves_like "loaded constant hiding", "TestClass::Nested" end context 'for a loaded constant prefixed with ::' do it_behaves_like 'loaded constant hiding', "::TestClass" end context 'for an unloaded constant with nested name that matches a top-level constant' do it_behaves_like "unloaded constant hiding", "TestClass::Hash" it 'does not hide the top-level constant' do top_level_hash = ::Hash hide_const("TestClass::Hash") expect(::Hash).to equal(top_level_hash) end it 'does not affect the ability to access the top-level constant from nested contexts', :silence_warnings do top_level_hash = ::Hash hide_const("TestClass::Hash") expect(TestClass::Hash).to equal(top_level_hash) end end context 'for a loaded deeply nested constant' do it_behaves_like "loaded constant hiding", "TestClass::Nested::NestedEvenMore" end context 'for an unloaded unnested constant' do it_behaves_like "unloaded constant hiding", "X" end context 'for an unloaded nested constant' do it_behaves_like "unloaded constant hiding", "X::Y" end it 'can be hidden multiple times but still restores the original value properly' do orig_value = TestClass hide_const("TestClass") hide_const("TestClass") reset_rspec_mocks expect(TestClass).to be(orig_value) end it 'allows a constant to be hidden, then stubbed, restoring it to its original value properly' do orig_value = TOP_LEVEL_VALUE_CONST hide_const("TOP_LEVEL_VALUE_CONST") expect(recursive_const_defined?("TOP_LEVEL_VALUE_CONST")).to be_false stub_const("TOP_LEVEL_VALUE_CONST", 12345) expect(TOP_LEVEL_VALUE_CONST).to eq 12345 reset_rspec_mocks expect(TOP_LEVEL_VALUE_CONST).to eq orig_value end end describe "#stub_const" do context "for a loaded constant nested in a module that redefines `send`" do it_behaves_like "loaded constant stubbing", "TestClassThatDefinesSend::C" end context 'for a loaded unnested constant' do it_behaves_like "loaded constant stubbing", "TestClass" it 'can be stubbed multiple times but still restores the original value properly' do orig_value = TestClass stub1, stub2 = Module.new, Module.new stub_const("TestClass", stub1) stub_const("TestClass", stub2) reset_rspec_mocks expect(TestClass).to be(orig_value) end it 'allows nested constants to be transferred to a stub module' do tc_nested = TestClass::Nested stub = Module.new stub_const("TestClass", stub, :transfer_nested_constants => true) expect(stub::M).to eq(:m) expect(stub::N).to eq(:n) expect(stub::Nested).to be(tc_nested) end it 'does not transfer nested constants that are inherited from a superclass' do stub = Module.new stub_const("TestSubClass", stub, :transfer_nested_constants => true) expect(stub::P).to eq(:p) expect(defined?(stub::M)).to be_false expect(defined?(stub::N)).to be_false end it 'raises an error when asked to transfer a nested inherited constant' do original_tsc = TestSubClass expect { stub_const("TestSubClass", Module.new, :transfer_nested_constants => [:M]) }.to raise_error(ArgumentError) expect(TestSubClass).to be(original_tsc) end it 'allows nested constants to be selectively transferred to a stub module' do stub = Module.new stub_const("TestClass", stub, :transfer_nested_constants => [:M, :N]) expect(stub::M).to eq(:m) expect(stub::N).to eq(:n) expect(defined?(stub::Nested)).to be_false end it 'raises an error if asked to transfer nested constants but given an object that does not support them' do original_tc = TestClass stub = Object.new expect { stub_const("TestClass", stub, :transfer_nested_constants => true) }.to raise_error(ArgumentError) expect(TestClass).to be(original_tc) expect { stub_const("TestClass", stub, :transfer_nested_constants => [:M]) }.to raise_error(ArgumentError) expect(TestClass).to be(original_tc) end it 'raises an error if asked to transfer nested constants on a constant that does not support nested constants' do stub = Module.new expect { stub_const("TOP_LEVEL_VALUE_CONST", stub, :transfer_nested_constants => true) }.to raise_error(ArgumentError) expect(TOP_LEVEL_VALUE_CONST).to eq(7) expect { stub_const("TOP_LEVEL_VALUE_CONST", stub, :transfer_nested_constants => [:M]) }.to raise_error(ArgumentError) expect(TOP_LEVEL_VALUE_CONST).to eq(7) end it 'raises an error if asked to transfer a nested constant that is not defined' do original_tc = TestClass expect(defined?(TestClass::V)).to be_false stub = Module.new expect { stub_const("TestClass", stub, :transfer_nested_constants => [:V]) }.to raise_error(/cannot transfer nested constant.*V/i) expect(TestClass).to be(original_tc) end end context 'for a loaded nested constant' do it_behaves_like "loaded constant stubbing", "TestClass::Nested" end context 'for a loaded constant prefixed with ::' do it_behaves_like 'loaded constant stubbing', "::TestClass" end context 'for an unloaded constant prefixed with ::' do it_behaves_like 'unloaded constant stubbing', "::SomeUndefinedConst" end context "for an unloaded constant nested in a module that redefines `send`" do it_behaves_like 'unloaded constant stubbing', "TestClassThatDefinesSend::SomeUndefinedConst" end context 'for an unloaded constant with nested name that matches a top-level constant' do it_behaves_like "unloaded constant stubbing", "TestClass::Hash" end context 'for a loaded deeply nested constant' do it_behaves_like "loaded constant stubbing", "TestClass::Nested::NestedEvenMore" end context 'for an unloaded unnested constant' do it_behaves_like "unloaded constant stubbing", "X" end context 'for an unloaded nested constant' do it_behaves_like "unloaded constant stubbing", "X::Y" it 'removes the root constant when rspec clears its mocks' do expect(defined?(X)).to be_false stub_const("X::Y", 7) reset_rspec_mocks expect(defined?(X)).to be_false end end context 'for an unloaded deeply nested constant' do it_behaves_like "unloaded constant stubbing", "X::Y::Z" it 'removes the root constant when rspec clears its mocks' do expect(defined?(X)).to be_false stub_const("X::Y::Z", 7) reset_rspec_mocks expect(defined?(X)).to be_false end end context 'for an unloaded constant nested within a loaded constant' do it_behaves_like "unloaded constant stubbing", "TestClass::X" it 'removes the unloaded constant but leaves the loaded constant when rspec resets its mocks' do expect(defined?(TestClass)).to be_true expect(defined?(TestClass::X)).to be_false stub_const("TestClass::X", 7) reset_rspec_mocks expect(defined?(TestClass)).to be_true expect(defined?(TestClass::X)).to be_false end it 'raises a helpful error if it cannot be stubbed due to an intermediary constant that is not a module' do expect(TestClass::M).to be_a(Symbol) expect { stub_const("TestClass::M::X", 5) }.to raise_error(/cannot stub/i) end end context 'for an unloaded constant nested deeply within a deeply nested loaded constant' do it_behaves_like "unloaded constant stubbing", "TestClass::Nested::NestedEvenMore::X::Y::Z" it 'removes the first unloaded constant but leaves the loaded nested constant when rspec resets its mocks' do expect(defined?(TestClass::Nested::NestedEvenMore)).to be_true expect(defined?(TestClass::Nested::NestedEvenMore::X)).to be_false stub_const("TestClass::Nested::NestedEvenMore::X::Y::Z", 7) reset_rspec_mocks expect(defined?(TestClass::Nested::NestedEvenMore)).to be_true expect(defined?(TestClass::Nested::NestedEvenMore::X)).to be_false end end end end describe Constant do describe ".original" do context 'for a previously defined unstubbed constant' do let(:const) { Constant.original("TestClass::M") } it("exposes its name") { expect(const.name).to eq("TestClass::M") } it("indicates it was previously defined") { expect(const).to be_previously_defined } it("indicates it has not been mutated") { expect(const).not_to be_mutated } it("indicates it has not been stubbed") { expect(const).not_to be_stubbed } it("indicates it has not been hidden") { expect(const).not_to be_hidden } it("exposes its original value") { expect(const.original_value).to eq(:m) } end context 'for a previously defined stubbed constant' do before { stub_const("TestClass::M", :other) } let(:const) { Constant.original("TestClass::M") } it("exposes its name") { expect(const.name).to eq("TestClass::M") } it("indicates it was previously defined") { expect(const).to be_previously_defined } it("indicates it has been mutated") { expect(const).to be_mutated } it("indicates it has been stubbed") { expect(const).to be_stubbed } it("indicates it has not been hidden") { expect(const).not_to be_hidden } it("exposes its original value") { expect(const.original_value).to eq(:m) } end context 'for a previously undefined stubbed constant' do before { stub_const("TestClass::Undefined", :other) } let(:const) { Constant.original("TestClass::Undefined") } it("exposes its name") { expect(const.name).to eq("TestClass::Undefined") } it("indicates it was not previously defined") { expect(const).not_to be_previously_defined } it("indicates it has been mutated") { expect(const).to be_mutated } it("indicates it has been stubbed") { expect(const).to be_stubbed } it("indicates it has not been hidden") { expect(const).not_to be_hidden } it("returns nil for the original value") { expect(const.original_value).to be_nil } end context 'for a previously undefined unstubbed constant' do let(:const) { Constant.original("TestClass::Undefined") } it("exposes its name") { expect(const.name).to eq("TestClass::Undefined") } it("indicates it was not previously defined") { expect(const).not_to be_previously_defined } it("indicates it has not been mutated") { expect(const).not_to be_mutated } it("indicates it has not been stubbed") { expect(const).not_to be_stubbed } it("indicates it has not been hidden") { expect(const).not_to be_hidden } it("returns nil for the original value") { expect(const.original_value).to be_nil } end context 'for a previously defined constant that has been stubbed twice' do before { stub_const("TestClass::M", 1) } before { stub_const("TestClass::M", 2) } let(:const) { Constant.original("TestClass::M") } it("exposes its name") { expect(const.name).to eq("TestClass::M") } it("indicates it was previously defined") { expect(const).to be_previously_defined } it("indicates it has been mutated") { expect(const).to be_mutated } it("indicates it has been stubbed") { expect(const).to be_stubbed } it("indicates it has not been hidden") { expect(const).not_to be_hidden } it("exposes its original value") { expect(const.original_value).to eq(:m) } end context 'for a previously undefined constant that has been stubbed twice' do before { stub_const("TestClass::Undefined", 1) } before { stub_const("TestClass::Undefined", 2) } let(:const) { Constant.original("TestClass::Undefined") } it("exposes its name") { expect(const.name).to eq("TestClass::Undefined") } it("indicates it was not previously defined") { expect(const).not_to be_previously_defined } it("indicates it has been mutated") { expect(const).to be_mutated } it("indicates it has been stubbed") { expect(const).to be_stubbed } it("indicates it has not been hidden") { expect(const).not_to be_hidden } it("returns nil for the original value") { expect(const.original_value).to be_nil } end context 'for a previously defined hidden constant' do before { hide_const("TestClass::M") } let(:const) { Constant.original("TestClass::M") } it("exposes its name") { expect(const.name).to eq("TestClass::M") } it("indicates it was previously defined") { expect(const).to be_previously_defined } it("indicates it has been mutated") { expect(const).to be_mutated } it("indicates it has not been stubbed") { expect(const).not_to be_stubbed } it("indicates it has been hidden") { expect(const).to be_hidden } it("exposes its original value") { expect(const.original_value).to eq(:m) } end context 'for a previously defined constant that has been hidden twice' do before { hide_const("TestClass::M") } before { hide_const("TestClass::M") } let(:const) { Constant.original("TestClass::M") } it("exposes its name") { expect(const.name).to eq("TestClass::M") } it("indicates it was previously defined") { expect(const).to be_previously_defined } it("indicates it has been mutated") { expect(const).to be_mutated } it("indicates it has not been stubbed") { expect(const).not_to be_stubbed } it("indicates it has been hidden") { expect(const).to be_hidden } it("exposes its original value") { expect(const.original_value).to eq(:m) } end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_10260_spec.rb0000644000004100000410000000033412202216237023475 0ustar www-datawww-datarequire 'spec_helper' describe "An RSpec Mock" do it "hides internals in its inspect representation" do m = double('cup') expect(m.inspect).to match(/#/) end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_957_spec.rb0000644000004100000410000000104512202216237023351 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "stubbing a base class class method" do before do @base_class = Class.new @concrete_class = Class.new(@base_class) @base_class.stub(:find).and_return "stubbed_value" end it "returns the value for the stub on the base class" do expect(@base_class.find).to eq "stubbed_value" end it "returns the value for the descendent class" do expect(@concrete_class.find).to eq "stubbed_value" end end end end rspec-mocks-2.14.3/spec/rspec/mocks/mock_space_spec.rb0000644000004100000410000000614012202216237022702 0ustar www-datawww-datarequire 'spec_helper' require 'rspec/mocks' module RSpec module Mocks describe Space do let(:space) { RSpec::Mocks::Space.new } let(:dbl_1) { Object.new } let(:dbl_2) { Object.new } before do space.ensure_registered(dbl_1) space.ensure_registered(dbl_2) end it "verifies all mocks within" do verifies = [] space.proxy_for(dbl_1).stub(:verify) { verifies << :dbl_1 } space.proxy_for(dbl_2).stub(:verify) { verifies << :dbl_2 } space.verify_all expect(verifies).to match_array([:dbl_1, :dbl_2]) end def define_singleton_method_on_recorder_for(klass, name, &block) recorder = space.any_instance_recorder_for(klass) (class << recorder; self; end).send(:define_method, name, &block) end it 'verifies all any_instance recorders within' do klass_1, klass_2 = Class.new, Class.new verifies = [] # We can't `stub` a method on the recorder because it defines its own `stub`... define_singleton_method_on_recorder_for(klass_1, :verify) { verifies << :klass_1 } define_singleton_method_on_recorder_for(klass_2, :verify) { verifies << :klass_2 } space.verify_all expect(verifies).to match_array([:klass_1, :klass_2]) end it "resets all mocks within" do resets = [] space.proxy_for(dbl_1).stub(:reset) { resets << :dbl_1 } space.proxy_for(dbl_2).stub(:reset) { resets << :dbl_2 } space.reset_all expect(resets).to match_array([:dbl_1, :dbl_2]) end it "does not leak mock proxies between examples" do expect { space.reset_all }.to change { space.proxies.size }.to(0) end it 'does not leak any instance recorders between examples' do space.any_instance_recorder_for(Class.new) expect { space.reset_all }.to change { space.any_instance_recorders.size }.to(0) end it "resets the ordering" do space.expectation_ordering.register :some_expectation expect { space.reset_all }.to change { space.expectation_ordering.empty? }.from(false).to(true) end it "only adds an instance once" do m1 = double("mock1") expect { space.ensure_registered(m1) }.to change { space.proxies } expect { space.ensure_registered(m1) }.not_to change { space.proxies } end it 'returns a consistent any_instance_recorder for a given class' do klass_1, klass_2 = Class.new, Class.new r1 = space.any_instance_recorder_for(klass_1) r2 = space.any_instance_recorder_for(klass_1) r3 = space.any_instance_recorder_for(klass_2) expect(r1).to be(r2) expect(r1).not_to be(r3) end it 'removes an any_instance_recorder when requested' do klass = Class.new space.any_instance_recorder_for(klass) expect { space.remove_any_instance_recorder_for(klass) }.to change { space.any_instance_recorders.size }.by(-1) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/stash_spec.rb0000644000004100000410000000216612202216237021724 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "only stashing the original method" do let(:klass) do Class.new do def self.foo(arg) :original_value end end end it "keeps the original method intact after multiple expectations are added on the same method" do klass.should_receive(:foo).with(:fizbaz).and_return(:wowwow) klass.should_receive(:foo).with(:bazbar).and_return(:okay) klass.foo(:fizbaz) klass.foo(:bazbar) verify klass reset klass expect(klass.foo(:yeah)).to equal(:original_value) end end describe "when a class method is aliased on a subclass and the method is mocked" do it "restores the original aliased public method" do klass = Class.new do class << self alias alternate_new new end end klass.should_receive(:alternate_new) expect(klass.alternate_new).to be_nil verify klass reset klass expect(klass.alternate_new).to be_an_instance_of(klass) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/extensions/0000755000004100000410000000000012202216237021435 5ustar www-datawww-datarspec-mocks-2.14.3/spec/rspec/mocks/extensions/marshal_spec.rb0000644000004100000410000000313612202216237024426 0ustar www-datawww-datarequire 'spec_helper' describe Marshal, 'extensions' do # An object that raises when code attempts to dup it. # # Because we manipulate the internals of RSpec::Mocks.space below, we need # an object that simply blows up when #dup is called without using any # partial mocking or stubbing from rspec-mocks itself. class UndupableObject def dup raise NotImplementedError end end describe '#dump' do context 'when rspec-mocks has not been fully initialized' do def without_space stashed_space, RSpec::Mocks.space = RSpec::Mocks.space, nil yield ensure RSpec::Mocks.space = stashed_space end it 'does not duplicate the object before serialization' do obj = UndupableObject.new without_space do serialized = Marshal.dump(obj) expect(Marshal.load(serialized)).to be_an(UndupableObject) end end end context 'when rspec-mocks has been fully initialized' do it 'duplicates objects with stubbed or mocked implementations before serialization' do obj = double(:foo => "bar") serialized = Marshal.dump(obj) expect(Marshal.load(serialized)).to be_an(obj.class) end it 'does not duplicate other objects before serialization' do obj = UndupableObject.new serialized = Marshal.dump(obj) expect(Marshal.load(serialized)).to be_an(UndupableObject) end it 'does not duplicate nil before serialization' do serialized = Marshal.dump(nil) expect(Marshal.load(serialized)).to be_nil end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_8165_spec.rb0000644000004100000410000000231312202216237023427 0ustar www-datawww-datarequire 'spec_helper' describe "An object where respond_to? is true and does not have method" do # When should_receive(message) is sent to any object, the Proxy sends # respond_to?(message) to that object to see if the method should be proxied. # # If respond_to? itself is proxied, then when the Proxy sends respond_to? # to the object, the proxy is invoked and responds yes (if so set in the spec). # When the object does NOT actually respond to `message`, an exception is thrown # when trying to proxy it. # # The fix was to keep track of whether `respond_to?` had been proxied and, if # so, call the munged copy of `respond_to?` on the object. it "does not raise an exception for Object" do obj = Object.new obj.should_receive(:respond_to?).with(:foobar).and_return(true) obj.should_receive(:foobar).and_return(:baz) expect(obj.respond_to?(:foobar)).to be_true expect(obj.foobar).to eq :baz end it "does not raise an exception for mock" do obj = double("obj") obj.should_receive(:respond_to?).with(:foobar).and_return(true) obj.should_receive(:foobar).and_return(:baz) expect(obj.respond_to?(:foobar)).to be_true expect(obj.foobar).to eq :baz end end rspec-mocks-2.14.3/spec/rspec/mocks/failing_argument_matchers_spec.rb0000644000004100000410000001050312202216237025775 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "failing MockArgumentMatchers" do before(:each) do @double = double("double") @reporter = double("reporter").as_null_object end after(:each) do reset @double end it "rejects non boolean" do @double.should_receive(:random_call).with(boolean()) expect do @double.random_call("false") end.to raise_error(RSpec::Mocks::MockExpectationError) end it "rejects non numeric" do @double.should_receive(:random_call).with(an_instance_of(Numeric)) expect do @double.random_call("1") end.to raise_error(RSpec::Mocks::MockExpectationError) end it "rejects non string" do @double.should_receive(:random_call).with(an_instance_of(String)) expect do @double.random_call(123) end.to raise_error(RSpec::Mocks::MockExpectationError) end it "rejects goose when expecting a duck" do @double.should_receive(:random_call).with(duck_type(:abs, :div)) expect { @double.random_call("I don't respond to :abs or :div") }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails if regexp does not match submitted string" do @double.should_receive(:random_call).with(/bcd/) expect { @double.random_call("abc") }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails if regexp does not match submitted regexp" do @double.should_receive(:random_call).with(/bcd/) expect { @double.random_call(/bcde/) }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails for a hash w/ wrong values" do @double.should_receive(:random_call).with(:a => "b", :c => "d") expect do @double.random_call(:a => "b", :c => "e") end.to raise_error(RSpec::Mocks::MockExpectationError, /Double "double" received :random_call with unexpected arguments\n expected: \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\)\n got: \(\{(:a=>\"b\", :c=>\"e\"|:c=>\"e\", :a=>\"b\")\}\)/) end it "fails for a hash w/ wrong keys" do @double.should_receive(:random_call).with(:a => "b", :c => "d") expect do @double.random_call("a" => "b", "c" => "d") end.to raise_error(RSpec::Mocks::MockExpectationError, /Double "double" received :random_call with unexpected arguments\n expected: \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\)\n got: \(\{(\"a\"=>\"b\", \"c\"=>\"d\"|\"c\"=>\"d\", \"a\"=>\"b\")\}\)/) end it "matches against a Matcher" do expect do @double.should_receive(:msg).with(equal(3)) @double.msg(37) end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (equal 3)\n got: (37)") end it "fails no_args with one arg" do expect do @double.should_receive(:msg).with(no_args) @double.msg(37) end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (no args)\n got: (37)") end it "fails hash_including with missing key" do expect do @double.should_receive(:msg).with(hash_including(:a => 1)) @double.msg({}) end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (hash_including(:a=>1))\n got: ({})") end it "fails with block matchers" do expect do @double.should_receive(:msg).with {|arg| expect(arg).to eq :received } @double.msg :no_msg_for_you end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected: :received.*\s*.*got: :no_msg_for_you/) end it "fails with sensible message when args respond to #description" do arg = Class.new do def description end def inspect "my_thing" end end.new expect do @double.should_receive(:msg).with(3) @double.msg arg end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (3)\n got: (my_thing)") end end end end rspec-mocks-2.14.3/spec/rspec/mocks/hash_excluding_matcher_spec.rb0000644000004100000410000000421612202216237025270 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks module ArgumentMatchers describe HashExcludingMatcher do it "describes itself properly" do expect(HashExcludingMatcher.new(:a => 5).description).to eq "hash_not_including(:a=>5)" end describe "passing" do it "matches a hash without the specified key" do expect(hash_not_including(:c)).to eq({:a => 1, :b => 2}) end it "matches a hash with the specified key, but different value" do expect(hash_not_including(:b => 3)).to eq({:a => 1, :b => 2}) end it "matches a hash without the specified key, given as anything()" do expect(hash_not_including(:c => anything)).to eq({:a => 1, :b => 2}) end it "matches an empty hash" do expect(hash_not_including(:a)).to eq({}) end it "matches a hash without any of the specified keys" do expect(hash_not_including(:a, :b, :c)).to eq(:d => 7) end end describe "failing" do it "does not match a non-hash" do expect(hash_not_including(:a => 1)).not_to eq 1 end it "does not match a hash with a specified key" do expect(hash_not_including(:b)).not_to eq(:b => 2) end it "does not match a hash with the specified key/value pair" do expect(hash_not_including(:b => 2)).not_to eq(:a => 1, :b => 2) end it "does not match a hash with the specified key" do expect(hash_not_including(:a, :b => 3)).not_to eq(:a => 1, :b => 2) end it "does not match a hash with one of the specified keys" do expect(hash_not_including(:a, :b)).not_to eq(:b => 2) end it "does not match a hash with some of the specified keys" do expect(hash_not_including(:a, :b, :c)).not_to eq(:a => 1, :b => 2) end it "does not match a hash with one key/value pair included" do expect(hash_not_including(:a, :b, :c, :d => 7)).not_to eq(:d => 7) end end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/block_return_value_spec.rb0000644000004100000410000000466312202216237024473 0ustar www-datawww-datarequire "spec_helper" describe "a double declaration with a block handed to:" do describe "should_receive" do it "returns the value of executing the block" do obj = Object.new obj.should_receive(:foo) { 'bar' } expect(obj.foo).to eq('bar') end it "works when a multi-return stub has already been set" do obj = Object.new return_value = Object.new obj.stub(:foo).and_return(return_value, nil) obj.should_receive(:foo) { return_value } expect(obj.foo).to be(return_value) end end describe "stub" do it "returns the value of executing the block" do obj = Object.new obj.stub(:foo) { 'bar' } expect(obj.foo).to eq('bar') end it "does not complain if a lambda block and mismatched arguments are passed" do obj = Object.new obj.stub(:foo, &lambda { 'bar' }) expect(obj.foo(1, 2)).to eq('bar') end end describe "with" do it "returns the value of executing the block" do obj = Object.new obj.stub(:foo).with('baz') { 'bar' } expect(obj.foo('baz')).to eq('bar') end it "does not complain if a lambda block and mismatched arguments are passed" do obj = Object.new obj.stub(:foo).with(1, 2, &lambda { 'bar' }) expect(obj.foo(1, 2)).to eq('bar') end end %w[once twice ordered and_return].each do |method| describe method do it "returns the value of executing the block" do obj = Object.new obj.stub(:foo).send(method) { 'bar' } expect(obj.foo).to eq('bar') end it "does not complain if a lambda block and mismatched arguments are passed" do obj = Object.new obj.stub(:foo).send(method, &lambda { 'bar' }) expect(obj.foo(1, 2)).to eq('bar') end end end describe 'any_number_of_times' do before do RSpec.stub(:deprecate) end it "warns about deprecation" do expect(RSpec).to receive(:deprecate).with("any_number_of_times", :replacement => "stub") Object.new.stub(:foo).any_number_of_times { 'bar' } end it "returns the value of executing the block" do obj = Object.new obj.stub(:foo).any_number_of_times { 'bar' } expect(obj.foo).to eq('bar') end end describe "times" do it "returns the value of executing the block" do obj = Object.new obj.stub(:foo).at_least(1).times { 'bar' } expect(obj.foo('baz')).to eq('bar') end end end rspec-mocks-2.14.3/spec/rspec/mocks/methods_spec.rb0000644000004100000410000000151412202216237022241 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "Methods added to every object" do include_context "with syntax", :expect def added_methods host = Class.new orig_instance_methods = host.instance_methods Syntax.enable_should(host) (host.instance_methods - orig_instance_methods).map(&:to_sym) end it 'limits the number of methods that get added to all objects' do # If really necessary, you can add to this list, but long term, # we are hoping to cut down on the number of methods added to all objects expect(added_methods).to match_array([ :as_null_object, :null_object?, :received_message?, :should_not_receive, :should_receive, :stub, :stub!, :stub_chain, :unstub, :unstub! ]) end end end end rspec-mocks-2.14.3/spec/rspec/mocks/twice_counts_spec.rb0000644000004100000410000000362312202216237023307 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "#twice" do before(:each) do @double = double("test double") end it "passes when called twice" do @double.should_receive(:do_something).twice @double.do_something @double.do_something verify @double end it "passes when called twice with specified args" do @double.should_receive(:do_something).twice.with("1", 1) @double.do_something("1", 1) @double.do_something("1", 1) verify @double end it "passes when called twice with unspecified args" do @double.should_receive(:do_something).twice @double.do_something("1") @double.do_something(1) verify @double end it "fails fast when call count is higher than expected" do @double.should_receive(:do_something).twice @double.do_something @double.do_something expect { @double.do_something }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails when call count is lower than expected" do @double.should_receive(:do_something).twice @double.do_something expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError) end it "fails when called wrong args on the first call" do @double.should_receive(:do_something).twice.with("1", 1) expect { @double.do_something(1, "1") }.to raise_error(RSpec::Mocks::MockExpectationError) reset @double end it "fails when called with wrong args on the second call" do @double.should_receive(:do_something).twice.with("1", 1) @double.do_something("1", 1) expect { @double.do_something(1, "1") }.to raise_error(RSpec::Mocks::MockExpectationError) reset @double end end end end rspec-mocks-2.14.3/spec/rspec/mocks/bug_report_10263_spec.rb0000644000004100000410000000126712202216237023506 0ustar www-datawww-datarequire 'spec_helper' describe "Double" do let(:test_double) { double } specify "when one example has an expectation inside the block passed to should_receive" do test_double.should_receive(:msg) do |arg| expect(arg).to be_true #this call exposes the problem end begin test_double.msg(false) rescue Exception end end specify "then the next example should behave as expected instead of saying" do test_double.should_receive(:foobar) test_double.foobar verify test_double begin test_double.foobar rescue Exception => e expect(e.message).to eq "Double received unexpected message :foobar with (no args)" end end end rspec-mocks-2.14.3/spec/rspec/mocks/any_number_of_times_spec.rb0000644000004100000410000000212712202216237024623 0ustar www-datawww-datarequire 'spec_helper' describe "AnyNumberOfTimes" do before(:each) do @mock = RSpec::Mocks::Mock.new("test mock") allow(RSpec).to receive(:deprecate) end it "is deprecated" do expect(RSpec).to receive(:deprecate).with("any_number_of_times", :replacement => "stub") expect(@mock).to receive(:random_call).any_number_of_times end it "passes if any number of times method is called many times" do @mock.should_receive(:random_call).any_number_of_times (1..10).each do @mock.random_call end end it "passes if any number of times method is called once" do @mock.should_receive(:random_call).any_number_of_times @mock.random_call end it "passes if any number of times method is not called" do @mock.should_receive(:random_call).any_number_of_times end it "returns the mocked value when called after a similar stub" do @mock.stub(:message).and_return :stub_value @mock.should_receive(:message).any_number_of_times.and_return(:mock_value) expect(@mock.message).to eq :mock_value expect(@mock.message).to eq :mock_value end end rspec-mocks-2.14.3/spec/rspec/mocks/at_least_spec.rb0000644000004100000410000001166112202216237022376 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "at_least" do before(:each) { @double = double } it "fails if method is never called" do @double.should_receive(:do_something).at_least(4).times expect { verify @double }.to raise_error(/expected: at least 4 times.*received: 0 times/m) end it "fails when called less than n times" do @double.should_receive(:do_something).at_least(4).times @double.do_something @double.do_something @double.do_something expect { verify @double }.to raise_error(/expected: at least 4 times.*received: 3 times/m) end it "fails when at least once method is never called" do @double.should_receive(:do_something).at_least(:once) expect { verify @double }.to raise_error(/expected: at least 1 time.*received: 0 times/m) end it "fails when at least twice method is called once" do @double.should_receive(:do_something).at_least(:twice) @double.do_something expect { verify @double }.to raise_error(/expected: at least 2 times.*received: 1 time/m) end it "fails when at least twice method is never called" do @double.should_receive(:do_something).at_least(:twice) expect { verify @double }.to raise_error(/expected: at least 2 times.*received: 0 times/m) end it "passes when at least n times method is called exactly n times" do @double.should_receive(:do_something).at_least(4).times @double.do_something @double.do_something @double.do_something @double.do_something verify @double end it "passes when at least n times method is called n plus 1 times" do @double.should_receive(:do_something).at_least(4).times @double.do_something @double.do_something @double.do_something @double.do_something @double.do_something verify @double end it "passes when at least once method is called once" do @double.should_receive(:do_something).at_least(:once) @double.do_something verify @double end it "passes when at least once method is called twice" do @double.should_receive(:do_something).at_least(:once) @double.do_something @double.do_something verify @double end it "passes when at least twice method is called three times" do @double.should_receive(:do_something).at_least(:twice) @double.do_something @double.do_something @double.do_something verify @double end it "passes when at least twice method is called twice" do @double.should_receive(:do_something).at_least(:twice) @double.do_something @double.do_something verify @double end it "returns the value given by a block when the at least once method is called" do @double.should_receive(:to_s).at_least(:once) { "testing" } expect(@double.to_s).to eq "testing" verify @double end context "when sent with 0" do before { RSpec.stub(:deprecate) } it "outputs a deprecation warning" do expect(RSpec).to receive(:deprecate).with("at_least\(0\) with should_receive", :replacement => "stub") expect(@double).to receive(:do_something).at_least(0).times end it "passes with no return if called once" do @double.should_receive(:do_something).at_least(0).times @double.do_something end it "passes with return block if called once" do @double.should_receive(:do_something).at_least(0).times { true } @double.do_something end it "passes with and_return if called once" do @double.should_receive(:do_something).at_least(0).times.and_return true @double.do_something end it "passes with no return if never called" do @double.should_receive(:do_something).at_least(0).times end it "passes with return block if never called" do @double.should_receive(:do_something).at_least(0).times { true } end it "passes with and_return if never called" do @double.should_receive(:do_something).at_least(0).times.and_return true end end it "uses a stub value if no value set" do @double.stub(:do_something => 'foo') @double.should_receive(:do_something).at_least(:once) expect(@double.do_something).to eq 'foo' expect(@double.do_something).to eq 'foo' end it "prefers its own return value over a stub" do @double.stub(:do_something => 'foo') @double.should_receive(:do_something).at_least(:once).and_return('bar') expect(@double.do_something).to eq 'bar' expect(@double.do_something).to eq 'bar' end end end end rspec-mocks-2.14.3/spec/rspec/mocks/configuration_spec.rb0000644000004100000410000001143112202216237023444 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe Configuration do let(:config) { Configuration.new } let(:mod_1) { Module.new } let(:mod_2) { Module.new } def instance_methods_of(mod) mod_1.instance_methods.map(&:to_sym) end it 'adds stub and should_receive to the given modules' do expect(instance_methods_of(mod_1)).not_to include(:stub, :should_receive) expect(instance_methods_of(mod_2)).not_to include(:stub, :should_receive) config.add_stub_and_should_receive_to(mod_1, mod_2) expect(instance_methods_of(mod_1)).to include(:stub, :should_receive) expect(instance_methods_of(mod_2)).to include(:stub, :should_receive) end shared_examples_for "configuring the syntax" do def sandboxed orig_syntax = RSpec::Mocks.configuration.syntax yield ensure configure_syntax(orig_syntax) end around(:each) { |ex| sandboxed(&ex) } let(:dbl) { double } let(:should_methods) { [:should_receive, :stub, :should_not_receive] } let(:should_class_methods) { [:any_instance] } let(:expect_methods) { [:receive, :allow, :expect_any_instance_of, :allow_any_instance_of] } it 'defaults to enabling both the :should and :expect syntaxes' do expect(dbl).to respond_to(*should_methods) expect(self).to respond_to(*expect_methods) end context 'when configured to :expect' do before { configure_syntax :expect } it 'removes the should methods from every object' do expect(dbl).not_to respond_to(*should_methods) end it 'removes `any_instance` from every class' do expect(Class.new).not_to respond_to(*should_class_methods) end it 'adds the expect methods to the example group context' do expect(self).to respond_to(*expect_methods) end it 'reports that the syntax is :expect' do expect(configured_syntax).to eq([:expect]) end it 'is a no-op when configured a second time' do expect(Syntax.default_should_syntax_host).not_to receive(:method_undefined) expect(::RSpec::Mocks::ExampleMethods).not_to receive(:method_added) configure_syntax :expect end end context 'when configured to :should' do before { configure_syntax :should } it 'adds the should methods to every object' do expect(dbl).to respond_to(*should_methods) end it 'adds `any_instance` to every class' do expect(Class.new).to respond_to(*should_class_methods) end it 'removes the expect methods from the example group context' do expect(self).not_to respond_to(*expect_methods) end it 'reports that the syntax is :should' do expect(configured_syntax).to eq([:should]) end it 'is a no-op when configured a second time' do Syntax.default_should_syntax_host.should_not_receive(:method_added) ::RSpec::Mocks::ExampleMethods.should_not_receive(:method_undefined) configure_syntax :should end end context 'when configured to [:should, :expect]' do before { configure_syntax [:should, :expect] } it 'adds the should methods to every object' do expect(dbl).to respond_to(*should_methods) end it 'adds `any_instance` to every class' do expect(Class.new).to respond_to(*should_class_methods) end it 'adds the expect methods to the example group context' do expect(self).to respond_to(*expect_methods) end it 'reports that both syntaxes are enabled' do expect(configured_syntax).to eq([:should, :expect]) end end end describe "configuring rspec-mocks directly" do it_behaves_like "configuring the syntax" do def configure_syntax(syntax) RSpec::Mocks.configuration.syntax = syntax end def configured_syntax RSpec::Mocks.configuration.syntax end end end describe "configuring using the rspec-core config API" do it_behaves_like "configuring the syntax" do def configure_syntax(syntax) RSpec.configure do |rspec| rspec.mock_with :rspec do |c| c.syntax = syntax end end end def configured_syntax RSpec.configure do |rspec| rspec.mock_with :rspec do |c| return c.syntax end end end end end end end end rspec-mocks-2.14.3/spec/rspec/mocks/stub_spec.rb0000644000004100000410000002614612202216237021563 0ustar www-datawww-datarequire 'spec_helper' module RSpec module Mocks describe "A method stub" do before(:each) do @class = Class.new do class << self def existing_class_method existing_private_class_method end private def existing_private_class_method :original_value end end def existing_instance_method existing_private_instance_method end private def existing_private_instance_method :original_value end end @instance = @class.new @stub = Object.new end describe "using stub" do it "returns declared value when message is received" do @instance.stub(:msg).and_return(:return_value) expect(@instance.msg).to equal(:return_value) verify @instance end end describe "using stub!" do before do allow(RSpec).to receive(:deprecate) end it "warns of deprecation" do expect(RSpec).to receive(:deprecate).with("stub!", :replacement => "stub") @instance.stub!(:msg).and_return(:return_value) end it "returns the declared value when the message is received" do @instance.stub!(:msg).and_return(:return_value) expect(@instance.msg).to equal(:return_value) verify @instance end it "can be used to stub the example context itself (since `stub` returns a test dobule instead)" do stub!(:foo).and_return(5) expect(foo).to eq(5) end end describe 'using unstub' do it 'removes the message stub' do @instance.stub(:msg) @instance.unstub(:msg) expect { @instance.msg }.to raise_error NoMethodError end end describe 'using unstub!' do it 'removes the message stub but warns about deprecation' do @instance.stub(:msg) RSpec.should_receive(:deprecate).with("unstub!", :replacement => "unstub") @instance.unstub!(:msg) expect { @instance.msg }.to raise_error NoMethodError end end it "instructs an instance to respond_to the message" do @instance.stub(:msg) expect(@instance).to respond_to(:msg) end it "instructs a class object to respond_to the message" do @class.stub(:msg) expect(@class).to respond_to(:msg) end it "ignores when expected message is received with no args" do @instance.stub(:msg) @instance.msg expect do verify @instance end.not_to raise_error end it "ignores when message is received with args" do @instance.stub(:msg) @instance.msg(:an_arg) expect do verify @instance end.not_to raise_error end it "ignores when expected message is not received" do @instance.stub(:msg) expect do verify @instance end.not_to raise_error end it "handles multiple stubbed methods" do @instance.stub(:msg1 => 1, :msg2 => 2) expect(@instance.msg1).to eq(1) expect(@instance.msg2).to eq(2) end describe "#rspec_reset" do it "removes stubbed methods that didn't exist" do @instance.stub(:non_existent_method) reset @instance expect(@instance).not_to respond_to(:non_existent_method) end it "restores existing instance methods" do # See bug reports 8302 adn 7805 @instance.stub(:existing_instance_method) { :stub_value } reset @instance expect(@instance.existing_instance_method).to eq(:original_value) end it "restores existing private instance methods" do # See bug reports 8302 adn 7805 @instance.stub(:existing_private_instance_method) { :stub_value } reset @instance expect(@instance.send(:existing_private_instance_method)).to eq(:original_value) end it "restores existing class methods" do # See bug reports 8302 adn 7805 @class.stub(:existing_class_method) { :stub_value } reset @class expect(@class.existing_class_method).to eq(:original_value) end it "restores existing private class methods" do # See bug reports 8302 adn 7805 @class.stub(:existing_private_class_method) { :stub_value } reset @class expect(@class.send(:existing_private_class_method)).to eq(:original_value) end it "does not remove existing methods that have been stubbed twice" do @instance.stub(:existing_instance_method) @instance.stub(:existing_instance_method) reset @instance expect(@instance.existing_instance_method).to eq(:original_value) end it "correctly restores the visibility of methods whose visibility has been tweaked on the singleton class" do # hello is a private method when mixed in, but public on the module # itself mod = Module.new { extend self def hello; :hello; end private :hello class << self; public :hello; end; } expect(mod.hello).to eq(:hello) mod.stub(:hello) { :stub } reset mod expect(mod.hello).to eq(:hello) end if RUBY_VERSION >= '2.0.0' context "with a prepended module (ruby 2.0.0+)" do before do mod = Module.new do def existing_instance_method "#{super}_prepended".to_sym end end @prepended_class = Class.new(@class) do prepend mod def non_prepended_method :not_prepended end end @prepended_instance = @prepended_class.new end it "restores prepended instance methods" do allow(@prepended_instance).to receive(:existing_instance_method) { :stubbed } expect(@prepended_instance.existing_instance_method).to eq :stubbed reset @prepended_instance expect(@prepended_instance.existing_instance_method).to eq :original_value_prepended end it "restores non-prepended instance methods" do allow(@prepended_instance).to receive(:non_prepended_method) { :stubbed } expect(@prepended_instance.non_prepended_method).to eq :stubbed reset @prepended_instance expect(@prepended_instance.non_prepended_method).to eq :not_prepended end end end end it "returns values in order to consecutive calls" do @instance.stub(:msg).and_return("1",2,:three) expect(@instance.msg).to eq("1") expect(@instance.msg).to eq(2) expect(@instance.msg).to eq(:three) end it "keeps returning last value in consecutive calls" do @instance.stub(:msg).and_return("1",2,:three) expect(@instance.msg).to eq("1") expect(@instance.msg).to eq(2) expect(@instance.msg).to eq(:three) expect(@instance.msg).to eq(:three) expect(@instance.msg).to eq(:three) end it "yields a specified object" do @instance.stub(:method_that_yields).and_yield(:yielded_obj) current_value = :value_before @instance.method_that_yields {|val| current_value = val} expect(current_value).to eq :yielded_obj verify @instance end it "yields multiple times with multiple calls to and_yield" do @instance.stub(:method_that_yields_multiple_times).and_yield(:yielded_value). and_yield(:another_value) current_value = [] @instance.method_that_yields_multiple_times {|val| current_value << val} expect(current_value).to eq [:yielded_value, :another_value] verify @instance end it "yields a specified object and return another specified object" do yielded_obj = double("my mock") yielded_obj.should_receive(:foo).with(:bar) @instance.stub(:method_that_yields_and_returns).and_yield(yielded_obj).and_return(:baz) expect(@instance.method_that_yields_and_returns { |o| o.foo :bar }).to eq :baz end it "throws when told to" do @stub.stub(:something).and_throw(:up) expect { @stub.something }.to throw_symbol(:up) end it "throws with argument when told to" do @stub.stub(:something).and_throw(:up, 'high') expect { @stub.something }.to throw_symbol(:up, 'high') end it "overrides a pre-existing method" do @stub.stub(:existing_instance_method).and_return(:updated_stub_value) expect(@stub.existing_instance_method).to eq :updated_stub_value end it "overrides a pre-existing stub" do @stub.stub(:foo) { 'bar' } @stub.stub(:foo) { 'baz' } expect(@stub.foo).to eq 'baz' end it "allows a stub and an expectation" do @stub.stub(:foo).with("bar") @stub.should_receive(:foo).with("baz") @stub.foo("bar") @stub.foo("baz") end it "calculates return value by executing block passed to #and_return" do @stub.stub(:something).with("a","b","c").and_return { |a,b,c| c+b+a } expect(@stub.something("a","b","c")).to eq "cba" verify @stub end end describe "A method stub with args" do before(:each) do @stub = Object.new @stub.stub(:foo).with("bar") end it "does not complain if not called" do end it "does not complain if called with arg" do @stub.foo("bar") end it "complains if called with no arg" do expect { @stub.foo }.to raise_error(/received :foo with unexpected arguments/) end it "complains if called with other arg", :github_issue => [123,147] do expect { @stub.foo("other") }.to raise_error(/received :foo with unexpected arguments.*Please stub a default value/m) end it "does not complain if also mocked w/ different args" do @stub.should_receive(:foo).with("baz") @stub.foo("bar") @stub.foo("baz") end it "complains if also mocked w/ different args AND called w/ a 3rd set of args" do @stub.should_receive(:foo).with("baz") @stub.foo("bar") @stub.foo("baz") expect { @stub.foo("other") }.to raise_error end it "supports options" do @stub.stub(:foo, :expected_from => "bar") end it 'uses the correct stubbed response when responding to a mock expectation' do @stub.stub(:bar) { 15 } @stub.stub(:bar).with(:eighteen) { 18 } @stub.stub(:bar).with(:thirteen) { 13 } @stub.should_receive(:bar).exactly(4).times expect(@stub.bar(:blah)).to eq(15) expect(@stub.bar(:thirteen)).to eq(13) expect(@stub.bar(:eighteen)).to eq(18) expect(@stub.bar).to eq(15) end end end end rspec-mocks-2.14.3/spec/rspec/mocks_spec.rb0000644000004100000410000000325712202216237020604 0ustar www-datawww-datarequire "spec_helper" describe RSpec::Mocks do describe "::setup" do context "with an existing Mock::Space" do before do @orig_space = RSpec::Mocks::space end after do RSpec::Mocks::space = @orig_space end it "memoizes the space" do RSpec::Mocks::setup(Object.new) space = RSpec::Mocks::space RSpec::Mocks::setup(Object.new) expect(RSpec::Mocks::space).to equal(space) end end context "with no pre-existing Mock::Space" do it "initializes a Mock::Space" do RSpec::Mocks::space = nil RSpec::Mocks::setup(Object.new) expect(RSpec::Mocks::space).not_to be_nil end end end describe "::verify" do it "delegates to the space" do foo = double foo.should_receive(:bar) expect do RSpec::Mocks::verify end.to raise_error(RSpec::Mocks::MockExpectationError) end end describe "::teardown" do it "delegates to the space" do foo = double foo.should_receive(:bar) RSpec::Mocks::teardown expect do foo.bar end.to raise_error(/received unexpected message/) end end describe ".configuration" do it 'returns a memoized configuration instance' do expect(RSpec::Mocks.configuration).to be_a(RSpec::Mocks::Configuration) expect(RSpec::Mocks.configuration).to be(RSpec::Mocks.configuration) end end context 'when requiring spec/mocks (as was valid for rspec 1)' do it 'prints a deprecation warning' do expect(::RSpec).to receive(:deprecate).with("require 'spec/mocks'", :replacement => "require 'rspec/mocks'") load "spec/mocks.rb" end end end rspec-mocks-2.14.3/.document0000644000004100000410000000006112202216237015670 0ustar www-datawww-datalib/**/*.rb - README.md License.txt Changelog.md rspec-mocks-2.14.3/metadata.yml0000644000004100000410000002756112202216237016372 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: rspec-mocks version: !ruby/object:Gem::Version prerelease: version: 2.14.3 platform: ruby authors: - Steven Baker - David Chelimsky autorequire: bindir: bin cert_chain: [] date: 2013-08-09 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 10.0.0 none: false prerelease: false name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 10.0.0 none: false type: :development - !ruby/object:Gem::Dependency version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 1.1.9 none: false prerelease: false name: cucumber requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 1.1.9 none: false type: :development - !ruby/object:Gem::Dependency version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.5' none: false prerelease: false name: aruba requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.5' none: false type: :development description: RSpec's 'test double' framework, with support for stubbing and mocking email: rspec-users@rubyforge.org executables: [] extensions: [] extra_rdoc_files: [] files: - lib/rspec/mocks.rb - lib/rspec/mocks/any_instance/chain.rb - lib/rspec/mocks/any_instance/expectation_chain.rb - lib/rspec/mocks/any_instance/message_chains.rb - lib/rspec/mocks/any_instance/recorder.rb - lib/rspec/mocks/any_instance/stub_chain.rb - lib/rspec/mocks/any_instance/stub_chain_chain.rb - lib/rspec/mocks/argument_list_matcher.rb - lib/rspec/mocks/argument_matchers.rb - lib/rspec/mocks/configuration.rb - lib/rspec/mocks/deprecation.rb - lib/rspec/mocks/error_generator.rb - lib/rspec/mocks/errors.rb - lib/rspec/mocks/example_methods.rb - lib/rspec/mocks/extensions/instance_exec.rb - lib/rspec/mocks/extensions/marshal.rb - lib/rspec/mocks/framework.rb - lib/rspec/mocks/instance_method_stasher.rb - lib/rspec/mocks/matchers/have_received.rb - lib/rspec/mocks/matchers/receive.rb - lib/rspec/mocks/message_expectation.rb - lib/rspec/mocks/method_double.rb - lib/rspec/mocks/mock.rb - lib/rspec/mocks/mutate_const.rb - lib/rspec/mocks/order_group.rb - lib/rspec/mocks/proxy.rb - lib/rspec/mocks/proxy_for_nil.rb - lib/rspec/mocks/space.rb - lib/rspec/mocks/standalone.rb - lib/rspec/mocks/stub_chain.rb - lib/rspec/mocks/syntax.rb - lib/rspec/mocks/targets.rb - lib/rspec/mocks/test_double.rb - lib/rspec/mocks/version.rb - lib/spec/mocks.rb - README.md - License.txt - Changelog.md - .yardopts - .document - features/README.md - features/Scope.md - features/Upgrade.md - features/argument_matchers/README.md - features/argument_matchers/explicit.feature - features/argument_matchers/general_matchers.feature - features/argument_matchers/type_matchers.feature - features/message_expectations/README.md - features/message_expectations/allow_any_instance_of.feature - features/message_expectations/any_instance.feature - features/message_expectations/block_local_expectations.feature.pending - features/message_expectations/call_original.feature - features/message_expectations/expect_any_instance_of.feature - features/message_expectations/expect_message_using_expect.feature - features/message_expectations/expect_message_using_should_receive.feature - features/message_expectations/receive_counts.feature - features/message_expectations/warn_when_expectation_is_set_on_nil.feature - features/method_stubs/README.md - features/method_stubs/any_instance.feature - features/method_stubs/as_null_object.feature - features/method_stubs/simple_return_value_with_allow.feature - features/method_stubs/simple_return_value_with_stub.feature - features/method_stubs/stub_chain.feature - features/method_stubs/stub_implementation.feature - features/method_stubs/to_ary.feature - features/mutating_constants/README.md - features/mutating_constants/hiding_defined_constant.feature - features/mutating_constants/stub_defined_constant.feature - features/mutating_constants/stub_undefined_constant.feature - features/outside_rspec/configuration.feature - features/outside_rspec/standalone.feature - features/spies/spy_partial_mock_method.feature - features/spies/spy_pure_mock_method.feature - features/spies/spy_unstubbed_method.feature - features/step_definitions/additional_cli_steps.rb - features/support/env.rb - features/support/rubinius.rb - features/test_frameworks/test_unit.feature - spec/rspec/mocks/and_call_original_spec.rb - spec/rspec/mocks/and_yield_spec.rb - spec/rspec/mocks/any_instance/message_chains_spec.rb - spec/rspec/mocks/any_instance_spec.rb - spec/rspec/mocks/any_number_of_times_spec.rb - spec/rspec/mocks/argument_expectation_spec.rb - spec/rspec/mocks/at_least_spec.rb - spec/rspec/mocks/at_most_spec.rb - spec/rspec/mocks/block_return_value_spec.rb - spec/rspec/mocks/bug_report_10260_spec.rb - spec/rspec/mocks/bug_report_10263_spec.rb - spec/rspec/mocks/bug_report_11545_spec.rb - spec/rspec/mocks/bug_report_496_spec.rb - spec/rspec/mocks/bug_report_600_spec.rb - spec/rspec/mocks/bug_report_7611_spec.rb - spec/rspec/mocks/bug_report_8165_spec.rb - spec/rspec/mocks/bug_report_830_spec.rb - spec/rspec/mocks/bug_report_957_spec.rb - spec/rspec/mocks/combining_implementation_instructions_spec.rb - spec/rspec/mocks/configuration_spec.rb - spec/rspec/mocks/double_spec.rb - spec/rspec/mocks/extensions/marshal_spec.rb - spec/rspec/mocks/failing_argument_matchers_spec.rb - spec/rspec/mocks/hash_excluding_matcher_spec.rb - spec/rspec/mocks/hash_including_matcher_spec.rb - spec/rspec/mocks/instance_method_stasher_spec.rb - spec/rspec/mocks/matchers/have_received_spec.rb - spec/rspec/mocks/matchers/receive_spec.rb - spec/rspec/mocks/methods_spec.rb - spec/rspec/mocks/mock_ordering_spec.rb - spec/rspec/mocks/mock_space_spec.rb - spec/rspec/mocks/mock_spec.rb - spec/rspec/mocks/multiple_return_value_spec.rb - spec/rspec/mocks/mutate_const_spec.rb - spec/rspec/mocks/nil_expectation_warning_spec.rb - spec/rspec/mocks/null_object_mock_spec.rb - spec/rspec/mocks/once_counts_spec.rb - spec/rspec/mocks/options_hash_spec.rb - spec/rspec/mocks/partial_mock_spec.rb - spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb - spec/rspec/mocks/passing_argument_matchers_spec.rb - spec/rspec/mocks/precise_counts_spec.rb - spec/rspec/mocks/record_messages_spec.rb - spec/rspec/mocks/serialization_spec.rb - spec/rspec/mocks/stash_spec.rb - spec/rspec/mocks/stub_chain_spec.rb - spec/rspec/mocks/stub_implementation_spec.rb - spec/rspec/mocks/stub_spec.rb - spec/rspec/mocks/stubbed_message_expectations_spec.rb - spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb - spec/rspec/mocks/test_double_spec.rb - spec/rspec/mocks/to_ary_spec.rb - spec/rspec/mocks/twice_counts_spec.rb - spec/rspec/mocks_spec.rb - spec/spec_helper.rb homepage: http://github.com/rspec/rspec-mocks licenses: - MIT post_install_message: rdoc_options: - --charset=UTF-8 require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' segments: - 0 hash: -4603029701728341322 none: false required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' segments: - 0 hash: -4603029701728341322 none: false requirements: [] rubyforge_project: rspec rubygems_version: 1.8.24 signing_key: specification_version: 3 summary: rspec-mocks-2.14.3 test_files: - features/README.md - features/Scope.md - features/Upgrade.md - features/argument_matchers/README.md - features/argument_matchers/explicit.feature - features/argument_matchers/general_matchers.feature - features/argument_matchers/type_matchers.feature - features/message_expectations/README.md - features/message_expectations/allow_any_instance_of.feature - features/message_expectations/any_instance.feature - features/message_expectations/block_local_expectations.feature.pending - features/message_expectations/call_original.feature - features/message_expectations/expect_any_instance_of.feature - features/message_expectations/expect_message_using_expect.feature - features/message_expectations/expect_message_using_should_receive.feature - features/message_expectations/receive_counts.feature - features/message_expectations/warn_when_expectation_is_set_on_nil.feature - features/method_stubs/README.md - features/method_stubs/any_instance.feature - features/method_stubs/as_null_object.feature - features/method_stubs/simple_return_value_with_allow.feature - features/method_stubs/simple_return_value_with_stub.feature - features/method_stubs/stub_chain.feature - features/method_stubs/stub_implementation.feature - features/method_stubs/to_ary.feature - features/mutating_constants/README.md - features/mutating_constants/hiding_defined_constant.feature - features/mutating_constants/stub_defined_constant.feature - features/mutating_constants/stub_undefined_constant.feature - features/outside_rspec/configuration.feature - features/outside_rspec/standalone.feature - features/spies/spy_partial_mock_method.feature - features/spies/spy_pure_mock_method.feature - features/spies/spy_unstubbed_method.feature - features/step_definitions/additional_cli_steps.rb - features/support/env.rb - features/support/rubinius.rb - features/test_frameworks/test_unit.feature - spec/rspec/mocks/and_call_original_spec.rb - spec/rspec/mocks/and_yield_spec.rb - spec/rspec/mocks/any_instance/message_chains_spec.rb - spec/rspec/mocks/any_instance_spec.rb - spec/rspec/mocks/any_number_of_times_spec.rb - spec/rspec/mocks/argument_expectation_spec.rb - spec/rspec/mocks/at_least_spec.rb - spec/rspec/mocks/at_most_spec.rb - spec/rspec/mocks/block_return_value_spec.rb - spec/rspec/mocks/bug_report_10260_spec.rb - spec/rspec/mocks/bug_report_10263_spec.rb - spec/rspec/mocks/bug_report_11545_spec.rb - spec/rspec/mocks/bug_report_496_spec.rb - spec/rspec/mocks/bug_report_600_spec.rb - spec/rspec/mocks/bug_report_7611_spec.rb - spec/rspec/mocks/bug_report_8165_spec.rb - spec/rspec/mocks/bug_report_830_spec.rb - spec/rspec/mocks/bug_report_957_spec.rb - spec/rspec/mocks/combining_implementation_instructions_spec.rb - spec/rspec/mocks/configuration_spec.rb - spec/rspec/mocks/double_spec.rb - spec/rspec/mocks/extensions/marshal_spec.rb - spec/rspec/mocks/failing_argument_matchers_spec.rb - spec/rspec/mocks/hash_excluding_matcher_spec.rb - spec/rspec/mocks/hash_including_matcher_spec.rb - spec/rspec/mocks/instance_method_stasher_spec.rb - spec/rspec/mocks/matchers/have_received_spec.rb - spec/rspec/mocks/matchers/receive_spec.rb - spec/rspec/mocks/methods_spec.rb - spec/rspec/mocks/mock_ordering_spec.rb - spec/rspec/mocks/mock_space_spec.rb - spec/rspec/mocks/mock_spec.rb - spec/rspec/mocks/multiple_return_value_spec.rb - spec/rspec/mocks/mutate_const_spec.rb - spec/rspec/mocks/nil_expectation_warning_spec.rb - spec/rspec/mocks/null_object_mock_spec.rb - spec/rspec/mocks/once_counts_spec.rb - spec/rspec/mocks/options_hash_spec.rb - spec/rspec/mocks/partial_mock_spec.rb - spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb - spec/rspec/mocks/passing_argument_matchers_spec.rb - spec/rspec/mocks/precise_counts_spec.rb - spec/rspec/mocks/record_messages_spec.rb - spec/rspec/mocks/serialization_spec.rb - spec/rspec/mocks/stash_spec.rb - spec/rspec/mocks/stub_chain_spec.rb - spec/rspec/mocks/stub_implementation_spec.rb - spec/rspec/mocks/stub_spec.rb - spec/rspec/mocks/stubbed_message_expectations_spec.rb - spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb - spec/rspec/mocks/test_double_spec.rb - spec/rspec/mocks/to_ary_spec.rb - spec/rspec/mocks/twice_counts_spec.rb - spec/rspec/mocks_spec.rb - spec/spec_helper.rb has_rdoc: rspec-mocks-2.14.3/.yardopts0000644000004100000410000000011512202216237015717 0ustar www-datawww-data--exclude features --no-private --markup markdown - Changelog.md License.txt rspec-mocks-2.14.3/lib/0000755000004100000410000000000012202216237014622 5ustar www-datawww-datarspec-mocks-2.14.3/lib/spec/0000755000004100000410000000000012202216237015554 5ustar www-datawww-datarspec-mocks-2.14.3/lib/spec/mocks.rb0000644000004100000410000000022112202216237017210 0ustar www-datawww-data# For backward compatibility with rspec-1 require 'rspec/mocks' RSpec.deprecate "require 'spec/mocks'", :replacement => "require 'rspec/mocks'" rspec-mocks-2.14.3/lib/rspec/0000755000004100000410000000000012202216237015736 5ustar www-datawww-datarspec-mocks-2.14.3/lib/rspec/mocks/0000755000004100000410000000000012202216237017052 5ustar www-datawww-datarspec-mocks-2.14.3/lib/rspec/mocks/space.rb0000644000004100000410000000407712202216237020502 0ustar www-datawww-datamodule RSpec module Mocks # @api private class Space attr_reader :proxies, :any_instance_recorders def initialize @proxies = {} @any_instance_recorders = {} end def verify_all proxies.each_value do |object| object.verify end any_instance_recorders.each_value do |recorder| recorder.verify end end def reset_all ConstantMutator.reset_all proxies.each_value do |object| object.reset end proxies.clear any_instance_recorders.clear expectation_ordering.clear end def expectation_ordering @expectation_ordering ||= OrderGroup.new end def any_instance_recorder_for(klass) id = klass.__id__ any_instance_recorders.fetch(id) do any_instance_recorders[id] = AnyInstance::Recorder.new(klass) end end def remove_any_instance_recorder_for(klass) any_instance_recorders.delete(klass.__id__) end def proxy_for(object) id = id_for(object) proxies.fetch(id) do proxies[id] = case object when NilClass then ProxyForNil.new when TestDouble then object.__build_mock_proxy else Proxy.new(object) end end end alias ensure_registered proxy_for def registered?(object) proxies.has_key?(id_for object) end if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2 require 'securerandom' def id_for(object) id = object.__id__ return id if object.equal?(::ObjectSpace._id2ref(id)) # this suggests that object.__id__ is proxying through to some wrapped object object.instance_eval do @__id_for_rspec_mocks_space ||= ::SecureRandom.uuid end end else def id_for(object) object.__id__ end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/version.rb0000644000004100000410000000013112202216237021057 0ustar www-datawww-datamodule RSpec module Mocks module Version STRING = '2.14.3' end end end rspec-mocks-2.14.3/lib/rspec/mocks/proxy.rb0000644000004100000410000001531512202216237020565 0ustar www-datawww-datamodule RSpec module Mocks # @private class Proxy # @private def initialize(object, name=nil, options={}) @object = object @name = name @error_generator = ErrorGenerator.new object, name, options @expectation_ordering = RSpec::Mocks::space.expectation_ordering @messages_received = [] @options = options @already_proxied_respond_to = false @null_object = false end # @private def null_object? @null_object end # @private # Tells the object to ignore any messages that aren't explicitly set as # stubs or message expectations. def as_null_object @null_object = true @object end # @private def already_proxied_respond_to @already_proxied_respond_to = true end # @private def already_proxied_respond_to? @already_proxied_respond_to end # @private def add_message_expectation(location, method_name, opts={}, &block) meth_double = method_double[method_name] if null_object? && !block meth_double.add_default_stub(@error_generator, @expectation_ordering, location, opts) do @object end end meth_double.add_expectation @error_generator, @expectation_ordering, location, opts, &block end # @private def build_expectation(method_name) meth_double = method_double[method_name] meth_double.build_expectation( @error_generator, @expectation_ordering ) end # @private def replay_received_message_on(expectation) expected_method_name = expectation.message meth_double = method_double[expected_method_name] if meth_double.expectations.any? @error_generator.raise_expectation_on_mocked_method(expected_method_name) end unless null_object? || meth_double.stubs.any? @error_generator.raise_expectation_on_unstubbed_method(expected_method_name) end @messages_received.each do |(actual_method_name, args, _)| if expectation.matches?(actual_method_name, *args) expectation.invoke(nil) end end end # @private def check_for_unexpected_arguments(expectation) @messages_received.each do |(method_name, args, _)| if expectation.matches_name_but_not_args(method_name, *args) raise_unexpected_message_args_error(expectation, *args) end end end # @private def add_stub(location, method_name, opts={}, &implementation) method_double[method_name].add_stub @error_generator, @expectation_ordering, location, opts, &implementation end # @private def remove_stub(method_name) method_double[method_name].remove_stub end # @private def verify method_doubles.each {|d| d.verify} ensure reset end # @private def reset method_doubles.each {|d| d.reset} @messages_received.clear end # @private def received_message?(method_name, *args, &block) @messages_received.any? {|array| array == [method_name, args, block]} end # @private def has_negative_expectation?(message) method_double[message].expectations.detect {|expectation| expectation.negative_expectation_for?(message)} end # @private def record_message_received(message, *args, &block) @messages_received << [message, args, block] end # @private def message_received(message, *args, &block) record_message_received message, *args, &block expectation = find_matching_expectation(message, *args) stub = find_matching_method_stub(message, *args) if (stub && expectation && expectation.called_max_times?) || (stub && !expectation) expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters? if expectation = find_almost_matching_expectation(message, *args) expectation.advise(*args) unless expectation.expected_messages_received? end stub.invoke(nil, *args, &block) elsif expectation expectation.invoke(stub, *args, &block) elsif expectation = find_almost_matching_expectation(message, *args) expectation.advise(*args) if null_object? unless expectation.expected_messages_received? raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(message) or null_object?) elsif stub = find_almost_matching_stub(message, *args) stub.advise(*args) raise_missing_default_stub_error(stub, *args) elsif @object.is_a?(Class) @object.superclass.__send__(message, *args, &block) else @object.__send__(:method_missing, message, *args, &block) end end # @private def raise_unexpected_message_error(method_name, *args) @error_generator.raise_unexpected_message_error method_name, *args end # @private def raise_unexpected_message_args_error(expectation, *args) @error_generator.raise_unexpected_message_args_error(expectation, *args) end # @private def raise_missing_default_stub_error(expectation, *args) @error_generator.raise_missing_default_stub_error(expectation, *args) end private def method_double @method_double ||= Hash.new {|h,k| h[k] = MethodDouble.new(@object, k, self) } end def method_doubles method_double.values end def find_matching_expectation(method_name, *args) find_best_matching_expectation_for(method_name) do |expectation| expectation.matches?(method_name, *args) end end def find_almost_matching_expectation(method_name, *args) find_best_matching_expectation_for(method_name) do |expectation| expectation.matches_name_but_not_args(method_name, *args) end end def find_best_matching_expectation_for(method_name) first_match = nil method_double[method_name].expectations.each do |expectation| next unless yield expectation return expectation unless expectation.called_max_times? first_match ||= expectation end first_match end def find_matching_method_stub(method_name, *args) method_double[method_name].stubs.find {|stub| stub.matches?(method_name, *args)} end def find_almost_matching_stub(method_name, *args) method_double[method_name].stubs.find {|stub| stub.matches_name_but_not_args(method_name, *args)} end end end end rspec-mocks-2.14.3/lib/rspec/mocks/standalone.rb0000644000004100000410000000006012202216237021523 0ustar www-datawww-datarequire 'rspec/mocks' RSpec::Mocks.setup(self) rspec-mocks-2.14.3/lib/rspec/mocks/mock.rb0000644000004100000410000000012612202216237020327 0ustar www-datawww-datamodule RSpec module Mocks class Mock include TestDouble end end end rspec-mocks-2.14.3/lib/rspec/mocks/configuration.rb0000644000004100000410000000255212202216237022252 0ustar www-datawww-datamodule RSpec module Mocks # Provides configuration options for rspec-mocks. class Configuration # Adds `stub` and `should_receive` to the given # modules or classes. This is usually only necessary # if you application uses some proxy classes that # "strip themselves down" to a bare minimum set of # methods and remove `stub` and `should_receive` in # the process. # # @example # # RSpec.configure do |rspec| # rspec.mock_with :rspec do |mocks| # mocks.add_stub_and_should_receive_to Delegator # end # end # def add_stub_and_should_receive_to(*modules) modules.each do |mod| Syntax.enable_should(mod) end end def syntax=(values) if Array(values).include?(:expect) Syntax.enable_expect else Syntax.disable_expect end if Array(values).include?(:should) Syntax.enable_should else Syntax.disable_should end end def syntax syntaxes = [] syntaxes << :should if Syntax.should_enabled? syntaxes << :expect if Syntax.expect_enabled? syntaxes end end def self.configuration @configuration ||= Configuration.new end configuration.syntax = [:should, :expect] end end rspec-mocks-2.14.3/lib/rspec/mocks/example_methods.rb0000644000004100000410000001340312202216237022556 0ustar www-datawww-datamodule RSpec module Mocks module ExampleMethods include RSpec::Mocks::ArgumentMatchers # @overload double() # @overload double(name) # @overload double(stubs) # @overload double(name, stubs) # @param name [String/Symbol] (optional) used in # clarify intent # @param stubs (Hash) (optional) hash of method/return-value pairs # @return (Mock) # # Constructs an instance of [RSpec::Mocks::Mock](RSpec::Mocks::Mock) configured # with an optional name, used for reporting in failure messages, and an optional # hash of method/return-value pairs. # # @example # # book = double("book", :title => "The RSpec Book") # book.title #=> "The RSpec Book" # # card = double("card", :suit => "Spades", :rank => "A") # card.suit #=> "Spades" # card.rank #=> "A" # # @see #mock # @see #stub def double(*args) declare_double('Double', *args) end # Deprecated: Use [double](#double-instance_method). def mock(*args) RSpec.deprecate "mock", :replacement => "double" declare_double('Mock', *args) end # Deprecated: Use [double](#double-instance_method). def stub(*args) RSpec.deprecate "stub", :replacement => "double" declare_double('Stub', *args) end # Disables warning messages about expectations being set on nil. # # By default warning messages are issued when expectations are set on # nil. This is to prevent false-positives and to catch potential bugs # early on. def allow_message_expectations_on_nil RSpec::Mocks.space.proxy_for(nil).warn_about_expectations = false end # Stubs the named constant with the given value. # Like method stubs, the constant will be restored # to its original value (or lack of one, if it was # undefined) when the example completes. # # @param constant_name [String] The fully qualified name of the constant. The current # constant scoping at the point of call is not considered. # @param value [Object] The value to make the constant refer to. When the # example completes, the constant will be restored to its prior state. # @param options [Hash] Stubbing options. # @option options :transfer_nested_constants [Boolean, Array] Determines # what nested constants, if any, will be transferred from the original value # of the constant to the new value of the constant. This only works if both # the original and new values are modules (or classes). # @return [Object] the stubbed value of the constant # # @example # # stub_const("MyClass", Class.new) # => Replaces (or defines) MyClass with a new class object. # stub_const("SomeModel::PER_PAGE", 5) # => Sets SomeModel::PER_PAGE to 5. # # class CardDeck # SUITS = [:Spades, :Diamonds, :Clubs, :Hearts] # NUM_CARDS = 52 # end # # stub_const("CardDeck", Class.new) # CardDeck::SUITS # => uninitialized constant error # CardDeck::NUM_CARDS # => uninitialized constant error # # stub_const("CardDeck", Class.new, :transfer_nested_constants => true) # CardDeck::SUITS # => our suits array # CardDeck::NUM_CARDS # => 52 # # stub_const("CardDeck", Class.new, :transfer_nested_constants => [:SUITS]) # CardDeck::SUITS # => our suits array # CardDeck::NUM_CARDS # => uninitialized constant error def stub_const(constant_name, value, options = {}) ConstantMutator.stub(constant_name, value, options) end # Hides the named constant with the given value. The constant will be # undefined for the duration of the test. # # Like method stubs, the constant will be restored to its original value # when the example completes. # # @param constant_name [String] The fully qualified name of the constant. # The current constant scoping at the point of call is not considered. # # @example # # hide_const("MyClass") # => MyClass is now an undefined constant def hide_const(constant_name) ConstantMutator.hide(constant_name) end # Verifies that the given object received the expected message during the # course of the test. The method must have previously been stubbed in # order for messages to be verified. # # Stubbing and verifying messages received in this way implements the # Test Spy pattern. # # @param method_name [Symbol] name of the method expected to have been # called. # # @example # # invitation = double('invitation', accept: true) # user.accept_invitation(invitation) # expect(invitation).to have_received(:accept) # # # You can also use most message expectations: # expect(invitation).to have_received(:accept).with(mailer).once def have_received(method_name) Matchers::HaveReceived.new(method_name) end def self.included(klass) klass.class_eval do # This gets mixed in so that if `RSpec::Matchers` is included in # `klass` later, it's definition of `expect` will take precedence. include ExpectHost unless method_defined?(:expect) end end private def declare_double(declared_as, *args) args << {} unless Hash === args.last args.last[:__declared_as] = declared_as RSpec::Mocks::Mock.new(*args) end # This module exists to host the `expect` method for cases where # rspec-mocks is used w/o rspec-expectations. module ExpectHost end end end end rspec-mocks-2.14.3/lib/rspec/mocks/errors.rb0000644000004100000410000000026012202216237020711 0ustar www-datawww-datamodule RSpec module Mocks # @private class MockExpectationError < Exception end # @private class AmbiguousReturnError < StandardError end end end rspec-mocks-2.14.3/lib/rspec/mocks/message_expectation.rb0000644000004100000410000004245112202216237023434 0ustar www-datawww-datamodule RSpec module Mocks class MessageExpectation # @private attr_accessor :error_generator, :implementation attr_reader :message attr_writer :expected_received_count, :expected_from, :argument_list_matcher protected :expected_received_count=, :expected_from=, :error_generator, :error_generator=, :implementation= # @private def initialize(error_generator, expectation_ordering, expected_from, method_double, expected_received_count=1, opts={}, &implementation_block) @error_generator = error_generator @error_generator.opts = opts @expected_from = expected_from @method_double = method_double @message = @method_double.method_name @actual_received_count = 0 @expected_received_count = expected_received_count @argument_list_matcher = ArgumentListMatcher.new(ArgumentMatchers::AnyArgsMatcher.new) @order_group = expectation_ordering @at_least = @at_most = @exactly = nil @args_to_yield = [] @failed_fast = nil @eval_context = nil @implementation = Implementation.new self.inner_implementation_action = implementation_block end # @private def expected_args @argument_list_matcher.expected_args end # @overload and_return(value) # @overload and_return(first_value, second_value) # @overload and_return(&block) # # Tells the object to return a value when it receives the message. Given # more than one value, the first value is returned the first time the # message is received, the second value is returned the next time, etc, # etc. # # If the message is received more times than there are values, the last # value is received for every subsequent call. # # The block format is still supported, but is unofficially deprecated in # favor of just passing a block to the stub method. # # @example # # counter.stub(:count).and_return(1) # counter.count # => 1 # counter.count # => 1 # # counter.stub(:count).and_return(1,2,3) # counter.count # => 1 # counter.count # => 2 # counter.count # => 3 # counter.count # => 3 # counter.count # => 3 # # etc # # # Supported, but ... # counter.stub(:count).and_return { 1 } # counter.count # => 1 # # # ... this is prefered # counter.stub(:count) { 1 } # counter.count # => 1 def and_return(*values, &implementation) if negative? RSpec.deprecate "`and_return` on a negative message expectation" end @expected_received_count = [@expected_received_count, values.size].max unless ignoring_args? || (@expected_received_count == 0 and @at_least) if implementation # TODO: deprecate `and_return { value }` self.inner_implementation_action = implementation else self.terminal_implementation_action = AndReturnImplementation.new(values) end nil end # Tells the object to delegate to the original unmodified method # when it receives the message. # # @note This is only available on partial mock objects. # # @example # # counter.should_receive(:increment).and_call_original # original_count = counter.count # counter.increment # expect(counter.count).to eq(original_count + 1) def and_call_original if @method_double.object.is_a?(RSpec::Mocks::TestDouble) @error_generator.raise_only_valid_on_a_partial_mock(:and_call_original) else @implementation = AndCallOriginalImplementation.new(@method_double.original_method) end end # @overload and_raise # @overload and_raise(ExceptionClass) # @overload and_raise(ExceptionClass, message) # @overload and_raise(exception_instance) # # Tells the object to raise an exception when the message is received. # # @note # # When you pass an exception class, the MessageExpectation will raise # an instance of it, creating it with `exception` and passing `message` # if specified. If the exception class initializer requires more than # one parameters, you must pass in an instance and not the class, # otherwise this method will raise an ArgumentError exception. # # @example # # car.stub(:go).and_raise # car.stub(:go).and_raise(OutOfGas) # car.stub(:go).and_raise(OutOfGas, "At least 2 oz of gas needed to drive") # car.stub(:go).and_raise(OutOfGas.new(2, :oz)) def and_raise(exception = RuntimeError, message = nil) if exception.respond_to?(:exception) exception = message ? exception.exception(message) : exception.exception end self.terminal_implementation_action = Proc.new { raise exception } nil end # @overload and_throw(symbol) # @overload and_throw(symbol, object) # # Tells the object to throw a symbol (with the object if that form is # used) when the message is received. # # @example # # car.stub(:go).and_throw(:out_of_gas) # car.stub(:go).and_throw(:out_of_gas, :level => 0.1) def and_throw(*args) self.terminal_implementation_action = Proc.new { throw(*args) } nil end # Tells the object to yield one or more args to a block when the message # is received. # # @example # # stream.stub(:open).and_yield(StringIO.new) def and_yield(*args, &block) yield @eval_context = Object.new.extend(RSpec::Mocks::InstanceExec) if block @args_to_yield << args self.initial_implementation_action = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator) self end # @private def matches?(message, *args) @message == message && @argument_list_matcher.args_match?(*args) end # @private def invoke(parent_stub, *args, &block) if negative? || ((@exactly || @at_most) && (@actual_received_count == @expected_received_count)) @actual_received_count += 1 @failed_fast = true #args are the args we actually received, @argument_list_matcher is the #list of args we were expecting @error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *args) end @order_group.handle_order_constraint self begin if implementation.present? implementation.call(*args, &block) elsif parent_stub parent_stub.invoke(nil, *args, &block) end ensure @actual_received_count += 1 end end # @private def negative? @expected_received_count == 0 && !@at_least end # @private def called_max_times? @expected_received_count != :any && !@at_least && @expected_received_count > 0 && @actual_received_count >= @expected_received_count end # @private def matches_name_but_not_args(message, *args) @message == message and not @argument_list_matcher.args_match?(*args) end # @private def verify_messages_received generate_error unless expected_messages_received? || failed_fast? rescue RSpec::Mocks::MockExpectationError => error error.backtrace.insert(0, @expected_from) Kernel::raise error end # @private def expected_messages_received? ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count? end # @private def ignoring_args? @expected_received_count == :any end # @private def matches_at_least_count? @at_least && @actual_received_count >= @expected_received_count end # @private def matches_at_most_count? @at_most && @actual_received_count <= @expected_received_count end # @private def matches_exact_count? @expected_received_count == @actual_received_count end # @private def similar_messages @similar_messages ||= [] end # @private def advise(*args) similar_messages << args end # @private def generate_error if similar_messages.empty? @error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *expected_args) else @error_generator.raise_similar_message_args_error(self, *@similar_messages) end end def expectation_count_type return :at_least if @at_least return :at_most if @at_most return nil end # @private def description @error_generator.describe_expectation(@message, @expected_received_count, @actual_received_count, *expected_args) end def raise_out_of_order_error @error_generator.raise_out_of_order_error @message end # Constrains a stub or message expectation to invocations with specific # arguments. # # With a stub, if the message might be received with other args as well, # you should stub a default value first, and then stub or mock the same # message using `with` to constrain to specific arguments. # # A message expectation will fail if the message is received with different # arguments. # # @example # # cart.stub(:add) { :failure } # cart.stub(:add).with(Book.new(:isbn => 1934356379)) { :success } # cart.add(Book.new(:isbn => 1234567890)) # # => :failure # cart.add(Book.new(:isbn => 1934356379)) # # => :success # # cart.should_receive(:add).with(Book.new(:isbn => 1934356379)) { :success } # cart.add(Book.new(:isbn => 1234567890)) # # => failed expectation # cart.add(Book.new(:isbn => 1934356379)) # # => passes def with(*args, &block) self.inner_implementation_action = block if block_given? unless args.empty? @argument_list_matcher = ArgumentListMatcher.new(*args, &block) self end # Constrain a message expectation to be received a specific number of # times. # # @example # # dealer.should_receive(:deal_card).exactly(10).times def exactly(n, &block) self.inner_implementation_action = block set_expected_received_count :exactly, n self end # Constrain a message expectation to be received at least a specific # number of times. # # @example # # dealer.should_receive(:deal_card).at_least(9).times def at_least(n, &block) if n == 0 RSpec.deprecate "at_least(0) with should_receive", :replacement => "stub" end self.inner_implementation_action = block set_expected_received_count :at_least, n self end # Constrain a message expectation to be received at most a specific # number of times. # # @example # # dealer.should_receive(:deal_card).at_most(10).times def at_most(n, &block) self.inner_implementation_action = block set_expected_received_count :at_most, n self end # Syntactic sugar for `exactly`, `at_least` and `at_most` # # @example # # dealer.should_receive(:deal_card).exactly(10).times # dealer.should_receive(:deal_card).at_least(10).times # dealer.should_receive(:deal_card).at_most(10).times def times(&block) self.inner_implementation_action = block self end # Allows an expected message to be received any number of times. def any_number_of_times(&block) RSpec.deprecate "any_number_of_times", :replacement => "stub" self.inner_implementation_action = block @expected_received_count = :any self end # Expect a message not to be received at all. # # @example # # car.should_receive(:stop).never def never ErrorGenerator.raise_double_negation_error("expect(obj)") if negative? @expected_received_count = 0 self end # Expect a message to be received exactly one time. # # @example # # car.should_receive(:go).once def once(&block) self.inner_implementation_action = block set_expected_received_count :exactly, 1 self end # Expect a message to be received exactly two times. # # @example # # car.should_receive(:go).twice def twice(&block) self.inner_implementation_action = block set_expected_received_count :exactly, 2 self end # Expect messages to be received in a specific order. # # @example # # api.should_receive(:prepare).ordered # api.should_receive(:run).ordered # api.should_receive(:finish).ordered def ordered(&block) self.inner_implementation_action = block @order_group.register(self) @ordered = true self end # @private def negative_expectation_for?(message) @message == message && negative? end # @private def actual_received_count_matters? @at_least || @at_most || @exactly end # @private def increase_actual_received_count! @actual_received_count += 1 end private def failed_fast? @failed_fast end def set_expected_received_count(relativity, n) @at_least = (relativity == :at_least) @at_most = (relativity == :at_most) @exactly = (relativity == :exactly) @expected_received_count = case n when Numeric then n when :once then 1 when :twice then 2 end end def initial_implementation_action=(action) implementation.initial_action = action end def inner_implementation_action=(action) implementation.inner_action = action if action end def terminal_implementation_action=(action) implementation.terminal_action = action end end # Handles the implementation of an `and_yield` declaration. # @private class AndYieldImplementation def initialize(args_to_yield, eval_context, error_generator) @args_to_yield = args_to_yield @eval_context = eval_context @error_generator = error_generator end def arity -1 end def call(*args_to_ignore, &block) return if @args_to_yield.empty? && @eval_context.nil? @error_generator.raise_missing_block_error @args_to_yield unless block value = nil @args_to_yield.each do |args| if block.arity > -1 && args.length != block.arity @error_generator.raise_wrong_arity_error args, block.arity end value = @eval_context ? @eval_context.instance_exec(*args, &block) : block.call(*args) end value end end # Handles the implementation of an `and_return` implementation. # @private class AndReturnImplementation def initialize(values_to_return) @values_to_return = values_to_return end def arity -1 end def call(*args_to_ignore, &block) if @values_to_return.size > 1 @values_to_return.shift else @values_to_return.first end end end # Represents a configured implementation. Takes into account # any number of sub-implementations. # @private class Implementation attr_accessor :initial_action, :inner_action, :terminal_action def call(*args, &block) actions.map do |action| action.call(*arg_slice_for(args, action.arity), &block) end.last end def arg_slice_for(args, arity) if arity >= 0 args.slice(0, arity) else args end end def present? actions.any? end private def actions [initial_action, inner_action, terminal_action].compact end end # Represents an `and_call_original` implementation. # @private class AndCallOriginalImplementation def initialize(method) @method = method end CannotModifyFurtherError = Class.new(StandardError) def arity @method.arity end def initial_action=(value) raise cannot_modify_further_error end def inner_action=(value) raise cannot_modify_further_error end def terminal_action=(value) raise cannot_modify_further_error end def present? true end def call(*args, &block) @method.call(*args, &block) end private def cannot_modify_further_error CannotModifyFurtherError.new "This method has already been configured " + "to call the original implementation, and cannot be modified further." end end end end rspec-mocks-2.14.3/lib/rspec/mocks/deprecation.rb0000644000004100000410000000074312202216237021700 0ustar www-datawww-datamodule RSpec module Mocks module Deprecation # @private # # Used internally to print deprecation warnings def deprecate(deprecated, options={}) message = "DEPRECATION: #{deprecated} is deprecated." message << " Use #{options[:replacement]} instead." if options[:replacement] message << " Called from #{caller(0)[2]}." warn message end end end extend(Mocks::Deprecation) unless respond_to?(:deprecate) end rspec-mocks-2.14.3/lib/rspec/mocks/mutate_const.rb0000644000004100000410000003125712202216237022114 0ustar www-datawww-datamodule RSpec module Mocks # Provides recursive constant lookup methods useful for # constant stubbing. # @api private module RecursiveConstMethods # We only want to consider constants that are defined directly on a # particular module, and not include top-level/inherited constants. # Unfortunately, the constant API changed between 1.8 and 1.9, so # we need to conditionally define methods to ignore the top-level/inherited # constants. # # Given: # class A; B = 1; end # class C < A; end # # On 1.8: # - C.const_get("Hash") # => ::Hash # - C.const_defined?("Hash") # => false # - C.constants # => ["B"] # - None of these methods accept the extra `inherit` argument # On 1.9: # - C.const_get("Hash") # => ::Hash # - C.const_defined?("Hash") # => true # - C.const_get("Hash", false) # => raises NameError # - C.const_defined?("Hash", false) # => false # - C.constants # => [:B] # - C.constants(false) #=> [] if Module.method(:const_defined?).arity == 1 def const_defined_on?(mod, const_name) mod.const_defined?(const_name) end def get_const_defined_on(mod, const_name) if const_defined_on?(mod, const_name) return mod.const_get(const_name) end raise NameError, "uninitialized constant #{mod.name}::#{const_name}" end def constants_defined_on(mod) mod.constants.select { |c| const_defined_on?(mod, c) } end else def const_defined_on?(mod, const_name) mod.const_defined?(const_name, false) end def get_const_defined_on(mod, const_name) mod.const_get(const_name, false) end def constants_defined_on(mod) mod.constants(false) end end def recursive_const_get(const_name) normalize_const_name(const_name).split('::').inject(Object) do |mod, name| get_const_defined_on(mod, name) end end def recursive_const_defined?(const_name) normalize_const_name(const_name).split('::').inject([Object, '']) do |(mod, full_name), name| yield(full_name, name) if block_given? && !mod.is_a?(Module) return false unless const_defined_on?(mod, name) [get_const_defined_on(mod, name), [mod, name].join('::')] end end def normalize_const_name(const_name) const_name.sub(/\A::/, '') end end # Provides information about constants that may (or may not) # have been mutated by rspec-mocks. class Constant extend RecursiveConstMethods # @api private def initialize(name) @name = name @previously_defined = false @stubbed = false @hidden = false end # @return [String] The fully qualified name of the constant. attr_reader :name # @return [Object, nil] The original value (e.g. before it # was mutated by rspec-mocks) of the constant, or # nil if the constant was not previously defined. attr_accessor :original_value # @api private attr_writer :previously_defined, :stubbed, :hidden # @return [Boolean] Whether or not the constant was defined # before the current example. def previously_defined? @previously_defined end # @return [Boolean] Whether or not rspec-mocks has mutated # (stubbed or hidden) this constant. def mutated? @stubbed || @hidden end # @return [Boolean] Whether or not rspec-mocks has stubbed # this constant. def stubbed? @stubbed end # @return [Boolean] Whether or not rspec-mocks has hidden # this constant. def hidden? @hidden end def to_s "#<#{self.class.name} #{name}>" end alias inspect to_s # @api private def self.unmutated(name) const = new(name) const.previously_defined = recursive_const_defined?(name) const.stubbed = false const.hidden = false const.original_value = recursive_const_get(name) if const.previously_defined? const end private_class_method :unmutated # Queries rspec-mocks to find out information about the named constant. # # @param [String] name the name of the constant # @return [Constant] an object contaning information about the named # constant. def self.original(name) mutator = ConstantMutator.find(name) mutator ? mutator.to_constant : unmutated(name) end end # Provides a means to stub constants. class ConstantMutator extend RecursiveConstMethods # Stubs a constant. # # @param (see ExampleMethods#stub_const) # @option (see ExampleMethods#stub_const) # @return (see ExampleMethods#stub_const) # # @see ExampleMethods#stub_const # @note It's recommended that you use `stub_const` in your # examples. This is an alternate public API that is provided # so you can stub constants in other contexts (e.g. helper # classes). def self.stub(constant_name, value, options = {}) mutator = if recursive_const_defined?(constant_name, &raise_on_invalid_const) DefinedConstantReplacer else UndefinedConstantSetter end mutate(mutator.new(constant_name, value, options[:transfer_nested_constants])) value end # Hides a constant. # # @param (see ExampleMethods#hide_const) # # @see ExampleMethods#hide_const # @note It's recommended that you use `hide_const` in your # examples. This is an alternate public API that is provided # so you can hide constants in other contexts (e.g. helper # classes). def self.hide(constant_name) return unless recursive_const_defined?(constant_name) mutate(ConstantHider.new(constant_name, nil, { })) nil end # Contains common functionality used by all of the constant mutators. # # @api private class BaseMutator include RecursiveConstMethods attr_reader :original_value, :full_constant_name def initialize(full_constant_name, mutated_value, transfer_nested_constants) @full_constant_name = normalize_const_name(full_constant_name) @mutated_value = mutated_value @transfer_nested_constants = transfer_nested_constants @context_parts = @full_constant_name.split('::') @const_name = @context_parts.pop end def to_constant const = Constant.new(full_constant_name) const.original_value = original_value const end end # Hides a defined constant for the duration of an example. # # @api private class ConstantHider < BaseMutator def mutate @context = recursive_const_get(@context_parts.join('::')) @original_value = get_const_defined_on(@context, @const_name) @context.__send__(:remove_const, @const_name) end def to_constant const = super const.hidden = true const.previously_defined = true const end def rspec_reset @context.const_set(@const_name, @original_value) end end # Replaces a defined constant for the duration of an example. # # @api private class DefinedConstantReplacer < BaseMutator def mutate @context = recursive_const_get(@context_parts.join('::')) @original_value = get_const_defined_on(@context, @const_name) constants_to_transfer = verify_constants_to_transfer! @context.__send__(:remove_const, @const_name) @context.const_set(@const_name, @mutated_value) transfer_nested_constants(constants_to_transfer) end def to_constant const = super const.stubbed = true const.previously_defined = true const end def rspec_reset @context.__send__(:remove_const, @const_name) @context.const_set(@const_name, @original_value) end def transfer_nested_constants(constants) constants.each do |const| @mutated_value.const_set(const, get_const_defined_on(original_value, const)) end end def verify_constants_to_transfer! return [] unless @transfer_nested_constants { @original_value => "the original value", @mutated_value => "the stubbed value" }.each do |value, description| unless value.respond_to?(:constants) raise ArgumentError, "Cannot transfer nested constants for #{@full_constant_name} " + "since #{description} is not a class or module and only classes " + "and modules support nested constants." end end if @transfer_nested_constants.is_a?(Array) @transfer_nested_constants = @transfer_nested_constants.map(&:to_s) if RUBY_VERSION == '1.8.7' undefined_constants = @transfer_nested_constants - constants_defined_on(@original_value) if undefined_constants.any? available_constants = constants_defined_on(@original_value) - @transfer_nested_constants raise ArgumentError, "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " + "for #{@full_constant_name} since they are not defined. Did you mean " + "#{available_constants.join(' or ')}?" end @transfer_nested_constants else constants_defined_on(@original_value) end end end # Sets an undefined constant for the duration of an example. # # @api private class UndefinedConstantSetter < BaseMutator def mutate remaining_parts = @context_parts.dup @deepest_defined_const = @context_parts.inject(Object) do |klass, name| break klass unless const_defined_on?(klass, name) remaining_parts.shift get_const_defined_on(klass, name) end context = remaining_parts.inject(@deepest_defined_const) do |klass, name| klass.const_set(name, Module.new) end @const_to_remove = remaining_parts.first || @const_name context.const_set(@const_name, @mutated_value) end def to_constant const = super const.stubbed = true const.previously_defined = false const end def rspec_reset @deepest_defined_const.__send__(:remove_const, @const_to_remove) end end # Uses the mutator to mutate (stub or hide) a constant. Ensures that # the mutator is correctly registered so it can be backed out at the end # of the test. # # @api private def self.mutate(mutator) register_mutator(mutator) mutator.mutate end # Resets all stubbed constants. This is called automatically # by rspec-mocks when an example finishes. # # @api private def self.reset_all # We use reverse order so that if the same constant # was stubbed multiple times, the original value gets # properly restored. mutators.reverse.each { |s| s.rspec_reset } mutators.clear end # The list of constant mutators that have been used for # the current example. # # @api private def self.mutators @mutators ||= [] end # @api private def self.register_mutator(mutator) mutators << mutator end def self.find(name) mutators.find { |s| s.full_constant_name == name } end # Used internally by the constant stubbing to raise a helpful # error when a constant like "A::B::C" is stubbed and A::B is # not a module (and thus, it's impossible to define "A::B::C" # since only modules can have nested constants). # # @api private def self.raise_on_invalid_const lambda do |const_name, failed_name| raise "Cannot stub constant #{failed_name} on #{const_name} " + "since #{const_name} is not a module." end end end # Keeps backwards compatibility since we had released an rspec-mocks that # only supported stubbing. Later, we released the hide_const feature and # decided that the term "mutator" was a better term to wrap up the concept # of both stubbing and hiding. ConstantStubber = ConstantMutator end end rspec-mocks-2.14.3/lib/rspec/mocks/any_instance/0000755000004100000410000000000012202216237021525 5ustar www-datawww-datarspec-mocks-2.14.3/lib/rspec/mocks/any_instance/stub_chain_chain.rb0000644000004100000410000000077112202216237025340 0ustar www-datawww-datamodule RSpec module Mocks module AnyInstance # @private class StubChainChain < StubChain private def create_message_expectation_on(instance) ::RSpec::Mocks::StubChain.stub_chain_on(instance, *@expectation_args, &@expectation_block) end def invocation_order @invocation_order ||= { :and_return => [nil], :and_raise => [nil], :and_yield => [nil] } end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/any_instance/expectation_chain.rb0000644000004100000410000000202512202216237025536 0ustar www-datawww-datamodule RSpec module Mocks module AnyInstance # @api private class ExpectationChain < Chain def expectation_fulfilled? @expectation_fulfilled || constrained_to_any_of?(:never, :any_number_of_times) end def initialize(*args, &block) @expectation_fulfilled = false super end private def verify_invocation_order(rspec_method_name, *args, &block) end end # @api private class PositiveExpectationChain < ExpectationChain private def create_message_expectation_on(instance) proxy = ::RSpec::Mocks.proxy_for(instance) expected_from = IGNORED_BACKTRACE_LINE proxy.add_message_expectation(expected_from, *@expectation_args, &@expectation_block) end def invocation_order @invocation_order ||= { :with => [nil], :and_return => [:with, nil], :and_raise => [:with, nil] } end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/any_instance/chain.rb0000644000004100000410000000467412202216237023147 0ustar www-datawww-datamodule RSpec module Mocks module AnyInstance class Chain def initialize(*args, &block) @expectation_args = args @expectation_block = block end module Customizations # @macro [attach] record # @method $1(*args, &block) # Records the `$1` message for playback against an instance that # invokes a method stubbed or mocked using `any_instance`. # # @see RSpec::Mocks::MessageExpectation#$1 # def self.record(method_name) class_eval(<<-EOM, __FILE__, __LINE__ + 1) def #{method_name}(*args, &block) record(:#{method_name}, *args, &block) end EOM end record :and_return record :and_raise record :and_throw record :and_yield record :and_call_original record :with record :once record :twice record :any_number_of_times record :exactly record :times record :never record :at_least record :at_most end include Customizations # @private def playback!(instance) message_expectation = create_message_expectation_on(instance) messages.inject(message_expectation) do |object, message| object.__send__(*message.first, &message.last) end end # @private def constrained_to_any_of?(*constraints) constraints.any? do |constraint| messages.any? do |message| message.first.first == constraint end end end # @private def expectation_fulfilled! @expectation_fulfilled = true end def never ErrorGenerator.raise_double_negation_error("expect_any_instance_of(MyClass)") if negated? super end private def negated? messages.any? { |(message, *_), _| message.to_sym == :never } end def messages @messages ||= [] end def last_message messages.last.first.first unless messages.empty? end def record(rspec_method_name, *args, &block) verify_invocation_order(rspec_method_name, *args, &block) messages << [args.unshift(rspec_method_name), block] self end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/any_instance/message_chains.rb0000644000004100000410000000347512202216237025034 0ustar www-datawww-datamodule RSpec module Mocks module AnyInstance # @private class MessageChains < Hash def initialize super {|h,k| h[k] = []} end # @private def add(method_name, chain) self[method_name] << chain chain end # @private def remove_stub_chains_for!(method_name) self[method_name].reject! {|chain| chain.is_a?(StubChain)} end # @private def has_expectation?(method_name) self[method_name].find {|chain| chain.is_a?(ExpectationChain)} end # @private def all_expectations_fulfilled? all? {|method_name, chains| chains.all? {|chain| chain.expectation_fulfilled?}} end # @private def unfulfilled_expectations map do |method_name, chains| method_name.to_s if chains.last.is_a?(ExpectationChain) unless chains.last.expectation_fulfilled? end.compact end # @private def received_expected_message!(method_name) self[method_name].each {|chain| chain.expectation_fulfilled!} end # @private def playback!(instance, method_name) raise_if_second_instance_to_receive_message(instance) self[method_name].each {|chain| chain.playback!(instance)} end private def raise_if_second_instance_to_receive_message(instance) @instance_with_expectation ||= instance if instance.is_a?(ExpectationChain) if instance.is_a?(ExpectationChain) && !@instance_with_expectation.equal?(instance) raise RSpec::Mocks::MockExpectationError, "Exactly one instance should have received the following message(s) but didn't: #{unfulfilled_expectations.sort.join(', ')}" end end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/any_instance/stub_chain.rb0000644000004100000410000000175412202216237024200 0ustar www-datawww-datamodule RSpec module Mocks module AnyInstance # @private class StubChain < Chain # @private def expectation_fulfilled? true end private def create_message_expectation_on(instance) proxy = ::RSpec::Mocks.proxy_for(instance) expected_from = IGNORED_BACKTRACE_LINE proxy.add_stub(expected_from, *@expectation_args, &@expectation_block) end def invocation_order @invocation_order ||= { :with => [nil], :and_return => [:with, nil], :and_raise => [:with, nil], :and_yield => [:with, nil], :and_call_original => [:with, nil] } end def verify_invocation_order(rspec_method_name, *args, &block) unless invocation_order[rspec_method_name].include?(last_message) raise(NoMethodError, "Undefined method #{rspec_method_name}") end end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/any_instance/recorder.rb0000644000004100000410000001656212202216237023671 0ustar www-datawww-datamodule RSpec module Mocks module AnyInstance # Given a class `TheClass`, `TheClass.any_instance` returns a `Recorder`, # which records stubs and message expectations for later playback on # instances of `TheClass`. # # Further constraints are stored in instances of [Chain](Chain). # # @see AnyInstance # @see Chain class Recorder # @private attr_reader :message_chains def initialize(klass) @message_chains = MessageChains.new @observed_methods = [] @played_methods = {} @klass = klass @expectation_set = false end # Initializes the recording a stub to be played back against any # instance of this object that invokes the submitted method. # # @see Methods#stub def stub(method_name_or_method_map, &block) if method_name_or_method_map.is_a?(Hash) method_name_or_method_map.each do |method_name, return_value| stub(method_name).and_return(return_value) end else observe!(method_name_or_method_map) message_chains.add(method_name_or_method_map, StubChain.new(method_name_or_method_map, &block)) end end # Initializes the recording a stub chain to be played back against any # instance of this object that invokes the method matching the first # argument. # # @see Methods#stub_chain def stub_chain(*method_names_and_optional_return_values, &block) normalize_chain(*method_names_and_optional_return_values) do |method_name, args| observe!(method_name) message_chains.add(method_name, StubChainChain.new(*args, &block)) end end # Initializes the recording a message expectation to be played back # against any instance of this object that invokes the submitted # method. # # @see Methods#should_receive def should_receive(method_name, &block) @expectation_set = true observe!(method_name) message_chains.add(method_name, PositiveExpectationChain.new(method_name, &block)) end def should_not_receive(method_name, &block) should_receive(method_name, &block).never end # Removes any previously recorded stubs, stub_chains or message # expectations that use `method_name`. # # @see Methods#unstub def unstub(method_name) unless @observed_methods.include?(method_name.to_sym) raise RSpec::Mocks::MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed" end message_chains.remove_stub_chains_for!(method_name) stop_observing!(method_name) unless message_chains.has_expectation?(method_name) end # @api private # # Used internally to verify that message expectations have been # fulfilled. def verify if @expectation_set && !message_chains.all_expectations_fulfilled? raise RSpec::Mocks::MockExpectationError, "Exactly one instance should have received the following message(s) but didn't: #{message_chains.unfulfilled_expectations.sort.join(', ')}" end ensure stop_all_observation! ::RSpec::Mocks.space.remove_any_instance_recorder_for(@klass) end # @private def stub!(*) raise "stub! is not supported on any_instance. Use stub instead." end # @private def unstub!(*) raise "unstub! is not supported on any_instance. Use unstub instead." end # @private def stop_all_observation! @observed_methods.each {|method_name| restore_method!(method_name)} end # @private def playback!(instance, method_name) RSpec::Mocks.space.ensure_registered(instance) message_chains.playback!(instance, method_name) @played_methods[method_name] = instance received_expected_message!(method_name) if message_chains.has_expectation?(method_name) end # @private def instance_that_received(method_name) @played_methods[method_name] end def build_alias_method_name(method_name) "__#{method_name}_without_any_instance__" end def already_observing?(method_name) @observed_methods.include?(method_name) end private def normalize_chain(*args) args.shift.to_s.split('.').map {|s| s.to_sym}.reverse.each {|a| args.unshift a} yield args.first, args end def received_expected_message!(method_name) message_chains.received_expected_message!(method_name) restore_method!(method_name) mark_invoked!(method_name) end def restore_method!(method_name) if public_protected_or_private_method_defined?(build_alias_method_name(method_name)) restore_original_method!(method_name) else remove_dummy_method!(method_name) end end def restore_original_method!(method_name) alias_method_name = build_alias_method_name(method_name) @klass.class_eval do remove_method method_name alias_method method_name, alias_method_name remove_method alias_method_name end end def remove_dummy_method!(method_name) @klass.class_eval do remove_method method_name end end def backup_method!(method_name) alias_method_name = build_alias_method_name(method_name) @klass.class_eval do alias_method alias_method_name, method_name end if public_protected_or_private_method_defined?(method_name) end def public_protected_or_private_method_defined?(method_name) @klass.method_defined?(method_name) || @klass.private_method_defined?(method_name) end def stop_observing!(method_name) restore_method!(method_name) @observed_methods.delete(method_name) end def observe!(method_name) stop_observing!(method_name) if already_observing?(method_name) @observed_methods << method_name backup_method!(method_name) @klass.class_eval(<<-EOM, __FILE__, __LINE__ + 1) def #{method_name}(*args, &blk) klass = ::RSpec::Mocks.method_handle_for(self, :#{method_name}).owner ::RSpec::Mocks.any_instance_recorder_for(klass).playback!(self, :#{method_name}) self.__send__(:#{method_name}, *args, &blk) end EOM end def mark_invoked!(method_name) backup_method!(method_name) @klass.class_eval(<<-EOM, __FILE__, __LINE__ + 1) def #{method_name}(*args, &blk) method_name = :#{method_name} klass = ::RSpec::Mocks.method_handle_for(self, :#{method_name}).owner invoked_instance = ::RSpec::Mocks.any_instance_recorder_for(klass).instance_that_received(method_name) raise RSpec::Mocks::MockExpectationError, "The message '#{method_name}' was received by \#{self.inspect} but has already been received by \#{invoked_instance}" end EOM end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/argument_list_matcher.rb0000644000004100000410000000606412202216237023765 0ustar www-datawww-datarequire 'rspec/mocks/argument_matchers' module RSpec module Mocks # Wrapper for matching arguments against a list of expected values. Used by # the `with` method on a `MessageExpectation`: # # object.should_receive(:message).with(:a, 'b', 3) # object.message(:a, 'b', 3) # # Values passed to `with` can be literal values or argument matchers that # match against the real objects .e.g. # # object.should_receive(:message).with(hash_including(:a => 'b')) # # Can also be used directly to match the contents of any `Array`. This # enables 3rd party mocking libs to take advantage of rspec's argument # matching without using the rest of rspec-mocks. # # require 'rspec/mocks/argument_list_matcher' # include RSpec::Mocks::ArgumentMatchers # # arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b')) # arg_list_matcher.args_match?(123, :a => 'b') # # @see ArgumentMatchers class ArgumentListMatcher # @private attr_reader :expected_args # @api public # @param [Array] *expected_args a list of expected literals and/or argument matchers # @param [Block] block a block with arity matching the expected # # Initializes an `ArgumentListMatcher` with a collection of literal # values and/or argument matchers, or a block that handles the evaluation # for you. # # @see ArgumentMatchers # @see #args_match? def initialize(*expected_args, &block) @expected_args = expected_args @block = expected_args.empty? ? block : nil @match_any_args = false @matchers = nil case expected_args.first when ArgumentMatchers::AnyArgsMatcher @match_any_args = true when ArgumentMatchers::NoArgsMatcher @matchers = [] else @matchers = expected_args.collect {|arg| matcher_for(arg)} end end # @api public # @param [Array] *args # # Matches each element in the `expected_args` against the element in the same # position of the arguments passed to `new`. # # @see #initialize def args_match?(*args) match_any_args? || block_passes?(*args) || matchers_match?(*args) end private def matcher_for(arg) return ArgumentMatchers::MatcherMatcher.new(arg) if is_matcher?(arg) return ArgumentMatchers::RegexpMatcher.new(arg) if arg.is_a?(Regexp) return ArgumentMatchers::EqualityProxy.new(arg) end def is_matcher?(object) return false if object.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher) [:failure_message_for_should, :failure_message].any? do |msg| object.respond_to?(msg) end && object.respond_to?(:matches?) end def block_passes?(*args) @block.call(*args) if @block end def matchers_match?(*args) @matchers == args end def match_any_args? @match_any_args end end end end rspec-mocks-2.14.3/lib/rspec/mocks/syntax.rb0000644000004100000410000002767612202216237020747 0ustar www-datawww-datamodule RSpec module Mocks # @api private # Provides methods for enabling and disabling the available syntaxes # provided by rspec-mocks. module Syntax # @api private # # Common stubbing logic for both `stub` and `stub!`. This used to # live in `stub`, and `stub!` delegated to `stub`, but we discovered # that `stub!` was delegating to `RSpec::Mocks::ExampleMethods#stub` # (which declares a test double) when called with an implicit receiver, # which was a regression in 2.14.0. def self.stub_object(object, message_or_hash, opts = {}, &block) if ::Hash === message_or_hash message_or_hash.each {|message, value| stub_object(object, message).and_return value } else opts[:expected_from] = caller(1)[1] ::RSpec::Mocks.allow_message(object, message_or_hash, opts, &block) end end # @api private # Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). def self.enable_should(syntax_host = default_should_syntax_host) return if should_enabled?(syntax_host) syntax_host.class_eval do def should_receive(message, opts={}, &block) opts[:expected_from] ||= caller(1)[0] ::RSpec::Mocks.expect_message(self, message.to_sym, opts, &block) end def should_not_receive(message, &block) opts = {:expected_from => caller(1)[0]} ::RSpec::Mocks.expect_message(self, message.to_sym, opts, &block).never end def stub(message_or_hash, opts={}, &block) ::RSpec::Mocks::Syntax.stub_object(self, message_or_hash, opts, &block) end def unstub(message) ::RSpec::Mocks.space.proxy_for(self).remove_stub(message) end def stub!(message_or_hash, opts={}, &block) ::RSpec.deprecate "stub!", :replacement => "stub" ::RSpec::Mocks::Syntax.stub_object(self, message_or_hash, opts, &block) end def unstub!(message) ::RSpec.deprecate "unstub!", :replacement => "unstub" unstub(message) end def stub_chain(*chain, &blk) ::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk) end def as_null_object @_null_object = true ::RSpec::Mocks.proxy_for(self).as_null_object end def null_object? defined?(@_null_object) end def received_message?(message, *args, &block) ::RSpec::Mocks.proxy_for(self).received_message?(message, *args, &block) end unless Class.respond_to? :any_instance Class.class_eval do def any_instance ::RSpec::Mocks.any_instance_recorder_for(self) end end end end end # @api private # Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). def self.disable_should(syntax_host = default_should_syntax_host) return unless should_enabled?(syntax_host) syntax_host.class_eval do undef should_receive undef should_not_receive undef stub undef unstub undef stub! undef unstub! undef stub_chain undef as_null_object undef null_object? undef received_message? end Class.class_eval do undef any_instance end end # @api private # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). def self.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods) return if expect_enabled?(syntax_host) syntax_host.class_eval do def receive(method_name, &block) Matchers::Receive.new(method_name, block) end def allow(target) AllowanceTarget.new(target) end def expect_any_instance_of(klass) AnyInstanceExpectationTarget.new(klass) end def allow_any_instance_of(klass) AnyInstanceAllowanceTarget.new(klass) end end RSpec::Mocks::ExampleMethods::ExpectHost.class_eval do def expect(target) ExpectationTarget.new(target) end end end # @api private # Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). def self.disable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods) return unless expect_enabled?(syntax_host) syntax_host.class_eval do undef receive undef allow undef expect_any_instance_of undef allow_any_instance_of end RSpec::Mocks::ExampleMethods::ExpectHost.class_eval do undef expect end end # @api private # Indicates whether or not the should syntax is enabled. def self.should_enabled?(syntax_host = default_should_syntax_host) syntax_host.method_defined?(:should_receive) end # @api private # Indicates whether or not the expect syntax is enabled. def self.expect_enabled?(syntax_host = ::RSpec::Mocks::ExampleMethods) syntax_host.method_defined?(:allow) end # @api private # Determines where the methods like `should_receive`, and `stub` are added. def self.default_should_syntax_host # JRuby 1.7.4 introduces a regression whereby `defined?(::BasicObject) => nil` # yet `BasicObject` still exists and patching onto ::Object breaks things # e.g. SimpleDelegator expectations won't work # # See: https://github.com/jruby/jruby/issues/814 if defined?(JRUBY_VERSION) && JRUBY_VERSION == '1.7.4' && RUBY_VERSION.to_f > 1.8 return ::BasicObject end # On 1.8.7, Object.ancestors.last == Kernel but # things blow up if we include `RSpec::Mocks::Methods` # into Kernel...not sure why. return Object unless defined?(::BasicObject) # MacRuby has BasicObject but it's not the root class. return Object unless Object.ancestors.last == ::BasicObject ::BasicObject end # @method should_receive # Sets an expectation that this object should receive a message before # the end of the example. # # @example # # logger = double('logger') # thing_that_logs = ThingThatLogs.new(logger) # logger.should_receive(:log) # thing_that_logs.do_something_that_logs_a_message # # @note This is only available when you have enabled the `should` syntax. # @method should_not_receive # Sets and expectation that this object should _not_ receive a message # during this example. # @method stub # Tells the object to respond to the message with the specified value. # # @example # # counter.stub(:count).and_return(37) # counter.stub(:count => 37) # counter.stub(:count) { 37 } # # @note This is only available when you have enabled the `should` syntax. # @method unstub # Removes a stub. On a double, the object will no longer respond to # `message`. On a real object, the original method (if it exists) is # restored. # # This is rarely used, but can be useful when a stub is set up during a # shared `before` hook for the common case, but you want to replace it # for a special case. # # @note This is only available when you have enabled the `should` syntax. # @method stub_chain # @overload stub_chain(method1, method2) # @overload stub_chain("method1.method2") # @overload stub_chain(method1, method_to_value_hash) # # Stubs a chain of methods. # # ## Warning: # # Chains can be arbitrarily long, which makes it quite painless to # violate the Law of Demeter in violent ways, so you should consider any # use of `stub_chain` a code smell. Even though not all code smells # indicate real problems (think fluent interfaces), `stub_chain` still # results in brittle examples. For example, if you write # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the # implementation calls `foo.baz.bar`, the stub will not work. # # @example # # double.stub_chain("foo.bar") { :baz } # double.stub_chain(:foo, :bar => :baz) # double.stub_chain(:foo, :bar) { :baz } # # # Given any of ^^ these three forms ^^: # double.foo.bar # => :baz # # # Common use in Rails/ActiveRecord: # Article.stub_chain("recent.published") { [Article.new] } # # @note This is only available when you have enabled the `should` syntax. # @method as_null_object # Tells the object to respond to all messages. If specific stub values # are declared, they'll work as expected. If not, the receiver is # returned. # # @note This is only available when you have enabled the `should` syntax. # @method null_object? # Returns true if this object has received `as_null_object` # # @note This is only available when you have enabled the `should` syntax. # @method any_instance # Used to set stubs and message expectations on any instance of a given # class. Returns a [Recorder](Recorder), which records messages like # `stub` and `should_receive` for later playback on instances of the # class. # # @example # # Car.any_instance.should_receive(:go) # race = Race.new # race.cars << Car.new # race.go # assuming this delegates to all of its cars # # this example would pass # # Account.any_instance.stub(:balance) { Money.new(:USD, 25) } # Account.new.balance # => Money.new(:USD, 25)) # # @return [Recorder] # # @note This is only available when you have enabled the `should` syntax. # @method expect # Used to wrap an object in preparation for setting a mock expectation # on it. # # @example # # expect(obj).to receive(:foo).with(5).and_return(:return_value) # # @note This method is usually provided by rspec-expectations, unless # you are using rspec-mocks w/o rspec-expectations, in which case it # is only made available if you enable the `expect` syntax. # @method allow # Used to wrap an object in preparation for stubbing a method # on it. # # @example # # allow(dbl).to receive(:foo).with(5).and_return(:return_value) # # @note This is only available when you have enabled the `expect` syntax. # @method expect_any_instance_of # Used to wrap a class in preparation for setting a mock expectation # on instances of it. # # @example # # expect_any_instance_of(MyClass).to receive(:foo) # # @note This is only available when you have enabled the `expect` syntax. # @method allow_any_instance_of # Used to wrap a class in preparation for stubbing a method # on instances of it. # # @example # # allow_any_instance_of(MyClass).to receive(:foo) # # @note This is only available when you have enabled the `expect` syntax. # @method receive # Used to specify a message that you expect or allow an object # to receive. The object returned by `receive` supports the same # fluent interface that `should_receive` and `stub` have always # supported, allowing you to constrain the arguments or number of # times, and configure how the object should respond to the message. # # @example # # expect(obj).to receive(:hello).with("world").exactly(3).times # # @note This is only available when you have enabled the `expect` syntax. end end end rspec-mocks-2.14.3/lib/rspec/mocks/order_group.rb0000644000004100000410000000133712202216237021732 0ustar www-datawww-datamodule RSpec module Mocks # @private class OrderGroup def initialize @ordering = Array.new end # @private def register(expectation) @ordering << expectation end # @private def ready_for?(expectation) @ordering.first == expectation end # @private def consume @ordering.shift end # @private def handle_order_constraint(expectation) return unless @ordering.include?(expectation) return consume if ready_for?(expectation) expectation.raise_out_of_order_error end def clear @ordering.clear end def empty? @ordering.empty? end end end end rspec-mocks-2.14.3/lib/rspec/mocks/framework.rb0000644000004100000410000000246112202216237021377 0ustar www-datawww-data# Require everything except the global extensions of class and object. This # supports wrapping rspec's mocking functionality without invading every # object in the system. require 'rspec/mocks/deprecation' require 'rspec/mocks/extensions/instance_exec' require 'rspec/mocks/instance_method_stasher' require 'rspec/mocks/method_double' require 'rspec/mocks/argument_matchers' require 'rspec/mocks/example_methods' require 'rspec/mocks/proxy' require 'rspec/mocks/proxy_for_nil' require 'rspec/mocks/test_double' require 'rspec/mocks/mock' require 'rspec/mocks/argument_list_matcher' require 'rspec/mocks/message_expectation' require 'rspec/mocks/order_group' require 'rspec/mocks/errors' require 'rspec/mocks/error_generator' require 'rspec/mocks/space' require 'rspec/mocks/extensions/marshal' require 'rspec/mocks/any_instance/chain' require 'rspec/mocks/any_instance/stub_chain' require 'rspec/mocks/any_instance/stub_chain_chain' require 'rspec/mocks/any_instance/expectation_chain' require 'rspec/mocks/any_instance/message_chains' require 'rspec/mocks/any_instance/recorder' require 'rspec/mocks/mutate_const' require 'rspec/mocks/matchers/have_received' require 'rspec/mocks/matchers/receive' require 'rspec/mocks/stub_chain' require 'rspec/mocks/targets' require 'rspec/mocks/syntax' require 'rspec/mocks/configuration' rspec-mocks-2.14.3/lib/rspec/mocks/matchers/0000755000004100000410000000000012202216237020660 5ustar www-datawww-datarspec-mocks-2.14.3/lib/rspec/mocks/matchers/have_received.rb0000644000004100000410000000445612202216237024007 0ustar www-datawww-datamodule RSpec module Mocks module Matchers class HaveReceived COUNT_CONSTRAINTS = %w(exactly at_least at_most times once twice) ARGS_CONSTRAINTS = %w(with) CONSTRAINTS = COUNT_CONSTRAINTS + ARGS_CONSTRAINTS def initialize(method_name) @method_name = method_name @constraints = [] @subject = nil end def matches?(subject) @subject = subject @expectation = expect expected_messages_received? end def does_not_match?(subject) @subject = subject ensure_count_unconstrained @expectation = expect.never expected_messages_received? end def failure_message generate_failure_message end def negative_failure_message generate_failure_message end def description expect.description end CONSTRAINTS.each do |expectation| define_method expectation do |*args| @constraints << [expectation, *args] self end end private def expect expectation = mock_proxy.build_expectation(@method_name) apply_constraints_to expectation expectation end def apply_constraints_to(expectation) @constraints.each do |constraint| expectation.send(*constraint) end end def ensure_count_unconstrained if count_constraint raise RSpec::Mocks::MockExpectationError, "can't use #{count_constraint} when negative" end end def count_constraint @constraints.map(&:first).detect do |constraint| COUNT_CONSTRAINTS.include?(constraint) end end def generate_failure_message mock_proxy.check_for_unexpected_arguments(@expectation) @expectation.generate_error rescue RSpec::Mocks::MockExpectationError => error error.message end def expected_messages_received? mock_proxy.replay_received_message_on @expectation @expectation.expected_messages_received? end def mock_proxy RSpec::Mocks.proxy_for(@subject) end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/matchers/receive.rb0000644000004100000410000000637012202216237022635 0ustar www-datawww-datamodule RSpec module Mocks module Matchers class Receive def initialize(message, block) @message = message @block = block @recorded_customizations = [] # MRI, JRuby and RBX report the caller inconsistently; MRI # reports an extra "in `new'" line in the backtrace that the # others do not include. The safest way to find the right # line is to search for the first line BEFORE rspec/mocks/syntax.rb. @backtrace_line = caller.find do |line| !line.split(':').first.end_with?('rspec/mocks/syntax.rb') end end def setup_expectation(subject, &block) setup_mock_proxy_method_substitute(subject, :add_message_expectation, block) end alias matches? setup_expectation def setup_negative_expectation(subject, &block) # ensure `never` goes first for cases like `never.and_return(5)`, # where `and_return` is meant to raise an error @recorded_customizations.unshift Customization.new(:never, [], nil) setup_expectation(subject, &block) end alias does_not_match? setup_negative_expectation def setup_allowance(subject, &block) setup_mock_proxy_method_substitute(subject, :add_stub, block) end def setup_any_instance_expectation(subject, &block) setup_any_instance_method_substitute(subject, :should_receive, block) end def setup_any_instance_negative_expectation(subject, &block) setup_any_instance_method_substitute(subject, :should_not_receive, block) end def setup_any_instance_allowance(subject, &block) setup_any_instance_method_substitute(subject, :stub, block) end MessageExpectation.public_instance_methods(false).each do |method| next if method_defined?(method) class_eval(<<-RUBY) def #{method}(*args, &block) @recorded_customizations << Customization.new(#{method.inspect}, args, block) self end RUBY end private def setup_mock_proxy_method_substitute(subject, method, block) proxy = ::RSpec::Mocks.proxy_for(subject) setup_method_substitute(proxy, method, block, @backtrace_line) end def setup_any_instance_method_substitute(subject, method, block) any_instance_recorder = ::RSpec::Mocks.any_instance_recorder_for(subject) setup_method_substitute(any_instance_recorder, method, block) end def setup_method_substitute(host, method, block, *args) args << @message.to_sym expectation = host.__send__(method, *args, &(@block || block)) @recorded_customizations.each do |customization| customization.playback_onto(expectation) end end class Customization def initialize(method_name, args, block) @method_name = method_name @args = args @block = block end def playback_onto(expectation) expectation.__send__(@method_name, *@args, &@block) end end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/error_generator.rb0000644000004100000410000001445312202216237022605 0ustar www-datawww-datamodule RSpec module Mocks # @private class ErrorGenerator attr_writer :opts def initialize(target, name, options={}) @declared_as = options[:__declared_as] || 'Mock' @target = target @name = name end # @private def opts @opts ||= {} end # @private def raise_unexpected_message_error(message, *args) __raise "#{intro} received unexpected message :#{message}#{arg_message(*args)}" end # @private def raise_unexpected_message_args_error(expectation, *args) expected_args = format_args(*expectation.expected_args) actual_args = format_received_args(*args) __raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}" end # @private def raise_missing_default_stub_error(expectation, *args) expected_args = format_args(*expectation.expected_args) actual_args = format_received_args(*args) __raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}\n Please stub a default value first if message might be received with other args as well. \n" end # @private def raise_similar_message_args_error(expectation, *args_for_multiple_calls) expected_args = format_args(*expectation.expected_args) actual_args = args_for_multiple_calls.collect {|a| format_received_args(*a)}.join(", ") __raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}" end # @private def raise_expectation_error(message, expected_received_count, argument_list_matcher, actual_received_count, expectation_count_type, *args) expected_part = expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) received_part = received_part_of_expectation_error(actual_received_count, *args) __raise "(#{intro}).#{message}#{format_args(*args)}\n #{expected_part}\n #{received_part}" end # @private def received_part_of_expectation_error(actual_received_count, *args) "received: #{count_message(actual_received_count)}" + method_call_args_description(args) end # @private def expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) "expected: #{count_message(expected_received_count, expectation_count_type)}" + method_call_args_description(argument_list_matcher.expected_args) end # @private def method_call_args_description(args) if args.first.is_a?(ArgumentMatchers::AnyArgsMatcher) " with any arguments" elsif args.first.is_a?(ArgumentMatchers::NoArgsMatcher) " with no arguments" elsif args.length > 0 " with arguments: #{args.inspect.gsub(/\A\[(.+)\]\z/, '(\1)')}" else "" end end # @private def describe_expectation(message, expected_received_count, actual_received_count, *args) "have received #{message}#{format_args(*args)} #{count_message(expected_received_count)}" end # @private def raise_out_of_order_error(message) __raise "#{intro} received :#{message} out of order" end # @private def raise_block_failed_error(message, detail) __raise "#{intro} received :#{message} but passed block failed with: #{detail}" end # @private def raise_missing_block_error(args_to_yield) __raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed" end # @private def raise_wrong_arity_error(args_to_yield, arity) __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}" end # @private def raise_only_valid_on_a_partial_mock(method) __raise "#{intro} is a pure mock object. `#{method}` is only " + "available on a partial mock object." end # @private def raise_expectation_on_unstubbed_method(method) __raise "#{intro} expected to have received #{method}, but that " + "method has not been stubbed." end # @private def raise_expectation_on_mocked_method(method) __raise "#{intro} expected to have received #{method}, but that " + "method has been mocked instead of stubbed." end def self.raise_double_negation_error(wrapped_expression) raise "Isn't life confusing enough? You've already set a " + "negative message expectation and now you are trying to " + "negate it again with `never`. What does an expression like " + "`#{wrapped_expression}.not_to receive(:msg).never` even mean?" end private def intro if @name "#{@declared_as} #{@name.inspect}" elsif TestDouble === @target @declared_as elsif Class === @target "<#{@target.inspect} (class)>" elsif @target @target else "nil" end end def __raise(message) message = opts[:message] unless opts[:message].nil? Kernel::raise(RSpec::Mocks::MockExpectationError, message) end def arg_message(*args) " with " + format_args(*args) end def format_args(*args) args.empty? ? "(no args)" : "(" + arg_list(*args) + ")" end def arg_list(*args) args.collect {|arg| arg.respond_to?(:description) ? arg.description : arg.inspect}.join(", ") end def format_received_args(*args) args.empty? ? "(no args)" : "(" + received_arg_list(*args) + ")" end def received_arg_list(*args) args.collect(&:inspect).join(", ") end def count_message(count, expectation_count_type=nil) return "at least #{pretty_print(count.abs)}" if count < 0 || expectation_count_type == :at_least return "at most #{pretty_print(count)}" if expectation_count_type == :at_most return pretty_print(count) end def pretty_print(count) "#{count} time#{count == 1 ? '' : 's'}" end end end end rspec-mocks-2.14.3/lib/rspec/mocks/argument_matchers.rb0000644000004100000410000001301112202216237023103 0ustar www-datawww-datamodule RSpec module Mocks # ArgumentMatchers are placeholders that you can include in message # expectations to match arguments against a broader check than simple # equality. # # With the exception of `any_args` and `no_args`, they all match against # the arg in same position in the argument list. # # @see ArgumentListMatcher module ArgumentMatchers class AnyArgsMatcher def description "any args" end end class AnyArgMatcher def initialize(ignore) end def ==(other) true end end class NoArgsMatcher def description "no args" end end class RegexpMatcher def initialize(regexp) @regexp = regexp end def ==(value) Regexp === value ? value == @regexp : value =~ @regexp end end class BooleanMatcher def initialize(ignore) end def ==(value) [true,false].include?(value) end end class HashIncludingMatcher def initialize(expected) @expected = expected end def ==(actual) @expected.all? {|k,v| actual.has_key?(k) && v == actual[k]} rescue NoMethodError false end def description "hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})" end end class HashExcludingMatcher def initialize(expected) @expected = expected end def ==(actual) @expected.none? {|k,v| actual.has_key?(k) && v == actual[k]} rescue NoMethodError false end def description "hash_not_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})" end end class DuckTypeMatcher def initialize(*methods_to_respond_to) @methods_to_respond_to = methods_to_respond_to end def ==(value) @methods_to_respond_to.all? {|message| value.respond_to?(message)} end end class MatcherMatcher def initialize(matcher) @matcher = matcher end def ==(value) @matcher.matches?(value) end end class EqualityProxy def initialize(given) @given = given end def ==(expected) @given == expected end end class InstanceOf def initialize(klass) @klass = klass end def ==(actual) actual.instance_of?(@klass) end end class KindOf def initialize(klass) @klass = klass end def ==(actual) actual.kind_of?(@klass) end end # Matches any args at all. Supports a more explicit variation of # `object.should_receive(:message)` # # @example # # object.should_receive(:message).with(any_args) def any_args AnyArgsMatcher.new end # Matches any argument at all. # # @example # # object.should_receive(:message).with(anything) def anything AnyArgMatcher.new(nil) end # Matches no arguments. # # @example # # object.should_receive(:message).with(no_args) def no_args NoArgsMatcher.new end # Matches if the actual argument responds to the specified messages. # # @example # # object.should_receive(:message).with(duck_type(:hello)) # object.should_receive(:message).with(duck_type(:hello, :goodbye)) def duck_type(*args) DuckTypeMatcher.new(*args) end # Matches a boolean value. # # @example # # object.should_receive(:message).with(boolean()) def boolean BooleanMatcher.new(nil) end # Matches a hash that includes the specified key(s) or key/value pairs. # Ignores any additional keys. # # @example # # object.should_receive(:message).with(hash_including(:key => val)) # object.should_receive(:message).with(hash_including(:key)) # object.should_receive(:message).with(hash_including(:key, :key2 => val2)) def hash_including(*args) HashIncludingMatcher.new(anythingize_lonely_keys(*args)) end # Matches a hash that doesn't include the specified key(s) or key/value. # # @example # # object.should_receive(:message).with(hash_excluding(:key => val)) # object.should_receive(:message).with(hash_excluding(:key)) # object.should_receive(:message).with(hash_excluding(:key, :key2 => :val2)) def hash_excluding(*args) HashExcludingMatcher.new(anythingize_lonely_keys(*args)) end alias_method :hash_not_including, :hash_excluding # Matches if `arg.instance_of?(klass)` # # @example # # object.should_receive(:message).with(instance_of(Thing)) def instance_of(klass) InstanceOf.new(klass) end alias_method :an_instance_of, :instance_of # Matches if `arg.kind_of?(klass)` # @example # # object.should_receive(:message).with(kind_of(Thing)) def kind_of(klass) KindOf.new(klass) end alias_method :a_kind_of, :kind_of private def anythingize_lonely_keys(*args) hash = args.last.class == Hash ? args.delete_at(-1) : {} args.each { | arg | hash[arg] = anything } hash end end end end rspec-mocks-2.14.3/lib/rspec/mocks/stub_chain.rb0000644000004100000410000000232712202216237021522 0ustar www-datawww-datamodule RSpec module Mocks # @private class StubChain def self.stub_chain_on(object, *chain, &blk) new(object, *chain, &blk).stub_chain end attr_reader :object, :chain, :block def initialize(object, *chain, &blk) @object = object @chain, @block = format_chain(*chain, &blk) end def stub_chain if chain.length > 1 if matching_stub = find_matching_stub chain.shift matching_stub.invoke(nil).stub_chain(*chain, &block) else next_in_chain = Mock.new object.stub(chain.shift) { next_in_chain } StubChain.stub_chain_on(next_in_chain, *chain, &block) end else object.stub(chain.shift, &block) end end private def format_chain(*chain, &blk) if Hash === chain.last hash = chain.pop hash.each do |k,v| chain << k blk = lambda { v } end end return chain.join('.').split('.'), blk end def find_matching_stub ::RSpec::Mocks.proxy_for(object). __send__(:find_matching_method_stub, chain.first.to_sym) end end end end rspec-mocks-2.14.3/lib/rspec/mocks/proxy_for_nil.rb0000644000004100000410000000203412202216237022267 0ustar www-datawww-datamodule RSpec module Mocks # @private class ProxyForNil < Proxy def initialize @warn_about_expectations = true super nil end attr_accessor :warn_about_expectations alias warn_about_expectations? warn_about_expectations def add_message_expectation(location, method_name, opts={}, &block) warn(method_name) if warn_about_expectations? super end def add_negative_message_expectation(location, method_name, &implementation) warn(method_name) if warn_about_expectations? super end def add_stub(location, method_name, opts={}, &implementation) warn(method_name) if warn_about_expectations? super end private def warn method_name non_rspec_caller = caller.find { |line| !line.include?('lib/rspec/mocks') } Kernel.warn("An expectation of :#{method_name} was set on nil. Called from #{non_rspec_caller}. Use allow_message_expectations_on_nil to disable warnings.") end end end end rspec-mocks-2.14.3/lib/rspec/mocks/instance_method_stasher.rb0000644000004100000410000000535012202216237024277 0ustar www-datawww-datamodule RSpec module Mocks # @private class InstanceMethodStasher def initialize(klass, method) @klass = klass @method = method @method_is_stashed = false end # @private def method_is_stashed? @method_is_stashed end # @private def stash return if !method_defined_directly_on_klass? || @method_is_stashed @klass.__send__(:alias_method, stashed_method_name, @method) @method_is_stashed = true end private # @private def method_defined_directly_on_klass? method_defined_on_klass? && method_owned_by_klass? end # @private def method_defined_on_klass?(klass = @klass) klass.method_defined?(@method) || klass.private_method_defined?(@method) end if ::UnboundMethod.method_defined?(:owner) # @private def method_owned_by_klass? owner = @klass.instance_method(@method).owner # On Ruby 2.0.0+ the owner of a method on a class which has been # `prepend`ed may actually be an instance, e.g. # `#`, rather than the expected `MyClass`. owner = owner.class unless owner.is_a? Class # On 1.8 (and some 1.9s -- e.g. rubinius) aliased methods # can report the wrong owner. Example: # class MyClass # class << self # alias alternate_new new # end # end # # MyClass.owner(:alternate_new) returns `Class` on 1.8, # but we need to consider the owner to be `MyClass` because # it is not actually available on `Class` but is on `MyClass`. # Hence, we verify that the owner actually has the method defined. # If the given owner does not have the method defined, we assume # that the method is actually owned by @klass. owner == @klass || !(method_defined_on_klass?(owner)) end else # @private def method_owned_by_klass? # On 1.8.6, which does not support Method#owner, we have no choice but # to assume it's defined on the klass even if it may be defined on # a superclass. true end end public # @private def stashed_method_name "obfuscated_by_rspec_mocks__#{@method}" end # @private def restore return unless @method_is_stashed if @klass.__send__(:method_defined?, @method) @klass.__send__(:undef_method, @method) end @klass.__send__(:alias_method, @method, stashed_method_name) @klass.__send__(:remove_method, stashed_method_name) @method_is_stashed = false end end end end rspec-mocks-2.14.3/lib/rspec/mocks/targets.rb0000644000004100000410000000405712202216237021056 0ustar www-datawww-datamodule RSpec module Mocks UnsupportedMatcherError = Class.new(StandardError) NegationUnsupportedError = Class.new(StandardError) class TargetBase def initialize(target) @target = target end def self.delegate_to(matcher_method, options = {}) method_name = options.fetch(:from) { :to } class_eval(<<-RUBY) def #{method_name}(matcher, &block) unless Matchers::Receive === matcher raise UnsupportedMatcherError, "only the `receive` matcher is supported " + "with `\#{expression}(...).\#{#{method_name.inspect}}`, but you have provided: \#{matcher}" end matcher.__send__(#{matcher_method.inspect}, @target, &block) end RUBY end def self.disallow_negation(method) define_method method do |*args| raise NegationUnsupportedError, "`#{expression}(...).#{method} receive` is not supported since it " + "doesn't really make sense. What would it even mean?" end end private def expression self.class::EXPRESSION end end class AllowanceTarget < TargetBase EXPRESSION = :allow delegate_to :setup_allowance disallow_negation :not_to disallow_negation :to_not end class ExpectationTarget < TargetBase EXPRESSION = :expect delegate_to :setup_expectation delegate_to :setup_negative_expectation, :from => :not_to delegate_to :setup_negative_expectation, :from => :to_not end class AnyInstanceAllowanceTarget < TargetBase EXPRESSION = :expect_any_instance_of delegate_to :setup_any_instance_allowance disallow_negation :not_to disallow_negation :to_not end class AnyInstanceExpectationTarget < TargetBase EXPRESSION = :expect_any_instance_of delegate_to :setup_any_instance_expectation delegate_to :setup_any_instance_negative_expectation, :from => :not_to delegate_to :setup_any_instance_negative_expectation, :from => :to_not end end end rspec-mocks-2.14.3/lib/rspec/mocks/extensions/0000755000004100000410000000000012202216237021251 5ustar www-datawww-datarspec-mocks-2.14.3/lib/rspec/mocks/extensions/instance_exec.rb0000644000004100000410000000217012202216237024406 0ustar www-datawww-datamodule RSpec module Mocks # @private module InstanceExec unless respond_to?(:instance_exec) # @private # # based on Bounded Spec InstanceExec (Mauricio Fernandez) # http://eigenclass.org/hiki/bounded+space+instance_exec # - uses singleton_class of matcher instead of global # InstanceExecHelper module # - this keeps it scoped to this class only, which is the # only place we need it # - only necessary for ruby 1.8.6 def instance_exec(*args, &block) singleton_class = (class << self; self; end) begin orig_critical, Thread.critical = Thread.critical, true n = 0 n += 1 while respond_to?(method_name="__instance_exec#{n}") singleton_class.module_eval{ define_method(method_name, &block) } ensure Thread.critical = orig_critical end begin return send(method_name, *args) ensure singleton_class.module_eval{ remove_method(method_name) } rescue nil end end end end end end rspec-mocks-2.14.3/lib/rspec/mocks/extensions/marshal.rb0000644000004100000410000000105012202216237023221 0ustar www-datawww-datamodule Marshal class << self # Duplicates any mock objects before serialization. Otherwise, # serialization will fail because methods exist on the singleton class. def dump_with_mocks(object, *rest) if ::RSpec::Mocks.space.nil? || !::RSpec::Mocks.space.registered?(object) || NilClass === object dump_without_mocks(object, *rest) else dump_without_mocks(object.dup, *rest) end end alias_method :dump_without_mocks, :dump undef_method :dump alias_method :dump, :dump_with_mocks end end rspec-mocks-2.14.3/lib/rspec/mocks/test_double.rb0000644000004100000410000000774112202216237021721 0ustar www-datawww-datamodule RSpec module Mocks # Implements the methods needed for a pure test double. RSpec::Mocks::Mock # includes this module, and it is provided for cases where you want a # pure test double without subclassing RSpec::Mocks::Mock. module TestDouble # Extends the TestDouble module onto the given object and # initializes it as a test double. # # @example # # module = Module.new # RSpec::Mocks::TestDouble.extend_onto(module, "MyMixin", :foo => "bar") # module.foo #=> "bar" def self.extend_onto(object, name=nil, stubs_and_options={}) object.extend self object.send(:__initialize_as_test_double, name, stubs_and_options) end # Creates a new test double with a `name` (that will be used in error # messages only) def initialize(name=nil, stubs_and_options={}) __initialize_as_test_double(name, stubs_and_options) end # Tells the object to respond to all messages. If specific stub values # are declared, they'll work as expected. If not, the receiver is # returned. def as_null_object @__null_object = true __mock_proxy.as_null_object end # Returns true if this object has received `as_null_object` def null_object? @__null_object end # This allows for comparing the mock to other objects that proxy such as # ActiveRecords belongs_to proxy objects. By making the other object run # the comparison, we're sure the call gets delegated to the proxy # target. def ==(other) other == __mock_proxy end # @private def inspect "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>" end # @private def to_s inspect.gsub('<','[').gsub('>',']') end alias_method :to_str, :to_s # @private def respond_to?(message, incl_private=false) __mock_proxy.null_object? ? true : super end # @private def __build_mock_proxy proxy = Proxy.new(self, @name, @options || {}) proxy.as_null_object if null_object? proxy end private def __initialize_as_test_double(name=nil, stubs_and_options={}) @__null_object = false if name.is_a?(Hash) && stubs_and_options.empty? stubs_and_options = name @name = nil else @name = name end @options = extract_options(stubs_and_options) assign_stubs(stubs_and_options) end def method_missing(message, *args, &block) if __mock_proxy.null_object? case message when :to_int then return 0 when :to_a, :to_ary then return nil end end __mock_proxy.record_message_received(message, *args, &block) begin __mock_proxy.null_object? ? self : super rescue NameError # Required wrapping doubles in an Array on Ruby 1.9.2 raise NoMethodError if [:to_a, :to_ary].include? message __mock_proxy.raise_unexpected_message_error(message, *args) end end def extract_options(stubs_and_options) if stubs_and_options[:null_object] @null_object = stubs_and_options.delete(:null_object) RSpec.deprecate("double('name', :null_object => true)", :replacement => "double('name').as_null_object") end options = {} extract_option(stubs_and_options, options, :__declared_as, 'Mock') options end def extract_option(source, target, key, default=nil) if source[key] target[key] = source.delete(key) elsif default target[key] = default end end def assign_stubs(stubs) stubs.each_pair do |message, response| Mocks.allow_message(self, message).and_return(response) end end private def __mock_proxy ::RSpec::Mocks.proxy_for(self) end end end end rspec-mocks-2.14.3/lib/rspec/mocks/method_double.rb0000644000004100000410000002125312202216237022214 0ustar www-datawww-datamodule RSpec module Mocks # @private class MethodDouble < Hash # @private attr_reader :method_name, :object # @private def initialize(object, method_name, proxy) @method_name = method_name @object = object @proxy = proxy @method_stasher = InstanceMethodStasher.new(object_singleton_class, @method_name) @method_is_proxied = false store(:expectations, []) store(:stubs, []) end # @private def expectations self[:expectations] end # @private def stubs self[:stubs] end # @private def visibility if TestDouble === @object 'public' elsif object_singleton_class.private_method_defined?(@method_name) 'private' elsif object_singleton_class.protected_method_defined?(@method_name) 'protected' else 'public' end end class ProcWithBlock < Struct.new(:object, :method_name) def call(*args, &block) self.object.__send__(:method_missing, self.method_name, *args, &block) end end # @private def original_method if @method_stasher.method_is_stashed? # Example: a singleton method defined on @object ::RSpec::Mocks.method_handle_for(@object, @method_stasher.stashed_method_name) elsif meth = original_unrecorded_any_instance_method # Example: a method that has been mocked through # klass.any_instance.should_receive(:msg).and_call_original # any_instance.should_receive(:msg) causes the method to be # replaced with a proxy method, and then `and_call_original` # is recorded and played back on the object instance. We need # special handling here to get a handle on the original method # object rather than the proxy method. meth else # Example: an instance method defined on one of @object's ancestors. original_method_from_ancestry end rescue NameError # We have no way of knowing if the object's method_missing # will handle this message or not...but we can at least try. # If it's not handled, a `NoMethodError` will be raised, just # like normally. ProcWithBlock.new(@object,@method_name) end def original_unrecorded_any_instance_method return nil unless any_instance_class_recorder_observing_method?(@object.class) alias_name = ::RSpec::Mocks.any_instance_recorder_for(@object.class).build_alias_method_name(@method_name) @object.method(alias_name) end def any_instance_class_recorder_observing_method?(klass) return true if ::RSpec::Mocks.any_instance_recorder_for(klass).already_observing?(@method_name) superklass = klass.superclass return false if superklass.nil? any_instance_class_recorder_observing_method?(superklass) end our_singleton_class = class << self; self; end if our_singleton_class.ancestors.include? our_singleton_class # In Ruby 2.1, ancestors include the correct ancestors, including the singleton classes def original_method_from_ancestry # Lookup in the ancestry, skipping over the singleton class itself original_method_from_ancestor(object_singleton_class.ancestors.drop(1)) end else # @private def original_method_from_ancestry original_method_from_ancestor(object_singleton_class.ancestors) rescue NameError raise unless @object.respond_to?(:superclass) # Example: a singleton method defined on @object's superclass. # # Note: we have to give precedence to instance methods # defined on @object's class, because in a case like: # # `klass.should_receive(:new).and_call_original` # # ...we want `Class#new` bound to `klass` (which will return # an instance of `klass`), not `klass.superclass.new` (which # would return an instance of `klass.superclass`). original_method_from_superclass end end def original_method_from_ancestor(ancestors) klass, *rest = ancestors klass.instance_method(@method_name).bind(@object) rescue NameError raise if rest.empty? original_method_from_ancestor(rest) end if RUBY_VERSION.to_f > 1.8 # @private def original_method_from_superclass @object.superclass. singleton_class. instance_method(@method_name). bind(@object) end else # Our implementation for 1.9 (above) causes an error on 1.8: # TypeError: singleton method bound for a different object # # This doesn't work quite right in all circumstances but it's the # best we can do. # @private def original_method_from_superclass ::Kernel.warn <<-WARNING.gsub(/^ +\|/, '') | |WARNING: On ruby 1.8, rspec-mocks is unable to bind the original |`#{@method_name}` method to your partial mock object (#{@object}) |for `and_call_original`. The superclass's `#{@method_name}` is being |used instead; however, it may not work correctly when executed due |to the fact that `self` will be #{@object.superclass}, not #{@object}. | |Called from: #{caller[2]} WARNING @object.superclass.method(@method_name) end end # @private def object_singleton_class class << @object; self; end end # @private def configure_method @original_visibility = visibility_for_method @method_stasher.stash unless @method_is_proxied define_proxy_method end # @private def define_proxy_method return if @method_is_proxied object_singleton_class.class_eval <<-EOF, __FILE__, __LINE__ + 1 def #{@method_name}(*args, &block) ::RSpec::Mocks.proxy_for(self).message_received :#{@method_name}, *args, &block end #{visibility_for_method} EOF @method_is_proxied = true end # @private def visibility_for_method "#{visibility} :#{method_name}" end # @private def restore_original_method return unless @method_is_proxied object_singleton_class.__send__(:remove_method, @method_name) @method_stasher.restore restore_original_visibility @method_is_proxied = false end # @private def restore_original_visibility return unless object_singleton_class.method_defined?(@method_name) || object_singleton_class.private_method_defined?(@method_name) object_singleton_class.class_eval(@original_visibility, __FILE__, __LINE__) end # @private def verify expectations.each {|e| e.verify_messages_received} end # @private def reset restore_original_method clear end # @private def clear expectations.clear stubs.clear end # @private def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation) configure_method expectation = MessageExpectation.new(error_generator, expectation_ordering, expected_from, self, 1, opts, &implementation) expectations << expectation expectation end # @private def build_expectation(error_generator, expectation_ordering) expected_from = IGNORED_BACKTRACE_LINE MessageExpectation.new(error_generator, expectation_ordering, expected_from, self) end # @private def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation) configure_method stub = MessageExpectation.new(error_generator, expectation_ordering, expected_from, self, :any, opts, &implementation) stubs.unshift stub stub end # @private def add_default_stub(*args, &implementation) return if stubs.any? add_stub(*args, &implementation) end # @private def remove_stub raise_method_not_stubbed_error if stubs.empty? expectations.empty? ? reset : stubs.clear end # @private def raise_method_not_stubbed_error raise MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed" end # @private IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored' end end end rspec-mocks-2.14.3/lib/rspec/mocks.rb0000644000004100000410000000562212202216237017404 0ustar www-datawww-datarequire 'rspec/mocks/framework' require 'rspec/mocks/version' module RSpec module Mocks class << self attr_accessor :space def setup(host) (class << host; self; end).class_eval do include RSpec::Mocks::ExampleMethods end self.space ||= RSpec::Mocks::Space.new end def verify space.verify_all end def teardown space.reset_all end def proxy_for(object) space.proxy_for(object) end def any_instance_recorder_for(klass) space.any_instance_recorder_for(klass) end # Adds an allowance (stub) on `subject` # # @param subject the subject to which the message will be added # @param message a symbol, representing the message that will be # added. # @param opts a hash of options, :expected_from is used to set the # original call site # @param block an optional implementation for the allowance # # @example Defines the implementation of `foo` on `bar`, using the passed block # x = 0 # RSpec::Mocks.allow_message(bar, :foo) { x += 1 } def allow_message(subject, message, opts={}, &block) orig_caller = opts.fetch(:expected_from) { caller(1)[0] } ::RSpec::Mocks.proxy_for(subject). add_stub(orig_caller, message.to_sym, opts, &block) end # Sets a message expectation on `subject`. # @param subject the subject on which the message will be expected # @param message a symbol, representing the message that will be # expected. # @param opts a hash of options, :expected_from is used to set the # original call site # @param block an optional implementation for the expectation # # @example Expect the message `foo` to receive `bar`, then call it # RSpec::Mocks.expect_message(bar, :foo) # bar.foo def expect_message(subject, message, opts={}, &block) orig_caller = opts.fetch(:expected_from) { caller(1)[0] } ::RSpec::Mocks.proxy_for(subject). add_message_expectation(orig_caller, message.to_sym, opts, &block) end # @api private KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method) # @api private # Used internally to get a method handle for a particular object # and method name. # # Includes handling for a few special cases: # # - Objects that redefine #method (e.g. an HTTPRequest struct) # - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator) def method_handle_for(object, method_name) if ::Kernel === object KERNEL_METHOD_METHOD.bind(object).call(method_name) else object.method(method_name) end end end # @private IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored' end end