[DRE-commits] [ruby-flexmock] 03/06: Imported Upstream version 1.3.2
Jonas Genannt
jonas at brachium-system.net
Fri Jan 17 11:48:21 UTC 2014
This is an automated email from the git hooks/post-receive script.
hggh-guest pushed a commit to branch master
in repository ruby-flexmock.
commit dccb8919b5c2fd31999ccf79e25fc4f5d6b8246b
Author: Jonas Genannt <jonas at brachium-system.net>
Date: Fri Jan 17 12:02:53 2014 +0100
Imported Upstream version 1.3.2
---
CHANGES | 31 +-
Gemfile | 7 +
Gemfile.lock | 20 +
README.md | 1192 ++++++++++++++
README.rdoc | 945 -----------
Rakefile | 81 +-
TAGS | 1677 ++++++++++++--------
doc/GoogleExample.rdoc | 84 +-
doc/examples/rspec_examples_spec.rdoc | 245 +++
doc/examples/test_unit_examples_test.rdoc | 241 +++
doc/index.rdoc | 31 +
doc/releases/flexmock-1.0.0.rdoc | 138 ++
doc/releases/flexmock-1.0.3.rdoc | 159 ++
doc/releases/flexmock-1.0.4.rdoc | 165 ++
doc/releases/flexmock-1.1.0.rdoc | 144 ++
doc/releases/flexmock-1.2.0.rdoc | 150 ++
doc/releases/flexmock-1.3.0.rdoc | 165 ++
doc/releases/flexmock-1.3.1.rdoc | 171 ++
lib/flexmock.rb | 2 +-
lib/flexmock/argument_matchers.rb | 19 +-
lib/flexmock/argument_matching.rb | 33 +
lib/flexmock/argument_types.rb | 6 +-
lib/flexmock/base.rb | 6 +-
lib/flexmock/class_extensions.rb | 17 +
lib/flexmock/composite.rb | 6 +-
lib/flexmock/core.rb | 85 +-
lib/flexmock/core_class_methods.rb | 16 +-
lib/flexmock/default_framework_adapter.rb | 7 +-
lib/flexmock/deprecated_methods.rb | 2 +-
lib/flexmock/errors.rb | 2 +-
lib/flexmock/expectation.rb | 59 +-
lib/flexmock/expectation_director.rb | 9 +-
lib/flexmock/explicit_needed.rb | 43 +
lib/flexmock/mock_container.rb | 50 +-
lib/flexmock/noop.rb | 2 +-
lib/flexmock/object_extensions.rb | 5 +
lib/flexmock/ordering.rb | 2 +-
lib/flexmock/partial_mock.rb | 87 +-
lib/flexmock/rails.rb | 2 +-
lib/flexmock/recorder.rb | 5 +-
lib/flexmock/rspec.rb | 11 +-
lib/flexmock/rspec/configure.rb | 12 +
lib/flexmock/rspec_spy_matcher.rb | 92 ++
lib/flexmock/spy_describers.rb | 76 +
lib/flexmock/symbol_extensions.rb | 17 +
lib/flexmock/test_unit.rb | 45 +-
lib/flexmock/test_unit_assert_spy_called.rb | 34 +
lib/flexmock/test_unit_integration.rb | 17 +-
lib/flexmock/undefined.rb | 2 +-
lib/flexmock/validators.rb | 73 +-
lib/flexmock/version.rb | 6 +-
metadata.yml | 104 +-
test/aliasing_test.rb | 91 +-
test/assert_spy_called_test.rb | 119 ++
test/base_class_test.rb | 71 +
test/based_partials_test.rb | 51 +
test/container_methods_test.rb | 2 +-
test/default_framework_adapter_test.rb | 10 +-
test/demeter_mocking_test.rb | 2 +-
test/deprecated_methods_test.rb | 4 +-
test/examples_from_readme_test.rb | 2 +-
test/expectation_description_test.rb | 80 +
test/extended_should_receive_test.rb | 2 +-
test/naming_test.rb | 3 +-
test/new_instances_test.rb | 6 +-
test/object_extensions_test.rb | 25 +
test/partial_mock_test.rb | 80 +-
test/record_mode_test.rb | 14 +-
test/rspec_integration/integration_spec.rb | 14 +-
test/rspec_integration/spy_example_spec.rb | 207 +++
test/samples_test.rb | 2 +-
test/should_ignore_missing_test.rb | 10 +-
test/should_receive_test.rb | 106 +-
test/spys_test.rb | 215 +++
test/symbol_extensions_test.rb | 8 +
test/test_class_extensions.rb | 34 +
test/test_setup.rb | 47 +-
test/test_unit_integration/auto_test_unit_test.rb | 12 +-
.../minitest_teardown_test.rb | 14 +
test/tu_integration_test.rb | 2 +-
test/undefined_test.rb | 2 +-
81 files changed, 5877 insertions(+), 1958 deletions(-)
diff --git a/CHANGES b/CHANGES
index 7ac90c1..33f53a1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,18 @@
= Changes for FlexMock
+== Version 1.0.0
+
+* Added spy support.
+* Added base class mocking restrictions.
+* Using singleton_methods to get list of singleton methods (rather
+ than methods(false))
+* Correctly handling mocking methods that were meta-programmed with
+ method_missing.
+
+== Version 0.9.0
+
+* Ruby 1.9.3 compatibility changes.
+
== Version 0.8.5
* Fixed warning about a void context.
@@ -45,7 +58,7 @@
* Updated install.rb to handle non-root destination directories via
DESTDIR.
-* Fixed operator bug introduced in 0.7.0.
+* Fixed operator bug introduced in 0.7.0.
== Version 0.7.0
@@ -79,15 +92,15 @@
where mock support methods in the domain object would cause
problems.
-* Internally renamed PartialMock to PartialMockProxy.
-
+* Internally renamed PartialMock to PartialMockProxy.
+
== Version 0.6.2
* flexmock() with a block now always returns the domain object.
flexmock() without a block returns the mock object. Note that for
normal mocks, the domain and mock objects are the same. For partial
mocks, the mock is separate from the domain object.
-* Added +and_raise+ to the list of expection specifications.
+* Added +and_raise+ to the list of expection specifications.
== Version 0.6.1
@@ -105,7 +118,7 @@
== Version 0.5.1
-* Changed the name of any_instance to new_instances.
+* Changed the name of any_instance to new_instances.
Deprecated any_instance.
* Added ability to stub any class method in new_instances.
* Added RCov task
@@ -128,12 +141,12 @@
== Version 0.4.3
* Fixed bug where non-direct class methods were not properly handled.
-
+
== Version 0.4.2
* Fixed bug where multiple stubs of a class method were not
properly restored.
-
+
== Version 0.4.1
* Removed include of Test::Unit::Assertions from Expectations.
@@ -167,8 +180,8 @@
* Added strict mode in record mode interface to facility using known
good algorithms for comparison testing.
* Improved the docs and examples. Fixed garbled first example in
- README.
-
+ README.
+
== Version 0.2.0
* Added record mode for building expectations.
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..eb0e463
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,7 @@
+source 'http://rubygems.org'
+
+gem 'rake', ">= 0.9.2.2"
+
+group 'test' do
+ gem 'rspec', ">= 2.0"
+end
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..8c934dc
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,20 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ diff-lcs (1.2.4)
+ rake (10.0.4)
+ rspec (2.13.0)
+ rspec-core (~> 2.13.0)
+ rspec-expectations (~> 2.13.0)
+ rspec-mocks (~> 2.13.0)
+ rspec-core (2.13.1)
+ rspec-expectations (2.13.0)
+ diff-lcs (>= 1.1.3, < 2.0)
+ rspec-mocks (2.13.1)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ rake (>= 0.9.2.2)
+ rspec (>= 2.0)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6b85f53
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1192 @@
+# Flex Mock -- Making Mocking Easy
+
+FlexMock is a simple, but flexible, mock object library for Ruby unit
+testing.
+
+Version :: 1.3.1
+
+# Links
+
+* **Documents** -- http://flexmock.rubyforge.org
+* **RubyGems** -- Install with: `gem install flexmock`
+* **Source** -- https://github.com/jimweirich/flexmock
+* **Bug Reports / Issue Tracking** -- https://github.com/jimweirich/flexmock/issues
+* **Continuous Integration** -- http://travis-ci.org/#!/jimweirich/flexmock
+
+## Installation
+
+You can install FlexMock with the following command.
+
+```
+ $ gem install flexmock
+```
+
+## Simple Example
+
+We have a data acquisition class (<code>TemperatureSampler</code>)
+that reads a temperature sensor and returns an average of 3 readings.
+We don't have a _real_ temperature to use for testing, so we mock one
+up with a mock object that responds to the
+`read_temperature` message.
+
+Here's the complete example:
+
+```ruby
+ require 'test/unit'
+ require 'flexmock/test_unit'
+
+ class TemperatureSampler
+ def initialize(sensor)
+ @sensor = sensor
+ end
+
+ def average_temp
+ total = (0...3).collect {
+ @sensor.read_temperature
+ }.inject { |i, s| i + s }
+ total / 3.0
+ end
+ end
+
+ class TestTemperatureSampler < Test::Unit::TestCase
+ def test_sensor_can_average_three_temperature_readings
+ sensor = flexmock("temp")
+ sensor.should_receive(:read_temperature).times(3).
+ and_return(10, 12, 14)
+
+ sampler = TemperatureSampler.new(sensor)
+ assert_equal 12, sampler.average_temp
+ end
+ end
+```
+
+You can find an extended example of FlexMock in
+[Google Example](http://flexmock.rubyforge.org/files/doc/GoogleExample_rdoc.html
+"Example").
+
+## Test::Unit Integration
+
+FlexMock integrates nicely with Test::Unit. Just require the
+'flexmock/test_unit' file at the top of your test file. The
+`flexmock` method will be available for mock creation, and
+any created mocks will be automatically validated and closed at the
+end of the individual test.
+
+Your test case will look something like this:
+
+```ruby
+ require 'flexmock/test_unit'
+
+ class TestDog < Test::Unit::TestCase
+ def test_dog_wags
+ tail_mock = flexmock(:wag => :happy)
+ assert_equal :happy, tail_mock.wag
+ end
+ end
+```
+
+**NOTE:** If you don't want to automatically extend every TestCase
+with the flexmock methods and overhead, then require the 'flexmock'
+file and explicitly include the FlexMock::TestCase module in each test
+case class where you wish to use mock objects. FlexMock versions prior
+to 0.6.0 required the explicit include.
+
+## RSpec Integration
+
+FlexMock also supports integration with the RSpec behavior
+specification framework. Starting with version 0.9.0 of RSpec, you
+will be able to say:
+
+```ruby
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe "Using FlexMock with RSpec" do
+ it "should be able to create a mock" do
+ m = flexmock(:foo => :bar)
+ m.foo.should === :bar
+ end
+ end
+```
+
+**NOTE:** _I often can't remember the proper RSpec configuration for
+flexmock without looking it up. If you are the same, you can put
+<code>require 'flexmock/rspec/configure'</code> in your spec helper to
+auto-configure RSpec to use flexmock._
+
+**NOTE:** _Older versions of RSpec used the Spec::Runner for
+configuration. If you are running with a very old RSpec, you may need
+the following:_
+
+```ruby
+ # Configuration for RSpec prior to RSpec 2.x
+ Spec::Runner.configure do |config|
+ config.mock_with :flexmock
+ end
+```
+
+## Quick Reference
+
+### Creating Mock Objects
+
+The `flexmock` method is used to create mocks in various
+configurations. Here's a quick rundown of the most common options. See
+FlexMock::MockContainer#flexmock for more details.
+
+* <b>mock = flexmock("joe")</b>
+
+ Create a mock object named "joe" (the name is used in reporting errors).
+
+* <b>mock = flexmock(:foo => :bar, :baz => :froz)</b>
+
+ Create a mock object and define two mocked methods (:foo and :baz)
+ that return the values :bar and :froz respectively. This is useful
+ when creating mock objects with just a few methods and simple return
+ values.
+
+* <b>mock = flexmock("joe", :foo => :bar, :bar => :froz)</b>
+
+ You can combine the mock name and an expectation hash in the same
+ call to flexmock.
+
+* <b>mock = flexmock("joe", :on, <em>User</em>)</b>
+
+ This defines a strict mock that is based on the User class. Strict
+ mocks prevent you from mocking or stubbing methods that are not
+ instance methods of the restricting class (i.e. User in our
+ example). This helps prevent tests from becoming stale with
+ incorrectly mocked objects when the method names change.
+
+ Use the `explicitly` modifier to `should_receive` to override the
+ strict mock restrictions.
+
+* <b>partial_mock = flexmock(<em>real_object</em>)</b>
+
+ If you you give `flexmock` a real object in the argument list, it
+ will treat that real object as a base for a partial mock object. The
+ return value `partial_mock` may be used to set expectations. The
+ real_object should be used in the reference portion of the test.
+
+* <b>partial_mock = flexmock(<em>real_object</em>, :on, <em>class_object</em>)</b>
+
+* <b>partial_mock = flexmock(<em>real_object</em>, :strict)</b>
+
+ Partial mocks can also take a restricting base, so that you cannot
+ mock methods not in the class (without the <code>explicitly</code>
+ modifier). Since partials already have a class, you can use the
+ <code>:strict</code> keyword to mean the same thing as <code>:on,
+ <em>real_object</em>.class</code>.
+
+* <b>partial_mock = flexmock(<em>real_object</em>, "name", :foo => :baz)</b>
+
+ Names and expectation hashes may be used with partial mocks as well.
+
+* <b>partial_mock = flexmock(:base, <em>real_string_object</em>)</b>
+
+ Since Strings (and Symbols for that matter) are used for mock names,
+ FlexMock will not recognize them as the base for a partial mock. To
+ force a string to be used as a partial mock base, proceed the string
+ object in the calling sequence with :base.
+
+* <b>partial_mock = flexmock(:safe, <em>real_object</em>) { |mock| mock.should_receive(...) }</b>
+
+ When mocking real objects (i.e. "partial mocks"), FlexMock will add
+ a handful of mock related methods to the actual object (see below
+ for list of method names). If one or more of these added methods
+ collide with an existing method on the partial mock, then there are
+ problems.
+
+ FlexMock offers a "safe" mode for partial mocks that does not add
+ these methods. Indicate safe mode by passing the symbol :safe as the
+ first argument of flexmock. A block _is required_ when using safe
+ mode (the partial_mock returned in safe mode does not have a
+ `should_receive` method).
+
+ The methods added to partial mocks in non-safe mode are:
+
+ * should_receive
+ * new_instances
+ * flexmock_get
+ * flexmock_teardown
+ * flexmock_verify
+ * flexmock_received?
+ * flexmock_calls
+
+* <b>mock = flexmock(...) { |mock| mock.should_receive(...) }</b>
+
+ If a block is given to any of the `flexmock` forms, the mock object
+ will be passed to the block as an argument. Code in the block can
+ set the desired expectations for the mock object.
+
+* <b>mock_model = flexmock(:model, <em>YourModel</em>, ...) { |mock| mock.should_receive(...) }</b>
+
+ When given `:model`, `flexmock()` will return a pure mock (not a
+ partial mock) that will have some ActiveRecord specific methods
+ defined. YourModel should be the class of an ActiveRecord model.
+ These predefined methods make it a bit easier to mock out
+ ActiveRecord model objects in a Rails application. Other that the
+ predefined mocked methods, the mock returned is a standard FlexMock
+ mock object.
+
+ The predefined mocked methods are:
+
+ * id -- returns a unique ID for each mocked model.
+ * to_params -- returns a stringified version of the id.
+ * new_record? -- returns false.
+ * errors -- returns an empty (mocked) errors object.
+ * is_a?(other) -- returns true if other == YourModel.
+ * instance_of?(class) -- returns true if class == YourModel
+ * kind_of?(class) -- returns true if class is YourModel or one of its ancestors
+ * class -- returns YourModel.
+
+* <b>mock = flexmock(... :on, <em>class_object</em>, ...)</b>
+
+**NOTE:** Versions of FlexMock prior to 0.6.0 used `flexstub` to
+create partial mocks. The `flexmock` method now assumes all the
+functionality that was spread out between two different methods.
+`flexstub` is deprecated, but still available for backward
+compatibility.
+
+### Expectation Declarators
+
+Once a mock is created, you need to define what that mock should
+expect to see. Expectation declarators are used to specify these
+expectations placed upon received method calls. A basic expectation,
+created with the `should_receive` method, just establishes the fact
+that a method may (or may not) be called on the mock object.
+Refinements to that expectation may be additionally declared. FlexMock
+always starts with the most general expectation and adds constraints
+to that.
+
+For example, the following code:
+
+```ruby
+ mock.should_receive(:average).and_return(12)
+```
+
+Means that the mock will now accept method calls to an
+`average` method. The expectation will accept any arguments
+and may be called any number of times (including zero times). Strictly
+speaking, the `and_return` part of the declaration isn't
+exactly a constraint, but it does specify what value the mock will
+return when the expectation is matched.
+
+If you want to be more specific, you need to add additional
+constraints to your expectation. Here are some examples:
+
+```ruby
+ mock.should_receive(:average).with(12).once
+
+ mock.should_receive(:average).with(Integer).
+ at_least.twice.at_most.times(10).
+ and_return { rand }
+```
+
+Expectation are always matched in order of declaration. That means if
+you have a general expectation before a more specific expectation, the
+general expectation will have an opportunity to match first,
+effectively hiding the second expectation.
+
+For example:
+
+```ruby
+ mock.should_receive(:average) # Matches any call to average
+ mock.should_receive(:average).with(1).once # Fails because it never matches
+```
+
+In the example, the second expectation will never be triggered because
+all calls to average will be handled by the first expectation. Since
+the second expectation is require to match one time, this test will
+fail.
+
+Reversing the order of the expections so that the more specific
+expectation comes first will fix that problem.
+
+If an expectation has a count requirement (e.g. `once` or `times`),
+then once it has matched its expected number of times, it will let
+other expectations have a chance to match.
+
+For example:
+
+```ruby
+ mock.should_receive(:average).once.and_return(1)
+ mock.should_receive(:average).once.and_return(2)
+ mock.should_receive(:average).and_return(3)
+```
+
+In the example, the first time average is called, the first
+expectation is matched an average will return 1. The second time
+average is called, the second expectation matches and 2 is returned.
+For all calls to average after that, the third expectation returning 3
+will be used.
+
+Occasionally it is useful define a set of expecations in a setup
+method of a test and override those expectations in specific tests. If
+you mark an expectation with the `by_default` marker, that expectation
+will be used only if there are no non-default expectations on that
+method name. See "by_default" below.
+
+### Expectation Criteria
+
+The following methods may be used to create and refine expectations on
+a mock object. See theFlexMock::Expectation for more details.
+
+* <b>should_receive(<em>method_name</em>)</b>
+
+ Declares that a message named _method_name_ will be sent to the mock
+ object. Constraints on this expected message (called expectations)
+ may be chained to the `should_receive` call.
+
+* <b>should_receive(<em>method_name1</em>, <em>method_name2</em>, ...)</b>
+
+ Define a number of expected messages that have the same constraints.
+
+* <b>should_receive(<em>meth1</em> => <em>result1</em>, <em>meth2</em> => <em>result2</em>, ...)</b>
+
+ Define a number of expected messages that have the same constrants, but
+ return different values.
+
+* <b>should_receive(...).explicitly</b>
+
+ If a mock has a base class, use the `explicitly` modifier to
+ override the restriction on method names imposed by the base class.
+ The `explicitly` modifier must come immediately after the
+ `should_receive` call and before any other expectation declarators.
+
+ If a mock does not have a base class, this method has no effect.
+
+* <b>should_expect { |<em>recorder</em>| ... }</b>
+
+ Creates a mock recording object that will translate received method
+ calls into mock expectations. The recorder is passed to a block
+ supplied with the `should_expect` method. See examples
+ below.
+
+* <b>with(<em>arglist</em>)</b>
+
+ Declares that this expectation matches messages that match the given
+ argument list. The `===` operator is used on a argument by argument
+ basis to determine matching. This means that most literal values
+ match literally, class values match any instance of a class and
+ regular expression match any matching string (after a `to_s`
+ conversion). See argument validators (below) for details on argument
+ validation options.
+
+* <b>with_any_args</b>
+
+ Declares that this expectation matches the message with any argument
+ (default)
+
+* <b>with_no_args</b>
+
+ Declares that this expectation matches messages with no arguments
+
+* <b>zero_or_more_times</b>
+
+ Declares that the expected message is may be sent zero or more times
+ (default, equivalent to `at_least.never`).
+
+* <b>once</b>
+
+ Declares that the expected message is only sent once. `at_least` /
+ `at_most` modifiers are allowed.
+
+* <b>twice</b>
+
+ Declares that the expected message is only sent twice. `at_least` /
+ `at_most` modifiers are allowed.
+
+* <b>never</b>
+
+ Declares that the expected message is never sent. `at_least` /
+ `at_most` modifiers are allowed.
+
+* <b>times(<em>n</em>)</b>
+
+ Declares that the expected message is sent _n_ times. `at_least` /
+ `at_most` modifiers are allowed.
+
+* <b>at_least</b>
+
+ Modifies the immediately following message count constraint so that
+ it means the message is sent at least that number of times. E.g.
+ `at_least.once` means the message is sent at least once during the
+ test, but may be sent more often. Both `at_least` and `at_most` may
+ be specified on the same expectation.
+
+* <b>at_most</b>
+
+ Similar to `at_least`, but puts an upper limit on the number of
+ messages. Both `at_least` and `at_most` may be specified on the same
+ expectation.
+
+* <b>ordered</b>
+
+ Declares that the expected message is ordered and is expected to be
+ received in a certain position in a sequence of messages. The
+ message should arrive after and previously declared ordered messages
+ and prior to any following declared ordered messages. Unordered
+ messages are ignored when considering the message order.
+
+ Normally ordering is performed only against calls in the same mock
+ object. If the "globally" adjective is used, then ordering is
+ performed against the other globally ordered method calls.
+
+* <b>ordered(<em>group</em>)</b>
+
+ Declare that the expected message belongs to an order group. Methods
+ within an order group may be received in any order. Ordered messages
+ outside the group must be received either before or after all of the
+ grouped messages.
+
+ For example, in the following, messages `flip` and `flop` may be
+ received in any order (because they are in the same group), but must
+ occur strictly after `start` but before `end`. The message
+ `any_time` may be received at any time because it is not ordered.
+
+```ruby
+ m = flexmock()
+ m.should_receive(:any_time)
+ m.should_receive(:start).ordered
+ m.should_receive(:flip).ordered(:flip_flop_group)
+ m.should_receive(:flop).ordered(:flip_flop_group)
+ m.should_receive(:end).ordered
+```
+
+ Normally ordering is performed only against calls in the same mock
+ object. If the "globally" adjective is used, then ordering is
+ performed against the other globally ordered method calls.
+
+* <b>globally.ordered</b>
+* <b>globally.ordered(<em>group_name</em>)</b>
+
+ When modified by the "globally" adjective, the mock call will be
+ ordered against other globally ordered methods in any of the mock
+ objects in the same container (i.e. same test). All the options of
+ the per-mock ordering are available in the globally ordered method
+ calls.
+
+* <b>by_default</b>
+
+ Marks the expectation as a default. Default expectations act as
+ normal as long as there are no non-default expectations for the same
+ method name. As soon as a non-default expectation is defined, all
+ default expectations for that method name are ignored.
+
+ Default expectations allow you to setup a set of default behaviors
+ for various methods in the setup of a test suite, and then override
+ only the methods that need special handling in any given test.
+
+### Expectation Actions
+
+Action expectations are used to specify what the mock should _do_ when
+the expectation is matched. The actions themselves do not take part in
+determining whether a given expectation matches or not.
+
+* <b>and_return(<em>value</em>)</b>
+
+ Declares that the expected message will return the given value.
+
+* <b>and_return(<em>value1</em>, <em>value2</em>, ...)</b>
+
+ Declares that the expected message will return a series of values.
+ Each invocation of the message will return the next value in the
+ series. The last value will be repeatably returned if the number of
+ matching calls exceeds the number of values.
+
+* <b>and_return { |<em>args</em>, ...| <em>code</em> ... }</b>
+
+ Declares that the expected message will return the yielded value of
+ the block. The block will receive all the arguments in the message.
+ If the message was provided a block, it will be passed as the last
+ parameter of the block's argument list.
+
+* <b>returns( ... )</b>
+
+ Alias for `and_return`.
+
+* <b>and_return_undefined</b>
+
+ Declares that the expected message will return a self-preserving
+ undefined object (see FlexMock::Undefined for details).
+
+* <b>returns_undefined</b>
+
+ Alias for `and_returns_undefined`
+
+* <b>and_raise(_exception_, _*args_)</b>
+
+ Declares that the expected message will raise the specified
+ exception. If `exception` is an exception class, then the raised
+ exception will be constructed from the class with `new` given the
+ supplied arguments. If `exception` is an instance of an exception
+ class, then it will be raised directly.
+
+* <b>raises( ... )</b>
+
+ Alias for `and_raise`.
+
+* <b>and_throw(<em>symbol</em>)</b>
+* <b>and_throw(<em>symbol</em>, <em>value</em>)</b>
+
+ Declares that the expected messsage will throw the specified symbol.
+ If an optional value is included, then it will be the value returned
+ from the corresponding catch statement.
+
+* <b>throws( ... )</b>
+
+ Alias for `and_throw`.
+
+* <b>and_yield(<em>values</em>, ...)</b>
+
+ Declares that the mocked method will receive a block, and the mock
+ will call that block with the values given. Not providing a block
+ will be an error. Providing more than one `and_yield` clause one a
+ single expectation will mean that subsquent mock method calls will
+ yield the values provided by the additional `and_yield` clause.
+
+* <b>yields( ... )</b>
+
+ Alias for `and_yield( ... )`.
+
+* <b>pass_thru</b>
+* <b>pass_thru { |<em>value</em>| .... }</b>
+
+ Declares that the expected message will allow the method to be
+ passed to the original method definition in the partial mock object.
+ `pass_thru` is also allowed on regular mocks, but since there is no
+ original method to be called, pass_thru will always return the
+ undefined object.
+
+ If a block is supplied to `pass_thru`, the value returned from the
+ original method will be passed to the block and the value of the
+ block will be returned. This allows you to mock methods on the
+ returned value.
+
+```ruby
+ Dog.should_receive(:new).pass_thru { |dog|
+ flexmock(dog, :wag => true)
+ }
+```
+
+### Other Expectation Methods
+
+* <b>mock</b>
+
+ Expectation constraints always return the expectation so that the
+ constraints can be chained. If you wish to do a one-liner and assign
+ the mock to a variable, the `mock` method on an expectation will
+ return the original mock object.
+
+```ruby
+ m = flexmock.should_receive(:hello).once.and_return("World").mock
+```
+
+ **NOTE:** _Using **mock** when specifying a Demeter mock
+ chain will return the last mock of the chain, which might not be
+ what you expect._
+
+### Argument Validation
+
+The values passed to the `with` declarator determine the criteria for
+matching expectations. The first expectation found that matches the
+arguments in a mock method call will be used to validate that mock
+method call.
+
+The following rules are used for argument matching:
+
+* A `with` parameter that is a class object will match any
+ actual argument that is an instance of that class.
+
+ Examples:
+
+```ruby
+ with(Integer) will match f(3)
+```
+
+* A regular expression will match any actual argument that matches the
+ regular expression. Non-string actual arguments are converted to
+ strings via `to_s` before applying the regular
+ expression.
+
+ Examples:
+
+```ruby
+ with(/^src/) will match f("src_object")
+ with(/^3\./) will match f(3.1415972)
+```
+
+* Most other objects will match based on equal values.
+
+ Examples:
+
+```ruby
+ with(3) will match f(3)
+ with("hello") will match f("hello")
+```
+
+* If you wish to override the default matching behavior and force
+ matching by equality, you can use the FlexMock.eq convenience
+ method. This is mostly used when you wish to match class objects,
+ since the default matching behavior for class objects is to match
+ instances, not themselves.
+
+ Examples:
+
+```ruby
+ with(eq(Integer)) will match f(Integer)
+ with(eq(Integer)) will NOT match f(3)
+```
+
+ **Note:** <em>If you do not use the FlexMock::TestCase Test Unit
+ integration module, or the FlexMock::ArgumentTypes module, you will
+ have to fully qualify the `eq` method. This is true of all the
+ special argument matches (`eq`, `on`, `any`, `hsh` and
+ `ducktype`).</em>
+
+```ruby
+ with(FlexMock.eq(Integer))
+ with(FlexMock.on { code })
+ with(FlexMock.any)
+ with(FlexMock.hsh(:tag => 3))
+ with(FlexMock.ducktype(:wag, :bark))
+```
+
+* If you wish to match a hash on _some_ of its values, the
+ `FlexMock.hsh(...)` method will work. Only specify the hash values
+ you are interested in, the others will be ignored.
+
+```ruby
+ with(hsh(:run => true)) will match f(:run => true, :stop => false)
+```
+
+* If you wish to match any object that responds to a certain set of
+ methods, use the `FlexMock.ducktype` method.
+
+
+```ruby
+ with(ducktype(:to_str)) will match f("string")
+ with(ducktype(:wag, :bark)) will match f(dog)
+ (assuming dog implements wag and bark)
+```
+
+* If you wish to match _anything_, then use the `FlexMock.any` method
+ in the with argument list.
+
+ Examples (assumes either the FlexMock::TestCase or FlexMock::ArgumentTypes
+ mix-ins has been included):
+
+```ruby
+ with(any) will match f(3)
+ with(any) will match f("hello")
+ with(any) will match f(Integer)
+ with(any) will match f(nil)
+```
+
+* If you wish to specify a complex matching criteria, use the
+ `FlexMock.on(&block)` with the logic contained in the block.
+
+ Examples (assumes `FlexMock::ArgumentTypes` has been included):
+
+```ruby
+ with(on { |arg| (arg % 2) == 0 } )
+```
+
+ will match any even integer.
+
+* If you wish to match a method call where a block is given, add
+ `Proc` as the last argument to `with`.
+
+ Example:
+
+```ruby
+ m.should_receive(:foo).with(Integer,Proc).and_return(:got_block)
+ m.should_receive(:foo).with(Integer).and_return(:no_block)
+```
+
+ will cause the mock to return the following:
+
+```ruby
+ m.foo(1) { } => returns :got_block
+ m.foo(1) => returns :no_block
+```
+
+### Creating Partial Mocks
+
+Sometimes it is useful to mock the behavior of one or two methods in
+an existing object without changing the behavior of the rest of the
+object. If you pass a real object to the `flexmock` method, it will
+allow you to use that real object in your test and will just mock out
+the one or two methods that you specify.
+
+For example, suppose that a Dog object uses a Woofer object to bark.
+The code for Dog looks like this (we will leave the code for Woofer to
+your imagination):
+
+```ruby
+ class Dog
+ def initialize
+ @woofer = Woofer.new
+ end
+ def bark
+ @woofer.woof
+ end
+ def wag
+ :happy
+ end
+ end
+```
+
+Now we want to test Dog, but using a real Woofer object in the test is
+a real pain (why? ... well because Woofer plays a sound file of a dog
+barking, and that's really annoying during testing).
+
+So, how can we create a Dog object with mocked Woofer? All we need to
+do is allow FlexMock to replace the `bark` method.
+
+Here's the test code:
+
+```ruby
+ class TestDogBarking < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ # Setup the tests by mocking the +new+ method of
+ # Woofer and return a mock woofer.
+ def setup
+ @dog = Dog.new
+ flexmock(@dog, :bark => :grrr)
+ end
+
+ def test_dog
+ assert_equal :grrr, @dog.bark # Mocked Method
+ assert_equal :happy, @dog.wag # Normal Method
+ end
+ end
+```
+
+The nice thing about this technique is that after the test is over,
+the mocked out methods are returned to their normal state. Outside the
+test everything is back to normal.
+
+**NOTE:** <em>In previous versions of FlexMock, partial mocking was
+called "stubs" and the `flexstub` method was used to create the
+partial mocks. Although partial mocks were often used as stubs, the
+terminology was not quite correct. The current version of FlexMock
+uses the `flexmock` method to create both regular stubs and partial
+stubs. A version of the `flexstub` method is included for backwards
+compatibility. See Martin Fowler's article
+[_Mocks Aren't Stubs_](http://www.martinfowler.com/articles/mocksArentStubs.html
+"Mocks Aren't Stubs") for a better understanding of the difference
+between mocks and stubs.</em>
+
+This partial mocking technique was inspired by the `Stuba` library in
+the `Mocha` project.
+
+### Spies
+
+FlexMock supports spy-like mocks as well as the traditional mocks.
+
+```ruby
+ # In Test::Unit / MiniTest
+ class TestDogBarking < Test::Unit::TestCase
+ def test_dog
+ dog = flexmock(:on, Dog)
+ dog.bark("loud")
+ assert_spy_called dog, :bark, "loud"
+ end
+ end
+
+ # In RSpec
+ describe Dog do
+ let(:dog) { flexmock(:on, Dog) }
+ it "barks loudly" do
+ dog.bark("loud")
+ dog.should have_received(:bark).with("loud")
+ end
+ end
+```
+
+Since spies are verified after the code under test is run, they fit
+very nicely with the Given/When/Then technique of specification. Here
+is the above RSpec example using the rspec-given gem:
+
+```ruby
+ require 'rspec/given'
+
+ describe Dog do
+ Given(:dog) { flexmock(:on, Dog) }
+
+ context "when barking loudly" do
+ When { dog.bark("loud") }
+ Then { dog.should have_received(:bark).with("loud") }
+ end
+ end
+```
+
+*NOTE:* <em>You can only spy on methods that are mocked or stubbed.
+That's not a problem with regular mocks, but normal methods on partial
+objects will not be recorded.</em>
+
+You can get around this limitation by stubbing the method in question
+on the normal mock, and then specifying `pass_thru`. Assuming `:bark`
+is a normal method on a Dog object, then the following allows for
+spying on `:bark`.
+
+```ruby
+ dog = Dog.new
+ flexmock(dog).should_receive(:bark).pass_thru
+ # ...
+ dog.should have_received(:bark)
+```
+
+#### Asserting Spy Methods are Called (Test::Unit / MiniTest)
+
+FlexMock provied a custom assertion method for use with Test::Unit and
+MiniTest for asserting that mocked methods are actually called.
+
+* <b>assert_spy_called <em>mock</em>, <em>options_hash</em>, <em>method_name</em>, <em>args...</em></b>
+
+ This will assert that the method called _method_name_ has been
+ called at least once on the given mock object. If arguments are
+ given, then the method must be called with actual argument that
+ match the given argument matchers.
+
+ All the argument matchers defined in the "Argument Validation"
+ section above are allowed in the `assert_spy_called`
+ method.
+
+ The `options` hash is optional. If omitted, all options will have
+ their default values. See below for spy option definitions.
+
+* <b>assert_spy_not_called <em>mock</em>, <em>options_hash</em>, <em>method_name</em>, <em>args...</em></b>
+
+ Same as `assert_spy_called`, except with the sense of the
+ test reversed.
+
+*Spy Options*
+
+* <b>times: <em>n</em></b>
+
+ Specify the number of times a matching method should have been
+ invoked. `nil` (or omitted) means any number of times.
+
+* <b>with_block: <em>true/false/nil</em>
+
+ Is a block required on the invocation? `true` means the method must
+ be invoked with a block. `false` means the method must have been
+ invoked without a block. `nil` means that the presence of a block
+ does not matter. Default is `nil`.
+
+* <b>and: [<em>proc1</em>, <em>proc2...</em>]</b>
+
+ Additional validations to be run on each matching method call. The
+ list of arguments for each call is passed to the procs. This allows
+ additional validations on supplied arguments. Default is no
+ additional validations.
+
+* <b>on: <em>n</em>
+
+ Only apply the additional validations on the <em>n</em>'th
+ invocation of the matching method. Default is apply additional
+ validations to all invocations.
+
+*Examples:*
+
+```ruby
+ dog = flexmock(:on, Dog)
+
+ dog.wag(:tail)
+ dog.wag(:head)
+ dog.bark(5)
+ dog.bark(6)
+
+ assert_spy_called dog, :wag, :tail
+ assert_spy_called dog, :wag, :head
+ assert_spy_called dog, {times: 2}, :wag
+
+ assert_spy_not_called dog, :bark
+ assert_spy_not_called dog, {times: 3}, :wag
+
+ is_even = proc { |n| assert_equal 0, n%2 }
+ assert_spy_called dog, { and: is_even, on: 2 }, :bark, Integer
+```
+
+#### RSpec Matcher for Spying
+
+FlexMock also provides an RSpec matcher that can be used to specify
+spy behavior.
+
+* <b>mock.should have_received(<em>method_name</em>).<em>modifier1</em>.<em>modifier2</em>...</b>
+
+ Specifies that the method named _method_name_ should have
+ been received by the mock object with the given arguments.
+
+ Just like `should_receive`, `have_received` will accept a number of
+ modifiers that modify its behavior.
+
+*Modifiers for `have_received`*
+
+* <b>with(<em>args</em>)
+
+ If a `with` modifier is given, only messages with matching arguments
+ are considered. _args_ can be any of the argument matches mentioned
+ in the "Argument Validation" section above. If `with` is not given,
+ then the arguments are not considered when finding matching calls.
+
+* <b>times(<em>n</em>)</b>
+
+ If a `times` modifier is given, then there must be exactly `n` calls
+ for that method name on the mock. If the `times` clause is not
+ given, then there must be at least one call matching the method name
+ (and arguments if they are considered).
+
+ * `never` is an alias for `times(0)`,
+ * `once` is an alias for `times(1)`, and
+ * `twice` is an alias for `times(2)`.
+
+* <b>and { |args| <em>code</em> }</b>
+
+ If an `and` modifier is given, then the supplied block will be run as
+ additional validations on any matching call. Arguments to the
+ matching call will be supplied to the block. If multiple `and`
+ modifiers are given, all the blocks will be run. The additional
+ validations are run on all the matching calls unless an `on`
+ modifier is supplied.
+
+* <b>on(<em>n</em>)</b>
+
+ If an `on` modifier is given, then the additional validations
+ supplied by `and` will only be run on the <em>n</em>'th invocation
+ of the matching method.
+
+*Examples:*
+
+```ruby
+ dog = flexmock(:on, Dog)
+
+ dog.wag(:tail)
+ dog.wag(:head)
+
+ dog.should have_received(:wag).with(:tail)
+ dog.should have_received(:wag).with(:head)
+ dog.should have_received(:wag).twice
+
+ dog.should_not have_received(:bark)
+ dog.should_not have_received(:wag).times(3)
+
+ dog.bark(3)
+ dog.bark(6)
+ dog.should have_received(:bark).with(Integer).and { |arg|
+ (arg % 3).should == 0
+ }
+ dog.should have_received(:bark).with(Integer).and { |arg|
+ arg.should == 6
+ }.on(2)
+
+```
+
+### Mocking Class Object
+
+In the previous example we mocked out the `bark` method of a Dog
+object to avoid invoking the Woofer object. Perhaps a better technique
+would be to mock the Woofer object directly. But Dog uses Woofer
+explicitly so we cannot just pass in a mock object for Dog to use.
+
+But wait, we can add mock behavior to any existing object, and classes
+are objects in Ruby. So why don't we just mock out the Woofer class
+object to return mocks for us.
+
+```ruby
+ class TestDogBarking < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ # Setup the tests by mocking the `new` method of
+ # Woofer and return a mock woofer.
+ def setup
+ flexmock(Woofer).should_receive(:new).
+ and_return(flexmock(:woof => :grrr))
+ @dog = Dog.new
+ end
+
+ def test_dog
+ assert_equal :grrrr, @dog.bark # Calls woof on mock object
+ # returned by Woofer.new
+ end
+ end
+```
+
+### Mocking Behavior in All Instances Created by a Class Object
+
+Sometimes returning a single mock object is not enough. Occasionally you want
+to mock _every_ instance object created by a class. FlexMock makes this
+very easy.
+
+```ruby
+ class TestDogBarking < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ # Setup the tests by mocking Woofer to always
+ # return partial mocks.
+ def setup
+ flexmock(Woofer).new_instances.should_receive(:woof => :grrr)
+ end
+
+ def test_dog
+ assert_equal :grrrr, Dog.new.bark # All dog objects
+ assert_equal :grrrr, Dog.new.bark # are mocked.
+ end
+ end
+```
+
+Note that FlexMock adds the mock expectations after the original `new`
+method has completed. If the original version of `new` yields the
+newly created instance to a block, that block will get an non-mocked
+version of the object.
+
+Note that `new_instances` will accept a block if you wish to mock
+several methods at the same time. E.g.
+
+```ruby
+ flexmock(Woofer).new_instances do |m|
+ m.should_receive(:woof).twice.and_return(:grrr)
+ m.should_receive(:wag).at_least.once.and_return(:happy)
+ end
+```
+
+### Default Expectations on Mocks
+
+Sometimes you want to setup a bunch of default expectations that are
+pretty much for a number of different tests. Then in the individual
+tests, you would like to override the default behavior on just that
+one method you are testing at the moment. You can do that by using
+the `by_default` modifier.
+
+In your test setup you might have:
+
+```ruby
+ def setup
+ @mock_dog = flexmock("Fido")
+ @mock_dog.should_receive(:tail => :a_tail, :bark => "woof").by_default
+ end
+```
+
+The behaviors for `:tail` and `:bark` are good for most of the tests,
+but perhaps you wish to verify that `:bark` is called exactly once in
+a given test. Since :bark by default has no count expectations, you
+can override the default in the given test.
+
+```ruby
+ def test_something_where_bark_must_be_called_once
+ @mock_dog.should_receive(:bark => "woof").once
+
+ # At this point, the default for :bark is ignored,
+ # and the "woof" value will be returned.
+
+ # However, the default for :tail (which returns :a_tail)
+ # is still active.
+ end
+```
+
+By setting defaults, your individual tests don't have to concern
+themselves with details of all the default setup. But the details of
+the overrides are right there in the body of the test.
+
+### Mocking Law of Demeter Violations
+
+The Law of Demeter says that you should only invoke methods on objects
+to which you have a direct connection, e.g. parameters, instance
+variables, and local variables. You can usually detect Law of Demeter
+violations by the excessive number of periods in an expression. For
+example:
+
+```ruby
+ car.chassis.axle.universal_joint.cog.turn
+```
+
+The Law of Demeter has a very big impact on mocking. If you need to
+mock the "turn" method on "cog", you first have to mock chassis, axle,
+and universal_joint.
+
+```ruby
+ # Manually mocking a Law of Demeter violation
+ cog = flexmock("cog")
+ cog.should_receive(:turn).once.and_return(:ok)
+ joint = flexmock("gear", :cog => cog)
+ axle = flexmock("axle", :universal_joint => joint)
+ chassis = flexmock("chassis", :axle => axle)
+ car = flexmock("car", :chassis => chassis)
+```
+
+Yuck!
+
+The best course of action is to avoid Law of Demeter violations. Then
+your mocking exploits will be very simple. However, sometimes you
+have to deal with code that already has a Demeter chain of method
+calls. So for those cases where you can't avoid it, FlexMock will
+allow you to easily mock Demeter method chains.
+
+Here's an example of Demeter chain mocking:
+
+```ruby
+ # Demeter chain mocking using the short form.
+ car = flexmock("car")
+ car.should_receive( "chassis.axle.universal_joint.cog.turn" => :ok).once
+```
+
+You can also use the long form:
+
+```ruby
+ # Demeter chain mocking using the long form.
+ car = flexmock("car")
+ car.should_receive("chassis.axle.universal_joint.cog.turn").once.
+ and_return(:ok)
+```
+
+That's it. Anywhere FlexMock accepts a method name for mocking, you
+can use a demeter chain and FlexMock will attempt to do the right
+thing.
+
+But beware, there are a few limitations.
+
+The all the methods in the chain, except for the last one, will mocked
+to return a mock object. That mock object, in turn, will be mocked so
+as to respond to the next method in the chain, returning the following
+mock. And so on. If you try to manually mock out any of the chained
+methods, you could easily interfer with the mocking specified by the
+Demeter chain. FlexMock will attempt to catch problems when it can,
+but there are certainly scenarios where it cannot detect the problem
+beforehand.
+
+## Examples
+
+Refer to the following documents for examples of using FlexMock:
+
+* [RSpec Examples](https://github.com/jimweirich/flexmock/blob/master/doc/examples/rspec_examples_spec.rb)
+* [Test::Unit / MiniTest Examples](https://github.com/jimweirich/flexmock/blob/master/doc/examples/test_unit_examples_test.rb)
+
+## License
+
+Copyright 2003-2013 by Jim Weirich (jim.weirich at gmail.com).
+All rights reserved.
+
+Permission is granted for use, copying, modification, distribution,
+and distribution of modified versions of this work as long as the
+above copyright notice is included.
+
+# Other stuff
+
+* **Author** -- Jim Weirich <jim.weirich at gmail.com>
+* **Requires** -- Ruby 1.9.2 or later (also works with Ruby 1.8.7)
+
+## See Also
+
+If you like the spy capability of FlexMock, you should check out the
+[rspec-given gem](http://rubygems.org/gems/rspec-given) that allows you
+to use Given/When/Then statements in you specifications.
+
+## Warranty
+
+This software is provided "as is" and without any express or implied
+warranties, including, without limitation, the implied warranties of
+merchantibility and fitness for a particular purpose.
diff --git a/README.rdoc b/README.rdoc
deleted file mode 100644
index d861042..0000000
--- a/README.rdoc
+++ /dev/null
@@ -1,945 +0,0 @@
-= Flex Mock -- Making Mock Easy
-
-FlexMock is a simple, but flexible, mock object library for Ruby unit
-testing.
-
-Version :: 0.9.0.beta.0
-
-= Links
-
-<b>Documents</b> :: http://flexmock.rubyforge.org
-<b>RubyGems</b> :: Install with: <b>gem install flexmock</b>
-<b>Download</b> :: Download from RubyForge at http://rubyforge.org/frs/?group_id=3433 (pre 0.6.0 versions may be found at http://rubyforge.org/frs/?group_id=170)
-<b>Issue Tracking</b> :: http://www.pivotaltracker.com/projects/28401
-<b>Bug Reports</b> :: http://onestepback.org/cgi-bin/bugs.cgi?project=flexmock
-
-== Installation
-
-You can install FlexMock with the following command.
-
- $ gem install flexmock
-
-== Simple Example
-
-We have a data acquisition class (+TemperatureSampler+) that reads a
-temperature sensor and returns an average of 3 readings. We don't
-have a _real_ temperature to use for testing, so we mock one up with a
-mock object that responds to the +read_temperature+ message.
-
-Here's the complete example:
-
- require 'test/unit'
- require 'flexmock/test_unit'
-
- class TemperatureSampler
- def initialize(sensor)
- @sensor = sensor
- end
-
- def average_temp
- total = (0...3).collect {
- @sensor.read_temperature
- }.inject { |i, s| i + s }
- total / 3.0
- end
- end
-
- class TestTemperatureSampler < Test::Unit::TestCase
- def test_sensor_can_average_three_temperature_readings
- sensor = flexmock("temp")
- sensor.should_receive(:read_temperature).times(3).
- and_return(10, 12, 14)
-
- sampler = TemperatureSampler.new(sensor)
- assert_equal 12, sampler.average_temp
- end
- end
-
-You can find an extended example of FlexMock in {Google
-Example}[http://flexmock.rubyforge.org/files/doc/GoogleExample_rdoc.html].
-
-== Test::Unit Integration
-
-FlexMock integrates nicely with Test::Unit. Just require the
-'flexmock/test_unit' file at the top of your test file. The +flexmock+ method
-will be available for mock creation, and any created mocks will be
-automatically validated and closed at the end of the individual test.
-
-Your test case will look something like this:
-
- require 'flexmock/test_unit'
-
- class TestDog < Test::Unit::TestCase
- def test_dog_wags
- tail_mock = flexmock(:wag => :happy)
- assert_equal :happy, tail_mock.wag
- end
- end
-
-<b>NOTE:</b> If you don't want to automatically extend every TestCase with the
-flexmock methods and overhead, then require the 'flexmock' file and explicitly
-include the FlexMock::TestCase module in each test case class where you wish
-to use mock objects. FlexMock versions prior to 0.6.0 required the explicit
-include.
-
-== RSpec Integration
-
-FlexMock also supports integration with the RSpec behavior
-specification framework. Starting with version 0.9.0 of RSpec, you
-will be able to say:
-
- Spec::Runner.configure do |config|
- config.mock_with :flexmock
- end
-
- describe "Using FlexMock with RSpec" do
- it "should be able to create a mock" do
- m = flexmock(:foo => :bar)
- m.foo.should === :bar
- end
- end
-
-If you wish to try this prior to the release of RSpec 0.9.0, check out
-the trunk of the RSpec subversion repository.
-
-== Quick Reference
-
-=== Creating Mock Objects
-
-The +flexmock+ method is used to create mocks in various
-configurations. Here's a quick rundown of the most common options.
-See FlexMock::MockContainer#flexmock for more details.
-
-* <b>mock = flexmock("joe")</b>
-
- Create a mock object named "joe" (the name is used in reporting errors).
-
-* <b>mock = flexmock(:foo => :bar, :baz => :froz)</b>
-
- Create a mock object and define two mocked methods (:foo and :baz) that
- return the values :bar and :froz respectively. This is useful when creating
- mock objects with just a few methods and simple return values.
-
-* <b>mock = flexmock("joe", :foo => :bar, :bar => :froz)</b>
-
- You can combine the mock name and an expectation hash in the same call to
- flexmock.
-
-* <b>partial_mock = flexmock(real_object)</b>
-
- If you you give +flexmock+ a real object in the argument list, it will treat
- that real object as a base for a partial mock object. The return value +m+
- may be used to set expectations. The real_object should be used in the
- reference portion of the test.
-
-* <b>partial_mock = flexmock(real_object, "name", :foo => :baz)</b>
-
- Names and expectation hashes may be used with partial mocks as well.
-
-* <b>partial_mock = flexmock(:base, real_string_object)</b>
-
- Since Strings (and Symbols for that matter) are used for mock names,
- FlexMock will not recognize them as the base for a partial mock. To force a
- string to be used as a partial mock base, proceed the string object in the
- calling sequence with :base.
-
-* <b>partial_mock = flexmock(:safe, real_object) { |mock| mock.should_receive(...) }</b>
-
- When mocking real objects (i.e. "partial mocks"), FlexMock will add
- a handful of mock related methods to the actual object (see below
- for list of method names). If one or more of these added methods
- collide with an existing method on the partial mock, then there are problems.
-
- FlexMock offers a "safe" mode for partial mocks that does not add
- these methods. Indicate safe mode by passing the symbol :safe as
- the first argument of flexmock. A block <em>is required</em> when
- using safe mode (the partial_mock returned in safe mode does not
- have a +should_receive+ method).
-
- The methods added to partial mocks in non-safe mode are:
-
- * should_receive
- * new_instances
- * any_instance (note: deprecated)
- * mock
- * mock_teardown
- * mock_setup
-
-* <b>mock = flexmock(...) { |mock| mock.should_receive(...) }</b>
-
- If a block is given to any of the +flexmock+ forms, the mock object will be
- passed to the block as an argument. Code in the block can set the desired
- expectations for the mock object.
-
-* <b>mock_model = flexmock(:model, YourModel, ...) { |mock| mock.should_receive(...) }</b>
-
- When given :model, flexmock() will return a pure mock (not a partial
- mock) that will have some ActiveRecord specific methods defined.
- YourModel should be the class of an ActiveRecord model. These
- predefined methods make it a bit easier to mock out ActiveRecord
- model objects in a Rails application. Other that the predefined
- mocked methods, the mock returned is a standard FlexMock mock
- object.
-
- The predefined mocked methods are:
-
- * id -- returns a unique ID for each mocked model.
- * to_params -- returns a stringified version of the id.
- * new_record? -- returns false.
- * errors -- returns an empty (mocked) errors object.
- * is_a?(other) -- returns true if other == YourModel.
- * instance_of?(class) -- returns true if class == YourModel
- * kind_of?(class) -- returns true if class is YourModel or one of its ancestors
- * class -- returns YourModel.
-
-<b>NOTE:</b> Versions of FlexMock prior to 0.6.0 used +flexstub+ to
-create partial mocks. The +flexmock+ method now assumes all the
-functionality that was spread out between two different methods.
-+flexstub+ is still available for backward compatibility.
-
-=== Expectation Declarators
-
-Once a mock is created, you need to define what that mock should expect to
-see. Expectation declarators are used to specify these expectations placed
-upon received method calls. A basic expectation, created with the
-+should_receive+ method, just establishes the fact that a method may (or may
-not) be called on the mock object. Refinements to that expectation may be
-additionally declared. FlexMock always starts with the most general
-expectation and adds constraints to that.
-
-For example, the following code:
-
- mock.should_receive(:average).and_return(12)
-
-Means that the mock will now accept method calls to an +average+ method. The
-expectation will accept any arguments and may be called any number of times
-(including zero times). Strictly speaking, the +and_return+ part of the
-declaration isn't exactly a constraint, but it does specify what value the
-mock will return when the expectation is matched.
-
-If you want to be more specific, you need to add additional constraints to
-your expectation. Here are some examples:
-
- mock.should_receive(:average).with(12).once
-
- mock.should_receive(:average).with(Integer).
- at_least.twice.at_most.times(10).
- and_return { rand }
-
-The following methods may be used to create and refine expectations on a mock
-object. See theFlexMock::Expectation for more details.
-
-* <b>should_receive(<em>method_name</em>)</b>
-
- Declares that a message named <em>method_name</em> will be sent to the mock
- object. Constraints on this expected message (called expectations) may be
- chained to the +should_receive+ call.
-
-* <b>should_receive(<em>method_name1</em>, <em>method_name2</em>, ...)</b>
-
- Define a number of expected messages that have the same constraints.
-
-* <b>should_receive(<em>meth1</em> => <em>result1</em>, <em>meth2</em> => <em>result2</em>, ...)</b>
-
- Define a number of expected messages that have the same constrants, but
- return different values.
-
-* <b>should_expect { |recorder| ... }</b>
-
- Creates a mock recording object that will translate received method calls
- into mock expectations. The recorder is passed to a block supplied with the
- +should_expect+ method. See examples below.
-
-* <b>with(<em>arglist</em>)</b>
-
- Declares that this expectation matches messages that match the given
- argument list. The <tt>===</tt> operator is used on a argument by argument
- basis to determine matching. This means that most literal values match
- literally, class values match any instance of a class and regular expression
- match any matching string (after a +to_s+ conversion). See argument
- validators (below) for details on argument validation options.
-
-* <b>with_any_args</b>
-
- Declares that this expectation matches the message with any argument
- (default)
-
-* <b>with_no_args</b>
-
- Declares that this expectation matches messages with no arguments
-
-* <b>and_return(<em>value</em>)</b>
-
- Declares that the expected message will return the given value.
-
-* <b>and_return(<em>value1</em>, <em>value2</em>, ...)</b>
-
- Declares that the expected message will return a series of values. Each
- invocation of the message will return the next value in the series. The last
- value will be repeatably returned if the number of matching calls exceeds
- the number of values.
-
-* <b>and_return { |args, ...| code ... } </b>
-
- Declares that the expected message will return the yielded value of the
- block. The block will receive all the arguments in the message. If the
- message was provided a block, it will be passed as the last parameter of the
- block's argument list.
-
-* <b>returns( ... )</b>
-
- Alias for <tt>and_return</tt>.
-
-* <b>and_raise(exception, *args)</b>
-
- Declares that the expected messsage will raise the specified
- exception. If +exception+ is an exception class, then the raised
- exception will be constructed from the class with +new+ given the
- supplied arguments. If +exception+ is an instance of an exception
- class, then it will be raised directly.
-
-* <b>raises( ... )</b>
-
- Alias for <tt>and_raise</tt>.
-
-* <b>and_throw(symbol)</b>
-* <b>and_throw(symbol, value)</b>
-
- Declares that the expected messsage will throw the specified symbol.
- If an optional value is included, then it will be the value returned
- from the corresponding catch statement.
-
-* <b>throws( ... )</b>
-
- Alias for <tt>and_throw</tt>.
-
-* <b>and_yield(values, ...)</b>
-
- Declares that the mocked method will receive a block, and the mock
- will call that block with the values given. Not providing a block
- will be an error. Providing more than one +and_yield+ clause one a
- single expectation will mean that subsquent mock method calls will
- yield the values provided by the additional +and_yield+ clause.
-
-* <b>yields( ... )</b>
-
- Alias for <tt>and_yield( ... )</tt>.
-
-* <b>zero_or_more_times</b>
-
- Declares that the expected message is may be sent zero or more times
- (default, equivalent to <tt>at_least.never</tt>).
-
-* <b>once</b>
-
- Declares that the expected message is only sent once. <tt>at_least</tt> /
- <tt>at_most</tt> modifiers are allowed.
-
-* <b>twice</b>
-
- Declares that the expected message is only sent twice. <tt>at_least</tt> /
- <tt>at_most</tt> modifiers are allowed.
-
-* <b>never</b>
-
- Declares that the expected message is never sent. <tt>at_least</tt> /
- <tt>at_most</tt> modifiers are allowed.
-
-* <b>times(<em>n</em>)</b>
-
- Declares that the expected message is sent <em>n</em> times.
- <tt>at_least</tt> / <tt>at_most</tt> modifiers are allowed.
-
-* <b>at_least</b>
-
- Modifies the immediately following message count constraint so that it means
- the message is sent at least that number of times. E.g.
- <tt>at_least.once</tt> means the message is sent at least once during the
- test, but may be sent more often. Both <tt>at_least</tt> and
- <tt>at_most</tt> may be specified on the same expectation.
-
-* <b>at_most</b>
-
- Similar to <tt>at_least</tt>, but puts an upper limit on the number of
- messages. Both <tt>at_least</tt> and <tt>at_most</tt> may be specified on
- the same expectation.
-
-* <b>ordered</b>
-
- Declares that the expected message is ordered and is expected to be received
- in a certain position in a sequence of messages. The message should arrive
- after and previously declared ordered messages and prior to any following
- declared ordered messages. Unordered messages are ignored when considering
- the message order.
-
- Normally ordering is performed only against calls in the same mock
- object. If the "globally" adjective is used, then ordering is
- performed against the other globally ordered method calls.
-
-* <b>ordered(<em>group</em>)</b>
-
- Declare that the expected message belongs to an order group. Methods within
- an order group may be received in any order. Ordered messages outside the
- group must be received either before or after all of the grouped messages.
-
- For example, in the following, messages +flip+ and +flop+ may be received in
- any order (because they are in the same group), but must occur strictly
- after +start+ but before +end+. The message +any_time+ may be received at
- any time because it is not ordered.
-
- m = flexmock()
- m.should_receive(:any_time)
- m.should_receive(:start).ordered
- m.should_receive(:flip).ordered(:flip_flop_group)
- m.should_receive(:flop).ordered(:flip_flop_group)
- m.should_receive(:end).ordered
-
- Normally ordering is performed only against calls in the same mock
- object. If the "globally" adjective is used, then ordering is
- performed against the other globally ordered method calls.
-
-* <b>globally.ordered</b>
-* <b>globally.ordered(<em>group_name</em>)</b>
-
- When modified by the "globally" adjective, the mock call will be
- ordered against other globally ordered methods in any of the mock
- objects in the same container (i.e. same test). All the options of
- the per-mock ordering are available in the globally ordered method
- calls.
-
-* <b>by_default</b>
-
- Marks the expectation as a default. Default expectations act as
- normal as long as there are no non-default expectations for the same
- method name. As soon as a non-default expectation is defined, all
- default expectations for that method name are ignored.
-
- Default expectations allow you to setup a set of default behaviors
- for various methods in the setup of a test suite, and then override
- only the methods that need special handling in any given test.
-
-* <b>mock</b>
-
- Expectation constraints always return the expectation so that the
- constraints can be chained. If you wish to do a one-liner and assign the
- mock to a variable, the +mock+ method on an expectation will return the
- original mock object.
-
- m = flexmock.should_receive(:hello).once.and_return("World").mock
-
- <b>NOTE:</b> <em>Using <b>mock</b> when specifying a Demeter mock
- chain will return the last mock of the chain, which might not be
- what you expect.
-
-=== Argument Validation
-
-The values passed to the +with+ declarator determine the criteria for matching
-expectations. The first expectation found that matches the arguments in a mock
-method call will be used to validate that mock method call.
-
-The following rules are used for argument matching:
-
-* A +with+ parameter that is a class object will match any actual argument
- that is an instance of that class.
-
- Examples:
-
- with(Integer) will match f(3)
-
-* A regular expression will match any actual argument that matches the regular
- expression. Non-string actual arguments are converted to strings via +to_s+
- before applying the regular expression.
-
- Examples:
-
- with(/^src/) will match f("src_object")
- with(/^3\./) will match f(3.1415972)
-
-* Most other objects will match based on equal values.
-
- Examples:
-
- with(3) will match f(3)
- with("hello") will match f("hello")
-
-* If you wish to override the default matching behavior and force matching by
- equality, you can use the FlexMock.eq convenience method. This is mostly
- used when you wish to match class objects, since the default matching
- behavior for class objects is to match instances, not themselves.
-
- Examples:
-
- with(eq(Integer)) will match f(Integer)
- with(eq(Integer)) will NOT match f(3)
-
- <b>Note:</b> If you do not use the FlexMock::TestCase Test Unit
- integration module, or the FlexMock::ArgumentTypes module, you will
- have to fully qualify the +eq+ method. This is true of all the
- special argument matches (+eq+, +on+, +any+, +hsh+ and +ducktype+).
-
- with(FlexMock.eq(Integer))
- with(FlexMock.on { code })
- with(FlexMock.any)
- with(FlexMock.hsh(:tag => 3))
- with(FlexMock.ducktype(:wag => "dog"))
-
-* If you wish to match a hash on _some_ of its values, the
- FlexMock.hsh(...) method will work. Only specify the hash values
- you are interested in, the others will be ignored.
-
- with(hsh(:run => true)) will match f(:run => true, :stop => false)
-
-* If you wish to match any object that responds to a certain set of
- methods, use the FlexMock.ducktype method.
-
- with(ducktype(:to_str)) will match f("string")
- with(ducktype(:wag, :bark)) will match f(dog)
- (assuming dog implements wag and bark)
-
-* If you wish to match _anything_, then use the <tt>FlexMock.any</tt>
- method in the with argument list.
-
- Examples (assumes either the FlexMock::TestCase or FlexMock::ArgumentTypes
- mix-ins has been included):
-
- with(any) will match f(3)
- with(any) will match f("hello")
- with(any) will match f(Integer)
- with(any) will match f(nil)
-
-* If you wish to specify a complex matching criteria, use the
- <tt>FlexMock.on(&block)</tt> with the logic contained in the block.
-
- Examples (assumes FlexMock::ArgumentTypes has been included):
-
- with(on { |arg| (arg % 2) == 0 } )
-
- will match any even integer.
-
-* If you wish to match a method call where a block is given, add
- <tt>Proc</tt> as the last argument to <tt>with</tt>.
-
- Example:
-
- m.should_receive(:foo).with(Integer,Proc).and_return(:got_block)
- m.should_receive(:foo).with(Integer).and_return(:no_block)
-
- will cause the mock to return the following:
-
- m.foo(1) { } => returns :got_block
- m.foo(1) => returns :no_block
-
-=== Creating Partial Mocks
-
-Sometimes it is useful to mock the behavior of one or two methods in an
-existing object without changing the behavior of the rest of the object. If
-you pass a real object to the +flexmock+ method, it will allow you to use that
-real object in your test and will just mock out the one or two methods that
-you specify.
-
-For example, suppose that a Dog object uses a Woofer object to bark. The code
-for Dog looks like this (we will leave the code for Woofer to your
-imagination):
-
- class Dog
- def initialize
- @woofer = Woofer.new
- end
- def bark
- @woofer.woof
- end
- def wag
- :happy
- end
- end
-
-Now we want to test Dog, but using a real Woofer object in the test is a real
-pain (why? ... well because Woofer plays a sound file of a dog barking, and
-that's really annoying during testing).
-
-So, how can we create a Dog object with mocked Woofer? All we need to do is
-allow FlexMock to replace the +bark+ method.
-
-Here's the test code:
-
- class TestDogBarking < Test::Unit::TestCase
- include FlexMock::TestCase
-
- # Setup the tests by mocking the +new+ method of
- # Woofer and return a mock woofer.
- def setup
- @dog = Dog.new
- flexmock(@dog, :bark => :grrr)
- end
-
- def test_dog
- assert_equal :grrr, @dog.bark # Mocked Method
- assert_equal :happy, @dog.wag # Normal Method
- end
- end
-
-The nice thing about this technique is that after the test is over, the mocked
-out methods are returned to their normal state. Outside the test everything is
-back to normal.
-
-<b>NOTE:</b> In previous versions of FlexMock, partial mocking was called
-"stubs" and the +flexstub+ method was used to create the partial mocks.
-Although partial mocks were often used as stubs, the terminology was not quite
-correct. The current version of FlexMock uses the +flexmock+ method to create
-both regular stubs and partial stubs. A version of the +flexstub+ method is
-included for backwards compatibility. See Martin Fowler's article <em>Mocks
-Aren't Stubs</em> (http://www.martinfowler.com/articles/mocksArentStubs.html)
-for a better understanding of the difference between mocks and stubs.
-
-This partial mocking technique was inspired by the +Stuba+ library in the
-+Mocha+ project.
-
-=== Mocking Class Objects
-
-In the previous example we mocked out the +bark+ method of a Dog object to
-avoid invoking the Woofer object. Perhaps a better technique would be to mock
-the Woofer object directly. But Dog uses Woofer explicitly so we cannot just
-pass in a mock object for Dog to use.
-
-But wait, we can add mock behavior to any existing object, and classes are
-objects in Ruby. So why don't we just mock out the Woofer class object to
-return mocks for us.
-
- class TestDogBarking < Test::Unit::TestCase
- include FlexMock::TestCase
-
- # Setup the tests by mocking the +new+ method of
- # Woofer and return a mock woofer.
- def setup
- flexmock(Woofer).should_receive(:new).
- and_return(flexmock(:woof => :grrr))
- @dog = Dog.new
- end
-
- def test_dog
- assert_equal :grrrr, @dog.bark # Calls woof on mock object
- # returned by Woofer.new
- end
- end
-
-=== Mocking Behavior in All Instances Created by a Class Object
-
-Sometimes returning a single mock object is not enough. Occasionally you want
-to mock <em>every</em> instance object created by a class. FlexMock makes this
-very easy.
-
- class TestDogBarking < Test::Unit::TestCase
- include FlexMock::TestCase
-
- # Setup the tests by mocking Woofer to always
- # return partial mocks.
- def setup
- flexmock(Woofer).new_instances.should_receive(:woof => :grrr)
- end
-
- def test_dog
- assert_equal :grrrr, Dog.new.bark # All dog objects
- assert_equal :grrrr, Dog.new.bark # are mocked.
- end
- end
-
-Note that FlexMock adds the mock expectations after the original +new+ method
-has completed. If the original version of +new+ yields the newly created
-instance to a block, that block will get an non-mocked version of the object.
-
-Note that +new_instances+ will accept a block if you wish to mock several
-methods at the same time. E.g.
-
- flexmock(Woofer).new_instances do |m|
- m.should_receive(:woof).twice.and_return(:grrr)
- m.should_receive(:wag).at_least.once.and_return(:happy)
- end
-
-=== Default Expectations on Mocks
-
-Sometimes you want to setup a bunch of default expectations that are
-pretty much for a number of different tests. Then in the individual
-tests, you would like to override the default behavior on just that
-one method you are testing at the moment. You can do that by using
-the <tt>by_default</tt> modifier.
-
-In your test setup you might have:
-
- def setup
- @mock_dog = flexmock("Fido")
- @mock_dog.should_receive(:tail => :a_tail, :bark => "woof").by_default
- end
-
-The behaviors for :tail and :bark are good for most of the tests, but
-perhaps you wish to verify that :bark is called exactly once in a
-given test. Since :bark by default has no count expectations, you can
-override the default in the given test.
-
- def test_something_where_bark_must_be_called_once
- @mock_dog.should_receive(:bark => "woof").once
-
- # At this point, the default for :bark is ignored,
- # and the "woof" value will be returned.
-
- # However, the default for :tail (which returns :a_tail)
- # is still active.
- end
-
-By setting defaults, your individual tests don't have to concern
-themselves with details of all the default setup. But the details of
-the overrides are right there in the body of the test.
-
-=== Mocking Law of Demeter Violations
-
-The Law of Demeter says that you should only invoke methods on objects
-to which you have a direct connection, e.g. parameters, instance
-variables, and local variables. You can usually detect Law of Demeter
-violations by the excessive number of periods in an expression. For
-example:
-
- car.chassis.axle.universal_joint.cog.turn
-
-The Law of Demeter has a very big impact on mocking. If you need to
-mock the "turn" method on "cog", you first have to mock chassis, axle,
-and universal_joint.
-
- # Manually mocking a Law of Demeter violation
- cog = flexmock("cog")
- cog.should_receive(:turn).once.and_return(:ok)
- joint = flexmock("gear", :cog => cog)
- axle = flexmock("axle", :universal_joint => joint)
- chassis = flexmock("chassis", :axle => axle)
- car = flexmock("car", :chassis => chassis)
-
-Yuck!
-
-The best course of action is to avoid Law of Demeter violations. Then
-your mocking exploits will be very simple. However, sometimes you
-have to deal with code that already has a Demeter chain of method
-calls. So for those cases where you can't avoid it, FlexMock will
-allow you to easily mock Demeter method chains.
-
-Here's an example of Demeter chain mocking:
-
- # Demeter chain mocking using the short form.
- car = flexmock("car")
- car.should_receive( "chassis.axle.universal_joint.cog.turn" => :ok).once
-
-You can also use the long form:
-
- # Demeter chain mocking using the long form.
- car = flexmock("car")
- car.should_receive("chassis.axle.universal_joint.cog.turn").once.
- and_return(:ok)
-
-That's it. Anywhere FlexMock accepts a method name for mocking, you
-can use a demeter chain and FlexMock will attempt to do the right
-thing.
-
-But beware, there are a few limitations.
-
-The all the methods in the chain, except for the last one, will mocked
-to return a mock object. That mock object, in turn, will be mocked so
-as to respond to the next method in the chain, returning the following
-mock. And so on. If you try to manually mock out any of the chained
-methods, you could easily interfer with the mocking specified by the
-Demeter chain. FlexMock will attempt to catch problems when it can,
-but there are certainly scenarios where it cannot detect the problem
-beforehand.
-
-== Examples
-
-=== Create a simple mock object that returns a value for a set of method calls
-
- require 'flexmock/test_unit'
-
- class TestSimple < Test::Unit::TestCase
- def test_simple_mock
- m = flexmock(:pi => 3.1416, :e => 2.71)
- assert_equal 3.1416, m.pi
- assert_equal 2.71, m.e
- end
- end
-
-=== Create a mock object that returns an undefined object for method calls
-
- require 'flexmock/test_unit'
-
- class TestUndefined < Test::Unit::TestCase
- def test_undefined_values
- m = flexmock("mock")
- m.should_receive(:divide_by).with(0).
- and_return_undefined
- assert_equal FlexMock.undefined, m.divide_by(0)
- end
- end
-
-=== Expect multiple queries and a single update
-
-Multiple calls to the query method will be allows, and calls may have any
-argument list. Each call to query will return the three element array [1, 2,
-3]. The call to update must have a specific argument of 5.
-
- require 'flexmock/test_unit'
-
- class TestDb < Test::Unit::TestCase
- def test_db
- db = flexmock('db')
- db.should_receive(:query).and_return([1,2,3])
- db.should_receive(:update).with(5).and_return(nil).once
- # test code here
- end
- end
-
-=== Expect all queries before any updates
-
-(This and following examples assume that the 'flexmock/test_unit' file has
-been required.)
-
-All the query message must occur before any of the update messages.
-
- def test_query_and_update
- db = flexmock('db')
- db.should_receive(:query).and_return([1,2,3]).ordered
- db.should_receive(:update).and_return(nil).ordered
- # test code here
- end
-
-=== Expect several queries with different parameters
-
-The queries should happen after startup but before finish. The
-queries themselves may happen in any order (because they are in the
-same order group). The first two queries should happen exactly once,
-but the third query (which matches any query call with a four
-character parameter) may be called multiple times (but at least once).
-Startup and finish must also happen exactly once.
-
-Also note that we use the +with+ method to match different argument
-values to figure out what value to return.
-
- def test_ordered_queries
- db = flexmock('db')
- db.should_receive(:startup).once.ordered
- db.should_receive(:query).with("CPWR").and_return(12.3).
- once.ordered(:queries)
- db.should_receive(:query).with("MSFT").and_return(10.0).
- once.ordered(:queries)
- db.should_receive(:query).with(/^....$/).and_return(3.3).
- at_least.once.ordered(:queries)
- db.should_receive(:finish).once.ordered
- # test code here
- end
-
-=== Same as above, but using the Record Mode interface
-
-The record mode interface offers much the same features as the
-+should_receive+ interface introduced so far, but it allows the
-messages to be sent directly to a recording object rather than be
-specified indirectly using a symbol.
-
- def test_ordered_queries_in_record_mode
- db = flexmock('db')
- db.should_expect do |rec|
- rec.startup.once.ordered
- rec.query("CPWR") { 12.3 }.once.ordered(:queries)
- rec.query("MSFT") { 10.0 }.once.ordered(:queries)
- rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries)
- rec.finish.once.ordered
- end
- # test code here using +db+.
- end
-
-=== Using Record Mode to record a known, good algorithm for testing
-
-Record mode is nice when you have a known, good algorithm that can use
-a recording mock object to record the steps. Then you compare the
-execution of a new algorithm to behavior of the old using the recorded
-expectations in the mock. For this you probably want to put the
-recorder in _strict_ mode so that the recorded expectations use exact
-matching on argument lists, and strict ordering of the method calls.
-
-<b>Note:</b> This is most useful when there are no queries on the mock
-objects, because the query responses cannot be programmed into the
-recorder object.
-
- def test_build_xml
- builder = flexmock('builder')
- builder.should_expect do |rec|
- rec.should_be_strict
- known_good_way_to_build_xml(rec) # record the messages
- end
- new_way_to_build_xml(builder) # compare to new way
- end
-
-=== Expect multiple calls, returning a different value each time
-
-Sometimes you need to return different values for each call to a
-mocked method. This example shifts values out of a list for this
-effect.
-
- def test_multiple_gets
- file = flexmock('file')
- file.should_receive(:gets).with_no_args.
- and_return("line 1\n", "line 2\n")
- # test code here
- end
-
-=== Ignore uninteresting messages
-
-Generally you need to mock only those methods that return an
-interesting value or wish to assert were sent in a particular manner.
-Use the +should_ignore_missing+ method to turn on missing method
-ignoring.
-
- def test_an_important_message
- m = flexmock('m')
- m.should_receive(:an_important_message).and_return(1).once
- m.should_ignore_missing
- # test code here
- end
-
-When +should_ignore_missing+ is enabled, ignored missing methods will
-return an undefined object. Any operation on the undefined object
-will return the undefined object.
-
-=== Mock just one method on an existing object
-
-The Portfolio class calculate the value of a set of stocks by talking
-to a quote service via a web service. Since we don't want to use a
-real web service in our unit tests, we will mock the quote service.
-
- def test_portfolio_value
- flexmock(QuoteService).new_instances do |m|
- m.should_receive(:quote).and_return(100)
- end
- port = Portfolio.new
- value = port.value # Portfolio calls QuoteService.quote
- assert_equal 100, value
- end
-
-== Other Mock Objects
-
-test-unit-mock :: http://www.deveiate.org/code/Test-Unit-Mock.shtml
-mocha/stubba :: http://mocha.rubyforge.org/
-Schmock :: http://rubyforge.org/projects/schmock/
-
-== License
-
-Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim at weirichhouse.org).
-All rights reserved.
-
-Permission is granted for use, copying, modification, distribution,
-and distribution of modified versions of this work as long as the
-above copyright notice is included.
-
-= Other stuff
-
-Author:: Jim Weirich <jim at weirichhouse.org>
-Requires:: Ruby 1.8.7 or later (Use Flexmock-0.8.8 for Ruby version 1.8.6)
-
-== Warranty
-
-This software is provided "as is" and without any express or
-implied warranties, including, without limitation, the implied
-warranties of merchantibility and fitness for a particular
-purpose.
diff --git a/Rakefile b/Rakefile
index 5577d4b..a6e590e 100644
--- a/Rakefile
+++ b/Rakefile
@@ -23,6 +23,12 @@ load './lib/flexmock/version.rb'
PKG_VERSION = FlexMock::VERSION
+EXAMPLE_RB = FileList['doc/examples/*.rb']
+EXAMPLE_DOC = EXAMPLE_RB.ext('rdoc')
+
+CLOBBER.include(EXAMPLE_DOC)
+CLEAN.include('pkg/flexmock-*').exclude("pkg/*.gem")
+
PKG_FILES = FileList[
'[A-Z]*',
'lib/**/*.rb',
@@ -32,13 +38,13 @@ PKG_FILES = FileList[
]
RDOC_FILES = FileList[
- 'README.rdoc',
+ 'doc/index.rdoc',
'CHANGES',
'lib/**/*.rb',
'doc/**/*.rdoc',
-]
+] + EXAMPLE_DOC
-task :default => [:test_all]
+task :default => [:test_all, :rspec, :testunit]
task :test_all => [:test]
task :test_units => [:test]
task :ta => [:test_all]
@@ -52,19 +58,27 @@ Rake::TestTask.new do |t|
t.warning = true
end
-Rake::TestTask.new(:test_extended) do |t|
- t.test_files = FileList['test/extended/*_test.rb']
- t.verbose = true
- t.warning = true
+module Configuration
+ def self.minitest?
+ require 'minitest/autorun'
+ return true
+ rescue Exception
+ return false
+ end
+end
+
+task :testunit do
+ files = FileList['test/test_unit_integration/*_test.rb']
+ if ! Configuration.minitest?
+ files = files.reject { |fn| fn =~ /minitest/ }
+ end
+ files.each do |file|
+ sh "ruby -Ilib:. #{file}"
+ end
end
task :rspec do
- ENV['RUBYLIB'] = "/Users/jim/working/svn/software/flexmock/lib"
- sh 'echo $RUBYLIB'
- sh "spec test/rspec_integration/*_spec.rb" rescue nil
- puts
- puts "*** There should be three failures in the above report. ***"
- puts
+ sh "rspec test/rspec_integration"
end
# RCov Target --------------------------------------------------------
@@ -83,14 +97,47 @@ end
# RDoc Target --------------------------------------------------------
-task :rdoc => ["html/index.html"]
+task :rdoc => ["html/index.html", :fixcss]
file "html/index.html" => ["Rakefile"] + RDOC_FILES do
- sh "rdoc -o html --title FlexMock --line-numbers -m README.rdoc #{RDOC_FILES}"
+ sh "rdoc -o html --title FlexMock --line-numbers -m doc/index.rdoc #{RDOC_FILES}"
+end
+
+EXAMPLE_RB.zip(EXAMPLE_DOC).each do |source, target|
+ file target => source do
+ open(source, "r") do |ins|
+ open(target, "w") do |outs|
+ outs.puts "= FlexMock Examples"
+ ins.each do |line|
+ outs.puts " #{line}"
+ end
+ end
+ end
+ end
end
-file "README.rdoc" => ["Rakefile", "lib/flexmock/version.rb"] do
- ruby %{-i.bak -pe '$_.sub!(/^Version *:: *(\\d+\\.)+\\d+ *$/, "Version :: #{PKG_VERSION}")' README.rdoc} # "
+file "README.md" => ["Rakefile", "lib/flexmock/version.rb"] do
+ ruby %{-i.bak -pe '$_.sub!(/^Version: *((\\d+|beta|rc)\\.)+\\d+ *$/i, "Version :: #{PKG_VERSION}")' README.md} # "
+end
+
+desc "Fix the Darkfish CSS so that paragraphs in lists have a bit of spacing"
+task :fixcss do
+ open("html/rdoc.css") do |ins|
+ open("html/rdoc.new", "w") do |outs|
+ count = 0
+ ins.each do |line|
+ if line =~ /^ *margin: +0;$/
+ count += 1
+ if count == 3
+ line = " margin: 0.5em 0;"
+ end
+ end
+ outs.puts line
+ end
+ end
+ end
+ rm_f "html/rdoc.css"
+ mv "html/rdoc.new", "html/rdoc.css"
end
# Package Task -------------------------------------------------------
diff --git a/TAGS b/TAGS
index a6f6797..0202462 100644
--- a/TAGS
+++ b/TAGS
@@ -1,210 +1,292 @@
-doc/jamis.rb,43
+(null),255
+ def known_good_way_to_build_xml(builder)known_good_way_to_build_xml160,4493
+ def new_way_to_build_xml(builder)new_way_to_build_xml164,4562
+ class QuoteServiceQuoteService235,6473
+ class PortfolioPortfolio238,6501
+ def valuevalue239,6519
+
+doc/examples/test_unit_examples_test.rb,1490
+class TestSimple < Test::Unit::TestCaseTestSimple3,30
+ def test_simple_mocktest_simple_mock7,108
+class TestUndefined < Test::Unit::TestCaseTestUndefined15,244
+ def test_undefined_valuestest_undefined_values19,364
+class TestDb < Test::Unit::TestCaseTestDb27,549
+ def test_dbtest_db36,862
+class TestOrdered < Test::Unit::TestCaseTestOrdered48,1069
+ def test_query_and_updatetest_query_and_update55,1231
+class MoreOrdered < Test::Unit::TestCaseMoreOrdered67,1457
+ def test_ordered_queriestest_ordered_queries81,2092
+class EvenMoreOrderedTest < Test::Unit::TestCaseEvenMoreOrderedTest102,2633
+ def test_ordered_queries_in_record_modetest_ordered_queries_in_record_mode112,2998
+class RecordedTest < Test::Unit::TestCaseRecordedTest132,3462
+ def test_build_xmltest_build_xml148,4182
+ def known_good_way_to_build_xml(builder)known_good_way_to_build_xml157,4437
+ def new_way_to_build_xml(builder)new_way_to_build_xml161,4506
+class MultipleReturnValueTest < Test::Unit::TestCaseMultipleReturnValueTest167,4573
+ def test_multiple_getstest_multiple_gets175,4844
+class IgnoreUnimportantMessages < Test::Unit::TestCaseIgnoreUnimportantMessages187,5119
+ def test_an_important_messagetest_an_important_message196,5444
+class PartialMockTest < Test::Unit::TestCasePartialMockTest213,5869
+ def test_portfolio_valuetest_portfolio_value222,6185
+ class QuoteServiceQuoteService231,6439
+ class PortfolioPortfolio234,6467
+ def valuevalue235,6485
+
+,43
module RDocRDoc1,0
module PagePage2,12
+dual_spec.rb,0
+
install.rb,29
def indir(newdir)indir7,68
-lib/flexmock/argument_matchers.rb,722
-class FlexMockFlexMock14,319
- class AnyMatcherAnyMatcher17,426
- def ===(target)===18,445
- def inspectinspect21,484
- class EqualMatcherEqualMatcher28,636
- def initialize(obj)initialize29,657
- def ===(target)===32,706
- def inspectinspect35,755
- class ProcMatcherProcMatcher44,966
- def initialize(&block)initialize45,986
- def ===(target)===48,1042
- def inspectinspect51,1096
- class HashMatcherHashMatcher58,1271
- def initialize(hash)initialize59,1291
- def ===(target)===62,1343
- def inspectinspect65,1414
- class DuckMatcherDuckMatcher72,1603
- def initialize(methods)initialize73,1623
- def ===(target)===76,1684
- def inspectinspect79,1762
-
-lib/flexmock/argument_types.rb,228
-class FlexMockFlexMock14,331
- module ArgumentTypesArgumentTypes21,624
- def anyany23,707
- def eq(obj)eq29,834
- def on(&block)on36,1034
- def hsh(hash)hsh42,1175
- def ducktype(*methods)ducktype48,1352
+,880
+class FlexMockFlexMock14,320
+ class AnyMatcherAnyMatcher17,427
+ def ===(target)===18,446
+ def inspectinspect21,485
+ class EqualMatcherEqualMatcher28,637
+ def initialize(obj)initialize29,658
+ def ===(target)===32,707
+ def inspectinspect35,756
+ class ProcMatcherProcMatcher44,967
+ def initialize(&block)initialize45,987
+ def ===(target)===48,1043
+ def inspectinspect51,1097
+ class HashMatcherHashMatcher58,1269
+ def initialize(hash)initialize59,1289
+ def ===(target)===62,1341
+ def inspectinspect65,1412
+ class DuckMatcherDuckMatcher72,1607
+ def initialize(methods)initialize73,1627
+ def ===(target)===76,1688
+ def inspectinspect79,1766
+ class OptionalProcMatcherOptionalProcMatcher86,1990
+ def initializeinitialize87,2018
+ def ===(target)===89,2045
+ def inspectinspect92,2132
+
+lib/flexmock/argument_matching.rb,224
+class FlexMockFlexMock1,0
+ module ArgumentMatchingArgumentMatching2,15
+ def all_match?(expected_args, actual_args)all_match?7,92
+ def match?(expected, actual)match?23,595
+ def missing?(arg)missing?29,752
+
+,272
+class FlexMockFlexMock14,332
+ module ArgumentTypesArgumentTypes21,625
+ def anyany23,708
+ def eq(obj)eq29,835
+ def on(&block)on36,1035
+ def hsh(hash)hsh42,1176
+ def ducktype(*methods)ducktype48,1353
+ def optional_procoptional_proc52,1420
lib/flexmock/base.rb,0
-lib/flexmock/composite.rb,30
+,87
+class ClassClass10,415
+ def flexmock_defined?(method_name)flexmock_defined?13,491
+
+,30
class FlexMockFlexMock8,133
-lib/flexmock/core.rb,900
-class FlexMockFlexMock46,1270
- def initialize(name="unknown", container=nil)initialize55,1540
- def inspectinspect65,1834
- def flexmock_verifyflexmock_verify71,1994
- def flexmock_teardownflexmock_teardown82,2235
- def should_ignore_missingshould_ignore_missing86,2315
- def by_defaultby_default91,2427
- def method_missing(sym, *args, &block)method_missing97,2556
- def respond_to?(sym, *args)respond_to?114,3028
- def flexmock_find_expectation(method_name, *args) # :nodoc:flexmock_find_expectation119,3184
- def flexmock_expectations_for(method_name) # :nodoc:flexmock_expectations_for125,3389
- def method(sym)method130,3548
- def should_receive(*args)should_receive159,4587
- def should_expectshould_expect182,5330
- def flexmock_wrap(&block)flexmock_wrap190,5520
- def override_existing_method(sym)override_existing_method204,6075
- def sclasssclass213,6295
-
-lib/flexmock/core_class_methods.rb,289
-class FlexMockFlexMock15,352
- def use(*names)use39,1293
- def format_args(sym, args) # :nodoc:format_args53,1691
- def check(msg, &block) # :nodoc:check63,1992
- class UseContainerUseContainer70,2165
- def initializeinitialize75,2247
- def passed?passed?79,2304
+lib/flexmock/core.rb,1372
+class FlexMockFlexMock49,1379
+ def initialize(name="unknown", container=nil)initialize58,1649
+ def inspectinspect70,1981
+ def flexmock_verifyflexmock_verify76,2141
+ def flexmock_teardownflexmock_teardown87,2382
+ def should_ignore_missingshould_ignore_missing91,2462
+ def by_defaultby_default97,2583
+ def matches?(sym, actual_args, options)matches?103,2727
+ def matches_block?(block_option)matches_block?111,2924
+ def method_missing(sym, *args, &block)method_missing119,3147
+ def respond_to?(sym, *args)respond_to?140,3840
+ def flexmock_find_expectation(method_name, *args) # :nodoc:flexmock_find_expectation145,3996
+ def flexmock_expectations_for(method_name) # :nodoc:flexmock_expectations_for151,4201
+ def flexmock_based_on(base_class)flexmock_based_on155,4294
+ def flexmock_received?(sym, args, options={})flexmock_received?161,4469
+ def flexmock_callsflexmock_calls183,5096
+ def flexmock_invoke_original(sym, args)flexmock_invoke_original189,5211
+ def method(sym)method194,5356
+ def should_receive(*args)should_receive223,6395
+ def flexmock_define_expectation(location, *args)flexmock_define_expectation228,6507
+ def should_expectshould_expect252,7384
+ def flexmock_wrap(&block)flexmock_wrap260,7574
+ def override_existing_method(sym)override_existing_method274,8129
+ def sclasssclass283,8349
+
+,335
+class FlexMockFlexMock15,353
+ def use(*names)use39,1294
+ def format_call(sym, args) # :nodoc:format_call53,1691
+ def format_args(args)format_args59,1865
+ def check(msg, &block) # :nodoc:check69,2129
+ class UseContainerUseContainer76,2302
+ def initializeinitialize81,2384
+ def passed?passed?85,2441
lib/flexmock/default_framework_adapter.rb,345
-class FlexMockFlexMock14,318
- class DefaultFrameworkAdapterDefaultFrameworkAdapter15,333
- def assert_block(msg, &block)assert_block16,365
- def assert_equal(a, b, msg=nil)assert_equal22,478
- class AssertionFailedError < StandardError; endAssertionFailedError26,578
- def assertion_failed_errorassertion_failed_error27,630
+class FlexMockFlexMock14,319
+ class DefaultFrameworkAdapterDefaultFrameworkAdapter15,334
+ def assert_block(msg, &block)assert_block16,366
+ def assert_equal(a, b, msg=nil)assert_equal23,521
+ class AssertionFailedError < StandardError; endAssertionFailedError27,621
+ def assertion_failed_errorassertion_failed_error28,673
lib/flexmock/deprecated_methods.rb,340
-class ModuleModule13,295
- def flexmock_deprecate(*method_names)flexmock_deprecate14,308
-class FlexMockFlexMock33,808
- def mock_handle(sym, expected_count=nil, &block) # :nodoc:mock_handle40,1106
- class PartialMockProxyPartialMockProxy47,1396
- def any_instance(&block)any_instance53,1553
- module OrderingOrdering59,1701
-
-lib/flexmock/errors.rb,137
-class FlexMockFlexMock14,319
- class UsageError < ::RuntimeErrorUsageError17,387
- class MockError < ::RuntimeErrorMockError20,430
-
-lib/flexmock/expectation.rb,2059
-class FlexMockFlexMock14,318
- class ExpectationExpectation28,851
- def initialize(mock, sym)initialize34,997
- def to_sto_s49,1359
- def verify_call(*args)verify_call55,1541
- def _return_value(args) # :nodoc:_return_value64,1761
- def return_value(args)return_value69,1901
- def perform_yielding(args)perform_yielding83,2229
- def eligible?eligible?99,2814
- def call_count_constrained?call_count_constrained?104,2963
- def validate_ordervalidate_order109,3067
- def flexmock_verifyflexmock_verify121,3442
- def match_args(args)match_args129,3639
- def match_arg(expected, actual)match_arg138,3985
- def with(*args)with145,4214
- def with_no_argswith_no_args151,4348
- def with_any_argswith_any_args157,4481
- def and_return(*args, &block)and_return188,5490
- def and_return_undefinedand_return_undefined212,6207
- def and_yield(*yield_values)and_yield228,6776
- def and_raise(exception, *args)and_raise252,7529
- def and_throw(sym, value=nil)and_throw266,7894
- def zero_or_more_timeszero_or_more_times272,8069
- def times(limit)times279,8292
- def nevernever288,8639
- def onceonce295,8854
- def twicetwice302,9069
- def at_leastat_least314,9395
- def at_mostat_most327,9774
- def ordered(group_name=nil)ordered356,11043
- def globallyglobally368,11423
- def define_ordered(group_name, ordering)define_ordered374,11538
- def by_defaultby_default388,12036
- class CompositeExpectationCompositeExpectation399,12443
- def initializeinitialize402,12517
- def add(expectation)add407,12613
- def method_missing(sym, *args, &block)method_missing412,12754
- def order_numberorder_number423,13129
- def mockmock428,13239
- def should_receive(*args, &block)should_receive434,13403
- def to_sto_s439,13549
- class ExpectationRecorderExpectationRecorder453,14007
- def initializeinitialize456,14067
- def method_missing(sym, *args, &block)method_missing461,14178
- def apply(mock)apply469,14450
-
-lib/flexmock/expectation_director.rb,483
-class FlexMockFlexMock15,344
- class ExpectationDirectorExpectationDirector20,555
- def initialize(sym)initialize23,639
- def call(*args)call38,1187
- def <<(expectation)<<46,1440
- def find_expectation(*args) # :nodoc:find_expectation51,1564
- def flexmock_verify # :nodoc:flexmock_verify62,1938
- def defaultify_expectation(exp) # :nodoc:defaultify_expectation69,2149
- def find_expectation_in(expectations, *args)find_expectation_in81,2430
-
-lib/flexmock/mock_container.rb,944
-class FlexMockFlexMock16,380
- module MockContainerMockContainer26,781
- def flexmock_teardownflexmock_teardown31,965
- def flexmock_verifyflexmock_verify40,1208
- def flexmock_created_mocksflexmock_created_mocks49,1448
- def flexmock_closeflexmock_close55,1668
- def flexmock(*args)flexmock123,4876
- def flexmock_remember(mocking_object)flexmock_remember165,6148
- class MockContainerHelperMockContainerHelper181,6798
- def next_idnext_id185,6907
- def parse_should_args(mock, args, &block) # :nodoc:parse_should_args198,7380
- def add_model_methods(mock, model_class, id)add_model_methods216,7893
- def make_partial_proxy(container, obj, name, safe_mode)make_partial_proxy245,9111
- def build_demeter_chain(mock, arg, &block)build_demeter_chain291,11097
- def check_proper_mock(mock, method_name)check_proper_mock316,11944
- def check_method_names(names)check_method_names326,12348
+class ModuleModule13,296
+ def flexmock_deprecate(*method_names)flexmock_deprecate14,309
+class FlexMockFlexMock33,809
+ def mock_handle(sym, expected_count=nil, &block) # :nodoc:mock_handle40,1107
+ class PartialMockProxyPartialMockProxy47,1397
+ def any_instance(&block)any_instance53,1554
+ module OrderingOrdering59,1702
+
+,137
+class FlexMockFlexMock14,320
+ class UsageError < ::RuntimeErrorUsageError17,388
+ class MockError < ::RuntimeErrorMockError20,431
+
+lib/flexmock/expectation.rb,2211
+class FlexMockFlexMock15,356
+ class ExpectationExpectation29,889
+ def initialize(mock, sym, location)initialize35,1035
+ def to_sto_s51,1434
+ def descriptiondescription62,1705
+ def verify_call(*args)verify_call73,2081
+ def _return_value(args) # :nodoc:_return_value82,2301
+ def return_value(args)return_value87,2441
+ def perform_yielding(args)perform_yielding101,2769
+ def eligible?eligible?117,3354
+ def call_count_constrained?call_count_constrained?122,3503
+ def validate_ordervalidate_order127,3607
+ def flexmock_verifyflexmock_verify139,3982
+ def match_args(args)match_args147,4179
+ def with(*args)with152,4338
+ def with_no_argswith_no_args158,4472
+ def with_any_argswith_any_args164,4605
+ def and_return(*args, &block)and_return195,5614
+ def and_return_undefinedand_return_undefined219,6331
+ def and_yield(*yield_values)and_yield235,6900
+ def and_raise(exception, *args)and_raise259,7653
+ def and_throw(sym, value=nil)and_throw273,8018
+ def pass_thru(&block)pass_thru278,8128
+ def zero_or_more_timeszero_or_more_times286,8367
+ def times(limit)times293,8590
+ def nevernever302,8937
+ def onceonce309,9152
+ def twicetwice316,9367
+ def at_leastat_least328,9693
+ def at_mostat_most341,10072
+ def ordered(group_name=nil)ordered370,11341
+ def globallyglobally382,11721
+ def define_ordered(group_name, ordering)define_ordered388,11836
+ def explicitlyexplicitly404,12417
+ def by_defaultby_default408,12456
+ def flexmock_location_filterflexmock_location_filter413,12606
+ class CompositeExpectationCompositeExpectation426,12999
+ def initializeinitialize429,13073
+ def add(expectation)add434,13169
+ def method_missing(sym, *args, &block)method_missing439,13310
+ def order_numberorder_number450,13685
+ def mockmock455,13795
+ def should_receive(*args, &block)should_receive461,13959
+ def to_sto_s466,14132
+ class ExpectationRecorderExpectationRecorder480,14590
+ def initializeinitialize483,14650
+ def method_missing(sym, *args, &block)method_missing488,14761
+ def apply(mock)apply496,15033
+
+,499
+class FlexMockFlexMock15,345
+ class ExpectationDirectorExpectationDirector20,556
+ def initialize(sym)initialize23,640
+ def call(args, call_record=nil)call38,1188
+ def <<(expectation)<<47,1509
+ def find_expectation(*args) # :nodoc:find_expectation52,1633
+ def flexmock_verify # :nodoc:flexmock_verify63,2007
+ def defaultify_expectation(exp) # :nodoc:defaultify_expectation70,2218
+ def find_expectation_in(expectations, *args)find_expectation_in82,2499
+
+,285
+class FlexMockFlexMock2,1
+ class ExplicitNeededExplicitNeeded11,389
+ def initialize(expectation, method_name, base_class)initialize12,412
+ def explicitlyexplicitly19,599
+ def explicit?explicit?24,661
+ def method_missing(sym, *args, &block)method_missing28,704
+
+lib/flexmock/mock_container.rb,1023
+class FlexMockFlexMock16,381
+ module MockContainerMockContainer26,782
+ def flexmock_teardownflexmock_teardown31,966
+ def flexmock_verifyflexmock_verify38,1146
+ def flexmock_created_mocksflexmock_created_mocks45,1302
+ def flexmock_closeflexmock_close51,1522
+ def flexmock(*args)flexmock119,4730
+ def flexmock_remember(mocking_object)flexmock_remember173,6352
+ def flexmock_test_has_failed?flexmock_test_has_failed?186,6823
+ class MockContainerHelperMockContainerHelper199,7335
+ def next_idnext_id203,7444
+ def parse_should_args(mock, args, &block) # :nodoc:parse_should_args216,7917
+ def add_model_methods(mock, model_class, id, location)add_model_methods234,8430
+ def make_partial_proxy(container, obj, name, safe_mode)make_partial_proxy263,9888
+ def build_demeter_chain(mock, arg, &block)build_demeter_chain309,11874
+ def check_proper_mock(mock, method_name)check_proper_mock334,12721
+ def check_method_names(names)check_method_names344,13130
lib/flexmock/noop.rb,0
-lib/flexmock/ordering.rb,399
-class FlexMockFlexMock12,293
- module OrderingOrdering20,665
- def flexmock_allocate_orderflexmock_allocate_order23,732
- def flexmock_groupsflexmock_groups29,895
- def flexmock_current_orderflexmock_current_order34,1003
- def flexmock_current_order=(value)flexmock_current_order=39,1126
- def flexmock_validate_order(method_name, order_number)flexmock_validate_order43,1212
-
-lib/flexmock/partial_mock.rb,1375
-class FlexMockFlexMock14,318
- class PartialMockProxyPartialMockProxy26,948
- def initialize(obj, mock, safe_mode)initialize40,1285
- def flexmock_getflexmock_get56,1685
- def should_receive(*args)should_receive80,2625
- def add_mock_method(method_name)add_mock_method91,2903
- def new_instances(*allocators, &block)new_instances123,4119
- def invoke_original(method, args)invoke_original144,4920
- def flexmock_verifyflexmock_verify152,5214
- def flexmock_teardownflexmock_teardown157,5350
- def flexmock_containerflexmock_container169,5688
- def flexmock_container=(container)flexmock_container=175,5883
- def flexmock_expectations_for(method_name)flexmock_expectations_for179,5999
- def sclasssclass186,6160
- def singleton?(method_name)singleton?192,6301
- def hide_existing_method(method_name)hide_existing_method202,6763
- def stow_existing_definition(method_name)stow_existing_definition209,6980
- def create_alias_for_existing_method(method_name)create_alias_for_existing_method229,7697
- def define_proxy_method(method_name)define_proxy_method247,8216
- def restore_original_definition(method_name)restore_original_definition268,8964
- def remove_current_method(method_name)remove_current_method280,9328
- def detached?detached?285,9489
- def new_name(old_name)new_name290,9597
-
-lib/flexmock/rails/view_mocking.rb,665
+,104
+class ObjectObject1,0
+ def flexmock_singleton_defined?(method_name)flexmock_singleton_defined?2,13
+
+,399
+class FlexMockFlexMock12,294
+ module OrderingOrdering20,666
+ def flexmock_allocate_orderflexmock_allocate_order23,733
+ def flexmock_groupsflexmock_groups29,896
+ def flexmock_current_orderflexmock_current_order34,1004
+ def flexmock_current_order=(value)flexmock_current_order=39,1127
+ def flexmock_validate_order(method_name, order_number)flexmock_validate_order43,1213
+
+lib/flexmock/partial_mock.rb,1813
+class FlexMockFlexMock14,319
+ class PartialMockProxyPartialMockProxy26,949
+ def initialize(obj, mock, safe_mode)initialize42,1368
+ def flexmock_getflexmock_get58,1768
+ def should_receive(*args)should_receive82,2708
+ def flexmock_define_expectation(location, *args)flexmock_define_expectation87,2828
+ def add_mock_method(method_name)add_mock_method98,3152
+ def new_instances(*allocators, &block)new_instances130,4368
+ def invoke_original(method, args)invoke_original155,5376
+ def flexmock_invoke_original(method, args)flexmock_invoke_original161,5530
+ def flexmock_verifyflexmock_verify167,5762
+ def flexmock_teardownflexmock_teardown172,5898
+ def flexmock_containerflexmock_container184,6236
+ def flexmock_received?(*args)flexmock_received?189,6329
+ def flexmock_callsflexmock_calls194,6436
+ def flexmock_container=(container)flexmock_container=200,6623
+ def flexmock_expectations_for(method_name)flexmock_expectations_for204,6739
+ def check_allocate_method(allocate_method)check_allocate_method210,6859
+ def sclasssclass217,7122
+ def singleton?(method_name)singleton?221,7177
+ def hide_existing_method(method_name)hide_existing_method231,7638
+ def stow_existing_definition(method_name)stow_existing_definition238,7855
+ def create_alias_for_existing_method(method_name)create_alias_for_existing_method258,8572
+ def safe_alias_method(new_alias, method_name)safe_alias_method270,9014
+ def define_proxy_method(method_name)define_proxy_method283,9375
+ def restore_original_definition(method_name)restore_original_definition304,10133
+ def remove_current_method(method_name)remove_current_method321,10604
+ def detached?detached?326,10765
+ def new_name(old_name)new_name331,10873
+
+,665
class FlexMockFlexMock3,20
module MockContainerMockContainer4,35
def rails_versionrails_version6,59
@@ -215,109 +297,185 @@ class FlexMockFlexMock3,20
def should_render_view_22x(template_name)should_render_view_22x109,3813
def should_render_view_23x(template_name)should_render_view_23x129,4575
-lib/flexmock/rails.rb,0
+,0
lib/flexmock/recorder.rb,271
-class FlexMockFlexMock14,328
- class RecorderRecorder20,504
- def initialize(mock)initialize24,610
- def should_be_strict(is_strict=true)should_be_strict48,1542
- def strict?strict?53,1656
- def method_missing(sym, *args, &block)method_missing59,1786
+class FlexMockFlexMock14,329
+ class RecorderRecorder20,505
+ def initialize(mock)initialize24,611
+ def should_be_strict(is_strict=true)should_be_strict48,1543
+ def strict?strict?53,1657
+ def method_missing(sym, *args, &block)method_missing59,1787
+
+lib/flexmock/rspec/configure.rb,0
lib/flexmock/rspec.rb,341
-class FlexMockFlexMock14,319
- class RSpecFrameworkAdapterRSpecFrameworkAdapter21,416
- def assert_block(msg, &block)assert_block22,446
- def assert_equal(a, b, msg=nil)assert_equal26,548
- class AssertionFailedError < StandardError; endAssertionFailedError31,711
- def assertion_failed_errorassertion_failed_error32,763
-
-lib/flexmock/test_unit.rb,120
-module TestTest14,335
- module UnitUnit15,347
- class TestCaseTestCase16,361
- def teardownteardown25,676
-
-lib/flexmock/test_unit_integration.rb,227
-class FlexMockFlexMock15,338
- module TestCaseTestCase29,895
- def teardownteardown35,1070
- class TestUnitFrameworkAdapterTestUnitFrameworkAdapter45,1277
- def assertion_failed_errorassertion_failed_error47,1345
-
-lib/flexmock/undefined.rb,288
-class FlexMockFlexMock12,293
- class UndefinedUndefined17,464
- def method_missing(sym, *args, &block)method_missing18,482
- def to_sto_s22,545
- def inspectinspect26,587
- def cloneclone30,623
- def coerce(other)coerce34,657
- def self.undefinedundefined43,862
-
-lib/flexmock/validators.rb,545
-class FlexMockFlexMock14,318
- class CountValidatorCountValidator19,454
- def initialize(expectation, limit)initialize20,477
- def eligible?(n)eligible?28,733
- class ExactCountValidator < CountValidatorExactCountValidator36,898
- def validate(n)validate39,1022
- class AtLeastCountValidator < CountValidatorAtLeastCountValidator48,1313
- def validate(n)validate51,1439
- def eligible?(n)eligible?61,1856
- class AtMostCountValidator < CountValidatorAtMostCountValidator69,2039
- def validate(n)validate71,2154
-
-lib/flexmock.rb,0
+class FlexMockFlexMock16,321
+ class RSpecFrameworkAdapterRSpecFrameworkAdapter23,418
+ def assert_block(msg, &block)assert_block24,448
+ def assert_equal(a, b, msg=nil)assert_equal29,590
+ class AssertionFailedError < StandardError; endAssertionFailedError34,753
+ def assertion_failed_errorassertion_failed_error35,805
-test/redirect_error.rb,114
-class FlexMockFlexMock3,20
- module RedirectErrorRedirectError4,35
- def redirect_errorredirect_error5,58
+�3�,778
+class FlexMockFlexMock3,35
+ module RSpecMatchersRSpecMatchers4,50
+ class HaveReceivedHaveReceived6,74
+ def initialize(method_name)initialize9,126
+ def matches?(spy)matches?18,332
+ def failure_message_for_shouldfailure_message_for_should24,486
+ def failure_message_for_should_notfailure_message_for_should_not28,604
+ def with(*args)with32,735
+ def with_a_blockwith_a_block37,802
+ def without_a_blockwithout_a_block42,877
+ def times(n)times47,956
+ def nevernever52,1018
+ def onceonce56,1062
+ def twicetwice60,1105
+ def on(on_count)on64,1149
+ def and(&block)and69,1225
+ def construct_optionsconstruct_options74,1312
+ def have_received(method_name)have_received84,1537
+
+,603
+class FlexMockFlexMock1,0
+ module SpyDescribersSpyDescribers3,16
+ def describe_spy_expectation(spy, sym, args, options={})describe_spy_expectation4,41
+ def describe_spy_negative_expectation(spy, sym, args, options={})describe_spy_negative_expectation8,161
+ def describe_spy(spy, sym, args, options, not_clause="")describe_spy14,313
+ def describe_calls(spy)describe_calls26,733
+ def times_description(times)times_description41,1280
+ def block_description(needs_block)block_description56,1529
+ def call_description(sym, args)call_description67,1736
+
+,120
+class SymbolSymbol1,0
+ def flexmock_as_nameflexmock_as_name5,58
+ def flexmock_as_nameflexmock_as_name10,117
+
+,120
+module TestTest14,336
+ module UnitUnit15,348
+ class TestCaseTestCase16,362
+ def teardownteardown25,677
+
+,328
+class FlexMockFlexMock3,35
+ module TestUnitAssertionsTestUnitAssertions4,50
+ def assert_spy_called(spy, method_name, *args)assert_spy_called7,115
+ def assert_spy_not_called(spy, method_name, *args)assert_spy_not_called11,232
+ def _assert_spy_called(negative, spy, method_name, *args)_assert_spy_called17,365
+
+lib/flexmock/test_unit_integration.rb,282
+class FlexMockFlexMock16,397
+ module TestCaseTestCase30,954
+ def teardownteardown37,1160
+ class TestUnitFrameworkAdapterTestUnitFrameworkAdapter47,1367
+ def assert_block(msg, &block)assert_block50,1436
+ def assertion_failed_errorassertion_failed_error60,1697
+
+,318
+class FlexMockFlexMock12,294
+ class UndefinedUndefined17,465
+ def method_missing(sym, *args, &block)method_missing18,483
+ def to_sto_s22,546
+ def inspectinspect26,588
+ def cloneclone30,624
+ def <=>(other)<=>34,658
+ def coerce(other)coerce38,697
+ def self.undefinedundefined47,902
+
+lib/flexmock/validators.rb,878
+class FlexMockFlexMock15,353
+ class CountValidatorCountValidator20,489
+ def initialize(expectation, limit)initialize23,549
+ def eligible?(n)eligible?31,805
+ def calls(n)calls36,875
+ def describedescribe41,983
+ def describe_limitdescribe_limit54,1165
+ def validate_count(n, &block)validate_count58,1215
+ class ExactCountValidator < CountValidatorExactCountValidator74,1741
+ def validate(n)validate77,1865
+ class AtLeastCountValidator < CountValidatorAtLeastCountValidator85,2079
+ def validate(n)validate88,2205
+ def describedescribe93,2325
+ def eligible?(n)eligible?105,2668
+ def describe_limitdescribe_limit109,2709
+ class AtMostCountValidator < CountValidatorAtMostCountValidator117,2910
+ def validate(n)validate119,3025
+ def describedescribe124,3144
+ def describe_limitdescribe_limit128,3195
+
+lib/flexmock/version.rb,58
+class FlexMockFlexMock1,0
+ module VersionVersion2,15
+
+pjw_94jc0000gn/T//tags.zA7zNy,0
-test/rspec_integration/integration_spec.rb,0
-
-test/test_aliasing.rb,521
-class FlexMockFlexMock5,48
- module StubsAndExpectsStubsAndExpects6,63
- def expects(*args)expects7,88
- def stubs(*args)stubs12,234
- module MockContainerMockContainer17,298
- class PartialMockProxyPartialMockProxy24,407
-class AliasingTest < Test::Unit::TestCaseAliasingTest30,510
- def test_mockingtest_mocking33,582
- def test_once_mockingtest_once_mocking39,741
- def test_twice_mockingtest_twice_mocking43,837
- def test_stubbingtest_stubbing48,1004
- def test_partialtest_partial53,1127
-
-test/test_container_methods.rb,1111
-class TestFlexmockContainerMethods < Test::Unit::TestCaseTestFlexmockContainerMethods15,378
- def test_simple_mock_creationtest_simple_mock_creation18,466
- def test_mock_with_nametest_mock_with_name24,605
- def test_mock_with_symbol_nametest_mock_with_symbol_name31,802
- def test_mock_with_hashtest_mock_with_hash38,1005
- def test_mock_with_name_and_hashtest_mock_with_name_and_hash44,1148
- def test_mock_with_name_hash_and_blocktest_mock_with_name_hash_and_block53,1444
- def test_basic_stubtest_basic_stub61,1665
- def test_basic_stub_with_nametest_basic_stub_with_name68,1825
- def test_stub_with_quick_definitionstest_stub_with_quick_definitions76,2075
- def test_stub_with_name_quick_definitionstest_stub_with_name_quick_definitions82,2219
- def test_stubs_are_auto_verifiedtest_stubs_are_auto_verified91,2531
- def test_stubbing_a_stringtest_stubbing_a_string98,2721
- def test_multiple_stubs_work_with_same_partial_mock_proxytest_multiple_stubs_work_with_same_partial_mock_proxy104,2846
- def test_multiple_stubs_layer_behaviortest_multiple_stubs_layer_behavior111,3016
-
-test/test_default_framework_adapter.rb,473
-class TestFlexmockDefaultFrameworkAdapter < Test::Unit::TestCaseTestFlexmockDefaultFrameworkAdapter14,320
- def setupsetup15,385
- def test_assert_block_raises_exceptiontest_assert_block_raises_exception19,457
- def test_assert_block_doesnt_raise_exceptiontest_assert_block_doesnt_raise_exception25,649
- def test_assert_equal_doesnt_raise_exceptiontest_assert_equal_doesnt_raise_exception29,757
- def test_assert_equal_can_failtest_assert_equal_can_fail33,861
-
-test/test_demeter_mocking.rb,1568
+,0
+
+test/assert_spy_called_test.rb,1272
+class AssertSpyCalledTest < Test::Unit::TestCaseAssertSpyCalledTest6,95
+ class FooBarFooBar9,174
+ def foofoo10,189
+ def barbar12,209
+ def setupsetup16,236
+ def spyspy21,298
+ def test_assert_detects_basic_calltest_assert_detects_basic_call25,324
+ def test_assert_detects_basic_call_with_argstest_assert_detects_basic_call_with_args30,412
+ def test_assert_rejects_incorrect_argstest_assert_rejects_incorrect_args35,521
+ def test_assert_detects_multiple_callstest_assert_detects_multiple_calls42,742
+ def test_assert_rejects_incorrect_typetest_assert_rejects_incorrect_type49,873
+ def test_assert_detects_blockstest_assert_detects_blocks57,1114
+ def test_assert_detects_any_argstest_assert_detects_any_args64,1252
+ def test_assert_rejects_bad_count_on_any_argstest_assert_rejects_bad_count_on_any_args72,1442
+ def test_assert_error_lists_calls_actually_made_without_handled_bytest_assert_error_lists_calls_actually_made_without_handled_by79,1686
+ def test_assert_error_lists_calls_actually_made_with_handled_bytest_assert_error_lists_calls_actually_made_with_handled_by91,2077
+ def test_assert_errors_say_no_calls_madetest_assert_errors_say_no_calls_made103,2487
+ def assert_fails(message_pattern)assert_fails111,2644
+
+test/base_class_test.rb,1070
+class BaseClassTest < Test::Unit::TestCaseBaseClassTest3,27
+ class FooBarFooBar6,100
+ def foofoo7,115
+ def method_missing(sym, *args, &block)method_missing10,136
+ def respond_to?(method)respond_to?15,235
+ def mockmock20,309
+ def test_base_class_auto_mocks_classtest_base_class_auto_mocks_class24,363
+ def test_base_class_auto_mocks_base_class_methodstest_base_class_auto_mocks_base_class_methods28,445
+ def test_base_class_does_not_mock_non_base_class_methodstest_base_class_does_not_mock_non_base_class_methods32,550
+ def test_can_stub_existing_methodstest_can_stub_existing_methods38,675
+ def test_can_not_stub_non_class_defined_methodstest_can_not_stub_non_class_defined_methods43,789
+ def test_can_not_stub_non_class_methods_in_single_linetest_can_not_stub_non_class_methods_in_single_line52,1097
+ def test_can_explicitly_stub_non_class_defined_methodstest_can_explicitly_stub_non_class_defined_methods61,1418
+ def test_can_explicitly_stub_meta_programmed_methodstest_can_explicitly_stub_meta_programmed_methods66,1572
+
+test/container_methods_test.rb,1111
+class TestFlexmockContainerMethods < Test::Unit::TestCaseTestFlexmockContainerMethods15,379
+ def test_simple_mock_creationtest_simple_mock_creation18,467
+ def test_mock_with_nametest_mock_with_name24,606
+ def test_mock_with_symbol_nametest_mock_with_symbol_name31,803
+ def test_mock_with_hashtest_mock_with_hash38,1006
+ def test_mock_with_name_and_hashtest_mock_with_name_and_hash44,1149
+ def test_mock_with_name_hash_and_blocktest_mock_with_name_hash_and_block53,1445
+ def test_basic_stubtest_basic_stub61,1666
+ def test_basic_stub_with_nametest_basic_stub_with_name68,1826
+ def test_stub_with_quick_definitionstest_stub_with_quick_definitions76,2076
+ def test_stub_with_name_quick_definitionstest_stub_with_name_quick_definitions82,2213
+ def test_stubs_are_auto_verifiedtest_stubs_are_auto_verified91,2525
+ def test_stubbing_a_stringtest_stubbing_a_string98,2710
+ def test_multiple_stubs_work_with_same_partial_mock_proxytest_multiple_stubs_work_with_same_partial_mock_proxy104,2828
+ def test_multiple_stubs_layer_behaviortest_multiple_stubs_layer_behavior111,2998
+
+,473
+class TestFlexmockDefaultFrameworkAdapter < Test::Unit::TestCaseTestFlexmockDefaultFrameworkAdapter14,321
+ def setupsetup15,386
+ def test_assert_block_raises_exceptiontest_assert_block_raises_exception19,458
+ def test_assert_block_doesnt_raise_exceptiontest_assert_block_doesnt_raise_exception25,645
+ def test_assert_equal_doesnt_raise_exceptiontest_assert_equal_doesnt_raise_exception29,753
+ def test_assert_equal_can_failtest_assert_equal_can_fail33,857
+
+,1568
class TestDemeterMocking < Test::Unit::TestCaseTestDemeterMocking5,48
def test_demeter_mockingtest_demeter_mocking8,126
def test_demeter_mocking_with_operatorstest_demeter_mocking_with_operators16,353
@@ -327,84 +485,100 @@ class TestDemeterMocking < Test::Unit::TestCaseTestDemeterMocking5,48
def test_final_method_can_have_multiple_expecationstest_final_method_can_have_multiple_expecations45,1280
def test_conflicting_mock_declarations_raises_an_errortest_conflicting_mock_declarations_raises_an_error53,1571
def test_conflicting_mock_declarations_in_reverse_order_does_not_raise_errortest_conflicting_mock_declarations_in_reverse_order_does_not_raise_error65,1976
- def test_preestablishing_existing_mock_is_oktest_preestablishing_existing_mock_is_ok75,2320
- def test_quick_defs_can_use_demeter_mockingtest_quick_defs_can_use_demeter_mocking83,2583
- def test_quick_defs_can_use_demeter_mocking_twotest_quick_defs_can_use_demeter_mocking_two93,2892
- def test_errors_on_ill_formed_method_namestest_errors_on_ill_formed_method_names100,3121
- def test_no_errors_on_well_formed_method_namestest_no_errors_on_well_formed_method_names109,3375
- def test_readme_example_1test_readme_example_1118,3593
- def test_readme_example_2test_readme_example_2128,3967
- def test_readme_example_3test_readme_example_3134,4168
-
-test/test_deprecated_methods.rb,2237
-class TestFlexMock < Test::Unit::TestCaseTestFlexMock15,358
- def s(&block)s19,464
- def setupsetup23,514
- def test_handletest_handle27,562
- def test_handle_no_blocktest_handle_no_block34,706
- def test_called_with_blocktest_called_with_block40,836
- def test_return_valuetest_return_value47,1034
- def test_handle_missing_methodtest_handle_missing_method52,1139
- def test_ignore_missing_methodtest_ignore_missing_method60,1369
- def test_good_countstest_good_counts66,1500
- def test_bad_countstest_bad_counts74,1639
- def test_undetermined_countstest_undetermined_counts85,1846
- def test_zero_countstest_zero_counts94,1991
- def test_file_io_with_usetest_file_io_with_use103,2160
- def count_lines(stream)count_lines111,2364
- def test_usetest_use119,2478
- def test_failures_during_usetest_failures_during_use128,2625
- def test_sequential_valuestest_sequential_values138,2844
- def test_respond_to_returns_false_for_non_handled_methodstest_respond_to_returns_false_for_non_handled_methods147,3076
- def test_respond_to_returns_true_for_explicit_methodstest_respond_to_returns_true_for_explicit_methods151,3211
- def test_respond_to_returns_true_for_missing_methods_when_ignoring_missingtest_respond_to_returns_true_for_missing_methods_when_ignoring_missing156,3370
- def test_respond_to_returns_true_for_missing_methods_when_ignoring_missing_using_shouldtest_respond_to_returns_true_for_missing_methods_when_ignoring_missing_using_should161,3551
- def test_method_proc_raises_error_on_unknowntest_method_proc_raises_error_on_unknown166,3747
- def test_method_returns_callable_proctest_method_returns_callable_proc172,3865
- def test_method_returns_do_nothing_proc_for_missing_methodstest_method_returns_do_nothing_proc_for_missing_methods181,4121
-class TestDeprecatedOrderingMethods < Test::Unit::TestCaseTestDeprecatedOrderingMethods189,4348
- def test_deprecated_ordering_methodstest_deprecated_ordering_methods193,4471
-class TestAnyInstance < Test::Unit::TestCaseTestAnyInstance205,4867
- class DogDog209,4976
- def barkbark210,4988
- def test_any_instance_still_works_for_backwards_compatibilitytest_any_instance_still_works_for_backwards_compatibility215,5028
-
-test/test_examples_from_readme.rb,1206
-class TemperatureSamplerTemperatureSampler14,320
- def initialize(sensor)initialize15,345
- def average_tempaverage_temp19,398
-class TestTemperatureSampler < Test::Unit::TestCaseTestTemperatureSampler25,525
- def test_tempurature_samplertest_tempurature_sampler28,607
-class TestExamplesFromReadme < Test::Unit::TestCaseTestExamplesFromReadme37,886
- def test_simple_return_valuestest_simple_return_values40,968
- def test_returning_an_undefined_valuetest_returning_an_undefined_value46,1108
- def test_dbtest_db52,1246
- def test_query_and_updatetest_query_and_update61,1476
- def test_ordered_queriestest_ordered_queries70,1729
- def test_ordered_queries_in_record_modetest_ordered_queries_in_record_mode88,2326
- def test_build_xmltest_build_xml105,2858
- def known_good_way_to_build_xml(rec)known_good_way_to_build_xml114,3113
- def new_way_to_build_xml(rec)new_way_to_build_xml119,3183
- def test_multiple_getstest_multiple_gets123,3271
- def test_an_important_messagetest_an_important_message132,3516
- class QuoteServiceQuoteService141,3746
- class PortfolioPortfolio143,3773
- def valuevalue144,3791
- def test_portfolio_valuetest_portfolio_value149,3849
-
-test/test_extended_should_receive.rb,808
-module ExtendedShouldReceiveTestsExtendedShouldReceiveTests14,320
- def test_accepts_expectation_hashtest_accepts_expectation_hash15,354
- def test_accepts_list_of_methodstest_accepts_list_of_methods21,518
- def test_contraints_apply_to_all_expectationstest_contraints_apply_to_all_expectations28,676
- def test_count_contraints_apply_to_all_expectationstest_count_contraints_apply_to_all_expectations35,943
- def test_multiple_should_receives_are_allowedtest_multiple_should_receives_are_allowed41,1134
-class TestExtendedShouldReceiveOnFullMocks < Test::Unit::TestCaseTestExtendedShouldReceiveOnFullMocks49,1351
- def setupsetup53,1484
-class TestExtendedShouldReceiveOnPartialMockProxies < Test::Unit::TestCaseTestExtendedShouldReceiveOnPartialMockProxies60,1554
- def setupsetup64,1696
-
-test/test_flexmodel.rb,528
+ def test_preestablishing_existing_mock_is_oktest_preestablishing_existing_mock_is_ok75,2318
+ def test_quick_defs_can_use_demeter_mockingtest_quick_defs_can_use_demeter_mocking83,2581
+ def test_quick_defs_can_use_demeter_mocking_twotest_quick_defs_can_use_demeter_mocking_two93,2890
+ def test_errors_on_ill_formed_method_namestest_errors_on_ill_formed_method_names100,3119
+ def test_no_errors_on_well_formed_method_namestest_no_errors_on_well_formed_method_names109,3373
+ def test_readme_example_1test_readme_example_1118,3591
+ def test_readme_example_2test_readme_example_2128,3965
+ def test_readme_example_3test_readme_example_3134,4166
+
+test/deprecated_methods_test.rb,2237
+class TestFlexMock < Test::Unit::TestCaseTestFlexMock15,359
+ def s(&block)s19,465
+ def setupsetup23,515
+ def test_handletest_handle27,563
+ def test_handle_no_blocktest_handle_no_block34,707
+ def test_called_with_blocktest_called_with_block40,837
+ def test_return_valuetest_return_value47,1035
+ def test_handle_missing_methodtest_handle_missing_method52,1140
+ def test_ignore_missing_methodtest_ignore_missing_method60,1370
+ def test_good_countstest_good_counts66,1501
+ def test_bad_countstest_bad_counts74,1640
+ def test_undetermined_countstest_undetermined_counts85,1847
+ def test_zero_countstest_zero_counts94,1992
+ def test_file_io_with_usetest_file_io_with_use103,2161
+ def count_lines(stream)count_lines111,2358
+ def test_usetest_use119,2465
+ def test_failures_during_usetest_failures_during_use128,2612
+ def test_sequential_valuestest_sequential_values138,2831
+ def test_respond_to_returns_false_for_non_handled_methodstest_respond_to_returns_false_for_non_handled_methods147,3063
+ def test_respond_to_returns_true_for_explicit_methodstest_respond_to_returns_true_for_explicit_methods151,3198
+ def test_respond_to_returns_true_for_missing_methods_when_ignoring_missingtest_respond_to_returns_true_for_missing_methods_when_ignoring_missing156,3357
+ def test_respond_to_returns_true_for_missing_methods_when_ignoring_missing_using_shouldtest_respond_to_returns_true_for_missing_methods_when_ignoring_missing_using_should161,3538
+ def test_method_proc_raises_error_on_unknowntest_method_proc_raises_error_on_unknown166,3734
+ def test_method_returns_callable_proctest_method_returns_callable_proc172,3852
+ def test_method_returns_do_nothing_proc_for_missing_methodstest_method_returns_do_nothing_proc_for_missing_methods181,4112
+class TestDeprecatedOrderingMethods < Test::Unit::TestCaseTestDeprecatedOrderingMethods189,4339
+ def test_deprecated_ordering_methodstest_deprecated_ordering_methods193,4462
+class TestAnyInstance < Test::Unit::TestCaseTestAnyInstance205,4858
+ class DogDog209,4967
+ def barkbark210,4979
+ def test_any_instance_still_works_for_backwards_compatibilitytest_any_instance_still_works_for_backwards_compatibility215,5019
+
+,1206
+class TemperatureSamplerTemperatureSampler14,321
+ def initialize(sensor)initialize15,346
+ def average_tempaverage_temp19,399
+class TestTemperatureSampler < Test::Unit::TestCaseTestTemperatureSampler25,526
+ def test_tempurature_samplertest_tempurature_sampler28,608
+class TestExamplesFromReadme < Test::Unit::TestCaseTestExamplesFromReadme37,887
+ def test_simple_return_valuestest_simple_return_values40,969
+ def test_returning_an_undefined_valuetest_returning_an_undefined_value46,1109
+ def test_dbtest_db52,1247
+ def test_query_and_updatetest_query_and_update61,1477
+ def test_ordered_queriestest_ordered_queries70,1730
+ def test_ordered_queries_in_record_modetest_ordered_queries_in_record_mode88,2327
+ def test_build_xmltest_build_xml105,2859
+ def known_good_way_to_build_xml(rec)known_good_way_to_build_xml114,3114
+ def new_way_to_build_xml(rec)new_way_to_build_xml119,3184
+ def test_multiple_getstest_multiple_gets123,3272
+ def test_an_important_messagetest_an_important_message132,3517
+ class QuoteServiceQuoteService141,3747
+ class PortfolioPortfolio143,3774
+ def valuevalue144,3792
+ def test_portfolio_valuetest_portfolio_value149,3850
+
+test/expectation_description_test.rb,782
+class ExpectationDescriptionTest < Test::Unit::TestCaseExpectationDescriptionTest14,321
+ def setupsetup17,407
+ def test_basic_descriptiontest_basic_description22,518
+ def test_with_no_argstest_with_no_args26,612
+ def test_with_simple_argstest_with_simple_args31,724
+ def test_with_nevertest_with_never36,856
+ def test_with_oncetest_with_once41,964
+ def test_with_twicetest_with_twice46,1069
+ def test_with_3test_with_351,1177
+ def test_with_at_least_oncetest_with_at_least_once56,1287
+ def test_with_at_least_10test_with_at_least_1061,1419
+ def test_with_at_most_oncetest_with_at_most_once66,1559
+ def test_with_zero_or_more_timestest_with_zero_or_more_times71,1688
+ def test_with_at_least_1_at_most_10test_with_at_least_1_at_most_1076,1843
+
+test/extended_should_receive_test.rb,808
+module ExtendedShouldReceiveTestsExtendedShouldReceiveTests14,321
+ def test_accepts_expectation_hashtest_accepts_expectation_hash15,355
+ def test_accepts_list_of_methodstest_accepts_list_of_methods21,519
+ def test_contraints_apply_to_all_expectationstest_contraints_apply_to_all_expectations28,677
+ def test_count_contraints_apply_to_all_expectationstest_count_contraints_apply_to_all_expectations35,944
+ def test_multiple_should_receives_are_allowedtest_multiple_should_receives_are_allowed41,1135
+class TestExtendedShouldReceiveOnFullMocks < Test::Unit::TestCaseTestExtendedShouldReceiveOnFullMocks49,1352
+ def setupsetup53,1485
+class TestExtendedShouldReceiveOnPartialMockProxies < Test::Unit::TestCaseTestExtendedShouldReceiveOnPartialMockProxies60,1555
+ def setupsetup64,1697
+
+`��:�,528
class DummyModelDummyModel5,48
class ChildModel < DummyModelChildModel8,70
class TestFlexModel < Test::Unit::TestCaseTestFlexModel12,176
@@ -414,107 +588,127 @@ class TestFlexModel < Test::Unit::TestCaseTestFlexModel12,176
def test_mock_models_can_have_quick_defstest_mock_models_can_have_quick_defs43,1048
def test_mock_models_can_have_blockstest_mock_models_can_have_blocks48,1188
-test/test_naming.rb,816
-class TestNaming < Test::Unit::TestCaseTestNaming14,320
- def test_nametest_name17,390
- def test_name_in_no_handler_found_errortest_name_in_no_handler_found_error22,473
- def test_name_in_received_count_errortest_name_in_received_count_error31,689
- def test_naming_with_usetest_naming_with_use40,909
- def test_naming_with_multiple_mocks_in_usetest_naming_with_multiple_mocks_in_use46,1026
- def test_inspect_returns_reasonable_nametest_inspect_returns_reasonable_name53,1214
- def test_mock_can_override_inspecttest_mock_can_override_inspect60,1398
- class DummyDummy67,1601
- def inspectinspect68,1615
- def test_partial_mocks_use_original_inspecttest_partial_mocks_use_original_inspect73,1668
- def test_partial_mocks_can_override_inspecttest_partial_mocks_can_override_inspect79,1832
-
-test/test_new_instances.rb,2271
-class TestNewInstances < Test::Unit::TestCaseTestNewInstances14,320
- class DogDog18,430
- def barkbark19,442
- def wagwag22,475
- def self.makemake25,507
- class CatCat30,550
- def initialize(name, &block)initialize32,584
- class ConnectionConnection38,690
- def initialize(*args)initialize39,709
- def send(args)send42,777
- def post(args)post45,821
- def test_new_instances_allows_stubbing_of_existing_methodstest_new_instances_allows_stubbing_of_existing_methods50,872
- def test_new_instances_stubs_still_have_existing_methodstest_new_instances_stubs_still_have_existing_methods58,1093
- def test_new_instances_will_pass_args_to_newtest_new_instances_will_pass_args_to_new66,1308
- def test_new_gets_block_after_restubbingtest_new_gets_block_after_restubbing79,1714
- def test_new_instances_stub_verification_happens_on_teardowntest_new_instances_stub_verification_happens_on_teardown92,2035
- def test_new_instances_reports_error_on_non_classestest_new_instances_reports_error_on_non_classes102,2380
- def test_does_not_by_default_stub_objects_created_with_allocatetest_does_not_by_default_stub_objects_created_with_allocate112,2659
- def test_can_explicitly_stub_objects_created_with_allocatetest_can_explicitly_stub_objects_created_with_allocate120,2887
- def test_can_stub_objects_created_with_arbitrary_class_methodstest_can_stub_objects_created_with_arbitrary_class_methods128,3124
- def test_stubbing_arbitrary_class_methods_leaves_new_alonetest_stubbing_arbitrary_class_methods_leaves_new_alone135,3347
- def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_newtest_stubbing_new_and_allocate_doesnt_double_stub_objects_on_new142,3562
- def test_blocks_on_new_do_not_have_stubs_installedtest_blocks_on_new_do_not_have_stubs_installed155,4015
- def test_new_instances_accept_chained_expectationstest_new_instances_accept_chained_expectations169,4353
- def test_fancy_use_of_chained_should_receivedtest_fancy_use_of_chained_should_received177,4623
- def test_writable_accessorstest_writable_accessors182,4778
- def test_ordering_can_be_specifiedtest_ordering_can_be_specified188,4923
- def test_ordering_can_be_specified_in_groupstest_ordering_can_be_specified_in_groups196,5117
-
-test/test_partial_mock.rb,4962
-class TestStubbing < Test::Unit::TestCaseTestStubbing14,320
- class DogDog17,392
- def barkbark18,404
- def Dog.createcreate21,437
- class DogPlus < DogDogPlus26,486
- def should_receiveshould_receive27,508
- def new_instancesnew_instances30,557
- def by_defaultby_default33,602
- def test_stub_command_add_behavior_to_arbitrary_objectstest_stub_command_add_behavior_to_arbitrary_objects38,658
- def test_stub_command_can_configure_via_blocktest_stub_command_can_configure_via_block44,842
- def test_stubbed_methods_can_take_blockstest_stubbed_methods_can_take_blocks52,1039
- def test_multiple_stubs_on_the_same_object_reuse_the_same_partial_mocktest_multiple_stubs_on_the_same_object_reuse_the_same_partial_mock59,1264
- def test_multiple_methods_can_be_stubbedtest_multiple_methods_can_be_stubbed64,1411
- def test_original_behavior_can_be_restoredtest_original_behavior_can_be_restored72,1663
- def test_original_missing_behavior_can_be_restoredtest_original_missing_behavior_can_be_restored82,1998
- def test_multiple_stubs_on_single_method_can_be_restored_missing_methodtest_multiple_stubs_on_single_method_can_be_restored_missing_method91,2277
- def test_original_behavior_is_restored_when_multiple_methods_are_mockedtest_original_behavior_is_restored_when_multiple_methods_are_mocked102,2686
- def test_original_behavior_is_restored_on_class_objectstest_original_behavior_is_restored_on_class_objects111,3015
- def test_original_behavior_is_restored_on_singleton_methodstest_original_behavior_is_restored_on_singleton_methods118,3262
- def obj.hi() :hello endhi120,3345
- def test_original_behavior_is_restored_on_singleton_methods_with_multiple_stubstest_original_behavior_is_restored_on_singleton_methods_with_multiple_stubs128,3541
- def obj.hi(n) "hello#{n}" endhi130,3644
- def test_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubstest_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubs140,3965
- def test_stubbing_file_shouldnt_break_writingtest_stubbing_file_shouldnt_break_writing156,4459
- def test_original_behavior_is_restored_even_when_errorstest_original_behavior_is_restored_even_when_errors172,4898
- def m.flexmock_verify() endflexmock_verify180,5217
- def test_not_calling_stubbed_method_is_an_errortest_not_calling_stubbed_method_is_an_error183,5256
- def test_mock_is_verified_when_the_stub_is_verifiedtest_mock_is_verified_when_the_stub_is_verified192,5474
- def test_stub_can_have_explicit_nametest_stub_can_have_explicit_name201,5731
- def test_unamed_stub_will_use_default_naming_conventiontest_unamed_stub_will_use_default_naming_convention207,5910
- def test_partials_can_be_defined_in_a_blocktest_partials_can_be_defined_in_a_block213,6106
- def test_partials_defining_block_return_real_obj_not_proxytest_partials_defining_block_return_real_obj_not_proxy221,6293
- def test_partial_mocks_always_return_domain_objecttest_partial_mocks_always_return_domain_object228,6487
- def test_domain_objects_do_not_have_mock_methodstest_domain_objects_do_not_have_mock_methods239,6767
- def test_partial_mocks_have_mock_methodstest_partial_mocks_have_mock_methods246,6959
- def test_partial_mocks_do_not_have_mock_methods_after_teardowntest_partial_mocks_do_not_have_mock_methods_after_teardown254,7155
- def test_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restoredtest_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restored263,7405
- def dog.mock() :original endmock265,7512
- class MockColisionMockColision271,7633
- def mockmock272,7654
- def test_partial_mocks_with_mock_method_non_singleton_colision_have_original_defs_restoredtest_partial_mocks_with_mock_method_non_singleton_colision_have_original_defs_restored277,7698
- def test_safe_partial_mocks_do_not_support_mock_methodstest_safe_partial_mocks_do_not_support_mock_methods284,7902
- def test_safe_partial_mocks_require_blocktest_safe_partial_mocks_require_block292,8130
- def test_safe_partial_mocks_are_actually_mockedtest_safe_partial_mocks_are_actually_mocked297,8268
- def test_should_receive_does_not_override_preexisting_deftest_should_receive_does_not_override_preexisting_def302,8438
- def test_should_receive_does_override_should_receive_preexisting_deftest_should_receive_does_override_should_receive_preexisting_def308,8638
- class LiarLiar313,8822
- def respond_to?(method_name)respond_to?314,8835
- def test_liar_actually_liestest_liar_actually_lies324,9004
- def test_partial_mock_where_respond_to_is_true_yet_method_is_not_theretest_partial_mock_where_respond_to_is_true_yet_method_is_not_there330,9156
- class ValueObjectValueObject341,9585
- def initialize(val)initialize344,9627
- def ==(other)==348,9677
- def test_partial_mocks_in_the_presense_of_equal_definitiontest_partial_mocks_in_the_presense_of_equal_definition353,9734
-
-test/test_rails_view_stub.rb,1492
+test/naming_test.rb,816
+class TestNaming < Test::Unit::TestCaseTestNaming14,321
+ def test_nametest_name17,391
+ def test_name_in_no_handler_found_errortest_name_in_no_handler_found_error22,474
+ def test_name_in_received_count_errortest_name_in_received_count_error31,690
+ def test_naming_with_usetest_naming_with_use40,910
+ def test_naming_with_multiple_mocks_in_usetest_naming_with_multiple_mocks_in_use46,1027
+ def test_inspect_returns_reasonable_nametest_inspect_returns_reasonable_name53,1215
+ def test_mock_can_override_inspecttest_mock_can_override_inspect60,1399
+ class DummyDummy67,1602
+ def inspectinspect68,1616
+ def test_partial_mocks_use_original_inspecttest_partial_mocks_use_original_inspect73,1669
+ def test_partial_mocks_can_override_inspecttest_partial_mocks_can_override_inspect79,1833
+
+test/new_instances_test.rb,2428
+class TestNewInstances < Test::Unit::TestCaseTestNewInstances14,321
+ class DogDog18,431
+ def barkbark19,443
+ def wagwag22,476
+ def self.makemake25,508
+ class CatCat30,551
+ def initialize(name, &block)initialize32,585
+ class ConnectionConnection38,691
+ def initialize(*args)initialize39,710
+ def send(args)send42,778
+ def post(args)post45,822
+ def test_new_instances_allows_stubbing_of_existing_methodstest_new_instances_allows_stubbing_of_existing_methods50,873
+ def test_new_instances_stubs_still_have_existing_methodstest_new_instances_stubs_still_have_existing_methods58,1094
+ def test_new_instances_will_pass_args_to_newtest_new_instances_will_pass_args_to_new66,1309
+ def test_new_gets_block_after_restubbingtest_new_gets_block_after_restubbing79,1715
+ def test_new_instances_stub_verification_happens_on_teardowntest_new_instances_stub_verification_happens_on_teardown92,2036
+ def test_new_instances_reports_error_on_non_classestest_new_instances_reports_error_on_non_classes102,2375
+ def test_does_not_by_default_stub_objects_created_with_allocatetest_does_not_by_default_stub_objects_created_with_allocate112,2654
+ def test_explicitly_mocking_allocation_in_new_instances_fails_in_ruby_19test_explicitly_mocking_allocation_in_new_instances_fails_in_ruby_19121,2909
+ def test_can_explicitly_stub_objects_created_with_allocatetest_can_explicitly_stub_objects_created_with_allocate129,3179
+ def test_can_stub_objects_created_with_arbitrary_class_methodstest_can_stub_objects_created_with_arbitrary_class_methods138,3436
+ def test_stubbing_arbitrary_class_methods_leaves_new_alonetest_stubbing_arbitrary_class_methods_leaves_new_alone145,3659
+ def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_newtest_stubbing_new_and_allocate_doesnt_double_stub_objects_on_new152,3874
+ def test_blocks_on_new_do_not_have_stubs_installedtest_blocks_on_new_do_not_have_stubs_installed165,4327
+ def test_new_instances_accept_chained_expectationstest_new_instances_accept_chained_expectations179,4665
+ def test_fancy_use_of_chained_should_receivedtest_fancy_use_of_chained_should_received187,4935
+ def test_writable_accessorstest_writable_accessors192,5090
+ def test_ordering_can_be_specifiedtest_ordering_can_be_specified198,5235
+ def test_ordering_can_be_specified_in_groupstest_ordering_can_be_specified_in_groups206,5429
+
+test/object_extensions_test.rb,377
+class ObjectExtensionsTest < Test::Unit::TestCaseObjectExtensionsTest6,85
+ def setupsetup7,135
+ def test_undefined_methods_are_not_singletonstest_undefined_methods_are_not_singletons14,215
+ def test_normal_methods_are_not_singletonstest_normal_methods_are_not_singletons18,324
+ def test_singleton_methods_are_singletonstest_singleton_methods_are_singletons22,429
+
+test/partial_mock_test.rb,6105
+class TestStubbing < Test::Unit::TestCaseTestStubbing14,321
+ class DogDog17,393
+ def barkbark18,405
+ def Dog.createcreate21,438
+ class DogPlus < DogDogPlus26,487
+ def should_receiveshould_receive27,509
+ def new_instancesnew_instances30,558
+ def by_defaultby_default33,603
+ def test_attempting_to_partially_mock_existing_mock_is_nooptest_attempting_to_partially_mock_existing_mock_is_noop38,659
+ def test_stub_command_add_behavior_to_arbitrary_objectstest_stub_command_add_behavior_to_arbitrary_objects44,844
+ def test_stub_command_can_configure_via_blocktest_stub_command_can_configure_via_block50,1028
+ def test_stubbed_methods_can_take_blockstest_stubbed_methods_can_take_blocks58,1225
+ def test_multiple_stubs_on_the_same_object_reuse_the_same_partial_mocktest_multiple_stubs_on_the_same_object_reuse_the_same_partial_mock65,1450
+ def test_stubbed_methods_can_invoke_original_behavior_directlytest_stubbed_methods_can_invoke_original_behavior_directly70,1597
+ def test_stubbed_methods_can_invoke_original_behavior_with_modificationtest_stubbed_methods_can_invoke_original_behavior_with_modification76,1775
+ def test_stubbed_methods_returning_partial_mockstest_stubbed_methods_returning_partial_mocks82,1995
+ def test_multiple_methods_can_be_stubbedtest_multiple_methods_can_be_stubbed91,2245
+ def test_original_behavior_can_be_restoredtest_original_behavior_can_be_restored99,2497
+ def test_original_missing_behavior_can_be_restoredtest_original_missing_behavior_can_be_restored109,2832
+ def test_multiple_stubs_on_single_method_can_be_restored_missing_methodtest_multiple_stubs_on_single_method_can_be_restored_missing_method118,3111
+ def test_original_behavior_is_restored_when_multiple_methods_are_mockedtest_original_behavior_is_restored_when_multiple_methods_are_mocked129,3520
+ def test_original_behavior_is_restored_on_class_objectstest_original_behavior_is_restored_on_class_objects138,3849
+ def test_original_behavior_is_restored_on_singleton_methodstest_original_behavior_is_restored_on_singleton_methods145,4096
+ def obj.hi() :hello endhi147,4179
+ def test_original_behavior_is_restored_on_singleton_methods_with_multiple_stubstest_original_behavior_is_restored_on_singleton_methods_with_multiple_stubs155,4375
+ def obj.hi(n) "hello#{n}" endhi157,4478
+ def test_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubstest_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubs167,4799
+ def test_stubbing_file_shouldnt_break_writingtest_stubbing_file_shouldnt_break_writing183,5293
+ def test_original_behavior_is_restored_even_when_errorstest_original_behavior_is_restored_even_when_errors199,5732
+ def m.flexmock_verify() endflexmock_verify211,6109
+ def test_not_calling_stubbed_method_is_an_errortest_not_calling_stubbed_method_is_an_error214,6148
+ def test_mock_is_verified_when_the_stub_is_verifiedtest_mock_is_verified_when_the_stub_is_verified223,6366
+ def test_stub_can_have_explicit_nametest_stub_can_have_explicit_name232,6623
+ def test_unamed_stub_will_use_default_naming_conventiontest_unamed_stub_will_use_default_naming_convention238,6802
+ def test_partials_can_be_defined_in_a_blocktest_partials_can_be_defined_in_a_block244,6998
+ def test_partials_defining_block_return_real_obj_not_proxytest_partials_defining_block_return_real_obj_not_proxy252,7185
+ def test_partial_mocks_always_return_domain_objecttest_partial_mocks_always_return_domain_object259,7379
+ def test_domain_objects_do_not_have_mock_methodstest_domain_objects_do_not_have_mock_methods270,7659
+ def test_partial_mocks_have_mock_methodstest_partial_mocks_have_mock_methods277,7851
+ def test_partial_mocks_do_not_have_mock_methods_after_teardowntest_partial_mocks_do_not_have_mock_methods_after_teardown285,8047
+ class NoMethodsNoMethods299,8639
+ def methods(arg = true)methods300,8657
+ def xtest_object_methods_method_is_not_used_in_singleton_checksxtest_object_methods_method_is_not_used_in_singleton_checks305,8757
+ def obj.mock() :original endmock307,8847
+ def test_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restoredtest_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restored311,8932
+ def dog.mock() :original endmock313,9039
+ class MockColisionMockColision319,9160
+ def mockmock320,9181
+ def test_partial_mocks_with_mock_method_non_singleton_colision_have_original_defs_restoredtest_partial_mocks_with_mock_method_non_singleton_colision_have_original_defs_restored325,9225
+ def test_safe_partial_mocks_do_not_support_mock_methodstest_safe_partial_mocks_do_not_support_mock_methods332,9429
+ def test_safe_partial_mocks_require_blocktest_safe_partial_mocks_require_block340,9657
+ def test_safe_partial_mocks_are_actually_mockedtest_safe_partial_mocks_are_actually_mocked345,9790
+ def test_should_receive_does_not_override_preexisting_deftest_should_receive_does_not_override_preexisting_def350,9960
+ def test_should_receive_does_override_should_receive_preexisting_deftest_should_receive_does_override_should_receive_preexisting_def356,10160
+ class LiarLiar361,10344
+ def respond_to?(method_name)respond_to?362,10357
+ def test_liar_actually_liestest_liar_actually_lies372,10526
+ def test_partial_mock_where_respond_to_is_true_yet_method_is_not_theretest_partial_mock_where_respond_to_is_true_yet_method_is_not_there378,10678
+ class MetaDog < DogMetaDog384,10863
+ def method_missing(method, *args, &block)method_missing385,10885
+ def respond_to_missing?(method, *)respond_to_missing?392,11019
+ def test_partial_mock_where_method_created_by_method_missing_and_respond_to_missingtest_partial_mock_where_method_created_by_method_missing_and_respond_to_missing397,11105
+ class ValueObjectValueObject408,11531
+ def initialize(val)initialize411,11573
+ def ==(other)==415,11623
+ def test_partial_mocks_in_the_presense_of_equal_definitiontest_partial_mocks_in_the_presense_of_equal_definition420,11680
+
+test/rails_view_stub_test.rb,1492
module ViewTestsViewTests6,86
def test_view_mocks_as_stubtest_view_mocks_as_stub7,103
def test_fails_if_no_rendertest_fails_if_no_render12,197
@@ -540,244 +734,323 @@ class TestRailsVersion < Test::Unit::TestCaseTestRailsVersion133,3107
module ActionViewActionView142,3280
class BaseBase143,3298
-test/test_record_mode.rb,1339
-class TestRecordMode < Test::Unit::TestCaseTestRecordMode14,320
- def test_recording_mode_workstest_recording_mode_works17,394
- def test_arguments_are_passed_to_recording_mode_blocktest_arguments_are_passed_to_recording_mode_block25,568
- def test_recording_mode_handles_multiple_returnstest_recording_mode_handles_multiple_returns36,832
- def test_recording_mode_does_not_specify_ordertest_recording_mode_does_not_specify_order50,1242
- def test_recording_mode_gets_block_args_tootest_recording_mode_gets_block_args_too61,1477
- def test_recording_mode_should_validate_args_with_equalstest_recording_mode_should_validate_args_with_equals73,1747
- def test_recording_mode_should_allow_arg_contraint_validationtest_recording_mode_should_allow_arg_contraint_validation84,1971
- def test_recording_mode_should_handle_multiplicity_contraintstest_recording_mode_should_handle_multiplicity_contraints95,2200
- def test_strict_record_mode_requires_exact_argument_matchestest_strict_record_mode_requires_exact_argument_matches107,2455
- def test_strict_record_mode_requires_exact_orderingtest_strict_record_mode_requires_exact_ordering119,2723
- def test_strict_record_mode_requires_oncetest_strict_record_mode_requires_once133,3014
- def test_strict_record_mode_can_not_failtest_strict_record_mode_can_not_fail146,3276
-
-test/test_samples.rb,2164
-class TestSamples < Test::Unit::TestCaseTestSamples16,346
- def test_file_iotest_file_io24,716
- def count_lines(file)count_lines32,967
-class TestUndefined < Test::Unit::TestCaseTestUndefined42,1060
- def test_undefined_valuestest_undefined_values45,1133
-class TestSimple < Test::Unit::TestCaseTestSimple54,1319
- def test_simple_mocktest_simple_mock57,1389
-class TestDog < Test::Unit::TestCaseTestDog64,1524
- def test_dog_wagstest_dog_wags67,1591
-class WooferWoofer73,1702
-class DogDog76,1720
- def initializeinitialize77,1730
- def barkbark80,1778
- def wagwag83,1812
-class TestDogBarking < Test::Unit::TestCaseTestDogBarking88,1844
- def setupsetup93,2006
- def test_dogtest_dog98,2079
-class TestDogBarkingWithNewInstances < Test::Unit::TestCaseTestDogBarkingWithNewInstances104,2210
- def setupsetup109,2374
- def test_dogtest_dog113,2459
-class TestDefaults < Test::Unit::TestCaseTestDefaults119,2593
- def setupsetup122,2665
- def test_something_where_bark_must_be_called_oncetest_something_where_bark_must_be_called_once127,2792
-class TestDemeter < Test::Unit::TestCaseTestDemeter135,2994
- def test_manual_mockingtest_manual_mocking137,3064
- def test_demetertest_demeter150,3498
-class TestDb < Test::Unit::TestCaseTestDb160,3713
- def test_dbtest_db163,3779
-class TestDb < Test::Unit::TestCaseTestDb174,3984
- def test_query_and_updatetest_query_and_update177,4050
- def test_ordered_queriestest_ordered_queries188,4327
- def test_ordered_queries_in_record_modetest_ordered_queries_in_record_mode206,4867
- def known_good_way_to_build_xml(builder)known_good_way_to_build_xml223,5342
- def new_way_to_build_xml(builder)new_way_to_build_xml227,5409
- def test_build_xmltest_build_xml231,5493
-class TestMoreSamples < Test::Unit::TestCaseTestMoreSamples242,5753
- def test_multiple_getstest_multiple_gets245,5828
- def test_an_important_messagetest_an_important_message254,6073
- class QuoteServiceQuoteService263,6334
- class PortfolioPortfolio266,6362
- def initializeinitialize267,6380
- def valuevalue270,6447
- def test_portfolio_valuetest_portfolio_value275,6503
-
-test/test_setup.rb,180
+test/record_mode_test.rb,1339
+class TestRecordMode < Test::Unit::TestCaseTestRecordMode14,321
+ def test_recording_mode_workstest_recording_mode_works17,395
+ def test_arguments_are_passed_to_recording_mode_blocktest_arguments_are_passed_to_recording_mode_block25,569
+ def test_recording_mode_handles_multiple_returnstest_recording_mode_handles_multiple_returns36,833
+ def test_recording_mode_does_not_specify_ordertest_recording_mode_does_not_specify_order50,1243
+ def test_recording_mode_gets_block_args_tootest_recording_mode_gets_block_args_too61,1478
+ def test_recording_mode_should_validate_args_with_equalstest_recording_mode_should_validate_args_with_equals73,1748
+ def test_recording_mode_should_allow_arg_contraint_validationtest_recording_mode_should_allow_arg_contraint_validation84,2013
+ def test_recording_mode_should_handle_multiplicity_contraintstest_recording_mode_should_handle_multiplicity_contraints95,2283
+ def test_strict_record_mode_requires_exact_argument_matchestest_strict_record_mode_requires_exact_argument_matches107,2564
+ def test_strict_record_mode_requires_exact_orderingtest_strict_record_mode_requires_exact_ordering119,2873
+ def test_strict_record_mode_requires_oncetest_strict_record_mode_requires_once133,3205
+ def test_strict_record_mode_can_not_failtest_strict_record_mode_can_not_fail146,3508
+
+test/redirect_error.rb,114
+class FlexMockFlexMock3,20
+ module RedirectErrorRedirectError4,35
+ def redirect_errorredirect_error5,58
+
+,0
+
+test/rspec_integration/spy_example_spec.rb,134
+ class DogDog8,106
+ def wags(arg)wags9,118
+ def barksbarks13,179
+ def should_fail(message_pattern)should_fail197,4898
+
+,2164
+class TestSamples < Test::Unit::TestCaseTestSamples16,347
+ def test_file_iotest_file_io24,717
+ def count_lines(file)count_lines32,968
+class TestUndefined < Test::Unit::TestCaseTestUndefined42,1061
+ def test_undefined_valuestest_undefined_values45,1134
+class TestSimple < Test::Unit::TestCaseTestSimple54,1320
+ def test_simple_mocktest_simple_mock57,1390
+class TestDog < Test::Unit::TestCaseTestDog64,1525
+ def test_dog_wagstest_dog_wags67,1592
+class WooferWoofer73,1703
+class DogDog76,1721
+ def initializeinitialize77,1731
+ def barkbark80,1779
+ def wagwag83,1813
+class TestDogBarking < Test::Unit::TestCaseTestDogBarking88,1845
+ def setupsetup93,2007
+ def test_dogtest_dog98,2080
+class TestDogBarkingWithNewInstances < Test::Unit::TestCaseTestDogBarkingWithNewInstances104,2211
+ def setupsetup109,2375
+ def test_dogtest_dog113,2460
+class TestDefaults < Test::Unit::TestCaseTestDefaults119,2594
+ def setupsetup122,2666
+ def test_something_where_bark_must_be_called_oncetest_something_where_bark_must_be_called_once127,2793
+class TestDemeter < Test::Unit::TestCaseTestDemeter135,2995
+ def test_manual_mockingtest_manual_mocking137,3065
+ def test_demetertest_demeter150,3499
+class TestDb < Test::Unit::TestCaseTestDb160,3714
+ def test_dbtest_db163,3780
+class TestDb < Test::Unit::TestCaseTestDb174,3985
+ def test_query_and_updatetest_query_and_update177,4051
+ def test_ordered_queriestest_ordered_queries188,4328
+ def test_ordered_queries_in_record_modetest_ordered_queries_in_record_mode206,4868
+ def known_good_way_to_build_xml(builder)known_good_way_to_build_xml223,5343
+ def new_way_to_build_xml(builder)new_way_to_build_xml227,5410
+ def test_build_xmltest_build_xml231,5494
+class TestMoreSamples < Test::Unit::TestCaseTestMoreSamples242,5754
+ def test_multiple_getstest_multiple_gets245,5829
+ def test_an_important_messagetest_an_important_message254,6074
+ class QuoteServiceQuoteService263,6335
+ class PortfolioPortfolio266,6363
+ def initializeinitialize267,6381
+ def valuevalue270,6448
+ def test_portfolio_valuetest_portfolio_value275,6504
+
+,1266
+class TestShouldIgnoreMissing < Test::Unit::TestCaseTestShouldIgnoreMissing14,321
+ def setupsetup17,404
+ def test_mocks_do_not_respond_to_undefined_methodstest_mocks_do_not_respond_to_undefined_methods21,452
+ def test_mocks_do_respond_to_defined_methodstest_mocks_do_respond_to_defined_methods25,556
+ def test_mocks_do_respond_to_any_method_when_ignoring_missingtest_mocks_do_respond_to_any_method_when_ignoring_missing30,696
+ def test_should_ignore_missing_returns_mocktest_should_ignore_missing_returns_mock35,842
+ def test_ignored_methods_return_undefinedtest_ignored_methods_return_undefined40,967
+ def test_undefined_mocking_with_argumentstest_undefined_mocking_with_arguments46,1141
+ def test_method_chains_with_undefined_are_self_preservingtest_method_chains_with_undefined_are_self_preserving51,1289
+ def test_method_proc_raises_error_on_unknowntest_method_proc_raises_error_on_unknown56,1454
+ def test_method_returns_callable_proctest_method_returns_callable_proc62,1578
+ def test_not_calling_method_proc_will_fail_count_constraintstest_not_calling_method_proc_will_fail_count_constraints69,1766
+ def test_method_returns_do_nothing_proc_for_missing_methodstest_method_returns_do_nothing_proc_for_missing_methods78,2028
+
+,11666
+def mock_top_level_functionmock_top_level_function14,321
+module KernelKernel18,362
+ def mock_kernel_functionmock_kernel_function19,376
+class CatCat25,442
+ def purrpurr26,452
+ def meowmeow28,469
+class TestFlexMockShoulds < Test::Unit::TestCaseTestFlexMockShoulds32,491
+ def test_defaultstest_defaults43,957
+ def test_returns_with_valuetest_returns_with_value52,1125
+ def test_returns_with_multiple_valuestest_returns_with_multiple_values60,1292
+ def test_multiple_returnstest_multiple_returns71,1552
+ def test_returns_with_blocktest_returns_with_block82,1812
+ def test_block_example_from_readmetest_block_example_from_readme91,2015
+ def test_return_with_and_without_block_interleavedtest_return_with_and_without_block_interleaved101,2311
+ def test_and_returns_aliastest_and_returns_alias111,2591
+ def test_and_return_undefinedtest_and_return_undefined118,2728
+ def test_and_yield_will_continue_to_yield_the_same_valuetest_and_yield_will_continue_to_yield_the_same_value128,3077
+ def test_and_yield_with_multiple_values_yields_the_valuestest_and_yield_with_multiple_values_yields_the_values136,3323
+ def test_multiple_yields_are_done_sequentiallytest_multiple_yields_are_done_sequentially143,3533
+ def test_multiple_yields_and_multiple_returns_are_syncedtest_multiple_yields_and_multiple_returns_are_synced152,3805
+ def test_failure_if_no_block_giventest_failure_if_no_block_given165,4322
+ def test_failure_different_return_value_than_yield_returntest_failure_different_return_value_than_yield_return172,4505
+ def test_multiple_yieldstest_multiple_yields181,4791
+ def test_multiple_yields_will_yield_the_last_value_settest_multiple_yields_will_yield_the_last_value_set189,5029
+ def test_yielding_then_not_yielding_and_then_yielding_againtest_yielding_then_not_yielding_and_then_yielding_again200,5406
+ def test_yields_syntaxtest_yields_syntax211,5753
+ class MyError < RuntimeErrorMyError218,5898
+ def test_and_raises_with_exception_class_throws_exceptiontest_and_raises_with_exception_class_throws_exception221,5936
+ def test_and_raises_with_arguments_throws_exception_made_with_argstest_and_raises_with_arguments_throws_exception_made_with_args230,6145
+ def test_and_raises_with_a_specific_exception_throws_the_exceptiontest_and_raises_with_a_specific_exception_throws_the_exception240,6426
+ def test_raises_is_an_alias_for_and_raisetest_raises_is_an_alias_for_and_raise251,6696
+ def test_multiple_and_raise_clauses_will_be_done_sequentiallytest_multiple_and_raise_clauses_will_be_done_sequentially260,6896
+ def test_and_throw_will_throw_a_symboltest_and_throw_will_throw_a_symbol272,7294
+ def test_and_throw_with_expression_will_throwtest_and_throw_with_expression_will_throw283,7537
+ def test_throws_is_an_alias_for_and_throwtest_throws_is_an_alias_for_and_throw294,7819
+ def test_multiple_throws_will_be_done_sequentiallytest_multiple_throws_will_be_done_sequentially305,8094
+ def test_pass_thru_just_returns_undefined_on_mockstest_pass_thru_just_returns_undefined_on_mocks317,8424
+ def test_multiple_expectationstest_multiple_expectations324,8598
+ def test_with_no_args_with_no_argstest_with_no_args_with_no_args334,8829
+ def test_with_no_args_but_with_argstest_with_no_args_but_with_args341,8957
+ def test_with_any_argstest_with_any_args350,9182
+ def test_with_any_single_arg_matchingtest_with_any_single_arg_matching360,9360
+ def test_with_any_single_arg_nonmatchingtest_with_any_single_arg_nonmatching368,9553
+ def test_with_equal_arg_matchingtest_with_equal_arg_matching378,9788
+ def test_with_ducktype_arg_matchingtest_with_ducktype_arg_matching385,9951
+ def test_with_ducktype_arg_matching_no_matchtest_with_ducktype_arg_matching_no_match392,10130
+ def test_with_hash_matchingtest_with_hash_matching401,10395
+ def test_with_hash_non_matchingtest_with_hash_non_matching408,10583
+ def test_with_equal_arg_nonmatchingtest_with_equal_arg_nonmatching417,10844
+ def test_with_optional_proctest_with_optional_proc426,11081
+ def test_with_optional_proc_and_missing_proctest_with_optional_proc_and_missing_proc433,11229
+ def test_with_optional_proc_distinquishes_between_nil_and_missingtest_with_optional_proc_distinquishes_between_nil_and_missing440,11390
+ def test_with_arbitrary_arg_matchingtest_with_arbitrary_arg_matching448,11621
+ def test_args_matching_with_regextest_args_matching_with_regex463,12052
+ def test_arg_matching_with_regex_matching_non_stringtest_arg_matching_with_regex_matching_non_string475,12373
+ def test_arg_matching_with_classtest_arg_matching_with_class482,12550
+ def test_arg_matching_with_no_matchtest_arg_matching_with_no_match493,12834
+ def test_arg_matching_with_string_doesnt_over_matchtest_arg_matching_with_string_doesnt_over_match502,13082
+ def test_block_arg_given_to_no_argstest_block_arg_given_to_no_args511,13353
+ def test_block_arg_given_to_matching_proctest_block_arg_given_to_matching_proc520,13609
+ def test_arg_matching_precedence_when_best_firsttest_arg_matching_precedence_when_best_first531,13894
+ def test_arg_matching_precedence_when_best_last_but_still_matches_firsttest_arg_matching_precedence_when_best_last_but_still_matches_first539,14103
+ def test_never_and_never_calledtest_never_and_never_called547,14335
+ def test_never_and_called_oncetest_never_and_called_once553,14450
+ def test_once_called_oncetest_once_called_once562,14689
+ def test_once_but_never_calledtest_once_but_never_called569,14823
+ def test_once_but_called_twicetest_once_but_called_twice577,15042
+ def test_twice_and_called_twicetest_twice_and_called_twice587,15293
+ def test_zero_or_more_called_zerotest_zero_or_more_called_zero595,15448
+ def test_zero_or_more_called_oncetest_zero_or_more_called_once601,15570
+ def test_zero_or_more_called_100test_zero_or_more_called_100608,15703
+ def test_timestest_times615,15849
+ def test_at_least_called_oncetest_at_least_called_once622,15990
+ def test_at_least_but_never_calledtest_at_least_but_never_called629,16137
+ def test_at_least_once_but_called_twicetest_at_least_once_but_called_twice637,16372
+ def test_at_least_and_exacttest_at_least_and_exact645,16543
+ def test_at_most_but_never_calledtest_at_most_but_never_called655,16805
+ def test_at_most_called_oncetest_at_most_called_once661,16941
+ def test_at_most_called_twicetest_at_most_called_twice668,17086
+ def test_at_most_and_at_least_called_nevertest_at_most_and_at_least_called_never679,17394
+ def test_at_most_and_at_least_called_oncetest_at_most_and_at_least_called_once688,17700
+ def test_at_most_and_at_least_called_twicetest_at_most_and_at_least_called_twice695,17873
+ def test_at_most_and_at_least_called_three_timestest_at_most_and_at_least_called_three_times703,18061
+ def test_call_counts_only_apply_to_matching_argstest_call_counts_only_apply_to_matching_args714,18371
+ def test_call_counts_only_apply_to_matching_args_with_mismatchtest_call_counts_only_apply_to_matching_args_with_mismatch726,18649
+ def test_ordered_calls_in_order_will_passtest_ordered_calls_in_order_will_pass742,19119
+ def test_ordered_calls_out_of_order_will_failtest_ordered_calls_out_of_order_will_fail752,19301
+ def test_order_calls_with_different_arg_lists_and_in_order_will_passtest_order_calls_with_different_arg_lists_and_in_order_will_pass764,19609
+ def test_order_calls_with_different_arg_lists_and_out_of_order_will_failtest_order_calls_with_different_arg_lists_and_out_of_order_will_fail774,19856
+ def test_unordered_calls_do_not_effect_ordered_testingtest_unordered_calls_do_not_effect_ordered_testing786,20229
+ def test_ordered_with_multiple_calls_will_passtest_ordered_with_multiple_calls_will_pass800,20493
+ def test_grouped_ordering_with_numberstest_grouped_ordering_with_numbers812,20702
+ def test_grouped_ordering_with_symbolstest_grouped_ordering_with_symbols827,21017
+ def test_explicit_ordering_mixed_with_implicit_ordering_should_not_overlaptest_explicit_ordering_mixed_with_implicit_ordering_should_not_overlap842,21373
+ def test_explicit_ordering_with_explicit_misorderstest_explicit_ordering_with_explicit_misorders852,21746
+ def test_ordering_with_explicit_no_args_matches_correctlytest_ordering_with_explicit_no_args_matches_correctly868,22321
+ def test_ordering_with_any_arg_matching_correctly_matchestest_ordering_with_any_arg_matching_correctly_matches880,22694
+ def test_ordering_between_mocks_is_not_normally_definedtest_ordering_between_mocks_is_not_normally_defined891,23002
+ def test_ordering_between_mocks_is_honored_for_global_orderingtest_ordering_between_mocks_is_honored_for_global_ordering903,23256
+ def test_expectation_formatingtest_expectation_formating915,23612
+ def test_multi_expectation_formattingtest_multi_expectation_formatting924,23840
+ def test_explicit_ordering_with_limits_allow_multiple_return_valuestest_explicit_ordering_with_limits_allow_multiple_return_values930,24003
+ def test_global_methods_can_be_mockedtest_global_methods_can_be_mocked949,24714
+ def test_kernel_methods_can_be_mockedtest_kernel_methods_can_be_mocked955,24898
+ def test_undefing_kernel_methods_dont_effect_other_mockstest_undefing_kernel_methods_dont_effect_other_mocks961,25076
+ def test_expectations_can_by_marked_as_defaulttest_expectations_can_by_marked_as_default969,25344
+ def test_default_expectations_are_search_in_the_proper_ordertest_default_expectations_are_search_in_the_proper_order975,25506
+ def test_expectations_with_count_constraints_can_by_marked_as_defaulttest_expectations_with_count_constraints_can_by_marked_as_default983,25809
+ def test_default_expectations_are_overridden_by_later_expectationstest_default_expectations_are_overridden_by_later_expectations991,26045
+ def test_default_expectations_can_be_changed_by_later_expectationstest_default_expectations_can_be_changed_by_later_expectations999,26273
+ def test_ordered_default_expectations_can_be_specifiedtest_ordered_default_expectations_can_be_specified1010,26635
+ def test_ordered_default_expectations_can_be_overriddentest_ordered_default_expectations_can_be_overridden1018,26876
+ def test_by_default_works_at_mock_leveltest_by_default_works_at_mock_level1030,27147
+ def test_by_default_at_mock_level_does_nothing_with_no_expectationstest_by_default_at_mock_level_does_nothing_with_no_expectations1041,27422
+ def test_partial_mocks_can_have_default_expectationstest_partial_mocks_can_have_default_expectations1047,27567
+ def test_partial_mocks_can_have_default_expectations_overriddentest_partial_mocks_can_have_default_expectations_overridden1053,27748
+ def test_wicked_and_evil_tricks_with_by_default_are_thwartedtest_wicked_and_evil_tricks_with_by_default_are_thwarted1060,27996
+ def test_mocks_can_handle_multi_parameter_respond_tostest_mocks_can_handle_multi_parameter_respond_tos1072,28401
+ def test_backtraces_point_to_should_receive_linetest_backtraces_point_to_should_receive_line1083,28748
+ def test_can_mock_operatorstest_can_mock_operators1097,29148
+ def assert_operator(op, &block)assert_operator1127,30212
+class TestFlexMockShouldsWithInclude < Test::Unit::TestCaseTestFlexMockShouldsWithInclude1135,30366
+ def test_include_enables_unqualified_arg_type_referencestest_include_enables_unqualified_arg_type_references1137,30460
+class TestFlexMockArgTypesDontLeak < Test::Unit::TestCaseTestFlexMockArgTypesDontLeak1145,30624
+ def test_unqualified_arg_type_references_are_undefined_by_defaulttest_unqualified_arg_type_references_are_undefined_by_default1146,30682
+
+test/spys_test.rb,3062
+class TestSpys < Test::Unit::TestCaseTestSpys5,48
+ class FooBarFooBar8,116
+ def foofoo9,131
+ def barbar12,165
+ def setupsetup16,192
+ def test_spy_detects_simple_calltest_spy_detects_simple_call21,254
+ def test_spy_detects_simple_call_ignoring_argstest_spy_detects_simple_call_ignoring_args26,342
+ def test_spy_rejects_a_never_made_calltest_spy_rejects_a_never_made_call31,451
+ def test_spy_detects_call_with_literal_argtest_spy_detects_call_with_literal_arg36,549
+ def test_spy_detects_call_with_class_argtest_spy_detects_call_with_class_arg41,653
+ def test_spy_rejects_call_with_non_matching_literal_argtest_spy_rejects_call_with_non_matching_literal_arg46,761
+ def test_spy_detects_call_with_multiple_argumentstest_spy_detects_call_with_multiple_arguments51,882
+ def test_spy_detects_multiple_calls_with_different_argumentstest_spy_detects_multiple_calls_with_different_arguments56,1021
+ def test_spy_rejects_if_times_options_not_matchingtest_spy_rejects_if_times_options_not_matching62,1174
+ def test_spy_detects_a_blocktest_spy_detects_a_block68,1321
+ def test_spy_rejects_a_blocktest_spy_rejects_a_block73,1415
+ def test_spy_detects_a_missing_blocktest_spy_detects_a_missing_block78,1531
+ def test_spy_rejects_a_missing_blocktest_spy_rejects_a_missing_block83,1647
+ def test_spy_ignores_blocktest_spy_ignores_block88,1749
+ def test_spy_accepts_correct_additional_validationstest_spy_accepts_correct_additional_validations93,1841
+ def test_spy_accepts_multiple_additional_validations_first_failingtest_spy_accepts_multiple_additional_validations_first_failing99,2028
+ def test_spy_accepts_multiple_additional_validations_second_failingtest_spy_accepts_multiple_additional_validations_second_failing108,2344
+ def test_spy_rejects_incorrect_additional_validationstest_spy_rejects_incorrect_additional_validations117,2661
+ def test_spy_selectively_applies_additional_validationstest_spy_selectively_applies_additional_validations125,2909
+ def assert_failed(message_pattern)assert_failed135,3201
+ def test_spy_methods_can_be_stubbedtest_spy_methods_can_be_stubbed146,3444
+ def test_spy_cannot_see_normal_methodstest_spy_cannot_see_normal_methods153,3619
+ def test_spy_cannot_see_normal_methods2test_spy_cannot_see_normal_methods2160,3776
+ def test_calling_non_spy_base_methods_is_an_errortest_calling_non_spy_base_methods_is_an_error167,3961
+ def test_cant_put_expectations_on_non_base_class_methodsxtest_cant_put_expectations_on_non_base_class_methodsx173,4078
+ def test_cant_put_expectations_on_non_base_class_methods_unless_explicittest_cant_put_expectations_on_non_base_class_methods_unless_explicit182,4418
+ def test_ok_to_use_explicit_even_when_its_not_neededtest_ok_to_use_explicit_even_when_its_not_needed188,4604
+ def test_can_spy_on_partial_mockstest_can_spy_on_partial_mocks194,4770
+ def test_can_spy_on_class_defined_methodstest_can_spy_on_class_defined_methods203,4984
+ def test_can_spy_on_regular_mockstest_can_spy_on_regular_mocks209,5146
+
+test/symbol_extensions_test.rb,161
+class SymbolEtentensionsTest < Test::Unit::TestCaseSymbolEtentensionsTest3,27
+ def test_as_name_converts_appropriatlytest_as_name_converts_appropriatly4,79
+
+test/test_class_extensions.rb,477
+class ClassExtensionsTest < Test::Unit::TestCaseClassExtensionsTest3,27
+ class DogDog5,77
+ def wagwag6,89
+ def method_missing(sym, *args, &block)method_missing9,110
+ def responds_to?(sym)responds_to?17,233
+ def test_class_directly_defines_methodtest_class_directly_defines_method22,302
+ def test_class_indirectly_defines_methodtest_class_indirectly_defines_method26,389
+ def test_class_does_not_define_methodtest_class_does_not_define_method30,481
+
+test/test_setup.rb,339
class FlexMockFlexMock7,91
module TestCaseTestCase8,106
def assertion_failed_errorassertion_failed_error9,124
- def assert_failure(message=nil)assert_failure16,378
-
-test/test_should_ignore_missing.rb,1173
-class TestShouldIgnoreMissing < Test::Unit::TestCaseTestShouldIgnoreMissing14,320
- def setupsetup17,403
- def test_mocks_do_not_respond_to_undefined_methodstest_mocks_do_not_respond_to_undefined_methods21,451
- def test_mocks_do_respond_to_defined_methodstest_mocks_do_respond_to_defined_methods25,555
- def test_mocks_do_respond_to_any_method_when_ignoring_missingtest_mocks_do_respond_to_any_method_when_ignoring_missing30,695
- def test_ignored_methods_return_undefinedtest_ignored_methods_return_undefined35,841
- def test_undefined_mocking_with_argumentstest_undefined_mocking_with_arguments41,1015
- def test_method_chains_with_undefined_are_self_preservingtest_method_chains_with_undefined_are_self_preserving46,1163
- def test_method_proc_raises_error_on_unknowntest_method_proc_raises_error_on_unknown51,1328
- def test_method_returns_callable_proctest_method_returns_callable_proc57,1452
- def test_not_calling_method_proc_will_fail_count_constraintstest_not_calling_method_proc_will_fail_count_constraints64,1636
- def test_method_returns_do_nothing_proc_for_missing_methodstest_method_returns_do_nothing_proc_for_missing_methods73,1898
-
-test/test_should_receive.rb,11020
-def mock_top_level_functionmock_top_level_function14,320
-module KernelKernel18,361
- def mock_kernel_functionmock_kernel_function19,375
-class CatCat25,441
- def purrpurr26,451
- def meowmeow28,468
-class TestFlexMockShoulds < Test::Unit::TestCaseTestFlexMockShoulds32,490
- def test_defaultstest_defaults43,995
- def test_returns_with_valuetest_returns_with_value52,1163
- def test_returns_with_multiple_valuestest_returns_with_multiple_values60,1330
- def test_multiple_returnstest_multiple_returns71,1590
- def test_returns_with_blocktest_returns_with_block82,1850
- def test_block_example_from_readmetest_block_example_from_readme91,2053
- def test_return_with_and_without_block_interleavedtest_return_with_and_without_block_interleaved101,2349
- def test_and_returns_aliastest_and_returns_alias111,2629
- def test_and_return_undefinedtest_and_return_undefined118,2766
- def test_and_yield_will_continue_to_yield_the_same_valuetest_and_yield_will_continue_to_yield_the_same_value128,3115
- def test_and_yield_with_multiple_values_yields_the_valuestest_and_yield_with_multiple_values_yields_the_values136,3361
- def test_multiple_yields_are_done_sequentiallytest_multiple_yields_are_done_sequentially143,3571
- def test_failure_if_no_block_giventest_failure_if_no_block_given152,3843
- def test_failure_different_return_value_than_yield_returntest_failure_different_return_value_than_yield_return159,4026
- def test_multiple_yieldstest_multiple_yields168,4312
- def test_multiple_yields_will_yield_the_last_value_settest_multiple_yields_will_yield_the_last_value_set176,4550
- def test_yielding_then_not_yielding_and_then_yielding_againtest_yielding_then_not_yielding_and_then_yielding_again187,4927
- def test_yields_syntaxtest_yields_syntax198,5274
- class MyError < RuntimeErrorMyError205,5419
- def test_and_raises_with_exception_class_throws_exceptiontest_and_raises_with_exception_class_throws_exception208,5457
- def test_and_raises_with_arguments_throws_exception_made_with_argstest_and_raises_with_arguments_throws_exception_made_with_args217,5666
- def test_and_raises_with_a_specific_exception_throws_the_exceptiontest_and_raises_with_a_specific_exception_throws_the_exception227,5947
- def test_raises_is_an_alias_for_and_raisetest_raises_is_an_alias_for_and_raise238,6217
- def test_multiple_and_raise_clauses_will_be_done_sequentiallytest_multiple_and_raise_clauses_will_be_done_sequentially247,6422
- def test_and_throw_will_throw_a_symboltest_and_throw_will_throw_a_symbol259,6820
- def test_and_throw_with_expression_will_throwtest_and_throw_with_expression_will_throw270,7063
- def test_throws_is_an_alias_for_and_throwtest_throws_is_an_alias_for_and_throw281,7345
- def test_multiple_throws_will_be_done_sequentiallytest_multiple_throws_will_be_done_sequentially292,7620
- def test_multiple_expectationstest_multiple_expectations304,7950
- def test_with_no_args_with_no_argstest_with_no_args_with_no_args314,8181
- def test_with_no_args_but_with_argstest_with_no_args_but_with_args321,8309
- def test_with_any_argstest_with_any_args330,8508
- def test_with_any_single_arg_matchingtest_with_any_single_arg_matching340,8686
- def test_with_any_single_arg_nonmatchingtest_with_any_single_arg_nonmatching348,8879
- def test_with_equal_arg_matchingtest_with_equal_arg_matching358,9114
- def test_with_ducktype_arg_matchingtest_with_ducktype_arg_matching365,9277
- def test_with_ducktype_arg_matching_no_matchtest_with_ducktype_arg_matching_no_match372,9456
- def test_with_hash_matchingtest_with_hash_matching381,9680
- def test_with_hash_non_matchingtest_with_hash_non_matching388,9868
- def test_with_equal_arg_nonmatchingtest_with_equal_arg_nonmatching397,10088
- def test_with_arbitrary_arg_matchingtest_with_arbitrary_arg_matching406,10325
- def test_args_matching_with_regextest_args_matching_with_regex421,10745
- def test_arg_matching_with_regex_matching_non_stringtest_arg_matching_with_regex_matching_non_string433,11066
- def test_arg_matching_with_classtest_arg_matching_with_class440,11243
- def test_arg_matching_with_no_matchtest_arg_matching_with_no_match451,11527
- def test_arg_matching_with_string_doesnt_over_matchtest_arg_matching_with_string_doesnt_over_match460,11740
- def test_block_arg_given_to_no_argstest_block_arg_given_to_no_args469,11959
- def test_block_arg_given_to_matching_proctest_block_arg_given_to_matching_proc478,12163
- def test_arg_matching_precedence_when_best_firsttest_arg_matching_precedence_when_best_first489,12448
- def test_arg_matching_precedence_when_best_last_but_still_matches_firsttest_arg_matching_precedence_when_best_last_but_still_matches_first497,12657
- def test_never_and_never_calledtest_never_and_never_called505,12889
- def test_never_and_called_oncetest_never_and_called_once511,13004
- def test_once_called_oncetest_once_called_once520,13196
- def test_once_but_never_calledtest_once_but_never_called527,13330
- def test_once_but_called_twicetest_once_but_called_twice535,13517
- def test_twice_and_called_twicetest_twice_and_called_twice545,13736
- def test_zero_or_more_called_zerotest_zero_or_more_called_zero553,13891
- def test_zero_or_more_called_oncetest_zero_or_more_called_once559,14013
- def test_zero_or_more_called_100test_zero_or_more_called_100566,14146
- def test_timestest_times573,14292
- def test_at_least_called_oncetest_at_least_called_once580,14433
- def test_at_least_but_never_calledtest_at_least_but_never_called587,14580
- def test_at_least_once_but_called_twicetest_at_least_once_but_called_twice595,14783
- def test_at_least_and_exacttest_at_least_and_exact603,14954
- def test_at_most_but_never_calledtest_at_most_but_never_called613,15184
- def test_at_most_called_oncetest_at_most_called_once619,15320
- def test_at_most_called_twicetest_at_most_called_twice626,15465
- def test_at_most_and_at_least_called_nevertest_at_most_and_at_least_called_never636,15693
- def test_at_most_and_at_least_called_oncetest_at_most_and_at_least_called_once644,15918
- def test_at_most_and_at_least_called_twicetest_at_most_and_at_least_called_twice651,16091
- def test_at_most_and_at_least_called_three_timestest_at_most_and_at_least_called_three_times659,16279
- def test_call_counts_only_apply_to_matching_argstest_call_counts_only_apply_to_matching_args670,16557
- def test_call_counts_only_apply_to_matching_args_with_mismatchtest_call_counts_only_apply_to_matching_args_with_mismatch682,16835
- def test_ordered_calls_in_order_will_passtest_ordered_calls_in_order_will_pass698,17268
- def test_ordered_calls_out_of_order_will_failtest_ordered_calls_out_of_order_will_fail708,17450
- def test_order_calls_with_different_arg_lists_and_in_order_will_passtest_order_calls_with_different_arg_lists_and_in_order_will_pass720,17711
- def test_order_calls_with_different_arg_lists_and_out_of_order_will_failtest_order_calls_with_different_arg_lists_and_out_of_order_will_fail730,17958
- def test_unordered_calls_do_not_effect_ordered_testingtest_unordered_calls_do_not_effect_ordered_testing742,18284
- def test_ordered_with_multiple_calls_will_passtest_ordered_with_multiple_calls_will_pass756,18548
- def test_grouped_ordering_with_numberstest_grouped_ordering_with_numbers768,18757
- def test_grouped_ordering_with_symbolstest_grouped_ordering_with_symbols783,19072
- def test_explicit_ordering_mixed_with_implicit_ordering_should_not_overlaptest_explicit_ordering_mixed_with_implicit_ordering_should_not_overlap798,19428
- def test_explicit_ordering_with_explicit_misorderstest_explicit_ordering_with_explicit_misorders808,19801
- def test_ordering_with_explicit_no_args_matches_correctlytest_ordering_with_explicit_no_args_matches_correctly824,20329
- def test_ordering_with_any_arg_matching_correctly_matchestest_ordering_with_any_arg_matching_correctly_matches836,20702
- def test_ordering_between_mocks_is_not_normally_definedtest_ordering_between_mocks_is_not_normally_defined847,21010
- def test_ordering_between_mocks_is_honored_for_global_orderingtest_ordering_between_mocks_is_honored_for_global_ordering859,21264
- def test_expectation_formatingtest_expectation_formating871,21573
- def test_multi_expectation_formattingtest_multi_expectation_formatting880,21801
- def test_explicit_ordering_with_limits_allow_multiple_return_valuestest_explicit_ordering_with_limits_allow_multiple_return_values886,21964
- def test_global_methods_can_be_mockedtest_global_methods_can_be_mocked905,22675
- def test_kernel_methods_can_be_mockedtest_kernel_methods_can_be_mocked911,22859
- def test_undefing_kernel_methods_dont_effect_other_mockstest_undefing_kernel_methods_dont_effect_other_mocks917,23037
- def test_expectations_can_by_marked_as_defaulttest_expectations_can_by_marked_as_default925,23305
- def test_default_expectations_are_search_in_the_proper_ordertest_default_expectations_are_search_in_the_proper_order931,23467
- def test_expectations_with_count_constraints_can_by_marked_as_defaulttest_expectations_with_count_constraints_can_by_marked_as_default939,23770
- def test_default_expectations_are_overridden_by_later_expectationstest_default_expectations_are_overridden_by_later_expectations947,24006
- def test_default_expectations_can_be_changed_by_later_expectationstest_default_expectations_can_be_changed_by_later_expectations955,24234
- def test_ordered_default_expectations_can_be_specifiedtest_ordered_default_expectations_can_be_specified966,24596
- def test_ordered_default_expectations_can_be_overriddentest_ordered_default_expectations_can_be_overridden974,24837
- def test_by_default_works_at_mock_leveltest_by_default_works_at_mock_level986,25108
- def test_by_default_at_mock_level_does_nothing_with_no_expectationstest_by_default_at_mock_level_does_nothing_with_no_expectations997,25383
- def test_partial_mocks_can_have_default_expectationstest_partial_mocks_can_have_default_expectations1003,25528
- def test_partial_mocks_can_have_default_expectations_overriddentest_partial_mocks_can_have_default_expectations_overridden1009,25709
- def test_wicked_and_evil_tricks_with_by_default_are_thwartedtest_wicked_and_evil_tricks_with_by_default_are_thwarted1016,25957
- def test_mocks_can_handle_multi_parameter_respond_tostest_mocks_can_handle_multi_parameter_respond_tos1028,26362
- def test_can_mock_operatorstest_can_mock_operators1039,26709
- def assert_operator(op, &block)assert_operator1069,27773
-class TestFlexMockShouldsWithInclude < Test::Unit::TestCaseTestFlexMockShouldsWithInclude1077,27927
- def test_include_enables_unqualified_arg_type_referencestest_include_enables_unqualified_arg_type_references1079,28021
-class TestFlexMockArgTypesDontLeak < Test::Unit::TestCaseTestFlexMockArgTypesDontLeak1087,28185
- def test_unqualified_arg_type_references_are_undefined_by_defaulttest_unqualified_arg_type_references_are_undefined_by_default1088,28243
-
-test/test_tu_integration.rb,1570
-class TestTuIntegrationFlexMockMethod < Test::Unit::TestCaseTestTuIntegrationFlexMockMethod14,320
- def test_can_construct_flexmocktest_can_construct_flexmock17,411
- def test_can_construct_flexmock_with_blocktest_can_construct_flexmock_with_block23,558
-class TestTuIntegrationMockVerificationInTeardown < Test::Unit::TestCaseTestTuIntegrationMockVerificationInTeardown31,734
- def teardownteardown34,837
- def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown40,923
-class TestTuIntegrationMockVerificationWithoutSetup < Test::Unit::TestCaseTestTuIntegrationMockVerificationWithoutSetup45,1041
- def teardownteardown48,1146
- def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown54,1232
-class TestTuIntegrationMockVerificationForgetfulSetup < Test::Unit::TestCaseTestTuIntegrationMockVerificationForgetfulSetup59,1350
- def teardownteardown62,1457
- def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown68,1543
-class TestTuIntegrationSetupOverridenAndNoMocksOk < Test::Unit::TestCaseTestTuIntegrationSetupOverridenAndNoMocksOk73,1661
- def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown76,1764
-class TestTuIntegrationFailurePreventsVerification < Test::Unit::TestCaseTestTuIntegrationFailurePreventsVerification80,1827
- def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown83,1931
- def simulate_failuresimulate_failure90,2065
-
-test/test_undefined.rb,873
-class UndefinedTest < Test::Unit::TestCaseUndefinedTest14,320
- def test_undefined_method_calls_return_undefinedtest_undefined_method_calls_return_undefined15,363
- def test_equalstest_equals19,481
- def test_math_operatorstest_math_operators24,579
- def test_math_operators_reversedtest_math_operators_reversed32,788
- def test_comparisonstest_comparisons40,1006
- def test_comparisons_reversedtest_comparisons_reversed48,1215
- def test_base_level_methodstest_base_level_methods56,1433
- def test_cant_create_a_new_undefinedtest_cant_create_a_new_undefined60,1520
- def test_cant_clone_undefinedtest_cant_clone_undefined64,1630
- def test_string_representationstest_string_representations69,1764
- def test_undefined_is_not_niltest_undefined_is_not_nil74,1902
- def assert_undefined(obj)assert_undefined80,1980
- def undefinedundefined84,2043
-
-test/test_unit_integration/test_auto_test_unit.rb,263
-class TestFlexmockTestUnit < Test::Unit::TestCaseTestFlexmockTestUnit17,374
- def teardownteardown18,424
- def test_can_create_mockstest_can_create_mocks23,483
- def test_should_fail__mocks_are_auto_verifiedtest_should_fail__mocks_are_auto_verified30,626
+ def assert_failure(options={}, &block)assert_failure16,378
+ def assert_mock_failure(options={}, &block)assert_mock_failure33,930
+ def assert_matching_line(ex, file, options)assert_matching_line47,1403
+
+В�:�,263
+class TestFlexmockTestUnit < Test::Unit::TestCaseTestFlexmockTestUnit17,375
+ def teardownteardown18,425
+ def test_can_create_mockstest_can_create_mocks23,484
+ def test_should_fail__mocks_are_auto_verifiedtest_should_fail__mocks_are_auto_verified30,627
+
+/var/folders/b9/zwv8g_296jq17rcjpjw_94jc0000gn/T//tags.wSbSTw,1606
+ class TestTuIntegrationFlexMockMethod < Test::Unit::TestCaseTestTuIntegrationFlexMockMethod19,548
+ def test_can_construct_flexmocktest_can_construct_flexmock22,643
+ def test_can_construct_flexmock_with_blocktest_can_construct_flexmock_with_block28,800
+ class TestTuIntegrationMockVerificationInTeardown < Test::Unit::TestCaseTestTuIntegrationMockVerificationInTeardown36,990
+ def teardownteardown39,1097
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown45,1193
+ class TestTuIntegrationMockVerificationWithoutSetup < Test::Unit::TestCaseTestTuIntegrationMockVerificationWithoutSetup50,1319
+ def teardownteardown53,1428
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown59,1524
+ class TestTuIntegrationMockVerificationForgetfulSetup < Test::Unit::TestCaseTestTuIntegrationMockVerificationForgetfulSetup64,1650
+ def teardownteardown67,1761
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown73,1857
+ class TestTuIntegrationSetupOverridenAndNoMocksOk < Test::Unit::TestCaseTestTuIntegrationSetupOverridenAndNoMocksOk78,1983
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown81,2090
+ class TestTuIntegrationFailurePreventsVerification < Test::Unit::TestCaseTestTuIntegrationFailurePreventsVerification85,2159
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown88,2267
+ def simulate_failuresimulate_failure95,2411
+
+test/undefined_test.rb,873
+class UndefinedTest < Test::Unit::TestCaseUndefinedTest14,321
+ def test_undefined_method_calls_return_undefinedtest_undefined_method_calls_return_undefined15,364
+ def test_equalstest_equals19,482
+ def test_math_operatorstest_math_operators24,580
+ def test_math_operators_reversedtest_math_operators_reversed32,789
+ def test_comparisonstest_comparisons40,1007
+ def test_comparisons_reversedtest_comparisons_reversed48,1216
+ def test_base_level_methodstest_base_level_methods56,1434
+ def test_cant_create_a_new_undefinedtest_cant_create_a_new_undefined60,1521
+ def test_cant_clone_undefinedtest_cant_clone_undefined64,1631
+ def test_string_representationstest_string_representations69,1765
+ def test_undefined_is_not_niltest_undefined_is_not_nil74,1903
+ def assert_undefined(obj)assert_undefined80,1981
+ def undefinedundefined84,2044
+
+,40
+class DogDog3,36
+ def barkbark4,46
+
+,0
diff --git a/doc/GoogleExample.rdoc b/doc/GoogleExample.rdoc
index 9f1e498..cf5acca 100755
--- a/doc/GoogleExample.rdoc
+++ b/doc/GoogleExample.rdoc
@@ -1,6 +1,8 @@
= Extended FlexMock Example Using Google4R
-Google4R is a simple Ruby wrapper around the Google APIs. In this extended example, we will use FlexMock to test software that uses the Google APIs, without every communicating with Google itself.
+Google4R is a simple Ruby wrapper around the Google APIs. In this
+extended example, we will use FlexMock to test software that uses the
+Google APIs, without every communicating with Google itself.
== Purchase.rb
@@ -38,9 +40,11 @@ talking to the Google APIs. The config object given to the Purchase
initializer is simply a hash of values defining the merchant_id, merchant_key
and sandbox flag. To use the real Google checkout APIs, you will need to
obtains a merchant id and key from Google. Since we will be mocking the Google
-interaction, we can use dummy values in our test.
+interaction, we can use dummy values in our test.
-The tax table factory is required by the Google4R software. We provide the following simplified one. Read the Google API documents for more information.
+The tax table factory is required by the Google4R software. We provide
+the following simplified one. Read the Google API documents for more
+information.
class TestTaxTableFactory
def effective_tax_tables_at(time)
@@ -49,12 +53,14 @@ The tax table factory is required by the Google4R software. We provide the foll
tax_free_table.create_rule do |rule|
rule.area = UsCountryArea.new(UsCountryArea::ALL)
rule.rate = 0.0
- end
+ end
return [tax_free_table]
end
end
-+Item+ is simply an ActiveRecord class that we are using to hold our purchase item information. It should respond to the +name+, +description+ and +unit_price+ messages.
++Item+ is simply an ActiveRecord class that we are using to hold our
+purchase item information. It should respond to the +name+,
++description+ and +unit_price+ messages.
== Testing Without Using External Resources
@@ -108,15 +114,15 @@ Here is the complete unit test:
:name => "Deschutes",
:description => "Deschutes model Guitar",
:unit_price => Money.new(2400.00)))
-
+
flexmock(Google4R::Checkout::CheckoutCommand).new_instances do |instance|
instance.should_receive(:send_to_google_checkout).once.
and_return(flexmock(:redirect_url => "http://google.response.url"))
end
# Execute
- p = Purchase.new({
- :merchant_id => 'dummy_id',
+ p = Purchase.new({
+ :merchant_id => 'dummy_id',
:merchant_key => 'dummy_key',
:use_sandbox => true })
url = p.purchase(1)
@@ -124,27 +130,37 @@ Here is the complete unit test:
# Assert
assert_equal "http://google.response.url", url
end
-
+
== Testing the Details
-The above test is fine as far as it goes. It demonstrates how to use mocks to
-avoid talking to external resources such as databases and web services. But as a unit test, it is sorely lacking in several areas.
+The above test is fine as far as it goes. It demonstrates how to use
+mocks to avoid talking to external resources such as databases and web
+services. But as a unit test, it is sorely lacking in several areas.
-All the test really demonstrates is that the +send_to_google_checkout+ method is called. There are no tests to ensure that the right item descriptions and prices are correctly stored in the cart. In fact, if we rewrote the purchase method as follows:
+All the test really demonstrates is that the +send_to_google_checkout+
+method is called. There are no tests to ensure that the right item
+descriptions and prices are correctly stored in the cart. In fact, if
+we rewrote the purchase method as follows:
def purchase(item_id, quantity=1)
@frontend.create_checkout_command.send_to_google_checkout.redirect_url
- end
+ end
-it would still pass the unit test we designed, even though the rewrite is obviously an incorrect implementation.
+it would still pass the unit test we designed, even though the rewrite
+is obviously an incorrect implementation.
A more complete test is a bit more complicated. Here are the details.
=== Mocking Active Record
-Our incorrect version of purchase never calls the +find+ method of Item. We can easily test for that by adding a +once+ constraint one that mock specification. Since find is a read-only method, we don't really care if it is called multiple times, as long as it is called at least one time, so we will add an +at_least+ modifier as well.
+Our incorrect version of purchase never calls the +find+ method of
+Item. We can easily test for that by adding a +once+ constraint one
+that mock specification. Since find is a read-only method, we don't
+really care if it is called multiple times, as long as it is called at
+least one time, so we will add an +at_least+ modifier as well.
-Finally, we are going to break the guitar mock out into its own declaration. The reason will become obvious in a bit.
+Finally, we are going to break the guitar mock out into its own
+declaration. The reason will become obvious in a bit.
mock_guitar = flexmock("guitar",
:name => "Deschutes",
@@ -156,11 +172,19 @@ Finally, we are going to break the guitar mock out into its own declaration. Th
=== Mocking a Cart Item
-The next bit is a wee bit complicated, but we will handle it a little bit at a time so that it doesn't become overwhelming.
+The next bit is a wee bit complicated, but we will handle it a little
+bit at a time so that it doesn't become overwhelming.
-There are three main objects in the Google checkout API that we deal with in the next section.: (1) the checkout command object returned by the front end, (2) the cart object returned by the checkout command, and (3) the item passed to the block in the +create_item+ call.
+There are three main objects in the Google checkout API that we deal
+with in the next section.: (1) the checkout command object returned by
+the front end, (2) the cart object returned by the checkout command,
+and (3) the item passed to the block in the +create_item+ call.
-We will tackle them in reverse order, starting with the item objects given to the +create_item+ block. The item must respond to four attribute assignments. This is straightforward to mock, just make sure you include the +once+ constraint so that the assignments are required.
+We will tackle them in reverse order, starting with the item objects
+given to the +create_item+ block. The item must respond to four
+attribute assignments. This is straightforward to mock, just make sure
+you include the +once+ constraint so that the assignments are
+required.
mock_item = flexmock("item")
mock_item.should_receive(:name=).with(mock_guitar.name).once
@@ -168,18 +192,24 @@ We will tackle them in reverse order, starting with the item objects given to th
mock_item.should_receive(:unit_price=).with(mock_guitar.unit_price).once
mock_item.should_receive(:quantity=).with(1).once
-Notice how we used the mock_guitar object defined earlier to provide values in the +with+ constraint. This way we don't have to repeat the explicit strings and values we are checking. (Keep it DRY!).
+Notice how we used the mock_guitar object defined earlier to provide
+values in the +with+ constraint. This way we don't have to repeat the
+explicit strings and values we are checking. (Keep it DRY!).
=== Mocking the Cart
-The mock cart object will pass the mock_item to a block when the +create_item+ method is called. We specify that with the following:
+The mock cart object will pass the mock_item to a block when the
++create_item+ method is called. We specify that with the following:
mock_cart = flexmock("cart")
mock_cart.should_receive(:create_item).with(Proc).once.and_return { |block|
block.call(mock_item)
}
-FlexMock objects can handle blocks passed to them by treating them as the final object in the calling list. Use +Proc+ in the +with+ constraint to match the block and then invoke the block explicitly via <tt>block.call(...)</tt> in the +and_return+ specification.
+FlexMock objects can handle blocks passed to them by treating them as
+the final object in the calling list. Use +Proc+ in the +with+
+constraint to match the block and then invoke the block explicitly via
+<tt>block.call(...)</tt> in the +and_return+ specification.
=== Mocking the Checkout Command
@@ -223,8 +253,8 @@ Here is the complete detailed version of the test method.
end
# Execute
- p = Purchase.new({
- :merchant_id => 'dummy_id',
+ p = Purchase.new({
+ :merchant_id => 'dummy_id',
:merchant_key => 'dummy_key',
:use_sandbox => true })
url = p.purchase(1)
@@ -253,9 +283,9 @@ Perhaps, but using mock objects have several definite advantages:
your code correctly handle the case where you get an exception when
connecting to google? Mocks can easily create those error conditions that
are difficult to achieve with real objects.
-
+
E.g.
-
+
instance.should_receive(:send_to_google_checkout).once.
and_return { raise Google4R::Checkout::GoogleCheckoutError }
@@ -272,4 +302,4 @@ expect it to. We don't actually care about the Google4R software itself in
this test case (presumably we do have tests that cover Google4R, but those are
different tests).
-In the end, mock objects are a power tool to have in your testing toolbox.
\ No newline at end of file
+In the end, mock objects are a powerful tool to have in your testing toolbox.
\ No newline at end of file
diff --git a/doc/examples/rspec_examples_spec.rdoc b/doc/examples/rspec_examples_spec.rdoc
new file mode 100644
index 0000000..93bb99f
--- /dev/null
+++ b/doc/examples/rspec_examples_spec.rdoc
@@ -0,0 +1,245 @@
+= FlexMock Examples
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe "Simple Spec" do
+
+ # Simple stubbing of some methods
+
+ it "stubs a couple of methods" do
+ m = flexmock(:pi => 3.1416, :e => 2.71)
+ m.pi.should == 3.1416
+ m.e.should == 2.71
+ end
+ end
+
+
+ describe "Returning Undefined" do
+
+ # Create a mock object that returns an undefined object for method calls
+
+ it "returns undefined values" do
+ m = flexmock("mock")
+ m.should_receive(:divide_by).with(0).
+ and_return_undefined
+
+ m.divide_by(0).should == FlexMock.undefined
+ end
+ end
+
+ describe "Multiple Queries and Single Updates" do
+
+ # Expect multiple queries and a single update
+
+ # Multiple calls to the query method will be allows, and calls may
+ # have any argument list. Each call to query will return the three
+ # element array [1, 2, 3]. The call to update must have a specific
+ # argument of 5.
+
+ it "queries the db" do
+ db = flexmock('db')
+ db.should_receive(:query).and_return([1,2,3])
+ db.should_receive(:update).with(5).and_return(nil).once
+
+ # Test Code
+
+ db.query
+ db.update(5)
+ end
+ end
+
+ describe "Ordered Mocks" do
+
+ # Expect all queries before any updates
+
+ # All the query message must occur before any of the update
+ # messages.
+
+ it "queries and updates the database" do
+ db = flexmock('db')
+ db.should_receive(:query).and_return([1,2,3]).ordered
+ db.should_receive(:update).and_return(nil).ordered
+
+ # test code here
+
+ db.query
+ db.update
+ end
+ end
+
+ describe "Ordered Mocks" do
+
+ # Expect several queries with different parameters
+
+ # The queries should happen after startup but before finish. The
+ # queries themselves may happen in any order (because they are in
+ # the same order group). The first two queries should happen exactly
+ # once, but the third query (which matches any query call with a
+ # four character parameter) may be called multiple times (but at
+ # least once). Startup and finish must also happen exactly once.
+
+ # Also note that we use the <code>with</code> method to match
+ # different argument values to figure out what value to return.
+
+ it "queries the database in a particular order" do
+ db = flexmock('db')
+ db.should_receive(:startup).once.ordered
+ db.should_receive(:query).with("CPWR").and_return(12.3).
+ once.ordered(:queries)
+ db.should_receive(:query).with("MSFT").and_return(10.0).
+ once.ordered(:queries)
+ db.should_receive(:query).with(/^....$/).and_return(3.3).
+ at_least.once.ordered(:queries)
+ db.should_receive(:finish).once.ordered
+
+ # Test Code
+
+ db.startup
+ db.query("MSFT")
+ db.query("XYZY")
+ db.query("CPWR")
+ db.finish
+ end
+ end
+
+ describe "Ordered Mocks" do
+
+ # Same as above, but using the Record Mode interface
+
+ # The record mode interface offers much the same features as the
+ # <code>should_receive</code> interface introduced so far, but it
+ # allows the messages to be sent directly to a recording object
+ # rather than be specified indirectly using a symbol.
+
+
+ it "records the queries for replay" do
+ db = flexmock('db')
+ db.should_expect do |rec|
+ rec.startup.once.ordered
+ rec.query("CPWR") { 12.3 }.once.ordered(:queries)
+ rec.query("MSFT") { 10.0 }.once.ordered(:queries)
+ rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries)
+ rec.finish.once.ordered
+ end
+
+ # Test Code
+
+ db.startup
+ db.query("MSFT")
+ db.query("XYZY")
+ db.query("CPWR")
+ db.finish
+ end
+ end
+
+ describe "Record Mode" do
+
+ # Using Record Mode to record a known, good algorithm for testing
+
+ # Record mode is nice when you have a known, good algorithm that can
+ # use a recording mock object to record the steps. Then you compare
+ # the execution of a new algorithm to behavior of the old using the
+ # recorded expectations in the mock. For this you probably want to
+ # put the recorder in _strict_ mode so that the recorded
+ # expectations use exact matching on argument lists, and strict
+ # ordering of the method calls.
+
+ # <b>Note:</b> This is most useful when there are no queries on the
+ # mock objects, because the query responses cannot be programmed
+ # into the recorder object.
+
+ it "compares a know algorithm with a new algorithm" do
+ builder = flexmock('builder')
+ builder.should_expect do |rec|
+ rec.should_be_strict
+ known_good_way_to_build_xml(rec) # record the messages
+ end
+ new_way_to_build_xml(builder) # compare to new way
+ end
+
+ def known_good_way_to_build_xml(builder)
+ builder.person
+ end
+
+ def new_way_to_build_xml(builder)
+ builder.person
+ end
+
+ end
+
+ describe "Multiple Return Values" do
+
+ # Expect multiple calls, returning a different value each time
+
+ # Sometimes you need to return different values for each call to a
+ # mocked method. This example shifts values out of a list for this
+ # effect.
+
+ it "returns multiple values" do
+ file = flexmock('file')
+ file.should_receive(:gets).with_no_args.
+ and_return("line 1\n", "line 2\n")
+
+ # test code here
+
+ file.gets # returns "line 1"
+ file.gets # returns "line 2"
+ end
+ end
+
+ describe "Ignore Unimportant Messages" do
+
+ # Ignore uninteresting messages
+
+ # Generally you need to mock only those methods that return an
+ # interesting value or wish to assert were sent in a particular
+ # manner. Use the <code>should_ignore_missing</code> method to turn
+ # on missing method ignoring.
+
+ it "ignores unimportant messages" do
+ m = flexmock('m')
+ m.should_receive(:an_important_message).and_return(1).once
+ m.should_ignore_missing
+
+ # Test Code
+
+ m.an_important_message
+ m.an_unimportant_message
+ end
+
+ # When <code>should_ignore_missing</code> is enabled, ignored
+ # missing methods will return an undefined object. Any operation on
+ # the undefined object will return the undefined object.
+
+ end
+
+
+ describe "Partial Mocks" do
+
+ # Mock just one method on an existing object
+
+ # The Portfolio class calculate the value of a set of stocks by
+ # talking to a quote service via a web service. Since we don't want
+ # to use a real web service in our unit tests, we will mock the
+ # quote service.
+
+ it "returns the portfolio value" do
+ flexmock(QuoteService).new_instances do |m|
+ m.should_receive(:quote).and_return(100)
+ end
+ port = Portfolio.new
+ value = port.value # Portfolio calls QuoteService.quote
+ value.should == 100
+ end
+
+ class QuoteService
+ end
+
+ class Portfolio
+ def value
+ qs = QuoteService.new
+ qs.quote
+ end
+ end
+ end
diff --git a/doc/examples/test_unit_examples_test.rdoc b/doc/examples/test_unit_examples_test.rdoc
new file mode 100644
index 0000000..bfc57ee
--- /dev/null
+++ b/doc/examples/test_unit_examples_test.rdoc
@@ -0,0 +1,241 @@
+= FlexMock Examples
+ require 'flexmock/test_unit'
+
+ class TestSimple < Test::Unit::TestCase
+
+ # Simple stubbing of some methods
+
+ def test_simple_mock
+ m = flexmock(:pi => 3.1416, :e => 2.71)
+ assert_equal 3.1416, m.pi
+ assert_equal 2.71, m.e
+ end
+ end
+
+
+ class TestUndefined < Test::Unit::TestCase
+
+ # Create a mock object that returns an undefined object for method calls
+
+ def test_undefined_values
+ m = flexmock("mock")
+ m.should_receive(:divide_by).with(0).
+ and_return_undefined
+ assert_equal FlexMock.undefined, m.divide_by(0)
+ end
+ end
+
+ class TestDb < Test::Unit::TestCase
+
+ # Expect multiple queries and a single update
+
+ # Multiple calls to the query method will be allows, and calls may
+ # have any argument list. Each call to query will return the three
+ # element array [1, 2, 3]. The call to update must have a specific
+ # argument of 5.
+
+ def test_db
+ db = flexmock('db')
+ db.should_receive(:query).and_return([1,2,3])
+ db.should_receive(:update).with(5).and_return(nil).once
+
+ # Test Code
+
+ db.query
+ db.update(5)
+ end
+ end
+
+ class TestOrdered < Test::Unit::TestCase
+
+ # Expect all queries before any updates
+
+ # All the query message must occur before any of the update
+ # messages.
+
+ def test_query_and_update
+ db = flexmock('db')
+ db.should_receive(:query).and_return([1,2,3]).ordered
+ db.should_receive(:update).and_return(nil).ordered
+
+ # test code here
+
+ db.query
+ db.update
+ end
+ end
+
+ class MoreOrdered < Test::Unit::TestCase
+
+ # Expect several queries with different parameters
+
+ # The queries should happen after startup but before finish. The
+ # queries themselves may happen in any order (because they are in
+ # the same order group). The first two queries should happen exactly
+ # once, but the third query (which matches any query call with a
+ # four character parameter) may be called multiple times (but at
+ # least once). Startup and finish must also happen exactly once.
+
+ # Also note that we use the <code>with</code> method to match
+ # different argument values to figure out what value to return.
+
+ def test_ordered_queries
+ db = flexmock('db')
+ db.should_receive(:startup).once.ordered
+ db.should_receive(:query).with("CPWR").and_return(12.3).
+ once.ordered(:queries)
+ db.should_receive(:query).with("MSFT").and_return(10.0).
+ once.ordered(:queries)
+ db.should_receive(:query).with(/^....$/).and_return(3.3).
+ at_least.once.ordered(:queries)
+ db.should_receive(:finish).once.ordered
+
+ # Test Code
+
+ db.startup
+ db.query("MSFT")
+ db.query("XYZY")
+ db.query("CPWR")
+ db.finish
+ end
+ end
+
+ class EvenMoreOrderedTest < Test::Unit::TestCase
+
+ # Same as above, but using the Record Mode interface
+
+ # The record mode interface offers much the same features as the
+ # <code>should_receive</code> interface introduced so far, but it
+ # allows the messages to be sent directly to a recording object
+ # rather than be specified indirectly using a symbol.
+
+
+ def test_ordered_queries_in_record_mode
+ db = flexmock('db')
+ db.should_expect do |rec|
+ rec.startup.once.ordered
+ rec.query("CPWR") { 12.3 }.once.ordered(:queries)
+ rec.query("MSFT") { 10.0 }.once.ordered(:queries)
+ rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries)
+ rec.finish.once.ordered
+ end
+
+ # Test Code
+
+ db.startup
+ db.query("MSFT")
+ db.query("XYZY")
+ db.query("CPWR")
+ db.finish
+ end
+ end
+
+ class RecordedTest < Test::Unit::TestCase
+
+ # Using Record Mode to record a known, good algorithm for testing
+
+ # Record mode is nice when you have a known, good algorithm that can
+ # use a recording mock object to record the steps. Then you compare
+ # the execution of a new algorithm to behavior of the old using the
+ # recorded expectations in the mock. For this you probably want to
+ # put the recorder in _strict_ mode so that the recorded
+ # expectations use exact matching on argument lists, and strict
+ # ordering of the method calls.
+
+ # <b>Note:</b> This is most useful when there are no queries on the
+ # mock objects, because the query responses cannot be programmed
+ # into the recorder object.
+
+ def test_build_xml
+ builder = flexmock('builder')
+ builder.should_expect do |rec|
+ rec.should_be_strict
+ known_good_way_to_build_xml(rec) # record the messages
+ end
+ new_way_to_build_xml(builder) # compare to new way
+ end
+
+ def known_good_way_to_build_xml(builder)
+ builder.person
+ end
+
+ def new_way_to_build_xml(builder)
+ builder.person
+ end
+
+ end
+
+ class MultipleReturnValueTest < Test::Unit::TestCase
+
+ # Expect multiple calls, returning a different value each time
+
+ # Sometimes you need to return different values for each call to a
+ # mocked method. This example shifts values out of a list for this
+ # effect.
+
+ def test_multiple_gets
+ file = flexmock('file')
+ file.should_receive(:gets).with_no_args.
+ and_return("line 1\n", "line 2\n")
+
+ # test code here
+
+ file.gets # returns "line 1"
+ file.gets # returns "line 2"
+ end
+ end
+
+ class IgnoreUnimportantMessages < Test::Unit::TestCase
+
+ # Ignore uninteresting messages
+
+ # Generally you need to mock only those methods that return an
+ # interesting value or wish to assert were sent in a particular
+ # manner. Use the <code>should_ignore_missing</code> method to turn
+ # on missing method ignoring.
+
+ def test_an_important_message
+ m = flexmock('m')
+ m.should_receive(:an_important_message).and_return(1).once
+ m.should_ignore_missing
+
+ # Test Code
+
+ m.an_important_message
+ m.an_unimportant_message
+ end
+
+ # When <code>should_ignore_missing</code> is enabled, ignored
+ # missing methods will return an undefined object. Any operation on
+ # the undefined object will return the undefined object.
+
+ end
+
+ class PartialMockTest < Test::Unit::TestCase
+
+ # Mock just one method on an existing object
+
+ # The Portfolio class calculate the value of a set of stocks by
+ # talking to a quote service via a web service. Since we don't want
+ # to use a real web service in our unit tests, we will mock the
+ # quote service.
+
+ def test_portfolio_value
+ flexmock(QuoteService).new_instances do |m|
+ m.should_receive(:quote).and_return(100)
+ end
+ port = Portfolio.new
+ value = port.value # Portfolio calls QuoteService.quote
+ assert_equal 100, value
+ end
+
+ class QuoteService
+ end
+
+ class Portfolio
+ def value
+ qs = QuoteService.new
+ qs.quote
+ end
+ end
+ end
diff --git a/doc/index.rdoc b/doc/index.rdoc
new file mode 100644
index 0000000..0f280e5
--- /dev/null
+++ b/doc/index.rdoc
@@ -0,0 +1,31 @@
+= Flex Mock -- Making Mocking Easy
+
+FlexMock is a simple, but flexible, mock object library for Ruby unit
+testing.
+
+This is the API documentation site for flexmock. You can find the user
+documentation at http://github.com/jimweirich/flexmock
+
+== Links
+
+* <b>User Guide</b> -- http://github.com/jimweirich/flexmock
+* <b>API Documents</b> -- http://flexmock.rubyforge.org
+* <b>RubyGems</b> -- Install with: `gem install flexmock`
+* <b>Source</b> -- https://github.com/jimweirich/flexmock
+* <b>Bug Reports / Issue Tracking</b> -- https://github.com/jimweirich/flexmock/issues
+* <b>Continuous Integration</b> -- http://travis-ci.org/#!/jimweirich/flexmock
+
+== License
+
+Copyright 2003-2013 by Jim Weirich (jim.weirich at gmail.com).
+All rights reserved.
+
+Permission is granted for use, copying, modification, distribution,
+and distribution of modified versions of this work as long as the
+above copyright notice is included.
+
+== Warranty
+
+This software is provided "as is" and without any express or implied
+warranties, including, without limitation, the implied warranties of
+merchantibility and fitness for a particular purpose.
diff --git a/doc/releases/flexmock-1.0.0.rdoc b/doc/releases/flexmock-1.0.0.rdoc
new file mode 100644
index 0000000..eab884c
--- /dev/null
+++ b/doc/releases/flexmock-1.0.0.rdoc
@@ -0,0 +1,138 @@
+= FlexMock 1.0.0 Released
+
+FlexMock is a flexible mocking library for use in unit testing and
+behavior specification in Ruby. Release 1.0.0 is a major release with
+some nice features and bug fixes.
+
+== Changes in 1.0.0
+
+=== Features
+
+* Mocks may now have a base class that limits what methods may be
+ mocked. This allows early detection of outdated mock setups when the
+ methods in the class are refactored.
+
+* Spy assertions are now allowed. The verification of the calling of
+ mocked methods may now be done in the "then" portion of the test,
+ after the code under test has been run. This allows for much more
+ natural Given/When/Then style testing.
+
+* A custom assert method (assert_spy_called) has been added to make
+ spy assertions easy when using Test::Unit or MiniTest.
+
+* An RSpec matcher (have_received) has been added to make spy
+ assertions easy when using RSpec.
+
+=== Bug Fixes
+
+* Now correctly handling the mocking of meta-programmed methods.
+
+* Using the documented +singleton_methods+ method.
+
+* Accidently trying to partial mock a regular mock is now a no-op.
+
+== What is FlexMock?
+
+FlexMock is a flexible framework for creating mock object for testing.
+When running unit tests, it is often desirable to use isolate the
+objects being tested from the "real world" by having them interact
+with simplified test objects. Sometimes these test objects simply
+return values when called, other times they verify that certain
+methods were called with particular arguments in a particular order.
+
+FlexMock makes creating these test objects easy.
+
+=== Features
+
+* Easy integration with both Test::Unit and RSpec. Mocks created with the
+ flexmock method are automatically verified at the end of the test or
+ example.
+
+* A fluent interface that allows mock behavior to be specified very
+ easily.
+
+* A "record mode" where an existing implementation can record its
+ interaction with a mock for later validation against a new
+ implementation.
+
+* Easy mocking of individual methods in existing, non-mock objects.
+
+* Easy mocking of chains of method calls.
+
+* The ability to cause classes to instantiate test instances (instead of real
+ instances) for the duration of a test.
+
+=== Example
+
+Suppose you had a Dog object that wagged a tail when it was happy.
+Something like this:
+
+ class Dog
+ def initialize(a_tail)
+ @tail = a_tail
+ end
+ def happy
+ @tail.wag
+ end
+ end
+
+To test the +Dog+ class without a real +Tail+ object (perhaps because
+real +Tail+ objects activate servos in some robotic equipment), you
+can do something like this:
+
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ tail.should_receive(:wag).once
+ dog = Dog.new(tail)
+ dog.happy
+ end
+ end
+
+FlexMock will automatically verify that the mocked tail object received the
+message +wag+ exactly one time. If it doesn't, the test will not pass.
+
+Here's the same thing using the new spy support:
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ dog = Dog.new(tail)
+ dog.happy
+ tail.should have_received(:wag)
+ end
+ end
+
+This style works particularly well with the rspec-given library.
+
+ require 'rspec/given'
+
+ describe Dog do
+ context "when the dog is happy" do
+ Given(:tail) { flexmock(:on, Tail) }
+ Given(:dog) { Dog.new(tail) }
+
+ When { dog.happy }
+
+ Then { tail.should have_received(:wag) }
+ end
+ end
+
+See the FlexMock documentation at http://flexmock.rubyforge.org for details on
+specifying arguments and return values on mocked methods, as well as a simple
+technique for mocking tail objects when the Dog class creates the tail objects
+directly.
+
+== Availability
+
+You can make sure you have the latest version with a quick RubyGems command:
+
+ gem install flexmock (you may need root/admin privileges)
+
+You will find documentation at: http://flexmock.rubyforge.org.
+
+-- Jim Weirich
diff --git a/doc/releases/flexmock-1.0.3.rdoc b/doc/releases/flexmock-1.0.3.rdoc
new file mode 100644
index 0000000..91fd9f6
--- /dev/null
+++ b/doc/releases/flexmock-1.0.3.rdoc
@@ -0,0 +1,159 @@
+= FlexMock 1.0.3 Released
+
+FlexMock is a flexible mocking library for use in unit testing and
+behavior specification in Ruby. Release 1.0.0 is a minor release with
+a few bug fixes.
+
+== Changes in 1.0.3
+
+=== Features
+
+* Better error messages when a mock is called the incorrect number of
+ times
+
+* Better stack output when validations fail during teardown.
+
+== Changes in 1.0.2
+
+=== Bug Fixes
+
+* Quick definitions now obey base class restrictions
+
+== Changes in 1.0.1
+
+=== Features
+
+* Better Ruby 1.8 compatibility
+
+== Changes in 1.0.0
+
+=== Features
+
+* Mocks may now have a base class that limits what methods may be
+ mocked. This allows early detection of outdated mock setups when the
+ methods in the class are refactored.
+
+* Spy assertions are now allowed. The verification of the calling of
+ mocked methods may now be done in the "then" portion of the test,
+ after the code under test has been run. This allows for much more
+ natural Given/When/Then style testing.
+
+* A custom assert method (assert_spy_called) has been added to make
+ spy assertions easy when using Test::Unit or MiniTest.
+
+* An RSpec matcher (have_received) has been added to make spy
+ assertions easy when using RSpec.
+
+=== Bug Fixes
+
+* Now correctly handling the mocking of meta-programmed methods.
+
+* Using the documented +singleton_methods+ method.
+
+* Accidently trying to partial mock a regular mock is now a no-op.
+
+== What is FlexMock?
+
+FlexMock is a flexible framework for creating mock object for testing.
+When running unit tests, it is often desirable to use isolate the
+objects being tested from the "real world" by having them interact
+with simplified test objects. Sometimes these test objects simply
+return values when called, other times they verify that certain
+methods were called with particular arguments in a particular order.
+
+FlexMock makes creating these test objects easy.
+
+=== Features
+
+* Easy integration with both Test::Unit and RSpec. Mocks created with the
+ flexmock method are automatically verified at the end of the test or
+ example.
+
+* A fluent interface that allows mock behavior to be specified very
+ easily.
+
+* A "record mode" where an existing implementation can record its
+ interaction with a mock for later validation against a new
+ implementation.
+
+* Easy mocking of individual methods in existing, non-mock objects.
+
+* Easy mocking of chains of method calls.
+
+* The ability to cause classes to instantiate test instances (instead of real
+ instances) for the duration of a test.
+
+=== Example
+
+Suppose you had a Dog object that wagged a tail when it was happy.
+Something like this:
+
+ class Dog
+ def initialize(a_tail)
+ @tail = a_tail
+ end
+ def happy
+ @tail.wag
+ end
+ end
+
+To test the +Dog+ class without a real +Tail+ object (perhaps because
+real +Tail+ objects activate servos in some robotic equipment), you
+can do something like this:
+
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ tail.should_receive(:wag).once
+ dog = Dog.new(tail)
+ dog.happy
+ end
+ end
+
+FlexMock will automatically verify that the mocked tail object received the
+message +wag+ exactly one time. If it doesn't, the test will not pass.
+
+Here's the same thing using the new spy support:
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ dog = Dog.new(tail)
+ dog.happy
+ tail.should have_received(:wag)
+ end
+ end
+
+This style works particularly well with the rspec-given library.
+
+ require 'rspec/given'
+
+ describe Dog do
+ context "when the dog is happy" do
+ Given(:tail) { flexmock(:on, Tail) }
+ Given(:dog) { Dog.new(tail) }
+
+ When { dog.happy }
+
+ Then { tail.should have_received(:wag) }
+ end
+ end
+
+See the FlexMock documentation at http://flexmock.rubyforge.org for details on
+specifying arguments and return values on mocked methods, as well as a simple
+technique for mocking tail objects when the Dog class creates the tail objects
+directly.
+
+== Availability
+
+You can make sure you have the latest version with a quick RubyGems command:
+
+ gem install flexmock (you may need root/admin privileges)
+
+You will find documentation at: http://flexmock.rubyforge.org.
+
+-- Jim Weirich
diff --git a/doc/releases/flexmock-1.0.4.rdoc b/doc/releases/flexmock-1.0.4.rdoc
new file mode 100644
index 0000000..281bd9c
--- /dev/null
+++ b/doc/releases/flexmock-1.0.4.rdoc
@@ -0,0 +1,165 @@
+= FlexMock 1.0.4 Released
+
+FlexMock is a flexible mocking library for use in unit testing and
+behavior specification in Ruby. Release 1.0.3 is a minor release with
+a few bug fixes.
+
+== Changes in 1.0.4
+
+=== Features
+
+* Add spy capability.
+
+== Changes in 1.0.3
+
+=== Features
+
+* Better error messages when a mock is called the incorrect number of
+ times
+
+* Better stack output when validations fail during teardown.
+
+== Changes in 1.0.2
+
+=== Bug Fixes
+
+* Quick definitions now obey base class restrictions
+
+== Changes in 1.0.1
+
+=== Features
+
+* Better Ruby 1.8 compatibility
+
+== Changes in 1.0.0
+
+=== Features
+
+* Mocks may now have a base class that limits what methods may be
+ mocked. This allows early detection of outdated mock setups when the
+ methods in the class are refactored.
+
+* Spy assertions are now allowed. The verification of the calling of
+ mocked methods may now be done in the "then" portion of the test,
+ after the code under test has been run. This allows for much more
+ natural Given/When/Then style testing.
+
+* A custom assert method (assert_spy_called) has been added to make
+ spy assertions easy when using Test::Unit or MiniTest.
+
+* An RSpec matcher (have_received) has been added to make spy
+ assertions easy when using RSpec.
+
+=== Bug Fixes
+
+* Now correctly handling the mocking of meta-programmed methods.
+
+* Using the documented +singleton_methods+ method.
+
+* Accidently trying to partial mock a regular mock is now a no-op.
+
+== What is FlexMock?
+
+FlexMock is a flexible framework for creating mock object for testing.
+When running unit tests, it is often desirable to use isolate the
+objects being tested from the "real world" by having them interact
+with simplified test objects. Sometimes these test objects simply
+return values when called, other times they verify that certain
+methods were called with particular arguments in a particular order.
+
+FlexMock makes creating these test objects easy.
+
+=== Features
+
+* Easy integration with both Test::Unit and RSpec. Mocks created with the
+ flexmock method are automatically verified at the end of the test or
+ example.
+
+* A fluent interface that allows mock behavior to be specified very
+ easily.
+
+* A "record mode" where an existing implementation can record its
+ interaction with a mock for later validation against a new
+ implementation.
+
+* Easy mocking of individual methods in existing, non-mock objects.
+
+* Easy mocking of chains of method calls.
+
+* The ability to cause classes to instantiate test instances (instead of real
+ instances) for the duration of a test.
+
+=== Example
+
+Suppose you had a Dog object that wagged a tail when it was happy.
+Something like this:
+
+ class Dog
+ def initialize(a_tail)
+ @tail = a_tail
+ end
+ def happy
+ @tail.wag
+ end
+ end
+
+To test the +Dog+ class without a real +Tail+ object (perhaps because
+real +Tail+ objects activate servos in some robotic equipment), you
+can do something like this:
+
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ tail.should_receive(:wag).once
+ dog = Dog.new(tail)
+ dog.happy
+ end
+ end
+
+FlexMock will automatically verify that the mocked tail object received the
+message +wag+ exactly one time. If it doesn't, the test will not pass.
+
+Here's the same thing using the new spy support:
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ dog = Dog.new(tail)
+ dog.happy
+ tail.should have_received(:wag)
+ end
+ end
+
+This style works particularly well with the rspec-given library.
+
+ require 'rspec/given'
+
+ describe Dog do
+ context "when the dog is happy" do
+ Given(:tail) { flexmock(:on, Tail) }
+ Given(:dog) { Dog.new(tail) }
+
+ When { dog.happy }
+
+ Then { tail.should have_received(:wag) }
+ end
+ end
+
+See the FlexMock documentation at http://flexmock.rubyforge.org for details on
+specifying arguments and return values on mocked methods, as well as a simple
+technique for mocking tail objects when the Dog class creates the tail objects
+directly.
+
+== Availability
+
+You can make sure you have the latest version with a quick RubyGems command:
+
+ gem install flexmock (you may need root/admin privileges)
+
+You will find documentation at: http://flexmock.rubyforge.org.
+
+-- Jim Weirich
diff --git a/doc/releases/flexmock-1.1.0.rdoc b/doc/releases/flexmock-1.1.0.rdoc
new file mode 100644
index 0000000..7cf8da3
--- /dev/null
+++ b/doc/releases/flexmock-1.1.0.rdoc
@@ -0,0 +1,144 @@
+= FlexMock 1.1.0 Released
+
+FlexMock is a flexible mocking library for use in unit testing and
+behavior specification in Ruby. Release 1.1.0 is a minor release with
+a few bug fixes and some small features.
+
+== Changes in 1.1.0
+
+=== Features
+
+* Add block support to pass_thru.
+
+== Changes in 1.0.0
+
+=== Features
+
+* Mocks may now have a base class that limits what methods may be
+ mocked. This allows early detection of outdated mock setups when the
+ methods in the class are refactored.
+
+* Spy assertions are now allowed. The verification of the calling of
+ mocked methods may now be done in the "then" portion of the test,
+ after the code under test has been run. This allows for much more
+ natural Given/When/Then style testing.
+
+* A custom assert method (assert_spy_called) has been added to make
+ spy assertions easy when using Test::Unit or MiniTest.
+
+* An RSpec matcher (have_received) has been added to make spy
+ assertions easy when using RSpec.
+
+=== Bug Fixes
+
+* Now correctly handling the mocking of meta-programmed methods.
+
+* Using the documented +singleton_methods+ method.
+
+* Accidently trying to partial mock a regular mock is now a no-op.
+
+== What is FlexMock?
+
+FlexMock is a flexible framework for creating mock object for testing.
+When running unit tests, it is often desirable to use isolate the
+objects being tested from the "real world" by having them interact
+with simplified test objects. Sometimes these test objects simply
+return values when called, other times they verify that certain
+methods were called with particular arguments in a particular order.
+
+FlexMock makes creating these test objects easy.
+
+=== Features
+
+* Easy integration with both Test::Unit and RSpec. Mocks created with the
+ flexmock method are automatically verified at the end of the test or
+ example.
+
+* A fluent interface that allows mock behavior to be specified very
+ easily.
+
+* A "record mode" where an existing implementation can record its
+ interaction with a mock for later validation against a new
+ implementation.
+
+* Easy mocking of individual methods in existing, non-mock objects.
+
+* Easy mocking of chains of method calls.
+
+* The ability to cause classes to instantiate test instances (instead of real
+ instances) for the duration of a test.
+
+=== Example
+
+Suppose you had a Dog object that wagged a tail when it was happy.
+Something like this:
+
+ class Dog
+ def initialize(a_tail)
+ @tail = a_tail
+ end
+ def happy
+ @tail.wag
+ end
+ end
+
+To test the +Dog+ class without a real +Tail+ object (perhaps because
+real +Tail+ objects activate servos in some robotic equipment), you
+can do something like this:
+
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ tail.should_receive(:wag).once
+ dog = Dog.new(tail)
+ dog.happy
+ end
+ end
+
+FlexMock will automatically verify that the mocked tail object received the
+message +wag+ exactly one time. If it doesn't, the test will not pass.
+
+Here's the same thing using the new spy support:
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ dog = Dog.new(tail)
+ dog.happy
+ tail.should have_received(:wag)
+ end
+ end
+
+This style works particularly well with the rspec-given library.
+
+ require 'rspec/given'
+
+ describe Dog do
+ context "when the dog is happy" do
+ Given(:tail) { flexmock(:on, Tail) }
+ Given(:dog) { Dog.new(tail) }
+
+ When { dog.happy }
+
+ Then { tail.should have_received(:wag) }
+ end
+ end
+
+See the FlexMock documentation at http://flexmock.rubyforge.org for details on
+specifying arguments and return values on mocked methods, as well as a simple
+technique for mocking tail objects when the Dog class creates the tail objects
+directly.
+
+== Availability
+
+You can make sure you have the latest version with a quick RubyGems command:
+
+ gem install flexmock (you may need root/admin privileges)
+
+You will find documentation at: http://flexmock.rubyforge.org.
+
+-- Jim Weirich
diff --git a/doc/releases/flexmock-1.2.0.rdoc b/doc/releases/flexmock-1.2.0.rdoc
new file mode 100644
index 0000000..7761568
--- /dev/null
+++ b/doc/releases/flexmock-1.2.0.rdoc
@@ -0,0 +1,150 @@
+= FlexMock 1.2.0 Released
+
+FlexMock is a flexible mocking library for use in unit testing and
+behavior specification in Ruby. Release 1.2.0 is a minor release with
+a few bug fixes and some simple features.
+
+== Changes in 1.2.0
+
+=== Features
+
+* Add auto configure by requiring 'flexmock/rspec/configure'.
+
+== Changes in 1.1.0
+
+=== Features
+
+* Add block support to pass_thru.
+
+== Changes in 1.0.0
+
+=== Features
+
+* Mocks may now have a base class that limits what methods may be
+ mocked. This allows early detection of outdated mock setups when the
+ methods in the class are refactored.
+
+* Spy assertions are now allowed. The verification of the calling of
+ mocked methods may now be done in the "then" portion of the test,
+ after the code under test has been run. This allows for much more
+ natural Given/When/Then style testing.
+
+* A custom assert method (assert_spy_called) has been added to make
+ spy assertions easy when using Test::Unit or MiniTest.
+
+* An RSpec matcher (have_received) has been added to make spy
+ assertions easy when using RSpec.
+
+=== Bug Fixes
+
+* Now correctly handling the mocking of meta-programmed methods.
+
+* Using the documented +singleton_methods+ method.
+
+* Accidently trying to partial mock a regular mock is now a no-op.
+
+== What is FlexMock?
+
+FlexMock is a flexible framework for creating mock object for testing.
+When running unit tests, it is often desirable to use isolate the
+objects being tested from the "real world" by having them interact
+with simplified test objects. Sometimes these test objects simply
+return values when called, other times they verify that certain
+methods were called with particular arguments in a particular order.
+
+FlexMock makes creating these test objects easy.
+
+=== Features
+
+* Easy integration with both Test::Unit and RSpec. Mocks created with the
+ flexmock method are automatically verified at the end of the test or
+ example.
+
+* A fluent interface that allows mock behavior to be specified very
+ easily.
+
+* A "record mode" where an existing implementation can record its
+ interaction with a mock for later validation against a new
+ implementation.
+
+* Easy mocking of individual methods in existing, non-mock objects.
+
+* Easy mocking of chains of method calls.
+
+* The ability to cause classes to instantiate test instances (instead of real
+ instances) for the duration of a test.
+
+=== Example
+
+Suppose you had a Dog object that wagged a tail when it was happy.
+Something like this:
+
+ class Dog
+ def initialize(a_tail)
+ @tail = a_tail
+ end
+ def happy
+ @tail.wag
+ end
+ end
+
+To test the +Dog+ class without a real +Tail+ object (perhaps because
+real +Tail+ objects activate servos in some robotic equipment), you
+can do something like this:
+
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ tail.should_receive(:wag).once
+ dog = Dog.new(tail)
+ dog.happy
+ end
+ end
+
+FlexMock will automatically verify that the mocked tail object received the
+message +wag+ exactly one time. If it doesn't, the test will not pass.
+
+Here's the same thing using the new spy support:
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ dog = Dog.new(tail)
+ dog.happy
+ tail.should have_received(:wag)
+ end
+ end
+
+This style works particularly well with the rspec-given library.
+
+ require 'rspec/given'
+
+ describe Dog do
+ context "when the dog is happy" do
+ Given(:tail) { flexmock(:on, Tail) }
+ Given(:dog) { Dog.new(tail) }
+
+ When { dog.happy }
+
+ Then { tail.should have_received(:wag) }
+ end
+ end
+
+See the FlexMock documentation at http://flexmock.rubyforge.org for details on
+specifying arguments and return values on mocked methods, as well as a simple
+technique for mocking tail objects when the Dog class creates the tail objects
+directly.
+
+== Availability
+
+You can make sure you have the latest version with a quick RubyGems command:
+
+ gem install flexmock (you may need root/admin privileges)
+
+You will find documentation at: http://flexmock.rubyforge.org.
+
+-- Jim Weirich
diff --git a/doc/releases/flexmock-1.3.0.rdoc b/doc/releases/flexmock-1.3.0.rdoc
new file mode 100644
index 0000000..af8ff71
--- /dev/null
+++ b/doc/releases/flexmock-1.3.0.rdoc
@@ -0,0 +1,165 @@
+= FlexMock 1.3.0 Released
+
+FlexMock is a flexible mocking library for use in unit testing and
+behavior specification in Ruby. This release is a minor release with a
+few bug fixes and some simple features.
+
+== Changes in 1.3.0
+
+=== Features
+
+* Add 'and' and 'on' modifiers for the RSpec spy matcher.
+
+* Add 'and' and 'on' options to the assert_spy_called test method.
+
+* General documentation improvement.
+
+=== Bug Fixes
+
+* Fix bug in should_fail test helper that was not detecting failed
+ failures.
+
+== Changes in 1.2.0
+
+=== Features
+
+* Add auto configure by requiring 'flexmock/rspec/configure'.
+
+== Changes in 1.1.0
+
+=== Features
+
+* Add block support to pass_thru.
+
+== Changes in 1.0.0
+
+=== Features
+
+* Mocks may now have a base class that limits what methods may be
+ mocked. This allows early detection of outdated mock setups when the
+ methods in the class are refactored.
+
+* Spy assertions are now allowed. The verification of the calling of
+ mocked methods may now be done in the "then" portion of the test,
+ after the code under test has been run. This allows for much more
+ natural Given/When/Then style testing.
+
+* A custom assert method (assert_spy_called) has been added to make
+ spy assertions easy when using Test::Unit or MiniTest.
+
+* An RSpec matcher (have_received) has been added to make spy
+ assertions easy when using RSpec.
+
+=== Bug Fixes
+
+* Now correctly handling the mocking of meta-programmed methods.
+
+* Using the documented +singleton_methods+ method.
+
+* Accidently trying to partial mock a regular mock is now a no-op.
+
+== What is FlexMock?
+
+FlexMock is a flexible framework for creating mock object for testing.
+When running unit tests, it is often desirable to use isolate the
+objects being tested from the "real world" by having them interact
+with simplified test objects. Sometimes these test objects simply
+return values when called, other times they verify that certain
+methods were called with particular arguments in a particular order.
+
+FlexMock makes creating these test objects easy.
+
+=== Features
+
+* Easy integration with both Test::Unit and RSpec. Mocks created with the
+ flexmock method are automatically verified at the end of the test or
+ example.
+
+* A fluent interface that allows mock behavior to be specified very
+ easily.
+
+* A "record mode" where an existing implementation can record its
+ interaction with a mock for later validation against a new
+ implementation.
+
+* Easy mocking of individual methods in existing, non-mock objects.
+
+* Easy mocking of chains of method calls.
+
+* The ability to cause classes to instantiate test instances (instead of real
+ instances) for the duration of a test.
+
+=== Example
+
+Suppose you had a Dog object that wagged a tail when it was happy.
+Something like this:
+
+ class Dog
+ def initialize(a_tail)
+ @tail = a_tail
+ end
+ def happy
+ @tail.wag
+ end
+ end
+
+To test the +Dog+ class without a real +Tail+ object (perhaps because
+real +Tail+ objects activate servos in some robotic equipment), you
+can do something like this:
+
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ tail.should_receive(:wag).once
+ dog = Dog.new(tail)
+ dog.happy
+ end
+ end
+
+FlexMock will automatically verify that the mocked tail object received the
+message +wag+ exactly one time. If it doesn't, the test will not pass.
+
+Here's the same thing using the new spy support:
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ dog = Dog.new(tail)
+ dog.happy
+ tail.should have_received(:wag)
+ end
+ end
+
+This style works particularly well with the rspec-given library.
+
+ require 'rspec/given'
+
+ describe Dog do
+ context "when the dog is happy" do
+ Given(:tail) { flexmock(:on, Tail) }
+ Given(:dog) { Dog.new(tail) }
+
+ When { dog.happy }
+
+ Then { tail.should have_received(:wag) }
+ end
+ end
+
+See the FlexMock documentation at http://flexmock.rubyforge.org for details on
+specifying arguments and return values on mocked methods, as well as a simple
+technique for mocking tail objects when the Dog class creates the tail objects
+directly.
+
+== Availability
+
+You can make sure you have the latest version with a quick RubyGems command:
+
+ gem install flexmock (you may need root/admin privileges)
+
+You will find documentation at: http://flexmock.rubyforge.org.
+
+-- Jim Weirich
diff --git a/doc/releases/flexmock-1.3.1.rdoc b/doc/releases/flexmock-1.3.1.rdoc
new file mode 100644
index 0000000..27ac5fd
--- /dev/null
+++ b/doc/releases/flexmock-1.3.1.rdoc
@@ -0,0 +1,171 @@
+= FlexMock 1.3.1 Released
+
+FlexMock is a flexible mocking library for use in unit testing and
+behavior specification in Ruby. This release is a minor release with a
+few bug fixes and some simple features.
+
+== Changes in 1.3.1
+
+* Removed use of assert_block (which is deprecated in MiniTest).
+
+* Documentation fixes.
+
+== Changes in 1.3.0
+
+=== Features
+
+* Add 'and' and 'on' modifiers for the RSpec spy matcher.
+
+* Add 'and' and 'on' options to the assert_spy_called test method.
+
+* General documentation improvement.
+
+=== Bug Fixes
+
+* Fix bug in should_fail test helper that was not detecting failed
+ failures.
+
+== Changes in 1.2.0
+
+=== Features
+
+* Add auto configure by requiring 'flexmock/rspec/configure'.
+
+== Changes in 1.1.0
+
+=== Features
+
+* Add block support to pass_thru.
+
+== Changes in 1.0.0
+
+=== Features
+
+* Mocks may now have a base class that limits what methods may be
+ mocked. This allows early detection of outdated mock setups when the
+ methods in the class are refactored.
+
+* Spy assertions are now allowed. The verification of the calling of
+ mocked methods may now be done in the "then" portion of the test,
+ after the code under test has been run. This allows for much more
+ natural Given/When/Then style testing.
+
+* A custom assert method (assert_spy_called) has been added to make
+ spy assertions easy when using Test::Unit or MiniTest.
+
+* An RSpec matcher (have_received) has been added to make spy
+ assertions easy when using RSpec.
+
+=== Bug Fixes
+
+* Now correctly handling the mocking of meta-programmed methods.
+
+* Using the documented +singleton_methods+ method.
+
+* Accidently trying to partial mock a regular mock is now a no-op.
+
+== What is FlexMock?
+
+FlexMock is a flexible framework for creating mock object for testing.
+When running unit tests, it is often desirable to use isolate the
+objects being tested from the "real world" by having them interact
+with simplified test objects. Sometimes these test objects simply
+return values when called, other times they verify that certain
+methods were called with particular arguments in a particular order.
+
+FlexMock makes creating these test objects easy.
+
+=== Features
+
+* Easy integration with both Test::Unit and RSpec. Mocks created with the
+ flexmock method are automatically verified at the end of the test or
+ example.
+
+* A fluent interface that allows mock behavior to be specified very
+ easily.
+
+* A "record mode" where an existing implementation can record its
+ interaction with a mock for later validation against a new
+ implementation.
+
+* Easy mocking of individual methods in existing, non-mock objects.
+
+* Easy mocking of chains of method calls.
+
+* The ability to cause classes to instantiate test instances (instead of real
+ instances) for the duration of a test.
+
+=== Example
+
+Suppose you had a Dog object that wagged a tail when it was happy.
+Something like this:
+
+ class Dog
+ def initialize(a_tail)
+ @tail = a_tail
+ end
+ def happy
+ @tail.wag
+ end
+ end
+
+To test the +Dog+ class without a real +Tail+ object (perhaps because
+real +Tail+ objects activate servos in some robotic equipment), you
+can do something like this:
+
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ tail.should_receive(:wag).once
+ dog = Dog.new(tail)
+ dog.happy
+ end
+ end
+
+FlexMock will automatically verify that the mocked tail object received the
+message +wag+ exactly one time. If it doesn't, the test will not pass.
+
+Here's the same thing using the new spy support:
+
+ describe Dog do
+ it "wags its tail when happy" do
+ tail = flexmock("tail")
+ dog = Dog.new(tail)
+ dog.happy
+ tail.should have_received(:wag)
+ end
+ end
+
+This style works particularly well with the rspec-given library.
+
+ require 'rspec/given'
+
+ describe Dog do
+ context "when the dog is happy" do
+ Given(:tail) { flexmock(:on, Tail) }
+ Given(:dog) { Dog.new(tail) }
+
+ When { dog.happy }
+
+ Then { tail.should have_received(:wag) }
+ end
+ end
+
+See the FlexMock documentation at http://flexmock.rubyforge.org for details on
+specifying arguments and return values on mocked methods, as well as a simple
+technique for mocking tail objects when the Dog class creates the tail objects
+directly.
+
+== Availability
+
+You can make sure you have the latest version with a quick RubyGems command:
+
+ gem install flexmock (you may need root/admin privileges)
+
+You will find documentation at: http://flexmock.rubyforge.org.
+
+-- Jim Weirich
diff --git a/lib/flexmock.rb b/lib/flexmock.rb
index 5a2562b..ffb8af3 100644
--- a/lib/flexmock.rb
+++ b/lib/flexmock.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/lib/flexmock/argument_matchers.rb b/lib/flexmock/argument_matchers.rb
index 39af398..76e9b08 100755
--- a/lib/flexmock/argument_matchers.rb
+++ b/lib/flexmock/argument_matchers.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
#
# Permission is granted for use, copying, modification, distribution,
@@ -54,7 +54,7 @@ class FlexMock
end
####################################################################
- # Match only things where the block evaluates to true.
+ # Match hashes that match all the fields of +hash+.
class HashMatcher
def initialize(hash)
@hash = hash
@@ -68,7 +68,7 @@ class FlexMock
end
####################################################################
- # Match only things where the block evaluates to true.
+ # Match objects that implement all the methods in +methods+.
class DuckMatcher
def initialize(methods)
@methods = methods
@@ -81,5 +81,18 @@ class FlexMock
end
end
+ ####################################################################
+ # Match objects that implement all the methods in +methods+.
+ class OptionalProcMatcher
+ def initialize
+ end
+ def ===(target)
+ ArgumentMatching.missing?(target) || Proc === target
+ end
+ def inspect
+ "optional_proc"
+ end
+ end
+ OPTIONAL_PROC_MATCHER = OptionalProcMatcher.new
end
diff --git a/lib/flexmock/argument_matching.rb b/lib/flexmock/argument_matching.rb
new file mode 100644
index 0000000..7f61d2e
--- /dev/null
+++ b/lib/flexmock/argument_matching.rb
@@ -0,0 +1,33 @@
+class FlexMock
+ module ArgumentMatching
+ module_function
+
+ MISSING_ARG = Object.new
+
+ def all_match?(expected_args, actual_args)
+ return true if expected_args.nil?
+ return false if actual_args.size > expected_args.size
+ i = 0
+ while i < actual_args.size
+ return false unless match?(expected_args[i], actual_args[i])
+ i += 1
+ end
+ while i < expected_args.size
+ return false unless match?(expected_args[i], MISSING_ARG)
+ i += 1
+ end
+ true
+ end
+
+ # Does the expected argument match the corresponding actual value.
+ def match?(expected, actual)
+ expected === actual ||
+ expected == actual ||
+ ( Regexp === expected && expected === actual.to_s )
+ end
+
+ def missing?(arg)
+ arg == MISSING_ARG
+ end
+ end
+end
diff --git a/lib/flexmock/argument_types.rb b/lib/flexmock/argument_types.rb
index 8c1e640..17c4951 100755
--- a/lib/flexmock/argument_types.rb
+++ b/lib/flexmock/argument_types.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -48,6 +48,10 @@ class FlexMock
def ducktype(*methods)
DuckMatcher.new(methods)
end
+
+ def optional_proc
+ OPTIONAL_PROC_MATCHER
+ end
end
extend ArgumentTypes
diff --git a/lib/flexmock/base.rb b/lib/flexmock/base.rb
index 3744f8f..dff285b 100755
--- a/lib/flexmock/base.rb
+++ b/lib/flexmock/base.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -9,6 +9,10 @@
# above copyright notice is included.
#+++
+require 'flexmock/symbol_extensions'
+require 'flexmock/object_extensions'
+require 'flexmock/class_extensions'
+
require 'flexmock/core'
require 'flexmock/default_framework_adapter'
diff --git a/lib/flexmock/class_extensions.rb b/lib/flexmock/class_extensions.rb
new file mode 100644
index 0000000..1c183ea
--- /dev/null
+++ b/lib/flexmock/class_extensions.rb
@@ -0,0 +1,17 @@
+# Detecting whether a class has a definition for a method or not
+# changes between Ruby 1.8 and Ruby 1.9. We introduce the
+# "flexmock_defined?" method on class objects to have a portable way
+# to determine that.
+#
+# NOTE: responds_to? isn't appropriate. We don't care if the object
+# responds to the method or not. We want to know if the class
+# has a definition for the method. A subtle difference.
+#
+class Class
+
+ # Does a class directly define a method named "method_name"?
+ def flexmock_defined?(method_name)
+ instance_methods.include?(method_name.flexmock_as_name)
+ end
+
+end
diff --git a/lib/flexmock/composite.rb b/lib/flexmock/composite.rb
index 1ebcbf9..8e8e56e 100755
--- a/lib/flexmock/composite.rb
+++ b/lib/flexmock/composite.rb
@@ -1,10 +1,10 @@
#!/usr/bin/env ruby
#
-# Created by Jim Weirich on 2007-04-14.
-# Copyright (c) 2007. All rights reserved.
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
+# All rights reserved.
require 'flexmock/noop'
class FlexMock
-end
\ No newline at end of file
+end
diff --git a/lib/flexmock/core.rb b/lib/flexmock/core.rb
index 9599fb9..75eccda 100755
--- a/lib/flexmock/core.rb
+++ b/lib/flexmock/core.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
#
# Permission is granted for use, copying, modification, distribution,
@@ -12,6 +12,9 @@
require 'flexmock/errors'
require 'flexmock/composite'
require 'flexmock/ordering'
+require 'flexmock/argument_matching'
+require 'flexmock/explicit_needed'
+require 'flexmock/class_extensions'
######################################################################
# FlexMock is a flexible mock object framework for supporting testing.
@@ -49,6 +52,11 @@ class FlexMock
attr_reader :flexmock_name
attr_accessor :flexmock_container
+ class << self
+ attr_accessor :partials_are_based
+ end
+ self.partials_are_based = false
+
# Create a FlexMock object with the given name. The name is used in
# error messages. If no container is given, create a new, one-off
# container for this mock.
@@ -57,6 +65,8 @@ class FlexMock
@expectations = Hash.new
@ignore_missing = false
@verified = false
+ @calls = []
+ @base_class = nil
container = UseContainer.new if container.nil?
container.flexmock_remember(self)
end
@@ -85,6 +95,7 @@ class FlexMock
# Ignore all undefined (missing) method calls.
def should_ignore_missing
@ignore_missing = true
+ self
end
alias mock_ignore_missing should_ignore_missing
@@ -93,12 +104,32 @@ class FlexMock
self
end
+ CallRecord = Struct.new(:method_name, :args, :block_given, :expectation) do
+ def matches?(sym, actual_args, options)
+ method_name == sym &&
+ ArgumentMatching.all_match?(actual_args, args) &&
+ matches_block?(options[:with_block])
+ end
+
+ private
+
+ def matches_block?(block_option)
+ block_option.nil? ||
+ (block_option && block_given) ||
+ (!block_option && !block_given)
+ end
+ end
+
# Handle missing methods by attempting to look up a handler.
def method_missing(sym, *args, &block)
+ enhanced_args = block_given? ? args + [block] : args
+ call_record = CallRecord.new(sym, enhanced_args, block_given?)
+ @calls << call_record
flexmock_wrap do
if handler = @expectations[sym]
- args << block if block_given?
- handler.call(*args)
+ handler.call(enhanced_args, call_record)
+ elsif @base_class && @base_class.flexmock_defined?(sym)
+ FlexMock.undefined
elsif @ignore_missing
FlexMock.undefined
else
@@ -126,6 +157,44 @@ class FlexMock
@expectations[method_name]
end
+ def flexmock_based_on(base_class)
+ @base_class = base_class
+ should_receive(:class => base_class)
+ end
+
+ # True if the mock received the given method and arguments.
+ def flexmock_received?(sym, args, options={})
+ count = 0
+ additional = options[:and] || []
+ additional = [additional] if additional.is_a?(Proc)
+ @calls.each { |call_record|
+ if call_record.matches?(sym, args, options)
+ count += 1
+ if options[:on_count].nil? || count == options[:on_count]
+ additional.each do |add| add.call(*call_record.args) end
+ end
+ end
+ }
+ if options[:times]
+ result = count == options[:times]
+ else
+ result = count > 0
+ end
+ result
+ end
+
+ # Return the list of calls made on this mock. Used in formatting
+ # error messages.
+ def flexmock_calls
+ @calls
+ end
+
+ # Invocke the original non-mocked functionality for the given
+ # symbol.
+ def flexmock_invoke_original(sym, args)
+ return FlexMock.undefined
+ end
+
# Override the built-in +method+ to include the mocked methods.
def method(sym)
@expectations[sym] || super
@@ -157,14 +226,20 @@ class FlexMock
# See Expectation for a list of declarators that can be used.
#
def should_receive(*args)
+ location = caller.first
+ flexmock_define_expectation(location, *args)
+ end
+
+ def flexmock_define_expectation(location, *args)
@last_expectation = ContainerHelper.parse_should_args(self, args) do |sym|
@expectations[sym] ||= ExpectationDirector.new(sym)
- result = Expectation.new(self, sym)
+ result = Expectation.new(self, sym, location)
@expectations[sym] << result
override_existing_method(sym) if flexmock_respond_to?(sym)
+ result = ExplicitNeeded.new(result, sym, @base_class) if
+ @base_class && ! @base_class.flexmock_defined?(sym)
result
end
- @last_expectation
end
# Declare that the mock object should expect methods by providing a
diff --git a/lib/flexmock/core_class_methods.rb b/lib/flexmock/core_class_methods.rb
index 046f032..28ca41f 100755
--- a/lib/flexmock/core_class_methods.rb
+++ b/lib/flexmock/core_class_methods.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -50,18 +50,24 @@ class FlexMock
# Class method to format a method name and argument list as a nice
# looking string.
- def format_args(sym, args) # :nodoc:
+ def format_call(sym, args) # :nodoc:
+ "#{sym}(#{format_args(args)})"
+ end
+
+ # Class method to format a list of args (the part between the
+ # parenthesis).
+ def format_args(args)
if args
- "#{sym}(#{args.collect { |a| a.inspect }.join(', ')})"
+ args.collect { |a| a.inspect }.join(', ')
else
- "#{sym}(*args)"
+ "*args"
end
end
# Check will assert the block returns true. If it doesn't, an
# assertion failure is triggered with the given message.
def check(msg, &block) # :nodoc:
- FlexMock.framework_adapter.assert_block(msg, &block)
+ FlexMock.framework_adapter.make_assertion(msg, &block)
end
end
diff --git a/lib/flexmock/default_framework_adapter.rb b/lib/flexmock/default_framework_adapter.rb
index d9994a3..8738f92 100755
--- a/lib/flexmock/default_framework_adapter.rb
+++ b/lib/flexmock/default_framework_adapter.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -13,14 +13,15 @@ require 'flexmock/noop'
class FlexMock
class DefaultFrameworkAdapter
- def assert_block(msg, &block)
+ def make_assertion(msg, &block)
unless yield
+ msg = msg.call if msg.is_a?(Proc)
fail assertion_failed_error, msg
end
end
def assert_equal(a, b, msg=nil)
- assert_block(msg || "Expected equal") { a == b }
+ make_assertion(msg || "Expected equal") { a == b }
end
class AssertionFailedError < StandardError; end
diff --git a/lib/flexmock/deprecated_methods.rb b/lib/flexmock/deprecated_methods.rb
index a4b58ca..b9bc96a 100644
--- a/lib/flexmock/deprecated_methods.rb
+++ b/lib/flexmock/deprecated_methods.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
#
# Permission is granted for use, copying, modification, distribution,
diff --git a/lib/flexmock/errors.rb b/lib/flexmock/errors.rb
index 979c5dd..7d538b8 100644
--- a/lib/flexmock/errors.rb
+++ b/lib/flexmock/errors.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
#
# Permission is granted for use, copying, modification, distribution,
diff --git a/lib/flexmock/expectation.rb b/lib/flexmock/expectation.rb
index b39c7a9..96bcceb 100755
--- a/lib/flexmock/expectation.rb
+++ b/lib/flexmock/expectation.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -10,6 +10,7 @@
#+++
require 'flexmock/noop'
+require 'flexmock/argument_matching'
class FlexMock
@@ -31,9 +32,10 @@ class FlexMock
attr_accessor :mock
# Create an expectation for a method named +sym+.
- def initialize(mock, sym)
+ def initialize(mock, sym, location)
@mock = mock
@sym = sym
+ @location = location
@expected_args = nil
@count_validators = []
@count_validator_class = ExactCountValidator
@@ -47,7 +49,23 @@ class FlexMock
end
def to_s
- FlexMock.format_args(@sym, @expected_args)
+ FlexMock.format_call(@sym, @expected_args)
+ end
+
+ # Return a description of the matching features of the
+ # expectation. Matching features include:
+ #
+ # * name of the method
+ # * argument matchers
+ # * call count validators
+ #
+ def description
+ result = "should_receive(#{@sym.inspect})"
+ result << ".with(#{FlexMock.format_args(@expected_args)})" if @expected_args
+ @count_validators.each do |validator|
+ result << validator.describe
+ end
+ result
end
# Verify the current call with the given arguments matches the
@@ -127,18 +145,7 @@ class FlexMock
# Does the argument list match this expectation's argument
# specification.
def match_args(args)
- # TODO: Rethink this:
- # return false if @expected_args.nil?
- return true if @expected_args.nil?
- return false if args.size != @expected_args.size
- (0...args.size).all? { |i| match_arg(@expected_args[i], args[i]) }
- end
-
- # Does the expected argument match the corresponding actual value.
- def match_arg(expected, actual)
- expected === actual ||
- expected == actual ||
- ( Regexp === expected && expected === actual.to_s )
+ ArgumentMatching.all_match?(@expected_args, args)
end
# Declare that the method should expect the given argument list.
@@ -268,6 +275,13 @@ class FlexMock
end
alias :throws :and_throw
+ def pass_thru(&block)
+ block ||= lambda { |value| value }
+ and_return { |*args|
+ block.call(@mock.flexmock_invoke_original(@sym, args))
+ }
+ end
+
# Declare that the method may be called any number of times.
def zero_or_more_times
at_least.never
@@ -385,11 +399,24 @@ class FlexMock
end
private :define_ordered
+ # No-op for allowing explicit calls when explicit not explicitly
+ # needed.
+ def explicitly
+ self
+ end
+
def by_default
expectations = mock.flexmock_expectations_for(@sym)
expectations.defaultify_expectation(self) if expectations
end
+ def flexmock_location_filter
+ yield
+ rescue Exception => ex
+ ex.backtrace.insert(0, @location)
+ raise ex
+ end
+
end
##########################################################################
@@ -432,7 +459,7 @@ class FlexMock
# Start a new method expectation. The following constraints will be
# applied to the new expectation.
def should_receive(*args, &block)
- @expectations.first.mock.should_receive(*args, &block)
+ @expectations.first.mock.flexmock_define_expectation(caller.first, *args, &block)
end
# Return a string representations
diff --git a/lib/flexmock/expectation_director.rb b/lib/flexmock/expectation_director.rb
index 2de46f5..7bec3c8 100755
--- a/lib/flexmock/expectation_director.rb
+++ b/lib/flexmock/expectation_director.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -35,10 +35,11 @@ class FlexMock
# but at least we will get a good failure message). Finally,
# check for expectations that don't have any argument matching
# criteria.
- def call(*args)
+ def call(args, call_record=nil)
exp = find_expectation(*args)
- FlexMock.check("no matching handler found for " +
- FlexMock.format_args(@sym, args)) { ! exp.nil? }
+ call_record.expectation = exp if call_record
+ FlexMock.check(
+ "no matching handler found for " + FlexMock.format_call(@sym, args)) { ! exp.nil? }
exp.verify_call(*args)
end
diff --git a/lib/flexmock/explicit_needed.rb b/lib/flexmock/explicit_needed.rb
new file mode 100644
index 0000000..8e5d073
--- /dev/null
+++ b/lib/flexmock/explicit_needed.rb
@@ -0,0 +1,43 @@
+
+class FlexMock
+
+ # Expectations on mocks with a base class can only be defined on
+ # methods supported by the base class. Attempting to add an stub to
+ # a method not defined on the base class will cause the expectation
+ # to be wrapped in an ExplicitNeeded wrapper. The wrapper will throw
+ # an exception unless the explicitly method is immediately called on
+ # the expectation.
+ #
+ class ExplicitNeeded
+ def initialize(expectation, method_name, base_class)
+ @expectation = expectation
+ @explicit = false
+ @method_name = method_name
+ @base_class = base_class
+ end
+
+ def explicitly
+ @explicit = true
+ self
+ end
+
+ def explicit?
+ @explicit
+ end
+
+ def mock=(m)
+ @expectation.mock = m
+ end
+
+ def method_missing(sym, *args, &block)
+ if explicit?
+ @expectation.send(sym, *args, &block)
+ else
+ fail NoMethodError, "Cannot stub methods not defined by the base class\n" +
+ " Method: #{@method_name}\n" +
+ " Base Class: #{@base_class}\n" +
+ " (Use 'explicitly' to override)"
+ end
+ end
+ end
+end
diff --git a/lib/flexmock/mock_container.rb b/lib/flexmock/mock_container.rb
index fedf202..6cf5b7a 100755
--- a/lib/flexmock/mock_container.rb
+++ b/lib/flexmock/mock_container.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -117,11 +117,14 @@ class FlexMock
# the mock object.
#
def flexmock(*args)
+ location = caller.first
name = nil
quick_defs = {}
domain_obj = nil
safe_mode = false
model_class = nil
+ base_class = nil
+ mock = nil
while ! args.empty?
case args.first
when :base, :safe
@@ -130,10 +133,16 @@ class FlexMock
when :model
args.shift
model_class = args.shift
+ when :on
+ args.shift
+ base_class = args.shift
+ name ||= "#{base_class} Mock"
when String, Symbol
name = args.shift.to_s
when Hash
quick_defs = args.shift
+ when FlexMock
+ mock = args.shift
else
domain_obj = args.shift
end
@@ -145,14 +154,21 @@ class FlexMock
result = domain_obj
elsif model_class
id = ContainerHelper.next_id
- result = mock = FlexMock.new("#{model_class}_#{id}", self)
+ mock ||= FlexMock.new("#{model_class}_#{id}", self)
+ result = mock
else
- result = mock = FlexMock.new(name || "unknown", self)
+ mock ||= FlexMock.new(name || "unknown", self)
+ result = mock
+ end
+ if base_class
+ mock.flexmock_based_on(base_class)
+ elsif domain_obj && FlexMock.partials_are_based
+ mock.flexmock_based_on(domain_obj.class)
end
- mock.should_receive(quick_defs)
+ mock.flexmock_define_expectation(location, quick_defs)
yield(mock) if block_given?
flexmock_remember(mock)
- ContainerHelper.add_model_methods(mock, model_class, id) if model_class
+ ContainerHelper.add_model_methods(mock, model_class, id, location) if model_class
result
end
alias flexstub flexmock
@@ -219,29 +235,29 @@ class FlexMock
# Automatically add mocks for some common methods in ActiveRecord
# models.
- def add_model_methods(mock, model_class, id)
+ def add_model_methods(mock, model_class, id, location)
container = mock.flexmock_container
mock_errors = container.flexmock("errors")
- mock_errors.should_receive(:count).and_return(0).by_default
- mock_errors.should_receive(:full_messages).and_return([]).by_default
+ mock_errors.flexmock_define_expectation(location, :count).and_return(0).by_default
+ mock_errors.flexmock_define_expectation(location, :full_messages).and_return([]).by_default
- mock.should_receive(:id).and_return(id).by_default
- mock.should_receive(:to_params).and_return(id.to_s).by_default
- mock.should_receive(:new_record?).and_return(false).by_default
- mock.should_receive(:class).and_return(model_class).by_default
- mock.should_receive(:errors).and_return(mock_errors).by_default
+ mock.flexmock_define_expectation(location, :id).and_return(id).by_default
+ mock.flexmock_define_expectation(location, :to_params).and_return(id.to_s).by_default
+ mock.flexmock_define_expectation(location, :new_record?).and_return(false).by_default
+ mock.flexmock_define_expectation(location, :class).and_return(model_class).by_default
+ mock.flexmock_define_expectation(location, :errors).and_return(mock_errors).by_default
# HACK: Ruby 1.9 needs the following lambda so that model_class
# is correctly bound below.
lambda { }
- mock.should_receive(:is_a?).with(any).and_return { |other|
+ mock.flexmock_define_expectation(location, :is_a?).with(any).and_return { |other|
other == model_class
}.by_default
- mock.should_receive(:instance_of?).with(any).and_return { |other|
+ mock.flexmock_define_expectation(location, :instance_of?).with(any).and_return { |other|
other == model_class
}.by_default
- mock.should_receive(:kind_of?).with(any).and_return { |other|
+ mock.flexmock_define_expectation(location, :kind_of?).with(any).and_return { |other|
model_class.ancestors.include?(other)
}.by_default
end
@@ -326,7 +342,7 @@ class FlexMock
end
end
- METHOD_NAME_RE = /^([A-Za-z_][A-Za-z0-9_]*[=!?]?|\[\]=?||\*\*|<<|>>|<=>|[<>=]=|=~|===|[-+]@|[-+\*\/%&^|<>~`])$/
+ METHOD_NAME_RE = /^([A-Za-z_][A-Za-z0-9_]*[=!?]?|\[\]=?||\*\*|<<|>>|<=>|[<>=!]=|[=!]~|===|[-+]@|[-+\*\/%&^|<>~`!])$/
# Check that all the names in the list are valid method names.
def check_method_names(names)
diff --git a/lib/flexmock/noop.rb b/lib/flexmock/noop.rb
index 4353627..5eb3857 100755
--- a/lib/flexmock/noop.rb
+++ b/lib/flexmock/noop.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/lib/flexmock/object_extensions.rb b/lib/flexmock/object_extensions.rb
new file mode 100644
index 0000000..d291e41
--- /dev/null
+++ b/lib/flexmock/object_extensions.rb
@@ -0,0 +1,5 @@
+class Object
+ def flexmock_singleton_defined?(method_name)
+ singleton_methods(false).include?(method_name.flexmock_as_name)
+ end
+end
diff --git a/lib/flexmock/ordering.rb b/lib/flexmock/ordering.rb
index f81da10..7bd0664 100644
--- a/lib/flexmock/ordering.rb
+++ b/lib/flexmock/ordering.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/lib/flexmock/partial_mock.rb b/lib/flexmock/partial_mock.rb
index 4e367f4..bb49f5a 100755
--- a/lib/flexmock/partial_mock.rb
+++ b/lib/flexmock/partial_mock.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -33,7 +33,9 @@ class FlexMock
MOCK_METHODS = [
:should_receive, :new_instances,
- :flexmock_get, :flexmock_teardown, :flexmock_verify
+ :should_receive_with_location,
+ :flexmock_get, :flexmock_teardown, :flexmock_verify,
+ :flexmock_received?, :flexmock_calls,
]
# Initialize a PartialMockProxy object.
@@ -78,11 +80,16 @@ class FlexMock
#
# See Expectation for a list of declarators that can be used.
def should_receive(*args)
+ location = caller.first
+ flexmock_define_expectation(location, *args)
+ end
+
+ def flexmock_define_expectation(location, *args)
ContainerHelper.parse_should_args(@mock, args) do |sym|
unless @methods_proxied.include?(sym)
hide_existing_method(sym)
end
- ex = @mock.should_receive(sym)
+ ex = @mock.flexmock_define_expectation(location, sym)
ex.mock = self
ex
end
@@ -122,14 +129,17 @@ class FlexMock
#
def new_instances(*allocators, &block)
fail ArgumentError, "new_instances requires a Class to stub" unless Class === @obj
+ location = caller.first
allocators = [:new] if allocators.empty?
result = ExpectationRecorder.new
allocators.each do |allocate_method|
check_allocate_method(allocate_method)
- # HACK: Without the following lambda, Ruby 1.9 will not bind
- # the allocate_method parameter correctly.
+ # HACK: Without the following lambda, Some versions of Ruby 1.9
+ # would not bind the allocate_method parameter
+ # correctly. I don't think it is necessary for recent
+ # versions.
lambda { }
- self.should_receive(allocate_method).and_return { |*args|
+ self.flexmock_define_expectation(location, allocate_method).and_return { |*args|
new_obj = invoke_original(allocate_method, args)
mock = flexmock_container.flexmock(new_obj)
block.call(mock) if block_given?
@@ -148,6 +158,10 @@ class FlexMock
end
private :invoke_original
+ def flexmock_invoke_original(method, args)
+ invoke_original(method, args)
+ end
+
# Verify that the mock has been properly called. After verification,
# detach the mocking infrastructure from the existing object.
def flexmock_verify
@@ -171,6 +185,16 @@ class FlexMock
@mock.flexmock_container
end
+ # Forward to the mock
+ def flexmock_received?(*args)
+ @mock.flexmock_received?(*args)
+ end
+
+ # Forward to the mock
+ def flexmock_calls
+ @mock.flexmock_calls
+ end
+
# Set the proxy's mock container. This set value is ignored
# because the proxy always uses the container of its mock.
def flexmock_container=(container)
@@ -181,6 +205,11 @@ class FlexMock
@mock.flexmock_expectations_for(method_name)
end
+ # Forward the based on request.
+ def flexmock_based_on(*args)
+ @mock.flexmock_based_on(*args)
+ end
+
private
def check_allocate_method(allocate_method)
@@ -194,10 +223,8 @@ class FlexMock
class << @obj; self; end
end
- # Is the given method name a singleton method in the object we are
- # mocking?
def singleton?(method_name)
- @obj.methods(false).include?(method_name.to_s)
+ @obj.flexmock_singleton_defined?(method_name)
end
# Hide the existing method definition with a singleton defintion
@@ -234,17 +261,24 @@ class FlexMock
# alias name. If the aliasing process fails (because the method
# doesn't really exist, then return nil.
def create_alias_for_existing_method(method_name)
- begin
- new_alias = new_name(method_name)
- unless @obj.respond_to?(new_alias)
- sclass.class_eval do
- alias_method(new_alias, method_name)
- end
+ new_alias = new_name(method_name)
+ unless @obj.respond_to?(new_alias)
+ safe_alias_method(new_alias, method_name)
+ end
+ new_alias
+ end
+
+ # Create an alias for the existing method named +method_name+. It
+ # is possible that +method_name+ is implemented via a
+ # meta-programming, so we provide for the case that the
+ # method_name does not exist.
+ def safe_alias_method(new_alias, method_name)
+ sclass.class_eval do
+ begin
+ alias_method(new_alias, method_name)
+ rescue NameError
+ nil
end
- new_alias
- rescue NameError => _
- # Alias attempt failed
- nil
end
end
@@ -273,12 +307,17 @@ class FlexMock
# Restore the original singleton defintion for method_name that
# was saved earlier.
def restore_original_definition(method_name)
- method_def = @method_definitions[method_name]
- if method_def
- the_alias = new_name(method_name)
- sclass.class_eval do
- alias_method(method_name, the_alias)
+ begin
+ method_def = @method_definitions[method_name]
+ if method_def
+ the_alias = new_name(method_name)
+ sclass.class_eval do
+ alias_method(method_name, the_alias)
+ end
end
+ rescue NameError => _
+ # Alias attempt failed
+ nil
end
end
diff --git a/lib/flexmock/rails.rb b/lib/flexmock/rails.rb
index e0d0971..257d893 100644
--- a/lib/flexmock/rails.rb
+++ b/lib/flexmock/rails.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
#
# Permission is granted for use, copying, modification, distribution,
diff --git a/lib/flexmock/recorder.rb b/lib/flexmock/recorder.rb
index 3ee7dd3..578fab4 100755
--- a/lib/flexmock/recorder.rb
+++ b/lib/flexmock/recorder.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -57,7 +57,8 @@ class FlexMock
# Record an expectation for receiving the method +sym+ with the
# given arguments.
def method_missing(sym, *args, &block)
- expectation = @mock.should_receive(sym).and_return(&block)
+ location = caller.first
+ expectation = @mock.flexmock_define_expectation(location, sym).and_return(&block)
if strict?
args = args.collect { |arg| eq(arg) }
expectation.with(*args).ordered.once
diff --git a/lib/flexmock/rspec.rb b/lib/flexmock/rspec.rb
index c1ddf65..3379776 100755
--- a/lib/flexmock/rspec.rb
+++ b/lib/flexmock/rspec.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim.weirich at gmail.com).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -9,6 +9,8 @@
# above copyright notice is included.
#+++
+
+
require 'flexmock/base'
class FlexMock
@@ -19,13 +21,14 @@ class FlexMock
end
class RSpecFrameworkAdapter
- def assert_block(msg, &block)
+ def make_assertion(msg, &block)
+ msg = msg.call if msg.is_a?(Proc)
SpecModule::Expectations.fail_with(msg) unless yield
end
def assert_equal(a, b, msg=nil)
message = msg || "Expected equal"
- assert_block(message + "\n<#{a}> expected, but was\n<#{b}>") { a == b }
+ make_assertion(message + "\n<#{a}> expected, but was\n<#{b}>") { a == b }
end
class AssertionFailedError < StandardError; end
@@ -36,3 +39,5 @@ class FlexMock
@framework_adapter = RSpecFrameworkAdapter.new
end
+
+require 'flexmock/rspec_spy_matcher'
diff --git a/lib/flexmock/rspec/configure.rb b/lib/flexmock/rspec/configure.rb
new file mode 100644
index 0000000..edbde64
--- /dev/null
+++ b/lib/flexmock/rspec/configure.rb
@@ -0,0 +1,12 @@
+# Auto configure for RSpec
+#
+# Just require 'flexmock/rspec/configure' to automatically configure
+# RSpec to use flexmock.
+
+if defined?(RSpec)
+ RSpec.configure do |config|
+ config.mock_with :flexmock
+ end
+else
+ fail "Cannot auto-configure flexmock for ancient versions of rspec"
+end
diff --git a/lib/flexmock/rspec_spy_matcher.rb b/lib/flexmock/rspec_spy_matcher.rb
new file mode 100644
index 0000000..337d4cd
--- /dev/null
+++ b/lib/flexmock/rspec_spy_matcher.rb
@@ -0,0 +1,92 @@
+require 'flexmock/spy_describers'
+
+class FlexMock
+ module RSpecMatchers
+
+ class HaveReceived
+ include SpyDescribers
+
+ def initialize(method_name)
+ @method_name = method_name
+ @args = nil
+ @block = nil
+ @times = nil
+ @needs_block = nil
+ @additional_validations = []
+ end
+
+ def matches?(spy)
+ @spy = spy
+ @options = construct_options
+ @spy.flexmock_received?(@method_name, @args, @options)
+ end
+
+ def failure_message_for_should
+ describe_spy_expectation(@spy, @method_name, @args, @options)
+ end
+
+ def failure_message_for_should_not
+ describe_spy_negative_expectation(@spy, @method_name, @args, @options)
+ end
+
+ def with(*args)
+ @args = args
+ self
+ end
+
+ def with_a_block
+ @needs_block = true
+ self
+ end
+
+ def without_a_block
+ @needs_block = false
+ self
+ end
+
+ def times(n)
+ @times = n
+ self
+ end
+
+ def never
+ times(0)
+ end
+
+ def once
+ times(1)
+ end
+
+ def twice
+ times(2)
+ end
+
+ def on(on_count)
+ @on_count = on_count
+ self
+ end
+
+ def and(&block)
+ @additional_validations << block
+ self
+ end
+
+ def construct_options
+ {
+ :times => @times,
+ :with_block => @needs_block,
+ :on_count => @on_count,
+ :and => @additional_validations,
+ }
+ end
+ end
+
+ def have_received(method_name)
+ HaveReceived.new(method_name)
+ end
+ end
+end
+
+RSpec::configure do |config|
+ config.include(FlexMock::RSpecMatchers)
+end
diff --git a/lib/flexmock/spy_describers.rb b/lib/flexmock/spy_describers.rb
new file mode 100644
index 0000000..937afe5
--- /dev/null
+++ b/lib/flexmock/spy_describers.rb
@@ -0,0 +1,76 @@
+class FlexMock
+
+ module SpyDescribers
+ def describe_spy_expectation(spy, sym, args, options={})
+ describe_spy(spy, sym, args, options)
+ end
+
+ def describe_spy_negative_expectation(spy, sym, args, options={})
+ describe_spy(spy, sym, args, options, " NOT")
+ end
+
+ private
+
+ def describe_spy(spy, sym, args, options, not_clause="")
+ result = "expected "
+ result << call_description(sym, args)
+ result << " to#{not_clause} be received by "
+ result << spy.inspect
+ result << times_description(options[:times])
+ result << block_description(options[:with_block])
+ result << ".\n"
+ result << describe_calls(spy)
+ result
+ end
+
+ def describe_calls(spy)
+ result = ''
+ if spy.flexmock_calls.empty?
+ result << "No messages have been received\n"
+ else
+ result << "The following messages have been received:\n"
+ spy.flexmock_calls.each do |call_record|
+ result << " " << call_description(call_record.method_name, call_record.args)
+ result << " matched by " << call_record.expectation.description if call_record.expectation
+ result << "\n"
+ end
+ end
+ result
+ end
+
+ def times_description(times)
+ case times
+ when 0
+ " never"
+ when 1
+ " once"
+ when 2
+ " twice"
+ when nil
+ ""
+ else
+ " #{times} times"
+ end
+ end
+
+ def block_description(needs_block)
+ case needs_block
+ when true
+ " with a block"
+ when false
+ " without a block"
+ else
+ ""
+ end
+ end
+
+ def call_description(sym, args)
+ if args
+ "#{sym}(#{args.map { |o| o.inspect }.join(', ')})"
+ else
+ "#{sym}(...)"
+ end
+ end
+ end
+
+end
diff --git a/lib/flexmock/symbol_extensions.rb b/lib/flexmock/symbol_extensions.rb
new file mode 100644
index 0000000..e0cc640
--- /dev/null
+++ b/lib/flexmock/symbol_extensions.rb
@@ -0,0 +1,17 @@
+class Symbol
+
+ case instance_methods.first
+ when Symbol
+ def flexmock_as_name
+ self
+ end
+
+ when String
+ def flexmock_as_name
+ to_s
+ end
+
+ else
+ fail "Unexpected class for method list #{instance_methods.first.class}"
+ end
+end
diff --git a/lib/flexmock/test_unit.rb b/lib/flexmock/test_unit.rb
index 28c0c36..6890ed0 100755
--- a/lib/flexmock/test_unit.rb
+++ b/lib/flexmock/test_unit.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -11,22 +11,41 @@
require 'flexmock/test_unit_integration'
-module Test
- module Unit
- class TestCase
- include FlexMock::ArgumentTypes
- include FlexMock::MockContainer
+class FlexMock
+ module GenericTestCase
+ def self.define_extensions_on(klass)
+ klass.class_eval do
+ include FlexMock::ArgumentTypes
+ include FlexMock::MockContainer
- # Alias the original teardown behavior for later use.
- alias :flexmock_original_teardown :teardown
+ # Alias the original teardown behavior for later use.
+ alias :flexmock_original_teardown :teardown
- # Teardown the test case, verifying any mocks that might have been
- # defined in this test case.
- def teardown
- flexmock_teardown
- flexmock_original_teardown
+ # Teardown the test case, verifying any mocks that might have been
+ # defined in this test case.
+ def teardown
+ flexmock_teardown
+ flexmock_original_teardown
+ end
end
+ end
+ end
+end
+if defined?(MiniTest)
+ module MiniTest
+ class Unit
+ class TestCase
+ FlexMock::GenericTestCase.define_extensions_on(self)
+ end
+ end
+ end
+else
+ module Test
+ module Unit
+ class TestCase
+ FlexMock::GenericTestCase.define_extensions_on(self)
+ end
end
end
end
diff --git a/lib/flexmock/test_unit_assert_spy_called.rb b/lib/flexmock/test_unit_assert_spy_called.rb
new file mode 100644
index 0000000..532617b
--- /dev/null
+++ b/lib/flexmock/test_unit_assert_spy_called.rb
@@ -0,0 +1,34 @@
+require 'flexmock/spy_describers'
+
+class FlexMock
+ module TestUnitAssertions
+ include FlexMock::SpyDescribers
+
+ def assert_spy_called(spy, method_name, *args)
+ _assert_spy_called(false, spy, method_name, *args)
+ end
+
+ def assert_spy_not_called(spy, method_name, *args)
+ _assert_spy_called(true, spy, method_name, *args)
+ end
+
+ private
+
+ def _assert_spy_called(negative, spy, method_name, *args)
+ options = {}
+ if method_name.is_a?(Hash)
+ options = method_name
+ method_name = args.shift
+ end
+ args = nil if args == [:_]
+ bool = spy.flexmock_received?(method_name, args, options)
+ if negative
+ bool = !bool
+ message = describe_spy_negative_expectation(spy, method_name, args, options)
+ else
+ message = describe_spy_expectation(spy, method_name, args, options)
+ end
+ assert bool, message
+ end
+ end
+end
diff --git a/lib/flexmock/test_unit_integration.rb b/lib/flexmock/test_unit_integration.rb
index fe1a43e..a27bedb 100755
--- a/lib/flexmock/test_unit_integration.rb
+++ b/lib/flexmock/test_unit_integration.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -9,8 +9,9 @@
# above copyright notice is included.
#+++
-require 'test/unit'
+require 'test/unit/assertions'
require 'flexmock/base'
+require 'flexmock/test_unit_assert_spy_called'
class FlexMock
@@ -29,6 +30,7 @@ class FlexMock
module TestCase
include ArgumentTypes
include MockContainer
+ include TestUnitAssertions
# Teardown the test case, verifying any mocks that might have been
# defined in this test case.
@@ -44,6 +46,17 @@ class FlexMock
#
class TestUnitFrameworkAdapter
include Test::Unit::Assertions
+
+ def make_assertion(msg, &block)
+ unless yield
+ msg = msg.call if msg.is_a?(Proc)
+ assert(false, msg)
+ end
+ rescue assertion_failed_error => ex
+ ex.message.sub!(/Expected block to return true value./,'')
+ raise ex
+ end
+
def assertion_failed_error
defined?(Test::Unit::AssertionFailedError) ? Test::Unit::AssertionFailedError : MiniTest::Assertion
end
diff --git a/lib/flexmock/undefined.rb b/lib/flexmock/undefined.rb
index a78ecb8..e5fec34 100644
--- a/lib/flexmock/undefined.rb
+++ b/lib/flexmock/undefined.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/lib/flexmock/validators.rb b/lib/flexmock/validators.rb
index 4663e11..cb08b9a 100755
--- a/lib/flexmock/validators.rb
+++ b/lib/flexmock/validators.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -10,6 +10,7 @@
#+++
require 'flexmock/noop'
+require 'flexmock/spy_describers'
class FlexMock
@@ -17,6 +18,8 @@ class FlexMock
# Base class for all the count validators.
#
class CountValidator
+ include FlexMock::SpyDescribers
+
def initialize(expectation, limit)
@exp = expectation
@limit = limit
@@ -28,6 +31,41 @@ class FlexMock
def eligible?(n)
n < @limit
end
+
+ # Pluralize "call"
+ def calls(n)
+ n == 1 ? "call" : "calls"
+ end
+
+ # Human readable description of the validator
+ def describe
+ case @limit
+ when 0
+ ".never"
+ when 1
+ ".once"
+ when 2
+ ".twice"
+ else
+ ".times(#{@limit})"
+ end
+ end
+
+ def describe_limit
+ @limit.to_s
+ end
+
+ def validate_count(n, &block)
+ @exp.flexmock_location_filter do
+ FlexMock.framework_adapter.make_assertion(
+ lambda {
+ "Method '#{@exp}' called incorrect number of times\n" +
+ "#{describe_limit} matching #{calls(@limit)} expected\n" +
+ "#{n} matching #{calls(n)} found\n" +
+ describe_calls(@exp.mock)
+ }, &block)
+ end
+ end
end
####################################################################
@@ -37,8 +75,7 @@ class FlexMock
# Validate that the method expectation was called exactly +n+
# times.
def validate(n)
- FlexMock.framework_adapter.assert_equal @limit, n,
- "method '#{@exp}' called incorrect number of times"
+ validate_count(n) { @limit == n }
end
end
@@ -49,9 +86,16 @@ class FlexMock
# Validate the method expectation was called no more than +n+
# times.
def validate(n)
- FlexMock.framework_adapter.assert_block(
- "Method '#{@exp}' should be called at least #{@limit} times,\n" +
- "only called #{n} times") { n >= @limit }
+ validate_count(n) { n >= @limit }
+ end
+
+ # Human readable description of the validator.
+ def describe
+ if @limit == 0
+ ".zero_or_more_times"
+ else
+ ".at_least#{super}"
+ end
end
# If the expectation has been called +n+ times, is it still
@@ -61,6 +105,10 @@ class FlexMock
def eligible?(n)
true
end
+
+ def describe_limit
+ "At least #{@limit}"
+ end
end
####################################################################
@@ -69,9 +117,16 @@ class FlexMock
class AtMostCountValidator < CountValidator
# Validate the method expectation was called at least +n+ times.
def validate(n)
- FlexMock.framework_adapter.assert_block(
- "Method '#{@exp}' should be called at most #{@limit} times,\n" +
- "only called #{n} times") { n <= @limit }
+ validate_count(n) { n <= @limit }
+ end
+
+ # Human readable description of the validator
+ def describe
+ ".at_most#{super}"
+ end
+
+ def describe_limit
+ "At most #{@limit}"
end
end
end
diff --git a/lib/flexmock/version.rb b/lib/flexmock/version.rb
index 9f4f2fb..e519de5 100644
--- a/lib/flexmock/version.rb
+++ b/lib/flexmock/version.rb
@@ -1,9 +1,9 @@
class FlexMock
module Version
NUMBERS = [
- MAJOR = 0,
- MINOR = 9,
- BUILD = 0,
+ MAJOR = 1,
+ MINOR = 3,
+ BUILD = 2,
]
end
diff --git a/metadata.yml b/metadata.yml
index 433b6fb..e46d10f 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,27 +1,24 @@
---- !ruby/object:Gem::Specification
+--- !ruby/object:Gem::Specification
name: flexmock
-version: !ruby/object:Gem::Version
+version: !ruby/object:Gem::Version
+ version: 1.3.2
prerelease:
- version: 0.9.0
platform: ruby
-authors:
+authors:
- Jim Weirich
autorequire:
bindir: bin
cert_chain: []
-
-date: 2011-02-27 00:00:00 -05:00
-default_executable:
+date: 2013-05-07 00:00:00.000000000 Z
dependencies: []
-
-description: "\n FlexMock is a extremely simple mock object class compatible\n with the Test::Unit framework. Although the FlexMock's\n interface is simple, it is very flexible.\n "
+description: ! "\n FlexMock is a extremely simple mock object class compatible\n
+ \ with the Test::Unit framework. Although the FlexMock's\n interface is
+ simple, it is very flexible.\n "
email: jim.weirich at gmail.com
executables: []
-
extensions: []
-
-extra_rdoc_files:
-- README.rdoc
+extra_rdoc_files:
+- doc/index.rdoc
- CHANGES
- doc/GoogleExample.rdoc
- doc/releases/flexmock-0.4.0.rdoc
@@ -43,14 +40,28 @@ extra_rdoc_files:
- doc/releases/flexmock-0.8.4.rdoc
- doc/releases/flexmock-0.8.5.rdoc
- doc/releases/flexmock-0.9.0.rdoc
-files:
+- doc/releases/flexmock-1.0.0.rdoc
+- doc/releases/flexmock-1.0.3.rdoc
+- doc/releases/flexmock-1.0.4.rdoc
+- doc/releases/flexmock-1.1.0.rdoc
+- doc/releases/flexmock-1.2.0.rdoc
+- doc/releases/flexmock-1.3.0.rdoc
+- doc/releases/flexmock-1.3.1.rdoc
+- doc/examples/rspec_examples_spec.rdoc
+- doc/examples/test_unit_examples_test.rdoc
+files:
- CHANGES
+- Gemfile
+- Gemfile.lock
+- README.md
- Rakefile
-- README.rdoc
- TAGS
+- lib/flexmock.rb
- lib/flexmock/argument_matchers.rb
+- lib/flexmock/argument_matching.rb
- lib/flexmock/argument_types.rb
- lib/flexmock/base.rb
+- lib/flexmock/class_extensions.rb
- lib/flexmock/composite.rb
- lib/flexmock/core.rb
- lib/flexmock/core_class_methods.rb
@@ -59,44 +70,61 @@ files:
- lib/flexmock/errors.rb
- lib/flexmock/expectation.rb
- lib/flexmock/expectation_director.rb
+- lib/flexmock/explicit_needed.rb
- lib/flexmock/mock_container.rb
- lib/flexmock/noop.rb
+- lib/flexmock/object_extensions.rb
- lib/flexmock/ordering.rb
- lib/flexmock/partial_mock.rb
-- lib/flexmock/rails/view_mocking.rb
- lib/flexmock/rails.rb
+- lib/flexmock/rails/view_mocking.rb
- lib/flexmock/recorder.rb
- lib/flexmock/rspec.rb
+- lib/flexmock/rspec/configure.rb
+- lib/flexmock/rspec_spy_matcher.rb
+- lib/flexmock/spy_describers.rb
+- lib/flexmock/symbol_extensions.rb
- lib/flexmock/test_unit.rb
+- lib/flexmock/test_unit_assert_spy_called.rb
- lib/flexmock/test_unit_integration.rb
- lib/flexmock/undefined.rb
- lib/flexmock/validators.rb
- lib/flexmock/version.rb
-- lib/flexmock.rb
- test/aliasing_test.rb
+- test/assert_spy_called_test.rb
+- test/base_class_test.rb
+- test/based_partials_test.rb
- test/container_methods_test.rb
- test/default_framework_adapter_test.rb
- test/demeter_mocking_test.rb
- test/deprecated_methods_test.rb
- test/examples_from_readme_test.rb
+- test/expectation_description_test.rb
- test/extended_should_receive_test.rb
- test/flexmodel_test.rb
- test/naming_test.rb
- test/new_instances_test.rb
+- test/object_extensions_test.rb
- test/partial_mock_test.rb
- test/rails_view_stub_test.rb
- test/record_mode_test.rb
- test/redirect_error.rb
- test/rspec_integration/integration_spec.rb
+- test/rspec_integration/spy_example_spec.rb
- test/samples_test.rb
- test/should_ignore_missing_test.rb
- test/should_receive_test.rb
+- test/spys_test.rb
+- test/symbol_extensions_test.rb
+- test/test_class_extensions.rb
- test/test_setup.rb
- test/test_unit_integration/auto_test_unit_test.rb
+- test/test_unit_integration/minitest_teardown_test.rb
- test/tu_integration_test.rb
- test/undefined_test.rb
- flexmock.blurb
- install.rb
+- doc/index.rdoc
- doc/GoogleExample.rdoc
- doc/releases/flexmock-0.4.0.rdoc
- doc/releases/flexmock-0.4.1.rdoc
@@ -117,37 +145,45 @@ files:
- doc/releases/flexmock-0.8.4.rdoc
- doc/releases/flexmock-0.8.5.rdoc
- doc/releases/flexmock-0.9.0.rdoc
-has_rdoc: true
+- doc/releases/flexmock-1.0.0.rdoc
+- doc/releases/flexmock-1.0.3.rdoc
+- doc/releases/flexmock-1.0.4.rdoc
+- doc/releases/flexmock-1.1.0.rdoc
+- doc/releases/flexmock-1.2.0.rdoc
+- doc/releases/flexmock-1.3.0.rdoc
+- doc/releases/flexmock-1.3.1.rdoc
+- doc/examples/rspec_examples_spec.rdoc
+- doc/examples/test_unit_examples_test.rdoc
homepage: https://github.com/jimweirich/flexmock
licenses: []
-
post_install_message:
-rdoc_options:
+rdoc_options:
- --title
- FlexMock
- --main
- README.rdoc
- --line-numbers
-require_paths:
+require_paths:
- lib
-required_ruby_version: !ruby/object:Gem::Requirement
+required_ruby_version: !ruby/object:Gem::Requirement
none: false
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: "0"
-required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
+ segments:
+ - 0
+ hash: 1970361257981767370
+required_rubygems_version: !ruby/object:Gem::Requirement
none: false
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: "0"
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
requirements: []
-
rubyforge_project:
-rubygems_version: 1.5.2
+rubygems_version: 1.8.24
signing_key:
specification_version: 3
summary: Simple and Flexible Mock Objects for Testing
test_files: []
-
diff --git a/test/aliasing_test.rb b/test/aliasing_test.rb
index b886abc..982120c 100644
--- a/test/aliasing_test.rb
+++ b/test/aliasing_test.rb
@@ -2,58 +2,65 @@
require 'test/test_setup'
-class FlexMock
- module StubsAndExpects
- def expects(*args)
- result = should_receive(*args)
- result.at_least.once unless result.call_count_constrained?
- result
- end
- def stubs(*args)
- should_receive(*args)
- end
- end
+# This is an experimental test to see if mock and stub methods can
+# easily be added to a flexmock core. These test are disabled by
+# default, and should be reviewed before something more production
+# oriented is provided.
- module MockContainer
- alias :mock :flexmock
- alias :stub :flexmock
- end
+if ENV['TEST_ALIASES']
+
+ class FlexMock
+ module StubsAndExpects
+ def expects(*args)
+ result = should_receive(*args)
+ result.at_least.once unless result.call_count_constrained?
+ result
+ end
+ def stubs(*args)
+ should_receive(*args)
+ end
+ end
- include StubsAndExpects
+ module MockContainer
+ alias :mock :flexmock
+ alias :stub :flexmock
+ end
- class PartialMockProxy
include StubsAndExpects
- MOCK_METHODS << :stubs << :expects
+
+ class PartialMockProxy
+ include StubsAndExpects
+ MOCK_METHODS << :stubs << :expects
+ end
end
-end
-class AliasingTest < Test::Unit::TestCase
- include FlexMock::TestCase
+ class AliasingTest < Test::Unit::TestCase
+ include FlexMock::TestCase
- def test_mocking
- m = mock("a cute dog").expects(:pat).twice.and_return(:woof!).mock
- assert_equal :woof!, m.pat
- assert_equal :woof!, m.pat
- end
+ def test_mocking
+ m = mock("a cute dog").expects(:pat).twice.and_return(:woof!).mock
+ assert_equal :woof!, m.pat
+ assert_equal :woof!, m.pat
+ end
- def test_once_mocking
- mock("a cute dog").expects(:pat).and_return(:woof!).mock
- end
+ def test_once_mocking
+ mock("a cute dog").expects(:pat).and_return(:woof!).mock
+ end
- def test_twice_mocking
- m = mock("a cute dog").expects(:pat).and_return(:woof!).twice.mock
- assert_raises(assertion_failed_error) { m.flexmock_verify }
- end
+ def test_twice_mocking
+ m = mock("a cute dog").expects(:pat).and_return(:woof!).twice.mock
+ assert_raises(assertion_failed_error) { m.flexmock_verify }
+ end
- def test_stubbing
- m = stub("a cute dog").expects(:pat).and_return(:woof!).mock
- assert_equal :woof!, m.pat
- end
+ def test_stubbing
+ m = stub("a cute dog").expects(:pat).and_return(:woof!).mock
+ assert_equal :woof!, m.pat
+ end
- def test_partial
- obj = Object.new
- stub(obj).stubs(:wag).and_return(:tail)
- assert_equal :tail, obj.wag
+ def test_partial
+ obj = Object.new
+ stub(obj).stubs(:wag).and_return(:tail)
+ assert_equal :tail, obj.wag
+ end
end
end
-
diff --git a/test/assert_spy_called_test.rb b/test/assert_spy_called_test.rb
new file mode 100644
index 0000000..3ef8c74
--- /dev/null
+++ b/test/assert_spy_called_test.rb
@@ -0,0 +1,119 @@
+#!/usr/bin/env ruby
+
+require 'test/test_setup'
+require 'flexmock/test_unit_assert_spy_called'
+
+class AssertSpyCalledTest < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ class FooBar
+ def foo
+ end
+ def bar
+ end
+ end
+
+ def setup
+ super
+ @spy = flexmock(:on, FooBar)
+ end
+
+ def spy
+ @spy
+ end
+
+ def test_assert_detects_basic_call
+ spy.foo
+ assert_spy_called spy, :foo
+ end
+
+ def test_assert_detects_basic_call_with_args
+ spy.foo(1,2)
+ assert_spy_called spy, :foo, 1, 2
+ end
+
+ def test_assert_rejects_incorrect_args
+ spy.foo(1,2)
+ assert_fails(/^expected foo\(1, 3\) to be received by <FlexMock:AssertSpyCalledTest::FooBar Mock>/i) do
+ assert_spy_called spy, :foo, 1, 3
+ end
+ end
+
+ def test_assert_detects_multiple_calls
+ spy.foo
+ spy.foo
+ spy.foo
+ assert_spy_called spy, {:times => 3}, :foo
+ end
+
+ def test_assert_rejects_incorrect_type
+ spy.foo
+ spy.foo
+ assert_fails(/^expected foo\(\) to be received by <FlexMock:AssertSpyCalledTest::FooBar Mock> 3 times/i) do
+ assert_spy_called spy, {:times => 3}, :foo
+ end
+ end
+
+ def test_assert_detects_blocks
+ spy.foo { }
+ spy.bar
+ assert_spy_called spy, :foo, Proc
+ assert_spy_called spy, :bar
+ end
+
+ def test_assert_detects_any_args
+ spy.foo
+ spy.foo(1)
+ spy.foo("HI")
+ spy.foo("Hello", "World", 10, :options => true)
+ assert_spy_called spy, {:times => 4}, :foo, :_
+ end
+
+ def test_assert_rejects_bad_count_on_any_args
+ spy.foo
+ assert_fails(/^expected foo\(\.\.\.\) to be received by <FlexMock:AssertSpyCalledTest::FooBar Mock> twice/i) do
+ assert_spy_called spy, {:times => 2}, :foo, :_
+ end
+ end
+
+ def test_assert_error_lists_calls_actually_made_without_handled_by
+ spy.foo
+ spy.bar(1)
+ ex = assert_fails(/The following messages have been received/) do
+ assert_spy_called spy, :baz
+ end
+ assert_match(/ foo\(\)/, ex.message)
+ assert_match(/ bar\(1\)/, ex.message)
+ assert_no_match(/ baz\(\)/, ex.message)
+ assert_no_match(/handled by/, ex.message)
+ end
+
+ def test_assert_error_lists_calls_actually_made_with_handled_by
+ spy.should_receive(:foo).once
+ spy.foo
+ spy.bar(1)
+ ex = assert_fails(/The following messages have been received/) do
+ assert_spy_called spy, :baz
+ end
+ assert_match(/ foo\(\) matched by should_receive\(:foo\)/, ex.message)
+ assert_match(/ bar\(1\)/, ex.message)
+ assert_no_match(/ baz\(\)/, ex.message)
+ end
+
+ def test_assert_errors_say_no_calls_made
+ assert_fails(/No messages have been received/) do
+ assert_spy_called spy, :baz
+ end
+ end
+
+ private
+
+ def assert_fails(message_pattern)
+ ex = assert_raises(FlexMock.framework_adapter.assertion_failed_error) do
+ yield
+ end
+ assert_match(message_pattern, ex.message)
+ ex
+ end
+
+end
diff --git a/test/base_class_test.rb b/test/base_class_test.rb
new file mode 100644
index 0000000..65a75ec
--- /dev/null
+++ b/test/base_class_test.rb
@@ -0,0 +1,71 @@
+require 'test/test_setup'
+
+class BaseClassTest < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ class FooBar
+ def foo
+ end
+
+ def method_missing(sym, *args, &block)
+ return :poof if sym == :barq
+ super
+ end
+
+ def respond_to?(method)
+ method == :barq || super
+ end
+ end
+
+ def mock
+ @mock ||= flexmock(:on, FooBar)
+ end
+
+ def test_base_class_auto_mocks_class
+ assert_equal FooBar, mock.class
+ end
+
+ def test_base_class_auto_mocks_base_class_methods
+ assert_equal FlexMock.undefined, mock.foo
+ end
+
+ def test_base_class_does_not_mock_non_base_class_methods
+ assert_raise(NoMethodError) do
+ mock.fuzz
+ end
+ end
+
+ def test_can_stub_existing_methods
+ mock.should_receive(:foo => :bar)
+ assert_equal :bar, mock.foo
+ end
+
+ def test_can_not_stub_non_class_defined_methods
+ ex = assert_raises(NoMethodError) do
+ mock.should_receive(:baz => :bar)
+ end
+ assert_match(/can *not stub methods.*base.*class/i, ex.message)
+ assert_match(/class:.+FooBar/i, ex.message)
+ assert_match(/method:.+baz/i, ex.message)
+ end
+
+ def test_can_not_stub_non_class_methods_in_single_line
+ ex = assert_raises(NoMethodError) do
+ flexmock(:on, FooBar, :bark => :value)
+ end
+ assert_match(/can *not stub methods.*base.*class/i, ex.message)
+ assert_match(/class:.+FooBar/i, ex.message)
+ assert_match(/method:.+bark/i, ex.message)
+ end
+
+ def test_can_explicitly_stub_non_class_defined_methods
+ mock.should_receive(:baz).explicitly.and_return(:bar)
+ assert_equal :bar, mock.baz
+ end
+
+ def test_can_explicitly_stub_meta_programmed_methods
+ mock.should_receive(:barq).explicitly.and_return(:bar)
+ assert_equal :bar, mock.barq
+ end
+
+end
diff --git a/test/based_partials_test.rb b/test/based_partials_test.rb
new file mode 100644
index 0000000..1a2ed25
--- /dev/null
+++ b/test/based_partials_test.rb
@@ -0,0 +1,51 @@
+#!/usr/bin/env ruby
+
+#---
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
+# All rights reserved.
+
+# Permission is granted for use, copying, modification, distribution,
+# and distribution of modified versions of this work as long as the
+# above copyright notice is included.
+#+++
+
+require 'test/test_setup'
+
+class BasedPartialsTest < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ def setup
+ super
+ FlexMock.partials_are_based = true
+ end
+
+ def teardown
+ FlexMock.partials_are_based = false
+ super
+ end
+
+ class Dog
+ def bark
+ :woof
+ end
+ end
+
+ def test_based_partials_allow_stubbing_defined_methods
+ dog = Dog.new
+ flexmock(dog).should_receive(:bark => :mock_value)
+ assert_equal :mock_value, dog.bark
+ end
+
+ def test_based_partials_disallow_stubbing_undefined_methods
+ dog = Dog.new
+ assert_raise(NoMethodError, /cannot stub.*wag.*explicitly/) do
+ flexmock(dog).should_receive(:wag => :mock_value)
+ end
+ end
+
+ def test_based_partials_allow_explicitly_stubbing_undefined_methods
+ dog = Dog.new
+ flexmock(dog).should_receive(:wag).explicitly.and_return(:mock_value)
+ end
+
+end
diff --git a/test/container_methods_test.rb b/test/container_methods_test.rb
index d8fd0ef..27815a5 100755
--- a/test/container_methods_test.rb
+++ b/test/container_methods_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/test/default_framework_adapter_test.rb b/test/default_framework_adapter_test.rb
index 27dd83c..8eff953 100755
--- a/test/default_framework_adapter_test.rb
+++ b/test/default_framework_adapter_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -18,15 +18,15 @@ class TestFlexmockDefaultFrameworkAdapter < Test::Unit::TestCase
def test_assert_block_raises_exception
assert_raise(FlexMock::DefaultFrameworkAdapter::AssertionFailedError) {
- @adapter.assert_block("failure message") { false }
+ @adapter.make_assertion("failure message") { false }
}
end
- def test_assert_block_doesnt_raise_exception
- @adapter.assert_block("failure message") { true }
+ def test_make_assertion_doesnt_raise_exception_when_making_assertion
+ @adapter.make_assertion("failure message") { true }
end
- def test_assert_equal_doesnt_raise_exception
+ def test_make_assertion_doesnt_raise_exception_when_asserting_equal
@adapter.assert_equal("a", "a", "no message")
end
diff --git a/test/demeter_mocking_test.rb b/test/demeter_mocking_test.rb
index 8876f5e..54440d8 100644
--- a/test/demeter_mocking_test.rb
+++ b/test/demeter_mocking_test.rb
@@ -65,7 +65,7 @@ class TestDemeterMocking < Test::Unit::TestCase
def test_conflicting_mock_declarations_in_reverse_order_does_not_raise_error
# Not all conflicting definitions can be detected.
m = flexmock("A")
- assert_failure() do
+ assert_failure do
m.should_receive("child.other").and_return(:other)
m.should_receive("child").and_return(:xyzzy)
assert_equal :xyzzy, m.child.other
diff --git a/test/deprecated_methods_test.rb b/test/deprecated_methods_test.rb
index 2cd00b6..65deb3a 100644
--- a/test/deprecated_methods_test.rb
+++ b/test/deprecated_methods_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -174,7 +174,7 @@ class TestFlexMock < Test::Unit::TestCase
s { @mock.mock_handle(:xyzzy) { got_it = true } }
method_proc = @mock.method(:xyzzy)
assert_not_nil method_proc
- method_proc.call
+ method_proc.call([])
assert(got_it, "method proc should run")
end
diff --git a/test/examples_from_readme_test.rb b/test/examples_from_readme_test.rb
index 1f871cd..df7c4fc 100644
--- a/test/examples_from_readme_test.rb
+++ b/test/examples_from_readme_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/test/expectation_description_test.rb b/test/expectation_description_test.rb
new file mode 100644
index 0000000..e119324
--- /dev/null
+++ b/test/expectation_description_test.rb
@@ -0,0 +1,80 @@
+#!/usr/bin/env ruby
+
+#---
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
+# All rights reserved.
+
+# Permission is granted for use, copying, modification, distribution,
+# and distribution of modified versions of this work as long as the
+# above copyright notice is included.
+#+++
+
+require 'test/test_setup'
+
+class ExpectationDescriptionTest < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ def setup
+ @mock = flexmock("mock")
+ @exp = FlexMock::Expectation.new(@mock, :foo, "file.rb:3")
+ end
+
+ def test_basic_description
+ assert_equal "should_receive(:foo)", @exp.description
+ end
+
+ def test_with_no_args
+ @exp.with()
+ assert_equal "should_receive(:foo).with()", @exp.description
+ end
+
+ def test_with_simple_args
+ @exp.with(1, "HI")
+ assert_equal "should_receive(:foo).with(1, \"HI\")", @exp.description
+ end
+
+ def test_with_never
+ @exp.never
+ assert_equal "should_receive(:foo).never", @exp.description
+ end
+
+ def test_with_once
+ @exp.once
+ assert_equal "should_receive(:foo).once", @exp.description
+ end
+
+ def test_with_twice
+ @exp.twice
+ assert_equal "should_receive(:foo).twice", @exp.description
+ end
+
+ def test_with_3
+ @exp.times(3)
+ assert_equal "should_receive(:foo).times(3)", @exp.description
+ end
+
+ def test_with_at_least_once
+ @exp.at_least.once
+ assert_equal "should_receive(:foo).at_least.once", @exp.description
+ end
+
+ def test_with_at_least_10
+ @exp.at_least.times(10)
+ assert_equal "should_receive(:foo).at_least.times(10)", @exp.description
+ end
+
+ def test_with_at_most_once
+ @exp.at_most.once
+ assert_equal "should_receive(:foo).at_most.once", @exp.description
+ end
+
+ def test_with_zero_or_more_times
+ @exp.at_most.zero_or_more_times
+ assert_equal "should_receive(:foo).zero_or_more_times", @exp.description
+ end
+
+ def test_with_at_least_1_at_most_10
+ @exp.at_least.once.at_most.times(10)
+ assert_equal "should_receive(:foo).at_least.once.at_most.times(10)", @exp.description
+ end
+end
diff --git a/test/extended_should_receive_test.rb b/test/extended_should_receive_test.rb
index 0294c92..0118b49 100755
--- a/test/extended_should_receive_test.rb
+++ b/test/extended_should_receive_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/test/naming_test.rb b/test/naming_test.rb
index 302db1d..bf674ca 100644
--- a/test/naming_test.rb
+++ b/test/naming_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -82,4 +82,3 @@ class TestNaming < Test::Unit::TestCase
assert_equal "MOCK-INSPECT", dummy.inspect
end
end
-
diff --git a/test/new_instances_test.rb b/test/new_instances_test.rb
index 3b60c0e..3aa8256 100755
--- a/test/new_instances_test.rb
+++ b/test/new_instances_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -96,7 +96,7 @@ class TestNewInstances < Test::Unit::TestCase
Dog.new
ex = assert_raise(assertion_failed_error) { flexmock_teardown }
- assert_match(/method 'bark\(.*\)' called incorrect number of times/, ex.message)
+ assert_match(/method 'bark\(.*\)' called incorrect number of times/i, ex.message)
end
def test_new_instances_reports_error_on_non_classes
@@ -213,5 +213,3 @@ class TestNewInstances < Test::Unit::TestCase
dog.bark
end
end
-
-
diff --git a/test/object_extensions_test.rb b/test/object_extensions_test.rb
new file mode 100644
index 0000000..8ec4a5b
--- /dev/null
+++ b/test/object_extensions_test.rb
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+
+require 'test/test_setup'
+require 'flexmock/object_extensions'
+
+class ObjectExtensionsTest < Test::Unit::TestCase
+ def setup
+ @obj = Object.new
+ def @obj.smethod
+ :ok
+ end
+ end
+
+ def test_undefined_methods_are_not_singletons
+ assert ! @obj.flexmock_singleton_defined?(:xyzzy)
+ end
+
+ def test_normal_methods_are_not_singletons
+ assert ! @obj.flexmock_singleton_defined?(:to_s)
+ end
+
+ def test_singleton_methods_are_singletons
+ assert @obj.flexmock_singleton_defined?(:smethod)
+ end
+end
diff --git a/test/partial_mock_test.rb b/test/partial_mock_test.rb
index 706f305..0ee3cdc 100644
--- a/test/partial_mock_test.rb
+++ b/test/partial_mock_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -35,6 +35,12 @@ class TestStubbing < Test::Unit::TestCase
end
end
+ def test_attempting_to_partially_mock_existing_mock_is_noop
+ m = flexmock("A")
+ flexmock(m)
+ assert ! m.instance_variables.include?(:@flexmock_proxy.flexmock_as_name)
+ end
+
def test_stub_command_add_behavior_to_arbitrary_objects
obj = Object.new
flexmock(obj).should_receive(:hi).once.and_return(:stub_hi)
@@ -61,6 +67,27 @@ class TestStubbing < Test::Unit::TestCase
assert_equal flexmock(obj), flexmock(obj)
end
+ def test_stubbed_methods_can_invoke_original_behavior_directly
+ dog = Dog.new
+ flexmock(dog).should_receive(:bark).pass_thru.once
+ assert_equal :woof, dog.bark
+ end
+
+ def test_stubbed_methods_can_invoke_original_behavior_with_modification
+ dog = Dog.new
+ flexmock(dog).should_receive(:bark).pass_thru { |result| result.to_s.upcase }.once
+ assert_equal "WOOF", dog.bark
+ end
+
+ def test_stubbed_methods_returning_partial_mocks
+ flexmock(Dog).should_receive(:new).pass_thru { |dog|
+ flexmock(dog, :beg => "Please")
+ }.once
+ dog = Dog.new
+ assert_equal "Please", dog.beg
+ assert_equal :woof, dog.bark
+ end
+
def test_multiple_methods_can_be_stubbed
dog = Dog.new
flexmock(dog).should_receive(:bark).and_return(:grrrr)
@@ -264,6 +291,23 @@ class TestStubbing < Test::Unit::TestCase
end
end
+ # This test ensures that singleton? does not use the old methods(false)
+ # call that has fallen out of favor in Ruby 1.9. In multiple 1.9 releases
+ # Delegator#methods will not even accept the optional argument, making flexmock
+ # explode. Since there is a way to get singleton methods officially we might
+ # as well just do it, right?
+ class NoMethods
+ def methods(arg = true)
+ raise "Should not be called in the test lifecycle"
+ end
+ end
+
+ def xtest_object_methods_method_is_not_used_in_singleton_checks
+ obj = NoMethods.new
+ def obj.mock() :original end
+ assert_nothing_raised { flexmock(obj) }
+ end
+
def test_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restored
dog = Dog.new
def dog.mock() :original end
@@ -337,6 +381,40 @@ class TestStubbing < Test::Unit::TestCase
assert_equal :xyzzy, liar.not_defined
end
+ class MetaDog < Dog
+ def method_missing(method, *args, &block)
+ if method.to_s =~ /meow/
+ :meow
+ else
+ super
+ end
+ end
+ def respond_to_missing?(method, *)
+ method =~ /meow/ || super
+ end
+ end
+
+ def test_partial_mock_where_method_created_by_method_missing_and_respond_to_missing
+ dog = MetaDog.new
+ flexmock(dog, :meow => :hiss)
+ assert_equal :hiss, dog.meow
+ end
+
+ def test_partial_mocks_allow_stubbing_defined_methods_when_using_on
+ dog = Dog.new
+ flexmock(dog, :on, Dog)
+ dog.should_receive(:bark).and_return(:grrr)
+ assert_equal :grrr, dog.bark
+ end
+
+ def test_partial_mocks_disallow_stubbing_undefined_methods_when_using_on
+ dog = Dog.new
+ flexmock(dog, :on, Dog)
+ assert_raise(NoMethodError, /meow.*explicitly/) do
+ dog.should_receive(:meow).and_return(:something)
+ end
+ end
+
# The following test was suggested by Pat Maddox for the RSpec
# mocks. Evidently the (poorly implemented) == method caused issues
# with RSpec Mock's internals. I'm just double checking for any
diff --git a/test/record_mode_test.rb b/test/record_mode_test.rb
index e6d0b7b..6ffc77e 100644
--- a/test/record_mode_test.rb
+++ b/test/record_mode_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -71,7 +71,7 @@ class TestRecordMode < Test::Unit::TestCase
end
def test_recording_mode_should_validate_args_with_equals
- assert_failure do
+ assert_mock_failure(:deep => true, :line => __LINE__+5) do
FlexMock.use("mock") do |mock|
mock.should_expect do |r|
r.f(1)
@@ -82,7 +82,7 @@ class TestRecordMode < Test::Unit::TestCase
end
def test_recording_mode_should_allow_arg_contraint_validation
- assert_failure do
+ assert_mock_failure(:deep => true, :line => __LINE__+5) do
FlexMock.use("mock") do |mock|
mock.should_expect do |r|
r.f(1)
@@ -93,7 +93,7 @@ class TestRecordMode < Test::Unit::TestCase
end
def test_recording_mode_should_handle_multiplicity_contraints
- assert_failure do
+ assert_mock_failure(:line => __LINE__+3) do
FlexMock.use("mock") do |mock|
mock.should_expect do |r|
r.f { :result }.once
@@ -105,7 +105,7 @@ class TestRecordMode < Test::Unit::TestCase
end
def test_strict_record_mode_requires_exact_argument_matches
- assert_failure do
+ assert_mock_failure(:deep => true, :line => __LINE__+6) do
FlexMock.use("mock") do |mock|
mock.should_expect do |rec|
rec.should_be_strict
@@ -117,7 +117,7 @@ class TestRecordMode < Test::Unit::TestCase
end
def test_strict_record_mode_requires_exact_ordering
- assert_failure do
+ assert_mock_failure(:deep => true, :line => __LINE__+8) do
FlexMock.use("mock") do |mock|
mock.should_expect do |rec|
rec.should_be_strict
@@ -131,7 +131,7 @@ class TestRecordMode < Test::Unit::TestCase
end
def test_strict_record_mode_requires_once
- assert_failure do
+ assert_mock_failure(:deep => true, :line => __LINE__+4) do
FlexMock.use("mock") do |mock|
mock.should_expect do |rec|
rec.should_be_strict
diff --git a/test/rspec_integration/integration_spec.rb b/test/rspec_integration/integration_spec.rb
index 2d3ed5e..fbb3536 100755
--- a/test/rspec_integration/integration_spec.rb
+++ b/test/rspec_integration/integration_spec.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -27,6 +27,9 @@ describe "FlexMock in a RSpec example" do
specify "should have an error when a mock is not called" do
m = flexmock("Expectation Failured")
m.should_receive(:hi).with().once
+ lambda {
+ flexmock_verify
+ }.should raise_error(RSpec::Expectations::ExpectationNotMetError, /\bhi\b.*incorrect.*times/i)
end
specify "should be able to create a stub" do
@@ -37,12 +40,17 @@ describe "FlexMock in a RSpec example" do
end
specify "Should show an example failure" do
- 1.should == 2
+ lambda {
+ 1.should == 2
+ }.should raise_error(RSpec::Expectations::ExpectationNotMetError,
+ /expected: 2.*got: 1/m)
end
specify "Should show how mocks are displayed in error messages" do
m = flexmock("x")
- m.should == 2
+ lambda {
+ m.should == 2
+ }.should raise_error(RSpec::Expectations::ExpectationNotMetError, /got: <FlexMock:x>/)
end
end
diff --git a/test/rspec_integration/spy_example_spec.rb b/test/rspec_integration/spy_example_spec.rb
new file mode 100644
index 0000000..3c2ebe5
--- /dev/null
+++ b/test/rspec_integration/spy_example_spec.rb
@@ -0,0 +1,207 @@
+require 'flexmock/rspec'
+
+RSpec.configure do |config|
+ config.mock_with :flexmock
+end
+
+describe "Dog" do
+ class Dog
+ def wags(arg)
+ fail "SHOULD NOT BE CALLED"
+ end
+
+ def barks
+ fail "SHOULD NOT BE CALLED"
+ end
+ end
+
+ let(:dog) { flexmock(:on, Dog) }
+
+ context "single calls with arguments" do
+ before do
+ dog.wags(:tail)
+ end
+
+ it "accepts no with" do
+ dog.should have_received(:wags)
+ end
+
+ it "accepts with restriction" do
+ dog.should have_received(:wags).with(:tail)
+ end
+
+ it "accepts not methods called" do
+ dog.should_not have_received(:bark)
+ end
+
+ it "rejects incorrect with restriction" do
+ should_fail(/^expected wag\(:foot\) to be received by <FlexMock:Dog Mock>/i) do
+ dog.should have_received(:wag).with(:foot)
+ end
+ end
+
+ it "rejects not on correct matcher" do
+ should_fail(/^expected wags\(:tail\) to NOT be received by <FlexMock:Dog Mock>/i) do
+ dog.should_not have_received(:wags).with(:tail)
+ end
+ end
+ end
+
+ context "multiple calls with multiple arguments" do
+ before do
+ dog.wags(:tail)
+ dog.wags(:tail)
+ dog.wags(:tail)
+ dog.wags(:head, :tail)
+ dog.barks
+ dog.barks
+ end
+
+ it "accepts wags(:tail) multiple times" do
+ dog.should have_received(:wags).with(:tail).times(3)
+ end
+
+ it "rejects wags(:tail) wrong times value" do
+ should_fail(/^expected wags\(:tail\) to be received by <FlexMock:Dog Mock>/i) do
+ dog.should have_received(:wags).with(:tail).times(2)
+ end
+ end
+
+ it "detects any_args" do
+ dog.should have_received(:wags).times(4)
+ end
+
+ it "accepts once" do
+ dog.should have_received(:wags).with(:head, :tail).once
+ end
+
+ it "rejects an incorrect once" do
+ should_fail(/^expected wags\(:tail\) to be received by <FlexMock:Dog Mock> once/i) do
+ dog.should have_received(:wags).with(:tail).once
+ end
+ end
+
+ it "accepts twice" do
+ dog.should have_received(:barks).twice
+ end
+
+ it "rejects an incorrect twice" do
+ should_fail(/^expected wags\(:tail\) to be received by <FlexMock:Dog Mock> twice/) do
+ dog.should have_received(:wags).with(:tail).twice
+ end
+ end
+
+ it "accepts never" do
+ dog.should have_received(:jump).never
+ end
+
+ it "rejects an incorrect never" do
+ should_fail(/^expected barks\(\) to be received by <FlexMock:Dog Mock> never/i) do
+ dog.should have_received(:barks).with().never
+ end
+ end
+
+ it "rejects an incorrect never" do
+ dog.should_not have_received(:jump)
+ end
+ end
+
+ context "with additional validations" do
+ it "accepts when correct" do
+ dog.wags(:tail)
+ dog.should have_received(:wags).and { |arg| arg.should == :tail }
+ end
+
+ it "rejects when incorrect" do
+ dog.wags(:tail)
+ should_fail(/expected: :foot.*got: :tail/im) do
+ dog.should have_received(:wags).and { |arg| arg.should == :foot }
+ end
+ end
+
+ it "rejects on all calls" do
+ dog.wags(:foot)
+ dog.wags(:foot)
+ dog.wags(:tail)
+ should_fail(/expected: :foot.*got: :tail/im) do
+ dog.should have_received(:wags).and { |arg| arg.should == :foot }
+ end
+ end
+
+ it "runs the first additional block" do
+ dog.wags(:tail)
+ should_fail(/expected: :foot.*got: :tail/im) do
+ dog.should have_received(:wags).and { |args|
+ args.should == :foot
+ }.and { |args|
+ args.should == :tail
+ }
+ end
+ end
+
+ it "runs the second additional block" do
+ dog.wags(:tail)
+ should_fail(/expected: :foot.*got: :tail/im) do
+ dog.should have_received(:wags).and { |args|
+ args.should == :tail
+ }.and { |args|
+ args.should == :foot
+ }
+ end
+ end
+ end
+
+ context "with ordinal constraints" do
+ it "detects the first call" do
+ dog.wags(:tail)
+ dog.wags(:foot)
+ dog.should have_received(:wags).and { |arg| arg.should == :tail }.on(1)
+ end
+
+ it "detects the second call" do
+ dog.wags(:tail)
+ dog.wags(:foot)
+ dog.should have_received(:wags).and { |arg| arg.should == :foot }.on(2)
+ end
+ end
+
+ context "with blocks" do
+ before do
+ dog.wags { }
+ dog.barks
+ end
+
+ it "accepts wags with a block" do
+ dog.should have_received(:wags).with_a_block
+ dog.should have_received(:wags)
+ end
+
+ it "accepts barks without a block" do
+ dog.should have_received(:barks).without_a_block
+ dog.should have_received(:barks)
+ end
+
+ it "rejects wags without a block" do
+ should_fail(/without a block/) do
+ dog.should have_received(:wags).without_a_block
+ end
+ end
+
+ it "rejects barks with a block" do
+ should_fail(/with a block/) do
+ dog.should have_received(:barks).with_a_block
+ end
+ end
+ end
+
+ def should_fail(message_pattern)
+ failed = false
+ begin
+ yield
+ rescue RSpec::Expectations::ExpectationNotMetError => ex
+ failed = true
+ ex.message.should match(message_pattern)
+ end
+ RSpec::Expectations.fail_with "Expected block to fail with message #{message_pattern.inspect}, no failure detected" unless failed
+ end
+end
diff --git a/test/samples_test.rb b/test/samples_test.rb
index 14c3e03..cbce7cf 100644
--- a/test/samples_test.rb
+++ b/test/samples_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/test/should_ignore_missing_test.rb b/test/should_ignore_missing_test.rb
index 19c8482..c214a4c 100644
--- a/test/should_ignore_missing_test.rb
+++ b/test/should_ignore_missing_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -32,6 +32,11 @@ class TestShouldIgnoreMissing < Test::Unit::TestCase
assert @mock.respond_to?(:unknown_foo)
end
+ def test_should_ignore_missing_returns_mock
+ result = @mock.should_ignore_missing
+ assert_equal result, @mock
+ end
+
def test_ignored_methods_return_undefined
@mock.should_ignore_missing
assert_equal FlexMock.undefined, @mock.unknown_foo
@@ -58,7 +63,7 @@ class TestShouldIgnoreMissing < Test::Unit::TestCase
@mock.should_receive(:known_foo).once
method_proc = @mock.method(:known_foo)
assert_not_nil method_proc
- method_proc.call
+ method_proc.call([])
end
def test_not_calling_method_proc_will_fail_count_constraints
@@ -77,4 +82,3 @@ class TestShouldIgnoreMissing < Test::Unit::TestCase
assert_equal FlexMock.undefined, method_proc.call
end
end
-
diff --git a/test/should_receive_test.rb b/test/should_receive_test.rb
index 4ebcbd6..436a283 100644
--- a/test/should_receive_test.rb
+++ b/test/should_receive_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -35,8 +35,8 @@ class TestFlexMockShoulds < Test::Unit::TestCase
# Expected error messages on failures
COUNT_ERROR_MESSAGE = /\bcalled\s+incorrect\s+number\s+of\s+times\b/
NO_MATCH_ERROR_MESSAGE = /\bno\s+matching\s+handler\b/
- AT_LEAST_ERROR_MESSAGE = /\bshould\s+be\s+called\s+at\s+least\b/
- AT_MOST_ERROR_MESSAGE = /\bshould\s+be\s+called\s+at\s+most\b/
+ AT_LEAST_ERROR_MESSAGE = COUNT_ERROR_MESSAGE
+ AT_MOST_ERROR_MESSAGE = COUNT_ERROR_MESSAGE
OUT_OF_ORDER_ERROR_MESSAGE = /\bcalled\s+out\s+of\s+order\b/
NON_CONTAINER_MESSAGE = /\bis\s+not\s+in\s+a\s+container\b/
@@ -149,6 +149,19 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
end
+ def test_multiple_yields_and_multiple_returns_are_synced
+ FlexMock.use do |m|
+ m.should_receive(:msg).and_yield(:one).and_return(1).and_yield(:two).and_return(2)
+ yielded_values = []
+ returned_values = []
+ returned_values << m.msg { |a| yielded_values << a }
+ returned_values << m.msg { |a| yielded_values << a }
+ returned_values << m.msg { |a| yielded_values << a }
+ assert_equal [:one, :two, :two], yielded_values
+ assert_equal [1, 2, 2], returned_values
+ end
+ end
+
def test_failure_if_no_block_given
FlexMock.use do |m|
m.should_receive(:hi).and_yield(:one, :two).once
@@ -301,6 +314,13 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
end
+ def test_pass_thru_just_returns_undefined_on_mocks
+ FlexMock.use do |m|
+ m.should_receive(:hi).pass_thru
+ assert_equal FlexMock.undefined, m.hi
+ end
+ end
+
def test_multiple_expectations
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10)
@@ -319,7 +339,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_with_no_args_but_with_args
- assert_failure(NO_MATCH_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>NO_MATCH_ERROR_MESSAGE, :deep => true) do
FlexMock.use do |m|
m.should_receive(:hi).with_no_args
m.hi(1)
@@ -372,7 +392,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
def test_with_ducktype_arg_matching_no_match
FlexMock.use('greeter') do |m|
m.should_receive(:hi).with(FlexMock.ducktype(:purr, :meow, :growl))
- assert_failure {
+ assert_mock_failure(:deep => true, :line => __LINE__+1) {
m.hi(Cat.new)
}
end
@@ -388,7 +408,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
def test_with_hash_non_matching
FlexMock.use('greeter') do |m|
m.should_receive(:hi).with(FlexMock.hsh(:a => 1, :b => 2))
- assert_failure {
+ assert_mock_failure(:deep => true, :line => __LINE__+1) {
m.hi(:a => 1, :b => 4, :c => 3)
}
end
@@ -403,9 +423,31 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
end
+ def test_with_optional_proc
+ FlexMock.use('greeter') do |m|
+ m.should_receive(:hi).with(optional_proc).once
+ m.hi { }
+ end
+ end
+
+ def test_with_optional_proc_and_missing_proc
+ FlexMock.use('greeter') do |m|
+ m.should_receive(:hi).with(optional_proc).once
+ m.hi
+ end
+ end
+
+ def test_with_optional_proc_distinquishes_between_nil_and_missing
+ FlexMock.use('greeter') do |m|
+ m.should_receive(:hi).with(optional_proc).never
+ m.should_receive(:hi).with(nil).once
+ m.hi(nil)
+ end
+ end
+
def test_with_arbitrary_arg_matching
FlexMock.use('greeter') do |m|
- m.should_receive(:hi).with(FlexMock.on { |arg| arg % 2 == 0 }).twice
+ m.should_receive(:hi).with(FlexMock.on { |arg| arg % 2 == 0 rescue nil }).twice
m.should_receive(:hi).never
m.should_receive(:hi).with(1).once
m.should_receive(:hi).with(2).never
@@ -451,8 +493,8 @@ class TestFlexMockShoulds < Test::Unit::TestCase
def test_arg_matching_with_no_match
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10)
- assert_failure(NO_MATCH_ERROR_MESSAGE) {
- assert_equal 20, m.hi(2)
+ assert_mock_failure(:message =>NO_MATCH_ERROR_MESSAGE, :deep => true, :line => __LINE__+1) {
+ m.hi(2)
}
end
end
@@ -460,7 +502,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
def test_arg_matching_with_string_doesnt_over_match
FlexMock.use do |m|
m.should_receive(:hi).with(String).returns(20)
- assert_failure(NO_MATCH_ERROR_MESSAGE) {
+ assert_mock_failure(:message =>NO_MATCH_ERROR_MESSAGE, :deep => true, :line => __LINE__+1) {
m.hi(1.0)
}
end
@@ -469,7 +511,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
def test_block_arg_given_to_no_args
FlexMock.use do |m|
m.should_receive(:hi).with_no_args.returns(20)
- assert_failure(NO_MATCH_ERROR_MESSAGE) {
+ assert_mock_failure(:message =>NO_MATCH_ERROR_MESSAGE, :deep => true, :line => __LINE__+1) {
m.hi { 1 }
}
end
@@ -509,7 +551,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_never_and_called_once
- assert_failure(COUNT_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>COUNT_ERROR_MESSAGE, :deep => true, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).never
m.hi(1)
@@ -525,7 +567,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_once_but_never_called
- assert_failure(COUNT_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>COUNT_ERROR_MESSAGE, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10).once
end
@@ -533,7 +575,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_once_but_called_twice
- assert_failure(COUNT_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>COUNT_ERROR_MESSAGE, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10).once
m.hi(1)
@@ -585,7 +627,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_at_least_but_never_called
- assert_failure(AT_LEAST_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>AT_LEAST_ERROR_MESSAGE, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10).at_least.once
end
@@ -601,7 +643,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_at_least_and_exact
- assert_failure(COUNT_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>COUNT_ERROR_MESSAGE, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10).at_least.once.once
m.hi(1)
@@ -624,21 +666,23 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_at_most_called_twice
- assert_failure(AT_MOST_ERROR_MESSAGE) do
+ ex = assert_mock_failure(:message =>AT_MOST_ERROR_MESSAGE, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10).at_most.once
m.hi(1)
m.hi(1)
end
end
+ assert_match(/at most 1/i, ex.message)
end
def test_at_most_and_at_least_called_never
- assert_failure(AT_LEAST_ERROR_MESSAGE) do
+ ex = assert_mock_failure(:message =>AT_LEAST_ERROR_MESSAGE, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice
end
end
+ assert_match(/at least 1/i, ex.message)
end
def test_at_most_and_at_least_called_once
@@ -657,7 +701,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_at_most_and_at_least_called_three_times
- assert_failure(AT_MOST_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>AT_MOST_ERROR_MESSAGE, :line => __LINE__+2) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice
m.hi(1)
@@ -680,7 +724,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_call_counts_only_apply_to_matching_args_with_mismatch
- ex = assert_failure(COUNT_ERROR_MESSAGE) do
+ ex = assert_mock_failure(:message =>COUNT_ERROR_MESSAGE, :line => __LINE__+3) do
FlexMock.use do |m|
m.should_receive(:hi).with(1).once
m.should_receive(:hi).with(2).twice
@@ -706,7 +750,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_ordered_calls_out_of_order_will_fail
- assert_failure(OUT_OF_ORDER_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do
FlexMock.use 'm' do |m|
m.should_receive(:hi).ordered
m.should_receive(:lo).ordered
@@ -728,7 +772,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_order_calls_with_different_arg_lists_and_out_of_order_will_fail
- assert_failure(OUT_OF_ORDER_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do
FlexMock.use 'm' do |m|
m.should_receive(:hi).with("one").ordered
m.should_receive(:hi).with("two").ordered
@@ -806,7 +850,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_explicit_ordering_with_explicit_misorders
- assert_failure(OUT_OF_ORDER_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do
FlexMock.use 'm' do |m|
m.should_receive(:hi).ordered(:first_group)
m.should_receive(:lo).ordered(:second_group)
@@ -857,7 +901,7 @@ class TestFlexMockShoulds < Test::Unit::TestCase
end
def test_ordering_between_mocks_is_honored_for_global_ordering
- assert_failure(OUT_OF_ORDER_ERROR_MESSAGE) do
+ assert_mock_failure(:message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do
FlexMock.use("x", "y") do |x, y|
x.should_receive(:one).globally.ordered
y.should_receive(:two).globally.ordered
@@ -1036,6 +1080,20 @@ class TestFlexMockShoulds < Test::Unit::TestCase
assert ! mock.respond_to?(:phoo, true)
end
+ def test_backtraces_point_to_should_receive_line
+ mock = flexmock("a mock")
+ file_name_re = Regexp.quote(__FILE__)
+ line_no = __LINE__ + 1
+ mock.should_receive(:foo).and_return(:bar).once
+ begin
+ flexmock_verify
+ rescue Exception => ex
+ exception = ex
+ end
+ assert_not_nil exception
+ assert_match(/#{file_name_re}:#{line_no}/, exception.backtrace.first)
+ end
+
def test_can_mock_operators
assert_operator(:[]) { |m| m[1] }
assert_operator(:[]=) { |m| m[1] = :value }
diff --git a/test/spys_test.rb b/test/spys_test.rb
new file mode 100644
index 0000000..0ed04b6
--- /dev/null
+++ b/test/spys_test.rb
@@ -0,0 +1,215 @@
+#!/usr/bin/env ruby
+
+require 'test/test_setup'
+
+class TestSpys < Test::Unit::TestCase
+ include FlexMock::TestCase
+
+ class FooBar
+ def foo
+ :foofoo
+ end
+ def bar
+ end
+ end
+
+ def setup
+ super
+ @spy = flexmock(:on, FooBar)
+ end
+
+ def test_spy_detects_simple_call
+ @spy.foo
+ assert_spy_called @spy, :foo
+ end
+
+ def test_spy_detects_simple_call_ignoring_args
+ @spy.foo(1)
+ assert_spy_called @spy, :foo, :_
+ end
+
+ def test_spy_rejects_a_never_made_call
+ @spy.foo
+ assert_spy_not_called @spy, :bar
+ end
+
+ def test_spy_detects_call_with_literal_arg
+ @spy.foo(1)
+ assert_spy_called @spy, :foo, 1
+ end
+
+ def test_spy_detects_call_with_class_arg
+ @spy.foo(1)
+ assert_spy_called @spy, :foo, Integer
+ end
+
+ def test_spy_rejects_call_with_non_matching_literal_arg
+ @spy.foo(2)
+ assert_spy_not_called @spy, :foo, 1
+ end
+
+ def test_spy_detects_call_with_multiple_arguments
+ @spy.foo(1, "HI", :foo)
+ assert_spy_called @spy, :foo, /1/, "HI", Symbol
+ end
+
+ def test_spy_detects_multiple_calls_with_different_arguments
+ @spy.foo(1)
+ @spy.foo(1)
+ assert_spy_called @spy, {:times => 2}, :foo, 1
+ end
+
+ def test_spy_rejects_if_times_options_not_matching
+ @spy.foo(1)
+ @spy.foo(1)
+ assert_spy_not_called @spy, {:times => 1}, :foo, 1
+ end
+
+ def test_spy_detects_a_block
+ @spy.foo { }
+ assert_spy_called @spy, :foo, Proc
+ end
+
+ def test_spy_rejects_a_block
+ @spy.foo { }
+ assert_spy_not_called @spy, {:with_block => false}, :foo
+ end
+
+ def test_spy_detects_a_missing_block
+ @spy.foo
+ assert_spy_called @spy, {:with_block => false}, :foo
+ end
+
+ def test_spy_rejects_a_missing_block
+ @spy.foo
+ assert_spy_not_called @spy, :foo, Proc
+ end
+
+ def test_spy_ignores_block
+ @spy.foo { }
+ assert_spy_called @spy, :foo, Proc
+ end
+
+ def test_spy_accepts_correct_additional_validations
+ @spy.foo(2)
+ is_even = proc { |n| assert_equal 0, n%2 }
+ assert_spy_called @spy, { :and => is_even }, :foo, Integer
+ end
+
+ def test_spy_accepts_multiple_additional_validations_first_failing
+ @spy.foo(4)
+ is_two = proc { |n| assert_equal 2, n }
+ is_even = proc { |n| assert_equal 0, n%2 }
+ assert_failed(/2.*expected but was.*4/mi) do
+ assert_spy_called @spy, { :and => [is_two, is_even] }, :foo, Integer
+ end
+ end
+
+ def test_spy_accepts_multiple_additional_validations_second_failing
+ @spy.foo(4)
+ is_even = proc { |n| assert_equal 0, n%2 }
+ is_two = proc { |n| assert_equal 2, n }
+ assert_failed(/2.*expected but was.*4/mi) do
+ assert_spy_called @spy, { :and => [is_even, is_two] }, :foo, Integer
+ end
+ end
+
+ def test_spy_rejects_incorrect_additional_validations
+ @spy.foo(3)
+ is_even = proc { |n| assert_equal 0, n%2 }
+ assert_failed(/0.*expected but was.*1/mi) do
+ assert_spy_called @spy, { :and => is_even }, :foo, Integer
+ end
+ end
+
+ def test_spy_selectively_applies_additional_validations
+ @spy.foo(2)
+ @spy.foo(3)
+ @spy.foo(4)
+ is_even = proc { |n| assert_equal 0, n%2 }
+ assert_failed(/0.*expected but was.*1/mi) do
+ assert_spy_called @spy, { :and => is_even, :on => 2 }, :foo, Integer
+ end
+ end
+
+ def assert_failed(message_pattern)
+ failed = false
+ begin
+ yield
+ rescue assertion_failed_error => ex
+ failed = true
+ assert_match message_pattern, ex.message
+ end
+ assert(failed, "Expected block to fail")
+ end
+
+ def test_spy_methods_can_be_stubbed
+ @spy.should_receive(:foo).and_return(:hi)
+ result = @spy.foo
+ assert_equal result, :hi
+ assert_spy_called @spy, :foo
+ end
+
+ def test_spy_cannot_see_normal_methods
+ foo = FooBar.new
+ flexmock(foo)
+ assert_equal :foofoo, foo.foo
+ assert_spy_not_called foo, :foo
+ end
+
+ def test_spy_cannot_see_normal_methods2
+ foo = FooBar.new
+ flexmock(foo).should_receive(:foo).pass_thru
+ assert_equal :foofoo, foo.foo
+ assert_spy_called foo, :foo
+ end
+
+ def test_calling_non_spy_base_methods_is_an_error
+ assert_raise(NoMethodError) do
+ @spy.baz
+ end
+ end
+
+ def test_cant_put_expectations_on_non_base_class_methodsx
+ ex = assert_raise(NoMethodError) do
+ @spy.should_receive(:baz).and_return(:bar)
+ end
+ assert_match(/cannot stub.*defined.*base.*class/i, ex.message)
+ assert_match(/method: +baz/i, ex.message)
+ assert_match(/base class: +TestSpys::FooBar/i, ex.message)
+ end
+
+ def test_cant_put_expectations_on_non_base_class_methods_unless_explicit
+ @spy.should_receive(:baz).explicitly.and_return(:bar)
+ @spy.baz
+ assert_spy_called @spy, :baz
+ end
+
+ def test_ok_to_use_explicit_even_when_its_not_needed
+ @spy.should_receive(:foo).explicitly.and_return(:bar)
+ @spy.foo
+ assert_spy_called @spy, :foo
+ end
+
+ def test_can_spy_on_partial_mocks
+ @foo = FooBar.new
+ @spy = flexmock(@foo)
+ @foo.should_receive(:foo => :baz)
+ result = @foo.foo
+ assert_equal :baz, result
+ assert_spy_called @foo, :foo
+ end
+
+ def test_can_spy_on_class_defined_methods
+ flexmock(FooBar).should_receive(:new).and_return(:dummy)
+ FooBar.new
+ assert_spy_called FooBar, :new
+ end
+
+ def test_can_spy_on_regular_mocks
+ mock = flexmock("regular mock")
+ mock.should_receive(:foo => :bar)
+ mock.foo
+ assert_spy_called mock, :foo
+ end
+end
diff --git a/test/symbol_extensions_test.rb b/test/symbol_extensions_test.rb
new file mode 100644
index 0000000..885253f
--- /dev/null
+++ b/test/symbol_extensions_test.rb
@@ -0,0 +1,8 @@
+require 'test/test_setup'
+
+class SymbolEtentensionsTest < Test::Unit::TestCase
+ def test_as_name_converts_appropriatly
+ method_name_class = self.class.instance_methods.first.class
+ assert_equal method_name_class, :some_name.flexmock_as_name.class
+ end
+end
diff --git a/test/test_class_extensions.rb b/test/test_class_extensions.rb
new file mode 100644
index 0000000..78edb51
--- /dev/null
+++ b/test/test_class_extensions.rb
@@ -0,0 +1,34 @@
+require 'test/test_setup'
+
+class ClassExtensionsTest < Test::Unit::TestCase
+
+ class Dog
+ def wag
+ end
+
+ def method_missing(sym, *args, &block)
+ if sym == :bark
+ :woof
+ else
+ super
+ end
+ end
+
+ def responds_to?(sym)
+ sym == :bark || super
+ end
+ end
+
+ def test_class_directly_defines_method
+ assert Dog.flexmock_defined?(:wag)
+ end
+
+ def test_class_indirectly_defines_method
+ assert ! Dog.flexmock_defined?(:bark)
+ end
+
+ def test_class_does_not_define_method
+ assert ! Dog.flexmock_defined?(:jump)
+ end
+
+end
diff --git a/test/test_setup.rb b/test/test_setup.rb
index ed46830..dce498b 100644
--- a/test/test_setup.rb
+++ b/test/test_setup.rb
@@ -13,7 +13,8 @@ class FlexMock
# Assertion helper used to assert validation failure. If a
# message is given, then the error message should match the
# expected error message.
- def assert_failure(message=nil)
+ def assert_failure(options={}, &block)
+ message = options[:message]
ex = assert_raises(assertion_failed_error) { yield }
if message
case message
@@ -26,5 +27,49 @@ class FlexMock
ex
end
+ # Similar to assert_failure, but assumes that a mock generated
+ # error object is return, so additional tests on the backtrace are
+ # added.
+ def assert_mock_failure(options={}, &block)
+ ex = assert_failure(options, &block)
+ file = eval("__FILE__", block.binding)
+ assert_matching_line(ex, file, options)
+ end
+
+ # Assert that there is a line matching file in the backtrace.
+ # Options are:
+ #
+ # deep: true -- matching line can be anywhere in backtrace,
+ # otherwise it must be the first.
+ #
+ # line: n -- Add a line number to the match
+ #
+ def assert_matching_line(ex, file, options)
+ line = options[:line]
+ search_all = options[:deep]
+ if line
+ loc_re = /#{Regexp.quote(file)}:#{line}/
+ else
+ loc_re = Regexp.compile(Regexp.quote(file))
+ end
+
+
+ if search_all
+ bts = ex.backtrace.join("\n")
+ assert_with_block("expected a backtrace line to match #{loc_re}\nBACKTRACE:\n#{bts}") {
+ ex.backtrace.any? { |bt| loc_re =~ bt }
+ }
+ else
+ assert_match(loc_re, ex.backtrace.first)
+ end
+
+ ex
+ end
+
+ def assert_with_block(msg=nil)
+ unless yield
+ assert(false, msg || "Expected block to yield true")
+ end
+ end
end
end
diff --git a/test/test_unit_integration/auto_test_unit_test.rb b/test/test_unit_integration/auto_test_unit_test.rb
index 4df2ad4..59adc64 100755
--- a/test/test_unit_integration/auto_test_unit_test.rb
+++ b/test/test_unit_integration/auto_test_unit_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -16,7 +16,13 @@ require "flexmock/test_unit"
class TestFlexmockTestUnit < Test::Unit::TestCase
def teardown
- super
+ failed = false
+ begin
+ super
+ rescue Exception => ex
+ failed = true
+ end
+ assert_equal @should_fail, failed, "Expected failed to be #{@should_fail}"
end
# This test should pass.
@@ -24,11 +30,13 @@ class TestFlexmockTestUnit < Test::Unit::TestCase
m = flexmock("mock")
m.should_receive(:hi).once
m.hi
+ @should_fail = false
end
# This test should fail during teardown.
def test_should_fail__mocks_are_auto_verified
m = flexmock("mock")
m.should_receive(:hi).once
+ @should_fail = true
end
end
diff --git a/test/test_unit_integration/minitest_teardown_test.rb b/test/test_unit_integration/minitest_teardown_test.rb
new file mode 100644
index 0000000..46e20a9
--- /dev/null
+++ b/test/test_unit_integration/minitest_teardown_test.rb
@@ -0,0 +1,14 @@
+require "minitest/autorun"
+require 'flexmock/test_unit'
+
+class SimpleTest < MiniTest::Unit::TestCase
+
+ # This validates that the minitest teardown method is properly
+ # aliased when using MiniTest.
+ #
+ # (see https://github.com/jimweirich/flexmock/issues/14).
+ #
+ def test_flexmock
+ flexmock()
+ end
+end
diff --git a/test/tu_integration_test.rb b/test/tu_integration_test.rb
index 7e36858..12ede67 100644
--- a/test/tu_integration_test.rb
+++ b/test/tu_integration_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
diff --git a/test/undefined_test.rb b/test/undefined_test.rb
index 273a1bd..e71cbc4 100644
--- a/test/undefined_test.rb
+++ b/test/undefined_test.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
#---
-# Copyright 2003-2011 by Jim Weirich (jim at weirichhouse.org).
+# Copyright 2003-2012 by Jim Weirich (jim.weirich at gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-flexmock.git
More information about the Pkg-ruby-extras-commits
mailing list