pax_global_header00006660000000000000000000000064146461505440014523gustar00rootroot0000000000000052 comment=e62fa61e086199f7777d70e85371525f6c2afe03 mocha-2.4.2/000077500000000000000000000000001464615054400126175ustar00rootroot00000000000000mocha-2.4.2/.circleci/000077500000000000000000000000001464615054400144525ustar00rootroot00000000000000mocha-2.4.2/.circleci/config.yml000066400000000000000000000055121464615054400164450ustar00rootroot00000000000000version: 2.1 jobs: build: parameters: docker-image: type: string gemfile: type: string docker: - image: << parameters.docker-image >> environment: MOCHA_OPTIONS=debug steps: - checkout - run: ruby --version - when: condition: equal: [ "jruby:latest", << parameters.docker-image >>] steps: - run: apt-get update - run: apt-get install -y git - run: gem --version - run: bundle --version - run: bundle install --gemfile=<< parameters.gemfile >> - when: condition: equal: [ "Gemfile", << parameters.gemfile >>] steps: - run: bundle exec rake test - when: condition: matches: pattern: ".*minitest.*" value: << parameters.gemfile >> steps: - run: MOCHA_RUN_INTEGRATION_TESTS=minitest bundle exec --gemfile=<< parameters.gemfile >> rake test - when: condition: matches: pattern: ".*test-unit.*" value: << parameters.gemfile >> steps: - run: MOCHA_RUN_INTEGRATION_TESTS=test-unit bundle exec --gemfile=<< parameters.gemfile >> rake test - when: condition: and: - equal: [ "ruby:latest", << parameters.docker-image >> ] - equal: [ "Gemfile", << parameters.gemfile >>] steps: - run: bundle exec rake test:performance - run: MOCHA_GENERATE_DOCS=1 bundle install --gemfile=<< parameters.gemfile >> - run: MOCHA_GENERATE_DOCS=1 rake yardoc lint: docker: - image: ruby:2.6 steps: - checkout - run: ruby --version - run: gem --version - run: bundle --version - run: bundle install --gemfile=Gemfile - run: bundle exec rake lint workflows: build-all: jobs: &all-jobs - lint - build: matrix: parameters: docker-image: - ruby:2.1 - ruby:2.2 - ruby:2.3 - ruby:2.4 - ruby:2.5 - ruby:2.6 - ruby:2.7 - ruby:3.0 - ruby:3.1 - ruby:3.2 - ruby:3.3 - ruby:latest - jruby:latest gemfile: - Gemfile - build: matrix: parameters: docker-image: - ruby:latest gemfile: - gemfiles/Gemfile.minitest.latest - gemfiles/Gemfile.test-unit.latest weekly: triggers: - schedule: cron: "0 3 * * 0" filters: branches: only: - main jobs: *all-jobs mocha-2.4.2/.gemtest000066400000000000000000000000001464615054400142560ustar00rootroot00000000000000mocha-2.4.2/.github/000077500000000000000000000000001464615054400141575ustar00rootroot00000000000000mocha-2.4.2/.github/FUNDING.yml000066400000000000000000000000231464615054400157670ustar00rootroot00000000000000github: floehopper mocha-2.4.2/.gitignore000066400000000000000000000000431464615054400146040ustar00rootroot00000000000000TODO Gemfile*.lock pkg tmp .yardoc mocha-2.4.2/.rubocop.yml000066400000000000000000000032411464615054400150710ustar00rootroot00000000000000inherit_from: .rubocop_todo.yml AllCops: TargetRubyVersion: 2.2 # closest to required_ruby_version of '>= 2.1' # Even the reference in the documentation suggests that you should prefer # `alias_method` vs `alias`, so I don't understand why that isn't the default. Style/Alias: EnforcedStyle: prefer_alias_method Style/Documentation: Enabled: false # Kernel#__dir__ has only been available since Ruby v2.0 Style/ExpandPathArguments: Enabled: false # I'm not keen on this cop, because it's easy to miss the conditional # I think the results are particularly unhelpful when Metrics/LineLength is big Style/IfUnlessModifier: Enabled: false # Lambda literal syntax has only been supported since Ruby v2.0 Style/Lambda: EnforcedStyle: lambda # Symbol array literal syntax has only been supported since Ruby v2.0 Style/SymbolArray: Enabled: false # I'm not keen on this cop, because it's easy to miss the while/until Style/WhileUntilModifier: Enabled: false # This recently introduced cop seems to have stirred up some controversy Style/AccessModifierDeclarations: Enabled: false # `Module#===` is useful in presence of objects such as mocks # that may have a `is_a?` implementation that lies. Style/CaseEquality: Enabled: false # This is useful when using `ExecutionPoint.current` to make tests more robust Style/Semicolon: Enabled: false # Enabling this cop results in an "Infinite loop detected" exception Layout/AccessModifierIndentation: Enabled: false # Allow long comment lines, e.g. YARD documentation Metrics/LineLength: IgnoredPatterns: ['\A\s*#'] # It's not possible to set TargetRubyVersion to Ruby < v2.2 Gemspec/RequiredRubyVersion: Enabled: false mocha-2.4.2/.rubocop_todo.yml000066400000000000000000000014541464615054400161220ustar00rootroot00000000000000# This configuration was generated by # `rubocop --auto-gen-config` # on 2019-11-16 18:15:36 +0000 using RuboCop version 0.58.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. # Offense count: 57 Metrics/AbcSize: Max: 26 # Offense count: 23 # Configuration parameters: CountComments. Metrics/ClassLength: Max: 366 # Offense count: 172 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 31 # Offense count: 545 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: Max: 180 mocha-2.4.2/.yardopts000066400000000000000000000010571464615054400144700ustar00rootroot00000000000000--output-dir docs --no-private lib/mocha/api.rb lib/mocha/hooks.rb lib/mocha/mock.rb lib/mocha/expectation.rb lib/mocha/object_methods.rb lib/mocha/class_methods.rb lib/mocha/parameter_matchers.rb lib/mocha/parameter_matchers lib/mocha/state_machine.rb lib/mocha/sequence.rb lib/mocha/configuration.rb lib/mocha/expectation_error_factory.rb lib/mocha/expectation_error.rb lib/mocha/stubbing_error.rb lib/mocha/unexpected_invocation.rb lib/mocha/integration/test_unit/adapter.rb lib/mocha/integration/minitest/adapter.rb - RELEASE.md COPYING.md MIT-LICENSE.md mocha-2.4.2/CONTRIBUTING.md000066400000000000000000000005451464615054400150540ustar00rootroot00000000000000* Pull requests are welcomed. * Fork the repository. * Make your changes in a branch. * Add/modify/remove tests as appropriate. * Open a pull request based on a branch on your fork. * Wait for your pull request build to pass on [Circle CI](https://app.circleci.com/pipelines/github/freerange/mocha). * Pull requests with failing tests will not be accepted. mocha-2.4.2/COPYING.md000066400000000000000000000003271464615054400142530ustar00rootroot00000000000000Copyright James Mead 2006 You may use, copy and redistribute this library under the same terms as [Ruby itself](https://www.ruby-lang.org/en/about/license.txt) or under the [MIT license](https://mit-license.org/). mocha-2.4.2/Gemfile000066400000000000000000000010731464615054400141130ustar00rootroot00000000000000source 'https://rubygems.org' gemspec # rubocop:disable Bundler/DuplicatedGem if RUBY_VERSION < '2.2' gem 'rake', '~> 12.3.3' else gem 'rake' end # rubocop:enable Bundler/DuplicatedGem gem 'introspection', '~> 0.0.1' # Avoid breaking change in psych v4 (https://bugs.ruby-lang.org/issues/17866) if RUBY_VERSION >= '3.1.0' gem 'psych', '< 4' end if RUBY_VERSION >= '2.2.0' # No test libraries in standard library gem 'minitest' end if RUBY_VERSION >= '2.2.0' gem 'rubocop', '<= 0.58.2' end if ENV['MOCHA_GENERATE_DOCS'] gem 'redcarpet' gem 'yard' end mocha-2.4.2/MIT-LICENSE.md000066400000000000000000000020361464615054400146530ustar00rootroot00000000000000Copyright (c) 2006 James Mead Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. mocha-2.4.2/README.md000066400000000000000000000320751464615054400141050ustar00rootroot00000000000000## Mocha [![CircleCI status of freerange/mocha](https://circleci.com/gh/freerange/mocha.svg?style=shield)](https://app.circleci.com/pipelines/github/freerange/mocha) [![Gem Version](https://badge.fury.io/rb/mocha.svg)](http://badge.fury.io/rb/mocha) ### Description * A Ruby library for [mocking](http://xunitpatterns.com/Mock%20Object.html) and [stubbing](http://xunitpatterns.com/Test%20Stub.html) - but deliberately not (yet) [faking](http://xunitpatterns.com/Fake%20Object.html) or [spying](http://xunitpatterns.com/Test%20Spy.html). * A unified, simple and readable syntax for both full & partial mocking. * Built-in support for Minitest and Test::Unit. * Supported by many other test frameworks. ### Intended Usage Mocha is intended to be used in unit tests for the [Mock Object](http://xunitpatterns.com/Mock%20Object.html) or [Test Stub](http://xunitpatterns.com/Test%20Stub.html) types of [Test Double](http://xunitpatterns.com/Test%20Double.html), not the [Fake Object](http://xunitpatterns.com/Fake%20Object.html) or [Test Spy](http://xunitpatterns.com/Test%20Spy.html) types. Although it would be possible to extend Mocha to allow the implementation of fakes and spies, we have chosen to keep it focused on mocks and stubs. ### Installation #### Gem Install the latest version of the gem with the following command... $ gem install mocha Note: If you are intending to use Mocha with Test::Unit or Minitest, you should only setup Mocha *after* loading the relevant test library... ##### Test::Unit ```ruby require 'rubygems' gem 'mocha' require 'test/unit' require 'mocha/test_unit' ``` ##### Minitest ```ruby require 'rubygems' gem 'mocha' require 'minitest/autorun' require 'mocha/minitest' ``` #### Bundler If you're using Bundler, include Mocha in the `Gemfile` and then setup Mocha later once you know the test library has been loaded... ##### Test::Unit ```ruby # Gemfile gem 'mocha' # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'` require 'test/unit' require 'mocha/test_unit' ``` ##### Minitest ```ruby # Gemfile gem 'mocha' # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'` require 'minitest/autorun' require 'mocha/minitest' ``` ##### RSpec RSpec includes a mocha adapter. Just tell RSpec you want to mock with `:mocha`: ```ruby # Gemfile in Rails app gem 'mocha' # Within `spec/spec_helper.rb` RSpec.configure do |config| config.mock_with :mocha end ``` Note: There is no need to use a require statement to setup Mocha; RSpec does this itself. ##### Cucumber ```ruby # In e.g. features/support/mocha.rb require 'mocha/api' World(Mocha::API) Around do |scenario, block| begin mocha_setup block.call mocha_verify ensure mocha_teardown end end ``` #### Rails If you're loading Mocha using Bundler within a Rails application, you should setup Mocha manually e.g. at the bottom of your `test_helper.rb`. ##### Minitest Note that since Rails v4 (at least), `ActiveSupport::TestCase` has inherited from `Minitest::Test` or its earlier equivalents. Thus unless you are *explicitly* using Test::Unit, you are likely to be using Minitest. ```ruby # Gemfile in Rails app gem 'mocha' # At bottom of test_helper.rb (or at least after `require 'rails/test_help'`) require 'mocha/minitest' ``` ##### Other Test Framework Follow the instructions for the relevant test framework in the [Bundler](#bundler) section, but ensure that the relevant Mocha file (`mocha/minitest`, `mocha/test_unit`, or `mocha/api`) is required **after** the test framework has been loaded, e.g. at the bottom of `test_helper.rb` or `spec_helper.rb`, or at least after `rails/test_help` has been required. #### Known Issues * In Mocha v1.10.0 an undocumented feature of `API#mock`, `API#stub` & `API#stub_everything` was changed. Previously when these methods were passed a single symbol, they returned a mock object that responded to the method identified by the symbol. Now Passing a single symbol is equivalent to passing a single string, i.e. it now defines the 'name' of the mock object. * In Mocha v1.2.0 there is a scenario where stubbing a class method originally defined in a module hangs the Ruby interpreter due to [a bug in Ruby v2.3.1](https://bugs.ruby-lang.org/issues/12832). See #272. This was fixed in Mocha v1.2.1. * Since v1.1.0 Mocha has used prepended modules internally for stubbing methods. There is [an obscure Ruby bug](https://bugs.ruby-lang.org/issues/12876) in many (but not all) versions of Ruby between v2.0 & v2.3 which under certain circumstances may cause your Ruby interpreter to hang. See the Ruby bug report for more details. The bug has been fixed in Ruby v2.3.3 & v2.4.0. * Stubbing an aliased class method, where the original method is defined in a module that's used to `extend` the class doesn't work in Ruby 1.8.x. See stub_method_defined_on_module_and_aliased_test.rb for an example of this behaviour. * 0.13.x versions cause a harmless, but annoying, deprecation warning when used with Rails 3.2.0-3.2.12, 3.1.0-3.1.10 & 3.0.0-3.0.19. * 0.11.x versions don't work with Rails 3.2.13 (`TypeError: superclass mismatch for class ExpectationError`). See #115. * Versions 0.10.2, 0.10.3 & 0.11.0 of the Mocha gem were broken. Please do not use these versions. ### Usage #### Quick Start ```ruby require 'test/unit' require 'mocha/test_unit' class MiscExampleTest < Test::Unit::TestCase def test_mocking_a_class_method product = Product.new Product.expects(:find).with(1).returns(product) assert_equal product, Product.find(1) end def test_mocking_an_instance_method_on_a_real_object product = Product.new product.expects(:save).returns(true) assert product.save end def test_stubbing_instance_methods_on_real_objects prices = [stub(pence: 1000), stub(pence: 2000)] product = Product.new product.stubs(:prices).returns(prices) assert_equal [1000, 2000], product.prices.collect {|p| p.pence} end def test_stubbing_an_instance_method_on_all_instances_of_a_class Product.any_instance.stubs(:name).returns('stubbed_name') product = Product.new assert_equal 'stubbed_name', product.name end def test_traditional_mocking object = mock('object') object.expects(:expected_method).with(:p1, :p2).returns(:result) assert_equal :result, object.expected_method(:p1, :p2) end def test_shortcuts object = stub(method1: :result1, method2: :result2) assert_equal :result1, object.method1 assert_equal :result2, object.method2 end end ``` #### Mock Objects ```ruby class Enterprise def initialize(dilithium) @dilithium = dilithium end def go(warp_factor) warp_factor.times { @dilithium.nuke(:anti_matter) } end end require 'test/unit' require 'mocha/test_unit' class EnterpriseTest < Test::Unit::TestCase def test_should_boldly_go dilithium = mock() dilithium.expects(:nuke).with(:anti_matter).at_least_once # auto-verified at end of test enterprise = Enterprise.new(dilithium) enterprise.go(2) end end ``` #### Partial Mocking ```ruby class Order attr_accessor :shipped_on def total_cost line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost end def total_weight line_items.inject(0) { |total, line_item| total + line_item.weight } end def shipping_cost total_weight * 5 + 10 end class << self def find_all # Database.connection.execute('select * from orders... end def number_shipped_since(date) find_all.select { |order| order.shipped_on > date }.length end def unshipped_value find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost } end end end require 'test/unit' require 'mocha/test_unit' class OrderTest < Test::Unit::TestCase # illustrates stubbing instance method def test_should_calculate_shipping_cost_based_on_total_weight order = Order.new order.stubs(:total_weight).returns(10) assert_equal 60, order.shipping_cost end # illustrates stubbing class method def test_should_count_number_of_orders_shipped_after_specified_date now = Time.now; week_in_secs = 7 * 24 * 60 * 60 order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs Order.stubs(:find_all).returns([order_1, order_2]) assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs) end # illustrates stubbing instance method for all instances of a class def test_should_calculate_value_of_unshipped_orders Order.stubs(:find_all).returns([Order.new, Order.new, Order.new]) Order.any_instance.stubs(:shipped_on).returns(nil) Order.any_instance.stubs(:total_cost).returns(10) assert_equal 30, Order.unshipped_value end end ``` ### Thread safety Mocha currently *does not* attempt to be thread-safe. #### Can I test multi-threaded code with Mocha? The short answer is no. In multi-threaded code Mocha exceptions may be raised in a thread other than the one which is running the test and thus a Mocha exception may not be correctly intercepted by Mocha exception handling code. #### Can I run my tests across multiple threads? Maybe, but probably not. Partial mocking changes the state of objects in the `ObjectSpace` which is shared across all threads in the Ruby process and this access to what is effectively global state is not synchronized. So, for example, if two tests are running concurrently and one uses `#any_instance` to modify a class, both tests will see those changes immediately. ### Expectation matching / invocation order Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The `Expectation#stubs` method is syntactic sugar to make the intent of the test more explicit. When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations. See the [documentation](https://mocha.jamesmead.org/Mocha/Mock.html) for `Mocha::Mock` for further details. ### Configuration If you want, Mocha can generate a warning or raise an exception when: * stubbing a method unnecessarily * stubbing method on a non-mock object * stubbing a non-existent method * stubbing a non-public method See the [documentation](https://mocha.jamesmead.org/Mocha/Configuration.html) for `Mocha::Configuration` for further details. ##### MOCHA_OPTIONS `MOCHA_OPTIONS` is an environment variable whose value can be set to a comma-separated list, so that we can specify multiple options e.g. `MOCHA_OPTIONS=debug,use_test_unit_gem`. Only the following values are currently recognized and have an effect: * `debug`: Enables a debug mode which will output backtraces for each deprecation warning. This is useful for finding where in the test suite the deprecated calls are. ### Semantic versioning * Every effort is made to comply with [semantic versioning](https://semver.org/). * However, this only applies to the behaviour documented in the public API. * The documented public API does *not* include the content or format of messsages displayed to the user, e.g. assertion failure messages. ### Useful Links * [Official Documentation](https://mocha.jamesmead.org) * [Source Code](http://github.com/freerange/mocha) * [Mailing List](http://groups.google.com/group/mocha-developer) * [James Mead's Blog](http://jamesmead.org/blog/) * [An Introduction To Mock Objects In Ruby](http://jamesmead.org/talks/2007-07-09-introduction-to-mock-objects-in-ruby-at-lrug/) * [Mocks Aren't Stubs](http://martinfowler.com/articles/mocksArentStubs.html) * [Growing Object-Oriented Software Guided By Tests](http://www.growing-object-oriented-software.com/) * [Mock Roles Not Objects](http://www.jmock.org/oopsla2004.pdf) * [jMock](http://www.jmock.org/) ### Contributors See this [list of contributors](https://github.com/freerange/mocha/graphs/contributors). ### Releasing a new version * Update the RELEASE.md file with a summary of changes * Bump the version in `lib/mocha/version.rb` * Commit & push to GitHub * Check CircleCI build is passing - https://app.circleci.com/pipelines/github/freerange/mocha * Generate documentation: ```bash $ MOCHA_GENERATE_DOCS=true bundle install $ MOCHA_GENERATE_DOCS=true rake generate_docs ``` * Commit documentation & push to GitHub * Sign in to rubygems.org and find API key - https://rubygems.org/profile/edit ```bash $ curl -u -H 'OTP:' https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials ``` * Release gem to Rubygems: ```bash $ rake release [runs tests] mocha 1.2.0 built to pkg/mocha-1.2.0.gem. Tagged v1.2.0. Pushed git commits and tags. Pushed mocha 1.2.0 to rubygems.org. ``` ### History Mocha was initially harvested from projects at [Reevoo](http://www.reevoo.com/). It's syntax is heavily based on that of [jMock](http://www.jmock.org). ### License © Copyright James Mead 2006 You may use, copy and redistribute this library under the same terms as [Ruby itself](https://www.ruby-lang.org/en/about/license.txt) or under the [MIT license](https://mit-license.org/). mocha-2.4.2/RELEASE.md000066400000000000000000001706361464615054400142360ustar00rootroot00000000000000# Release Notes ## 2.4.2 ### External changes * Don't trust `Object#is_a?` in presence of mock objects (#656) - thanks to @casperisfine ## 2.4.1 ### External changes * Fix regression in matchers when used with keyword arguments (#654 & #655) - thanks to @ElvinEfendi for reporting ### Internal changes * Reduce duplication & consolidate `#to_matcher` method definitions (600ee2aa, e9de64e4, #655) * Change `#to_matcher` method to use keyword arguments (3b60b7df, #655) ## 2.4.0 ### External changes * Improve rendering of keyword arguments (#652) - thanks to @casperisfine ### Internal changes * Improvements to `#mocha_inspect` unit tests (#650) ## 2.3.0 ### External changes * Fix nested parameter matching for keyword arguments (f94e2504, #648) - thanks to @CodingAnarchy for reporting ## 2.2.0 ### External changes * Support multiple methods in `responds_with` matcher (f086b7e4, #578) - thanks to @vlad-pisanov for the suggestion * Add block syntax for sequences (93fdffd, #61) * Improve sequence failure message (0800c6ff, #60) * Drop support for Ruby v2.0 (85848fb0, #642) * Include the original test name in expired stub error messages (ca3ff8eb, #641, #642) - thanks to @casperisfine * Avoid rubocop directive ending up in YARD docs (2a9ee81a) * Update docs to fix those for `Mock#method_missing` (cee0bad6) * Reinstate missing CNAME for GitHub Pages site (da67bb0d) * Use Ruby v1.9 Hash syntax in docs (6de20726, #625) * Add missing YARD tag for API#sequence name param (343c5979) * Add missing YARD tag for API#states name param (f798df83) ### Internal changes * Tidy up Minitest vs MiniTest references (#626, #614, #615) - thanks to @zenspider & @Maimer for their help * Add Ruby v3.3 to CI build matrix (ce31b544) ## 2.1.0 ### External changes * Fix compatibility with Minitest (#614) - thanks to @kyrofa & @manewitz for reporting and to @zenspider for his input ### Internal changes * Update URLs for links to Ruby & MIT licenses (d6470af4) ## 2.0.4 ### Internal changes * Update `README.md` (e8c21e1b) ## 2.0.3 ### External changes * Fix `BacktraceFilter` to handle special characters (e242033f, #592) - thanks to @casperisfine ### Internal changes * Add Ruby v3.1 to the CircleCI build (3e460489) * DRY up `regexp_matches` test (ae9fed4a) * Fix regexp_matches tests in Ruby v3.2 (26b106a5, #590) * Use Ruby 1.9 hash syntax (8bc0ad2f, #598, #537) - thanks to @herwinw * Simplify storage of `MOCHA_OPTIONS` (b70507a1, #600) - thanks to @herwinw * Pin JRuby to v9.3.9.0 in CircleCI builds (b8e6d064, #591) * Rubocop: enable Style/FormatStringToken cop (089a688e, #603) - thanks to @herwinw * Remove Ruby version check from `RespondsLikeTest` (21583129) * Add Ruby v3.2 to CircleCI build (f7e17636, #601) * Use Ruby v2.6 vs v2.2 to run lint CI job (af40b7db) * Pin yard version to v0.9.28 to avoid `ArgumentError` (12f1eef7) * Revert "Pin JRuby to v9.3.9.0 in CircleCI builds" (4f5bb2f0, #591) * Remove invalid CircleCI token from badge URL (7078e76a) * Revert "Pin yard version to v0.9.28 to avoid ArgumentError" (7c6c10c5, #609) * Remove Google Analytics tracking code (2279c49d, #612) * Update `MIT-LICENSE.md` (48162b4e) * Update `COPYING.md` (f3152376) ## 2.0.2 ### External changes * Fix regression in `Mock#responds_like` behaviour - thanks to @adrianna-chang-shopify for reporting (#580,#583,ba4d619e) ## 2.0.1 ### External changes * Fix `LoadError` when using v2.0.0 with Ruby < v2.7 by moving declaration of runtime dependency on `ruby2_keywords` gem from `Gemfile` to `mocha.gemspec` - thanks to @mishina2228 for reporting (#581, #582, cdeb0356) ## 2.0.0 ### External changes * Remove support for Ruby v1.9 - thanks to @wasabigeek (#552) * Support strict keyword argument matching - see docs for `Expectation#with` & `Configuration#strict_keyword_argument_matching=` - thanks to @wasabigeek (#446,#535,#544,#562) * Deprecate `Hash` args that don't strictly match (#563,981c31be) * Drop support for older versions of test-unit - gem versions of test-unit earlier than v2.5.1 and versions of test-unit from the Ruby v1.8 standard library are no longer supported (#540,969f4845) * Drop support for older versions of minitest - versions of minitest earlier than v3.3.0 are no longer supported (#541,ca69dc9e) * Remove deprecated `mocha/setup.rb` mechanism (642a0ff4) * Add missing docs for `API#stub` parameter (257b4cb4) * Remove optional reinstatement of v1.9 behaviour (#436,#438,#569,1473ee25) * Remove deprecated methods in `Configuration` (#421,e7ff7528) * Fail fast when mock receives invocations in another test (#440,#442,cb054d59) * Improve docs re using matchers in `Expectation#with` (da7237cd) * Expand `Expectation#with` docs re keyword arguments (fed6808d) * Improve docs for `strict_keyword_argument_matching` (8d8f881d) * Remove deprecated Rails plugin `init.rb` file (1c617175) * Improve strict keyword argument matching deprecation warning by including the source location of the stub definition (77c0d4cc) * Add README section re semantic versioning (00758246) ### Internal changes * Separate linting from tests in terms of Rake tasks & CircleCI jobs - thanks to @wasabigeek (#556) * Remove tests specific to Ruby v1.8 behaviour (46fca7ac, 3b369e99) * Multi-line rubocop disable in `Mock#method_missing` (af2194c4) * Remove unused arg for `HashMethods#mocha_inspect` (4f59e27f) * Improve test runner assertions - failure vs error (eec7200a) * Improve test coverage of `PositionalOrKeywordHash` (c294fe70) * More consistent Test::Unit & Minitest integration (27dd3817) * Remove redundant `require` statements (d82218a8,fa17b114) * Add missing `require` statement (73493761) * Disable Style/Semicolon cop globally (8cd0b705) ## 1.16.1 ### External changes * Fix regression in `Mock#responds_like` behaviour - thanks to @adrianna-chang-shopify for reporting (#580,#583,77af2af1) ## 1.16.0 ### External changes * Default `Configuration#reinstate_undocumented_behaviour_from_v1_9=` to `false` (6fcaf947) * Deprecate `Configuration#reinstate_undocumented_behaviour_from_v1_9=` (a797c5fd) ### Internal changes * Remove redundant deprecation disabling in MockTest (dc8ca969) ## 1.15.1 ### External changes * Fix regression in `Mock#responds_like` behaviour - thanks to @adrianna-chang-shopify for reporting (#580,#583,c586a08c) ## 1.15.0 ### External changes * Fix examples using mock constructor with block (1cc17667) * Add another example for `API#sequence` (b7a7d233, #59) * Remove support for Ruby v1.8 (ddb5d672) * Deprecate support for Ruby versions earlier than v2.0 - thanks to @wasabigeek (#553, #555) ### Internal changes * Update instructions for obtaining Rubygems API key (ed9c040a) * Consistent definitions for `respond_to?` methods (#533) * Run test tasks before release tasks (92a1bc6e, #447) * Fix test:performance Rake task (#538, #539) * Tidying following removal of support for Ruby v1.8 - thanks to @nitishr (#542) * Remove `ParametersMatcher` from `Invocation#call_description` - thanks to @wasabigeek (#543) * Remove unnecessary splatting in Invocation - thanks to @wasabigeek (#549) * Extract `handle_method_call` from `method_missing` - thanks to @wasabigeek (#550) ## 1.14.0 ### External changes * Mock#expects,#stubs should return last expectation - thanks to @vlad-pisanov for #524 (b6b637db) ### Internal changes * Avoid breaking change in psych v4 in ruby v3.1 (08b9f4ca) * Remove broken Dependabot badge from README (d446657a) * Add Ruby 3.0 to the CI matrix - thanks to @mishina2228 for #526 (65bc626e) * Move development dependencies from gemspec to Gemfile - thanks to @mishina2228 for #527 (dd127f7b) ## 1.13.0 ### External changes * Add `ParameterMatchers#has_keys` - thanks to @cstyles for #512 (18d8104) * Fix misleading exception message in `ParameterMatchers#has_entry` - thanks to @cstyles for #513 (9c4ef13) * Only add dependency on rubocop if we're actually going to use it (f2f879f) * Fix rake dependency constraints for older Ruby versions (7ce5f29) ### Internal changes * Check documentation can be generated as part of CircleCI build (b30d9a9) * Add --fail-on-warning option to yard rake task (53a6ee3) * Add a weekly scheduled build to the CircleCI build (fd2a4c6) * Add Ruby v1.8 to the CircleCI build matrix (818ca03) * Add API token to fix CircleCI badge in README (607c5aa) * Provide wrapped option for #mocha_inspect on hashes & arrays (d8f44bc) * Use CircleCI instead of TravisCI for automated builds (c98c6ec) * Switch to newer default Travis CI build env (c78f75c) * Use latest Ruby versions in Travis CI builds (9e0043a) * Use latest JRuby v9.2.18 in Travis CI builds (8c99a1b) * Use consistent JRuby versions in Travis CI builds (0f849aa) * Use more recent version of JRuby in Travis CI build matrix (58653db) ## 1.12.0 ### External changes * Various improvements to README inspired by #207 and #390 - thanks to @nitishr for his work on #390 (fed0eee6) * Improve documentation related to `StateMachine` classes - thanks to @nitishr (#425 & #427) * Fix regression in cardinality introduced in v1.10.0 (59454a8) and reported in #473 - thanks to @srvance for reporting and @nitishr for fixing (#474) * Fix documentation for `Mocha::Expectation#when` - thanks to @olleolleolle (b4f59daa & #477) * Remove `Mocha::Mock#respond_to?` from documentation - thanks to @nitishr (#480) * Improvements to documentation for `Expectation#yields` & `#multiple_yields` - thanks to @andyw8 for reporting in #495 (1b6571c) * Remove documentation & tests from gem to reduce its size by over 50% - thanks to @gabetax (#500) * Update documentation to point to travis-ci.com instead of travis-ci.org ### Internal changes * Refactor `StateMachine`-related classes - thanks to @nitishr (#425 & #427) * Remove redundant test - thanks to @nitishr (8e4f1a7c) * Add Ruby 2.7 to Travis CI matrix - thanks to @bastelfreak (fc5ea2f2) * Simplify `Mockery` - thanks to @nitishr (#449) * Update Travis CI badge to point to main vs master branch (bd8028f8) * Generate docs using newer version of yard (v0.9.25) (c619afac) * Manually upgrade jquery in docs from v1.7.1 -> v1.9.0 to fix CVE-2017-16011 (211098a5, dd5eeedb & 1b76e4d5; also see #492) * Remove reference to non-existent jquery source map to fix error in Chrome developer tools (20156555) * Temporarily ignore Ruby v1.8.7 build failures (e5b9feef) ## 1.11.2 ### External changes * Fix regression introduced in v1.10.0 that meant `Object#inspect` was called unnecessarily (368abd98) * Warn when mock object receives invocations in another test - thanks to @nitishr (#442) * Avoid rubocop comments appearing in YARD-generated docs (d8019eed) ### Internal changes * Replace `StubbedMethod#original_method` & `#original_visibility` attribute reader methods with instance variables - thanks to @nitishr (d917f332) * Set up `MochaExampleTest` & `StubbaExampleTest` as acceptance tests - thanks to @nitishr (4881cc58) * Delete unused `PrettyParameters` class - thanks to @nitishr (314ea922) ## 1.11.1 ### External changes * The `reinstate_undocumented_behaviour_from_v1_9` configuration option is now enabled by default to give people a chance to see and fix the relevant deprecation warnings before the behaviour is removed in a future release (b91b1c9e) ## 1.11.0 ### External changes * Add `Expectation#with_block_given` & `Expectation#with_no_block_given` (#441). * Allows non-deprecated solution for #382. Thanks to @yemartin for reporting and to @techbelly & @nitishr for feedback. * Fix issue with non-Array arguments passed to `Expectation#multiple_yields` (#444). * The undocumented behaviour is now properly supported and documented. ### Internal changes * Move static YARD options from Rake task to `.yardopts` file - thanks to @nitishr (#429) * Simplify implementation of yielding functionality - thanks to @nitishr (#439) * Add missing require statement to `acceptance_test_helper.rb` (1070fc02) * Add some baseline acceptance tests for yielding behaviour (c2cac911) * Display a sponsor button on GitHub repo page (9fc5911b) * Use new Deprecation.warning behaviour in `Invocation#call` (932d1166) ## 1.10.2 * Optionally reinstate undocumented behaviour from v1.9. This introduces a new configuration option (`reinstate_undocumented_behaviour_from_v1_9`) to reinstate a couple of bits of undocumented behaviour from v1.9 which were changed in v1.10 without any prior deprecation warning (#438): * The behaviour of `API#mock`, `API#stub` and `API#stub_everything` when called with a symbol as the first argument. * The behaviour of `Expectation#yields` and `Expectation#multiple_yields` when the stubbed method is called without a block. ## 1.10.1 * Ensure ObjectMethods & ClassMethods included when API extended (43778756) * Fix regression in `any_instance` stubbing of methods on object which has an implementation of `#respond_to?` that depends on the object's internal state - thanks to @rafaelfranca for reporting & @nitishr for fixing (#432, #434, 469d4b17) ## 1.10.0 * Improve deprecation warning when requiring 'mocha/setup' (388f44d7) * Add documentation for Cucumber integration (13ab797b) * Add documentation about an undocumented feature of `API#mock`, `API#stub` & `API#stub_everything` being changed (7ed2e4e7, d30c1717) ## 1.10.0.beta.1 * Hide `ClassMethods#method_visibility` & `#method_exists?` methods to avoid clash with Rails (#428) ## 1.10.0.alpha ### External changes * Remove dependency on metaclass gem (#49, #365) * Accept symbol (as well as a string) as mock/stub name - thanks to @nitishr (#347, #353, #377) * More realistic examples in documentation for `Expectation#yields` and `#multiple_yields` - thanks to @nitishr (#352, #383) * Improve documentation for `Mock#responds_like` & `#responds_like_instance_of` - thanks to @nitishr (#337, #384) * Make `Expectation#yields` & `Expectation#multiple_yields` fail when the caller of the stubbed method does not provide a block. This is a change to an undocumented aspect of the public API's behaviour. If this causes your tests to fail, then fix it by removing the unnecessary call to `Expectation#yields` or `Expectation#multiple_yields` - thanks to @nitishr (#382) * Document `MOCHA_OPTIONS` in README - thanks to @nitishr (#311, #386) * Add documentation to explain how Mocha is intended to be used - thanks to @nitishr (#330, #385) * Deprecation warning if integration using 'mocha/test_unit' or 'mocha/minitest' fails - thanks to @nitishr (#229, #389, c6032d0b) * Require at least one specified sequence for `Expectation#in_sequence` - thanks to @nitishr (#79, #396, 9020248a) * Make signatures of `Mock#unstub` & `ObjectMethods#unstub` consistent - thanks to @nitishr (#397, f04d437) * Deprecate requiring 'mocha/setup' (36adf880) * Optionally display matching invocations alongside expectations - thanks to @nitishr (#178, #394, 00f0540, #410) * Put deprecations into effect (#400, #418): * Remove deprecated 'mocha_standalone.rb' & 'mocha/standalone.rb' * Fail fast if no test library loaded * Removed optional block for `Mocha::API#mock`, `#stub` & `#stub_everything` * Remove deprecated `ParameterMatchers#has_equivalent_query_string` method * Remove deprecated 'mocha/mini_test.rb' * Fix typo in docs for `Mocha::Configuration.prevent` (266ce71c) * New-style configuration (see documentation for `Mocha::Configuration`) (#407, #421) * Deprecate support for Ruby versions earlier than v1.9 (#325, c5f8496d) * Deprecate support for versions of test-unit & minitest which need monkey-patching (a34e1a88) * Deprecate old-style Rails plugin (#403, 2df77134) * Documentation fixes & improvements which also fix YARD warnings (472d5416, a2c0d64a) ### Internal changes * Pin minitest to v5.11.3 for Ruby v1.8.7 to fix build; minitest no longer supports Ruby v1.8.7 (4a0a580) * Upgrade JRuby to v9.2.8.0 in Travis CI builds (aa29b3f) * Only run rubocop for MRI Ruby versions & non-integration test builds (8f1c6af) * Reduce duplication in any instance method class - thanks to @nitishr (#378) * Simplify `AnyInstanceMethod`, `ClassMethod`, `InstanceMethod`, `ModuleMethod` class hierarchy - thanks to @nitishr (#381) * Simplify `ClassMethods#method_exists?` & `ObjectMethods#method_exists?` making them consistent - thanks to @nitishr (#270, #362, #370) * Don't override definition of `singleton_class` in `ClassMethods` - thanks to @nitishr (#391, #392) * Do not include 'method_definer' methods into all objects (#268, #402) * Distinguish different `ObjectMethods` modules (#268, #404) * Pass invocation to expectation list methods - thanks to @nitishr (#408, #409, #411) * Consistently use `assert_raises` - thanks to @nitishr (#405, #412, a66b7bed) * Update Ruby & JRuby versions in Travis CI config (18cb1a93, eb061c53) * Rubocop improvements (aa16ea67...6f4db70b, 2a1240e6...e95716ae) * Fix inconsistency in CardinalityTest (aa10e0a8) * Fix test failures on Mac OSX Catalina - thanks to @nitishr (#413, #417, #419, 8a0f2535) * Remove default argument in `Expectation#invoke` - thanks to @nitishr (#414, #420) ## 1.9.0 * Add TruffleRuby to Travis CI build matrix - thanks to @deepj (#354) * Explicitly set Travis CI OS to Ubuntu Trusty 14.04 (ded1fa45) * Expand explanation of thread-safety concerns - thanks to @techbelly (#357) * Refactor class method and any instance method - thanks to @chrisroos (#358) * Rely on default bundler version in Travis CI builds (3352e9c5) * Fix local build-matrix script (11abe231) * No need to install latest bundler in build-matrix script (8247a894) ## 1.8.0 * Constrain rubocop version to avoid breaking Travis CI builds (05e507f5) * Avoid calling Kernel#format from ObjectMethods#mocha_inspect - thanks to @hoffmanilya (#345) * Fix build matrix script (#346) * Avoid deprecation warning in gemspec (4976e0bc) * Removed link to documentation translation (ef428ea2) * Don't use the new bundler v2 in builds (683ded9b) * Moved documentation from https://gofreerange.com/mocha/docs to https://mocha.jamesmead.org/ [683ded...a17fde](https://github.com/freerange/mocha/compare/683ded...a17fde) ## 1.7.0 * Update Ruby & JRuby versions in Travis CI config (9bf55631 & 3883af7e) * Simplify gemspec (63744f86) * Add rubocop and fix most cop violations (#341) * Use Kernel#warn for deprecations - thanks to @etiennebarrie (#333, 196970a) ## 1.6.0 * Fix subtle bug in setting correct visibility of stubbed module methods on `Kernel` or `Object` - thanks to @chrisroos (#295) * Avoid mocks for partial mocking leaking into subsequent tests - thanks to @skliew for reporting (#331) * Remove OpenCollective badge, backers & sponsors (a283a079) * Change gem version badge to SVG format and add SemVer stability badge - thanks to @greysteil (#335) * Improve documentation for Configuration (#236) ## 1.5.0 * Prevent use of Mocha outside the context of a test/example - thanks to @andyw8 & @lzap (#327) ## 1.4.0 * Fix deprecation warning for `assert_nil` in `ClassMethodTest` (#308 & #309) * Display file and line number in deprecation warning - thanks to @chrisarcand (#310, #312 & #313) * Rename `mocha/mini_test.rb` to `mocha/minitest.rb` - thanks to @grosser (#320 & #322) * Fix warning when delegating to mock in Ruby 2.4 - thanks to @tjvc (#321 & #323) * Updates to Travis CI configuration ([73af600..9732726](https://github.com/freerange/mocha/compare/73af600...9732726) & 0426e5e) ## 1.3.0 * Ensure all tests run individually - thanks to @chrisroos (#267) * Update Travis CI build status badge to show master branch status (#264) * Correct RSpec section of the README - thanks to @myronmarston (0cc039c8) * Fix pretty printing of quotes in `String#mocha_inspect` (#215 & #223) * Add release instructions to README - thanks to @chrisroos (70a5febd & 3c664df7) * Require at least Ruby v1.8.7 in gemspec - thanks to @knappe (3e20be8e) * Remove redundant InstanceMethod#method_exists? - thanks to @chrisroos (8f58eddf) * Reduce risk of hitting bug 12832 in Ruby v2.3 - thanks to @chrisroos (#277 & eca7560c) * Fix JRuby build - thanks to @headius (jruby/jruby#4250) & @chrisroos (#274) * Add latest stable version of JRuby to Travis CI build matrix (#288) * Fix Ruby v1.8.7 builds on Travis CI (928b5a40 & 460dce5b) * Deprecate passing block to mock object constructor (#290) * Add a known issue to README for Ruby bug 12876 (#276) * Add Ruby 2.4 and ruby-head to Travis CI build matrix - thanks to @junaruga (#297) * Fix `Mocha::ParameterMatchers#includes` for `Array` values - thanks to @timcraft (#302) * Use faster container-based virtual environments for Travis CI builds (#305) * Rename `Mocha::ParameterMatchers::QueryStringMatches` to `QueryString` (#306) * Handle blank parameter value for query string matcher - thanks to @weynsee (#303 & #304) * Rename `Mocha::ParameterMatchers::QueryString` -> `EquivalentUri` (#307) * Use `do ... end` instead of `{ ... }` in acceptance tests - thanks to @chrisroos (#294) ## 1.2.1 * Fixed #272. Workaround Ruby bug 12832 which caused interpreter to hang. See https://bugs.ruby-lang.org/issues/12832. Thanks to @chrisroos & @petems (6f1c8b9b, #273). ## 1.2.0 * Always use prepended module to stub class & instance methods for Ruby v2+ - thanks to @grosser & @chrisroos (43d56671, #244) * Always use prepended module to stub AnyInstance methods in Ruby v2+ - thanks to @chrisroos (#262) * Always set visibility of stub method to match stubbed method on included module - thanks to @grosser & @chrisroos (e87c03b0, #248) * Always set visibility to stub method to match stubbed method on superclass - thanks to @chrisroos (38d902ad) * Allow stubbing of method to which any instance responds (#200) * Allow `includes` matcher to take matcher arguments - thanks to @lazyatom (#217) * Avoid exception in older version of Rubygems - thanks to @chrisroos (78d930a7) * Add licenses to gemspec as requested by @coreyhaines (#201) * Fix typo in README - thanks to @jaredbeck (6119460d) * Added section about using Mocha with RSpec & Rails to README (#221) * Fix documentation for Mocha::API#stub method - thanks to @raeno (599b1dcd) * Added backers and sponsors from OpenCollective - thanks to @piamancini (#253) * Fix typo in docs for equals - thanks to @alexcoco (#254) * Add known issue for Ruby v1.8 to README - thanks to @chrisroos (2c642096) ## 1.1.0 * Set visibility of any instance stub method. * Stub methods with a prepended method if there are other prepended methods. Thanks to @mrsimo. * Improve docs for `Mock#responds_like` & `#responds_like_instance_of`. * Use GitHub convention for instructions on contributing to Mocha. * Fix typos in docs. Thanks to @10io ## 1.0.0 ### External changes * Assume 'mocha' has been required when requiring 'mocha/setup'. * Provide shortcuts for integrating with specific test library i.e. `require 'mocha/test_unit'` or `require 'mocha/mini_test'` as alternatives to `require 'mocha/setup'`. * Do not automatically try to integrate with test libraries. Since the automatic test library integration functionality requires the test library to be loaded and this doesn't usually happen until *after* the bundle is loaded, it makes things simpler if we use `require 'mocha/setup'` to explicitly setup Mocha when we know the test library has been loaded. Fixes #146 & #155. * Consider stubs on superclasses if none exist on primary receiver. Largely based on changes suggested by @ccutrer in #145. Note: this may break existing tests which rely on the old behaviour. Stubbing a superclass method and then invoking that method on a child class would previously cause an unexpected invocation error. By searching up through the inheritance hierarchy for each of the delegate mock objects, we can provide more intuitive behaviour. Instead of an unexpected invocation error, invoking the method on the child class will cause the stubbed method on the superclass to be used. * Avoid recursion when constructing unexpected invocation message. Fixes #168. * Add explanation of method dispatch. Heavily based on the relevant jMock v1 documentation. Fixes #172. * Make class_eval line number more accurate. This sets the line number as the line number of the `def` statement. Closes #169. * Allow nesting of `responds_with` parameter matcher. Closes #166. * Define `Mocha` module before it's referenced. The test helper defines a class `TestCase` within the `Mocha` module. When running the tests inside the bundle, the `Mocha` module happens to be defined at this point. However when running the tests outside the bundle, it is not defined and so an exception is raised: `uninitialized constant Mocha (NameError)`. Fixes #163. * Document lack of thread-safety. Fixes #154. * Document how to use the build-matrix script. Fixes #160. * Stubbing non-public method should use same visibility. This will probably break some existing tests that were somehow relying on the stubbed method being public while the original method was protected or private. Fixes #150. ### Internal changes * Use lastest Rubygems in Travis CI builds. * Run the standard test suite against Ruby 2.1.0 in the build matrix. * Run integration tests against Ruby 2.0.0 with latest Test::Unit gem in the build matrix. * Test::Unit is not available in Ruby v1.9.3 standard library, so remove it from the build matrix. * Force use of Test::Unit runner, etc in relevant integration tests. Prior to this, I don't think we were really testing the Mocha integration with Test::Unit much, because, although `TestUnitTest` was a subclass of `Test::Unit::TestCase`, the important test case instances are the temporary ones built by `TestRunner#run_as_test` et al. Prior to this change, these would only have used Test::Unit where MiniTest was not available *at all* i.e. only in early versions of Ruby and when the MiniTest gem was not loaded. * Reset environment variables between build matrix builds. * Only activate integration with relevant test library for each of the integration tests. * Include standard build combinations from Travis CI config i.e. builds using standard library versions of test libraries. * Fix `build-matrix.rb` script. Also use `.travis.yml` to decide what combinations to run. This means we can now simulate the Travis CI build locally and avoid duplication. Fixes #157. * Remove Ruby version map from build matrix script. I'm using the `rbenv-aliases` plugin to alias minor versions to the relevant patch version. ## 0.14.0 * Official support for MiniTest v5. All tests now pass on the continuous integration build. ## 0.14.0.alpha * Add speculative support for Minitest v5. Due to incompatibilities it has not yet been possible to run the Mocha test suite against Minitest v5. However, @zenspider (author of Minitest) provided the patch and he has tested it against Rails v4. Fixes #156. Thanks to @zenspider. * Documentation updates. ## 0.13.3 * Allow `Mocha::ParameterMatchers#includes` to accept multiple items. Thanks to @simao. * Allow stubbing of *private* `Kernel` methods. Fixes #134. Thanks to @camski for reporting. * Avoid a warning when `test/unit/version` is required by other libraries in the same project. Fixes #140. Thanks to @tmiller. * Make auto-activation of Test::Unit integration more resilient. This change is specifically to cope with the nasty re-defining of classes that is done by the `minitest-spec-rails` gem. Fixes #143. Thanks to @tubaxenor for reporting. * Safer restoration of stubbed method visibility. Fixes #141. Thanks to @tmm1. * Ensure `Mockery` instance gets reset even if exception raised. Fixes #144. * Adapt Mocha acceptance tests to cope with changes in output from latest (v4.6.2) of MiniTest. * Updates to README about Rails compatibility. ## 0.13.2 * Stubbing of methods re-declared with different visibilty. Fixes #109. * Add `Mock#responds_like_instance_of`. Fixes #119. * Make `Expectation#inspect` less verbose and more useful. Fixes #122. * Make unit tests more robust to changes in environment. Fixes #121. * Update README in an attempt to head Rails-related issues off at the pass. * Add a Gem Badge to provide a link to Mocha on Rubygems. * Make documentation example consistent with other examples. ## 0.13.1 * Fix #97 - `Mocha::ParameterMatchers#has_entry` does not work with an Array as the entry's value. Thanks to @ngokli. * Allow deprecation `:debug` mode to be switched on from `MOCHA_OPTIONS` environment variable. ## 0.13.0 * Major overhaul of MiniTest & Test::Unit integration. Mocha now integrates with later versions of the two test libraries using documented hooks rather than monkey-patching. This should mean that Mocha will integrate with new versions of either library without the need to release a new version of Mocha each time, which was clearly bad and unsustainable. Many thanks to @tenderlove, @zenspider & @kou for their help, suggestions & patience. * Temporarily deprecated `require 'mocha'`. Use `require 'mocha/setup'` instead. The plan is that eventually `require 'mocha'` will *not* automatically integrate with either of the two test libraries as it does at the moment, and you'll need to explicitly & separately trigger the integration. I think this will provide a lot more flexibility and will hopefully do away with the need for the `require: false` option in the `Gemfile` which has always confused people. * Deprecated `require 'mocha_standalone'` and `require 'mocha/standalone'`. Use `require 'mocha/api` instead. * Although these are not part of Mocha's public API, I thought I should mention that the MiniTest and Test::Unit assertion counter classes have been combined into a single class `Mocha::Integration::AssertionCounter`. * Extracted Mocha::Hooks module from Mocha::API and added documentation for test library authors. * Improvements to documentation. Much of it has been combined into the README file. * Fix #101 - Mock#respond_to? doesn't work with a string argument - thanks to @urbanautomaton. * Fix #105 - Travis link in README - thanks to @cknadler. * Various improvements to automated testing of integration with test libraries. * Make deprecation warnings more prominent. ## 0.12.7 * Officially support minitest v4.1.0 (still monkey-patching). ## 0.12.6 * Fixes #103. ## 0.12.5 * Officially support minitest v3.5.0 (still monkey-patching). ## 0.12.4 * Officially support minitest v3.4.0 & test-unit v2.5.2 (still monkey-patching). ## 0.12.3 * Revert rename of undocumented internal module since it turns out Rails/ActiveSupport is relying on its existence. ## 0.12.2 * Officially support minitest v3.3.0 (still monkey-patching) ## 0.12.1 * Deprecation warning (instead of fail fast) if neither Test::Unit nor MiniTest is loaded. Fixes #88. * Remove deprecated access to `Mocha::Standalone`. * Remove the deprecated file `stubba.rb`. * Officially support test-unit v2.5.1 (still monkey-patching). * Improve the API acceptance test. ## 0.12.0 * Fail fast if neither Test::Unit nor MiniTest is loaded. Fixes #40. * Officially support MiniTest up to v3.2.0 (still monkey-patching). * Officially support test-unit v2.5.0 (still monkey-patching). * Do not monkey-patch Test::Unit or MiniTest unless we *know* it's ok. * Add acceptance tests to demonstrate using a block as a custom parameter matcher. * Update Travis CI build status image to use the new build under the freerange account. ## 0.11.4 * Homepage has moved to http://gofreerange.com/mocha/docs. ## 0.11.3 * Fix for #78 i.e. alias Object#method as Object#_method, not Object#__method__ which already exists as another Ruby method. ## 0.11.2 * Rails has a Request class which defines its own #method method. This broke the new mechanism for stubbing a method. This release includes a slightly modified version of fix #77 provided by @sikachu. See https://github.com/rails/rails/pull/5907 for further info. ## 0.11.1 * In Ruby 1.8.7 methods accepting a block parameter were incorrectly restored without the block parameter after being stubbed. Fix for #76. ## 0.11.0 * Store original method when stubbing rather than using alias_method. This fixes #41, #47, #74 and all tests now pass on both Ruby 1.8.7 and 1.9.3. * Attempting to stub a method on a frozen object should fail fast. See #68. * Prevent stubbing a method on nil by default. See #68. * Generate documentation using YARD instead of Rdoc - removes dependency on Coderay. * Publish documentation on Github pages instead of Rubyforge - uses rake task written by @tomafro. * Remove agiledox which has outlived it's usefulness. * Removed trailing whitespace throughout codebase. * Add documentation for Mock#unstub. * Improve documentation for ObjectMethods. * Provide a way to run multiple tests within a single acceptance test method. ## 0.10.5 * Fix for issue #66 (hopefully without regressing on issue #63) - Mocha::Mock has Mocha::Mockery as a dependency. Stop trying to pretend otherwise. Thanks to @kennyj for reporting. * Fix a bunch of warnings in Ruby 1.9. There are still the 6 test failures mentioned in issue #41 which I suspect are due to the introspection gem not being Ruby 1.9-compatible. * Add links to README for source code & issue tracker. * Fix for issue #67 - Make the travis-ci badge visible in the README. Thanks to Diego Plentz for pull request. * Fix for issue #70 - Rename Mock#expectations to Mock#__expectations__ to avoid conflicts. Thanks to Jeremy Stephens for pull request. ## 0.10.4 * Fix for issue #65 - expectations not being verified in subsequent tests. * Fix for issue #63 - require Mocha::Mockery at Mocha::Mock class load time and not on invocation of Mock#method_missing. * Fix for issue #45 - raise ArgumentError if Mocha::ParameterMatchers#has_entry is given Hash with wrong number of entries. * Make global variable name more obscure to avoid clashes with other libraries. * Move travis-ci-related gemfiles into their own directory. ## 0.10.3 * Fix for issue #57. Gem::Requirement#=~ was only added in rubygems v1.8.0, but Object#=~ means the result of various monkey-patching checks is always false/nil for earlier versions of rubygems. However, the method it aliases #satisfied_by? has existed since Gem::Dependency was extracted from Gem::Version in rubygems v0.9.4.4, so it's much safer to use that. Thanks to fguillen for reporting and helping with diagnosis. ## 0.10.2 * Merge pull request #53. Unstubbing a method should not remove expectations for other stubbed methods. Fixes #52. Thanks to saikat. ## 0.10.1 * Merge pull request #51. Use Gem::Requirement & Gem::Version for version comparison. Fixes issue #50. Thanks to meineerde. * Fixed typo in rdoc for Mocha::ObjectMethods. * Improve README as suggested in issue #46. Explain that Mocha must be loaded after test libraries and how to achieve this using Bundler. * Merge pull request #43 - nobody expects the spanish inquisition! Thanks to cairo140. * Fix for issue #39 - improve documentation for Expectation#multiple_yields. * Fix for issue #38 where a subtle change in test-unit v2.3.0 had been missed - only visible in verbose mode. * Support for MiniTest up to v2.6.2 has been verified. * Add explicit development dependency on coderay for generating syntax-highlighted code examples. ## 0.10.0 * Add Expectation#throws to allow a stubbed method to use Kernel#throw. * Updates for versions of Test::Unit up to and including v2.3.3 (including patch by Jens Fahnenbruck). * Updates for versions of MiniTest up to and including v2.5.1. * Since the singleton method added by Mocha masks the underlying instance method, there's no need to move it out the way and then back again. This fixes Github issue #20, because the original method is left unchanged - https://github.com/floehopper/mocha/issues/20 (thanks to Nick Lewis). * Handle stubbing of a singleton method, leaving the original method unchanged after the test. * When stubbing an instance method that was originally defined as a singleton method, the original method should still exist after the test. * Fixed mis-print in Mocha::ObjectMethods#unstub documentation (patch by Gleb Pomykalov). * Improved test coverage around stubbing of methods defined in different ways - this makes use of the newly extracted introspection gem (although this means some tests are now failing in Ruby v1.9.2). * Added configuration for Travis continuous integration. * Make the gemspec the canonical reference and stop generating it from the Rakefile. * Use the built-in Bundler rake tasks for packaging the gem. * Use the "release" rake task provided by Bundler instead of using the Rake::XForge::Release functionality. * Extract Object#__metaclass__ into a new metaclass gem. * Run rake tasks without `bundle exec`. * Avoid deprecation warning for rdoc rake task. * Remove the `use_test_unit_gem` MOCHA_OPTION which hasn't worked since we switched to bundler - we can now run the tests specifying a different Gemfile instead. * Use multiple Gemfiles seems to run Travis CI builds against multiple version of test-unit & minitest. ## 0.9.12 * Make Mocha's tests pass under Ruby 1.9.2 i.e. using MiniTest. One of the main issues was that we were not parsing stacktraces on MiniTest errors comprehensively enough. * Avoid 'circular require considered harmful' warning when running Mocha's tests in Ruby 1.9.2 * Make performance tests work on Ruby 1.9.2 i.e. using MiniTest. * Declare rake as a *development* dependency with newer versions of Rubygems since it's only needed to carry out developer-related tasks. ## 0.9.11 * Added explicit support for minitest v1.5.0 to v2.0.2. * Make testable by rubygems-test. * Update links to my blog and make other links consistent. * Added a URI parameter matcher that ignores the order of query parameters so that tests can be independent of undefined hash ordering (patch by Paul Battley). * Include unexpected invocation in failure message and change the language slightly to make the failure message less confusing. See http://floehopper.lighthouseapp.com/projects/22289/tickets/52. * No need to create regular expression every time the BacktraceFilter#filtered method is called. See http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/66. ## 0.9.10 * Added Mocha::ObjectMethods#unstub method - https://github.com/floehopper/mocha/issues#issue/6 * Inherit Mocha::ExpectationError from Exception instead of StandardError to reduce the chances of a test passing by accident - thanks to James Sanders (jsanders) - https://github.com/floehopper/mocha/issues#issue/15 * Fixed bug - GitHub README page to link correctly to code examples - https://github.com/floehopper/mocha/issues/closed#issue/11 * Fixed bug - PASSTHROUGH_EXCEPTIONS are defined on MiniTest::Unit::TestCase not in Mocha - thanks to Brian Troutwine (blt) - https://github.com/floehopper/mocha/issues/closed#issue/14 ## 0.9.9 * Avoid loading bits of the test-unit gem by accident. This is an attempt at a fix for the problem that James Adam reported [1]. By using 'load' instead of 'require' to detect the version of Test::Unit, we can avoid rubygems trying to load bits of the test-unit gem when it's not wanted. [1] http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/50#ticket-50-13 * Fix exception when running rake without test-unit gem. When test-unit gem >=v2.0.0 was installed but the "use_test_unit_gem" MOCHA_OPTIONS was not specified, a "comparison of Fixnum with Hash failed" exception was being raised when running the performance tests. This was because bits of the test-unit gem were being loaded accidentally and a Hash was being incorrectly supplied to the TestRunner.run method. * Explicitly require rubygems for running tests via rake using test-unit gem. * Handle newer versions of test-unit gem (v2.0.2 to v2.0.9) * Handle newer versions of minitest gem (v1.4.0 to v1.6.0) * Added warnings about monkey-patching test-unit and minitest to aid debugging. These are enabled by including "debug" in the MOCHA_OPTIONS environment variable. This is now a comma-separated list, so that we can specify multiple options e.g. MOCHA_OPTIONS=debug,use_test_unit_gem * Eloy Duran (alloy) made the unit tests run on 1.9.2dev r25249. * Eloy Duran (alloy) also improved some MiniTest TestResult code I'd written and got the acceptance tests running on Ruby 1.9 HEAD. There are still 4 failures because for some reason the backtrace line numbers are off by one. And the minitest_test test case does not run when the whole suite is run with MiniTest. These issues still need investigation. * Fixed some acceptance tests to run in Ruby 1.9.2 - it's no longer possible to subvert the protection of a method by calling it via Object#send. * Fixed "test:performance" rake task so it runs in Ruby 1.9.2. * Fix test incorrectly failing under Rubinius 1.0. This test imposed too many constraints. It appears that Object#inspect legitimately calls Object#object_id in Rubinius. But we're only interested in what 'id' methods Mocha::ObjectMethods#mocha_inspect calls. By stubbing Object#inspect we can relax the constraints imposed by the test. * Luke Redpath (lukeredpath) added new shorthand "any" and "all" composite parameter matchers using "&" and "|". This provides an alternative syntax for expecting any or all matchers to pass, e.g. foo.expects(:bar).with(equals(1) | equals(2)). * Improved documentation for Expectation#raises. A number of people have suggested an extension to the API to cope with custom exceptions that have extra constructor parameters. However, since the arguments supplied to Expectation#raises are just passed on to Kernel#raise, it's possible to pass in an instance of an exception. Thus no change to the API is required, but it does seem worthwhile pointing this out in the docs. * Corrected RDoc example for Expectation#never thanks to Red David (reddavis). * Improved RDoc including a change suggested by Rohit Arondekar (rohit). * Updated gemspec as requested by Sam Woodard (shwoodard). ## 0.9.8 * Fixed bug "NameError raised when using Mocha as a Rails plug-in" - http://floehopper.lighthouseapp.com/projects/22289/tickets/53. Since 0.9.6 the Rails plugin has been broken. See bug report for details. You will need to explicitly load Mocha *after* the test framework has been loaded, e.g. by adding "require 'mocha'" at the bottom of test/test_helper.rb. * Make Mocha::ParameterMatchers#regexp_matches, #includes, #has_value, #has_key more robust. Thanks to Sander Hartlage. * Allow passing a block to Mocha::Configuration methods to only change configuration for the duration of the block. Thanks to Dan Manges. * Fixed bug "doc generation fails in 0.9.7 gem" - http://floehopper.lighthouseapp.com/projects/22289/tickets/51. * Remove rdoc template incorporating google analytics from source control. The file just needs to exist locally and be ignored by source control. This should stop the warning showing up on e.g. RunCodeRun build results. ## 0.9.7 * Although I had provided a deprecation warning for people using Mocha::Standalone, I had assumed people wouldn't be explicitly loading the mocha/standalone.rb file. It turns out this assumption was incorrect at least in the case of Rspec. This is now fixed. ## 0.9.6 * Version 2.0.1 of the test-unit gem introduced a private 'run_test' method on TestCase which clashed with the public TestRunner#run_test method. So this latter method has been renamed to 'run_as_test'. * Stop requiring rubygems - this should be an environmental choice for the user. http://gist.github.com/54177 - describes why requiring rubygems in your library code is a bad idea. * It seems like overkill to vendorize coderay and meta_project when they're only needed to generate the examples for documentation and for publishing files on RubyForge. So I'm removing them and installing them locally as gems when I need them. * Added support for 'test-unit' gem (version >= 2.0). Note that as with other versions of Test::Unit I'm completely replacing the TestCase#run method. Unfortunately in version 2.0.0 this method differs slightly from the same method in version 2.0.1 & 2.0.2, so we have to provide different implementations to ensure that the internal working of Test::Unit are not compromised by Mocha. Note also that unless the 'test-unit' gem is loaded, requiring 'test/unit' leads to a mixture of stdlib and gem classes being loaded causing errors. To avoid a dependency on rubygems, the gem is loaded only if MOCHA_OPTIONS is set to 'use_test_unit_gem' - this option is only intended for use in running Mocha's own tests. It might be worthwhile to create a shim gem like minitest_tu_shim to allow the test-unit gem to completely replace the stdlib, but that's a job for another day. The changes in the Rakefile are to make the default task run with the 'test-unit' gem (version >= 2.0). * Renamed Mocha::Standalone to Mocha::API to better reflect its purpose. Added a deprecation warning for those who are referencing Mocha::Standalone. * Fix exception raised by HasEntry#matches? if first param is not a Hash (thanks to Taylor Barstow). * Ken Collins reported [1] that Mocha is always loading MiniTest if it is available and loading it causes some Rails/ActionPack tests to break. I've removed the loading of MiniTest, but this now means the user has to ensure that if they want to use MiniTest in conjunction with Mocha, he must load MiniTest before loading Mocha. [1] http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2060 * Implemented Bacon integration (thanks to Ubiratan Pires Alberton), but this was then removed after deciding only to maintain integration with Test::Unit and MiniTest which are both Ruby standard libraries. See mailing list for details. * Don't monkey-patch MiniTest if it's already been monkey-patched by Mocha. * Fixed bug: MiniTest integration was counting ExpectationErrors as errors not failures. http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/41. * Fixed bug: Some Bacon tests were failing in Ruby 1.9.1. http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/43. * Chad Humphries pointed out that in Ruby 1.9.1, if you are not using Test::Unit or MiniTest, Mocha will attempt to load and monkey-patch Test::Unit. Mocha will now only monkey-patch Test::Unit and/or MiniTest if they have already been loaded. MiniTest tests will now run in both Ruby 1.8.6 (with MiniTest gem) and in Ruby 1.9.1 (with MiniTest std lib). See Ligthouse ticket - http://floehopper.lighthouseapp.com/projects/22289/tickets/49. * Made Mocha compatible with minitest 1.4.0 and above (thanks to Denis Defreyne). ## 0.9.5 * Fixed Lighthouse bug #32 - stub_everything should mean mock responds to anything. * Added Expectation#twice to improve readability. Thanks to pull request from Celestino Gomes. * In Ruby 1.9.1, requiring 'test/unit' loads a thin wrapper around MiniTest and Test::Unit::TestCase ends up inheriting from MiniTest::Unit::TestCase. So we need to avoid including the Mocha modules more than once to avoid nasty consequences. Thanks to Matthias Hennemeyer for help with this. * Ruby 1.9 includes rake, but not rake/contrib. For the moment I've moved the sshpublisher require into the only rake task that needs it, so that I can at least run the tests in Ruby 1.9. It looks like I will need to build a rake/contrib gem or similar to get this working properly - http://intertwingly.net/blog/2008/01/07/Rake-Contrib-for-1-9 ## 0.9.4 * Added mocha.gemspec file generated with Chad Woolley's new rake task, so that a floehopper-mocha gem will get built on GitHub. * Add rake task to update mocha.gemspec with unique version, which will cause gem to be auto-built on github * As Tobias Crawley correctly pointed out in feature request #23055 "stubs(with_hash) not working with existing object" [1], following the principle of least surprise, it should be possible to call ObjectMethods#expects & ObjectMethods#stubs with a Hash of method_names vs return_values like you can with Mock#expects & Mock#stubs. I've also updated & improved the docs to reflect the changes. [1] http://rubyforge.org/tracker/index.php?func=detail&aid=23055&group_id=1917&atid=7480 * Removed deprecated gem autorequire. ## 0.9.3 * Added support for MiniTest thanks to Jeff Smick. * Fixed a possible bug with some of the non-default Configuration options relating to the argument to Object#respond_to? * As per Jay Fields recommendations [1] and with further impetus from a talk at Ruby Manor, any methods added to core classes are now added by including a module. This means that Mocha is a better citizen of the Ruby world and it's behaviour is more easily extended. [1] http://blog.jayfields.com/2008/07/ruby-underuse-of-modules.html & http://blog.jayfields.com/2008/07/ruby-redefine-method-behavior.html * Removed deprecated gem autorequire. ## 0.9.2 * Improved documentation to address [#22530] 'Mock methods with multiple return values not possible?' * respond_with parameter matcher was not available in tests. * Patch [#22630] Fix for a bug in running Rails tests with Ruby 1.8.7. Array#flatten was being called which in turn was checking whether each element responded to #to_ary. This check was using the two parameter version of #respond_to?, but Mock was only defining a one parameter version. ## 0.9.1 * Fixed bug #21465 - expects & stubs should support method names as strings (as well as symbols) or fail fast. Convert all expectation method names to a symbol in case they were supplied as a string. * By removing Mock#unexpected_method_called we reduce the number of methods vulnerable to the problem that surfaced in bug #21563. * Fix bug #21563 - stubbing 'verified?' method is unsafe. Instance method names on the Mock class should be more obscure. * Performance improvement. StubbaExampleTest goes twice as fast on my local machine. * Added primitive performance test to default rake task. * Fix format of case statements which don't work in Ruby 1.9 and make others consistent. * There is no point in running (potentially expensive) checks if configuration is set to allow such checks to fail. This is a relatively quick fix in response to Chris McGrath's performance problems. * Fix for bug #21161 - 'uninitialized constant Deprecation in stubba.rb'. * It's more readable to talk about 'once' and 'twice' rather than '1 time' and '2 times'. * Fix bug #20883 - never should raise when called to prevent follow up errors. Fail fast when there are no matching invokable expectations and handle the stub_everything case sensibly. This might not be entirely backwards compatible, but I think the benefits outweigh the risks. The most likely change is that a test that was already failing will now fail faster, which doesn't seem so awful. ## 0.9.0 * Configurable warnings or errors * when a method on a non-public method is stubbed * when a method on a non-existent method is stubbed * when a method on a non-mock object is stubbed * when a method is stubbed unnecessarily (i.e. the stubbed method is not called during the test) * Improved error messages * User-friendly list of unsatisfied expectations, satisfied expectations and state machines. * Improved readability of cardinality description. * Display sensible failure message for any_instance expectations e.g. "#.bar - expected calls: 1, actual calls: 0" * Parameter matchers * New to this release * optionally (allows matching of optional parameters if available) * yaml_equivalent (allows matching of YAML that represents the specified object) * responds_with (tests the quack not the duck) * Nesting of parameter matchers is now supported. * Optional block passed into mock initializer is evaluated in the context of the new mock instance and can be used as a shortcut to set up expectations. * Added JMock-style sequences for constraining the order of expected invocations. See Standalone#sequence and Expectation#in_sequence. * Added JMock-style states for constraining the order of expected invocations. See Standalone#states, Expectation#then, Expectation#when and StateMachine. * Compatibility with versions of Ruby * Compatibility with Ruby v1.9. All test errors and warnings fixed. * Nasty fix so that TestCaseAdaptor works consistently with earlier versions of Test::Unit as well as more recent versions. * Added platform to gem specification to avoid bug in rubygems 0.9.5 - see http://www.dcmanges.com/blog/rubygems-0-9-5-platform-bug and http://rubygems.org/read/chapter/20#platform. * Make ExpectationRaiser deal with subclasses of Interrupt which seem to need a message supplied in the raise statement in Ruby 1.8.6 (but not 1.8.4 or 1.9). Not sure this is really Mocha's responsibility. * Added deprecation warning in stubba.rb which is no longer needed and will be removed. * Supply positioning information to evals to improve any error messages. See http://ola-bini.blogspot.com/2008/01/ruby-antipattern-using-eval-without.html * Bug fixes * 18914 in revision 296 - http://rubyforge.org/tracker/index.php?func=detail&aid=18914&group_id=1917&atid=7477 * 18917 in revision 295 - http://rubyforge.org/tracker/index.php?func=detail&aid=18917&group_id=1917&atid=7477 * 18336 in revision 287 - http://rubyforge.org/tracker/index.php?func=detail&aid=18336&group_id=1917&atid=7477 * 17835 in revision 255 - http://rubyforge.org/tracker/index.php?func=detail&aid=17835&group_id=1917&atid=7477 * 17412 in revision 242 - http://rubyforge.org/tracker/index.php?func=detail&aid=17412&group_id=1917&atid=7477 * 15977 in revision 198 - http://rubyforge.org/tracker/index.php?func=detail&aid=15977&group_id=1917&atid=7477 * 11885 in revision 156 - http://rubyforge.org/tracker/index.php?func=detail&aid=11885&group_id=1917&atid=7477 ## 0.5.5 - Renamed Matches parameter matcher to RegexpMatches for clarity. - Added noframes tag to rdoc index to assist Google. ## 0.5.4 - Added matches parameter matcher for matching regular expressions. ## 0.5.3 - Attempt to fix packaging problems by switching to newer version (1.15.1) of gnutar and setting COPY_EXTENDED_ATTRIBUTES_DISABLE environment variable. - Removed unused ExpectationSequenceError exception. - Added instance_of and kind_of parameter matchers. - Added Google Webmaster meta tag to rdoc template header. - Put Google Webmaster meta tag in the right header i.e. the one for the index page. ## 0.5.2 - Fix bug 11885 - "never doesn't work with stub_everything" submitted by Alexander Lang. In fixing this bug, also fixed undiscoverd bug where expected & actual invocation counts were being incorrectly reported which seems to have been introduced when fixes were added for invocation dispatch (see MockedMethodDispatchAcceptanceTest). - Previously when an expectation did not allow more invocations, it was treated as not matching. Now we prefer matching expectations which allow more invocations, but still match expectations which cannot allow more invocations. I think this may be overcomplicating things, but let's see how it goes. ## 0.5.1 - Fixed bug #11583 "Mocha 0.5.0 throwing unexpected warnings". Also switched on ruby warning for all rake test tasks. Fixed majority of warnings, but some left to fix. ## 0.5.0 - Parameter Matchers - I've added a few Hamcrest-style parameter matchers which are designed to be used inside Expectation#with. The following matchers are currently available: anything(), includes(), has_key(), has_value(), has_entry(), all_of() & any_of(). More to follow soon. The idea is eventually to get rid of the nasty parameter_block option on Expectation#with. object = mock() object.expects(:method).with(has_key('key_1')) object.method('key_1' => 1, 'key_2' => 2) # no verification error raised object = mock() object.expects(:method).with(has_key('key_1')) object.method('key_2' => 2) # verification error raised, because method was not called with Hash containing key: 'key_1' - Values Returned and Exceptions Raised on Consecutive Invocations - Allow multiple calls to Expectation#returns and Expectation#raises to build up a sequence of responses to invocations on the mock. Added syntactic sugar method Expectation#then to allow more readable expectations. object = mock() object.stubs(:method).returns(1, 2).then.raises(Exception).then.returns(4) object.method # => 1 object.method # => 2 object.method # => raises exception of class Exception object.method # => 4 - Yields on Consecutive Invocations - Allow multiple calls to yields on single expectation to allow yield parameters to be specified for consecutive invocations. object = mock() object.stubs(:method).yields(1, 2).then.yields(3) object.method { |*values| p values } # => [1, 2] object.method { |*values| p values } # => [3] - Multiple Yields on Single Invocation - Added Expectation#multiple_yields to allow a mocked or stubbed method to yield multiple times for a single invocation. object = mock() object.stubs(:method).multiple_yields([1, 2], [3]) object.method { |*values| p values } # => [1, 2] # => [3] - Invocation Dispatch - Expectations were already being matched in reverse order i.e. the most recently defined one was being found first. This is still the case, but we now stop matching an expectation when its maximum number of expected invocations is reached. c.f. JMock v1. A stub will never stop matching by default. Hopefully this means we can soon get rid of the need to pass a Proc to Expectation#returns. object = mock() object.stubs(:method).returns(2) object.expects(:method).once.returns(1) object.method # => 1 object.method # => 2 object.method # => 2 # no verification error raised # The following should still work... Time.stubs(:now).returns(Time.parse('Mon Jan 01 00:00:00 UTC 2007')) Time.now # => Mon Jan 01 00:00:00 UTC 2007 Time.stubs(:now).returns(Time.parse('Thu Feb 01 00:00:00 UTC 2007')) Time.now # => Thu Feb 01 00:00:00 UTC 2007 - Deprecate passing an instance of Proc to Expectation#returns. - Explicitly include all Rakefile dependencies in project. - Fixed old Stubba example. - Fix so that it is possible for a stubbed method to raise an Interrupt exception without a message in Ruby 1.8.6 - Added responds_like and quacks_like. - Capture standard object methods before Mocha adds any. - Added Expectation#once method to make interface less surprising. - Use Rake::TestTask to run tests. Created three separate tasks to run unit, integration & acceptance tests. Split inspect_test into one file per TestCase. Deleted superfluous all_tests file. - Fiddled with mocha_inspect and tests to give more sensible results on x86 platform. - Fixed bug #7834 "infinite_range.rb makes incorrect assumption about to_f" logged by James Moore. ## 0.4.0 - Allow naming of mocks (patch from Chris Roos). - Specify multiple return values for consecutive calls. - Improved consistency of expectation error messages. - Allow mocking of Object instance methods e.g. kind_of?, type. - Provide aliased versions of #expects and #stubs to allow mocking of these methods. - Added at_least, at_most, at_most_once methods to expectation. - Allow expects and stubs to take a hash of method and return values. - Eliminate warning: "instance variable @yield not initialized" (patch from Xavier Shay). - Restore instance methods on partial mocks (patch from Chris Roos). - Allow stubbing of a method with non-word characters in its name (patch from Paul Battley). - Removed coupling to Test::Unit. - Allow specified exception instance to be raised (patch from Chris Roos). - Make mock object_id appear in hex like normal Ruby inspect (patch from Paul Battley). - Fix path to object.rb in rdoc rake task (patch from Tomas Pospisek). - Reverse order in which expectations are matched, so that last expectation is matched first. This allows e.g. a call to #stubs to be effectively overridden by a call to #expects (patch from Tobias Lutke). - Stubba & SmartTestCase modules incorporated into Mocha module so only need to require 'mocha' - no longer need to require 'stubba'. - AutoMocha removed. ## 0.3.3 - Quick bug fix to restore instance methods on partial mocks (for Kevin Clark). ## 0.3.2 - Examples added. ## 0.3.1 - Dual licensing with MIT license added. ## 0.3.0 * Rails plugin. * Auto-verify for expectations on concrete classes. * Include each expectation verification in the test result assertion count. * Filter out noise from assertion backtraces. * Point assertion backtrace to line where failing expectation was created. * New yields method for expectations. * Create stubs which stub all method calls. * Mocks now respond_to? expected methods. ## 0.2.1 * Rename MochaAcceptanceTest::Rover#move method to avoid conflict with Rake (in Ruby 1.8.4 only?) ## 0.2.0 * Small change to SetupAndTeardown#teardown_stubs suggested by Luke Redpath (http://www.lukeredpath.co.uk) to allow use of Stubba with RSpec (http://rspec.rubyforge.org). * Reorganized directory structure and extracted addition of setup and teardown methods into SmartTestCase mini-library. * Addition of auto-verify for Mocha (but not Stubba). This means there is more significance in the choice of expects or stubs in that any expects on a mock will automatically get verified. So instead of... wotsit = Mocha.new wotsit.expects(:thingummy).with(5).returns(10) doobrey = Doobrey.new(wotsit) doobrey.hoojamaflip wotsit.verify you need to do... wotsit = mock() wotsit.expects(:thingummy).with(5).returns(10) doobrey = Doobrey.new(wotsit) doobrey.hoojamaflip # no need to verify There are also shortcuts as follows... instead of... wotsit = Mocha.new wotsit.expects(:thingummy).returns(10) wotsit.expects(:summat).returns(25) you can have... wotsit = mock(:thingummy => 5, :summat => 25) and instead of... wotsit = Mocha.new wotsit.stubs(:thingummy).returns(10) wotsit.stubs(:summat).returns(25) you can have... wotsit = stub(:thingummy => 5, :summat => 25) ## 0.1.2 * Minor tweaks ## 0.1.1 * Initial release. mocha-2.4.2/Rakefile000066400000000000000000000107001464615054400142620ustar00rootroot00000000000000require 'bundler' namespace 'rubygems' do Bundler::GemHelper.install_tasks end require 'bundler/setup' require 'rake/testtask' begin # Only available with default Gemfile and in Ruby >= v2.2 require 'rubocop/rake_task' rescue LoadError # rubocop:disable Lint/HandleExceptions end desc 'Run all linters and tests' task 'default' => ['lint', 'test', 'test:performance'] desc 'Run tests' task 'test' do if (test_library = ENV['MOCHA_RUN_INTEGRATION_TESTS']) Rake::Task["test:integration:#{test_library}"].invoke else Rake::Task['test:units'].invoke Rake::Task['test:acceptance'].invoke end end namespace 'test' do # rubocop:disable Metrics/BlockLength desc 'Run unit tests' Rake::TestTask.new('units') do |t| t.libs << 'test' t.test_files = FileList['test/unit/**/*_test.rb'] t.verbose = true t.warning = true end desc 'Run acceptance tests' Rake::TestTask.new('acceptance') do |t| t.libs << 'test' t.test_files = FileList['test/acceptance/*_test.rb'] t.verbose = true t.warning = true end namespace 'integration' do desc 'Run Minitest integration tests (intended to be run in its own process)' Rake::TestTask.new('minitest') do |t| t.libs << 'test' t.test_files = FileList['test/integration/minitest_test.rb'] t.verbose = true t.warning = true end desc 'Run Test::Unit integration tests (intended to be run in its own process)' Rake::TestTask.new('test-unit') do |t| t.libs << 'test' t.test_files = FileList['test/integration/test_unit_test.rb'] t.verbose = true t.warning = true end end # require 'rcov/rcovtask' # Rcov::RcovTask.new('coverage') do |t| # t.libs << 'test' # t.test_files = unit_tests + acceptance_tests # t.verbose = true # t.warning = true # t.rcov_opts << '--sort coverage' # t.rcov_opts << '--xref' # end desc 'Run performance tests' task 'performance' do require File.join(File.dirname(__FILE__), 'test', 'acceptance', 'stubba_example_test') require File.join(File.dirname(__FILE__), 'test', 'acceptance', 'mocha_example_test') iterations = 1000 puts "\nBenchmarking with #{iterations} iterations..." [MochaExampleTest, StubbaExampleTest].each do |test_case| puts "#{test_case}: #{benchmark_test_case(test_case, iterations)} seconds." end end end task 'lint' do if defined?(RuboCop::RakeTask) RuboCop::RakeTask.new Rake::Task['rubocop'].invoke else puts 'RuboCop not available - skipping linting' end end # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity def benchmark_test_case(klass, iterations) require 'benchmark' require 'mocha/detection/minitest' if defined?(Minitest) minitest_version = Gem::Version.new(Mocha::Detection::Minitest.version) if Gem::Requirement.new('>= 5.0.0').satisfied_by?(minitest_version) Minitest.seed = 1 result = Benchmark.realtime { iterations.times { |_i| klass.run(Minitest::CompositeReporter.new) } } Minitest::Runnable.runnables.delete(klass) result else Minitest::Unit.output = StringIO.new Benchmark.realtime { iterations.times { |_i| Minitest::Unit.new.run([klass]) } } end else load 'test/unit/ui/console/testrunner.rb' unless defined?(Test::Unit::UI::Console::TestRunner) unless @silent_option begin load 'test/unit/ui/console/outputlevel.rb' unless defined?(Test::Unit::UI::Console::OutputLevel::SILENT) @silent_option = { output_level: Test::Unit::UI::Console::OutputLevel::SILENT } rescue LoadError @silent_option = Test::Unit::UI::SILENT end end Benchmark.realtime { iterations.times { Test::Unit::UI::Console::TestRunner.run(klass, @silent_option) } } end end # rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity if ENV['MOCHA_GENERATE_DOCS'] require 'yard' desc 'Remove generated documentation' task 'clobber_yardoc' do `rm -rf ./docs` end desc 'Generate documentation' YARD::Rake::YardocTask.new('yardoc') do |task| task.options = ['--title', "Mocha #{Mocha::VERSION}", '--fail-on-warning'] end task 'checkout_docs_cname' do `git checkout docs/CNAME` end task 'checkout_docs_js' do `git checkout docs/js/app.js` `git checkout docs/js/jquery.js` end desc 'Generate documentation' task 'generate_docs' => %w[clobber_yardoc yardoc checkout_docs_cname checkout_docs_js] end task 'release' => ['default', 'rubygems:release'] mocha-2.4.2/docs/000077500000000000000000000000001464615054400135475ustar00rootroot00000000000000mocha-2.4.2/docs/CNAME000066400000000000000000000000241464615054400143110ustar00rootroot00000000000000mocha.jamesmead.org mocha-2.4.2/docs/Mocha.html000066400000000000000000000217231464615054400154710ustar00rootroot00000000000000 Module: Mocha — Mocha 2.4.2

Module: Mocha

Defined in:
lib/mocha/api.rb,
lib/mocha/hooks.rb,
lib/mocha/mock.rb,
lib/mocha/expectation.rb,
lib/mocha/object_methods.rb,
lib/mocha/class_methods.rb,
lib/mocha/parameter_matchers.rb,
lib/mocha/parameter_matchers/not.rb,
lib/mocha/parameter_matchers/base.rb,
lib/mocha/parameter_matchers/is_a.rb,
lib/mocha/parameter_matchers/all_of.rb,
lib/mocha/parameter_matchers/any_of.rb,
lib/mocha/parameter_matchers/equals.rb,
lib/mocha/parameter_matchers/has_key.rb,
lib/mocha/parameter_matchers/kind_of.rb,
lib/mocha/parameter_matchers/anything.rb,
lib/mocha/parameter_matchers/has_keys.rb,
lib/mocha/parameter_matchers/includes.rb,
lib/mocha/parameter_matchers/has_entry.rb,
lib/mocha/parameter_matchers/has_value.rb,
lib/mocha/parameter_matchers/optionally.rb,
lib/mocha/parameter_matchers/has_entries.rb,
lib/mocha/parameter_matchers/instance_of.rb,
lib/mocha/parameter_matchers/responds_with.rb,
lib/mocha/parameter_matchers/any_parameters.rb,
lib/mocha/parameter_matchers/equivalent_uri.rb,
lib/mocha/parameter_matchers/regexp_matches.rb,
lib/mocha/parameter_matchers/yaml_equivalent.rb,
lib/mocha/parameter_matchers/instance_methods.rb,
lib/mocha/parameter_matchers/positional_or_keyword_hash.rb,
lib/mocha/state_machine.rb,
lib/mocha/sequence.rb,
lib/mocha/configuration.rb,
lib/mocha/expectation_error_factory.rb,
lib/mocha/expectation_error.rb,
lib/mocha/stubbing_error.rb,
lib/mocha/integration/test_unit/adapter.rb,
lib/mocha/integration/minitest/adapter.rb

Defined Under Namespace

Modules: API, ClassMethods, Hooks, Integration, ObjectMethods, ParameterMatchers Classes: Configuration, Expectation, ExpectationError, ExpectationErrorFactory, Mock, Sequence, StateMachine, StubbingError

Class Method Summary collapse

Class Method Details

.configure {|configuration| ... } ⇒ Object

Allows setting of configuration options. See Configuration for the available options.

Typically the configuration is set globally in a test_helper.rb or spec_helper.rb file.

Examples:

Setting multiple configuration options

Mocha.configure do |c|
  c.stubbing_method_unnecessarily = :prevent
  c.stubbing_method_on_non_mock_object = :warn
  c.stubbing_method_on_nil = :allow
end

Yield Parameters:

  • configuration (Configuration)

    the configuration for modification

See Also:



19
20
21
# File 'lib/mocha/configuration.rb', line 19

def self.configure
  yield configuration
end
mocha-2.4.2/docs/Mocha/000077500000000000000000000000001464615054400145765ustar00rootroot00000000000000mocha-2.4.2/docs/Mocha/API.html000066400000000000000000001663051464615054400161100ustar00rootroot00000000000000 Module: Mocha::API — Mocha 2.4.2

Module: Mocha::API

Includes:
Hooks, ParameterMatchers
Included in:
Integration::Minitest::Adapter, Integration::TestUnit::Adapter
Defined in:
lib/mocha/api.rb

Overview

Methods added to Test::Unit::TestCase, Minitest::Unit::TestCase or equivalent. The mock creation methods are #mock, #stub and #stub_everything, all of which return a #Mock which can be further modified by Mock#responds_like and Mock#responds_like_instance_of methods, both of which return a Mock, too, and can therefore, be chained to the original creation methods.

Mock#responds_like and Mock#responds_like_instance_of force the mock to indicate what it is supposed to be mocking, thus making it a safer verifying mock. They check that the underlying responder will actually respond to the methods being stubbed, throwing a NoMethodError upon invocation otherwise.

Examples:

Verifying mock using Mock#responds_like_instance_of

class Sheep
  def initialize
    raise "some awkward code we don't want to call"
  end
  def chew(grass); end
end

sheep = mock('sheep').responds_like_instance_of(Sheep)
sheep.expects(:chew)
sheep.expects(:foo)
sheep.respond_to?(:chew) # => true
sheep.respond_to?(:foo) # => false
sheep.chew
sheep.foo # => raises NoMethodError exception

Instance Method Summary collapse

Methods included from Hooks

#mocha_setup, #mocha_teardown, #mocha_test_name, #mocha_verify

Methods included from ParameterMatchers

#Not, #all_of, #any_of, #any_parameters, #anything, #equals, #equivalent_uri, #has_entries, #has_entry, #has_key, #has_keys, #has_value, #includes, #instance_of, #is_a, #kind_of, #optionally, #regexp_matches, #responds_with, #yaml_equivalent

Instance Method Details

#mock(name) ⇒ Mock #mock(expected_methods_vs_return_values = {}) ⇒ Mock #mock(name, expected_methods_vs_return_values = {}) ⇒ Mock

Builds a new mock object

Examples:

Using expected_methods_vs_return_values Hash to setup expectations.

def test_motor_starts_and_stops
  motor = mock('motor', start: true, stop: true)
  assert motor.start
  assert motor.stop
  # an error will be raised unless both Motor#start and Motor#stop have been called
end

Overloads:

  • #mock(name) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

  • #mock(expected_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • expected_methods_vs_return_values (Hash) (defaults to: {})

      expected method name symbols as keys and corresponding return values as values - these expectations are setup as if Mock#expects were called multiple times.

  • #mock(name, expected_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

    • expected_methods_vs_return_values (Hash) (defaults to: {})

      expected method name symbols as keys and corresponding return values as values - these expectations are setup as if Mock#expects were called multiple times.

Returns:

  • (Mock)

    a new mock object



69
70
71
72
73
74
75
# File 'lib/mocha/api.rb', line 69

def mock(*arguments)
  name = arguments.shift.to_s if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol)
  expectations = arguments.shift || {}
  mock = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock
  mock.expects(expectations)
  mock
end

#sequence(name) { ... } ⇒ Sequence

Builds a new sequence which can be used to constrain the order in which expectations can occur.

Specify that an expected invocation must occur within a named Sequence by calling Expectation#in_sequence on each expectation or by passing a block within which all expectations should be constrained by the Sequence.

Examples:

Ensure methods on egg are invoked in correct order.

breakfast = sequence('breakfast')

egg = mock('egg')
egg.expects(:crack).in_sequence(breakfast)
egg.expects(:fry).in_sequence(breakfast)
egg.expects(:eat).in_sequence(breakfast)

Ensure methods across multiple objects are invoked in correct order.

sequence = sequence(:task_order)

task_one = mock("task_one")
task_two = mock("task_two")

task_one.expects(:execute).in_sequence(sequence)
task_two.expects(:execute).in_sequence(sequence)

task_one.execute
task_two.execute

Ensure methods on egg are invoked in the correct order using a block.

egg = mock('egg')
sequence('breakfast') do
  egg.expects(:crack)
  egg.expects(:fry)
  egg.expects(:eat)
end

Parameters:

  • name (String)

    name of sequence

Yields:

  • optional block within which expectations should be constrained by the sequence

Returns:

See Also:



170
171
172
173
174
175
176
177
178
179
# File 'lib/mocha/api.rb', line 170

def sequence(name)
  Sequence.new(name).tap do |seq|
    Mockery.instance.sequences.push(seq)
    begin
      yield if block_given?
    ensure
      Mockery.instance.sequences.pop
    end
  end
end

#states(name) ⇒ StateMachine

Builds a new state machine which can be used to constrain the order in which expectations can occur.

Specify the initial state of the state machine by using StateMachine#starts_as.

Specify that an expected invocation should change the state of the state machine by using Expectation#then.

Specify that an expected invocation should be constrained to occur within a particular state by using Expectation#when.

A test can contain multiple state machines.

Examples:

Constrain expected invocations to occur in particular states.

power = states('power').starts_as('off')

radio = mock('radio')
radio.expects(:switch_on).then(power.is('on'))
radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
radio.expects(:adjust_volume).with(+5).when(power.is('on'))
radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
radio.expects(:adjust_volume).with(-5).when(power.is('on'))
radio.expects(:switch_off).then(power.is('off'))

Parameters:

  • name (String)

    name of state machine

Returns:

See Also:



207
208
209
# File 'lib/mocha/api.rb', line 207

def states(name)
  Mockery.instance.new_state_machine(name)
end

#stub(name) ⇒ Mock #stub(stubbed_methods_vs_return_values = {}) ⇒ Mock #stub(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

Builds a new mock object

Examples:

Using stubbed_methods_vs_return_values Hash to setup stubbed methods.

def test_motor_starts_and_stops
  motor = stub('motor', start: true, stop: true)
  assert motor.start
  assert motor.stop
  # an error will not be raised even if either Motor#start or Motor#stop has not been called
end

Overloads:

  • #stub(name) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

  • #stub(stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

      stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if Mock#stubs were called multiple times.

  • #stub(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

      stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if Mock#stubs were called multiple times.

Returns:

  • (Mock)

    a new mock object



96
97
98
99
100
101
102
# File 'lib/mocha/api.rb', line 96

def stub(*arguments)
  name = arguments.shift.to_s if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol)
  expectations = arguments.shift || {}
  stub = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock
  stub.stubs(expectations)
  stub
end

#stub_everything(name) ⇒ Mock #stub_everything(stubbed_methods_vs_return_values = {}) ⇒ Mock #stub_everything(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

Builds a mock object that accepts calls to any method. By default it will return nil for any method call.

Examples:

Ignore invocations of irrelevant methods.

def test_motor_stops
  motor = stub_everything('motor', stop: true)
  assert_nil motor.irrelevant_method_1 # => no error raised
  assert_nil motor.irrelevant_method_2 # => no error raised
  assert motor.stop
end

Overloads:

  • #stub_everything(name) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

  • #stub_everything(stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

      stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if Mock#stubs were called multiple times.

  • #stub_everything(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

      stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if Mock#stubs were called multiple times.

Returns:

  • (Mock)

    a new mock object



123
124
125
126
127
128
129
130
# File 'lib/mocha/api.rb', line 123

def stub_everything(*arguments)
  name = arguments.shift if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol)
  expectations = arguments.shift || {}
  stub = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock
  stub.stub_everything
  stub.stubs(expectations)
  stub
end
mocha-2.4.2/docs/Mocha/ClassMethods.html000066400000000000000000000164241464615054400200640ustar00rootroot00000000000000 Module: Mocha::ClassMethods — Mocha 2.4.2

Module: Mocha::ClassMethods

Defined in:
lib/mocha/class_methods.rb

Overview

Methods added to all classes to allow mocking and stubbing on real (i.e. non-mock) objects.

Instance Method Summary collapse

Instance Method Details

#any_instanceMock

Returns a mock object which will detect calls to any instance of this class.

Examples:

Return false to invocation of Product#save for any instance of Product.

Product.any_instance.stubs(:save).returns(false)
product_1 = Product.new
assert_equal false, product_1.save
product_2 = Product.new
assert_equal false, product_2.save

Returns:

  • (Mock)

    a mock object which will detect calls to any instance of this class.

Raises:

  • (StubbingError)

    if attempting to stub method which is not allowed.



45
46
47
48
49
50
# File 'lib/mocha/class_methods.rb', line 45

def any_instance
  if frozen?
    raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}.any_instance", caller)
  end
  @any_instance ||= AnyInstance.new(self)
end
mocha-2.4.2/docs/Mocha/Configuration.html000066400000000000000000001225741464615054400203060ustar00rootroot00000000000000 Class: Mocha::Configuration — Mocha 2.4.2

Class: Mocha::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/configuration.rb

Overview

This class provides a number of ways to configure the library.

Typically the configuration is set globally in a test_helper.rb or spec_helper.rb file.

Examples:

Setting multiple configuration options

Mocha.configure do |c|
  c.stubbing_method_unnecessarily = :prevent
  c.stubbing_method_on_non_mock_object = :warn
  c.stubbing_method_on_nil = :allow
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.override(temporary_options) { ... } ⇒ Object

Temporarily modify Mocha::Configuration options.

The supplied temporary_options will override the current configuration for the duration of the supplied block. The configuration will be returned to its original state when the block returns.

Examples:

Temporarily allow stubbing of nil

Mocha::Configuration.override(stubbing_method_on_nil: :allow) do
  nil.stubs(:foo)
end

Parameters:

  • temporary_options (Hash)

    the configuration options to apply for the duration of the block.

Yields:

  • block during which the configuration change will be in force.



318
319
320
321
322
323
324
# File 'lib/mocha/configuration.rb', line 318

def override(temporary_options)
  original_configuration = configuration
  @configuration = configuration.merge(new(temporary_options))
  yield
ensure
  @configuration = original_configuration
end

Instance Method Details

#display_matching_invocations_on_failure=(value) ⇒ Object

Display matching invocations alongside expectations on Mocha-related test failure.

Examples:

Enable display of matching invocations

Mocha.configure do |c|
  c.display_matching_invocations_on_failure = true
end

foo = mock('foo')
foo.expects(:bar)
foo.stubs(:baz).returns('baz').raises(RuntimeError).throws(:tag, 'value')

foo.baz(1, 2)
assert_raises(RuntimeError) { foo.baz(3, 4) }
assert_throws(:tag) { foo.baz(5, 6) }

not all expectations were satisfied
unsatisfied expectations:
- expected exactly once, invoked never: #<Mock:foo>.bar
satisfied expectations:
- allowed any number of times, invoked 3 times: #<Mock:foo>.baz(any_parameters)
  - #<Mock:foo>.baz(1, 2) # => "baz"
  - #<Mock:foo>.baz(3, 4) # => raised RuntimeError
  - #<Mock:foo>.baz(5, 6) # => threw (:tag, "value")

Parameters:

  • value (Boolean)

    true to enable display of matching invocations; disabled by default.



244
245
246
# File 'lib/mocha/configuration.rb', line 244

def display_matching_invocations_on_failure=(value)
  @options[:display_matching_invocations_on_failure] = value
end

#strict_keyword_argument_matching=(value) ⇒ Object

Perform strict keyword argument comparison. Only supported in Ruby >= v2.7.

When this option is set to false a positional Hash and a set of keyword arguments are treated the same during comparison, which can lead to misleading passing tests in Ruby >= v3.0 (see examples below). However, a deprecation warning will be displayed if a positional Hash matches a set of keyword arguments or vice versa. This is because #strict_keyword_argument_matching= will default to true in the future.

For more details on keyword arguments in Ruby v3, refer to this article.

Note that Hash-related matchers such as ParameterMatchers#has_value or ParameterMatchers#has_key will still treat a positional Hash and a set of keyword arguments the same, so misleading passing tests are still possible when they are used.

This configuration option is false by default to enable gradual adoption, but will be true by default in the future.

Examples:

Loose keyword argument matching (default)


class Example
  def foo(a, bar:); end
end

example = Example.new
example.expects(:foo).with('a', bar: 'b')
example.foo('a', { bar: 'b' })
# This passes the test, but would result in an ArgumentError in practice

Strict keyword argument matching


Mocha.configure do |c|
  c.strict_keyword_argument_matching = true
end

class Example
  def foo(a, bar:); end
end

example = Example.new
example.expects(:foo).with('a', bar: 'b')
example.foo('a', { bar: 'b' })
# This now fails as expected

Parameters:

  • value (Boolean)

    true to enable strict keyword argument matching; false by default.



290
291
292
293
# File 'lib/mocha/configuration.rb', line 290

def strict_keyword_argument_matching=(value)
  raise 'Strict keyword argument matching requires Ruby 2.7 and above.' unless Mocha::RUBY_V27_PLUS
  @options[:strict_keyword_argument_matching] = value
end

#stubbing_method_on_nil=(value) ⇒ Object

Configure whether stubbing methods on the nil object is allowed.

This is usually done accidentally, but there might be rare cases where it is intended.

This option only works for Ruby < v2.2.0. In later versions of Ruby nil is frozen and so a StubbingError will be raised if you attempt to stub a method on nil.

When value is :allow, do nothing. When value is :warn, display a warning. When value is :prevent, raise a StubbingError. This is the default.

Parameters:

  • value (Symbol)

    one of :allow, :warn, :prevent.



210
211
212
# File 'lib/mocha/configuration.rb', line 210

def stubbing_method_on_nil=(value)
  @options[:stubbing_method_on_nil] = value
end

#stubbing_method_on_non_mock_object=(value) ⇒ Object

Configure whether stubbing methods on non-mock objects is allowed.

If you like the idea of mocking roles not objects and you don’t like stubbing concrete classes, this is the setting for you. However, while this restriction makes a lot of sense in Java with its explicit interfaces, it may be moot in Ruby where roles are probably best represented as Modules.

When value is :allow, do nothing. This is the default. When value is :warn, display a warning. When value is :prevent, raise a StubbingError.

Examples:

Preventing stubbing of a method on a non-mock object

Mocha.configure do |c|
  c.stubbing_method_on_non_mock_object = :prevent
end

class Example
  def example_method; end
end

example = Example.new
example.stubs(:example_method)
# => Mocha::StubbingError: stubbing method on non-mock object:
# =>   #<Example:0x593620>.example_method

Parameters:

  • value (Symbol)

    one of :allow, :warn, :prevent.



122
123
124
# File 'lib/mocha/configuration.rb', line 122

def stubbing_method_on_non_mock_object=(value)
  @options[:stubbing_method_on_non_mock_object] = value
end

#stubbing_method_unnecessarily=(value) ⇒ Object

Configure whether stubbing methods unnecessarily is allowed.

This is useful for identifying unused stubs. Unused stubs are often accidentally introduced when code is refactored.

When value is :allow, do nothing. This is the default. When value is :warn, display a warning. When value is :prevent, raise a StubbingError.

Examples:

Preventing unnecessary stubbing of a method

Mocha.configure do |c|
  c.stubbing_method_unnecessarily = :prevent
end

example = mock('example')
example.stubs(:unused_stub)
# => Mocha::StubbingError: stubbing method unnecessarily:
# =>   #<Mock:example>.unused_stub(any_parameters)

Parameters:

  • value (Symbol)

    one of :allow, :warn, :prevent.



89
90
91
# File 'lib/mocha/configuration.rb', line 89

def stubbing_method_unnecessarily=(value)
  @options[:stubbing_method_unnecessarily] = value
end

#stubbing_non_existent_method=(value) ⇒ Object

Configure whether stubbing of non-existent methods is allowed.

This is useful if you want to ensure that methods you’re mocking really exist. A common criticism of unit tests with mock objects is that such a test may (incorrectly) pass when an equivalent non-mocking test would (correctly) fail. While you should always have some integration tests, particularly for critical business functionality, this Mocha configuration setting should catch scenarios when mocked methods and real methods have become misaligned.

When value is :allow, do nothing. This is the default. When value is :warn, display a warning. When value is :prevent, raise a StubbingError.

Examples:

Preventing stubbing of a non-existent method


Mocha.configure do |c|
  c.stubbing_non_existent_method = :prevent
end

class Example
end

example = Example.new
example.stubs(:method_that_doesnt_exist)
# => Mocha::StubbingError: stubbing non-existent method:
# =>   #<Example:0x593760>.method_that_doesnt_exist

Parameters:

  • value (Symbol)

    one of :allow, :warn, :prevent.



155
156
157
# File 'lib/mocha/configuration.rb', line 155

def stubbing_non_existent_method=(value)
  @options[:stubbing_non_existent_method] = value
end

#stubbing_non_public_method=(value) ⇒ Object

Configure whether stubbing of non-public methods is allowed.

Many people think that it’s good practice only to mock public methods. This is one way to prevent your tests being too tightly coupled to the internal implementation of a class. Such tests tend to be very brittle and not much use when refactoring.

When value is :allow, do nothing. This is the default. When value is :warn, display a warning. When value is :prevent, raise a StubbingError.

Examples:

Preventing stubbing of a non-public method

Mocha.configure do |c|
  c.stubbing_non_public_method = :prevent
end

class Example
  def internal_method; end
  private :internal_method
end

example = Example.new
example.stubs(:internal_method)
# => Mocha::StubbingError: stubbing non-public method:
# =>   #<Example:0x593530>.internal_method

Parameters:

  • value (Symbol)

    one of :allow, :warn, :prevent.



189
190
191
# File 'lib/mocha/configuration.rb', line 189

def stubbing_non_public_method=(value)
  @options[:stubbing_non_public_method] = value
end
mocha-2.4.2/docs/Mocha/Expectation.html000066400000000000000000004511331464615054400177560ustar00rootroot00000000000000 Class: Mocha::Expectation — Mocha 2.4.2

Class: Mocha::Expectation

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/expectation.rb

Overview

Methods on expectations returned from Mock#expects, Mock#stubs, ObjectMethods#expects and ObjectMethods#stubs.

Instance Method Summary collapse

Instance Method Details

#at_least(minimum_number_of_times) ⇒ Expectation

Modifies expectation so that the expected method must be called at least a minimum_number_of_times.

Examples:

Expected method must be called at least twice.

object = mock()
object.expects(:expected_method).at_least(2)
3.times { object.expected_method }
# => verify succeeds

object = mock()
object.expects(:expected_method).at_least(2)
object.expected_method
# => verify fails

Parameters:

  • minimum_number_of_times (Integer)

    minimum number of expected invocations.

Returns:



134
135
136
137
# File 'lib/mocha/expectation.rb', line 134

def at_least(minimum_number_of_times)
  @cardinality.at_least(minimum_number_of_times)
  self
end

#at_least_onceExpectation

Modifies expectation so that the expected method must be called at least once.

Examples:

Expected method must be called at least once.

object = mock()
object.expects(:expected_method).at_least_once
object.expected_method
# => verify succeeds

object = mock()
object.expects(:expected_method).at_least_once
# => verify fails

Returns:



152
153
154
# File 'lib/mocha/expectation.rb', line 152

def at_least_once
  at_least(1)
end

#at_most(maximum_number_of_times) ⇒ Expectation

Modifies expectation so that the expected method must be called at most a maximum_number_of_times.

Examples:

Expected method must be called at most twice.

object = mock()
object.expects(:expected_method).at_most(2)
2.times { object.expected_method }
# => verify succeeds

object = mock()
object.expects(:expected_method).at_most(2)
3.times { object.expected_method } # => unexpected invocation

Parameters:

  • maximum_number_of_times (Integer)

    maximum number of expected invocations.

Returns:



170
171
172
173
# File 'lib/mocha/expectation.rb', line 170

def at_most(maximum_number_of_times)
  @cardinality.at_most(maximum_number_of_times)
  self
end

#at_most_onceExpectation

Modifies expectation so that the expected method must be called at most once.

Examples:

Expected method must be called at most once.

object = mock()
object.expects(:expected_method).at_most_once
object.expected_method
# => verify succeeds

object = mock()
object.expects(:expected_method).at_most_once
2.times { object.expected_method } # => unexpected invocation

Returns:



188
189
190
# File 'lib/mocha/expectation.rb', line 188

def at_most_once
  at_most(1)
end

#in_sequence(sequence, *sequences) ⇒ Expectation

Constrains the expectation so that it must be invoked at the current point in the sequence.

To expect a sequence of invocations, write the expectations in order and add the in_sequence(sequence) clause to each one.

Expectations in a sequence can have any invocation count.

If an expectation in a sequence is stubbed, rather than expected, it can be skipped in the sequence.

An expected method can appear in multiple sequences.

Examples:

Ensure methods are invoked in a specified order.

breakfast = sequence('breakfast')

egg = mock('egg')
egg.expects(:crack).in_sequence(breakfast)
egg.expects(:fry).in_sequence(breakfast)
egg.expects(:eat).in_sequence(breakfast)

Parameters:

  • sequence (Sequence)

    sequence in which expected method should appear.

  • sequences (*Array<Sequence>)

    more sequences in which expected method should appear.

Returns:

See Also:



588
589
590
591
# File 'lib/mocha/expectation.rb', line 588

def in_sequence(sequence, *sequences)
  sequences.unshift(sequence).each { |seq| add_in_sequence_ordering_constraint(seq) }
  self
end

#multiple_yields(*parameter_groups) ⇒ Expectation

Modifies expectation so that when the expected method is called, it yields multiple times per invocation with the specified parameter_groups.

If no block is provided, the method will still attempt to yield resulting in a LocalJumpError. Note that this is what would happen if a “real” (non-mock) method implementation tried to yield to a non-existent block.

Examples:

When foreach is called, the stub will invoke the block twice, the first time it passes [‘row1_col1’, ‘row1_col2’] as the parameters, and the second time it passes [‘row2_col1’, ”] as the parameters.

csv = mock()
csv.expects(:foreach).with("path/to/file.csv").multiple_yields(['row1_col1', 'row1_col2'], ['row2_col1', ''])
rows = []
csv.foreach { |row| rows << row }
rows # => [['row1_col1', 'row1_col2'], ['row2_col1', '']]

Yield different groups of parameters on different invocations of the expected method. Simulating a situation where the CSV file at ‘path/to/file.csv’ has been modified between the two calls to foreach.

csv = mock()
csv.stubs(:foreach).with("path/to/file.csv").multiple_yields(['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']).then.multiple_yields(['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2'])
rows_from_first_invocation = []
rows_from_second_invocation = []
csv.foreach { |row| rows_from_first_invocation << row } # first invocation
csv.foreach { |row| rows_from_second_invocation << row } # second invocation
rows_from_first_invocation # => [['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']]
rows_from_second_invocation # => [['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2']]

Parameters:

  • parameter_groups (*Array<Array>)

    each element of parameter_groups should iself be an Array representing the parameters to be passed to the block for a single yield. Any element of parameter_groups that is not an Array is wrapped in an Array.

Returns:

See Also:



375
376
377
378
# File 'lib/mocha/expectation.rb', line 375

def multiple_yields(*parameter_groups)
  @yield_parameters.add(*parameter_groups)
  self
end

#neverExpectation

Modifies expectation so that the expected method must never be called.

Examples:

Expected method must never be called.

object = mock()
object.expects(:expected_method).never
object.expected_method # => unexpected invocation

object = mock()
object.expects(:expected_method).never
# => verify succeeds

Returns:



114
115
116
117
# File 'lib/mocha/expectation.rb', line 114

def never
  @cardinality.exactly(0)
  self
end

#onceExpectation

Modifies expectation so that the expected method must be called exactly once.

Note that this is the default behaviour for an expectation, but you may wish to use it for clarity/emphasis.

Examples:

Expected method must be invoked exactly once.

object = mock()
object.expects(:expected_method).once
object.expected_method
# => verify succeeds

object = mock()
object.expects(:expected_method).once
object.expected_method
object.expected_method # => unexpected invocation

object = mock()
object.expects(:expected_method).once
# => verify fails

Returns:



97
98
99
100
# File 'lib/mocha/expectation.rb', line 97

def once
  @cardinality.exactly(1)
  self
end

#raisesExpectation #raises(exception) ⇒ Expectation #raises(exception, message) ⇒ Expectation

Modifies expectation so that when the expected method is called, it raises the specified exception with the specified message i.e. calls Kernel#raise(exception, message).

Examples:

Raise specified exception if expected method is invoked.

object = stub()
object.stubs(:expected_method).raises(Exception, 'message')
object.expected_method # => raises exception of class Exception and with message 'message'

Raise custom exception with extra constructor parameters by passing in an instance of the exception.

object = stub()
object.stubs(:expected_method).raises(MyException.new('message', 1, 2, 3))
object.expected_method # => raises the specified instance of MyException

Raise different exceptions on consecutive invocations of the expected method.

object = stub()
object.stubs(:expected_method).raises(Exception1).then.raises(Exception2)
object.expected_method # => raises exception of class Exception1
object.expected_method # => raises exception of class Exception2

Raise an exception on first invocation of expected method and then return values on subsequent invocations.

object = stub()
object.stubs(:expected_method).raises(Exception).then.returns(2, 3)
object.expected_method # => raises exception of class Exception1
object.expected_method # => 2
object.expected_method # => 3

Parameters:

  • exception (Class, Exception, String, #exception) (defaults to: RuntimeError)

    exception to be raised or message to be passed to RuntimeError.

  • message (String) (defaults to: nil)

    exception message.

Returns:

See Also:



462
463
464
465
# File 'lib/mocha/expectation.rb', line 462

def raises(exception = RuntimeError, message = nil)
  @return_values += ReturnValues.new(ExceptionRaiser.new(exception, message))
  self
end

#returns(value) ⇒ Expectation #returns(*values) ⇒ Expectation

Modifies expectation so that when the expected method is called, it returns the specified value.

Examples:

Return the same value on every invocation.

object = mock()
object.stubs(:stubbed_method).returns('result')
object.stubbed_method # => 'result'
object.stubbed_method # => 'result'

Return a different value on consecutive invocations.

object = mock()
object.stubs(:stubbed_method).returns(1, 2)
object.stubbed_method # => 1
object.stubbed_method # => 2

Alternative way to return a different value on consecutive invocations.

object = mock()
object.stubs(:expected_method).returns(1, 2).then.returns(3)
object.expected_method # => 1
object.expected_method # => 2
object.expected_method # => 3

May be called in conjunction with #raises on the same expectation.

object = mock()
object.stubs(:expected_method).returns(1, 2).then.raises(Exception)
object.expected_method # => 1
object.expected_method # => 2
object.expected_method # => raises exception of class Exception1

Note that in Ruby a method returning multiple values is exactly equivalent to a method returning an Array of those values.

object = mock()
object.stubs(:expected_method).returns([1, 2])
x, y = object.expected_method
x # => 1
y # => 2

Overloads:

  • #returns(value) ⇒ Expectation

    Parameters:

    • value (Object)

      value to return on invocation of expected method.

  • #returns(*values) ⇒ Expectation

    Parameters:

    • values (*Array)

      values to return on consecutive invocations of expected method.

Returns:

See Also:



422
423
424
425
# File 'lib/mocha/expectation.rb', line 422

def returns(*values)
  @return_values += ReturnValues.build(*values)
  self
end

#thenExpectation #then(state) ⇒ Expectation

Returns the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

Examples:

Using #then as syntactic sugar when specifying values to be returned and exceptions to be raised on consecutive invocations of the expected method.

object = mock()
object.stubs(:expected_method).returns(1, 2).then.raises(Exception).then.returns(4)
object.expected_method # => 1
object.expected_method # => 2
object.expected_method # => raises exception of class Exception
object.expected_method # => 4

Using #then to change the state of a state_machine on the invocation of an expected method.

power = states('power').starts_as('off')

radio = mock('radio')
radio.expects(:switch_on).then(power.is('on'))
radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
radio.expects(:adjust_volume).with(+5).when(power.is('on'))
radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
radio.expects(:adjust_volume).with(-5).when(power.is('on'))
radio.expects(:switch_off).then(power.is('off'))

Overloads:

  • #thenExpectation

    Used as syntactic sugar to improve readability. It has no effect on state of the expectation.

  • #then(state) ⇒ Expectation

    Used to change the state_machine to the specified state when the expected invocation occurs.

    Parameters:

    • state (StateMachine::State)

      state_machine.is(state_name) provides a mechanism to change the state_machine into the state specified by state_name when the expected method is invoked.

    See Also:

Returns:



536
537
538
539
# File 'lib/mocha/expectation.rb', line 536

def then(state = nil)
  add_side_effect(ChangeStateSideEffect.new(state)) if state
  self
end

#throw(tag) ⇒ Expectation #throw(tag, object) ⇒ Expectation

Modifies expectation so that when the expected method is called, it throws the specified tag with the specific return value object i.e. calls Kernel#throw(tag, object).

Examples:

Throw tag when expected method is invoked.

object = stub()
object.stubs(:expected_method).throws(:done)
object.expected_method # => throws tag :done

Throw tag with return value object c.f. Kernel#throw.

object = stub()
object.stubs(:expected_method).throws(:done, 'result')
object.expected_method # => throws tag :done and causes catch block to return 'result'

Throw different tags on consecutive invocations of the expected method.

object = stub()
object.stubs(:expected_method).throws(:done).then.throws(:continue)
object.expected_method # => throws :done
object.expected_method # => throws :continue

Throw tag on first invocation of expected method and then return values for subsequent invocations.

object = stub()
object.stubs(:expected_method).throws(:done).then.returns(2, 3)
object.expected_method # => throws :done
object.expected_method # => 2
object.expected_method # => 3

Parameters:

  • tag (Symbol, String)

    tag to throw to transfer control to the active catch block.

  • object (Object) (defaults to: nil)

    return value for the catch block.

Returns:

See Also:



501
502
503
504
# File 'lib/mocha/expectation.rb', line 501

def throws(tag, object = nil)
  @return_values += ReturnValues.new(Thrower.new(tag, object))
  self
end

#times(range) ⇒ Expectation

Modifies expectation so that the number of calls to the expected method must be within a specific range.

Examples:

Specifying a specific number of expected invocations.

object = mock()
object.expects(:expected_method).times(3)
3.times { object.expected_method }
# => verify succeeds

object = mock()
object.expects(:expected_method).times(3)
2.times { object.expected_method }
# => verify fails

Specifying a range in the number of expected invocations.

object = mock()
object.expects(:expected_method).times(2..4)
3.times { object.expected_method }
# => verify succeeds

object = mock()
object.expects(:expected_method).times(2..4)
object.expected_method
# => verify fails

Parameters:

  • range (Range, Integer)

    specifies the allowable range in the number of expected invocations.

Returns:



46
47
48
49
# File 'lib/mocha/expectation.rb', line 46

def times(range)
  @cardinality.times(range)
  self
end

#twiceExpectation

Modifies expectation so that the expected method must be called exactly twice.

Examples:

Expected method must be invoked exactly twice.

object = mock()
object.expects(:expected_method).twice
object.expected_method
object.expected_method
# => verify succeeds

object = mock()
object.expects(:expected_method).twice
object.expected_method
object.expected_method
object.expected_method # => unexpected invocation

object = mock()
object.expects(:expected_method).twice
object.expected_method
# => verify fails

Returns:



72
73
74
75
# File 'lib/mocha/expectation.rb', line 72

def twice
  @cardinality.exactly(2)
  self
end

#when(state_predicate) ⇒ Expectation

Constrains the expectation to occur only when the state_machine is in the state specified by state_predicate.

Examples:

Using #when to only allow invocation of methods when “power” state machine is in the “on” state.

power = states('power').starts_as('off')

radio = mock('radio')
radio.expects(:switch_on).then(power.is('on'))
radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
radio.expects(:adjust_volume).with(+5).when(power.is('on'))
radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
radio.expects(:adjust_volume).with(-5).when(power.is('on'))
radio.expects(:switch_off).then(power.is('off'))

Parameters:

  • state_predicate (StateMachine::StatePredicate)

    state_machine.is(state_name) provides a mechanism to determine whether the state_machine is in the state specified by state_predicate when the expected method is invoked.

Returns:

See Also:



560
561
562
563
# File 'lib/mocha/expectation.rb', line 560

def when(state_predicate)
  add_ordering_constraint(InStateOrderingConstraint.new(state_predicate))
  self
end

#with(*expected_parameters_or_matchers) {|actual_parameters| ... } ⇒ Expectation

Modifies expectation so that the expected method must be called with expected_parameters_or_matchers.

May be used with Ruby literals or variables for exact matching or with parameter matchers for less-specific matching, e.g. ParameterMatchers#includes, ParameterMatchers#has_key, etc. See ParameterMatchers for a list of all available parameter matchers.

Positional arguments were separated from keyword arguments in Ruby v3 (see this article). In relation to this a new configuration option (Configuration#strict_keyword_argument_matching=) is available in Ruby >= 2.7.

When Configuration#strict_keyword_argument_matching= is set to false (which is currently the default), a positional Hash and a set of keyword arguments passed to #with are treated the same for the purposes of parameter matching. However, a deprecation warning will be displayed if a positional Hash matches a set of keyword arguments or vice versa. This is because Configuration#strict_keyword_argument_matching= will default to true in the future.

When Configuration#strict_keyword_argument_matching= is set to true, an actual positional Hash will not match an expected set of keyword arguments; and vice versa, an actual set of keyword arguments will not match an expected positional Hash, i.e. the parameter matching is stricter.

Examples:

Expected method must be called with exact parameter values.

object = mock()
object.expects(:expected_method).with(:param1, :param2)
object.expected_method(:param1, :param2)
# => verify succeeds

object = mock()
object.expects(:expected_method).with(:param1, :param2)
object.expected_method(:param3)
# => verify fails

Expected method must be called with parameters matching parameter matchers.

object = mock()
object.expects(:expected_method).with(includes('string2'), anything)
object.expected_method(['string1', 'string2'], 'any-old-value')
# => verify succeeds

object = mock()
object.expects(:expected_method).with(includes('string2'), anything)
object.expected_method(['string1'], 'any-old-value')
# => verify fails

Loose keyword argument matching (default)


class Example
  def foo(a, bar:); end
end

example = Example.new
example.expects(:foo).with('a', bar: 'b')
example.foo('a', { bar: 'b' })
# This passes the test, but would result in an ArgumentError in practice

Strict keyword argument matching


Mocha.configure do |c|
  c.strict_keyword_argument_matching = true
end

class Example
  def foo(a, bar:); end
end

example = Example.new
example.expects(:foo).with('a', bar: 'b')
example.foo('a', { bar: 'b' })
# This now fails as expected

Expected method must be called with a value divisible by 4.

object = mock()
object.expects(:expected_method).with() { |value| value % 4 == 0 }
object.expected_method(16)
# => verify succeeds

object = mock()
object.expects(:expected_method).with() { |value| value % 4 == 0 }
object.expected_method(17)
# => verify fails

Parameters:

  • expected_parameters_or_matchers (*Array<Object,ParameterMatchers::Base>)

    expected parameter values or parameter matchers.

Yields:

  • optional block specifying custom matching.

Yield Parameters:

  • actual_parameters (*Array<Object>)

    parameters with which expected method was invoked.

Yield Returns:

  • (Boolean)

    true if actual_parameters are acceptable.

Returns:

See Also:



269
270
271
272
# File 'lib/mocha/expectation.rb', line 269

def with(*expected_parameters_or_matchers, &matching_block)
  @parameters_matcher = ParametersMatcher.new(expected_parameters_or_matchers, self, &matching_block)
  self
end

#with_block_givenExpectation

Modifies expectation so that the expected method must be called with a block.

Examples:

Expected method must be called with a block.

object = mock()
object.expects(:expected_method).with_block_given
object.expected_method { 1 + 1 }
# => verify succeeds

object = mock()
object.expects(:expected_method).with_block_given
object.expected_method
# => verify fails

Returns:



289
290
291
292
# File 'lib/mocha/expectation.rb', line 289

def with_block_given
  @block_matcher = BlockMatchers::BlockGiven.new
  self
end

#with_no_block_givenExpectation

Modifies expectation so that the expected method must be called without a block.

Examples:

Expected method must be called without a block.

object = mock()
object.expects(:expected_method).with_no_block_given
object.expected_method
# => verify succeeds

object = mock()
object.expects(:expected_method).with_block_given
object.expected_method { 1 + 1 }
# => verify fails

Returns:



308
309
310
311
# File 'lib/mocha/expectation.rb', line 308

def with_no_block_given
  @block_matcher = BlockMatchers::NoBlockGiven.new
  self
end

#yields(*parameters) ⇒ Expectation

Modifies expectation so that when the expected method is called, it yields to the block with the specified parameters.

If no parameters are specified, it yields to the block without any parameters.

If no block is provided, the method will still attempt to yield resulting in a LocalJumpError. Note that this is what would happen if a “real” (non-mock) method implementation tried to yield to a non-existent block.

May be called multiple times on the same expectation for consecutive invocations.

Examples:

Yield when expected method is invoked.

benchmark = mock()
benchmark.expects(:measure).yields
yielded = false
benchmark.measure { yielded = true }
yielded # => true

Yield parameters when expected method is invoked.

fibonacci = mock()
fibonacci.expects(:next_pair).yields(0, 1)
sum = 0
fibonacci.next_pair { |first, second| sum = first + second }
sum # => 1

Yield different parameters on different invocations of the expected method.

fibonacci = mock()
fibonacci.expects(:next_pair).yields(0, 1).then.yields(1, 1)
sum = 0
fibonacci.next_pair { |first, second| sum = first + second }
sum # => 1
fibonacci.next_pair { |first, second| sum = first + second }
sum # => 2

Parameters:

  • parameters (*Array)

    parameters to be yielded.

Returns:

See Also:



347
348
349
# File 'lib/mocha/expectation.rb', line 347

def yields(*parameters)
  multiple_yields(parameters)
end
mocha-2.4.2/docs/Mocha/ExpectationError.html000066400000000000000000000057201464615054400207650ustar00rootroot00000000000000 Exception: Mocha::ExpectationError — Mocha 2.4.2

Exception: Mocha::ExpectationError

Inherits:
Exception
  • Object
show all
Defined in:
lib/mocha/expectation_error.rb

Overview

Default exception class raised when an unexpected invocation or an unsatisfied expectation occurs.

Authors of test libraries may use Mocha::ExpectationErrorFactory to have Mocha raise a different exception.

mocha-2.4.2/docs/Mocha/ExpectationErrorFactory.html000066400000000000000000000127771464615054400223270ustar00rootroot00000000000000 Class: Mocha::ExpectationErrorFactory — Mocha 2.4.2

Class: Mocha::ExpectationErrorFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/expectation_error_factory.rb

Overview

This factory determines what class of exception should be raised when Mocha detects a test failure.

This class should only be used by authors of test libraries and not by typical “users” of Mocha.

For example, it is used by Mocha::Integration::Minitest::Adapter in order to have Mocha raise a Minitest::Assertion which can then be sensibly handled by Minitest::Unit::TestCase.

Class Attribute Summary collapse

Class Attribute Details

.exception_classException

Determines what class of exception should be raised when Mocha detects a test failure.

This attribute may be set by authors of test libraries in order to have Mocha raise exceptions of a specific class when there is an unexpected invocation or an unsatisfied expectation.

By default a Mocha::ExpectationError will be raised.

Returns:

  • (Exception)

    class of exception to be raised when an expectation error occurs

See Also:



23
24
25
# File 'lib/mocha/expectation_error_factory.rb', line 23

def exception_class
  @exception_class
end
mocha-2.4.2/docs/Mocha/Hooks.html000066400000000000000000000245151464615054400165560ustar00rootroot00000000000000 Module: Mocha::Hooks — Mocha 2.4.2

Module: Mocha::Hooks

Included in:
API
Defined in:
lib/mocha/hooks.rb

Overview

Integration hooks for test library authors.

The methods in this module should be called from test libraries wishing to integrate with Mocha.

This module is provided as part of the Mocha::API module and is therefore part of the public API, but should only be used by authors of test libraries and not by typical “users” of Mocha.

Integration with Test::Unit and Minitest are provided as part of Mocha, because they are (or were once) part of the Ruby standard library. Integration with other test libraries is not provided as part of Mocha, but is supported by means of the methods in this module.

See the code in the Adapter modules for examples of how to use the methods in this module. Mocha::ExpectationErrorFactory may be used if you want Mocha to raise a different type of exception.

Instance Method Summary collapse

Instance Method Details

#mocha_setupObject

Prepares Mocha before a test (only for use by authors of test libraries).

This method should be called before each individual test starts (including before any “setup” code).



22
23
24
# File 'lib/mocha/hooks.rb', line 22

def mocha_setup
  Mockery.setup
end

#mocha_teardown(origin = mocha_test_name) ⇒ Object

Resets Mocha after a test (only for use by authors of test libraries).

This method should be called after each individual test has finished (including after any “teardown” code).



38
39
40
# File 'lib/mocha/hooks.rb', line 38

def mocha_teardown(origin = mocha_test_name)
  Mockery.teardown(origin)
end

#mocha_test_nameObject

Returns a string representing the unit test name, to be included in some Mocha to help track down potential bugs.



44
45
46
# File 'lib/mocha/hooks.rb', line 44

def mocha_test_name
  nil
end

#mocha_verify(assertion_counter = nil) ⇒ Object

Verifies that all mock expectations have been met (only for use by authors of test libraries).

This is equivalent to a series of “assertions”.

This method should be called at the end of each individual test, before it has been determined whether or not the test has passed.



31
32
33
# File 'lib/mocha/hooks.rb', line 31

def mocha_verify(assertion_counter = nil)
  Mockery.verify(assertion_counter)
end
mocha-2.4.2/docs/Mocha/Integration.html000066400000000000000000000046421464615054400177550ustar00rootroot00000000000000 Module: Mocha::Integration — Mocha 2.4.2

Module: Mocha::Integration

Defined in:
lib/mocha/integration/test_unit/adapter.rb,
lib/mocha/integration/minitest/adapter.rb

Defined Under Namespace

Modules: Minitest, TestUnit

mocha-2.4.2/docs/Mocha/Integration/000077500000000000000000000000001464615054400170615ustar00rootroot00000000000000mocha-2.4.2/docs/Mocha/Integration/MiniTest.html000066400000000000000000000046371464615054400215150ustar00rootroot00000000000000 Module: Mocha::Integration::Minitest — Mocha 2.4.2

Module: Mocha::Integration::Minitest

Defined in:
lib/mocha/integration/minitest/adapter.rb

Defined Under Namespace

Modules: Adapter

mocha-2.4.2/docs/Mocha/Integration/MiniTest/000077500000000000000000000000001464615054400206155ustar00rootroot00000000000000mocha-2.4.2/docs/Mocha/Integration/MiniTest/Adapter.html000066400000000000000000000174041464615054400230710ustar00rootroot00000000000000 Module: Mocha::Integration::Minitest::Adapter — Mocha 2.4.2

Module: Mocha::Integration::Minitest::Adapter

Includes:
API
Defined in:
lib/mocha/integration/minitest/adapter.rb

Overview

Integrates Mocha into recent versions of Minitest.

See the source code for an example of how to integrate Mocha into a test library.

Method Summary

Methods included from API

#mock, #sequence, #states, #stub, #stub_everything

Methods included from Hooks

#mocha_setup, #mocha_teardown, #mocha_verify

Methods included from ParameterMatchers

#Not, #all_of, #any_of, #any_parameters, #anything, #equals, #equivalent_uri, #has_entries, #has_entry, #has_key, #has_keys, #has_value, #includes, #instance_of, #is_a, #kind_of, #optionally, #regexp_matches, #responds_with, #yaml_equivalent

mocha-2.4.2/docs/Mocha/Integration/TestUnit.html000066400000000000000000000046401464615054400215320ustar00rootroot00000000000000 Module: Mocha::Integration::TestUnit — Mocha 2.4.2

Module: Mocha::Integration::TestUnit

Defined in:
lib/mocha/integration/test_unit/adapter.rb

Defined Under Namespace

Modules: Adapter

mocha-2.4.2/docs/Mocha/Integration/TestUnit/000077500000000000000000000000001464615054400206405ustar00rootroot00000000000000mocha-2.4.2/docs/Mocha/Integration/TestUnit/Adapter.html000066400000000000000000000174071464615054400231170ustar00rootroot00000000000000 Module: Mocha::Integration::TestUnit::Adapter — Mocha 2.4.2

Module: Mocha::Integration::TestUnit::Adapter

Includes:
API
Defined in:
lib/mocha/integration/test_unit/adapter.rb

Overview

Integrates Mocha into recent versions of Test::Unit.

See the source code for an example of how to integrate Mocha into a test library.

Method Summary

Methods included from API

#mock, #sequence, #states, #stub, #stub_everything

Methods included from Hooks

#mocha_setup, #mocha_teardown, #mocha_verify

Methods included from ParameterMatchers

#Not, #all_of, #any_of, #any_parameters, #anything, #equals, #equivalent_uri, #has_entries, #has_entry, #has_key, #has_keys, #has_value, #includes, #instance_of, #is_a, #kind_of, #optionally, #regexp_matches, #responds_with, #yaml_equivalent

mocha-2.4.2/docs/Mocha/Mock.html000066400000000000000000001616261464615054400163710ustar00rootroot00000000000000 Class: Mocha::Mock — Mocha 2.4.2

Class: Mocha::Mock

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/mock.rb

Overview

Traditional mock object.

#expects and #stubs return an Expectation which can be further modified by methods on Expectation.

#responds_like and #responds_like_instance_of both return a Mock, and can therefore, be chained to the original creation methods in API. They force the mock to indicate what it is supposed to be mocking, thus making it a safer verifying mock. They check that the underlying responder will actually respond to the methods being stubbed, throwing a NoMethodError upon invocation otherwise.

Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The #stubs method is syntactic sugar to make the intent of the test more explicit.

When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations. For example, an expects(:foo).once expectation only matches once and will be ignored on future invocations while an expects(:foo).at_least_once expectation will always be matched against invocations.

This scheme allows you to:

  • Set up default stubs in your the setup method of your test class and override some of those stubs in individual tests.

  • Set up different once expectations for the same method with different action per invocation. However, it’s better to use the Expectation#returns method with multiple arguments to do this, as described below.

However, there are some possible “gotchas” caused by this scheme:

  • if you create an expectation and then a stub for the same method, the stub will always override the expectation and the expectation will never be met.

  • if you create a stub and then an expectation for the same method, the expectation will match, and when it stops matching the stub will be used instead, possibly masking test failures.

  • if you create different expectations for the same method, they will be invoked in the opposite order than that in which they were specified, rather than the same order.

The best thing to do is not set up multiple expectations and stubs for the same method with exactly the same matchers. Instead, use the Expectation#returns method with multiple arguments to create multiple actions for a method. You can also chain multiple calls to Expectation#returns and Expectation#raises (along with syntactic sugar Expectation#then if desired).

If you want to specify more complex ordering or order invocations across different mock objects, use the Expectation#in_sequence method to explicitly define a total or partial ordering of invocations.

Examples:

object = mock()
object.stubs(:expected_method).returns(1, 2).then.raises(Exception)
object.expected_method # => 1
object.expected_method # => 2
object.expected_method # => raises exception of class Exception1

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *arguments, &block) ⇒ Object



314
315
316
# File 'lib/mocha/mock.rb', line 314

def method_missing(symbol, *arguments, &block) # rubocop:disable Style/MethodMissingSuper
  handle_method_call(symbol, arguments, block)
end

Instance Method Details

#expects(method_name) ⇒ Expectation #expects(expected_methods_vs_return_values) ⇒ Expectation Also known as: __expects__

Adds an expectation that the specified method must be called exactly once with any parameters.

Examples:

Expected method invoked once so no error raised

object = mock()
object.expects(:expected_method)
object.expected_method

Expected method not invoked so error raised

object = mock()
object.expects(:expected_method)
# error raised when test completes, because expected_method not called exactly once

Expected method invoked twice so error raised

object = mock()
object.expects(:expected_method)
object.expected_method
object.expected_method # => error raised when expected method invoked second time

Setup multiple expectations using expected_methods_vs_return_values.

object = mock()
object.expects(expected_method_one: :result_one, expected_method_two: :result_two)

# is exactly equivalent to

object = mock()
object.expects(:expected_method_one).returns(:result_one)
object.expects(:expected_method_two).returns(:result_two)

Overloads:

  • #expects(method_name) ⇒ Expectation

    Parameters:

    • method_name (Symbol, String)

      name of expected method

  • #expects(expected_methods_vs_return_values) ⇒ Expectation

    Parameters:

    • expected_methods_vs_return_values (Hash)

      expected method name symbols as keys and corresponding return values as values - these expectations are setup as if #expects were called multiple times.

Returns:



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/mocha/mock.rb', line 110

def expects(method_name_or_hash, backtrace = nil)
  expectation = nil
  iterator = ArgumentIterator.new(method_name_or_hash)
  iterator.each do |*args|
    method_name = args.shift
    ensure_method_not_already_defined(method_name)
    expectation = Expectation.new(self, method_name, backtrace)
    expectation.in_sequence(@mockery.sequences.last) if @mockery.sequences.any?
    expectation.returns(args.shift) unless args.empty?
    @expectations.add(expectation)
  end
  expectation
end

#responds_like(responder) ⇒ Mock Also known as: quacks_like

Constrains the Mocha::Mock instance so that it can only expect or stub methods to which responder responds publicly. The constraint is only applied at method invocation time.

A NoMethodError will be raised if the responder does not publicly #respond_to? the invoked method (even if the method has been expected or stubbed).

The Mocha::Mock instance will delegate its #respond_to? method to the responder. However, the include_all parameter is not passed through, so only public methods on the responder will be considered.

Note that the methods on responder are never actually invoked.

Examples:

Normal mocking

sheep = mock('sheep')
sheep.expects(:chew)
sheep.expects(:foo)
sheep.respond_to?(:chew) # => true
sheep.respond_to?(:foo) # => true
sheep.chew
sheep.foo
# no error raised

Using #responds_like with an instance method

class Sheep
  def chew(grass); end
end

sheep = mock('sheep')
sheep.responds_like(Sheep.new)
sheep.expects(:chew)
sheep.expects(:foo)
sheep.respond_to?(:chew) # => true
sheep.respond_to?(:foo) # => false
sheep.chew
sheep.foo # => raises NoMethodError exception

Using #responds_like with a class method

class Sheep
  def self.number_of_legs; end
end

sheep_class = mock('sheep_class')
sheep_class.responds_like(Sheep)
sheep_class.stubs(:number_of_legs).returns(4)
sheep_class.expects(:foo)
sheep_class.respond_to?(:number_of_legs) # => true
sheep_class.respond_to?(:foo) # => false
sheep_class.number_of_legs # => 4
sheep_class.foo # => raises NoMethodError exception

Parameters:

  • responder (Object, #respond_to?)

    an object used to determine whether Mocha::Mock instance should #respond_to? to an invocation.

Returns:

See Also:



237
238
239
240
# File 'lib/mocha/mock.rb', line 237

def responds_like(responder)
  @responder = responder
  self
end

#responds_like_instance_of(responder_class) ⇒ Mock Also known as: quacks_like_instance_of

Constrains the Mocha::Mock instance so that it can only expect or stub methods to which an instance of the responder_class responds publicly. The constraint is only applied at method invocation time. Note that the responder instance is instantiated using Class#allocate.

A NoMethodError will be raised if the responder instance does not publicly #respond_to? the invoked method (even if the method has been expected or stubbed).

The Mocha::Mock instance will delegate its #respond_to? method to the responder instance. However, the include_all parameter is not passed through, so only public methods on the responder will be considered.

Note that the methods on the responder instance are never actually invoked.

Examples:

class Sheep
  def initialize
    raise "some awkward code we don't want to call"
  end
  def chew(grass); end
end

sheep = mock('sheep')
sheep.responds_like_instance_of(Sheep)
sheep.expects(:chew)
sheep.expects(:foo)
sheep.respond_to?(:chew) # => true
sheep.respond_to?(:foo) # => false
sheep.chew
sheep.foo # => raises NoMethodError exception

Parameters:

  • responder_class (Class)

    a class used to determine whether Mocha::Mock instance should #respond_to? to an invocation.

Returns:

See Also:



270
271
272
# File 'lib/mocha/mock.rb', line 270

def responds_like_instance_of(responder_class)
  responds_like(responder_class.allocate)
end

#stubs(method_name) ⇒ Expectation #stubs(stubbed_methods_vs_return_values) ⇒ Expectation Also known as: __stubs__

Adds an expectation that the specified method may be called any number of times with any parameters.

Examples:

No error raised however many times stubbed method is invoked

object = mock()
object.stubs(:stubbed_method)
object.stubbed_method
object.stubbed_method
# no error raised

Setup multiple expectations using stubbed_methods_vs_return_values.

object = mock()
object.stubs(stubbed_method_one: :result_one, stubbed_method_two: :result_two)

# is exactly equivalent to

object = mock()
object.stubs(:stubbed_method_one).returns(:result_one)
object.stubs(:stubbed_method_two).returns(:result_two)

Overloads:

  • #stubs(method_name) ⇒ Expectation

    Parameters:

    • method_name (Symbol, String)

      name of stubbed method

  • #stubs(stubbed_methods_vs_return_values) ⇒ Expectation

    Parameters:

    • stubbed_methods_vs_return_values (Hash)

      stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if #stubs were called multiple times.

Returns:



149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/mocha/mock.rb', line 149

def stubs(method_name_or_hash, backtrace = nil)
  expectation = nil
  iterator = ArgumentIterator.new(method_name_or_hash)
  iterator.each do |*args|
    method_name = args.shift
    ensure_method_not_already_defined(method_name)
    expectation = Expectation.new(self, method_name, backtrace)
    expectation.at_least(0)
    expectation.in_sequence(@mockery.sequences.last) if @mockery.sequences.any?
    expectation.returns(args.shift) unless args.empty?
    @expectations.add(expectation)
  end
  expectation
end

#unstub(*method_names) ⇒ Object

Removes the specified stubbed methods (added by calls to #expects or #stubs) and all expectations associated with them.

Examples:

Invoking an unstubbed method causes error to be raised

object = mock('mock')
object.stubs(:stubbed_method).returns(:result_one)
object.stubbed_method # => :result_one
object.unstub(:stubbed_method)
object.stubbed_method # => unexpected invocation: #<Mock:mock>.stubbed_method()

Unstubbing multiple methods.

multiplier.unstub(:double, :triple)

# exactly equivalent to

multiplier.unstub(:double)
multiplier.unstub(:triple)

Parameters:

  • method_names (Array<Symbol>)

    names of methods to unstub.



182
183
184
185
186
# File 'lib/mocha/mock.rb', line 182

def unstub(*method_names)
  method_names.each do |method_name|
    @expectations.remove_all_matching_method(method_name)
  end
end
mocha-2.4.2/docs/Mocha/ObjectMethods.html000066400000000000000000001062341464615054400202240ustar00rootroot00000000000000 Module: Mocha::ObjectMethods — Mocha 2.4.2

Module: Mocha::ObjectMethods

Defined in:
lib/mocha/object_methods.rb

Overview

Methods added to all objects to allow mocking and stubbing on real (i.e. non-mock) objects.

Both #expects and #stubs return an Expectation which can be further modified by methods on Expectation.

Instance Method Summary collapse

Instance Method Details

#expects(method_name) ⇒ Expectation #expects(expected_methods_vs_return_values) ⇒ Expectation

Adds an expectation that the specified method must be called exactly once with any parameters.

The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.

Examples:

Setting up an expectation on a non-mock object.

product = Product.new
product.expects(:save).returns(true)
assert_equal true, product.save

Setting up multiple expectations on a non-mock object.

product = Product.new
product.expects(valid?: true, save: true)

# exactly equivalent to

product = Product.new
product.expects(:valid?).returns(true)
product.expects(:save).returns(true)

Overloads:

  • #expects(method_name) ⇒ Expectation

    Parameters:

    • method_name (Symbol, String)

      name of expected method

  • #expects(expected_methods_vs_return_values) ⇒ Expectation

    Parameters:

    • expected_methods_vs_return_values (Hash)

      expected method name symbols as keys and corresponding return values as values - these expectations are setup as if #expects were called multiple times.

Returns:

Raises:

  • (StubbingError)

    if attempting to stub method which is not allowed.

See Also:



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/mocha/object_methods.rb', line 71

def expects(expected_methods_vs_return_values)
  if expected_methods_vs_return_values.to_s =~ /the[^a-z]*spanish[^a-z]*inquisition/i
    raise ExpectationErrorFactory.build('NOBODY EXPECTS THE SPANISH INQUISITION!')
  end
  if frozen?
    raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
  end
  expectation = nil
  mockery = Mocha::Mockery.instance
  iterator = ArgumentIterator.new(expected_methods_vs_return_values)
  iterator.each do |*args|
    method_name = args.shift
    mockery.on_stubbing(self, method_name)
    method = stubba_method.new(stubba_object, method_name)
    mockery.stubba.stub(method)
    expectation = mocha.expects(method_name, caller)
    expectation.returns(args.shift) unless args.empty?
  end
  expectation
end

#stubs(method_name) ⇒ Expectation #stubs(stubbed_methods_vs_return_values) ⇒ Expectation

Adds an expectation that the specified method may be called any number of times with any parameters.

The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.

Examples:

Setting up a stubbed methods on a non-mock object.

product = Product.new
product.stubs(:save).returns(true)
assert_equal true, product.save

Setting up multiple stubbed methods on a non-mock object.

product = Product.new
product.stubs(valid?: true, save: true)

# exactly equivalent to

product = Product.new
product.stubs(:valid?).returns(true)
product.stubs(:save).returns(true)

Overloads:

  • #stubs(method_name) ⇒ Expectation

    Parameters:

    • method_name (Symbol, String)

      name of stubbed method

  • #stubs(stubbed_methods_vs_return_values) ⇒ Expectation

    Parameters:

    • stubbed_methods_vs_return_values (Hash)

      stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if #stubs were called multiple times.

Returns:

Raises:

  • (StubbingError)

    if attempting to stub method which is not allowed.

See Also:



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/mocha/object_methods.rb', line 120

def stubs(stubbed_methods_vs_return_values)
  if frozen?
    raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
  end
  expectation = nil
  mockery = Mocha::Mockery.instance
  iterator = ArgumentIterator.new(stubbed_methods_vs_return_values)
  iterator.each do |*args|
    method_name = args.shift
    mockery.on_stubbing(self, method_name)
    method = stubba_method.new(stubba_object, method_name)
    mockery.stubba.stub(method)
    expectation = mocha.stubs(method_name, caller)
    expectation.returns(args.shift) unless args.empty?
  end
  expectation
end

#unstub(*method_names) ⇒ Object

Removes the specified stubbed methods (added by calls to #expects or #stubs) and all expectations associated with them.

Restores the original behaviour of the methods before they were stubbed. This is normally done automatically at the end of each test, but in some circumstances you may want to do it before the end of the test.

WARNING: If you #unstub a method which still has unsatisfied expectations, you may be removing the only way those expectations can be satisfied. Use #unstub with care.

Examples:

Stubbing and unstubbing a method on a real (non-mock) object.

multiplier = Multiplier.new
multiplier.double(2) # => 4
multiplier.stubs(:double).raises # new behaviour defined
multiplier.double(2) # => raises exception
multiplier.unstub(:double) # original behaviour restored
multiplier.double(2) # => 4

Unstubbing multiple methods on a real (non-mock) object.

multiplier.unstub(:double, :triple)

# exactly equivalent to

multiplier.unstub(:double)
multiplier.unstub(:triple)

Parameters:

  • method_names (Array<Symbol>)

    names of methods to unstub.



161
162
163
164
165
166
167
# File 'lib/mocha/object_methods.rb', line 161

def unstub(*method_names)
  mockery = Mocha::Mockery.instance
  method_names.each do |method_name|
    method = stubba_method.new(stubba_object, method_name)
    mockery.stubba.unstub(method)
  end
end
mocha-2.4.2/docs/Mocha/ParameterMatchers.html000066400000000000000000004433401464615054400211030ustar00rootroot00000000000000 Module: Mocha::ParameterMatchers — Mocha 2.4.2

Module: Mocha::ParameterMatchers

Included in:
API
Defined in:
lib/mocha/parameter_matchers.rb,
lib/mocha/parameter_matchers/not.rb,
lib/mocha/parameter_matchers/base.rb,
lib/mocha/parameter_matchers/is_a.rb,
lib/mocha/parameter_matchers/all_of.rb,
lib/mocha/parameter_matchers/any_of.rb,
lib/mocha/parameter_matchers/equals.rb,
lib/mocha/parameter_matchers/has_key.rb,
lib/mocha/parameter_matchers/kind_of.rb,
lib/mocha/parameter_matchers/anything.rb,
lib/mocha/parameter_matchers/has_keys.rb,
lib/mocha/parameter_matchers/includes.rb,
lib/mocha/parameter_matchers/has_entry.rb,
lib/mocha/parameter_matchers/has_value.rb,
lib/mocha/parameter_matchers/optionally.rb,
lib/mocha/parameter_matchers/has_entries.rb,
lib/mocha/parameter_matchers/instance_of.rb,
lib/mocha/parameter_matchers/responds_with.rb,
lib/mocha/parameter_matchers/any_parameters.rb,
lib/mocha/parameter_matchers/equivalent_uri.rb,
lib/mocha/parameter_matchers/regexp_matches.rb,
lib/mocha/parameter_matchers/yaml_equivalent.rb,
lib/mocha/parameter_matchers/instance_methods.rb,
lib/mocha/parameter_matchers/positional_or_keyword_hash.rb

Overview

Used as parameters for Expectation#with to restrict the parameter values which will match the expectation. Can be nested.

Defined Under Namespace

Classes: AllOf, AnyOf, AnyParameters, Anything, Base, Equals, EquivalentUri, HasEntries, HasEntry, HasKey, HasKeys, HasValue, Includes, InstanceOf, IsA, KindOf, Not, Optionally, RegexpMatches, RespondsWith, YamlEquivalent

Instance Method Summary collapse

Instance Method Details

#all_of(*matchers) ⇒ AllOf

Matches if all matchers match.

Examples:

All parameter matchers match.

object = mock()
object.expects(:method_1).with(all_of(includes(1), includes(3)))
object.method_1([1, 3])
# no error raised

One of the parameter matchers does not match.

object = mock()
object.expects(:method_1).with(all_of(includes(1), includes(3)))
object.method_1([1, 2])
# error raised, because method_1 was not called with object including 1 and 3

Parameters:

  • matchers (*Array<Base>)

    parameter matchers.

Returns:

  • (AllOf)

    parameter matcher.

See Also:



23
24
25
# File 'lib/mocha/parameter_matchers/all_of.rb', line 23

def all_of(*matchers)
  AllOf.new(*matchers)
end

#any_of(*matchers) ⇒ AnyOf

Matches if any matchers match.

Examples:

One parameter matcher matches.

object = mock()
object.expects(:method_1).with(any_of(1, 3))
object.method_1(1)
# no error raised

The other parameter matcher matches.

object = mock()
object.expects(:method_1).with(any_of(1, 3))
object.method_1(3)
# no error raised

Neither parameter matcher matches.

object = mock()
object.expects(:method_1).with(any_of(1, 3))
object.method_1(2)
# error raised, because method_1 was not called with 1 or 3

Parameters:

  • matchers (*Array<Base>)

    parameter matchers.

Returns:

  • (AnyOf)

    parameter matcher.

See Also:



29
30
31
# File 'lib/mocha/parameter_matchers/any_of.rb', line 29

def any_of(*matchers)
  AnyOf.new(*matchers)
end

#any_parametersAnyParameters

Matches any parameters. This is used as the default for a newly built expectation.

Examples:

Any parameters will match.

object = mock()
object.expects(:method_1).with(any_parameters)
object.method_1(1, 2, 3, 4)
# no error raised

object = mock()
object.expects(:method_1).with(any_parameters)
object.method_1(5, 6, 7, 8, 9, 0)
# no error raised

Returns:

See Also:



21
22
23
# File 'lib/mocha/parameter_matchers/any_parameters.rb', line 21

def any_parameters
  AnyParameters.new
end

#anythingAnything

Matches any object.

Examples:

Any object will match.

object = mock()
object.expects(:method_1).with(anything)
object.method_1('foo')
object.method_1(789)
object.method_1(:bar)
# no error raised

Returns:

See Also:



18
19
20
# File 'lib/mocha/parameter_matchers/anything.rb', line 18

def anything
  Anything.new
end

#equals(value) ⇒ Equals

Matches any Object equalling value.

Examples:

Actual parameter equals expected parameter.

object = mock()
object.expects(:method_1).with(equals(2))
object.method_1(2)
# no error raised

Actual parameter does not equal expected parameter.

object = mock()
object.expects(:method_1).with(equals(2))
object.method_1(3)
# error raised, because method_1 was not called with an +Object+ that equals 2

Parameters:

  • value (Object)

    expected value.

Returns:

  • (Equals)

    parameter matcher.

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/equals.rb', line 24

def equals(value)
  Equals.new(value)
end

#equivalent_uri(uri) ⇒ EquivalentUri

Matches a URI without regard to the ordering of parameters in the query string.

Examples:

Actual URI is equivalent.

object = mock()
object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2))
object.method_1('http://example.com/foo?b=2&a=1')
# no error raised

Actual URI is not equivalent.

object = mock()
object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2))
object.method_1('http://example.com/foo?a=1&b=3')
# error raised, because the query parameters were different

Parameters:

  • uri (String)

    URI to match.

Returns:

See Also:



25
26
27
# File 'lib/mocha/parameter_matchers/equivalent_uri.rb', line 25

def equivalent_uri(uri)
  EquivalentUri.new(uri)
end

#has_entries(entries) ⇒ HasEntries

Matches Hash containing all entries.

Examples:

Actual parameter contains all expected entries.

object = mock()
object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
object.method_1('key_1' => 1, 'key_2' => 2, 'key_3' => 3)
# no error raised

Actual parameter does not contain all expected entries.

object = mock()
object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
object.method_1('key_1' => 1, 'key_2' => 99)
# error raised, because method_1 was not called with Hash containing entries: 'key_1' => 1, 'key_2' => 2

Parameters:

  • entries (Hash)

    expected Hash entries.

Returns:

See Also:



26
27
28
# File 'lib/mocha/parameter_matchers/has_entries.rb', line 26

def has_entries(entries) # rubocop:disable Naming/PredicateName
  HasEntries.new(entries)
end

#has_entry(key, value) ⇒ HasEntry #has_entry(single_entry_hash) ⇒ HasEntry

Matches Hash containing entry with key and value.

Examples:

Actual parameter contains expected entry supplied as key and value.

object = mock()
object.expects(:method_1).with(has_entry('key_1', 1))
object.method_1('key_1' => 1, 'key_2' => 2)
# no error raised

Actual parameter contains expected entry supplied as Hash entry.

object = mock()
object.expects(:method_1).with(has_entry('key_1' => 1))
object.method_1('key_1' => 1, 'key_2' => 2)
# no error raised

Actual parameter does not contain expected entry supplied as key and value.

object = mock()
object.expects(:method_1).with(has_entry('key_1', 1))
object.method_1('key_1' => 2, 'key_2' => 1)
# error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1

Actual parameter does not contain expected entry supplied as Hash entry.


object = mock()
object.expects(:method_1).with(has_entry('key_1' => 1))
object.method_1('key_1' => 2, 'key_2' => 1)
# error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1

Overloads:

  • #has_entry(key, value) ⇒ HasEntry

    Parameters:

    • key (Object)

      key for entry.

    • value (Object)

      value for entry.

  • #has_entry(single_entry_hash) ⇒ HasEntry

    Parameters:

    • single_entry_hash (Hash)

      Hash with single entry.

    Raises:

    • (ArgumentError)

      if single_entry_hash does not contain exactly one entry.

Returns:

See Also:



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/mocha/parameter_matchers/has_entry.rb', line 43

def has_entry(*options) # rubocop:disable Naming/PredicateName
  case options.length
  when 0
    raise ArgumentError, 'No arguments. Expecting at least one.'
  when 1
    key, value = parse_option(options[0])
  when 2
    key, value = options
  else
    raise ArgumentError, 'Too many arguments; use either a single argument (must be a Hash) or two arguments (a key and a value).'
  end
  HasEntry.new(key, value)
end

#has_key(key) ⇒ HasKey

Matches Hash containing key.

Examples:

Actual parameter contains entry with expected key.

object = mock()
object.expects(:method_1).with(has_key('key_1'))
object.method_1('key_1' => 1, 'key_2' => 2)
# no error raised

Actual parameter does not contain entry with expected key.

object = mock()
object.expects(:method_1).with(has_key('key_1'))
object.method_1('key_2' => 2)
# error raised, because method_1 was not called with Hash containing key: 'key_1'

Parameters:

  • key (Object)

    expected key.

Returns:

  • (HasKey)

    parameter matcher.

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/has_key.rb', line 24

def has_key(key) # rubocop:disable Naming/PredicateName
  HasKey.new(key)
end

#has_keys(*keys) ⇒ HasKeys

Matches Hash containing keys.

Examples:

Actual parameter contains entry with expected keys.

object = mock()
object.expects(:method_1).with(has_keys(:key_1, :key_2))
object.method_1(:key_1 => 1, :key_2 => 2, :key_3 => 3)
# no error raised

Actual parameter does not contain all expected keys.

object = mock()
object.expects(:method_1).with(has_keys(:key_1, :key_2))
object.method_1(:key_2 => 2)
# error raised, because method_1 was not called with Hash containing key: :key_1

Parameters:

  • keys (*Array<Object>)

    expected keys.

Returns:

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/has_keys.rb', line 24

def has_keys(*keys) # rubocop:disable Naming/PredicateName
  HasKeys.new(*keys)
end

#has_value(value) ⇒ HasValue

Matches Hash containing value.

Examples:

Actual parameter contains entry with expected value.

object = mock()
object.expects(:method_1).with(has_value(1))
object.method_1('key_1' => 1, 'key_2' => 2)
# no error raised

Actual parameter does not contain entry with expected value.

object = mock()
object.expects(:method_1).with(has_value(1))
object.method_1('key_2' => 2)
# error raised, because method_1 was not called with Hash containing value: 1

Parameters:

  • value (Object)

    expected value.

Returns:

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/has_value.rb', line 24

def has_value(value) # rubocop:disable Naming/PredicateName
  HasValue.new(value)
end

#includes(*items) ⇒ Includes

Matches any object that responds with true to include?(item) for all items.

Examples:

Actual parameter includes all items.

object = mock()
object.expects(:method_1).with(includes('foo', 'bar'))
object.method_1(['foo', 'bar', 'baz'])
# no error raised

Actual parameter does not include all items.

object.method_1(['foo', 'baz'])
# error raised, because ['foo', 'baz'] does not include 'bar'.

Actual parameter includes item which matches nested matcher.

object = mock()
object.expects(:method_1).with(includes(has_key(:key)))
object.method_1(['foo', 'bar', {key: 'baz'}])
# no error raised

Actual parameter does not include item matching nested matcher.

object.method_1(['foo', 'bar', {:other_key => 'baz'}])
# error raised, because no element matches `has_key(:key)` matcher

Actual parameter is a String including substring.

object = mock()
object.expects(:method_1).with(includes('bar'))
object.method_1('foobarbaz')
# no error raised

Actual parameter is a String not including substring.

object.method_1('foobaz')
# error raised, because 'foobaz' does not include 'bar'

Actual parameter is a Hash including the given key.

object = mock()
object.expects(:method_1).with(includes(:bar))
object.method_1({foo: 1, bar: 2})
# no error raised

Actual parameter is a Hash without the given key.

object.method_1({foo: 1, baz: 2})
# error raised, because hash does not include key 'bar'

Actual parameter is a Hash with a key matching the given matcher.

object = mock()
object.expects(:method_1).with(includes(regexp_matches(/ar/)))
object.method_1({'foo' => 1, 'bar' => 2})
# no error raised

Actual parameter is a Hash no key matching the given matcher.

object.method_1({'foo' => 1, 'baz' => 3})
# error raised, because hash does not include a key matching /ar/

Parameters:

  • items (*Array)

    expected items.

Returns:

See Also:



63
64
65
# File 'lib/mocha/parameter_matchers/includes.rb', line 63

def includes(*items)
  Includes.new(*items)
end

#instance_of(klass) ⇒ InstanceOf

Matches any object that is an instance of klass

Examples:

Actual parameter is an instance of String.

object = mock()
object.expects(:method_1).with(instance_of(String))
object.method_1('string')
# no error raised

Actual parameter is not an instance of String.

object = mock()
object.expects(:method_1).with(instance_of(String))
object.method_1(99)
# error raised, because method_1 was not called with an instance of String

Parameters:

  • klass (Class)

    expected class.

Returns:

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/instance_of.rb', line 24

def instance_of(klass)
  InstanceOf.new(klass)
end

#is_a(klass) ⇒ IsA

Matches any object that is a klass.

Examples:

Actual parameter is a Integer.

object = mock()
object.expects(:method_1).with(is_a(Integer))
object.method_1(99)
# no error raised

Actual parameter is not a Integer.

object = mock()
object.expects(:method_1).with(is_a(Integer))
object.method_1('string')
# error raised, because method_1 was not called with an Integer

Parameters:

  • klass (Class)

    expected class.

Returns:

  • (IsA)

    parameter matcher.

See Also:



25
26
27
# File 'lib/mocha/parameter_matchers/is_a.rb', line 25

def is_a(klass) # rubocop:disable Naming/PredicateName
  IsA.new(klass)
end

#kind_of(klass) ⇒ KindOf

Matches any Object that is a kind of klass.

Examples:

Actual parameter is a kind of Integer.

object = mock()
object.expects(:method_1).with(kind_of(Integer))
object.method_1(99)
# no error raised

Actual parameter is not a kind of Integer.

object = mock()
object.expects(:method_1).with(kind_of(Integer))
object.method_1('string')
# error raised, because method_1 was not called with a kind of Integer

Parameters:

  • klass (Class)

    expected class.

Returns:

  • (KindOf)

    parameter matcher.

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/kind_of.rb', line 24

def kind_of(klass)
  KindOf.new(klass)
end

#Not(matcher) ⇒ Not

Matches if matcher does not match.

Examples:

Actual parameter does not include the value 1.

object = mock()
object.expects(:method_1).with(Not(includes(1)))
object.method_1([0, 2, 3])
# no error raised

Actual parameter does include the value 1.

object = mock()
object.expects(:method_1).with(Not(includes(1)))
object.method_1([0, 1, 2, 3])
# error raised, because method_1 was not called with object not including 1

Parameters:

  • matcher (Base)

    matcher whose logic to invert.

Returns:

  • (Not)

    parameter matcher.

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/not.rb', line 24

def Not(matcher) # rubocop:disable Naming/MethodName
  Not.new(matcher)
end

#optionally(*matchers) ⇒ Optionally

Matches optional parameters if available.

Examples:

Only the two required parameters are supplied and they both match their expected value.

object = mock()
object.expects(:method_1).with(1, 2, optionally(3, 4))
object.method_1(1, 2)
# no error raised

Both required parameters and one of the optional parameters are supplied and they all match their expected value.

object = mock()
object.expects(:method_1).with(1, 2, optionally(3, 4))
object.method_1(1, 2, 3)
# no error raised

Both required parameters and both of the optional parameters are supplied and they all match their expected value.

object = mock()
object.expects(:method_1).with(1, 2, optionally(3, 4))
object.method_1(1, 2, 3, 4)
# no error raised

One of the actual optional parameters does not match the expected value.

object = mock()
object.expects(:method_1).with(1, 2, optionally(3, 4))
object.method_1(1, 2, 3, 5)
# error raised, because optional parameters did not match

Parameters:

  • matchers (*Array<Base>)

    matchers for optional parameters.

Returns:

See Also:



33
34
35
# File 'lib/mocha/parameter_matchers/optionally.rb', line 33

def optionally(*matchers)
  Optionally.new(*matchers)
end

#regexp_matches(regexp) ⇒ RegexpMatches

Matches any object that matches regexp.

Examples:

Actual parameter is matched by specified regular expression.

object = mock()
object.expects(:method_1).with(regexp_matches(/e/))
object.method_1('hello')
# no error raised

Actual parameter is not matched by specified regular expression.

object = mock()
object.expects(:method_1).with(regexp_matches(/a/))
object.method_1('hello')
# error raised, because method_1 was not called with a parameter that matched the
# regular expression

Parameters:

  • regexp (Regexp)

    regular expression to match.

Returns:

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/regexp_matches.rb', line 24

def regexp_matches(regexp)
  RegexpMatches.new(regexp)
end

#responds_with(message, result) ⇒ RespondsWith #responds_with(messages_vs_results) ⇒ RespondsWith

Returns parameter matcher.

Examples:

Actual parameter responds with “FOO” when :upcase is invoked.

object = mock()
object.expects(:method_1).with(responds_with(:upcase, "FOO"))
object.method_1("foo")
# no error raised, because "foo".upcase == "FOO"

Actual parameter does not respond with “FOO” when :upcase is invoked.

object = mock()
object.expects(:method_1).with(responds_with(:upcase, "BAR"))
object.method_1("foo")
# error raised, because "foo".upcase != "BAR"

Actual parameter responds with “FOO” when :upcase is invoked and “oof” when :reverse is invoked.

object = mock()
object.expects(:method_1).with(responds_with(upcase: "FOO", reverse: "oof"))
object.method_1("foo")
# no error raised, because "foo".upcase == "FOO" and "foo".reverse == "oof"

Overloads:

  • #responds_with(message, result) ⇒ RespondsWith

    Matches any object that responds to message with result. To put it another way, it tests the quack, not the duck.

    Parameters:

    • message (Symbol)

      method to invoke.

    • result (Object)

      expected result of sending message.

  • #responds_with(messages_vs_results) ⇒ RespondsWith

    Matches any object that responds to all the messages with the corresponding results as specified by messages_vs_results.

    Parameters:

    • messages_vs_results (Hash<Symbol,Object>)

      Hash of messages vs results.

    Raises:

    • (ArgumentError)

      if messages_vs_results does not contain at least one entry.

Returns:

See Also:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/mocha/parameter_matchers/responds_with.rb', line 37

def responds_with(*options)
  case options.length
  when 0
    raise ArgumentError, 'No arguments. Expecting at least one.'
  when 1
    option = options.first
    raise ArgumentError, 'Argument is not a Hash.' unless option.is_a?(Hash)
    raise ArgumentError, 'Argument has no entries.' if option.empty?

    matchers = option.map { |message, result| RespondsWith.new(message, result) }
    AllOf.new(*matchers)
  when 2
    message, result = options
    RespondsWith.new(message, result)
  else
    raise ArgumentError, 'Too many arguments; use either a single argument (must be a Hash) or two arguments (a message and a result).'
  end
end

#yaml_equivalent(object) ⇒ YamlEquivalent

Matches any YAML that represents the specified object

Examples:

Actual parameter is YAML equivalent of specified object.

object = mock()
object.expects(:method_1).with(yaml_equivalent(1, 2, 3))
object.method_1("--- \n- 1\n- 2\n- 3\n")
# no error raised

Actual parameter is not YAML equivalent of specified object.

object = mock()
object.expects(:method_1).with(yaml_equivalent(1, 2, 3))
object.method_1("--- \n- 1\n- 2\n")
# error raised, because method_1 was not called with YAML representing the specified Array

Parameters:

  • object (Object)

    object whose YAML to compare.

Returns:

See Also:



24
25
26
# File 'lib/mocha/parameter_matchers/yaml_equivalent.rb', line 24

def yaml_equivalent(object)
  YamlEquivalent.new(object)
end
mocha-2.4.2/docs/Mocha/ParameterMatchers/000077500000000000000000000000001464615054400202055ustar00rootroot00000000000000mocha-2.4.2/docs/Mocha/ParameterMatchers/AllOf.html000066400000000000000000000067361464615054400221040ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::AllOf — Mocha 2.4.2

Class: Mocha::ParameterMatchers::AllOf

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/all_of.rb

Overview

Parameter matcher which combines a number of other matchers using a logical AND.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/AnyOf.html000066400000000000000000000067351464615054400221220ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::AnyOf — Mocha 2.4.2

Class: Mocha::ParameterMatchers::AnyOf

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/any_of.rb

Overview

Parameter matcher which combines a number of other matchers using a logical OR.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/AnyParameters.html000066400000000000000000000067751464615054400236650ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::AnyParameters — Mocha 2.4.2

Class: Mocha::ParameterMatchers::AnyParameters

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/any_parameters.rb

Overview

Parameter matcher which always matches whatever the parameters.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/Anything.html000066400000000000000000000067311464615054400226630ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::Anything — Mocha 2.4.2

Class: Mocha::ParameterMatchers::Anything

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/anything.rb

Overview

Parameter matcher which always matches a single parameter.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/Base.html000066400000000000000000000422151464615054400217510ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::Base — Mocha 2.4.2

Class: Mocha::ParameterMatchers::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/base.rb

Overview

This class is abstract.

Subclass and implement #matches? and #mocha_inspect to define a custom matcher. Also add a suitably named instance method to Mocha::ParameterMatchers to build an instance of the new matcher c.f. #equals.

Instance Method Summary collapse

Instance Method Details

#&(other) ⇒ AllOf

A shorthand way of combining two matchers when both must match.

Returns a new AllOf parameter matcher combining two matchers using a logical AND.

This shorthand will not work with an implicit equals match. Instead, an explicit Equals matcher should be used.

Examples:

Alternative ways to combine matchers with a logical AND.

object = mock()
object.expects(:run).with(all_of(has_key(:foo), has_key(:bar)))
object.run(foo: 'foovalue', bar: 'barvalue')

# is exactly equivalent to

object.expects(:run).with(has_key(:foo) & has_key(:bar))
object.run(foo: 'foovalue', bar: 'barvalue)

Parameters:

  • other (Base)

    parameter matcher.

Returns:

  • (AllOf)

    parameter matcher.

See Also:



25
26
27
# File 'lib/mocha/parameter_matchers/base.rb', line 25

def &(other)
  AllOf.new(self, other)
end

#|(other) ⇒ AnyOf

A shorthand way of combining two matchers when at least one must match.

Returns a new AnyOf parameter matcher combining two matchers using a logical OR.

This shorthand will not work with an implicit equals match. Instead, an explicit Equals matcher should be used.

Examples:

Alternative ways to combine matchers with a logical OR.

object = mock()
object.expects(:run).with(any_of(has_key(:foo), has_key(:bar)))
object.run(foo: 'foovalue')

# is exactly equivalent to

object.expects(:run).with(has_key(:foo) | has_key(:bar))
object.run(foo: 'foovalue')

Using an explicit Equals matcher in combination with #|.

object.expects(:run).with(equals(1) | equals(2))
object.run(1) # passes
object.run(2) # passes
object.run(3) # fails

Parameters:

  • other (Base)

    parameter matcher.

Returns:

  • (AnyOf)

    parameter matcher.

See Also:



55
56
57
# File 'lib/mocha/parameter_matchers/base.rb', line 55

def |(other)
  AnyOf.new(self, other)
end
mocha-2.4.2/docs/Mocha/ParameterMatchers/Equals.html000066400000000000000000000067371464615054400223420ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::Equals — Mocha 2.4.2

Class: Mocha::ParameterMatchers::Equals

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/equals.rb

Overview

Parameter matcher which matches when actual parameter equals expected value.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/EquivalentUri.html000066400000000000000000000070011464615054400236660ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::EquivalentUri — Mocha 2.4.2

Class: Mocha::ParameterMatchers::EquivalentUri

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/equivalent_uri.rb

Overview

Parameter matcher which matches URIs with equivalent query strings.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/HasEntries.html000066400000000000000000000070221464615054400231410ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::HasEntries — Mocha 2.4.2

Class: Mocha::ParameterMatchers::HasEntries

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/has_entries.rb

Overview

Parameter matcher which matches when actual parameter contains all expected Hash entries.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/HasEntry.html000066400000000000000000000070001464615054400226250ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::HasEntry — Mocha 2.4.2

Class: Mocha::ParameterMatchers::HasEntry

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/has_entry.rb

Overview

Parameter matcher which matches when actual parameter contains expected Hash entry.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/HasKey.html000066400000000000000000000067751464615054400222760ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::HasKey — Mocha 2.4.2

Class: Mocha::ParameterMatchers::HasKey

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/has_key.rb

Overview

Parameter matcher which matches when actual parameter contains Hash entry with expected key.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/HasKeys.html000066400000000000000000000070021464615054400224410ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::HasKeys — Mocha 2.4.2

Class: Mocha::ParameterMatchers::HasKeys

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/has_keys.rb

Overview

Parameter matcher which matches when actual parameter contains Hash with all expected keys.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/HasValue.html000066400000000000000000000070131464615054400226040ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::HasValue — Mocha 2.4.2

Class: Mocha::ParameterMatchers::HasValue

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/has_value.rb

Overview

Parameter matcher which matches when actual parameter contains Hash entry with expected value.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/Includes.html000066400000000000000000000067561464615054400226570ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::Includes — Mocha 2.4.2

Class: Mocha::ParameterMatchers::Includes

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/includes.rb

Overview

Parameter matcher which matches when actual parameter includes expected values.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/InstanceOf.html000066400000000000000000000070101464615054400231220ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::InstanceOf — Mocha 2.4.2

Class: Mocha::ParameterMatchers::InstanceOf

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/instance_of.rb

Overview

Parameter matcher which matches when actual parameter is an instance of the specified class.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/IsA.html000066400000000000000000000067141464615054400215570ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::IsA — Mocha 2.4.2

Class: Mocha::ParameterMatchers::IsA

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/is_a.rb

Overview

Parameter matcher which matches when actual parameter is a specific class.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/KindOf.html000066400000000000000000000067471464615054400222630ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::KindOf — Mocha 2.4.2

Class: Mocha::ParameterMatchers::KindOf

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/kind_of.rb

Overview

Parameter matcher which matches when actual parameter is a kind of specified class.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/Not.html000066400000000000000000000067421464615054400216440ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::Not — Mocha 2.4.2

Class: Mocha::ParameterMatchers::Not

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/not.rb

Overview

Parameter matcher which inverts the logic of the specified matcher using a logical NOT operation.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/Optionally.html000066400000000000000000000067561464615054400232430ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::Optionally — Mocha 2.4.2

Class: Mocha::ParameterMatchers::Optionally

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/optionally.rb

Overview

Parameter matcher which allows optional parameters to be specified.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/RegexpMatches.html000066400000000000000000000070261464615054400236370ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::RegexpMatches — Mocha 2.4.2

Class: Mocha::ParameterMatchers::RegexpMatches

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/regexp_matches.rb

Overview

Parameter matcher which matches if specified regular expression matches actual paramter.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/RespondsWith.html000066400000000000000000000070451464615054400235320ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::RespondsWith — Mocha 2.4.2

Class: Mocha::ParameterMatchers::RespondsWith

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/responds_with.rb

Overview

Parameter matcher which matches if actual parameter returns expected result when specified method is invoked.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/ParameterMatchers/YamlEquivalent.html000066400000000000000000000070371464615054400240420ustar00rootroot00000000000000 Class: Mocha::ParameterMatchers::YamlEquivalent — Mocha 2.4.2

Class: Mocha::ParameterMatchers::YamlEquivalent

Inherits:
Base
  • Object
show all
Defined in:
lib/mocha/parameter_matchers/yaml_equivalent.rb

Overview

Parameter matcher which matches if actual parameter is YAML equivalent of specified object.

Method Summary

Methods inherited from Base

#&, #|

mocha-2.4.2/docs/Mocha/Sequence.html000066400000000000000000000055741464615054400172470ustar00rootroot00000000000000 Class: Mocha::Sequence — Mocha 2.4.2

Class: Mocha::Sequence

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/sequence.rb

Overview

Used to constrain the order in which expectations can occur.

mocha-2.4.2/docs/Mocha/StateMachine.html000066400000000000000000000460631464615054400200420ustar00rootroot00000000000000 Class: Mocha::StateMachine — Mocha 2.4.2

Class: Mocha::StateMachine

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/state_machine.rb

Overview

A state machine that is used to constrain the order of invocations. An invocation can be constrained to occur when a state #is, or #is_not, active.

Defined Under Namespace

Classes: State, StatePredicate

Instance Method Summary collapse

Instance Method Details

#become(next_state_name) ⇒ Object

Put the Mocha::StateMachine into the next_state_name.

Parameters:

  • next_state_name (String)

    name of new state



58
59
60
# File 'lib/mocha/state_machine.rb', line 58

def become(next_state_name)
  @current_state = next_state_name
end

#is(expected_state_name) ⇒ StatePredicate #is(desired_state_name) ⇒ State

Provides mechanisms to (a) determine whether the Mocha::StateMachine is in a given state; or (b) to change the Mocha::StateMachine into the given state.

Overloads:

  • #is(expected_state_name) ⇒ StatePredicate

    Provides a mechanism to determine whether the Mocha::StateMachine is in the state specified by expected_state_name at some point in the future

    Parameters:

    • expected_state_name (String)

      name of expected state.

    Returns:

  • #is(desired_state_name) ⇒ State

    Provides a mechanism to change the Mocha::StateMachine into the state specified by desired_state_name at some point in the future.

    Parameters:

    • desired_state_name (String)

      name of desired new state.

    Returns:

    • (State)

      state which, when activated, will change the Mocha::StateMachine into the state with the specified desired_state_name.

Parameters:

  • state_name (String)

    name of expected/desired state.

Returns:



76
77
78
# File 'lib/mocha/state_machine.rb', line 76

def is(state_name)
  State.new(self, state_name, 'is') { |current, given| current == given }
end

#is_not(unexpected_state_name) ⇒ StatePredicate

Provides a mechanism to determine whether the Mocha::StateMachine is not in the state specified by unexpected_state_name at some point in the future.

Parameters:

  • unexpected_state_name (String)

    name of unexpected state.

Returns:



84
85
86
# File 'lib/mocha/state_machine.rb', line 84

def is_not(unexpected_state_name) # rubocop:disable Naming/PredicateName
  StatePredicate.new(self, unexpected_state_name, 'is not') { |current, given| current != given }
end

#starts_as(initial_state_name) ⇒ StateMachine

Put the Mocha::StateMachine into the state specified by initial_state_name.

Parameters:

  • initial_state_name (String)

    name of initial state

Returns:



50
51
52
53
# File 'lib/mocha/state_machine.rb', line 50

def starts_as(initial_state_name)
  become(initial_state_name)
  self
end
mocha-2.4.2/docs/Mocha/StateMachine/000077500000000000000000000000001464615054400171435ustar00rootroot00000000000000mocha-2.4.2/docs/Mocha/StateMachine/State.html000066400000000000000000000061651464615054400211210ustar00rootroot00000000000000 Class: Mocha::StateMachine::State — Mocha 2.4.2

Class: Mocha::StateMachine::State

Inherits:
StatePredicate show all
Defined in:
lib/mocha/state_machine.rb

Overview

Provides a mechanism to change the state of a Mocha::StateMachine at some point in the future.

mocha-2.4.2/docs/Mocha/StateMachine/StatePredicate.html000066400000000000000000000061321464615054400227340ustar00rootroot00000000000000 Class: Mocha::StateMachine::StatePredicate — Mocha 2.4.2

Class: Mocha::StateMachine::StatePredicate

Inherits:
Object
  • Object
show all
Defined in:
lib/mocha/state_machine.rb

Overview

Provides the ability to determine whether a Mocha::StateMachine is in a specified state at some point in the future.

Direct Known Subclasses

State

mocha-2.4.2/docs/Mocha/StubbingError.html000066400000000000000000000052721464615054400202610ustar00rootroot00000000000000 Class: Mocha::StubbingError — Mocha 2.4.2

Class: Mocha::StubbingError

Inherits:
ErrorWithFilteredBacktrace
  • Object
show all
Defined in:
lib/mocha/stubbing_error.rb

Overview

Exception raised when stubbing a particular method is not allowed.

See Also:

  • Configuration.prevent
mocha-2.4.2/docs/_index.html000066400000000000000000000403241464615054400157060ustar00rootroot00000000000000 Mocha 2.4.2

Mocha 2.4.2

Alphabetic Index

File Listing

Namespace Listing A-Z

  • B
    • Base (Mocha::ParameterMatchers)
  • K
    • KindOf (Mocha::ParameterMatchers)
  • N
    • Not (Mocha::ParameterMatchers)
mocha-2.4.2/docs/class_list.html000066400000000000000000000350251464615054400166020ustar00rootroot00000000000000 Class List

Class List

mocha-2.4.2/docs/css/000077500000000000000000000000001464615054400143375ustar00rootroot00000000000000mocha-2.4.2/docs/css/common.css000066400000000000000000000000521464615054400163360ustar00rootroot00000000000000/* Override this file with custom rules */mocha-2.4.2/docs/css/full_list.css000066400000000000000000000130041464615054400170440ustar00rootroot00000000000000body { margin: 0; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; font-size: 13px; height: 101%; overflow-x: hidden; background: #fafafa; } h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } .clear { clear: both; } .fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } #search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } #content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } #full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } #full_list ul { padding: 0; } #full_list li { padding: 0; margin: 0; list-style: none; } #full_list li .item { padding: 5px 5px 5px 12px; } #noresults { padding: 7px 12px; background: #fff; } #content.insearch #noresults { margin-left: 7px; } li.collapsed ul { display: none; } li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } li { color: #888; cursor: pointer; } li.deprecated { text-decoration: line-through; font-style: italic; } li.odd { background: #f0f0f0; } li.even { background: #fafafa; } .item:hover { background: #ddd; } li small:before { content: "("; } li small:after { content: ")"; } li small.search_info { display: none; } a, a:visited { text-decoration: none; color: #05a; } li.clicked > .item { background: #05a; color: #ccc; } li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } li.collapsed.clicked a.toggle { background-position: top right; } #search input { border: 1px solid #bbb; border-radius: 3px; } #full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } #full_list_nav a, #nav a:visited { color: #358; } #full_list_nav a:hover { background: transparent; color: #5af; } #full_list_nav span:after { content: ' | '; } #full_list_nav span:last-child:after { content: ''; } #content h1 { margin-top: 0; } li { white-space: nowrap; cursor: normal; } li small { display: block; font-size: 0.8em; } li small:before { content: ""; } li small:after { content: ""; } li small.search_info { display: none; } #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } #content.insearch #search { background-position: center right; } #search input { width: 110px; } #full_list.insearch ul { display: block; } #full_list.insearch .item { display: none; } #full_list.insearch .found { display: block; padding-left: 11px !important; } #full_list.insearch li a.toggle { display: none; } #full_list.insearch li small.search_info { display: block; } mocha-2.4.2/docs/css/style.css000066400000000000000000000506061464615054400162200ustar00rootroot00000000000000html { width: 100%; height: 100%; } body { font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; font-size: 13px; width: 100%; margin: 0; padding: 0; display: flex; display: -webkit-flex; display: -ms-flexbox; } #nav { position: relative; width: 100%; height: 100%; border: 0; border-right: 1px dotted #eee; overflow: auto; } .nav_wrap { margin: 0; padding: 0; width: 20%; height: 100%; position: relative; display: flex; display: -webkit-flex; display: -ms-flexbox; flex-shrink: 0; -webkit-flex-shrink: 0; -ms-flex: 1 0; } #resizer { position: absolute; right: -5px; top: 0; width: 10px; height: 100%; cursor: col-resize; z-index: 9999; } #main { flex: 5 1; -webkit-flex: 5 1; -ms-flex: 5 1; outline: none; position: relative; background: #fff; padding: 1.2em; padding-top: 0.2em; box-sizing: border-box; } @media (max-width: 920px) { .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; } #resizer { display: none; } #nav { z-index: 9999; background: #fff; display: none; position: absolute; top: 40px; right: 12px; width: 500px; max-width: 80%; height: 80%; overflow-y: scroll; border: 1px solid #999; border-collapse: collapse; box-shadow: -7px 5px 25px #aaa; border-radius: 2px; } } @media (min-width: 920px) { body { height: 100%; overflow: hidden; } #main { height: 100%; overflow: auto; } #search { display: none; } } #main img { max-width: 100%; } h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } h1.title { margin-bottom: 10px; } h1.alphaindex { margin-top: 0; font-size: 22px; } h2 { padding: 0; padding-bottom: 3px; border-bottom: 1px #aaa solid; font-size: 1.4em; margin: 1.8em 0 0.5em; position: relative; } h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; } h2 small a { display: block; height: 20px; border: 1px solid #aaa; border-bottom: 0; border-top-left-radius: 5px; background: #f8f8f8; position: relative; padding: 2px 7px; } .clear { clear: both; } .inline { display: inline; } .inline p:first-child { display: inline; } .docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; } .docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt { color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em; border-radius: 4px; } .docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } .docstring h1 { font-size: 1.2em; } .docstring h2 { font-size: 1.1em; } .docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } .summary_desc .object_link a, .docstring .object_link a { font-family: monospace; font-size: 1.05em; color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em; border-radius: 4px; } .rdoc-term { padding-right: 25px; font-weight: bold; } .rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } .summary_desc pre.code .object_link a, .docstring pre.code .object_link a { padding: 0px; background: inherit; color: inherit; border-radius: inherit; } /* style for */ #filecontents table, .docstring table { border-collapse: collapse; } #filecontents table th, #filecontents table td, .docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } #filecontents table tr:nth-child(odd), .docstring table tr:nth-child(odd) { background: #eee; } #filecontents table tr:nth-child(even), .docstring table tr:nth-child(even) { background: #fff; } #filecontents table th, .docstring table th { background: #fff; } /* style for
    */ #filecontents li > p, .docstring li > p { margin: 0px; } #filecontents ul, .docstring ul { padding-left: 20px; } /* style for
    */ #filecontents dl, .docstring dl { border: 1px solid #ccc; } #filecontents dt, .docstring dt { background: #ddd; font-weight: bold; padding: 3px 5px; } #filecontents dd, .docstring dd { padding: 5px 0px; margin-left: 18px; } #filecontents dd > p, .docstring dd > p { margin: 0px; } .note { color: #222; margin: 20px 0; padding: 10px; border: 1px solid #eee; border-radius: 3px; display: block; } .docstring .note { border-left-color: #ccc; border-left-width: 5px; } .note.todo { background: #ffffc5; border-color: #ececaa; } .note.returns_void { background: #efefef; } .note.deprecated { background: #ffe5e5; border-color: #e9dada; } .note.title.deprecated { background: #ffe5e5; border-color: #e9dada; } .note.private { background: #ffffc5; border-color: #ececaa; } .note.title { padding: 3px 6px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; display: inline; } .summary_signature + .note.title { margin-left: 7px; } h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; } .note.title { background: #efefef; } .note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; } .note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; } .note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; } .note.title.private { background: #d5d5d5; border-color: #c5c5c5; } .note.title.not_defined_here { background: transparent; border: none; font-style: italic; } .discussion .note { margin-top: 6px; } .discussion .note:first-child { margin-top: 0; } h3.inherited { font-style: italic; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; font-weight: normal; padding: 0; margin: 0; margin-top: 12px; margin-bottom: 3px; font-size: 13px; } p.inherited { padding: 0; margin: 0; margin-left: 25px; } .box_info dl { margin: 0; border: 0; width: 100%; font-size: 1em; display: flex; display: -webkit-flex; display: -ms-flexbox; } .box_info dl dt { flex-shrink: 0; -webkit-flex-shrink: 1; -ms-flex-shrink: 1; width: 100px; text-align: right; font-weight: bold; border: 1px solid #aaa; border-width: 1px 0px 0px 1px; padding: 6px 0; padding-right: 10px; } .box_info dl dd { flex-grow: 1; -webkit-flex-grow: 1; -ms-flex: 1; max-width: 420px; padding: 6px 0; padding-right: 20px; border: 1px solid #aaa; border-width: 1px 1px 0 0; overflow: hidden; position: relative; } .box_info dl:last-child > * { border-bottom: 1px solid #aaa; } .box_info dl:nth-child(odd) > * { background: #eee; } .box_info dl:nth-child(even) > * { background: #fff; } .box_info dl > * { margin: 0; } ul.toplevel { list-style: none; padding-left: 0; font-size: 1.1em; } .index_inline_list { padding-left: 0; font-size: 1.1em; } .index_inline_list li { list-style: none; display: inline-block; padding: 0 12px; line-height: 30px; margin-bottom: 5px; } dl.constants { margin-left: 10px; } dl.constants dt { font-weight: bold; font-size: 1.1em; margin-bottom: 5px; } dl.constants.compact dt { display: inline-block; font-weight: normal } dl.constants dd { width: 75%; white-space: pre; font-family: monospace; margin-bottom: 18px; } dl.constants .docstring .note:first-child { margin-top: 5px; } .summary_desc { margin-left: 32px; display: block; font-family: sans-serif; font-size: 1.1em; margin-top: 8px; line-height: 1.5145em; margin-bottom: 0.8em; } .summary_desc tt { font-size: 0.9em; } dl.constants .note { padding: 2px 6px; padding-right: 12px; margin-top: 6px; } dl.constants .docstring { margin-left: 32px; font-size: 0.9em; font-weight: normal; } dl.constants .tags { padding-left: 32px; font-size: 0.9em; line-height: 0.8em; } dl.constants .discussion *:first-child { margin-top: 0; } dl.constants .discussion *:last-child { margin-bottom: 0; } .method_details { border-top: 1px dotted #ccc; margin-top: 25px; padding-top: 0; } .method_details.first { border: 0; margin-top: 5px; } .method_details.first h3.signature { margin-top: 1em; } p.signature, h3.signature { font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace; padding: 6px 10px; margin-top: 1em; background: #E8F4FF; border: 1px solid #d8d8e5; border-radius: 5px; } p.signature tt, h3.signature tt { font-family: Monaco, Consolas, Courier, monospace; } p.signature .overload, h3.signature .overload { display: block; } p.signature .extras, h3.signature .extras { font-weight: normal; font-family: sans-serif; color: #444; font-size: 1em; } p.signature .not_defined_here, h3.signature .not_defined_here, p.signature .aliases, h3.signature .aliases { display: block; font-weight: normal; font-size: 0.9em; font-family: sans-serif; margin-top: 0px; color: #555; } p.signature .aliases .names, h3.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace; font-weight: bold; color: #000; font-size: 1.2em; } .tags .tag_title { font-size: 1.05em; margin-bottom: 0; font-weight: bold; } .tags .tag_title tt { color: initial; padding: initial; background: initial; } .tags ul { margin-top: 5px; padding-left: 30px; list-style: square; } .tags ul li { margin-bottom: 3px; } .tags ul .name { font-family: monospace; font-weight: bold; } .tags ul .note { padding: 3px 6px; } .tags { margin-bottom: 12px; } .tags .examples .tag_title { margin-bottom: 10px; font-weight: bold; } .tags .examples .inline p { padding: 0; margin: 0; font-weight: bold; font-size: 1em; } .tags .examples .inline p:before { content: "▸"; font-size: 1em; margin-right: 5px; } .tags .overload .overload_item { list-style: none; margin-bottom: 25px; } .tags .overload .overload_item .signature { padding: 2px 8px; background: #F1F8FF; border: 1px solid #d8d8e5; border-radius: 3px; } .tags .overload .signature { margin-left: -15px; font-family: monospace; display: block; font-size: 1.1em; } .tags .overload .docstring { margin-top: 15px; } .defines { display: none; } #method_missing_details .notice.this { position: relative; top: -8px; color: #888; padding: 0; margin: 0; } .showSource { font-size: 0.9em; } .showSource a, .showSource a:visited { text-decoration: none; color: #666; } #content a, #content a:visited { text-decoration: none; color: #05a; } #content a:hover { background: #ffffa5; } ul.summary { list-style: none; font-family: monospace; font-size: 1em; line-height: 1.5em; padding-left: 0px; } ul.summary a, ul.summary a:visited { text-decoration: none; font-size: 1.1em; } ul.summary li { margin-bottom: 5px; } .summary_signature { padding: 4px 8px; background: #f8f8f8; border: 1px solid #f0f0f0; border-radius: 5px; } .summary_signature:hover { background: #CFEBFF; border-color: #A4CCDA; cursor: pointer; } .summary_signature.deprecated { background: #ffe5e5; border-color: #e9dada; } ul.summary.compact li { display: inline-block; margin: 0px 5px 0px 0px; line-height: 2.6em;} ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; } #content .summary_signature:hover a, #content .summary_signature:hover a:visited { background: transparent; color: #049; } p.inherited a { font-family: monospace; font-size: 0.9em; } p.inherited { word-spacing: 5px; font-size: 1.2em; } p.children { font-size: 1.2em; } p.children a { font-size: 0.9em; } p.children strong { font-size: 0.8em; } p.children strong.modules { padding-left: 5px; } ul.fullTree { display: none; padding-left: 0; list-style: none; margin-left: 0; margin-bottom: 10px; } ul.fullTree ul { margin-left: 0; padding-left: 0; list-style: none; } ul.fullTree li { text-align: center; padding-top: 18px; padding-bottom: 12px; background: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAHtJREFUeNqMzrEJAkEURdGzuhgZbSoYWcAWoBVsB4JgZAGmphsZCZYzTQgWNCYrDN9RvMmHx+X916SUBFbo8CzD1idXrLErw1mQttgXtyrOcQ/Ny5p4Qh+2XqLYYazsPWNTiuMkRxa4vcV+evuNAUOLIx5+c2hyzv7hNQC67Q+/HHmlEwAAAABJRU5ErkJggg==) no-repeat top center; } ul.fullTree li:first-child { padding-top: 0; background: transparent; } ul.fullTree li:last-child { padding-bottom: 0; } .showAll ul.fullTree { display: block; } .showAll .inheritName { display: none; } #search { position: absolute; right: 12px; top: 0px; z-index: 9000; } #search a { display: block; float: left; padding: 4px 8px; text-decoration: none; color: #05a; fill: #05a; border: 1px solid #d8d8e5; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; background: #F1F8FF; box-shadow: -1px 1px 3px #ddd; } #search a:hover { background: #f5faff; color: #06b; fill: #06b; } #search a.active { background: #568; padding-bottom: 20px; color: #fff; fill: #fff; border: 1px solid #457; border-top-left-radius: 5px; border-top-right-radius: 5px; } #search a.inactive { color: #999; fill: #999; } .inheritanceTree, .toggleDefines { float: right; border-left: 1px solid #aaa; position: absolute; top: 0; right: 0; height: 100%; background: #f6f6f6; padding: 5px; min-width: 55px; text-align: center; } #menu { font-size: 1.3em; color: #bbb; } #menu .title, #menu a { font-size: 0.7em; } #menu .title a { font-size: 1em; } #menu .title { color: #555; } #menu a, #menu a:visited { color: #333; text-decoration: none; border-bottom: 1px dotted #bbd; } #menu a:hover { color: #05a; } #footer { margin-top: 15px; border-top: 1px solid #ccc; text-align: center; padding: 7px 0; color: #999; } #footer a, #footer a:visited { color: #444; text-decoration: none; border-bottom: 1px dotted #bbd; } #footer a:hover { color: #05a; } #listing ul.alpha { font-size: 1.1em; } #listing ul.alpha { margin: 0; padding: 0; padding-bottom: 10px; list-style: none; } #listing ul.alpha li.letter { font-size: 1.4em; padding-bottom: 10px; } #listing ul.alpha ul { margin: 0; padding-left: 15px; } #listing ul small { color: #666; font-size: 0.7em; } li.r1 { background: #f0f0f0; } li.r2 { background: #fafafa; } #content ul.summary li.deprecated .summary_signature a, #content ul.summary li.deprecated .summary_signature a:visited { text-decoration: line-through; font-style: italic; } #toc { position: relative; float: right; overflow-x: auto; right: -3px; margin-left: 20px; margin-bottom: 20px; padding: 20px; padding-right: 30px; max-width: 300px; z-index: 5000; background: #fefefe; border: 1px solid #ddd; box-shadow: -2px 2px 6px #bbb; } #toc .title { margin: 0; } #toc ol { padding-left: 1.8em; } #toc li { font-size: 1.1em; line-height: 1.7em; } #toc > ol > li { font-size: 1.1em; font-weight: bold; } #toc ol > li > ol { font-size: 0.9em; } #toc ol ol > li > ol { padding-left: 2.3em; } #toc ol + li { margin-top: 0.3em; } #toc.hidden { padding: 10px; background: #fefefe; box-shadow: none; } #toc.hidden:hover { background: #fafafa; } #filecontents h1 + #toc.nofloat { margin-top: 0; } @media (max-width: 560px) { #toc { margin-left: 0; margin-top: 16px; float: none; max-width: none; } } /* syntax highlighting */ .source_code { display: none; padding: 3px 8px; border-left: 8px solid #ddd; margin-top: 5px; } #filecontents pre.code, .docstring pre.code, .source_code pre { font-family: monospace; } #filecontents pre.code, .docstring pre.code { display: block; } .source_code .lines { padding-right: 12px; color: #555; text-align: right; } #filecontents pre.code, .docstring pre.code, .tags pre.example { padding: 9px 14px; margin-top: 4px; border: 1px solid #e1e1e8; background: #f7f7f9; border-radius: 4px; font-size: 1em; overflow-x: auto; line-height: 1.2em; } pre.code { color: #000; tab-size: 2; } pre.code .info.file { color: #555; } pre.code .val { color: #036A07; } pre.code .tstring_content, pre.code .heredoc_beg, pre.code .heredoc_end, pre.code .qwords_beg, pre.code .qwords_end, pre.code .qwords_sep, pre.code .words_beg, pre.code .words_end, pre.code .words_sep, pre.code .qsymbols_beg, pre.code .qsymbols_end, pre.code .qsymbols_sep, pre.code .symbols_beg, pre.code .symbols_end, pre.code .symbols_sep, pre.code .tstring, pre.code .dstring { color: #036A07; } pre.code .fid, pre.code .rubyid_new, pre.code .rubyid_to_s, pre.code .rubyid_to_sym, pre.code .rubyid_to_f, pre.code .dot + pre.code .id, pre.code .rubyid_to_i pre.code .rubyid_each { color: #0085FF; } pre.code .comment { color: #0066FF; } pre.code .const, pre.code .constant { color: #585CF6; } pre.code .label, pre.code .symbol { color: #C5060B; } pre.code .kw, pre.code .rubyid_require, pre.code .rubyid_extend, pre.code .rubyid_include { color: #0000FF; } pre.code .ivar { color: #318495; } pre.code .gvar, pre.code .rubyid_backref, pre.code .rubyid_nth_ref { color: #6D79DE; } pre.code .regexp, .dregexp { color: #036A07; } pre.code a { border-bottom: 1px dotted #bbf; } /* inline code */ *:not(pre) > code { padding: 1px 3px 1px 3px; border: 1px solid #E1E1E8; background: #F7F7F9; border-radius: 4px; } /* Color fix for links */ #content .summary_desc pre.code .id > .object_link a, /* identifier */ #content .docstring pre.code .id > .object_link a { color: #0085FF; } #content .summary_desc pre.code .const > .object_link a, /* constant */ #content .docstring pre.code .const > .object_link a { color: #585CF6; } mocha-2.4.2/docs/file.COPYING.html000066400000000000000000000035301464615054400164640ustar00rootroot00000000000000 File: COPYING — Mocha 2.4.2

    Copyright James Mead 2006

    You may use, copy and redistribute this library under the same terms as Ruby itself or under the MIT license.

    mocha-2.4.2/docs/file.MIT-LICENSE.html000066400000000000000000000052671464615054400170760ustar00rootroot00000000000000 File: MIT-LICENSE — Mocha 2.4.2

    Copyright (c) 2006 James Mead

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    mocha-2.4.2/docs/file.README.html000066400000000000000000001254711464615054400163220ustar00rootroot00000000000000 File: README — Mocha 2.4.2

    Mocha CircleCI status of freerange/mocha Gem Version

    Description

    • A Ruby library for mocking and stubbing - but deliberately not (yet) faking or spying.
    • A unified, simple and readable syntax for both full & partial mocking.
    • Built-in support for Minitest and Test::Unit.
    • Supported by many other test frameworks.

    Intended Usage

    Mocha is intended to be used in unit tests for the Mock Object or Test Stub types of Test Double, not the Fake Object or Test Spy types. Although it would be possible to extend Mocha to allow the implementation of fakes and spies, we have chosen to keep it focused on mocks and stubs.

    Installation

    Gem

    Install the latest version of the gem with the following command...

    $ gem install mocha
    

    Note: If you are intending to use Mocha with Test::Unit or Minitest, you should only setup Mocha after loading the relevant test library...

    Test::Unit
    require 'rubygems'
    gem 'mocha'
    require 'test/unit'
    require 'mocha/test_unit'
    
    Minitest
    require 'rubygems'
    gem 'mocha'
    require 'minitest/autorun'
    require 'mocha/minitest'
    

    Bundler

    If you're using Bundler, include Mocha in the Gemfile and then setup Mocha later once you know the test library has been loaded...

    Test::Unit
    # Gemfile
    gem 'mocha'
    
    # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
    require 'test/unit'
    require 'mocha/test_unit'
    
    Minitest
    # Gemfile
    gem 'mocha'
    
    # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
    require 'minitest/autorun'
    require 'mocha/minitest'
    
    RSpec

    RSpec includes a mocha adapter. Just tell RSpec you want to mock with :mocha:

    # Gemfile in Rails app
    gem 'mocha'
    
    # Within `spec/spec_helper.rb`
    RSpec.configure do |config|
      config.mock_with :mocha
    end
    

    Note: There is no need to use a require statement to setup Mocha; RSpec does this itself.

    Cucumber
    # In e.g. features/support/mocha.rb
    require 'mocha/api'
    
    World(Mocha::API)
    
    Around do |scenario, block|
      begin
        mocha_setup
        block.call
        mocha_verify
      ensure
        mocha_teardown
      end
    end
    

    Rails

    If you're loading Mocha using Bundler within a Rails application, you should setup Mocha manually e.g. at the bottom of your test_helper.rb.

    Minitest

    Note that since Rails v4 (at least), ActiveSupport::TestCase has inherited from Minitest::Test or its earlier equivalents. Thus unless you are explicitly using Test::Unit, you are likely to be using Minitest.

    # Gemfile in Rails app
    gem 'mocha'
    
    # At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
    require 'mocha/minitest'
    
    Other Test Framework

    Follow the instructions for the relevant test framework in the Bundler section, but ensure that the relevant Mocha file (mocha/minitest, mocha/test_unit, or mocha/api) is required after the test framework has been loaded, e.g. at the bottom of test_helper.rb or spec_helper.rb, or at least after rails/test_help has been required.

    Known Issues

    • In Mocha v1.10.0 an undocumented feature of API#mock, API#stub & API#stub_everything was changed. Previously when these methods were passed a single symbol, they returned a mock object that responded to the method identified by the symbol. Now Passing a single symbol is equivalent to passing a single string, i.e. it now defines the 'name' of the mock object.
    • In Mocha v1.2.0 there is a scenario where stubbing a class method originally defined in a module hangs the Ruby interpreter due to a bug in Ruby v2.3.1. See #272. This was fixed in Mocha v1.2.1.
    • Since v1.1.0 Mocha has used prepended modules internally for stubbing methods. There is an obscure Ruby bug in many (but not all) versions of Ruby between v2.0 & v2.3 which under certain circumstances may cause your Ruby interpreter to hang. See the Ruby bug report for more details. The bug has been fixed in Ruby v2.3.3 & v2.4.0.
    • Stubbing an aliased class method, where the original method is defined in a module that's used to extend the class doesn't work in Ruby 1.8.x. See stub_method_defined_on_module_and_aliased_test.rb for an example of this behaviour.
    • 0.13.x versions cause a harmless, but annoying, deprecation warning when used with Rails 3.2.0-3.2.12, 3.1.0-3.1.10 & 3.0.0-3.0.19.
    • 0.11.x versions don't work with Rails 3.2.13 (TypeError: superclass mismatch for class ExpectationError). See #115.
    • Versions 0.10.2, 0.10.3 & 0.11.0 of the Mocha gem were broken. Please do not use these versions.

    Usage

    Quick Start

    require 'test/unit'
    require 'mocha/test_unit'
    
    class MiscExampleTest < Test::Unit::TestCase
      def test_mocking_a_class_method
        product = Product.new
        Product.expects(:find).with(1).returns(product)
        assert_equal product, Product.find(1)
      end
    
      def test_mocking_an_instance_method_on_a_real_object
        product = Product.new
        product.expects(:save).returns(true)
        assert product.save
      end
    
      def test_stubbing_instance_methods_on_real_objects
        prices = [stub(pence: 1000), stub(pence: 2000)]
        product = Product.new
        product.stubs(:prices).returns(prices)
        assert_equal [1000, 2000], product.prices.collect {|p| p.pence}
      end
    
      def test_stubbing_an_instance_method_on_all_instances_of_a_class
        Product.any_instance.stubs(:name).returns('stubbed_name')
        product = Product.new
        assert_equal 'stubbed_name', product.name
      end
    
      def test_traditional_mocking
        object = mock('object')
        object.expects(:expected_method).with(:p1, :p2).returns(:result)
        assert_equal :result, object.expected_method(:p1, :p2)
      end
    
      def test_shortcuts
        object = stub(method1: :result1, method2: :result2)
        assert_equal :result1, object.method1
        assert_equal :result2, object.method2
      end
    end
    

    Mock Objects

    class Enterprise
      def initialize(dilithium)
        @dilithium = dilithium
      end
    
      def go(warp_factor)
        warp_factor.times { @dilithium.nuke(:anti_matter) }
      end
    end
    
    require 'test/unit'
    require 'mocha/test_unit'
    
    class EnterpriseTest < Test::Unit::TestCase
      def test_should_boldly_go
        dilithium = mock()
        dilithium.expects(:nuke).with(:anti_matter).at_least_once  # auto-verified at end of test
        enterprise = Enterprise.new(dilithium)
        enterprise.go(2)
      end
    end
    

    Partial Mocking

    class Order
      attr_accessor :shipped_on
    
      def total_cost
        line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost
      end
    
      def total_weight
        line_items.inject(0) { |total, line_item| total + line_item.weight }
      end
    
      def shipping_cost
        total_weight * 5 + 10
      end
    
      class << self
        def find_all
          # Database.connection.execute('select * from orders...
        end
    
        def number_shipped_since(date)
          find_all.select { |order| order.shipped_on > date }.length
        end
    
        def unshipped_value
          find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost }
        end
      end
    end
    
    require 'test/unit'
    require 'mocha/test_unit'
    
    class OrderTest < Test::Unit::TestCase
      # illustrates stubbing instance method
      def test_should_calculate_shipping_cost_based_on_total_weight
        order = Order.new
        order.stubs(:total_weight).returns(10)
        assert_equal 60, order.shipping_cost
      end
    
      # illustrates stubbing class method
      def test_should_count_number_of_orders_shipped_after_specified_date
        now = Time.now; week_in_secs = 7 * 24 * 60 * 60
        order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs
        order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs
        Order.stubs(:find_all).returns([order_1, order_2])
        assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs)
      end
    
      # illustrates stubbing instance method for all instances of a class
      def test_should_calculate_value_of_unshipped_orders
        Order.stubs(:find_all).returns([Order.new, Order.new, Order.new])
        Order.any_instance.stubs(:shipped_on).returns(nil)
        Order.any_instance.stubs(:total_cost).returns(10)
        assert_equal 30, Order.unshipped_value
      end
    end
    

    Thread safety

    Mocha currently does not attempt to be thread-safe.

    Can I test multi-threaded code with Mocha?

    The short answer is no. In multi-threaded code Mocha exceptions may be raised in a thread other than the one which is running the test and thus a Mocha exception may not be correctly intercepted by Mocha exception handling code.

    Can I run my tests across multiple threads?

    Maybe, but probably not. Partial mocking changes the state of objects in the ObjectSpace which is shared across all threads in the Ruby process and this access to what is effectively global state is not synchronized. So, for example, if two tests are running concurrently and one uses #any_instance to modify a class, both tests will see those changes immediately.

    Expectation matching / invocation order

    Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The Expectation#stubs method is syntactic sugar to make the intent of the test more explicit.

    When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations.

    See the documentation for Mocha::Mock for further details.

    Configuration

    If you want, Mocha can generate a warning or raise an exception when:

    • stubbing a method unnecessarily
    • stubbing method on a non-mock object
    • stubbing a non-existent method
    • stubbing a non-public method

    See the documentation for Mocha::Configuration for further details.

    MOCHA_OPTIONS

    MOCHA_OPTIONS is an environment variable whose value can be set to a comma-separated list, so that we can specify multiple options e.g. MOCHA_OPTIONS=debug,use_test_unit_gem. Only the following values are currently recognized and have an effect:

    • debug: Enables a debug mode which will output backtraces for each deprecation warning. This is useful for finding where in the test suite the deprecated calls are.

    Semantic versioning

    • Every effort is made to comply with semantic versioning.
    • However, this only applies to the behaviour documented in the public API.
    • The documented public API does not include the content or format of messsages displayed to the user, e.g. assertion failure messages.

    Contributors

    See this list of contributors.

    Releasing a new version

    $ MOCHA_GENERATE_DOCS=true bundle install
    
    $ MOCHA_GENERATE_DOCS=true rake generate_docs
    
    $ curl -u <email-address> -H 'OTP:<one-time-password>' https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
    
    • Release gem to Rubygems:
    $ rake release
    [runs tests]
    mocha 1.2.0 built to pkg/mocha-1.2.0.gem.
    Tagged v1.2.0.
    Pushed git commits and tags.
    Pushed mocha 1.2.0 to rubygems.org.
    

    History

    Mocha was initially harvested from projects at Reevoo. It's syntax is heavily based on that of jMock.

    License

    © Copyright James Mead 2006

    You may use, copy and redistribute this library under the same terms as Ruby itself or under the MIT license.

    mocha-2.4.2/docs/file.RELEASE.html000066400000000000000000002271211464615054400164400ustar00rootroot00000000000000 File: RELEASE — Mocha 2.4.2

    Release Notes

    2.4.2

    External changes

    • Don't trust Object#is_a? in presence of mock objects (#656) - thanks to @casperisfine

    2.4.1

    External changes

    • Fix regression in matchers when used with keyword arguments (#654 & #655) - thanks to @ElvinEfendi for reporting

    Internal changes

    • Reduce duplication & consolidate #to_matcher method definitions (600ee2aa, e9de64e4, #655)
    • Change #to_matcher method to use keyword arguments (3b60b7df, #655)

    2.4.0

    External changes

    • Improve rendering of keyword arguments (#652) - thanks to @casperisfine

    Internal changes

    • Improvements to #mocha_inspect unit tests (#650)

    2.3.0

    External changes

    • Fix nested parameter matching for keyword arguments (f94e2504, #648) - thanks to @CodingAnarchy for reporting

    2.2.0

    External changes

    • Support multiple methods in responds_with matcher (f086b7e4, #578) - thanks to @vlad-pisanov for the suggestion
    • Add block syntax for sequences (93fdffd, #61)
    • Improve sequence failure message (0800c6ff, #60)
    • Drop support for Ruby v2.0 (85848fb0, #642)
    • Include the original test name in expired stub error messages (ca3ff8eb, #641, #642) - thanks to @casperisfine

    • Avoid rubocop directive ending up in YARD docs (2a9ee81a)

    • Update docs to fix those for Mock#method_missing (cee0bad6)

    • Reinstate missing CNAME for GitHub Pages site (da67bb0d)

    • Use Ruby v1.9 Hash syntax in docs (6de20726, #625)

    • Add missing YARD tag for API#sequence name param (343c5979)

    • Add missing YARD tag for API#states name param (f798df83)

    Internal changes

    • Tidy up Minitest vs MiniTest references (#626, #614, #615) - thanks to @zenspider & @Maimer for their help
    • Add Ruby v3.3 to CI build matrix (ce31b544)

    2.1.0

    External changes

    • Fix compatibility with Minitest (#614) - thanks to @kyrofa & @manewitz for reporting and to @zenspider for his input

    Internal changes

    • Update URLs for links to Ruby & MIT licenses (d6470af4)

    2.0.4

    Internal changes

    • Update README.md (e8c21e1b)

    2.0.3

    External changes

    • Fix BacktraceFilter to handle special characters (e242033f, #592) - thanks to @casperisfine

    Internal changes

    • Add Ruby v3.1 to the CircleCI build (3e460489)
    • DRY up regexp_matches test (ae9fed4a)
    • Fix regexp_matches tests in Ruby v3.2 (26b106a5, #590)
    • Use Ruby 1.9 hash syntax (8bc0ad2f, #598, #537) - thanks to @herwinw
    • Simplify storage of MOCHA_OPTIONS (b70507a1, #600) - thanks to @herwinw
    • Pin JRuby to v9.3.9.0 in CircleCI builds (b8e6d064, #591)
    • Rubocop: enable Style/FormatStringToken cop (089a688e, #603) - thanks to @herwinw
    • Remove Ruby version check from RespondsLikeTest (21583129)
    • Add Ruby v3.2 to CircleCI build (f7e17636, #601)
    • Use Ruby v2.6 vs v2.2 to run lint CI job (af40b7db)
    • Pin yard version to v0.9.28 to avoid ArgumentError (12f1eef7)
    • Revert "Pin JRuby to v9.3.9.0 in CircleCI builds" (4f5bb2f0, #591)
    • Remove invalid CircleCI token from badge URL (7078e76a)
    • Revert "Pin yard version to v0.9.28 to avoid ArgumentError" (7c6c10c5, #609)
    • Remove Google Analytics tracking code (2279c49d, #612)
    • Update MIT-LICENSE.md (48162b4e)
    • Update COPYING.md (f3152376)

    2.0.2

    External changes

    • Fix regression in Mock#responds_like behaviour - thanks to @adrianna-chang-shopify for reporting (#580,#583,ba4d619e)

    2.0.1

    External changes

    • Fix LoadError when using v2.0.0 with Ruby < v2.7 by moving declaration of runtime dependency on ruby2_keywords gem from Gemfile to mocha.gemspec - thanks to @mishina2228 for reporting (#581, #582, cdeb0356)

    2.0.0

    External changes

    • Remove support for Ruby v1.9 - thanks to @wasabigeek (#552)
    • Support strict keyword argument matching - see docs for Expectation#with & Configuration#strict_keyword_argument_matching= - thanks to @wasabigeek (#446,#535,#544,#562)
    • Deprecate Hash args that don't strictly match (#563,981c31be)
    • Drop support for older versions of test-unit - gem versions of test-unit earlier than v2.5.1 and versions of test-unit from the Ruby v1.8 standard library are no longer supported (#540,969f4845)
    • Drop support for older versions of minitest - versions of minitest earlier than v3.3.0 are no longer supported (#541,ca69dc9e)
    • Remove deprecated mocha/setup.rb mechanism (642a0ff4)
    • Add missing docs for API#stub parameter (257b4cb4)
    • Remove optional reinstatement of v1.9 behaviour (#436,#438,#569,1473ee25)
    • Remove deprecated methods in Configuration (#421,e7ff7528)
    • Fail fast when mock receives invocations in another test (#440,#442,cb054d59)
    • Improve docs re using matchers in Expectation#with (da7237cd)
    • Expand Expectation#with docs re keyword arguments (fed6808d)
    • Improve docs for strict_keyword_argument_matching (8d8f881d)
    • Remove deprecated Rails plugin init.rb file (1c617175)
    • Improve strict keyword argument matching deprecation warning by including the source location of the stub definition (77c0d4cc)
    • Add README section re semantic versioning (00758246)

    Internal changes

    • Separate linting from tests in terms of Rake tasks & CircleCI jobs - thanks to @wasabigeek (#556)
    • Remove tests specific to Ruby v1.8 behaviour (46fca7ac, 3b369e99)
    • Multi-line rubocop disable in Mock#method_missing (af2194c4)
    • Remove unused arg for HashMethods#mocha_inspect (4f59e27f)
    • Improve test runner assertions - failure vs error (eec7200a)
    • Improve test coverage of PositionalOrKeywordHash (c294fe70)
    • More consistent Test::Unit & Minitest integration (27dd3817)
    • Remove redundant require statements (d82218a8,fa17b114)
    • Add missing require statement (73493761)
    • Disable Style/Semicolon cop globally (8cd0b705)

    1.16.1

    External changes

    • Fix regression in Mock#responds_like behaviour - thanks to @adrianna-chang-shopify for reporting (#580,#583,77af2af1)

    1.16.0

    External changes

    • Default Configuration#reinstate_undocumented_behaviour_from_v1_9= to false (6fcaf947)
    • Deprecate Configuration#reinstate_undocumented_behaviour_from_v1_9= (a797c5fd)

    Internal changes

    • Remove redundant deprecation disabling in MockTest (dc8ca969)

    1.15.1

    External changes

    • Fix regression in Mock#responds_like behaviour - thanks to @adrianna-chang-shopify for reporting (#580,#583,c586a08c)

    1.15.0

    External changes

    • Fix examples using mock constructor with block (1cc17667)
    • Add another example for API#sequence (b7a7d233, #59)
    • Remove support for Ruby v1.8 (ddb5d672)
    • Deprecate support for Ruby versions earlier than v2.0 - thanks to @wasabigeek (#553, #555)

    Internal changes

    • Update instructions for obtaining Rubygems API key (ed9c040a)
    • Consistent definitions for respond_to? methods (#533)
    • Run test tasks before release tasks (92a1bc6e, #447)
    • Fix test:performance Rake task (#538, #539)
    • Tidying following removal of support for Ruby v1.8 - thanks to @nitishr (#542)
    • Remove ParametersMatcher from Invocation#call_description - thanks to @wasabigeek (#543)
    • Remove unnecessary splatting in Invocation - thanks to @wasabigeek (#549)
    • Extract handle_method_call from method_missing - thanks to @wasabigeek (#550)

    1.14.0

    External changes

    • Mock#expects,#stubs should return last expectation - thanks to @vlad-pisanov for #524 (b6b637db)

    Internal changes

    • Avoid breaking change in psych v4 in ruby v3.1 (08b9f4ca)
    • Remove broken Dependabot badge from README (d446657a)
    • Add Ruby 3.0 to the CI matrix - thanks to @mishina2228 for #526 (65bc626e)
    • Move development dependencies from gemspec to Gemfile - thanks to @mishina2228 for #527 (dd127f7b)

    1.13.0

    External changes

    • Add ParameterMatchers#has_keys - thanks to @cstyles for #512 (18d8104)
    • Fix misleading exception message in ParameterMatchers#has_entry - thanks to @cstyles for #513 (9c4ef13)
    • Only add dependency on rubocop if we're actually going to use it (f2f879f)
    • Fix rake dependency constraints for older Ruby versions (7ce5f29)

    Internal changes

    • Check documentation can be generated as part of CircleCI build (b30d9a9)
    • Add --fail-on-warning option to yard rake task (53a6ee3)
    • Add a weekly scheduled build to the CircleCI build (fd2a4c6)
    • Add Ruby v1.8 to the CircleCI build matrix (818ca03)
    • Add API token to fix CircleCI badge in README (607c5aa)
    • Provide wrapped option for #mocha_inspect on hashes & arrays (d8f44bc)
    • Use CircleCI instead of TravisCI for automated builds (c98c6ec)
    • Switch to newer default Travis CI build env (c78f75c)
    • Use latest Ruby versions in Travis CI builds (9e0043a)
    • Use latest JRuby v9.2.18 in Travis CI builds (8c99a1b)
    • Use consistent JRuby versions in Travis CI builds (0f849aa)
    • Use more recent version of JRuby in Travis CI build matrix (58653db)

    1.12.0

    External changes

    • Various improvements to README inspired by #207 and #390 - thanks to @nitishr for his work on #390 (fed0eee6)
    • Improve documentation related to StateMachine classes - thanks to @nitishr (#425 & #427)
    • Fix regression in cardinality introduced in v1.10.0 (59454a8) and reported in #473 - thanks to @srvance for reporting and @nitishr for fixing (#474)
    • Fix documentation for Mocha::Expectation#when - thanks to @olleolleolle (b4f59daa & #477)
    • Remove Mocha::Mock#respond_to? from documentation - thanks to @nitishr (#480)
    • Improvements to documentation for Expectation#yields & #multiple_yields - thanks to @andyw8 for reporting in #495 (1b6571c)
    • Remove documentation & tests from gem to reduce its size by over 50% - thanks to @gabetax (#500)
    • Update documentation to point to travis-ci.com instead of travis-ci.org

    Internal changes

    • Refactor StateMachine-related classes - thanks to @nitishr (#425 & #427)
    • Remove redundant test - thanks to @nitishr (8e4f1a7c)
    • Add Ruby 2.7 to Travis CI matrix - thanks to @bastelfreak (fc5ea2f2)
    • Simplify Mockery - thanks to @nitishr (#449)
    • Update Travis CI badge to point to main vs master branch (bd8028f8)
    • Generate docs using newer version of yard (v0.9.25) (c619afac)
    • Manually upgrade jquery in docs from v1.7.1 -> v1.9.0 to fix CVE-2017-16011 (211098a5, dd5eeedb & 1b76e4d5; also see #492)
    • Remove reference to non-existent jquery source map to fix error in Chrome developer tools (20156555)
    • Temporarily ignore Ruby v1.8.7 build failures (e5b9feef)

    1.11.2

    External changes

    • Fix regression introduced in v1.10.0 that meant Object#inspect was called unnecessarily (368abd98)
    • Warn when mock object receives invocations in another test - thanks to @nitishr (#442)
    • Avoid rubocop comments appearing in YARD-generated docs (d8019eed)

    Internal changes

    • Replace StubbedMethod#original_method & #original_visibility attribute reader methods with instance variables - thanks to @nitishr (d917f332)
    • Set up MochaExampleTest & StubbaExampleTest as acceptance tests - thanks to @nitishr (4881cc58)
    • Delete unused PrettyParameters class - thanks to @nitishr (314ea922)

    1.11.1

    External changes

    • The reinstate_undocumented_behaviour_from_v1_9 configuration option is now enabled by default to give people a chance to see and fix the relevant deprecation warnings before the behaviour is removed in a future release (b91b1c9e)

    1.11.0

    External changes

    • Add Expectation#with_block_given & Expectation#with_no_block_given (#441).
      • Allows non-deprecated solution for #382. Thanks to @yemartin for reporting and to @techbelly & @nitishr for feedback.
    • Fix issue with non-Array arguments passed to Expectation#multiple_yields (#444).
      • The undocumented behaviour is now properly supported and documented.

    Internal changes

    • Move static YARD options from Rake task to .yardopts file - thanks to @nitishr (#429)
    • Simplify implementation of yielding functionality - thanks to @nitishr (#439)
    • Add missing require statement to acceptance_test_helper.rb (1070fc02)
    • Add some baseline acceptance tests for yielding behaviour (c2cac911)
    • Display a sponsor button on GitHub repo page (9fc5911b)
    • Use new Deprecation.warning behaviour in Invocation#call (932d1166)

    1.10.2

    • Optionally reinstate undocumented behaviour from v1.9. This introduces a new configuration option (reinstate_undocumented_behaviour_from_v1_9) to reinstate a couple of bits of undocumented behaviour from v1.9 which were changed in v1.10 without any prior deprecation warning (#438):
      • The behaviour of API#mock, API#stub and API#stub_everything when called with a symbol as the first argument.
      • The behaviour of Expectation#yields and Expectation#multiple_yields when the stubbed method is called without a block.

    1.10.1

    • Ensure ObjectMethods & ClassMethods included when API extended (43778756)
    • Fix regression in any_instance stubbing of methods on object which has an implementation of #respond_to? that depends on the object's internal state - thanks to @rafaelfranca for reporting & @nitishr for fixing (#432, #434, 469d4b17)

    1.10.0

    • Improve deprecation warning when requiring 'mocha/setup' (388f44d7)
    • Add documentation for Cucumber integration (13ab797b)
    • Add documentation about an undocumented feature of API#mock, API#stub & API#stub_everything being changed (7ed2e4e7, d30c1717)

    1.10.0.beta.1

    • Hide ClassMethods#method_visibility & #method_exists? methods to avoid clash with Rails (#428)

    1.10.0.alpha

    External changes

    • Remove dependency on metaclass gem (#49, #365)
    • Accept symbol (as well as a string) as mock/stub name - thanks to @nitishr (#347, #353, #377)
    • More realistic examples in documentation for Expectation#yields and #multiple_yields - thanks to @nitishr (#352, #383)
    • Improve documentation for Mock#responds_like & #responds_like_instance_of - thanks to @nitishr (#337, #384)
    • Make Expectation#yields & Expectation#multiple_yields fail when the caller of the stubbed method does not provide a block. This is a change to an undocumented aspect of the public API's behaviour. If this causes your tests to fail, then fix it by removing the unnecessary call to Expectation#yields or Expectation#multiple_yields - thanks to @nitishr (#382)
    • Document MOCHA_OPTIONS in README - thanks to @nitishr (#311, #386)
    • Add documentation to explain how Mocha is intended to be used - thanks to @nitishr (#330, #385)
    • Deprecation warning if integration using 'mocha/test_unit' or 'mocha/minitest' fails - thanks to @nitishr (#229, #389, c6032d0b)
    • Require at least one specified sequence for Expectation#in_sequence - thanks to @nitishr (#79, #396, 9020248a)
    • Make signatures of Mock#unstub & ObjectMethods#unstub consistent - thanks to @nitishr (#397, f04d437)
    • Deprecate requiring 'mocha/setup' (36adf880)
    • Optionally display matching invocations alongside expectations - thanks to @nitishr (#178, #394, 00f0540, #410)
    • Put deprecations into effect (#400, #418):
      • Remove deprecated 'mocha_standalone.rb' & 'mocha/standalone.rb'
      • Fail fast if no test library loaded
      • Removed optional block for Mocha::API#mock, #stub & #stub_everything
      • Remove deprecated ParameterMatchers#has_equivalent_query_string method
      • Remove deprecated 'mocha/mini_test.rb'
    • Fix typo in docs for Mocha::Configuration.prevent (266ce71c)
    • New-style configuration (see documentation for Mocha::Configuration) (#407, #421)
    • Deprecate support for Ruby versions earlier than v1.9 (#325, c5f8496d)
    • Deprecate support for versions of test-unit & minitest which need monkey-patching (a34e1a88)
    • Deprecate old-style Rails plugin (#403, 2df77134)
    • Documentation fixes & improvements which also fix YARD warnings (472d5416, a2c0d64a)

    Internal changes

    • Pin minitest to v5.11.3 for Ruby v1.8.7 to fix build; minitest no longer supports Ruby v1.8.7 (4a0a580)
    • Upgrade JRuby to v9.2.8.0 in Travis CI builds (aa29b3f)
    • Only run rubocop for MRI Ruby versions & non-integration test builds (8f1c6af)
    • Reduce duplication in any instance method class - thanks to @nitishr (#378)
    • Simplify AnyInstanceMethod, ClassMethod, InstanceMethod, ModuleMethod class hierarchy - thanks to @nitishr (#381)
    • Simplify ClassMethods#method_exists? & ObjectMethods#method_exists? making them consistent - thanks to @nitishr (#270, #362, #370)
    • Don't override definition of singleton_class in ClassMethods - thanks to @nitishr (#391, #392)
    • Do not include 'method_definer' methods into all objects (#268, #402)
    • Distinguish different ObjectMethods modules (#268, #404)
    • Pass invocation to expectation list methods - thanks to @nitishr (#408, #409, #411)
    • Consistently use assert_raises - thanks to @nitishr (#405, #412, a66b7bed)
    • Update Ruby & JRuby versions in Travis CI config (18cb1a93, eb061c53)
    • Rubocop improvements (aa16ea67...6f4db70b, 2a1240e6...e95716ae)
    • Fix inconsistency in CardinalityTest (aa10e0a8)
    • Fix test failures on Mac OSX Catalina - thanks to @nitishr (#413, #417, #419, 8a0f2535)
    • Remove default argument in Expectation#invoke - thanks to @nitishr (#414, #420)

    1.9.0

    • Add TruffleRuby to Travis CI build matrix - thanks to @deepj (#354)
    • Explicitly set Travis CI OS to Ubuntu Trusty 14.04 (ded1fa45)
    • Expand explanation of thread-safety concerns - thanks to @techbelly (#357)
    • Refactor class method and any instance method - thanks to @chrisroos (#358)
    • Rely on default bundler version in Travis CI builds (3352e9c5)
    • Fix local build-matrix script (11abe231)
    • No need to install latest bundler in build-matrix script (8247a894)

    1.8.0

    • Constrain rubocop version to avoid breaking Travis CI builds (05e507f5)
    • Avoid calling Kernel#format from ObjectMethods#mocha_inspect - thanks to @hoffmanilya (#345)
    • Fix build matrix script (#346)
    • Avoid deprecation warning in gemspec (4976e0bc)
    • Removed link to documentation translation (ef428ea2)
    • Don't use the new bundler v2 in builds (683ded9b)
    • Moved documentation from https://gofreerange.com/mocha/docs to https://mocha.jamesmead.org/ 683ded...a17fde

    1.7.0

    • Update Ruby & JRuby versions in Travis CI config (9bf55631 & 3883af7e)
    • Simplify gemspec (63744f86)
    • Add rubocop and fix most cop violations (#341)
    • Use Kernel#warn for deprecations - thanks to @etiennebarrie (#333, 196970a)

    1.6.0

    • Fix subtle bug in setting correct visibility of stubbed module methods on Kernel or Object - thanks to @chrisroos (#295)
    • Avoid mocks for partial mocking leaking into subsequent tests - thanks to @skliew for reporting (#331)
    • Remove OpenCollective badge, backers & sponsors (a283a079)
    • Change gem version badge to SVG format and add SemVer stability badge - thanks to @greysteil (#335)
    • Improve documentation for Configuration (#236)

    1.5.0

    • Prevent use of Mocha outside the context of a test/example - thanks to @andyw8 & @lzap (#327)

    1.4.0

    • Fix deprecation warning for assert_nil in ClassMethodTest (#308 & #309)
    • Display file and line number in deprecation warning - thanks to @chrisarcand (#310, #312 & #313)
    • Rename mocha/mini_test.rb to mocha/minitest.rb - thanks to @grosser (#320 & #322)
    • Fix warning when delegating to mock in Ruby 2.4 - thanks to @tjvc (#321 & #323)
    • Updates to Travis CI configuration (73af600..9732726 & 0426e5e)

    1.3.0

    • Ensure all tests run individually - thanks to @chrisroos (#267)
    • Update Travis CI build status badge to show master branch status (#264)
    • Correct RSpec section of the README - thanks to @myronmarston (0cc039c8)
    • Fix pretty printing of quotes in String#mocha_inspect (#215 & #223)
    • Add release instructions to README - thanks to @chrisroos (70a5febd & 3c664df7)
    • Require at least Ruby v1.8.7 in gemspec - thanks to @knappe (3e20be8e)
    • Remove redundant InstanceMethod#method_exists? - thanks to @chrisroos (8f58eddf)
    • Reduce risk of hitting bug 12832 in Ruby v2.3 - thanks to @chrisroos (#277 & eca7560c)
    • Fix JRuby build - thanks to @headius (jruby/jruby#4250) & @chrisroos (#274)
    • Add latest stable version of JRuby to Travis CI build matrix (#288)
    • Fix Ruby v1.8.7 builds on Travis CI (928b5a40 & 460dce5b)
    • Deprecate passing block to mock object constructor (#290)
    • Add a known issue to README for Ruby bug 12876 (#276)
    • Add Ruby 2.4 and ruby-head to Travis CI build matrix - thanks to @junaruga (#297)
    • Fix Mocha::ParameterMatchers#includes for Array values - thanks to @timcraft (#302)
    • Use faster container-based virtual environments for Travis CI builds (#305)
    • Rename Mocha::ParameterMatchers::QueryStringMatches to QueryString (#306)
    • Handle blank parameter value for query string matcher - thanks to @weynsee (#303 & #304)
    • Rename Mocha::ParameterMatchers::QueryString -> EquivalentUri (#307)
    • Use do ... end instead of { ... } in acceptance tests - thanks to @chrisroos (#294)

    1.2.1

    1.2.0

    • Always use prepended module to stub class & instance methods for Ruby v2+ - thanks to @grosser & @chrisroos (43d56671, #244)
    • Always use prepended module to stub AnyInstance methods in Ruby v2+ - thanks to @chrisroos (#262)
    • Always set visibility of stub method to match stubbed method on included module - thanks to @grosser & @chrisroos (e87c03b0, #248)
    • Always set visibility to stub method to match stubbed method on superclass - thanks to @chrisroos (38d902ad)
    • Allow stubbing of method to which any instance responds (#200)
    • Allow includes matcher to take matcher arguments - thanks to @lazyatom (#217)
    • Avoid exception in older version of Rubygems - thanks to @chrisroos (78d930a7)
    • Add licenses to gemspec as requested by @coreyhaines (#201)
    • Fix typo in README - thanks to @jaredbeck (6119460d)
    • Added section about using Mocha with RSpec & Rails to README (#221)
    • Fix documentation for Mocha::API#stub method - thanks to @raeno (599b1dcd)
    • Added backers and sponsors from OpenCollective - thanks to @piamancini (#253)
    • Fix typo in docs for equals - thanks to @alexcoco (#254)
    • Add known issue for Ruby v1.8 to README - thanks to @chrisroos (2c642096)

    1.1.0

    • Set visibility of any instance stub method.
    • Stub methods with a prepended method if there are other prepended methods. Thanks to @mrsimo.
    • Improve docs for Mock#responds_like & #responds_like_instance_of.
    • Use GitHub convention for instructions on contributing to Mocha.
    • Fix typos in docs. Thanks to @10io

    1.0.0

    External changes

    • Assume 'mocha' has been required when requiring 'mocha/setup'.
    • Provide shortcuts for integrating with specific test library i.e. require 'mocha/test_unit' or require 'mocha/mini_test' as alternatives to require 'mocha/setup'.
    • Do not automatically try to integrate with test libraries. Since the automatic test library integration functionality requires the test library to be loaded and this doesn't usually happen until after the bundle is loaded, it makes things simpler if we use require 'mocha/setup' to explicitly setup Mocha when we know the test library has been loaded. Fixes #146 & #155.
    • Consider stubs on superclasses if none exist on primary receiver. Largely based on changes suggested by @ccutrer in #145. Note: this may break existing tests which rely on the old behaviour. Stubbing a superclass method and then invoking that method on a child class would previously cause an unexpected invocation error. By searching up through the inheritance hierarchy for each of the delegate mock objects, we can provide more intuitive behaviour. Instead of an unexpected invocation error, invoking the method on the child class will cause the stubbed method on the superclass to be used.
    • Avoid recursion when constructing unexpected invocation message. Fixes #168.
    • Add explanation of method dispatch. Heavily based on the relevant jMock v1 documentation. Fixes #172.
    • Make class_eval line number more accurate. This sets the line number as the line number of the def statement. Closes #169.
    • Allow nesting of responds_with parameter matcher. Closes #166.
    • Define Mocha module before it's referenced. The test helper defines a class TestCase within the Mocha module. When running the tests inside the bundle, the Mocha module happens to be defined at this point. However when running the tests outside the bundle, it is not defined and so an exception is raised: uninitialized constant Mocha (NameError). Fixes #163.
    • Document lack of thread-safety. Fixes #154.
    • Document how to use the build-matrix script. Fixes #160.
    • Stubbing non-public method should use same visibility. This will probably break some existing tests that were somehow relying on the stubbed method being public while the original method was protected or private. Fixes #150.

    Internal changes

    • Use lastest Rubygems in Travis CI builds.
    • Run the standard test suite against Ruby 2.1.0 in the build matrix.
    • Run integration tests against Ruby 2.0.0 with latest Test::Unit gem in the build matrix.
    • Test::Unit is not available in Ruby v1.9.3 standard library, so remove it from the build matrix.
    • Force use of Test::Unit runner, etc in relevant integration tests. Prior to this, I don't think we were really testing the Mocha integration with Test::Unit much, because, although TestUnitTest was a subclass of Test::Unit::TestCase, the important test case instances are the temporary ones built by TestRunner#run_as_test et al. Prior to this change, these would only have used Test::Unit where MiniTest was not available at all i.e. only in early versions of Ruby and when the MiniTest gem was not loaded.
    • Reset environment variables between build matrix builds.
    • Only activate integration with relevant test library for each of the integration tests.
    • Include standard build combinations from Travis CI config i.e. builds using standard library versions of test libraries.
    • Fix build-matrix.rb script. Also use .travis.yml to decide what combinations to run. This means we can now simulate the Travis CI build locally and avoid duplication. Fixes #157.
    • Remove Ruby version map from build matrix script. I'm using the rbenv-aliases plugin to alias minor versions to the relevant patch version.

    0.14.0

    • Official support for MiniTest v5. All tests now pass on the continuous integration build.

    0.14.0.alpha

    • Add speculative support for Minitest v5. Due to incompatibilities it has not yet been possible to run the Mocha test suite against Minitest v5. However, @zenspider (author of Minitest) provided the patch and he has tested it against Rails v4. Fixes #156. Thanks to @zenspider.
    • Documentation updates.

    0.13.3

    • Allow Mocha::ParameterMatchers#includes to accept multiple items. Thanks to @simao.
    • Allow stubbing of private Kernel methods. Fixes #134. Thanks to @camski for reporting.
    • Avoid a warning when test/unit/version is required by other libraries in the same project. Fixes #140. Thanks to @tmiller.
    • Make auto-activation of Test::Unit integration more resilient. This change is specifically to cope with the nasty re-defining of classes that is done by the minitest-spec-rails gem. Fixes #143. Thanks to @tubaxenor for reporting.
    • Safer restoration of stubbed method visibility. Fixes #141. Thanks to @tmm1.
    • Ensure Mockery instance gets reset even if exception raised. Fixes #144.
    • Adapt Mocha acceptance tests to cope with changes in output from latest (v4.6.2) of MiniTest.
    • Updates to README about Rails compatibility.

    0.13.2

    • Stubbing of methods re-declared with different visibilty. Fixes #109.
    • Add Mock#responds_like_instance_of. Fixes #119.
    • Make Expectation#inspect less verbose and more useful. Fixes #122.
    • Make unit tests more robust to changes in environment. Fixes #121.
    • Update README in an attempt to head Rails-related issues off at the pass.
    • Add a Gem Badge to provide a link to Mocha on Rubygems.
    • Make documentation example consistent with other examples.

    0.13.1

    • Fix #97 - Mocha::ParameterMatchers#has_entry does not work with an Array as the entry's value. Thanks to @ngokli.
    • Allow deprecation :debug mode to be switched on from MOCHA_OPTIONS environment variable.

    0.13.0

    • Major overhaul of MiniTest & Test::Unit integration. Mocha now integrates with later versions of the two test libraries using documented hooks rather than monkey-patching. This should mean that Mocha will integrate with new versions of either library without the need to release a new version of Mocha each time, which was clearly bad and unsustainable. Many thanks to @tenderlove, @zenspider & @kou for their help, suggestions & patience.
    • Temporarily deprecated require 'mocha'. Use require 'mocha/setup' instead. The plan is that eventually require 'mocha' will not automatically integrate with either of the two test libraries as it does at the moment, and you'll need to explicitly & separately trigger the integration. I think this will provide a lot more flexibility and will hopefully do away with the need for the require: false option in the Gemfile which has always confused people.
    • Deprecated require 'mocha_standalone' and require 'mocha/standalone'. Use require 'mocha/api instead.
    • Although these are not part of Mocha's public API, I thought I should mention that the MiniTest and Test::Unit assertion counter classes have been combined into a single class Mocha::Integration::AssertionCounter.
    • Extracted Mocha::Hooks module from Mocha::API and added documentation for test library authors.
    • Improvements to documentation. Much of it has been combined into the README file.
    • Fix #101 - Mock#respond_to? doesn't work with a string argument - thanks to @urbanautomaton.
    • Fix #105 - Travis link in README - thanks to @cknadler.
    • Various improvements to automated testing of integration with test libraries.
    • Make deprecation warnings more prominent.

    0.12.7

    • Officially support minitest v4.1.0 (still monkey-patching).

    0.12.6

    • Fixes #103.

    0.12.5

    • Officially support minitest v3.5.0 (still monkey-patching).

    0.12.4

    • Officially support minitest v3.4.0 & test-unit v2.5.2 (still monkey-patching).

    0.12.3

    • Revert rename of undocumented internal module since it turns out Rails/ActiveSupport is relying on its existence.

    0.12.2

    • Officially support minitest v3.3.0 (still monkey-patching)

    0.12.1

    • Deprecation warning (instead of fail fast) if neither Test::Unit nor MiniTest is loaded. Fixes #88.
    • Remove deprecated access to Mocha::Standalone.
    • Remove the deprecated file stubba.rb.
    • Officially support test-unit v2.5.1 (still monkey-patching).
    • Improve the API acceptance test.

    0.12.0

    • Fail fast if neither Test::Unit nor MiniTest is loaded. Fixes #40.
    • Officially support MiniTest up to v3.2.0 (still monkey-patching).
    • Officially support test-unit v2.5.0 (still monkey-patching).
    • Do not monkey-patch Test::Unit or MiniTest unless we know it's ok.
    • Add acceptance tests to demonstrate using a block as a custom parameter matcher.
    • Update Travis CI build status image to use the new build under the freerange account.

    0.11.4

    0.11.3

    • Fix for #78 i.e. alias Object#method as Object#method, not Object#method_ which already exists as another Ruby method.

    0.11.2

    • Rails has a Request class which defines its own #method method. This broke the new mechanism for stubbing a method. This release includes a slightly modified version of fix #77 provided by @sikachu. See https://github.com/rails/rails/pull/5907 for further info.

    0.11.1

    • In Ruby 1.8.7 methods accepting a block parameter were incorrectly restored without the block parameter after being stubbed. Fix for #76.

    0.11.0

    • Store original method when stubbing rather than using alias_method. This fixes #41, #47, #74 and all tests now pass on both Ruby 1.8.7 and 1.9.3.
    • Attempting to stub a method on a frozen object should fail fast. See #68.
    • Prevent stubbing a method on nil by default. See #68.
    • Generate documentation using YARD instead of Rdoc - removes dependency on Coderay.
    • Publish documentation on Github pages instead of Rubyforge - uses rake task written by @tomafro.
    • Remove agiledox which has outlived it's usefulness.
    • Removed trailing whitespace throughout codebase.
    • Add documentation for Mock#unstub.
    • Improve documentation for ObjectMethods.
    • Provide a way to run multiple tests within a single acceptance test method.

    0.10.5

    • Fix for issue #66 (hopefully without regressing on issue #63) - Mocha::Mock has Mocha::Mockery as a dependency. Stop trying to pretend otherwise. Thanks to @kennyj for reporting.
    • Fix a bunch of warnings in Ruby 1.9. There are still the 6 test failures mentioned in issue #41 which I suspect are due to the introspection gem not being Ruby 1.9-compatible.
    • Add links to README for source code & issue tracker.
    • Fix for issue #67 - Make the travis-ci badge visible in the README. Thanks to Diego Plentz for pull request.
    • Fix for issue #70 - Rename Mock#expectations to Mock#expectations to avoid conflicts. Thanks to Jeremy Stephens for pull request.

    0.10.4

    • Fix for issue #65 - expectations not being verified in subsequent tests.
    • Fix for issue #63 - require Mocha::Mockery at Mocha::Mock class load time and not on invocation of Mock#method_missing.
    • Fix for issue #45 - raise ArgumentError if Mocha::ParameterMatchers#has_entry is given Hash with wrong number of entries.
    • Make global variable name more obscure to avoid clashes with other libraries.
    • Move travis-ci-related gemfiles into their own directory.

    0.10.3

    • Fix for issue #57. Gem::Requirement#=~ was only added in rubygems v1.8.0, but Object#=~ means the result of various monkey-patching checks is always false/nil for earlier versions of rubygems. However, the method it aliases #satisfied_by? has existed since Gem::Dependency was extracted from Gem::Version in rubygems v0.9.4.4, so it's much safer to use that. Thanks to fguillen for reporting and helping with diagnosis.

    0.10.2

    • Merge pull request #53. Unstubbing a method should not remove expectations for other stubbed methods. Fixes #52. Thanks to saikat.

    0.10.1

    • Merge pull request #51. Use Gem::Requirement & Gem::Version for version comparison. Fixes issue #50. Thanks to meineerde.
    • Fixed typo in rdoc for Mocha::ObjectMethods.
    • Improve README as suggested in issue #46. Explain that Mocha must be loaded after test libraries and how to achieve this using Bundler.
    • Merge pull request #43 - nobody expects the spanish inquisition! Thanks to cairo140.
    • Fix for issue #39 - improve documentation for Expectation#multiple_yields.
    • Fix for issue #38 where a subtle change in test-unit v2.3.0 had been missed - only visible in verbose mode.
    • Support for MiniTest up to v2.6.2 has been verified.
    • Add explicit development dependency on coderay for generating syntax-highlighted code examples.

    0.10.0

    • Add Expectation#throws to allow a stubbed method to use Kernel#throw.
    • Updates for versions of Test::Unit up to and including v2.3.3 (including patch by Jens Fahnenbruck).
    • Updates for versions of MiniTest up to and including v2.5.1.
    • Since the singleton method added by Mocha masks the underlying instance method, there's no need to move it out the way and then back again. This fixes Github issue #20, because the original method is left unchanged - https://github.com/floehopper/mocha/issues/20 (thanks to Nick Lewis).
    • Handle stubbing of a singleton method, leaving the original method unchanged after the test.
    • When stubbing an instance method that was originally defined as a singleton method, the original method should still exist after the test.
    • Fixed mis-print in Mocha::ObjectMethods#unstub documentation (patch by Gleb Pomykalov).
    • Improved test coverage around stubbing of methods defined in different ways - this makes use of the newly extracted introspection gem (although this means some tests are now failing in Ruby v1.9.2).
    • Added configuration for Travis continuous integration.
    • Make the gemspec the canonical reference and stop generating it from the Rakefile.
    • Use the built-in Bundler rake tasks for packaging the gem.
    • Use the "release" rake task provided by Bundler instead of using the Rake::XForge::Release functionality.
    • Extract Object#metaclass into a new metaclass gem.
    • Run rake tasks without bundle exec.
    • Avoid deprecation warning for rdoc rake task.
    • Remove the use_test_unit_gem MOCHA_OPTION which hasn't worked since we switched to bundler - we can now run the tests specifying a different Gemfile instead.
    • Use multiple Gemfiles seems to run Travis CI builds against multiple version of test-unit & minitest.

    0.9.12

    • Make Mocha's tests pass under Ruby 1.9.2 i.e. using MiniTest. One of the main issues was that we were not parsing stacktraces on MiniTest errors comprehensively enough.
    • Avoid 'circular require considered harmful' warning when running Mocha's tests in Ruby 1.9.2
    • Make performance tests work on Ruby 1.9.2 i.e. using MiniTest.
    • Declare rake as a development dependency with newer versions of Rubygems since it's only needed to carry out developer-related tasks.

    0.9.11

    • Added explicit support for minitest v1.5.0 to v2.0.2.
    • Make testable by rubygems-test.
    • Update links to my blog and make other links consistent.
    • Added a URI parameter matcher that ignores the order of query parameters so that tests can be independent of undefined hash ordering (patch by Paul Battley).
    • Include unexpected invocation in failure message and change the language slightly to make the failure message less confusing. See http://floehopper.lighthouseapp.com/projects/22289/tickets/52.
    • No need to create regular expression every time the BacktraceFilter#filtered method is called. See http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/66.

    0.9.10

    0.9.9

    • Avoid loading bits of the test-unit gem by accident. This is an attempt at a fix for the problem that James Adam reported [1]. By using 'load' instead of 'require' to detect the version of Test::Unit, we can avoid rubygems trying to load bits of the test-unit gem when it's not wanted. [1] http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/50#ticket-50-13
    • Fix exception when running rake without test-unit gem. When test-unit gem >=v2.0.0 was installed but the "use_test_unit_gem" MOCHA_OPTIONS was not specified, a "comparison of Fixnum with Hash failed" exception was being raised when running the performance tests. This was because bits of the test-unit gem were being loaded accidentally and a Hash was being incorrectly supplied to the TestRunner.run method.
    • Explicitly require rubygems for running tests via rake using test-unit gem.
    • Handle newer versions of test-unit gem (v2.0.2 to v2.0.9)
    • Handle newer versions of minitest gem (v1.4.0 to v1.6.0)
    • Added warnings about monkey-patching test-unit and minitest to aid debugging. These are enabled by including "debug" in the MOCHA_OPTIONS environment variable. This is now a comma-separated list, so that we can specify multiple options e.g. MOCHA_OPTIONS=debug,use_test_unit_gem
    • Eloy Duran (alloy) made the unit tests run on 1.9.2dev r25249.
    • Eloy Duran (alloy) also improved some MiniTest TestResult code I'd written and got the acceptance tests running on Ruby 1.9 HEAD. There are still 4 failures because for some reason the backtrace line numbers are off by one. And the minitest_test test case does not run when the whole suite is run with MiniTest. These issues still need investigation.
    • Fixed some acceptance tests to run in Ruby 1.9.2 - it's no longer possible to subvert the protection of a method by calling it via Object#send.
    • Fixed "test:performance" rake task so it runs in Ruby 1.9.2.
    • Fix test incorrectly failing under Rubinius 1.0. This test imposed too many constraints. It appears that Object#inspect legitimately calls Object#object_id in Rubinius. But we're only interested in what 'id' methods Mocha::ObjectMethods#mocha_inspect calls. By stubbing Object#inspect we can relax the constraints imposed by the test.
    • Luke Redpath (lukeredpath) added new shorthand "any" and "all" composite parameter matchers using "&" and "|". This provides an alternative syntax for expecting any or all matchers to pass, e.g. foo.expects(:bar).with(equals(1) | equals(2)).
    • Improved documentation for Expectation#raises. A number of people have suggested an extension to the API to cope with custom exceptions that have extra constructor parameters. However, since the arguments supplied to Expectation#raises are just passed on to Kernel#raise, it's possible to pass in an instance of an exception. Thus no change to the API is required, but it does seem worthwhile pointing this out in the docs.
    • Corrected RDoc example for Expectation#never thanks to Red David (reddavis).
    • Improved RDoc including a change suggested by Rohit Arondekar (rohit).
    • Updated gemspec as requested by Sam Woodard (shwoodard).

    0.9.8

    • Fixed bug "NameError raised when using Mocha as a Rails plug-in" - http://floehopper.lighthouseapp.com/projects/22289/tickets/53. Since 0.9.6 the Rails plugin has been broken. See bug report for details. You will need to explicitly load Mocha after the test framework has been loaded, e.g. by adding "require 'mocha'" at the bottom of test/test_helper.rb.
    • Make Mocha::ParameterMatchers#regexp_matches, #includes, #has_value, #has_key more robust. Thanks to Sander Hartlage.
    • Allow passing a block to Mocha::Configuration methods to only change configuration for the duration of the block. Thanks to Dan Manges.
    • Fixed bug "doc generation fails in 0.9.7 gem" - http://floehopper.lighthouseapp.com/projects/22289/tickets/51.
    • Remove rdoc template incorporating google analytics from source control. The file just needs to exist locally and be ignored by source control. This should stop the warning showing up on e.g. RunCodeRun build results.

    0.9.7

    • Although I had provided a deprecation warning for people using Mocha::Standalone, I had assumed people wouldn't be explicitly loading the mocha/standalone.rb file. It turns out this assumption was incorrect at least in the case of Rspec. This is now fixed.

    0.9.6

    • Version 2.0.1 of the test-unit gem introduced a private 'run_test' method on TestCase which clashed with the public TestRunner#run_test method. So this latter method has been renamed to 'run_as_test'.
    • Stop requiring rubygems - this should be an environmental choice for the user. http://gist.github.com/54177 - describes why requiring rubygems in your library code is a bad idea.
    • It seems like overkill to vendorize coderay and meta_project when they're only needed to generate the examples for documentation and for publishing files on RubyForge. So I'm removing them and installing them locally as gems when I need them.
    • Added support for 'test-unit' gem (version >= 2.0). Note that as with other versions of Test::Unit I'm completely replacing the TestCase#run method. Unfortunately in version 2.0.0 this method differs slightly from the same method in version 2.0.1 & 2.0.2, so we have to provide different implementations to ensure that the internal working of Test::Unit are not compromised by Mocha. Note also that unless the 'test-unit' gem is loaded, requiring 'test/unit' leads to a mixture of stdlib and gem classes being loaded causing errors. To avoid a dependency on rubygems, the gem is loaded only if MOCHA_OPTIONS is set to 'use_test_unit_gem' - this option is only intended for use in running Mocha's own tests. It might be worthwhile to create a shim gem like minitest_tu_shim to allow the test-unit gem to completely replace the stdlib, but that's a job for another day. The changes in the Rakefile are to make the default task run with the 'test-unit' gem (version >= 2.0).
    • Renamed Mocha::Standalone to Mocha::API to better reflect its purpose. Added a deprecation warning for those who are referencing Mocha::Standalone.
    • Fix exception raised by HasEntry#matches? if first param is not a Hash (thanks to Taylor Barstow).
    • Ken Collins reported [1] that Mocha is always loading MiniTest if it is available and loading it causes some Rails/ActionPack tests to break. I've removed the loading of MiniTest, but this now means the user has to ensure that if they want to use MiniTest in conjunction with Mocha, he must load MiniTest before loading Mocha. [1] http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2060
    • Implemented Bacon integration (thanks to Ubiratan Pires Alberton), but this was then removed after deciding only to maintain integration with Test::Unit and MiniTest which are both Ruby standard libraries. See mailing list for details.
    • Don't monkey-patch MiniTest if it's already been monkey-patched by Mocha.
    • Fixed bug: MiniTest integration was counting ExpectationErrors as errors not failures. http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/41.
    • Fixed bug: Some Bacon tests were failing in Ruby 1.9.1. http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/43.
    • Chad Humphries pointed out that in Ruby 1.9.1, if you are not using Test::Unit or MiniTest, Mocha will attempt to load and monkey-patch Test::Unit. Mocha will now only monkey-patch Test::Unit and/or MiniTest if they have already been loaded. MiniTest tests will now run in both Ruby 1.8.6 (with MiniTest gem) and in Ruby 1.9.1 (with MiniTest std lib). See Ligthouse ticket - http://floehopper.lighthouseapp.com/projects/22289/tickets/49.
    • Made Mocha compatible with minitest 1.4.0 and above (thanks to Denis Defreyne).

    0.9.5

    • Fixed Lighthouse bug #32 - stub_everything should mean mock responds to anything.
    • Added Expectation#twice to improve readability. Thanks to pull request from Celestino Gomes.
    • In Ruby 1.9.1, requiring 'test/unit' loads a thin wrapper around MiniTest and Test::Unit::TestCase ends up inheriting from MiniTest::Unit::TestCase. So we need to avoid including the Mocha modules more than once to avoid nasty consequences. Thanks to Matthias Hennemeyer for help with this.
    • Ruby 1.9 includes rake, but not rake/contrib. For the moment I've moved the sshpublisher require into the only rake task that needs it, so that I can at least run the tests in Ruby 1.9. It looks like I will need to build a rake/contrib gem or similar to get this working properly - http://intertwingly.net/blog/2008/01/07/Rake-Contrib-for-1-9

    0.9.4

    • Added mocha.gemspec file generated with Chad Woolley's new rake task, so that a floehopper-mocha gem will get built on GitHub.
    • Add rake task to update mocha.gemspec with unique version, which will cause gem to be auto-built on github
    • As Tobias Crawley correctly pointed out in feature request #23055 "stubs(with_hash) not working with existing object" [1], following the principle of least surprise, it should be possible to call ObjectMethods#expects & ObjectMethods#stubs with a Hash of method_names vs return_values like you can with Mock#expects & Mock#stubs. I've also updated & improved the docs to reflect the changes. [1] http://rubyforge.org/tracker/index.php?func=detail&aid=23055&group_id=1917&atid=7480
    • Removed deprecated gem autorequire.

    0.9.3

    0.9.2

    • Improved documentation to address [#22530] 'Mock methods with multiple return values not possible?'
    • respond_with parameter matcher was not available in tests.
    • Patch [#22630] Fix for a bug in running Rails tests with Ruby 1.8.7. Array#flatten was being called which in turn was checking whether each element responded to #to_ary. This check was using the two parameter version of #respond_to?, but Mock was only defining a one parameter version.

    0.9.1

    • Fixed bug #21465 - expects & stubs should support method names as strings (as well as symbols) or fail fast. Convert all expectation method names to a symbol in case they were supplied as a string.
    • By removing Mock#unexpected_method_called we reduce the number of methods vulnerable to the problem that surfaced in bug #21563.
    • Fix bug #21563 - stubbing 'verified?' method is unsafe. Instance method names on the Mock class should be more obscure.
    • Performance improvement. StubbaExampleTest goes twice as fast on my local machine.
    • Added primitive performance test to default rake task.
    • Fix format of case statements which don't work in Ruby 1.9 and make others consistent.
    • There is no point in running (potentially expensive) checks if configuration is set to allow such checks to fail. This is a relatively quick fix in response to Chris McGrath's performance problems.
    • Fix for bug #21161 - 'uninitialized constant Deprecation in stubba.rb'.
    • It's more readable to talk about 'once' and 'twice' rather than '1 time' and '2 times'.
    • Fix bug #20883 - never should raise when called to prevent follow up errors. Fail fast when there are no matching invokable expectations and handle the stub_everything case sensibly. This might not be entirely backwards compatible, but I think the benefits outweigh the risks. The most likely change is that a test that was already failing will now fail faster, which doesn't seem so awful.

    0.9.0

    0.5.5

    • Renamed Matches parameter matcher to RegexpMatches for clarity.
    • Added noframes tag to rdoc index to assist Google.

    0.5.4

    • Added matches parameter matcher for matching regular expressions.

    0.5.3

    • Attempt to fix packaging problems by switching to newer version (1.15.1) of gnutar and setting COPY_EXTENDED_ATTRIBUTES_DISABLE environment variable.
    • Removed unused ExpectationSequenceError exception.
    • Added instance_of and kind_of parameter matchers.
    • Added Google Webmaster meta tag to rdoc template header.
    • Put Google Webmaster meta tag in the right header i.e. the one for the index page.

    0.5.2

    • Fix bug 11885 - "never doesn't work with stub_everything" submitted by Alexander Lang. In fixing this bug, also fixed undiscoverd bug where expected & actual invocation counts were being incorrectly reported which seems to have been introduced when fixes were added for invocation dispatch (see MockedMethodDispatchAcceptanceTest).
    • Previously when an expectation did not allow more invocations, it was treated as not matching. Now we prefer matching expectations which allow more invocations, but still match expectations which cannot allow more invocations. I think this may be overcomplicating things, but let's see how it goes.

    0.5.1

    • Fixed bug #11583 "Mocha 0.5.0 throwing unexpected warnings". Also switched on ruby warning for all rake test tasks. Fixed majority of warnings, but some left to fix.

    0.5.0

    • Parameter Matchers - I've added a few Hamcrest-style parameter matchers which are designed to be used inside Expectation#with. The following matchers are currently available: anything(), includes(), has_key(), has_value(), has_entry(), all_of() & any_of(). More to follow soon. The idea is eventually to get rid of the nasty parameter_block option on Expectation#with.

    object = mock() object.expects(:method).with(has_key('key_1')) object.method('key_1' => 1, 'key_2' => 2) # no verification error raised

    object = mock() object.expects(:method).with(has_key('key_1')) object.method('key_2' => 2) # verification error raised, because method was not called with Hash containing key: 'key_1'

    • Values Returned and Exceptions Raised on Consecutive Invocations - Allow multiple calls to Expectation#returns and Expectation#raises to build up a sequence of responses to invocations on the mock. Added syntactic sugar method Expectation#then to allow more readable expectations.

    object = mock() object.stubs(:method).returns(1, 2).then.raises(Exception).then.returns(4) object.method # => 1 object.method # => 2 object.method # => raises exception of class Exception object.method # => 4

    • Yields on Consecutive Invocations - Allow multiple calls to yields on single expectation to allow yield parameters to be specified for consecutive invocations.

    object = mock() object.stubs(:method).yields(1, 2).then.yields(3) object.method { |*values| p values } # => [1, 2] object.method { |*values| p values } # => [3]

    • Multiple Yields on Single Invocation - Added Expectation#multiple_yields to allow a mocked or stubbed method to yield multiple times for a single invocation.

    object = mock() object.stubs(:method).multiple_yields([1, 2], [3]) object.method { |*values| p values } # => [1, 2] # => [3]

    • Invocation Dispatch - Expectations were already being matched in reverse order i.e. the most recently defined one was being found first. This is still the case, but we now stop matching an expectation when its maximum number of expected invocations is reached. c.f. JMock v1. A stub will never stop matching by default. Hopefully this means we can soon get rid of the need to pass a Proc to Expectation#returns.

    object = mock() object.stubs(:method).returns(2) object.expects(:method).once.returns(1) object.method # => 1 object.method # => 2 object.method # => 2 # no verification error raised

    # The following should still work...

    Time.stubs(:now).returns(Time.parse('Mon Jan 01 00:00:00 UTC 2007')) Time.now # => Mon Jan 01 00:00:00 UTC 2007 Time.stubs(:now).returns(Time.parse('Thu Feb 01 00:00:00 UTC 2007')) Time.now # => Thu Feb 01 00:00:00 UTC 2007

    • Deprecate passing an instance of Proc to Expectation#returns.
    • Explicitly include all Rakefile dependencies in project.
    • Fixed old Stubba example.
    • Fix so that it is possible for a stubbed method to raise an Interrupt exception without a message in Ruby 1.8.6
    • Added responds_like and quacks_like.
    • Capture standard object methods before Mocha adds any.
    • Added Expectation#once method to make interface less surprising.
    • Use Rake::TestTask to run tests. Created three separate tasks to run unit, integration & acceptance tests. Split inspect_test into one file per TestCase. Deleted superfluous all_tests file.
    • Fiddled with mocha_inspect and tests to give more sensible results on x86 platform.
    • Fixed bug #7834 "infinite_range.rb makes incorrect assumption about to_f" logged by James Moore.

    0.4.0

    • Allow naming of mocks (patch from Chris Roos).
    • Specify multiple return values for consecutive calls.
    • Improved consistency of expectation error messages.
    • Allow mocking of Object instance methods e.g. kind_of?, type.
    • Provide aliased versions of #expects and #stubs to allow mocking of these methods.
    • Added at_least, at_most, at_most_once methods to expectation.
    • Allow expects and stubs to take a hash of method and return values.
    • Eliminate warning: "instance variable @yield not initialized" (patch from Xavier Shay).
    • Restore instance methods on partial mocks (patch from Chris Roos).
    • Allow stubbing of a method with non-word characters in its name (patch from Paul Battley).
    • Removed coupling to Test::Unit.
    • Allow specified exception instance to be raised (patch from Chris Roos).
    • Make mock object_id appear in hex like normal Ruby inspect (patch from Paul Battley).
    • Fix path to object.rb in rdoc rake task (patch from Tomas Pospisek).
    • Reverse order in which expectations are matched, so that last expectation is matched first. This allows e.g. a call to #stubs to be effectively overridden by a call to #expects (patch from Tobias Lutke).
    • Stubba & SmartTestCase modules incorporated into Mocha module so only need to require 'mocha' - no longer need to require 'stubba'.
    • AutoMocha removed.

    0.3.3

    • Quick bug fix to restore instance methods on partial mocks (for Kevin Clark).

    0.3.2

    • Examples added.

    0.3.1

    • Dual licensing with MIT license added.

    0.3.0

    • Rails plugin.
    • Auto-verify for expectations on concrete classes.
    • Include each expectation verification in the test result assertion count.
    • Filter out noise from assertion backtraces.
    • Point assertion backtrace to line where failing expectation was created.
    • New yields method for expectations.
    • Create stubs which stub all method calls.
    • Mocks now respond_to? expected methods.

    0.2.1

    • Rename MochaAcceptanceTest::Rover#move method to avoid conflict with Rake (in Ruby 1.8.4 only?)

    0.2.0

    • Small change to SetupAndTeardown#teardown_stubs suggested by Luke Redpath (http://www.lukeredpath.co.uk) to allow use of Stubba with RSpec (http://rspec.rubyforge.org).
    • Reorganized directory structure and extracted addition of setup and teardown methods into SmartTestCase mini-library.
    • Addition of auto-verify for Mocha (but not Stubba). This means there is more significance in the choice of expects or stubs in that any expects on a mock will automatically get verified.

    So instead of...

    wotsit = Mocha.new wotsit.expects(:thingummy).with(5).returns(10) doobrey = Doobrey.new(wotsit) doobrey.hoojamaflip wotsit.verify

    you need to do...

    wotsit = mock() wotsit.expects(:thingummy).with(5).returns(10) doobrey = Doobrey.new(wotsit) doobrey.hoojamaflip # no need to verify

    There are also shortcuts as follows...

    instead of...

    wotsit = Mocha.new wotsit.expects(:thingummy).returns(10) wotsit.expects(:summat).returns(25)

    you can have...

    wotsit = mock(:thingummy => 5, :summat => 25)

    and instead of...

    wotsit = Mocha.new wotsit.stubs(:thingummy).returns(10) wotsit.stubs(:summat).returns(25)

    you can have...

    wotsit = stub(:thingummy => 5, :summat => 25)

    0.1.2

    • Minor tweaks

    0.1.1

    • Initial release.
    mocha-2.4.2/docs/file_list.html000066400000000000000000000036531464615054400164160ustar00rootroot00000000000000 File List mocha-2.4.2/docs/frames.html000066400000000000000000000010521464615054400157100ustar00rootroot00000000000000 Mocha 2.4.2 mocha-2.4.2/docs/index.html000066400000000000000000001254721464615054400155570ustar00rootroot00000000000000 File: README — Mocha 2.4.2

    Mocha CircleCI status of freerange/mocha Gem Version

    Description

    • A Ruby library for mocking and stubbing - but deliberately not (yet) faking or spying.
    • A unified, simple and readable syntax for both full & partial mocking.
    • Built-in support for Minitest and Test::Unit.
    • Supported by many other test frameworks.

    Intended Usage

    Mocha is intended to be used in unit tests for the Mock Object or Test Stub types of Test Double, not the Fake Object or Test Spy types. Although it would be possible to extend Mocha to allow the implementation of fakes and spies, we have chosen to keep it focused on mocks and stubs.

    Installation

    Gem

    Install the latest version of the gem with the following command...

    $ gem install mocha
    

    Note: If you are intending to use Mocha with Test::Unit or Minitest, you should only setup Mocha after loading the relevant test library...

    Test::Unit
    require 'rubygems'
    gem 'mocha'
    require 'test/unit'
    require 'mocha/test_unit'
    
    Minitest
    require 'rubygems'
    gem 'mocha'
    require 'minitest/autorun'
    require 'mocha/minitest'
    

    Bundler

    If you're using Bundler, include Mocha in the Gemfile and then setup Mocha later once you know the test library has been loaded...

    Test::Unit
    # Gemfile
    gem 'mocha'
    
    # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
    require 'test/unit'
    require 'mocha/test_unit'
    
    Minitest
    # Gemfile
    gem 'mocha'
    
    # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
    require 'minitest/autorun'
    require 'mocha/minitest'
    
    RSpec

    RSpec includes a mocha adapter. Just tell RSpec you want to mock with :mocha:

    # Gemfile in Rails app
    gem 'mocha'
    
    # Within `spec/spec_helper.rb`
    RSpec.configure do |config|
      config.mock_with :mocha
    end
    

    Note: There is no need to use a require statement to setup Mocha; RSpec does this itself.

    Cucumber
    # In e.g. features/support/mocha.rb
    require 'mocha/api'
    
    World(Mocha::API)
    
    Around do |scenario, block|
      begin
        mocha_setup
        block.call
        mocha_verify
      ensure
        mocha_teardown
      end
    end
    

    Rails

    If you're loading Mocha using Bundler within a Rails application, you should setup Mocha manually e.g. at the bottom of your test_helper.rb.

    Minitest

    Note that since Rails v4 (at least), ActiveSupport::TestCase has inherited from Minitest::Test or its earlier equivalents. Thus unless you are explicitly using Test::Unit, you are likely to be using Minitest.

    # Gemfile in Rails app
    gem 'mocha'
    
    # At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
    require 'mocha/minitest'
    
    Other Test Framework

    Follow the instructions for the relevant test framework in the Bundler section, but ensure that the relevant Mocha file (mocha/minitest, mocha/test_unit, or mocha/api) is required after the test framework has been loaded, e.g. at the bottom of test_helper.rb or spec_helper.rb, or at least after rails/test_help has been required.

    Known Issues

    • In Mocha v1.10.0 an undocumented feature of API#mock, API#stub & API#stub_everything was changed. Previously when these methods were passed a single symbol, they returned a mock object that responded to the method identified by the symbol. Now Passing a single symbol is equivalent to passing a single string, i.e. it now defines the 'name' of the mock object.
    • In Mocha v1.2.0 there is a scenario where stubbing a class method originally defined in a module hangs the Ruby interpreter due to a bug in Ruby v2.3.1. See #272. This was fixed in Mocha v1.2.1.
    • Since v1.1.0 Mocha has used prepended modules internally for stubbing methods. There is an obscure Ruby bug in many (but not all) versions of Ruby between v2.0 & v2.3 which under certain circumstances may cause your Ruby interpreter to hang. See the Ruby bug report for more details. The bug has been fixed in Ruby v2.3.3 & v2.4.0.
    • Stubbing an aliased class method, where the original method is defined in a module that's used to extend the class doesn't work in Ruby 1.8.x. See stub_method_defined_on_module_and_aliased_test.rb for an example of this behaviour.
    • 0.13.x versions cause a harmless, but annoying, deprecation warning when used with Rails 3.2.0-3.2.12, 3.1.0-3.1.10 & 3.0.0-3.0.19.
    • 0.11.x versions don't work with Rails 3.2.13 (TypeError: superclass mismatch for class ExpectationError). See #115.
    • Versions 0.10.2, 0.10.3 & 0.11.0 of the Mocha gem were broken. Please do not use these versions.

    Usage

    Quick Start

    require 'test/unit'
    require 'mocha/test_unit'
    
    class MiscExampleTest < Test::Unit::TestCase
      def test_mocking_a_class_method
        product = Product.new
        Product.expects(:find).with(1).returns(product)
        assert_equal product, Product.find(1)
      end
    
      def test_mocking_an_instance_method_on_a_real_object
        product = Product.new
        product.expects(:save).returns(true)
        assert product.save
      end
    
      def test_stubbing_instance_methods_on_real_objects
        prices = [stub(pence: 1000), stub(pence: 2000)]
        product = Product.new
        product.stubs(:prices).returns(prices)
        assert_equal [1000, 2000], product.prices.collect {|p| p.pence}
      end
    
      def test_stubbing_an_instance_method_on_all_instances_of_a_class
        Product.any_instance.stubs(:name).returns('stubbed_name')
        product = Product.new
        assert_equal 'stubbed_name', product.name
      end
    
      def test_traditional_mocking
        object = mock('object')
        object.expects(:expected_method).with(:p1, :p2).returns(:result)
        assert_equal :result, object.expected_method(:p1, :p2)
      end
    
      def test_shortcuts
        object = stub(method1: :result1, method2: :result2)
        assert_equal :result1, object.method1
        assert_equal :result2, object.method2
      end
    end
    

    Mock Objects

    class Enterprise
      def initialize(dilithium)
        @dilithium = dilithium
      end
    
      def go(warp_factor)
        warp_factor.times { @dilithium.nuke(:anti_matter) }
      end
    end
    
    require 'test/unit'
    require 'mocha/test_unit'
    
    class EnterpriseTest < Test::Unit::TestCase
      def test_should_boldly_go
        dilithium = mock()
        dilithium.expects(:nuke).with(:anti_matter).at_least_once  # auto-verified at end of test
        enterprise = Enterprise.new(dilithium)
        enterprise.go(2)
      end
    end
    

    Partial Mocking

    class Order
      attr_accessor :shipped_on
    
      def total_cost
        line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost
      end
    
      def total_weight
        line_items.inject(0) { |total, line_item| total + line_item.weight }
      end
    
      def shipping_cost
        total_weight * 5 + 10
      end
    
      class << self
        def find_all
          # Database.connection.execute('select * from orders...
        end
    
        def number_shipped_since(date)
          find_all.select { |order| order.shipped_on > date }.length
        end
    
        def unshipped_value
          find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost }
        end
      end
    end
    
    require 'test/unit'
    require 'mocha/test_unit'
    
    class OrderTest < Test::Unit::TestCase
      # illustrates stubbing instance method
      def test_should_calculate_shipping_cost_based_on_total_weight
        order = Order.new
        order.stubs(:total_weight).returns(10)
        assert_equal 60, order.shipping_cost
      end
    
      # illustrates stubbing class method
      def test_should_count_number_of_orders_shipped_after_specified_date
        now = Time.now; week_in_secs = 7 * 24 * 60 * 60
        order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs
        order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs
        Order.stubs(:find_all).returns([order_1, order_2])
        assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs)
      end
    
      # illustrates stubbing instance method for all instances of a class
      def test_should_calculate_value_of_unshipped_orders
        Order.stubs(:find_all).returns([Order.new, Order.new, Order.new])
        Order.any_instance.stubs(:shipped_on).returns(nil)
        Order.any_instance.stubs(:total_cost).returns(10)
        assert_equal 30, Order.unshipped_value
      end
    end
    

    Thread safety

    Mocha currently does not attempt to be thread-safe.

    Can I test multi-threaded code with Mocha?

    The short answer is no. In multi-threaded code Mocha exceptions may be raised in a thread other than the one which is running the test and thus a Mocha exception may not be correctly intercepted by Mocha exception handling code.

    Can I run my tests across multiple threads?

    Maybe, but probably not. Partial mocking changes the state of objects in the ObjectSpace which is shared across all threads in the Ruby process and this access to what is effectively global state is not synchronized. So, for example, if two tests are running concurrently and one uses #any_instance to modify a class, both tests will see those changes immediately.

    Expectation matching / invocation order

    Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The Expectation#stubs method is syntactic sugar to make the intent of the test more explicit.

    When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations.

    See the documentation for Mocha::Mock for further details.

    Configuration

    If you want, Mocha can generate a warning or raise an exception when:

    • stubbing a method unnecessarily
    • stubbing method on a non-mock object
    • stubbing a non-existent method
    • stubbing a non-public method

    See the documentation for Mocha::Configuration for further details.

    MOCHA_OPTIONS

    MOCHA_OPTIONS is an environment variable whose value can be set to a comma-separated list, so that we can specify multiple options e.g. MOCHA_OPTIONS=debug,use_test_unit_gem. Only the following values are currently recognized and have an effect:

    • debug: Enables a debug mode which will output backtraces for each deprecation warning. This is useful for finding where in the test suite the deprecated calls are.

    Semantic versioning

    • Every effort is made to comply with semantic versioning.
    • However, this only applies to the behaviour documented in the public API.
    • The documented public API does not include the content or format of messsages displayed to the user, e.g. assertion failure messages.

    Contributors

    See this list of contributors.

    Releasing a new version

    $ MOCHA_GENERATE_DOCS=true bundle install
    
    $ MOCHA_GENERATE_DOCS=true rake generate_docs
    
    $ curl -u <email-address> -H 'OTP:<one-time-password>' https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
    
    • Release gem to Rubygems:
    $ rake release
    [runs tests]
    mocha 1.2.0 built to pkg/mocha-1.2.0.gem.
    Tagged v1.2.0.
    Pushed git commits and tags.
    Pushed mocha 1.2.0 to rubygems.org.
    

    History

    Mocha was initially harvested from projects at Reevoo. It's syntax is heavily based on that of jMock.

    License

    © Copyright James Mead 2006

    You may use, copy and redistribute this library under the same terms as Ruby itself or under the MIT license.

    mocha-2.4.2/docs/js/000077500000000000000000000000001464615054400141635ustar00rootroot00000000000000mocha-2.4.2/docs/js/app.js000066400000000000000000000226121464615054400153040ustar00rootroot00000000000000(function() { var localStorage = {}, sessionStorage = {}; try { localStorage = window.localStorage; } catch (e) { } try { sessionStorage = window.sessionStorage; } catch (e) { } function createSourceLinks() { $('.method_details_list .source_code'). before("[View source]"); $('.toggleSource').toggle(function() { $(this).parent().nextAll('.source_code').slideDown(100); $(this).text("Hide source"); }, function() { $(this).parent().nextAll('.source_code').slideUp(100); $(this).text("View source"); }); } function createDefineLinks() { var tHeight = 0; $('.defines').after(" more..."); $('.toggleDefines').toggle(function() { tHeight = $(this).parent().prev().height(); $(this).prev().css('display', 'inline'); $(this).parent().prev().height($(this).parent().height()); $(this).text("(less)"); }, function() { $(this).prev().hide(); $(this).parent().prev().height(tHeight); $(this).text("more..."); }); } function createFullTreeLinks() { var tHeight = 0; $('.inheritanceTree').toggle(function() { tHeight = $(this).parent().prev().height(); $(this).parent().toggleClass('showAll'); $(this).text("(hide)"); $(this).parent().prev().height($(this).parent().height()); }, function() { $(this).parent().toggleClass('showAll'); $(this).parent().prev().height(tHeight); $(this).text("show all"); }); } function searchFrameButtons() { $('.full_list_link').click(function() { toggleSearchFrame(this, $(this).attr('href')); return false; }); window.addEventListener('message', function(e) { if (e.data === 'navEscape') { $('#nav').slideUp(100); $('#search a').removeClass('active inactive'); $(window).focus(); } }); $(window).resize(function() { if ($('#search:visible').length === 0) { $('#nav').removeAttr('style'); $('#search a').removeClass('active inactive'); $(window).focus(); } }); } function toggleSearchFrame(id, link) { var frame = $('#nav'); $('#search a').removeClass('active').addClass('inactive'); if (frame.attr('src') === link && frame.css('display') !== "none") { frame.slideUp(100); $('#search a').removeClass('active inactive'); } else { $(id).addClass('active').removeClass('inactive'); if (frame.attr('src') !== link) frame.attr('src', link); frame.slideDown(100); } } function linkSummaries() { $('.summary_signature').click(function() { document.location = $(this).find('a').attr('href'); }); } function summaryToggle() { $('.summary_toggle').click(function(e) { e.preventDefault(); localStorage.summaryCollapsed = $(this).text(); $('.summary_toggle').each(function() { $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); var next = $(this).parent().parent().nextAll('ul.summary').first(); if (next.hasClass('compact')) { next.toggle(); next.nextAll('ul.summary').first().toggle(); } else if (next.hasClass('summary')) { var list = $('
      '); list.html(next.html()); list.find('.summary_desc, .note').remove(); list.find('a').each(function() { $(this).html($(this).find('strong').html()); $(this).parent().html($(this)[0].outerHTML); }); next.before(list); next.toggle(); } }); return false; }); if (localStorage.summaryCollapsed == "collapse") { $('.summary_toggle').first().click(); } else { localStorage.summaryCollapsed = "expand"; } } function constantSummaryToggle() { $('.constants_summary_toggle').click(function(e) { e.preventDefault(); localStorage.summaryCollapsed = $(this).text(); $('.constants_summary_toggle').each(function() { $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); var next = $(this).parent().parent().nextAll('dl.constants').first(); if (next.hasClass('compact')) { next.toggle(); next.nextAll('dl.constants').first().toggle(); } else if (next.hasClass('constants')) { var list = $('
      '); list.html(next.html()); list.find('dt').each(function() { $(this).addClass('summary_signature'); $(this).text( $(this).text().split('=')[0]); if ($(this).has(".deprecated").length) { $(this).addClass('deprecated'); }; }); // Add the value of the constant as "Tooltip" to the summary object list.find('pre.code').each(function() { console.log($(this).parent()); var dt_element = $(this).parent().prev(); var tooltip = $(this).text(); if (dt_element.hasClass("deprecated")) { tooltip = 'Deprecated. ' + tooltip; }; dt_element.attr('title', tooltip); }); list.find('.docstring, .tags, dd').remove(); next.before(list); next.toggle(); } }); return false; }); if (localStorage.summaryCollapsed == "collapse") { $('.constants_summary_toggle').first().click(); } else { localStorage.summaryCollapsed = "expand"; } } function generateTOC() { if ($('#filecontents').length === 0) return; var _toc = $('
        '); var show = false; var toc = _toc; var counter = 0; var tags = ['h2', 'h3', 'h4', 'h5', 'h6']; var i; var curli; if ($('#filecontents h1').length > 1) tags.unshift('h1'); for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; } var lastTag = parseInt(tags[0][1], 10); $(tags.join(', ')).each(function() { if ($(this).parents('.method_details .docstring').length != 0) return; if (this.id == "filecontents") return; show = true; var thisTag = parseInt(this.tagName[1], 10); if (this.id.length === 0) { var proposedId = $(this).attr('toc-id'); if (typeof(proposedId) != "undefined") this.id = proposedId; else { var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_'); if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; } this.id = proposedId; } } if (thisTag > lastTag) { for (i = 0; i < thisTag - lastTag; i++) { if ( typeof(curli) == "undefined" ) { curli = $('
      1. '); toc.append(curli); } toc = $('
          '); curli.append(toc); curli = undefined; } } if (thisTag < lastTag) { for (i = 0; i < lastTag - thisTag; i++) { toc = toc.parent(); toc = toc.parent(); } } var title = $(this).attr('toc-title'); if (typeof(title) == "undefined") title = $(this).text(); curli =$('
        1. ' + title + '
        2. '); toc.append(curli); lastTag = thisTag; }); if (!show) return; html = ''; $('#content').prepend(html); $('#toc').append(_toc); $('#toc .hide_toc').toggle(function() { $('#toc .top').slideUp('fast'); $('#toc').toggleClass('hidden'); $('#toc .title small').toggle(); }, function() { $('#toc .top').slideDown('fast'); $('#toc').toggleClass('hidden'); $('#toc .title small').toggle(); }); } function navResizeFn(e) { if (e.which !== 1) { navResizeFnStop(); return; } sessionStorage.navWidth = e.pageX.toString(); $('.nav_wrap').css('width', e.pageX); $('.nav_wrap').css('-ms-flex', 'inherit'); } function navResizeFnStop() { $(window).unbind('mousemove', navResizeFn); window.removeEventListener('message', navMessageFn, false); } function navMessageFn(e) { if (e.data.action === 'mousemove') navResizeFn(e.data.event); if (e.data.action === 'mouseup') navResizeFnStop(); } function navResizer() { $('#resizer').mousedown(function(e) { e.preventDefault(); $(window).mousemove(navResizeFn); window.addEventListener('message', navMessageFn, false); }); $(window).mouseup(navResizeFnStop); if (sessionStorage.navWidth) { navResizeFn({which: 1, pageX: parseInt(sessionStorage.navWidth, 10)}); } } function navExpander() { var done = false, timer = setTimeout(postMessage, 500); function postMessage() { if (done) return; clearTimeout(timer); var opts = { action: 'expand', path: pathId }; document.getElementById('nav').contentWindow.postMessage(opts, '*'); done = true; } window.addEventListener('message', function(event) { if (event.data === 'navReady') postMessage(); return false; }, false); } function mainFocus() { var hash = window.location.hash; if (hash !== '' && $(hash)[0]) { $(hash)[0].scrollIntoView(); } setTimeout(function() { $('#main').focus(); }, 10); } function navigationChange() { // This works around the broken anchor navigation with the YARD template. window.onpopstate = function() { var hash = window.location.hash; if (hash !== '' && $(hash)[0]) { $(hash)[0].scrollIntoView(); } }; } $(document).ready(function() { navResizer(); navExpander(); createSourceLinks(); createDefineLinks(); createFullTreeLinks(); searchFrameButtons(); linkSummaries(); summaryToggle(); constantSummaryToggle(); generateTOC(); mainFocus(); navigationChange(); }); })(); mocha-2.4.2/docs/js/full_list.js000066400000000000000000000131621464615054400165210ustar00rootroot00000000000000(function() { var $clicked = $(null); var searchTimeout = null; var searchCache = []; var caseSensitiveMatch = false; var ignoreKeyCodeMin = 8; var ignoreKeyCodeMax = 46; var commandKey = 91; RegExp.escape = function(text) { return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); } function escapeShortcut() { $(document).keydown(function(evt) { if (evt.which == 27) { window.parent.postMessage('navEscape', '*'); } }); } function navResizer() { $(window).mousemove(function(e) { window.parent.postMessage({ action: 'mousemove', event: {pageX: e.pageX, which: e.which} }, '*'); }).mouseup(function(e) { window.parent.postMessage({action: 'mouseup'}, '*'); }); window.parent.postMessage("navReady", "*"); } function clearSearchTimeout() { clearTimeout(searchTimeout); searchTimeout = null; } function enableLinks() { // load the target page in the parent window $('#full_list li').on('click', function(evt) { $('#full_list li').removeClass('clicked'); $clicked = $(this); $clicked.addClass('clicked'); evt.stopPropagation(); if (evt.target.tagName === 'A') return true; var elem = $clicked.find('> .item .object_link a')[0]; var e = evt.originalEvent; var newEvent = new MouseEvent(evt.originalEvent.type); newEvent.initMouseEvent(e.type, e.canBubble, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); elem.dispatchEvent(newEvent); evt.preventDefault(); return false; }); } function enableToggles() { // show/hide nested classes on toggle click $('#full_list a.toggle').on('click', function(evt) { evt.stopPropagation(); evt.preventDefault(); $(this).parent().parent().toggleClass('collapsed'); highlight(); }); } function populateSearchCache() { $('#full_list li .item').each(function() { var $node = $(this); var $link = $node.find('.object_link a'); if ($link.length > 0) { searchCache.push({ node: $node, link: $link, name: $link.text(), fullName: $link.attr('title').split(' ')[0] }); } }); } function enableSearch() { $('#search input').keyup(function(event) { if (ignoredKeyPress(event)) return; if (this.value === "") { clearSearch(); } else { performSearch(this.value); } }); $('#full_list').after(""); } function ignoredKeyPress(event) { if ( (event.keyCode > ignoreKeyCodeMin && event.keyCode < ignoreKeyCodeMax) || (event.keyCode == commandKey) ) { return true; } else { return false; } } function clearSearch() { clearSearchTimeout(); $('#full_list .found').removeClass('found').each(function() { var $link = $(this).find('.object_link a'); $link.text($link.text()); }); $('#full_list, #content').removeClass('insearch'); $clicked.parents().removeClass('collapsed'); highlight(); } function performSearch(searchString) { clearSearchTimeout(); $('#full_list, #content').addClass('insearch'); $('#noresults').text('').hide(); partialSearch(searchString, 0); } function partialSearch(searchString, offset) { var lastRowClass = ''; var i = null; for (i = offset; i < Math.min(offset + 50, searchCache.length); i++) { var item = searchCache[i]; var searchName = (searchString.indexOf('::') != -1 ? item.fullName : item.name); var matchString = buildMatchString(searchString); var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i"); if (searchName.match(matchRegexp) == null) { item.node.removeClass('found'); item.link.text(item.link.text()); } else { item.node.addClass('found'); item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1'); lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2'; item.link.html(item.name.replace(matchRegexp, "$&")); } } if(i == searchCache.length) { searchDone(); } else { searchTimeout = setTimeout(function() { partialSearch(searchString, i); }, 0); } } function searchDone() { searchTimeout = null; highlight(); if ($('#full_list li:visible').size() === 0) { $('#noresults').text('No results were found.').hide().fadeIn(); } else { $('#noresults').text('').hide(); } $('#content').removeClass('insearch'); } function buildMatchString(searchString, event) { caseSensitiveMatch = searchString.match(/[A-Z]/) != null; var regexSearchString = RegExp.escape(searchString); if (caseSensitiveMatch) { regexSearchString += "|" + $.map(searchString.split(''), function(e) { return RegExp.escape(e); }). join('.+?'); } return regexSearchString; } function highlight() { $('#full_list li:visible').each(function(n) { $(this).removeClass('even odd').addClass(n % 2 == 0 ? 'odd' : 'even'); }); } /** * Expands the tree to the target element and its immediate * children. */ function expandTo(path) { var $target = $(document.getElementById('object_' + path)); $target.addClass('clicked'); $target.removeClass('collapsed'); $target.parentsUntil('#full_list', 'li').removeClass('collapsed'); if($target[0]) { window.scrollTo(window.scrollX, $target.offset().top - 250); highlight(); } } function windowEvents(event) { var msg = event.data; if (msg.action === "expand") { expandTo(msg.path); } return false; } window.addEventListener("message", windowEvents, false); $(document).ready(function() { escapeShortcut(); navResizer(); enableLinks(); enableToggles(); populateSearchCache(); enableSearch(); }); })(); mocha-2.4.2/docs/js/jquery.js000066400000000000000000002672541464615054400160600ustar00rootroot00000000000000/*! jQuery v1.7.1 jquery.com | jquery.org/license */ (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
    a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
    "+""+"
    ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
    t
    ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
    ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() {for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);mocha-2.4.2/docs/method_list.html000066400000000000000000000514341464615054400167570ustar00rootroot00000000000000 Method List

    Method List

    mocha-2.4.2/docs/top-level-namespace.html000066400000000000000000000036231464615054400203020ustar00rootroot00000000000000 Top Level Namespace — Mocha 2.4.2

    Top Level Namespace

    Defined Under Namespace

    Modules: Mocha

    mocha-2.4.2/gemfiles/000077500000000000000000000000001464615054400144125ustar00rootroot00000000000000mocha-2.4.2/gemfiles/Gemfile.minitest.latest000066400000000000000000000001551464615054400210340ustar00rootroot00000000000000source 'https://rubygems.org' gemspec :path=>"../" group :development do gem "rake" gem "minitest" end mocha-2.4.2/gemfiles/Gemfile.test-unit.latest000066400000000000000000000001561464615054400211350ustar00rootroot00000000000000source 'https://rubygems.org' gemspec :path=>"../" group :development do gem "rake" gem "test-unit" end mocha-2.4.2/lib/000077500000000000000000000000001464615054400133655ustar00rootroot00000000000000mocha-2.4.2/lib/mocha.rb000066400000000000000000000000301464615054400147720ustar00rootroot00000000000000require 'mocha/version' mocha-2.4.2/lib/mocha/000077500000000000000000000000001464615054400144545ustar00rootroot00000000000000mocha-2.4.2/lib/mocha/any_instance_method.rb000066400000000000000000000004611464615054400210150ustar00rootroot00000000000000require 'mocha/stubbed_method' module Mocha class AnyInstanceMethod < StubbedMethod private def mock_owner stubbee.any_instance end def stubbee_method(method_name) stubbee.instance_method(method_name) end def original_method_owner stubbee end end end mocha-2.4.2/lib/mocha/api.rb000066400000000000000000000223031464615054400155520ustar00rootroot00000000000000require 'mocha/ruby_version' require 'mocha/parameter_matchers' require 'mocha/hooks' require 'mocha/mockery' require 'mocha/sequence' require 'mocha/object_methods' require 'mocha/class_methods' module Mocha # Methods added to +Test::Unit::TestCase+, +Minitest::Unit::TestCase+ or equivalent. # The mock creation methods are {#mock}, {#stub} and {#stub_everything}, all of which return a #{Mock} # which can be further modified by {Mock#responds_like} and {Mock#responds_like_instance_of} methods, # both of which return a {Mock}, too, and can therefore, be chained to the original creation methods. # # {Mock#responds_like} and {Mock#responds_like_instance_of} force the mock to indicate what it is # supposed to be mocking, thus making it a safer verifying mock. They check that the underlying +responder+ # will actually respond to the methods being stubbed, throwing a +NoMethodError+ upon invocation otherwise. # # @example Verifying mock using {Mock#responds_like_instance_of} # class Sheep # def initialize # raise "some awkward code we don't want to call" # end # def chew(grass); end # end # # sheep = mock('sheep').responds_like_instance_of(Sheep) # sheep.expects(:chew) # sheep.expects(:foo) # sheep.respond_to?(:chew) # => true # sheep.respond_to?(:foo) # => false # sheep.chew # sheep.foo # => raises NoMethodError exception module API include ParameterMatchers include Hooks # @private def self.included(_mod) Object.send(:include, Mocha::ObjectMethods) Class.send(:include, Mocha::ClassMethods) end # @private def self.extended(mod) included(mod) end # Builds a new mock object # # @return [Mock] a new mock object # # @overload def mock(name) # @param [String, Symbol] name identifies mock object in error messages. # @overload def mock(expected_methods_vs_return_values = {}) # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {Mock#expects} were called multiple times. # @overload def mock(name, expected_methods_vs_return_values = {}) # @param [String, Symbol] name identifies mock object in error messages. # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {Mock#expects} were called multiple times. # # @example Using expected_methods_vs_return_values Hash to setup expectations. # def test_motor_starts_and_stops # motor = mock('motor', start: true, stop: true) # assert motor.start # assert motor.stop # # an error will be raised unless both Motor#start and Motor#stop have been called # end # def mock(*arguments) name = arguments.shift.to_s if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol) expectations = arguments.shift || {} mock = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock mock.expects(expectations) mock end # Builds a new mock object # # @return [Mock] a new mock object # # @overload def stub(name) # @param [String, Symbol] name identifies mock object in error messages. # @overload def stub(stubbed_methods_vs_return_values = {}) # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times. # @overload def stub(name, stubbed_methods_vs_return_values = {}) # @param [String, Symbol] name identifies mock object in error messages. # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times. # # @example Using stubbed_methods_vs_return_values Hash to setup stubbed methods. # def test_motor_starts_and_stops # motor = stub('motor', start: true, stop: true) # assert motor.start # assert motor.stop # # an error will not be raised even if either Motor#start or Motor#stop has not been called # end def stub(*arguments) name = arguments.shift.to_s if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol) expectations = arguments.shift || {} stub = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock stub.stubs(expectations) stub end # Builds a mock object that accepts calls to any method. By default it will return +nil+ for any method call. # # @return [Mock] a new mock object # # @overload def stub_everything(name) # @param [String, Symbol] name identifies mock object in error messages. # @overload def stub_everything(stubbed_methods_vs_return_values = {}) # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times. # @overload def stub_everything(name, stubbed_methods_vs_return_values = {}) # @param [String, Symbol] name identifies mock object in error messages. # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times. # # @example Ignore invocations of irrelevant methods. # def test_motor_stops # motor = stub_everything('motor', stop: true) # assert_nil motor.irrelevant_method_1 # => no error raised # assert_nil motor.irrelevant_method_2 # => no error raised # assert motor.stop # end def stub_everything(*arguments) name = arguments.shift if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol) expectations = arguments.shift || {} stub = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock stub.stub_everything stub.stubs(expectations) stub end # Builds a new sequence which can be used to constrain the order in which expectations can occur. # # Specify that an expected invocation must occur within a named {Sequence} by calling {Expectation#in_sequence} # on each expectation or by passing a block within which all expectations should be constrained by the {Sequence}. # # @param [String] name name of sequence # @yield optional block within which expectations should be constrained by the sequence # @return [Sequence] a new sequence # # @see Expectation#in_sequence # # @example Ensure methods on egg are invoked in correct order. # breakfast = sequence('breakfast') # # egg = mock('egg') # egg.expects(:crack).in_sequence(breakfast) # egg.expects(:fry).in_sequence(breakfast) # egg.expects(:eat).in_sequence(breakfast) # # @example Ensure methods across multiple objects are invoked in correct order. # sequence = sequence(:task_order) # # task_one = mock("task_one") # task_two = mock("task_two") # # task_one.expects(:execute).in_sequence(sequence) # task_two.expects(:execute).in_sequence(sequence) # # task_one.execute # task_two.execute # # @example Ensure methods on egg are invoked in the correct order using a block. # egg = mock('egg') # sequence('breakfast') do # egg.expects(:crack) # egg.expects(:fry) # egg.expects(:eat) # end def sequence(name) Sequence.new(name).tap do |seq| Mockery.instance.sequences.push(seq) begin yield if block_given? ensure Mockery.instance.sequences.pop end end end # Builds a new state machine which can be used to constrain the order in which expectations can occur. # # Specify the initial state of the state machine by using {StateMachine#starts_as}. # # Specify that an expected invocation should change the state of the state machine by using {Expectation#then}. # # Specify that an expected invocation should be constrained to occur within a particular +state+ by using {Expectation#when}. # # A test can contain multiple state machines. # # @param [String] name name of state machine # @return [StateMachine] a new state machine # # @see Expectation#then # @see Expectation#when # @see StateMachine # @example Constrain expected invocations to occur in particular states. # power = states('power').starts_as('off') # # radio = mock('radio') # radio.expects(:switch_on).then(power.is('on')) # radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on')) # radio.expects(:adjust_volume).with(+5).when(power.is('on')) # radio.expects(:select_channel).with('BBC World Service').when(power.is('on')) # radio.expects(:adjust_volume).with(-5).when(power.is('on')) # radio.expects(:switch_off).then(power.is('off')) def states(name) Mockery.instance.new_state_machine(name) end end end mocha-2.4.2/lib/mocha/argument_iterator.rb000066400000000000000000000004761464615054400205430ustar00rootroot00000000000000module Mocha class ArgumentIterator def initialize(argument) @argument = argument end def each if @argument.is_a?(Hash) @argument.each do |method_name, return_value| yield method_name, return_value end else yield @argument end end end end mocha-2.4.2/lib/mocha/backtrace_filter.rb000066400000000000000000000005611464615054400202670ustar00rootroot00000000000000module Mocha class BacktraceFilter LIB_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), '..')) + File::SEPARATOR def initialize(lib_directory = LIB_DIRECTORY) @lib_directory = lib_directory end def filtered(backtrace) backtrace.reject { |location| File.expand_path(location).start_with?(@lib_directory) } end end end mocha-2.4.2/lib/mocha/block_matcher.rb000066400000000000000000000007471464615054400176060ustar00rootroot00000000000000module Mocha module BlockMatchers class OptionalBlock def match?(_actual_block) true end def mocha_inspect; end end class BlockGiven def match?(actual_block) !actual_block.nil? end def mocha_inspect 'with block given' end end class NoBlockGiven def match?(actual_block) actual_block.nil? end def mocha_inspect 'with no block given' end end end end mocha-2.4.2/lib/mocha/cardinality.rb000066400000000000000000000044121464615054400173050ustar00rootroot00000000000000module Mocha class Cardinality INFINITY = 1 / 0.0 def initialize(required = 0, maximum = INFINITY) update(required, maximum) @invocations = [] end def exactly(count) update(count, count) end def at_least(count) update(count, INFINITY) end def at_most(count) update(0, count) end def times(range_or_count) case range_or_count when Range then update(range_or_count.first, range_or_count.last) else update(range_or_count, range_or_count) end end def <<(invocation) @invocations << invocation end def invocations_allowed? @invocations.size < maximum end def satisfied? @invocations.size >= required end def needs_verifying? !allowed_any_number_of_times? end def verified? (@invocations.size >= required) && (@invocations.size <= maximum) end def allowed_any_number_of_times? required.zero? && infinite?(maximum) end def used? @invocations.any? || maximum.zero? end # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity def anticipated_times if allowed_any_number_of_times? 'allowed any number of times' elsif required.zero? && maximum.zero? "expected #{count(maximum)}" elsif required == maximum "expected exactly #{count(required)}" elsif infinite?(maximum) "expected at least #{count(required)}" elsif required.zero? "expected at most #{count(maximum)}" else "expected between #{required} and #{count(maximum)}" end end # rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity def invoked_times "invoked #{count(@invocations.size)}" end def actual_invocations @invocations.map(&:full_description).join end protected attr_reader :required, :maximum def count(number) case number when 0 then 'never' when 1 then 'once' when 2 then 'twice' else "#{number} times" end end def update(required, maximum) @required = required @maximum = maximum self end def infinite?(number) number.respond_to?(:infinite?) && number.infinite? end end end mocha-2.4.2/lib/mocha/central.rb000066400000000000000000000015011464615054400164260ustar00rootroot00000000000000module Mocha class Central class Null < self def initialize(&block) super @raise_not_initialized_error = block end def stub(*) @raise_not_initialized_error.call end def unstub(*) @raise_not_initialized_error.call end end attr_accessor :stubba_methods def initialize self.stubba_methods = [] end def stub(method) return if stubba_methods.detect { |m| m.matches?(method) } method.stub stubba_methods.push(method) end def unstub(method) return unless (existing = stubba_methods.detect { |m| m.matches?(method) }) existing.unstub stubba_methods.delete(existing) end def unstub_all while stubba_methods.any? unstub(stubba_methods.first) end end end end mocha-2.4.2/lib/mocha/change_state_side_effect.rb000066400000000000000000000003371464615054400217510ustar00rootroot00000000000000module Mocha class ChangeStateSideEffect def initialize(state) @state = state end def perform @state.activate end def mocha_inspect "then #{@state.mocha_inspect}" end end end mocha-2.4.2/lib/mocha/class_methods.rb000066400000000000000000000036711464615054400176400ustar00rootroot00000000000000require 'mocha/mockery' require 'mocha/any_instance_method' module Mocha # Methods added to all classes to allow mocking and stubbing on real (i.e. non-mock) objects. module ClassMethods # @private class AnyInstance def initialize(klass) @stubba_object = klass end def mocha(instantiate = true) if instantiate @mocha ||= Mocha::Mockery.instance.mock_impersonating_any_instance_of(@stubba_object) else defined?(@mocha) ? @mocha : nil end end def stubba_method Mocha::AnyInstanceMethod end def stubba_class @stubba_object end def respond_to?(symbol, include_all = false) @stubba_object.allocate.respond_to?(symbol.to_sym, include_all) end attr_reader :stubba_object end # @return [Mock] a mock object which will detect calls to any instance of this class. # @raise [StubbingError] if attempting to stub method which is not allowed. # # @example Return false to invocation of +Product#save+ for any instance of +Product+. # Product.any_instance.stubs(:save).returns(false) # product_1 = Product.new # assert_equal false, product_1.save # product_2 = Product.new # assert_equal false, product_2.save def any_instance if frozen? raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}.any_instance", caller) end @any_instance ||= AnyInstance.new(self) end # @private # rubocop:disable Metrics/CyclomaticComplexity def __method_visibility__(method, include_public_methods = true) (include_public_methods && public_method_defined?(method) && :public) || (protected_method_defined?(method) && :protected) || (private_method_defined?(method) && :private) end # rubocop:enable Metrics/CyclomaticComplexity alias_method :__method_exists__?, :__method_visibility__ end end mocha-2.4.2/lib/mocha/configuration.rb000066400000000000000000000316521464615054400176570ustar00rootroot00000000000000require 'mocha/ruby_version' module Mocha # Allows setting of configuration options. See {Configuration} for the available options. # # Typically the configuration is set globally in a +test_helper.rb+ or +spec_helper.rb+ file. # # @see Configuration # # @yieldparam configuration [Configuration] the configuration for modification # # @example Setting multiple configuration options # Mocha.configure do |c| # c.stubbing_method_unnecessarily = :prevent # c.stubbing_method_on_non_mock_object = :warn # c.stubbing_method_on_nil = :allow # end # def self.configure yield configuration end # @private def self.configuration Configuration.configuration end # This class provides a number of ways to configure the library. # # Typically the configuration is set globally in a +test_helper.rb+ or +spec_helper.rb+ file. # # @example Setting multiple configuration options # Mocha.configure do |c| # c.stubbing_method_unnecessarily = :prevent # c.stubbing_method_on_non_mock_object = :warn # c.stubbing_method_on_nil = :allow # end # class Configuration # @private DEFAULTS = { stubbing_method_unnecessarily: :allow, stubbing_method_on_non_mock_object: :allow, stubbing_non_existent_method: :allow, stubbing_non_public_method: :allow, stubbing_method_on_nil: :prevent, display_matching_invocations_on_failure: false, strict_keyword_argument_matching: false }.freeze attr_reader :options protected :options # @private def initialize(options = {}) @options = DEFAULTS.merge(options) end # @private def initialize_copy(other) @options = other.options.dup end # @private def merge(other) self.class.new(@options.merge(other.options)) end # Configure whether stubbing methods unnecessarily is allowed. # # This is useful for identifying unused stubs. Unused stubs are often accidentally introduced when code is {http://martinfowler.com/bliki/DefinitionOfRefactoring.html refactored}. # # When +value+ is +:allow+, do nothing. This is the default. # When +value+ is +:warn+, display a warning. # When +value+ is +:prevent+, raise a {StubbingError}. # # @param [Symbol] value one of +:allow+, +:warn+, +:prevent+. # # @example Preventing unnecessary stubbing of a method # Mocha.configure do |c| # c.stubbing_method_unnecessarily = :prevent # end # # example = mock('example') # example.stubs(:unused_stub) # # => Mocha::StubbingError: stubbing method unnecessarily: # # => #.unused_stub(any_parameters) # def stubbing_method_unnecessarily=(value) @options[:stubbing_method_unnecessarily] = value end # @private def stubbing_method_unnecessarily @options[:stubbing_method_unnecessarily] end # Configure whether stubbing methods on non-mock objects is allowed. # # If you like the idea of {http://www.jmock.org/oopsla2004.pdf mocking roles not objects} and {http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html you don't like stubbing concrete classes}, this is the setting for you. However, while this restriction makes a lot of sense in Java with its {http://java.sun.com/docs/books/tutorial/java/concepts/interface.html explicit interfaces}, it may be moot in Ruby where roles are probably best represented as Modules. # # When +value+ is +:allow+, do nothing. This is the default. # When +value+ is +:warn+, display a warning. # When +value+ is +:prevent+, raise a {StubbingError}. # # @param [Symbol] value one of +:allow+, +:warn+, +:prevent+. # # @example Preventing stubbing of a method on a non-mock object # Mocha.configure do |c| # c.stubbing_method_on_non_mock_object = :prevent # end # # class Example # def example_method; end # end # # example = Example.new # example.stubs(:example_method) # # => Mocha::StubbingError: stubbing method on non-mock object: # # => #.example_method # def stubbing_method_on_non_mock_object=(value) @options[:stubbing_method_on_non_mock_object] = value end # @private def stubbing_method_on_non_mock_object @options[:stubbing_method_on_non_mock_object] end # Configure whether stubbing of non-existent methods is allowed. # # This is useful if you want to ensure that methods you're mocking really exist. A common criticism of unit tests with mock objects is that such a test may (incorrectly) pass when an equivalent non-mocking test would (correctly) fail. While you should always have some integration tests, particularly for critical business functionality, this Mocha configuration setting should catch scenarios when mocked methods and real methods have become misaligned. # # When +value+ is +:allow+, do nothing. This is the default. # When +value+ is +:warn+, display a warning. # When +value+ is +:prevent+, raise a {StubbingError}. # # @param [Symbol] value one of +:allow+, +:warn+, +:prevent+. # # @example Preventing stubbing of a non-existent method # # Mocha.configure do |c| # c.stubbing_non_existent_method = :prevent # end # # class Example # end # # example = Example.new # example.stubs(:method_that_doesnt_exist) # # => Mocha::StubbingError: stubbing non-existent method: # # => #.method_that_doesnt_exist # def stubbing_non_existent_method=(value) @options[:stubbing_non_existent_method] = value end # @private def stubbing_non_existent_method @options[:stubbing_non_existent_method] end # Configure whether stubbing of non-public methods is allowed. # # Many people think that it's good practice only to mock public methods. This is one way to prevent your tests being too tightly coupled to the internal implementation of a class. Such tests tend to be very brittle and not much use when refactoring. # # When +value+ is +:allow+, do nothing. This is the default. # When +value+ is +:warn+, display a warning. # When +value+ is +:prevent+, raise a {StubbingError}. # # @param [Symbol] value one of +:allow+, +:warn+, +:prevent+. # # @example Preventing stubbing of a non-public method # Mocha.configure do |c| # c.stubbing_non_public_method = :prevent # end # # class Example # def internal_method; end # private :internal_method # end # # example = Example.new # example.stubs(:internal_method) # # => Mocha::StubbingError: stubbing non-public method: # # => #.internal_method # def stubbing_non_public_method=(value) @options[:stubbing_non_public_method] = value end # @private def stubbing_non_public_method @options[:stubbing_non_public_method] end # Configure whether stubbing methods on the +nil+ object is allowed. # # This is usually done accidentally, but there might be rare cases where it is intended. # # This option only works for Ruby < v2.2.0. In later versions of Ruby +nil+ is frozen and so a {StubbingError} will be raised if you attempt to stub a method on +nil+. # # When +value+ is +:allow+, do nothing. # When +value+ is +:warn+, display a warning. # When +value+ is +:prevent+, raise a {StubbingError}. This is the default. # # @param [Symbol] value one of +:allow+, +:warn+, +:prevent+. # def stubbing_method_on_nil=(value) @options[:stubbing_method_on_nil] = value end # @private def stubbing_method_on_nil @options[:stubbing_method_on_nil] end # Display matching invocations alongside expectations on Mocha-related test failure. # # @param [Boolean] value +true+ to enable display of matching invocations; disabled by default. # # @example Enable display of matching invocations # Mocha.configure do |c| # c.display_matching_invocations_on_failure = true # end # # foo = mock('foo') # foo.expects(:bar) # foo.stubs(:baz).returns('baz').raises(RuntimeError).throws(:tag, 'value') # # foo.baz(1, 2) # assert_raises(RuntimeError) { foo.baz(3, 4) } # assert_throws(:tag) { foo.baz(5, 6) } # # not all expectations were satisfied # unsatisfied expectations: # - expected exactly once, invoked never: #.bar # satisfied expectations: # - allowed any number of times, invoked 3 times: #.baz(any_parameters) # - #.baz(1, 2) # => "baz" # - #.baz(3, 4) # => raised RuntimeError # - #.baz(5, 6) # => threw (:tag, "value") def display_matching_invocations_on_failure=(value) @options[:display_matching_invocations_on_failure] = value end # @private def display_matching_invocations_on_failure? @options[:display_matching_invocations_on_failure] end # Perform strict keyword argument comparison. Only supported in Ruby >= v2.7. # # When this option is set to +false+ a positional +Hash+ and a set of keyword arguments are treated the same during comparison, which can lead to misleading passing tests in Ruby >= v3.0 (see examples below). However, a deprecation warning will be displayed if a positional +Hash+ matches a set of keyword arguments or vice versa. This is because {#strict_keyword_argument_matching=} will default to +true+ in the future. # # For more details on keyword arguments in Ruby v3, refer to {https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0 this article}. # # Note that +Hash+-related matchers such as {ParameterMatchers#has_value} or {ParameterMatchers#has_key} will still treat a positional +Hash+ and a set of keyword arguments the same, so misleading passing tests are still possible when they are used. # # This configuration option is +false+ by default to enable gradual adoption, but will be +true+ by default in the future. # # @param [Boolean] value +true+ to enable strict keyword argument matching; +false+ by default. # # @example Loose keyword argument matching (default) # # class Example # def foo(a, bar:); end # end # # example = Example.new # example.expects(:foo).with('a', bar: 'b') # example.foo('a', { bar: 'b' }) # # This passes the test, but would result in an ArgumentError in practice # # @example Strict keyword argument matching # # Mocha.configure do |c| # c.strict_keyword_argument_matching = true # end # # class Example # def foo(a, bar:); end # end # # example = Example.new # example.expects(:foo).with('a', bar: 'b') # example.foo('a', { bar: 'b' }) # # This now fails as expected def strict_keyword_argument_matching=(value) raise 'Strict keyword argument matching requires Ruby 2.7 and above.' unless Mocha::RUBY_V27_PLUS @options[:strict_keyword_argument_matching] = value end # @private def strict_keyword_argument_matching? @options[:strict_keyword_argument_matching] end class << self # @private def reset_configuration @configuration = nil end # Temporarily modify {Configuration} options. # # The supplied +temporary_options+ will override the current configuration for the duration of the supplied block. # The configuration will be returned to its original state when the block returns. # # @param [Hash] temporary_options the configuration options to apply for the duration of the block. # @yield block during which the configuration change will be in force. # # @example Temporarily allow stubbing of +nil+ # Mocha::Configuration.override(stubbing_method_on_nil: :allow) do # nil.stubs(:foo) # end def override(temporary_options) original_configuration = configuration @configuration = configuration.merge(new(temporary_options)) yield ensure @configuration = original_configuration end # @private def configuration @configuration ||= new end private # @private def change_config(action, new_value, &block) if block_given? temporarily_change_config action, new_value, &block else configuration.send("#{action}=".to_sym, new_value) end end # @private def temporarily_change_config(action, new_value) original_configuration = configuration new_configuration = configuration.dup new_configuration.send("#{action}=".to_sym, new_value) @configuration = new_configuration yield ensure @configuration = original_configuration end end end end mocha-2.4.2/lib/mocha/debug.rb000066400000000000000000000002701464615054400160660ustar00rootroot00000000000000module Mocha module Debug OPTIONS = (ENV['MOCHA_OPTIONS'] || '').split(',').freeze def self.puts(message) warn(message) if OPTIONS.include?('debug') end end end mocha-2.4.2/lib/mocha/deprecation.rb000066400000000000000000000007351464615054400173030ustar00rootroot00000000000000require 'mocha/backtrace_filter' module Mocha class Deprecation class << self attr_accessor :mode, :messages def warning(*messages) message = messages.join @messages << message return if mode == :disabled filter = BacktraceFilter.new location = filter.filtered(caller)[0] warn "Mocha deprecation warning at #{location}: #{message}" end end self.mode = :enabled self.messages = [] end end mocha-2.4.2/lib/mocha/detection/000077500000000000000000000000001464615054400164325ustar00rootroot00000000000000mocha-2.4.2/lib/mocha/detection/minitest.rb000066400000000000000000000007671464615054400206250ustar00rootroot00000000000000module Mocha module Detection module Minitest def self.testcase if defined?(::Minitest::Test) ::Minitest::Test elsif defined?(::Minitest::Unit::TestCase) ::Minitest::Unit::TestCase end end def self.version if defined?(::Minitest::Unit::VERSION) ::Minitest::Unit::VERSION elsif defined?(::Minitest::VERSION) ::Minitest::VERSION else '0.0.0' end end end end end mocha-2.4.2/lib/mocha/detection/test_unit.rb000066400000000000000000000013471464615054400210020ustar00rootroot00000000000000module Mocha module Detection module TestUnit def self.testcase if defined?(::Test::Unit::TestCase) && !(defined?(::Minitest::Unit::TestCase) && (::Test::Unit::TestCase < ::Minitest::Unit::TestCase)) && !(defined?(::Minitest::Spec) && (::Test::Unit::TestCase < ::Minitest::Spec)) ::Test::Unit::TestCase end end def self.version version = '1.0.0' if testcase begin require 'test/unit/version' rescue LoadError # rubocop:disable Lint/HandleExceptions end if defined?(::Test::Unit::VERSION) version = ::Test::Unit::VERSION end end version end end end end mocha-2.4.2/lib/mocha/error_with_filtered_backtrace.rb000066400000000000000000000004521464615054400230430ustar00rootroot00000000000000require 'mocha/backtrace_filter' module Mocha # @private class ErrorWithFilteredBacktrace < StandardError # @private def initialize(message = nil, backtrace = []) super(message) filter = BacktraceFilter.new set_backtrace(filter.filtered(backtrace)) end end end mocha-2.4.2/lib/mocha/exception_raiser.rb000066400000000000000000000006021464615054400203420ustar00rootroot00000000000000module Mocha class ExceptionRaiser def initialize(exception, message) @exception = exception @message = message end def evaluate(invocation) invocation.raised(@exception) raise @exception, @exception.to_s if @exception.is_a?(Module) && (@exception < Interrupt) raise @exception, @message if @message raise @exception end end end mocha-2.4.2/lib/mocha/expectation.rb000066400000000000000000000727701464615054400173410ustar00rootroot00000000000000require 'ruby2_keywords' require 'mocha/method_matcher' require 'mocha/parameters_matcher' require 'mocha/expectation_error' require 'mocha/return_values' require 'mocha/exception_raiser' require 'mocha/thrower' require 'mocha/yield_parameters' require 'mocha/is_a' require 'mocha/in_state_ordering_constraint' require 'mocha/change_state_side_effect' require 'mocha/cardinality' require 'mocha/configuration' require 'mocha/block_matcher' require 'mocha/backtrace_filter' module Mocha # Methods on expectations returned from {Mock#expects}, {Mock#stubs}, {ObjectMethods#expects} and {ObjectMethods#stubs}. class Expectation # Modifies expectation so that the number of calls to the expected method must be within a specific +range+. # # @param [Range,Integer] range specifies the allowable range in the number of expected invocations. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Specifying a specific number of expected invocations. # object = mock() # object.expects(:expected_method).times(3) # 3.times { object.expected_method } # # => verify succeeds # # object = mock() # object.expects(:expected_method).times(3) # 2.times { object.expected_method } # # => verify fails # # @example Specifying a range in the number of expected invocations. # object = mock() # object.expects(:expected_method).times(2..4) # 3.times { object.expected_method } # # => verify succeeds # # object = mock() # object.expects(:expected_method).times(2..4) # object.expected_method # # => verify fails def times(range) @cardinality.times(range) self end # Modifies expectation so that the expected method must be called exactly twice. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be invoked exactly twice. # object = mock() # object.expects(:expected_method).twice # object.expected_method # object.expected_method # # => verify succeeds # # object = mock() # object.expects(:expected_method).twice # object.expected_method # object.expected_method # object.expected_method # => unexpected invocation # # object = mock() # object.expects(:expected_method).twice # object.expected_method # # => verify fails def twice @cardinality.exactly(2) self end # Modifies expectation so that the expected method must be called exactly once. # # Note that this is the default behaviour for an expectation, but you may wish to use it for clarity/emphasis. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be invoked exactly once. # object = mock() # object.expects(:expected_method).once # object.expected_method # # => verify succeeds # # object = mock() # object.expects(:expected_method).once # object.expected_method # object.expected_method # => unexpected invocation # # object = mock() # object.expects(:expected_method).once # # => verify fails def once @cardinality.exactly(1) self end # Modifies expectation so that the expected method must never be called. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must never be called. # object = mock() # object.expects(:expected_method).never # object.expected_method # => unexpected invocation # # object = mock() # object.expects(:expected_method).never # # => verify succeeds def never @cardinality.exactly(0) self end # Modifies expectation so that the expected method must be called at least a +minimum_number_of_times+. # # @param [Integer] minimum_number_of_times minimum number of expected invocations. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be called at least twice. # object = mock() # object.expects(:expected_method).at_least(2) # 3.times { object.expected_method } # # => verify succeeds # # object = mock() # object.expects(:expected_method).at_least(2) # object.expected_method # # => verify fails def at_least(minimum_number_of_times) @cardinality.at_least(minimum_number_of_times) self end # Modifies expectation so that the expected method must be called at least once. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be called at least once. # object = mock() # object.expects(:expected_method).at_least_once # object.expected_method # # => verify succeeds # # object = mock() # object.expects(:expected_method).at_least_once # # => verify fails def at_least_once at_least(1) end # Modifies expectation so that the expected method must be called at most a +maximum_number_of_times+. # # @param [Integer] maximum_number_of_times maximum number of expected invocations. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be called at most twice. # object = mock() # object.expects(:expected_method).at_most(2) # 2.times { object.expected_method } # # => verify succeeds # # object = mock() # object.expects(:expected_method).at_most(2) # 3.times { object.expected_method } # => unexpected invocation def at_most(maximum_number_of_times) @cardinality.at_most(maximum_number_of_times) self end # Modifies expectation so that the expected method must be called at most once. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be called at most once. # object = mock() # object.expects(:expected_method).at_most_once # object.expected_method # # => verify succeeds # # object = mock() # object.expects(:expected_method).at_most_once # 2.times { object.expected_method } # => unexpected invocation def at_most_once at_most(1) end # Modifies expectation so that the expected method must be called with +expected_parameters_or_matchers+. # # May be used with Ruby literals or variables for exact matching or with parameter matchers for less-specific matching, e.g. {ParameterMatchers#includes}, {ParameterMatchers#has_key}, etc. See {ParameterMatchers} for a list of all available parameter matchers. # # Positional arguments were separated from keyword arguments in Ruby v3 (see {https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0 this article}). In relation to this a new configuration option ({Configuration#strict_keyword_argument_matching=}) is available in Ruby >= 2.7. # # When {Configuration#strict_keyword_argument_matching=} is set to +false+ (which is currently the default), a positional +Hash+ and a set of keyword arguments passed to {#with} are treated the same for the purposes of parameter matching. However, a deprecation warning will be displayed if a positional +Hash+ matches a set of keyword arguments or vice versa. This is because {Configuration#strict_keyword_argument_matching=} will default to +true+ in the future. # # When {Configuration#strict_keyword_argument_matching=} is set to +true+, an actual positional +Hash+ will not match an expected set of keyword arguments; and vice versa, an actual set of keyword arguments will not match an expected positional +Hash+, i.e. the parameter matching is stricter. # # @see ParameterMatchers # @see Configuration#strict_keyword_argument_matching= # # @param [*Array] expected_parameters_or_matchers expected parameter values or parameter matchers. # @yield optional block specifying custom matching. # @yieldparam [*Array] actual_parameters parameters with which expected method was invoked. # @yieldreturn [Boolean] +true+ if +actual_parameters+ are acceptable. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be called with exact parameter values. # object = mock() # object.expects(:expected_method).with(:param1, :param2) # object.expected_method(:param1, :param2) # # => verify succeeds # # object = mock() # object.expects(:expected_method).with(:param1, :param2) # object.expected_method(:param3) # # => verify fails # # @example Expected method must be called with parameters matching parameter matchers. # object = mock() # object.expects(:expected_method).with(includes('string2'), anything) # object.expected_method(['string1', 'string2'], 'any-old-value') # # => verify succeeds # # object = mock() # object.expects(:expected_method).with(includes('string2'), anything) # object.expected_method(['string1'], 'any-old-value') # # => verify fails # # @example Loose keyword argument matching (default) # # class Example # def foo(a, bar:); end # end # # example = Example.new # example.expects(:foo).with('a', bar: 'b') # example.foo('a', { bar: 'b' }) # # This passes the test, but would result in an ArgumentError in practice # # @example Strict keyword argument matching # # Mocha.configure do |c| # c.strict_keyword_argument_matching = true # end # # class Example # def foo(a, bar:); end # end # # example = Example.new # example.expects(:foo).with('a', bar: 'b') # example.foo('a', { bar: 'b' }) # # This now fails as expected # # @example Expected method must be called with a value divisible by 4. # object = mock() # object.expects(:expected_method).with() { |value| value % 4 == 0 } # object.expected_method(16) # # => verify succeeds # # object = mock() # object.expects(:expected_method).with() { |value| value % 4 == 0 } # object.expected_method(17) # # => verify fails def with(*expected_parameters_or_matchers, &matching_block) @parameters_matcher = ParametersMatcher.new(expected_parameters_or_matchers, self, &matching_block) self end ruby2_keywords(:with) # Modifies expectation so that the expected method must be called with a block. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be called with a block. # object = mock() # object.expects(:expected_method).with_block_given # object.expected_method { 1 + 1 } # # => verify succeeds # # object = mock() # object.expects(:expected_method).with_block_given # object.expected_method # # => verify fails def with_block_given @block_matcher = BlockMatchers::BlockGiven.new self end # Modifies expectation so that the expected method must be called without a block. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Expected method must be called without a block. # object = mock() # object.expects(:expected_method).with_no_block_given # object.expected_method # # => verify succeeds # # object = mock() # object.expects(:expected_method).with_block_given # object.expected_method { 1 + 1 } # # => verify fails def with_no_block_given @block_matcher = BlockMatchers::NoBlockGiven.new self end # Modifies expectation so that when the expected method is called, it yields to the block with the specified +parameters+. # # If no +parameters+ are specified, it yields to the block without any parameters. # # If no block is provided, the method will still attempt to yield resulting in a +LocalJumpError+. Note that this is what would happen if a "real" (non-mock) method implementation tried to yield to a non-existent block. # # May be called multiple times on the same expectation for consecutive invocations. # # @param [*Array] parameters parameters to be yielded. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # @see #then # # @example Yield when expected method is invoked. # benchmark = mock() # benchmark.expects(:measure).yields # yielded = false # benchmark.measure { yielded = true } # yielded # => true # # @example Yield parameters when expected method is invoked. # fibonacci = mock() # fibonacci.expects(:next_pair).yields(0, 1) # sum = 0 # fibonacci.next_pair { |first, second| sum = first + second } # sum # => 1 # # @example Yield different parameters on different invocations of the expected method. # fibonacci = mock() # fibonacci.expects(:next_pair).yields(0, 1).then.yields(1, 1) # sum = 0 # fibonacci.next_pair { |first, second| sum = first + second } # sum # => 1 # fibonacci.next_pair { |first, second| sum = first + second } # sum # => 2 def yields(*parameters) multiple_yields(parameters) end # Modifies expectation so that when the expected method is called, it yields multiple times per invocation with the specified +parameter_groups+. # # If no block is provided, the method will still attempt to yield resulting in a +LocalJumpError+. Note that this is what would happen if a "real" (non-mock) method implementation tried to yield to a non-existent block. # # @param [*Array] parameter_groups each element of +parameter_groups+ should iself be an +Array+ representing the parameters to be passed to the block for a single yield. Any element of +parameter_groups+ that is not an +Array+ is wrapped in an +Array+. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # @see #then # # @example When +foreach+ is called, the stub will invoke the block twice, the first time it passes ['row1_col1', 'row1_col2'] as the parameters, and the second time it passes ['row2_col1', ''] as the parameters. # csv = mock() # csv.expects(:foreach).with("path/to/file.csv").multiple_yields(['row1_col1', 'row1_col2'], ['row2_col1', '']) # rows = [] # csv.foreach { |row| rows << row } # rows # => [['row1_col1', 'row1_col2'], ['row2_col1', '']] # # @example Yield different groups of parameters on different invocations of the expected method. Simulating a situation where the CSV file at 'path/to/file.csv' has been modified between the two calls to +foreach+. # csv = mock() # csv.stubs(:foreach).with("path/to/file.csv").multiple_yields(['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']).then.multiple_yields(['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2']) # rows_from_first_invocation = [] # rows_from_second_invocation = [] # csv.foreach { |row| rows_from_first_invocation << row } # first invocation # csv.foreach { |row| rows_from_second_invocation << row } # second invocation # rows_from_first_invocation # => [['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']] # rows_from_second_invocation # => [['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2']] def multiple_yields(*parameter_groups) @yield_parameters.add(*parameter_groups) self end # Modifies expectation so that when the expected method is called, it returns the specified +value+. # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # @see #then # # @overload def returns(value) # @param [Object] value value to return on invocation of expected method. # @overload def returns(*values) # @param [*Array] values values to return on consecutive invocations of expected method. # # @example Return the same value on every invocation. # object = mock() # object.stubs(:stubbed_method).returns('result') # object.stubbed_method # => 'result' # object.stubbed_method # => 'result' # # @example Return a different value on consecutive invocations. # object = mock() # object.stubs(:stubbed_method).returns(1, 2) # object.stubbed_method # => 1 # object.stubbed_method # => 2 # # @example Alternative way to return a different value on consecutive invocations. # object = mock() # object.stubs(:expected_method).returns(1, 2).then.returns(3) # object.expected_method # => 1 # object.expected_method # => 2 # object.expected_method # => 3 # # @example May be called in conjunction with {#raises} on the same expectation. # object = mock() # object.stubs(:expected_method).returns(1, 2).then.raises(Exception) # object.expected_method # => 1 # object.expected_method # => 2 # object.expected_method # => raises exception of class Exception1 # # @example Note that in Ruby a method returning multiple values is exactly equivalent to a method returning an +Array+ of those values. # object = mock() # object.stubs(:expected_method).returns([1, 2]) # x, y = object.expected_method # x # => 1 # y # => 2 def returns(*values) @return_values += ReturnValues.build(*values) self end # Modifies expectation so that when the expected method is called, it raises the specified +exception+ with the specified +message+ i.e. calls +Kernel#raise(exception, message)+. # # @param [Class,Exception,String,#exception] exception exception to be raised or message to be passed to RuntimeError. # @param [String] message exception message. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @see Kernel#raise # @see #then # # @overload def raises # @overload def raises(exception) # @overload def raises(exception, message) # # @example Raise specified exception if expected method is invoked. # object = stub() # object.stubs(:expected_method).raises(Exception, 'message') # object.expected_method # => raises exception of class Exception and with message 'message' # # @example Raise custom exception with extra constructor parameters by passing in an instance of the exception. # object = stub() # object.stubs(:expected_method).raises(MyException.new('message', 1, 2, 3)) # object.expected_method # => raises the specified instance of MyException # # @example Raise different exceptions on consecutive invocations of the expected method. # object = stub() # object.stubs(:expected_method).raises(Exception1).then.raises(Exception2) # object.expected_method # => raises exception of class Exception1 # object.expected_method # => raises exception of class Exception2 # # @example Raise an exception on first invocation of expected method and then return values on subsequent invocations. # object = stub() # object.stubs(:expected_method).raises(Exception).then.returns(2, 3) # object.expected_method # => raises exception of class Exception1 # object.expected_method # => 2 # object.expected_method # => 3 def raises(exception = RuntimeError, message = nil) @return_values += ReturnValues.new(ExceptionRaiser.new(exception, message)) self end # Modifies expectation so that when the expected method is called, it throws the specified +tag+ with the specific return value +object+ i.e. calls +Kernel#throw(tag, object)+. # # @param [Symbol,String] tag tag to throw to transfer control to the active catch block. # @param [Object] object return value for the catch block. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @see Kernel#throw # @see #then # # @overload def throw(tag) # @overload def throw(tag, object) # # @example Throw tag when expected method is invoked. # object = stub() # object.stubs(:expected_method).throws(:done) # object.expected_method # => throws tag :done # # @example Throw tag with return value +object+ c.f. +Kernel#throw+. # object = stub() # object.stubs(:expected_method).throws(:done, 'result') # object.expected_method # => throws tag :done and causes catch block to return 'result' # # @example Throw different tags on consecutive invocations of the expected method. # object = stub() # object.stubs(:expected_method).throws(:done).then.throws(:continue) # object.expected_method # => throws :done # object.expected_method # => throws :continue # # @example Throw tag on first invocation of expected method and then return values for subsequent invocations. # object = stub() # object.stubs(:expected_method).throws(:done).then.returns(2, 3) # object.expected_method # => throws :done # object.expected_method # => 2 # object.expected_method # => 3 def throws(tag, object = nil) @return_values += ReturnValues.new(Thrower.new(tag, object)) self end # @overload def then # Used as syntactic sugar to improve readability. It has no effect on state of the expectation. # @overload def then(state) # Used to change the +state_machine+ to the specified state when the expected invocation occurs. # @param [StateMachine::State] state state_machine.is(state_name) provides a mechanism to change the +state_machine+ into the state specified by +state_name+ when the expected method is invoked. # # @see API#states # @see StateMachine # @see #when # # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @example Using {#then} as syntactic sugar when specifying values to be returned and exceptions to be raised on consecutive invocations of the expected method. # object = mock() # object.stubs(:expected_method).returns(1, 2).then.raises(Exception).then.returns(4) # object.expected_method # => 1 # object.expected_method # => 2 # object.expected_method # => raises exception of class Exception # object.expected_method # => 4 # # @example Using {#then} to change the +state+ of a +state_machine+ on the invocation of an expected method. # power = states('power').starts_as('off') # # radio = mock('radio') # radio.expects(:switch_on).then(power.is('on')) # radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on')) # radio.expects(:adjust_volume).with(+5).when(power.is('on')) # radio.expects(:select_channel).with('BBC World Service').when(power.is('on')) # radio.expects(:adjust_volume).with(-5).when(power.is('on')) # radio.expects(:switch_off).then(power.is('off')) def then(state = nil) add_side_effect(ChangeStateSideEffect.new(state)) if state self end # Constrains the expectation to occur only when the +state_machine+ is in the state specified by +state_predicate+. # # @param [StateMachine::StatePredicate] state_predicate +state_machine.is(state_name)+ provides a mechanism to determine whether the +state_machine+ is in the state specified by +state_predicate+ when the expected method is invoked. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @see API#states # @see StateMachine # @see #then # # @example Using {#when} to only allow invocation of methods when "power" state machine is in the "on" state. # power = states('power').starts_as('off') # # radio = mock('radio') # radio.expects(:switch_on).then(power.is('on')) # radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on')) # radio.expects(:adjust_volume).with(+5).when(power.is('on')) # radio.expects(:select_channel).with('BBC World Service').when(power.is('on')) # radio.expects(:adjust_volume).with(-5).when(power.is('on')) # radio.expects(:switch_off).then(power.is('off')) def when(state_predicate) add_ordering_constraint(InStateOrderingConstraint.new(state_predicate)) self end # Constrains the expectation so that it must be invoked at the current point in the +sequence+. # # To expect a sequence of invocations, write the expectations in order and add the +in_sequence(sequence)+ clause to each one. # # Expectations in a +sequence+ can have any invocation count. # # If an expectation in a sequence is stubbed, rather than expected, it can be skipped in the +sequence+. # # An expected method can appear in multiple sequences. # # @param [Sequence] sequence sequence in which expected method should appear. # @param [*Array] sequences more sequences in which expected method should appear. # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. # # @see API#sequence # # @example Ensure methods are invoked in a specified order. # breakfast = sequence('breakfast') # # egg = mock('egg') # egg.expects(:crack).in_sequence(breakfast) # egg.expects(:fry).in_sequence(breakfast) # egg.expects(:eat).in_sequence(breakfast) def in_sequence(sequence, *sequences) sequences.unshift(sequence).each { |seq| add_in_sequence_ordering_constraint(seq) } self end # @private attr_reader :backtrace # @private def initialize(mock, expected_method_name, backtrace = nil) @mock = mock @method_matcher = MethodMatcher.new(expected_method_name.to_sym) @parameters_matcher = ParametersMatcher.new @block_matcher = BlockMatchers::OptionalBlock.new @ordering_constraints = [] @side_effects = [] @cardinality = Cardinality.new.exactly(1) @return_values = ReturnValues.new @yield_parameters = YieldParameters.new @backtrace = backtrace || caller end # @private def add_ordering_constraint(ordering_constraint) @ordering_constraints << ordering_constraint end # @private def add_in_sequence_ordering_constraint(sequence) sequence.constrain_as_next_in_sequence(self) end # @private def add_side_effect(side_effect) @side_effects << side_effect end # @private def perform_side_effects @side_effects.each(&:perform) end # @private def in_correct_order? @ordering_constraints.all?(&:allows_invocation_now?) end # @private def ordering_constraints_not_allowing_invocation_now @ordering_constraints.reject(&:allows_invocation_now?) end # @private def matches_method?(method_name) @method_matcher.match?(method_name) end # @private def match?(invocation, ignoring_order: false) order_independent_match = @method_matcher.match?(invocation.method_name) && @parameters_matcher.match?(invocation.arguments) && @block_matcher.match?(invocation.block) ignoring_order ? order_independent_match : order_independent_match && in_correct_order? end # @private def invocations_allowed? @cardinality.invocations_allowed? end # @private def satisfied? @cardinality.satisfied? end # @private def invoke(invocation) perform_side_effects @cardinality << invocation invocation.call(@yield_parameters, @return_values) end # @private def verified?(assertion_counter = nil) assertion_counter.increment if assertion_counter && @cardinality.needs_verifying? @cardinality.verified? end # @private def used? @cardinality.used? end # @private def inspect address = __id__ * 2 address += 0x100000000 if address < 0 "#x', address: address)} #{mocha_inspect} >" end # @private def mocha_inspect message = "#{@cardinality.anticipated_times}, #{@cardinality.invoked_times}: #{method_signature}" message << "; #{@ordering_constraints.map(&:mocha_inspect).join('; ')}" unless @ordering_constraints.empty? if Mocha.configuration.display_matching_invocations_on_failure? message << @cardinality.actual_invocations end message end # @private def method_signature signature = "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}" signature << " #{@block_matcher.mocha_inspect}" if @block_matcher.mocha_inspect signature end # @private def definition_location filter = BacktraceFilter.new filter.filtered(backtrace)[0] end end end mocha-2.4.2/lib/mocha/expectation_error.rb000066400000000000000000000005541464615054400205410ustar00rootroot00000000000000module Mocha # Default exception class raised when an unexpected invocation or an unsatisfied expectation occurs. # # Authors of test libraries may use +Mocha::ExpectationErrorFactory+ to have Mocha raise a different exception. # # @see Mocha::ExpectationErrorFactory class ExpectationError < Exception; end # rubocop:disable Lint/InheritException end mocha-2.4.2/lib/mocha/expectation_error_factory.rb000066400000000000000000000027021464615054400222650ustar00rootroot00000000000000require 'mocha/backtrace_filter' require 'mocha/expectation_error' module Mocha # This factory determines what class of exception should be raised when Mocha detects a test failure. # # This class should only be used by authors of test libraries and not by typical "users" of Mocha. # # For example, it is used by +Mocha::Integration::Minitest::Adapter+ in order to have Mocha raise a +Minitest::Assertion+ which can then be sensibly handled by +Minitest::Unit::TestCase+. # # @see Mocha::Integration::Minitest::Adapter class ExpectationErrorFactory class << self # @!attribute exception_class # Determines what class of exception should be raised when Mocha detects a test failure. # # This attribute may be set by authors of test libraries in order to have Mocha raise exceptions of a specific class when there is an unexpected invocation or an unsatisfied expectation. # # By default a +Mocha::ExpectationError+ will be raised. # # @return [Exception] class of exception to be raised when an expectation error occurs # @see Mocha::ExpectationError attr_accessor :exception_class # @private def build(message = nil, backtrace = []) exception = exception_class.new(message) filter = BacktraceFilter.new exception.set_backtrace(filter.filtered(backtrace)) exception end end self.exception_class = ExpectationError end end mocha-2.4.2/lib/mocha/expectation_list.rb000066400000000000000000000026171464615054400203650ustar00rootroot00000000000000module Mocha class ExpectationList def initialize(expectations = []) @expectations = expectations end def add(expectation) @expectations.unshift(expectation) expectation end def remove_all_matching_method(method_name) @expectations.reject! { |expectation| expectation.matches_method?(method_name) } end def matches_method?(method_name) @expectations.any? { |expectation| expectation.matches_method?(method_name) } end def match(invocation, ignoring_order: false) matching_expectations(invocation, ignoring_order: ignoring_order).first end def match_but_out_of_order(invocation) matching_expectations(invocation).first end def match_allowing_invocation(invocation) matching_expectations(invocation).detect(&:invocations_allowed?) end def verified?(assertion_counter = nil) @expectations.all? { |expectation| expectation.verified?(assertion_counter) } end def to_a @expectations end def to_set @expectations.to_set end def length @expectations.length end def any? @expectations.any? end def +(other) self.class.new(to_a + other.to_a) end private def matching_expectations(invocation, ignoring_order: false) @expectations.select { |e| e.match?(invocation, ignoring_order: ignoring_order) } end end end mocha-2.4.2/lib/mocha/hooks.rb000066400000000000000000000041471464615054400161320ustar00rootroot00000000000000require 'mocha/mockery' module Mocha # Integration hooks for test library authors. # # The methods in this module should be called from test libraries wishing to integrate with Mocha. # # This module is provided as part of the +Mocha::API+ module and is therefore part of the public API, but should only be used by authors of test libraries and not by typical "users" of Mocha. # # Integration with Test::Unit and Minitest are provided as part of Mocha, because they are (or were once) part of the Ruby standard library. Integration with other test libraries is not provided as *part* of Mocha, but is supported by means of the methods in this module. # # See the code in the +Adapter+ modules for examples of how to use the methods in this module. +Mocha::ExpectationErrorFactory+ may be used if you want +Mocha+ to raise a different type of exception. # # @see Mocha::Integration::TestUnit::Adapter # @see Mocha::Integration::Minitest::Adapter # @see Mocha::ExpectationErrorFactory # @see Mocha::API module Hooks # Prepares Mocha before a test (only for use by authors of test libraries). # # This method should be called before each individual test starts (including before any "setup" code). def mocha_setup Mockery.setup end # Verifies that all mock expectations have been met (only for use by authors of test libraries). # # This is equivalent to a series of "assertions". # # This method should be called at the end of each individual test, before it has been determined whether or not the test has passed. def mocha_verify(assertion_counter = nil) Mockery.verify(assertion_counter) end # Resets Mocha after a test (only for use by authors of test libraries). # # This method should be called after each individual test has finished (including after any "teardown" code). def mocha_teardown(origin = mocha_test_name) Mockery.teardown(origin) end # Returns a string representing the unit test name, to be included in some Mocha # to help track down potential bugs. def mocha_test_name nil end end end mocha-2.4.2/lib/mocha/in_state_ordering_constraint.rb000066400000000000000000000004431464615054400227450ustar00rootroot00000000000000module Mocha class InStateOrderingConstraint def initialize(state_predicate) @state_predicate = state_predicate end def allows_invocation_now? @state_predicate.active? end def mocha_inspect "when #{@state_predicate.mocha_inspect}" end end end mocha-2.4.2/lib/mocha/inspect.rb000077500000000000000000000026671464615054400164640ustar00rootroot00000000000000require 'date' module Mocha module Inspect module ObjectMethods def mocha_inspect address = __id__ * 2 address += 0x100000000 if address < 0 inspect =~ /#x', address: address)}>" : inspect end end module ArrayMethods def mocha_inspect(wrapped = true) unwrapped = collect(&:mocha_inspect).join(', ') wrapped ? "[#{unwrapped}]" : unwrapped end end module HashMethods def mocha_inspect if Hash.ruby2_keywords_hash?(self) collect do |key, value| case key when Symbol "#{key}: #{value.mocha_inspect}" else "#{key.mocha_inspect} => #{value.mocha_inspect}" end end.join(', ') else unwrapped = collect { |key, value| "#{key.mocha_inspect} => #{value.mocha_inspect}" }.join(', ') "{#{unwrapped}}" end end end module TimeMethods def mocha_inspect "#{inspect} (#{to_f} secs)" end end module DateMethods def mocha_inspect to_s end end end end class Object include Mocha::Inspect::ObjectMethods end class Array include Mocha::Inspect::ArrayMethods end class Hash include Mocha::Inspect::HashMethods end class Time include Mocha::Inspect::TimeMethods end class Date include Mocha::Inspect::DateMethods end mocha-2.4.2/lib/mocha/instance_method.rb000066400000000000000000000004511464615054400201450ustar00rootroot00000000000000require 'mocha/stubbed_method' module Mocha class InstanceMethod < StubbedMethod private def mock_owner stubbee end def stubbee_method(method_name) stubbee._method(method_name) end def original_method_owner stubbee.singleton_class end end end mocha-2.4.2/lib/mocha/integration/000077500000000000000000000000001464615054400167775ustar00rootroot00000000000000mocha-2.4.2/lib/mocha/integration/assertion_counter.rb000066400000000000000000000003271464615054400230740ustar00rootroot00000000000000module Mocha module Integration class AssertionCounter def initialize(test_case) @test_case = test_case end def increment @test_case.assert(true) end end end end mocha-2.4.2/lib/mocha/integration/minitest.rb000066400000000000000000000014061464615054400211610ustar00rootroot00000000000000require 'mocha/debug' require 'mocha/detection/minitest' require 'mocha/integration/minitest/adapter' module Mocha module Integration module Minitest def self.activate target = Detection::Minitest.testcase return false unless target minitest_version = Gem::Version.new(Detection::Minitest.version) Debug.puts "Detected Minitest version: #{minitest_version}" unless Minitest::Adapter.applicable_to?(minitest_version) raise 'Versions of minitest earlier than v3.3.0 are not supported.' end unless target < Minitest::Adapter Debug.puts "Applying #{Minitest::Adapter.description}" target.send(:include, Minitest::Adapter) end true end end end end mocha-2.4.2/lib/mocha/integration/minitest/000077500000000000000000000000001464615054400206335ustar00rootroot00000000000000mocha-2.4.2/lib/mocha/integration/minitest/adapter.rb000066400000000000000000000030631464615054400226020ustar00rootroot00000000000000require 'mocha/api' require 'mocha/integration/assertion_counter' require 'mocha/expectation_error_factory' module Mocha module Integration module Minitest # Integrates Mocha into recent versions of Minitest. # # See the source code for an example of how to integrate Mocha into a test library. module Adapter include Mocha::API # @private def self.applicable_to?(minitest_version) Gem::Requirement.new('>= 3.3.0').satisfied_by?(minitest_version) end # @private def self.description 'adapter for Minitest gem >= v3.3.0' end # @private def self.included(_mod) Mocha::ExpectationErrorFactory.exception_class = ::Minitest::Assertion end # @private def before_setup mocha_setup super end # @private def before_teardown return unless passed? assertion_counter = Integration::AssertionCounter.new(self) mocha_verify(assertion_counter) ensure super end # @private def after_teardown super mocha_teardown end # @private def mocha_test_name if respond_to?(:name) test_name = name elsif respond_to?(:__name__) # Older minitest test_name = __name__ end if test_name "#{self.class.name}##{test_name}" else self.class.name end end end end end end mocha-2.4.2/lib/mocha/integration/minitest/exception_translation.rb000066400000000000000000000006151464615054400255760ustar00rootroot00000000000000require 'mocha/expectation_error' module Mocha module Integration module Minitest def self.translate(exception) return exception unless exception.is_a?(::Mocha::ExpectationError) translated_exception = ::Minitest::Assertion.new(exception.message) translated_exception.set_backtrace(exception.backtrace) translated_exception end end end end mocha-2.4.2/lib/mocha/integration/monkey_patcher.rb000066400000000000000000000013331464615054400223340ustar00rootroot00000000000000require 'mocha/api' module Mocha module Integration module MonkeyPatcher def self.apply(mod, run_method_patch) if mod < Mocha::API Debug.puts "Mocha::API already included in #{mod}" else mod.send(:include, Mocha::API) end if mod.method_defined?(:run_before_mocha) Debug.puts "#{mod}#run_before_mocha method already defined" elsif mod.method_defined?(:run) mod.send(:alias_method, :run_before_mocha, :run) mod.send(:remove_method, :run) mod.send(:include, run_method_patch) else raise "Unable to monkey-patch #{mod}, because it does not define a `#run` method" end end end end end mocha-2.4.2/lib/mocha/integration/test_unit.rb000066400000000000000000000014161464615054400213440ustar00rootroot00000000000000require 'mocha/debug' require 'mocha/detection/test_unit' require 'mocha/integration/test_unit/adapter' module Mocha module Integration module TestUnit def self.activate target = Detection::TestUnit.testcase return false unless target test_unit_version = Gem::Version.new(Detection::TestUnit.version) Debug.puts "Detected Test::Unit version: #{test_unit_version}" unless TestUnit::Adapter.applicable_to?(test_unit_version) raise 'Versions of test-unit earlier than v2.5.1 are not supported.' end unless target < TestUnit::Adapter Debug.puts "Applying #{TestUnit::Adapter.description}" target.send(:include, TestUnit::Adapter) end true end end end end mocha-2.4.2/lib/mocha/integration/test_unit/000077500000000000000000000000001464615054400210155ustar00rootroot00000000000000mocha-2.4.2/lib/mocha/integration/test_unit/adapter.rb000066400000000000000000000026131464615054400227640ustar00rootroot00000000000000require 'mocha/api' require 'mocha/integration/assertion_counter' require 'mocha/expectation_error' module Mocha module Integration module TestUnit # Integrates Mocha into recent versions of Test::Unit. # # See the source code for an example of how to integrate Mocha into a test library. module Adapter include Mocha::API # @private def self.applicable_to?(test_unit_version) Gem::Requirement.new('>= 2.5.1').satisfied_by?(test_unit_version) end # @private def self.description 'adapter for Test::Unit gem >= v2.5.1' end # @private def self.included(mod) mod.setup :mocha_setup, before: :prepend mod.exception_handler(:handle_mocha_expectation_error) mod.cleanup after: :append do assertion_counter = Integration::AssertionCounter.new(self) mocha_verify(assertion_counter) end mod.teardown :mocha_teardown, after: :append end private # @private def mocha_test_name name end # @private def handle_mocha_expectation_error(exception) return false unless exception.is_a?(Mocha::ExpectationError) problem_occurred add_failure(exception.message, exception.backtrace) true end end end end end mocha-2.4.2/lib/mocha/invocation.rb000066400000000000000000000033501464615054400171530ustar00rootroot00000000000000require 'mocha/parameters_matcher' require 'mocha/raised_exception' require 'mocha/return_values' require 'mocha/thrown_object' require 'mocha/yield_parameters' module Mocha class Invocation attr_reader :method_name, :block def initialize(mock, method_name, arguments = [], block = nil) @mock = mock @method_name = method_name @arguments = arguments @block = block @yields = [] @result = nil end def call(yield_parameters = YieldParameters.new, return_values = ReturnValues.new) yield_parameters.next_invocation.each do |yield_args| @yields << ParametersMatcher.new(yield_args) raise LocalJumpError unless @block @block.call(*yield_args) end return_values.next(self) end def returned(value) @result = value end def raised(exception) @result = RaisedException.new(exception) end def threw(tag, value) @result = ThrownObject.new(tag, value) end def arguments @arguments.dup end def call_description description = "#{@mock.mocha_inspect}.#{@method_name}#{argument_description}" description << ' { ... }' unless @block.nil? description end def short_call_description "#{@method_name}(#{@arguments.join(', ')})" end def result_description desc = "# => #{@result.mocha_inspect}" desc << " after yielding #{@yields.map(&:mocha_inspect).join(', then ')}" if @yields.any? desc end def full_description "\n - #{call_description} #{result_description}" end private def argument_description signature = arguments.mocha_inspect signature = signature.gsub(/^\[|\]$/, '') "(#{signature})" end end end mocha-2.4.2/lib/mocha/is_a.rb000066400000000000000000000001211464615054400157060ustar00rootroot00000000000000class Object # :stopdoc: alias_method :__is_a__, :is_a? # :startdoc: end mocha-2.4.2/lib/mocha/logger.rb000066400000000000000000000002301464615054400162530ustar00rootroot00000000000000module Mocha class Logger def initialize(io) @io = io end def warn(message) @io.puts "WARNING: #{message}" end end end mocha-2.4.2/lib/mocha/macos_version.rb000066400000000000000000000002331464615054400176460ustar00rootroot00000000000000module Mocha MACOS = /darwin/.match(RUBY_PLATFORM) MACOS_VERSION = MACOS && /darwin(\d+)/.match(RUBY_PLATFORM)[1].to_i MACOS_MOJAVE_VERSION = 18 end mocha-2.4.2/lib/mocha/method_matcher.rb000066400000000000000000000005351464615054400177670ustar00rootroot00000000000000module Mocha class MethodMatcher attr_reader :expected_method_name def initialize(expected_method_name) @expected_method_name = expected_method_name end def match?(actual_method_name) @expected_method_name == actual_method_name.to_sym end def mocha_inspect @expected_method_name.to_s end end end mocha-2.4.2/lib/mocha/minitest.rb000066400000000000000000000002731464615054400166370ustar00rootroot00000000000000require 'mocha/ruby_version' require 'mocha/integration/minitest' unless Mocha::Integration::Minitest.activate raise "Minitest must be loaded *before* `require 'mocha/minitest'`." end mocha-2.4.2/lib/mocha/mock.rb000066400000000000000000000401061464615054400157330ustar00rootroot00000000000000require 'ruby2_keywords' require 'mocha/expectation' require 'mocha/expectation_list' require 'mocha/invocation' require 'mocha/names' require 'mocha/receivers' require 'mocha/method_matcher' require 'mocha/parameters_matcher' require 'mocha/argument_iterator' require 'mocha/expectation_error_factory' module Mocha # Traditional mock object. # # {expects} and {stubs} return an {Expectation} which can be further modified # by methods on {Expectation}. # # {responds_like} and {responds_like_instance_of} both return a {Mock}, and # can therefore, be chained to the original creation methods in {API}. # They force the mock to indicate what it is supposed to be mocking, thus # making it a safer verifying mock. They check that the underlying +responder+ # will actually respond to the methods being stubbed, throwing a # +NoMethodError+ upon invocation otherwise. # # Stubs and expectations are basically the same thing. A stub is just an # expectation of zero or more invocations. The {#stubs} method is syntactic # sugar to make the intent of the test more explicit. # # When a method is invoked on a mock object, the mock object searches through # its expectations from newest to oldest to find one that matches the # invocation. After the invocation, the matching expectation might stop # matching further invocations. For example, an +expects(:foo).once+ # expectation only matches once and will be ignored on future invocations # while an +expects(:foo).at_least_once+ expectation will always be matched # against invocations. # # This scheme allows you to: # # - Set up default stubs in your the +setup+ method of your test class and # override some of those stubs in individual tests. # - Set up different +once+ expectations for the same method with different # action per invocation. However, it's better to use the # {Expectation#returns} method with multiple arguments to do this, as # described below. # # However, there are some possible "gotchas" caused by this scheme: # # - if you create an expectation and then a stub for the same method, the # stub will always override the expectation and the expectation will never # be met. # - if you create a stub and then an expectation for the same method, the # expectation will match, and when it stops matching the stub will be used # instead, possibly masking test failures. # - if you create different expectations for the same method, they will be # invoked in the opposite order than that in which they were specified, # rather than the same order. # # The best thing to do is not set up multiple expectations and stubs for the # same method with exactly the same matchers. Instead, use the # {Expectation#returns} method with multiple arguments to create multiple # actions for a method. You can also chain multiple calls to # {Expectation#returns} and {Expectation#raises} (along with syntactic sugar # {Expectation#then} if desired). # # @example # object = mock() # object.stubs(:expected_method).returns(1, 2).then.raises(Exception) # object.expected_method # => 1 # object.expected_method # => 2 # object.expected_method # => raises exception of class Exception1 # # If you want to specify more complex ordering or order invocations across # different mock objects, use the {Expectation#in_sequence} method to # explicitly define a total or partial ordering of invocations. class Mock # Adds an expectation that the specified method must be called exactly once with any parameters. # # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}. # # @overload def expects(method_name) # @param [Symbol,String] method_name name of expected method # @overload def expects(expected_methods_vs_return_values) # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times. # # @example Expected method invoked once so no error raised # object = mock() # object.expects(:expected_method) # object.expected_method # # @example Expected method not invoked so error raised # object = mock() # object.expects(:expected_method) # # error raised when test completes, because expected_method not called exactly once # # @example Expected method invoked twice so error raised # object = mock() # object.expects(:expected_method) # object.expected_method # object.expected_method # => error raised when expected method invoked second time # # @example Setup multiple expectations using +expected_methods_vs_return_values+. # object = mock() # object.expects(expected_method_one: :result_one, expected_method_two: :result_two) # # # is exactly equivalent to # # object = mock() # object.expects(:expected_method_one).returns(:result_one) # object.expects(:expected_method_two).returns(:result_two) def expects(method_name_or_hash, backtrace = nil) expectation = nil iterator = ArgumentIterator.new(method_name_or_hash) iterator.each do |*args| method_name = args.shift ensure_method_not_already_defined(method_name) expectation = Expectation.new(self, method_name, backtrace) expectation.in_sequence(@mockery.sequences.last) if @mockery.sequences.any? expectation.returns(args.shift) unless args.empty? @expectations.add(expectation) end expectation end # Adds an expectation that the specified method may be called any number of times with any parameters. # # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}. # # @overload def stubs(method_name) # @param [Symbol,String] method_name name of stubbed method # @overload def stubs(stubbed_methods_vs_return_values) # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times. # # @example No error raised however many times stubbed method is invoked # object = mock() # object.stubs(:stubbed_method) # object.stubbed_method # object.stubbed_method # # no error raised # # @example Setup multiple expectations using +stubbed_methods_vs_return_values+. # object = mock() # object.stubs(stubbed_method_one: :result_one, stubbed_method_two: :result_two) # # # is exactly equivalent to # # object = mock() # object.stubs(:stubbed_method_one).returns(:result_one) # object.stubs(:stubbed_method_two).returns(:result_two) def stubs(method_name_or_hash, backtrace = nil) expectation = nil iterator = ArgumentIterator.new(method_name_or_hash) iterator.each do |*args| method_name = args.shift ensure_method_not_already_defined(method_name) expectation = Expectation.new(self, method_name, backtrace) expectation.at_least(0) expectation.in_sequence(@mockery.sequences.last) if @mockery.sequences.any? expectation.returns(args.shift) unless args.empty? @expectations.add(expectation) end expectation end # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them. # # @param [Array] method_names names of methods to unstub. # # @example Invoking an unstubbed method causes error to be raised # object = mock('mock') # object.stubs(:stubbed_method).returns(:result_one) # object.stubbed_method # => :result_one # object.unstub(:stubbed_method) # object.stubbed_method # => unexpected invocation: #.stubbed_method() # # @example Unstubbing multiple methods. # multiplier.unstub(:double, :triple) # # # exactly equivalent to # # multiplier.unstub(:double) # multiplier.unstub(:triple) def unstub(*method_names) method_names.each do |method_name| @expectations.remove_all_matching_method(method_name) end end # Constrains the {Mock} instance so that it can only expect or stub methods to which +responder+ responds publicly. The constraint is only applied at method invocation time. # # A +NoMethodError+ will be raised if the +responder+ does not publicly +#respond_to?+ the invoked method (even if the method has been expected or stubbed). # # The {Mock} instance will delegate its +#respond_to?+ method to the +responder+. However, the +include_all+ parameter is not passed through, so only public methods on the +responder+ will be considered. # # Note that the methods on +responder+ are never actually invoked. # # @param [Object, #respond_to?] responder an object used to determine whether {Mock} instance should +#respond_to?+ to an invocation. # @return [Mock] the same {Mock} instance, thereby allowing invocations of other {Mock} methods to be chained. # @see #responds_like_instance_of # # @example Normal mocking # sheep = mock('sheep') # sheep.expects(:chew) # sheep.expects(:foo) # sheep.respond_to?(:chew) # => true # sheep.respond_to?(:foo) # => true # sheep.chew # sheep.foo # # no error raised # # @example Using {#responds_like} with an instance method # class Sheep # def chew(grass); end # end # # sheep = mock('sheep') # sheep.responds_like(Sheep.new) # sheep.expects(:chew) # sheep.expects(:foo) # sheep.respond_to?(:chew) # => true # sheep.respond_to?(:foo) # => false # sheep.chew # sheep.foo # => raises NoMethodError exception # # @example Using {#responds_like} with a class method # class Sheep # def self.number_of_legs; end # end # # sheep_class = mock('sheep_class') # sheep_class.responds_like(Sheep) # sheep_class.stubs(:number_of_legs).returns(4) # sheep_class.expects(:foo) # sheep_class.respond_to?(:number_of_legs) # => true # sheep_class.respond_to?(:foo) # => false # sheep_class.number_of_legs # => 4 # sheep_class.foo # => raises NoMethodError exception def responds_like(responder) @responder = responder self end # Constrains the {Mock} instance so that it can only expect or stub methods to which an instance of the +responder_class+ responds publicly. The constraint is only applied at method invocation time. Note that the responder instance is instantiated using +Class#allocate+. # # A +NoMethodError+ will be raised if the responder instance does not publicly +#respond_to?+ the invoked method (even if the method has been expected or stubbed). # # The {Mock} instance will delegate its +#respond_to?+ method to the responder instance. However, the +include_all+ parameter is not passed through, so only public methods on the +responder+ will be considered. # # Note that the methods on the responder instance are never actually invoked. # # @param [Class] responder_class a class used to determine whether {Mock} instance should +#respond_to?+ to an invocation. # @return [Mock] the same {Mock} instance, thereby allowing invocations of other {Mock} methods to be chained. # @see #responds_like # # @example Using {#responds_like_instance_of} # class Sheep # def initialize # raise "some awkward code we don't want to call" # end # def chew(grass); end # end # # sheep = mock('sheep') # sheep.responds_like_instance_of(Sheep) # sheep.expects(:chew) # sheep.expects(:foo) # sheep.respond_to?(:chew) # => true # sheep.respond_to?(:foo) # => false # sheep.chew # sheep.foo # => raises NoMethodError exception def responds_like_instance_of(responder_class) responds_like(responder_class.allocate) end # @private def initialize(mockery, name = nil, receiver = nil) @mockery = mockery @name = name || DefaultName.new(self) @receiver = receiver || DefaultReceiver.new(self) @expectations = ExpectationList.new @everything_stubbed = false @responder = nil @unexpected_invocation = nil @expired = false end # @private attr_reader :everything_stubbed alias_method :__expects__, :expects alias_method :__stubs__, :stubs alias_method :__singleton_class__, :singleton_class alias_method :quacks_like, :responds_like alias_method :quacks_like_instance_of, :responds_like_instance_of # @private def __expectations__ @expectations end # @private def stub_everything @everything_stubbed = true end # @private def all_expectations @receiver.mocks.inject(ExpectationList.new) { |e, m| e + m.__expectations__ } end # @private def method_missing(symbol, *arguments, &block) # rubocop:disable Style/MethodMissingSuper handle_method_call(symbol, arguments, block) end ruby2_keywords(:method_missing) # @private def handle_method_call(symbol, arguments, block) check_expiry check_responder_responds_to(symbol) invocation = Invocation.new(self, symbol, arguments, block) if (matching_expectation_allowing_invocation = all_expectations.match_allowing_invocation(invocation)) matching_expectation_allowing_invocation.invoke(invocation) elsif (matching_expectation = all_expectations.match(invocation, ignoring_order: true)) || (!matching_expectation && !@everything_stubbed) raise_unexpected_invocation_error(invocation, matching_expectation) end end # @private def respond_to_missing?(symbol, _include_all) if @responder @responder.respond_to?(symbol) else @everything_stubbed || all_expectations.matches_method?(symbol) end end # @private def __verified__?(assertion_counter = nil) @expectations.verified?(assertion_counter) end # @private def __expire__(origin) @expired = origin || true end # @private def mocha_inspect @name.mocha_inspect end # @private def inspect mocha_inspect end # @private def ensure_method_not_already_defined(method_name) __singleton_class__.send(:undef_method, method_name) if __singleton_class__.method_defined?(method_name) || __singleton_class__.private_method_defined?(method_name) end # @private def any_expectations? @expectations.any? end private def raise_unexpected_invocation_error(invocation, matching_expectation) if @unexpected_invocation.nil? @unexpected_invocation = invocation matching_expectation.invoke(invocation) if matching_expectation call_description = @unexpected_invocation.call_description if matching_expectation && !matching_expectation.in_correct_order? call_description += ' invoked out of order' end message = "#{call_description}\n#{@mockery.mocha_inspect}" else message = @unexpected_invocation.short_call_description end raise ExpectationErrorFactory.build("unexpected invocation: #{message}", caller) end def check_responder_responds_to(symbol) if @responder && !@responder.respond_to?(symbol) # rubocop:disable Style/GuardClause raise NoMethodError, "undefined method `#{symbol}' for #{mocha_inspect} which responds like #{@responder.mocha_inspect}" end end def check_expiry return unless @expired origin = @expired == true ? 'one test' : @expired sentences = [ "#{mocha_inspect} was instantiated in #{origin} but it is receiving invocations within another test.", 'This can lead to unintended interactions between tests and hence unexpected test failures.', 'Ensure that every test correctly cleans up any state that it introduces.' ] raise StubbingError.new(sentences.join(' '), caller) end end end mocha-2.4.2/lib/mocha/mockery.rb000066400000000000000000000115111464615054400164510ustar00rootroot00000000000000require 'mocha/central' require 'mocha/mock' require 'mocha/names' require 'mocha/receivers' require 'mocha/state_machine' require 'mocha/logger' require 'mocha/configuration' require 'mocha/stubbing_error' require 'mocha/not_initialized_error' require 'mocha/expectation_error_factory' module Mocha class Mockery class Null < self def add_mock(*) raise_not_initialized_error end def add_state_machine(*) raise_not_initialized_error end def stubba Central::Null.new(&method(:raise_not_initialized_error)) end private def raise_not_initialized_error message = 'Mocha methods cannot be used outside the context of a test' raise NotInitializedError.new(message, caller) end end class << self def instance @instances.last || Null.new end def setup @instances ||= [] mockery = new mockery.logger = instance.logger unless @instances.empty? @instances.push(mockery) end def verify(*args) instance.verify(*args) end def teardown(origin = nil) instance.teardown(origin) ensure @instances.pop end end def named_mock(name) add_mock(Mock.new(self, Name.new(name))) end def unnamed_mock add_mock(Mock.new(self)) end def mock_impersonating(object) add_mock(Mock.new(self, ImpersonatingName.new(object), ObjectReceiver.new(object))) end def mock_impersonating_any_instance_of(klass) add_mock(Mock.new(self, ImpersonatingAnyInstanceName.new(klass), AnyInstanceReceiver.new(klass))) end def new_state_machine(name) add_state_machine(StateMachine.new(name)) end def verify(assertion_counter = nil) unless mocks.all? { |mock| mock.__verified__?(assertion_counter) } message = "not all expectations were satisfied\n#{mocha_inspect}" backtrace = if unsatisfied_expectations.empty? caller else unsatisfied_expectations[0].backtrace end raise ExpectationErrorFactory.build(message, backtrace) end expectations.reject(&:used?).each do |expectation| signature_proc = lambda { expectation.method_signature } check(:stubbing_method_unnecessarily, 'method unnecessarily', signature_proc, expectation.backtrace) end end def teardown(origin = nil) stubba.unstub_all mocks.each { |m| m.__expire__(origin) } reset end def stubba @stubba ||= Central.new end def mocks @mocks ||= [] end def state_machines @state_machines ||= [] end def sequences @sequences ||= [] end def mocha_inspect message = '' message << "unsatisfied expectations:\n- #{unsatisfied_expectations.map(&:mocha_inspect).join("\n- ")}\n" if unsatisfied_expectations.any? message << "satisfied expectations:\n- #{satisfied_expectations.map(&:mocha_inspect).join("\n- ")}\n" if satisfied_expectations.any? message << "states:\n- #{state_machines.map(&:mocha_inspect).join("\n- ")}\n" if state_machines.any? message end def on_stubbing(object, method) signature_proc = lambda { "#{object.mocha_inspect}.#{method}" } check(:stubbing_non_existent_method, 'non-existent method', signature_proc) do !(object.stubba_class.__method_exists__?(method, true) || object.respond_to?(method)) end check(:stubbing_non_public_method, 'non-public method', signature_proc) do object.stubba_class.__method_exists__?(method, false) end check(:stubbing_method_on_nil, 'method on nil', signature_proc) { object.nil? } check(:stubbing_method_on_non_mock_object, 'method on non-mock object', signature_proc) end attr_writer :logger def logger @logger ||= Logger.new($stderr) end private def check(action, description, signature_proc, backtrace = caller) treatment = Mocha.configuration.send(action) return if (treatment == :allow) || (block_given? && !yield) method_signature = signature_proc.call message = "stubbing #{description}: #{method_signature}" raise StubbingError.new(message, backtrace) if treatment == :prevent logger.warn(message) if treatment == :warn end def expectations mocks.map { |mock| mock.__expectations__.to_a }.flatten end def unsatisfied_expectations expectations.reject(&:verified?) end def satisfied_expectations expectations.select(&:verified?) end def add_mock(mock) mocks << mock mock end def add_state_machine(state_machine) state_machines << state_machine state_machine end def reset @stubba = nil @mocks = nil @state_machines = nil end end end mocha-2.4.2/lib/mocha/names.rb000066400000000000000000000013241464615054400161040ustar00rootroot00000000000000module Mocha class ImpersonatingName def initialize(object) @object = object end def mocha_inspect @object.mocha_inspect end end class ImpersonatingAnyInstanceName def initialize(klass) @klass = klass end def mocha_inspect "#" end end class Name def initialize(name) @name = name.to_s end def mocha_inspect "#" end end class DefaultName def initialize(mock) @mock = mock end def mocha_inspect address = @mock.__id__ * 2 address += 0x100000000 if address < 0 "#x', address: address)}>" end end end mocha-2.4.2/lib/mocha/not_initialized_error.rb000066400000000000000000000003401464615054400213740ustar00rootroot00000000000000require 'mocha/error_with_filtered_backtrace' module Mocha # Exception raised when Mocha has not been initialized, e.g. outside the # context of a test. class NotInitializedError < ErrorWithFilteredBacktrace; end end mocha-2.4.2/lib/mocha/object_methods.rb000066400000000000000000000151271464615054400200000ustar00rootroot00000000000000require 'mocha/mockery' require 'mocha/instance_method' require 'mocha/argument_iterator' require 'mocha/expectation_error_factory' module Mocha # Methods added to all objects to allow mocking and stubbing on real (i.e. non-mock) objects. # # Both {#expects} and {#stubs} return an {Expectation} which can be further modified by methods on {Expectation}. module ObjectMethods # @private alias_method :_method, :method # @private def mocha(instantiate = true) if instantiate @mocha ||= Mocha::Mockery.instance.mock_impersonating(self) else defined?(@mocha) ? @mocha : nil end end # @private def reset_mocha @mocha = nil end # @private def stubba_method Mocha::InstanceMethod end # @private def stubba_object self end # @private def stubba_class singleton_class end # Adds an expectation that the specified method must be called exactly once with any parameters. # # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method. # # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}. # @raise [StubbingError] if attempting to stub method which is not allowed. # # @overload def expects(method_name) # @param [Symbol,String] method_name name of expected method # @overload def expects(expected_methods_vs_return_values) # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times. # # @example Setting up an expectation on a non-mock object. # product = Product.new # product.expects(:save).returns(true) # assert_equal true, product.save # # @example Setting up multiple expectations on a non-mock object. # product = Product.new # product.expects(valid?: true, save: true) # # # exactly equivalent to # # product = Product.new # product.expects(:valid?).returns(true) # product.expects(:save).returns(true) # # @see Mock#expects def expects(expected_methods_vs_return_values) if expected_methods_vs_return_values.to_s =~ /the[^a-z]*spanish[^a-z]*inquisition/i raise ExpectationErrorFactory.build('NOBODY EXPECTS THE SPANISH INQUISITION!') end if frozen? raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller) end expectation = nil mockery = Mocha::Mockery.instance iterator = ArgumentIterator.new(expected_methods_vs_return_values) iterator.each do |*args| method_name = args.shift mockery.on_stubbing(self, method_name) method = stubba_method.new(stubba_object, method_name) mockery.stubba.stub(method) expectation = mocha.expects(method_name, caller) expectation.returns(args.shift) unless args.empty? end expectation end # Adds an expectation that the specified method may be called any number of times with any parameters. # # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method. # # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}. # @raise [StubbingError] if attempting to stub method which is not allowed. # # @overload def stubs(method_name) # @param [Symbol,String] method_name name of stubbed method # @overload def stubs(stubbed_methods_vs_return_values) # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times. # # @example Setting up a stubbed methods on a non-mock object. # product = Product.new # product.stubs(:save).returns(true) # assert_equal true, product.save # # @example Setting up multiple stubbed methods on a non-mock object. # product = Product.new # product.stubs(valid?: true, save: true) # # # exactly equivalent to # # product = Product.new # product.stubs(:valid?).returns(true) # product.stubs(:save).returns(true) # # @see Mock#stubs def stubs(stubbed_methods_vs_return_values) if frozen? raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller) end expectation = nil mockery = Mocha::Mockery.instance iterator = ArgumentIterator.new(stubbed_methods_vs_return_values) iterator.each do |*args| method_name = args.shift mockery.on_stubbing(self, method_name) method = stubba_method.new(stubba_object, method_name) mockery.stubba.stub(method) expectation = mocha.stubs(method_name, caller) expectation.returns(args.shift) unless args.empty? end expectation end # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them. # # Restores the original behaviour of the methods before they were stubbed. This is normally done automatically at the end of each test, but in some circumstances you may want to do it *before* the end of the test. # # WARNING: If you {#unstub} a method which still has unsatisfied expectations, you may be removing the only way those expectations can be satisfied. Use {#unstub} with care. # # @param [Array] method_names names of methods to unstub. # # @example Stubbing and unstubbing a method on a real (non-mock) object. # multiplier = Multiplier.new # multiplier.double(2) # => 4 # multiplier.stubs(:double).raises # new behaviour defined # multiplier.double(2) # => raises exception # multiplier.unstub(:double) # original behaviour restored # multiplier.double(2) # => 4 # # @example Unstubbing multiple methods on a real (non-mock) object. # multiplier.unstub(:double, :triple) # # # exactly equivalent to # # multiplier.unstub(:double) # multiplier.unstub(:triple) def unstub(*method_names) mockery = Mocha::Mockery.instance method_names.each do |method_name| method = stubba_method.new(stubba_object, method_name) mockery.stubba.unstub(method) end end end end mocha-2.4.2/lib/mocha/parameter_matchers.rb000066400000000000000000000021561464615054400206530ustar00rootroot00000000000000module Mocha # Used as parameters for {Expectation#with} to restrict the parameter values which will match the expectation. Can be nested. module ParameterMatchers; end end require 'mocha/parameter_matchers/instance_methods' require 'mocha/parameter_matchers/all_of' require 'mocha/parameter_matchers/any_of' require 'mocha/parameter_matchers/any_parameters' require 'mocha/parameter_matchers/anything' require 'mocha/parameter_matchers/equals' require 'mocha/parameter_matchers/has_entry' require 'mocha/parameter_matchers/has_entries' require 'mocha/parameter_matchers/has_key' require 'mocha/parameter_matchers/has_keys' require 'mocha/parameter_matchers/has_value' require 'mocha/parameter_matchers/includes' require 'mocha/parameter_matchers/instance_of' require 'mocha/parameter_matchers/is_a' require 'mocha/parameter_matchers/kind_of' require 'mocha/parameter_matchers/not' require 'mocha/parameter_matchers/optionally' require 'mocha/parameter_matchers/regexp_matches' require 'mocha/parameter_matchers/responds_with' require 'mocha/parameter_matchers/yaml_equivalent' require 'mocha/parameter_matchers/equivalent_uri' mocha-2.4.2/lib/mocha/parameter_matchers/000077500000000000000000000000001464615054400203225ustar00rootroot00000000000000mocha-2.4.2/lib/mocha/parameter_matchers/all_of.rb000066400000000000000000000024651464615054400221120ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches if all +matchers+ match. # # @param [*Array] matchers parameter matchers. # @return [AllOf] parameter matcher. # # @see Expectation#with # # @example All parameter matchers match. # object = mock() # object.expects(:method_1).with(all_of(includes(1), includes(3))) # object.method_1([1, 3]) # # no error raised # # @example One of the parameter matchers does not match. # object = mock() # object.expects(:method_1).with(all_of(includes(1), includes(3))) # object.method_1([1, 2]) # # error raised, because method_1 was not called with object including 1 and 3 def all_of(*matchers) AllOf.new(*matchers) end # Parameter matcher which combines a number of other matchers using a logical AND. class AllOf < Base # @private def initialize(*matchers) @matchers = matchers end # @private def matches?(available_parameters) parameter = available_parameters.shift @matchers.all? { |matcher| matcher.to_matcher.matches?([parameter]) } end # @private def mocha_inspect "all_of(#{@matchers.map(&:mocha_inspect).join(', ')})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/any_of.rb000066400000000000000000000026421464615054400221260ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches if any +matchers+ match. # # @param [*Array] matchers parameter matchers. # @return [AnyOf] parameter matcher. # # @see Expectation#with # # @example One parameter matcher matches. # object = mock() # object.expects(:method_1).with(any_of(1, 3)) # object.method_1(1) # # no error raised # # @example The other parameter matcher matches. # object = mock() # object.expects(:method_1).with(any_of(1, 3)) # object.method_1(3) # # no error raised # # @example Neither parameter matcher matches. # object = mock() # object.expects(:method_1).with(any_of(1, 3)) # object.method_1(2) # # error raised, because method_1 was not called with 1 or 3 def any_of(*matchers) AnyOf.new(*matchers) end # Parameter matcher which combines a number of other matchers using a logical OR. class AnyOf < Base # @private def initialize(*matchers) @matchers = matchers end # @private def matches?(available_parameters) parameter = available_parameters.shift @matchers.any? { |matcher| matcher.to_matcher.matches?([parameter]) } end # @private def mocha_inspect "any_of(#{@matchers.map(&:mocha_inspect).join(', ')})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/any_parameters.rb000066400000000000000000000020011464615054400236520ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any parameters. This is used as the default for a newly built expectation. # # @return [AnyParameters] parameter matcher. # # @see Expectation#with # # @example Any parameters will match. # object = mock() # object.expects(:method_1).with(any_parameters) # object.method_1(1, 2, 3, 4) # # no error raised # # object = mock() # object.expects(:method_1).with(any_parameters) # object.method_1(5, 6, 7, 8, 9, 0) # # no error raised def any_parameters AnyParameters.new end # Parameter matcher which always matches whatever the parameters. class AnyParameters < Base # @private def matches?(available_parameters) until available_parameters.empty? available_parameters.shift end true end # @private def mocha_inspect 'any_parameters' end end end end mocha-2.4.2/lib/mocha/parameter_matchers/anything.rb000066400000000000000000000013751464615054400224760ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any object. # # @return [Anything] parameter matcher. # # @see Expectation#with # # @example Any object will match. # object = mock() # object.expects(:method_1).with(anything) # object.method_1('foo') # object.method_1(789) # object.method_1(:bar) # # no error raised def anything Anything.new end # Parameter matcher which always matches a single parameter. class Anything < Base # @private def matches?(available_parameters) available_parameters.shift true end # @private def mocha_inspect 'anything' end end end end mocha-2.4.2/lib/mocha/parameter_matchers/base.rb000066400000000000000000000044311464615054400215630ustar00rootroot00000000000000module Mocha module ParameterMatchers # @abstract Subclass and implement +#matches?+ and +#mocha_inspect+ to define a custom matcher. Also add a suitably named instance method to {ParameterMatchers} to build an instance of the new matcher c.f. {#equals}. class Base # A shorthand way of combining two matchers when both must match. # # Returns a new {AllOf} parameter matcher combining two matchers using a logical AND. # # This shorthand will not work with an implicit equals match. Instead, an explicit {Equals} matcher should be used. # # @param [Base] other parameter matcher. # @return [AllOf] parameter matcher. # # @see Expectation#with # # @example Alternative ways to combine matchers with a logical AND. # object = mock() # object.expects(:run).with(all_of(has_key(:foo), has_key(:bar))) # object.run(foo: 'foovalue', bar: 'barvalue') # # # is exactly equivalent to # # object.expects(:run).with(has_key(:foo) & has_key(:bar)) # object.run(foo: 'foovalue', bar: 'barvalue) def &(other) AllOf.new(self, other) end # A shorthand way of combining two matchers when at least one must match. # # Returns a new +AnyOf+ parameter matcher combining two matchers using a logical OR. # # This shorthand will not work with an implicit equals match. Instead, an explicit {Equals} matcher should be used. # # @param [Base] other parameter matcher. # @return [AnyOf] parameter matcher. # # @see Expectation#with # # @example Alternative ways to combine matchers with a logical OR. # object = mock() # object.expects(:run).with(any_of(has_key(:foo), has_key(:bar))) # object.run(foo: 'foovalue') # # # is exactly equivalent to # # object.expects(:run).with(has_key(:foo) | has_key(:bar)) # object.run(foo: 'foovalue') # # @example Using an explicit {Equals} matcher in combination with {#|}. # object.expects(:run).with(equals(1) | equals(2)) # object.run(1) # passes # object.run(2) # passes # object.run(3) # fails def |(other) AnyOf.new(self, other) end end end end mocha-2.4.2/lib/mocha/parameter_matchers/equals.rb000066400000000000000000000022721464615054400221440ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any +Object+ equalling +value+. # # @param [Object] value expected value. # @return [Equals] parameter matcher. # # @see Expectation#with # @see Object#== # # @example Actual parameter equals expected parameter. # object = mock() # object.expects(:method_1).with(equals(2)) # object.method_1(2) # # no error raised # # @example Actual parameter does not equal expected parameter. # object = mock() # object.expects(:method_1).with(equals(2)) # object.method_1(3) # # error raised, because method_1 was not called with an +Object+ that equals 2 def equals(value) Equals.new(value) end # Parameter matcher which matches when actual parameter equals expected value. class Equals < Base # @private def initialize(value) @value = value end # @private def matches?(available_parameters) parameter = available_parameters.shift parameter == @value end # @private def mocha_inspect @value.mocha_inspect end end end end mocha-2.4.2/lib/mocha/parameter_matchers/equivalent_uri.rb000066400000000000000000000031541464615054400237060ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' require 'uri' require 'cgi' module Mocha module ParameterMatchers # Matches a URI without regard to the ordering of parameters in the query string. # # @param [String] uri URI to match. # @return [EquivalentUri] parameter matcher. # # @see Expectation#with # # @example Actual URI is equivalent. # object = mock() # object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2)) # object.method_1('http://example.com/foo?b=2&a=1') # # no error raised # # @example Actual URI is not equivalent. # object = mock() # object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2)) # object.method_1('http://example.com/foo?a=1&b=3') # # error raised, because the query parameters were different def equivalent_uri(uri) EquivalentUri.new(uri) end # Parameter matcher which matches URIs with equivalent query strings. class EquivalentUri < Base # @private def initialize(uri) @uri = URI.parse(uri) end # @private def matches?(available_parameters) actual = explode(URI.parse(available_parameters.shift)) expected = explode(@uri) actual == expected end # @private def mocha_inspect "equivalent_uri(#{@uri.mocha_inspect})" end private # @private def explode(uri) query_hash = CGI.parse(uri.query || '') URI::Generic::COMPONENT.inject({}) { |h, k| h.merge(k => uri.__send__(k)) }.merge(query: query_hash) end end end end mocha-2.4.2/lib/mocha/parameter_matchers/has_entries.rb000066400000000000000000000032051464615054400231530ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' require 'mocha/parameter_matchers/all_of' require 'mocha/parameter_matchers/has_entry' module Mocha module ParameterMatchers # Matches +Hash+ containing all +entries+. # # @param [Hash] entries expected +Hash+ entries. # @return [HasEntries] parameter matcher. # # @see Expectation#with # # @example Actual parameter contains all expected entries. # object = mock() # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2)) # object.method_1('key_1' => 1, 'key_2' => 2, 'key_3' => 3) # # no error raised # # @example Actual parameter does not contain all expected entries. # object = mock() # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2)) # object.method_1('key_1' => 1, 'key_2' => 99) # # error raised, because method_1 was not called with Hash containing entries: 'key_1' => 1, 'key_2' => 2 # def has_entries(entries) # rubocop:disable Naming/PredicateName HasEntries.new(entries) end # Parameter matcher which matches when actual parameter contains all expected +Hash+ entries. class HasEntries < Base # @private def initialize(entries) @entries = entries end # @private def matches?(available_parameters) parameter = available_parameters.shift has_entry_matchers = @entries.map { |key, value| HasEntry.new(key, value) } AllOf.new(*has_entry_matchers).matches?([parameter]) end # @private def mocha_inspect "has_entries(#{@entries.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/has_entry.rb000066400000000000000000000065241464615054400226520ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches +Hash+ containing entry with +key+ and +value+. # # @overload def has_entry(key, value) # @param [Object] key key for entry. # @param [Object] value value for entry. # @overload def has_entry(single_entry_hash) # @param [Hash] single_entry_hash +Hash+ with single entry. # @raise [ArgumentError] if +single_entry_hash+ does not contain exactly one entry. # # @return [HasEntry] parameter matcher. # # @see Expectation#with # # @example Actual parameter contains expected entry supplied as key and value. # object = mock() # object.expects(:method_1).with(has_entry('key_1', 1)) # object.method_1('key_1' => 1, 'key_2' => 2) # # no error raised # # @example Actual parameter contains expected entry supplied as +Hash+ entry. # object = mock() # object.expects(:method_1).with(has_entry('key_1' => 1)) # object.method_1('key_1' => 1, 'key_2' => 2) # # no error raised # # @example Actual parameter does not contain expected entry supplied as key and value. # object = mock() # object.expects(:method_1).with(has_entry('key_1', 1)) # object.method_1('key_1' => 2, 'key_2' => 1) # # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1 # # @example Actual parameter does not contain expected entry supplied as +Hash+ entry. # # object = mock() # object.expects(:method_1).with(has_entry('key_1' => 1)) # object.method_1('key_1' => 2, 'key_2' => 1) # # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1 # def has_entry(*options) # rubocop:disable Naming/PredicateName case options.length when 0 raise ArgumentError, 'No arguments. Expecting at least one.' when 1 key, value = parse_option(options[0]) when 2 key, value = options else raise ArgumentError, 'Too many arguments; use either a single argument (must be a Hash) or two arguments (a key and a value).' end HasEntry.new(key, value) end # Parameter matcher which matches when actual parameter contains expected +Hash+ entry. class HasEntry < Base # @private def initialize(key, value) @key = key @value = value end # @private def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:keys) && parameter.respond_to?(:[]) matching_keys = parameter.keys.select { |key| @key.to_matcher.matches?([key]) } matching_keys.any? { |key| @value.to_matcher.matches?([parameter[key]]) } end # @private def mocha_inspect "has_entry(#{@key.mocha_inspect} => #{@value.mocha_inspect})" end end private # @private def parse_option(option) case option when Hash case option.length when 0 raise ArgumentError, 'Argument has no entries.' when 1 option.first else raise ArgumentError, 'Argument has multiple entries. Use Mocha::ParameterMatchers#has_entries instead.' end else raise ArgumentError, 'Argument is not a Hash.' end end end end mocha-2.4.2/lib/mocha/parameter_matchers/has_key.rb000066400000000000000000000026021464615054400222720ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches +Hash+ containing +key+. # # @param [Object] key expected key. # @return [HasKey] parameter matcher. # # @see Expectation#with # # @example Actual parameter contains entry with expected key. # object = mock() # object.expects(:method_1).with(has_key('key_1')) # object.method_1('key_1' => 1, 'key_2' => 2) # # no error raised # # @example Actual parameter does not contain entry with expected key. # object = mock() # object.expects(:method_1).with(has_key('key_1')) # object.method_1('key_2' => 2) # # error raised, because method_1 was not called with Hash containing key: 'key_1' # def has_key(key) # rubocop:disable Naming/PredicateName HasKey.new(key) end # Parameter matcher which matches when actual parameter contains +Hash+ entry with expected key. class HasKey < Base # @private def initialize(key) @key = key end # @private def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:keys) parameter.keys.any? { |key| @key.to_matcher.matches?([key]) } end # @private def mocha_inspect "has_key(#{@key.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/has_keys.rb000066400000000000000000000031031464615054400224520ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches +Hash+ containing +keys+. # # @param [*Array] keys expected keys. # @return [HasKeys] parameter matcher. # # @see Expectation#with # # @example Actual parameter contains entry with expected keys. # object = mock() # object.expects(:method_1).with(has_keys(:key_1, :key_2)) # object.method_1(:key_1 => 1, :key_2 => 2, :key_3 => 3) # # no error raised # # @example Actual parameter does not contain all expected keys. # object = mock() # object.expects(:method_1).with(has_keys(:key_1, :key_2)) # object.method_1(:key_2 => 2) # # error raised, because method_1 was not called with Hash containing key: :key_1 # def has_keys(*keys) # rubocop:disable Naming/PredicateName HasKeys.new(*keys) end # Parameter matcher which matches when actual parameter contains +Hash+ with all expected keys. class HasKeys < Base # @private def initialize(*keys) raise ArgumentError, 'No arguments. Expecting at least one.' if keys.empty? @keys = keys end # @private def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:keys) @keys.map(&:to_matcher).all? do |matcher| parameter.keys.any? { |key| matcher.matches?([key]) } end end # @private def mocha_inspect "has_keys(#{@keys.mocha_inspect(false)})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/has_value.rb000066400000000000000000000026421464615054400226220ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches +Hash+ containing +value+. # # @param [Object] value expected value. # @return [HasValue] parameter matcher. # # @see Expectation#with # # @example Actual parameter contains entry with expected value. # object = mock() # object.expects(:method_1).with(has_value(1)) # object.method_1('key_1' => 1, 'key_2' => 2) # # no error raised # # @example Actual parameter does not contain entry with expected value. # object = mock() # object.expects(:method_1).with(has_value(1)) # object.method_1('key_2' => 2) # # error raised, because method_1 was not called with Hash containing value: 1 # def has_value(value) # rubocop:disable Naming/PredicateName HasValue.new(value) end # Parameter matcher which matches when actual parameter contains +Hash+ entry with expected value. class HasValue < Base # @private def initialize(value) @value = value end # @private def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:values) parameter.values.any? { |value| @value.to_matcher.matches?([value]) } end # @private def mocha_inspect "has_value(#{@value.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/includes.rb000066400000000000000000000072361464615054400224650ustar00rootroot00000000000000require 'mocha/parameter_matchers/all_of' require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any object that responds with +true+ to +include?(item)+ # for all items. # # @param [*Array] items expected items. # @return [Includes] parameter matcher. # # @see Expectation#with # # @example Actual parameter includes all items. # object = mock() # object.expects(:method_1).with(includes('foo', 'bar')) # object.method_1(['foo', 'bar', 'baz']) # # no error raised # # @example Actual parameter does not include all items. # object.method_1(['foo', 'baz']) # # error raised, because ['foo', 'baz'] does not include 'bar'. # # @example Actual parameter includes item which matches nested matcher. # object = mock() # object.expects(:method_1).with(includes(has_key(:key))) # object.method_1(['foo', 'bar', {key: 'baz'}]) # # no error raised # # @example Actual parameter does not include item matching nested matcher. # object.method_1(['foo', 'bar', {:other_key => 'baz'}]) # # error raised, because no element matches `has_key(:key)` matcher # # @example Actual parameter is a String including substring. # object = mock() # object.expects(:method_1).with(includes('bar')) # object.method_1('foobarbaz') # # no error raised # # @example Actual parameter is a String not including substring. # object.method_1('foobaz') # # error raised, because 'foobaz' does not include 'bar' # # @example Actual parameter is a Hash including the given key. # object = mock() # object.expects(:method_1).with(includes(:bar)) # object.method_1({foo: 1, bar: 2}) # # no error raised # # @example Actual parameter is a Hash without the given key. # object.method_1({foo: 1, baz: 2}) # # error raised, because hash does not include key 'bar' # # @example Actual parameter is a Hash with a key matching the given matcher. # object = mock() # object.expects(:method_1).with(includes(regexp_matches(/ar/))) # object.method_1({'foo' => 1, 'bar' => 2}) # # no error raised # # @example Actual parameter is a Hash no key matching the given matcher. # object.method_1({'foo' => 1, 'baz' => 3}) # # error raised, because hash does not include a key matching /ar/ def includes(*items) Includes.new(*items) end # Parameter matcher which matches when actual parameter includes expected values. class Includes < Base # @private def initialize(*items) @items = items end # @private # rubocop:disable Metrics/PerceivedComplexity def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:include?) if @items.size == 1 # rubocop:disable Style/GuardClause if parameter.respond_to?(:any?) && !parameter.is_a?(String) parameter = parameter.keys if parameter.is_a?(Hash) return parameter.any? { |p| @items.first.to_matcher.matches?([p]) } else return parameter.include?(@items.first) end # rubocop:enable Style/GuardClause else includes_matchers = @items.map { |item| Includes.new(item) } AllOf.new(*includes_matchers).matches?([parameter]) end end # rubocop:enable Metrics/PerceivedComplexity # @private def mocha_inspect item_descriptions = @items.map(&:mocha_inspect) "includes(#{item_descriptions.join(', ')})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/instance_methods.rb000066400000000000000000000012141464615054400241740ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' require 'mocha/parameter_matchers/equals' require 'mocha/parameter_matchers/positional_or_keyword_hash' module Mocha module ParameterMatchers # @private module InstanceMethods # @private def to_matcher(expectation: nil, top_level: false) if Base === self self elsif Hash === self && top_level Mocha::ParameterMatchers::PositionalOrKeywordHash.new(self, expectation) else Mocha::ParameterMatchers::Equals.new(self) end end end end end # @private class Object include Mocha::ParameterMatchers::InstanceMethods end mocha-2.4.2/lib/mocha/parameter_matchers/instance_of.rb000066400000000000000000000024411464615054400231400ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any object that is an instance of +klass+ # # @param [Class] klass expected class. # @return [InstanceOf] parameter matcher. # # @see Expectation#with # @see Kernel#instance_of? # # @example Actual parameter is an instance of +String+. # object = mock() # object.expects(:method_1).with(instance_of(String)) # object.method_1('string') # # no error raised # # @example Actual parameter is not an instance of +String+. # object = mock() # object.expects(:method_1).with(instance_of(String)) # object.method_1(99) # # error raised, because method_1 was not called with an instance of String def instance_of(klass) InstanceOf.new(klass) end # Parameter matcher which matches when actual parameter is an instance of the specified class. class InstanceOf < Base # @private def initialize(klass) @klass = klass end # @private def matches?(available_parameters) parameter = available_parameters.shift parameter.instance_of?(@klass) end # @private def mocha_inspect "instance_of(#{@klass.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/is_a.rb000066400000000000000000000023201464615054400215570ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any object that is a +klass+. # # @param [Class] klass expected class. # @return [IsA] parameter matcher. # # @see Expectation#with # @see Kernel#is_a? # # @example Actual parameter is a +Integer+. # object = mock() # object.expects(:method_1).with(is_a(Integer)) # object.method_1(99) # # no error raised # # @example Actual parameter is not a +Integer+. # object = mock() # object.expects(:method_1).with(is_a(Integer)) # object.method_1('string') # # error raised, because method_1 was not called with an Integer # def is_a(klass) # rubocop:disable Naming/PredicateName IsA.new(klass) end # Parameter matcher which matches when actual parameter is a specific class. class IsA < Base # @private def initialize(klass) @klass = klass end # @private def matches?(available_parameters) parameter = available_parameters.shift parameter.is_a?(@klass) end # @private def mocha_inspect "is_a(#{@klass.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/kind_of.rb000066400000000000000000000024751464615054400222700ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any +Object+ that is a kind of +klass+. # # @param [Class] klass expected class. # @return [KindOf] parameter matcher. # # @see Expectation#with # @see Kernel#kind_of? # # @example Actual parameter is a kind of +Integer+. # object = mock() # object.expects(:method_1).with(kind_of(Integer)) # object.method_1(99) # # no error raised # # @example Actual parameter is not a kind of +Integer+. # object = mock() # object.expects(:method_1).with(kind_of(Integer)) # object.method_1('string') # # error raised, because method_1 was not called with a kind of Integer def kind_of(klass) KindOf.new(klass) end # Parameter matcher which matches when actual parameter is a kind of specified class. class KindOf < Base # @private def initialize(klass) @klass = klass end # @private def matches?(available_parameters) parameter = available_parameters.shift # rubocop:disable Style/ClassCheck parameter.kind_of?(@klass) # rubocop:enable Style/ClassCheck end # @private def mocha_inspect "kind_of(#{@klass.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/not.rb000066400000000000000000000024441464615054400214530ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches if +matcher+ does *not* match. # # @param [Base] matcher matcher whose logic to invert. # @return [Not] parameter matcher. # # @see Expectation#with # # @example Actual parameter does not include the value +1+. # object = mock() # object.expects(:method_1).with(Not(includes(1))) # object.method_1([0, 2, 3]) # # no error raised # # @example Actual parameter does include the value +1+. # object = mock() # object.expects(:method_1).with(Not(includes(1))) # object.method_1([0, 1, 2, 3]) # # error raised, because method_1 was not called with object not including 1 # def Not(matcher) # rubocop:disable Naming/MethodName Not.new(matcher) end # Parameter matcher which inverts the logic of the specified matcher using a logical NOT operation. class Not < Base # @private def initialize(matcher) @matcher = matcher end # @private def matches?(available_parameters) parameter = available_parameters.shift !@matcher.matches?([parameter]) end # @private def mocha_inspect "Not(#{@matcher.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/optionally.rb000066400000000000000000000040361464615054400230440ustar00rootroot00000000000000module Mocha module ParameterMatchers # Matches optional parameters if available. # # @param [*Array] matchers matchers for optional parameters. # @return [Optionally] parameter matcher. # # @see Expectation#with # # @example Only the two required parameters are supplied and they both match their expected value. # object = mock() # object.expects(:method_1).with(1, 2, optionally(3, 4)) # object.method_1(1, 2) # # no error raised # # @example Both required parameters and one of the optional parameters are supplied and they all match their expected value. # object = mock() # object.expects(:method_1).with(1, 2, optionally(3, 4)) # object.method_1(1, 2, 3) # # no error raised # # @example Both required parameters and both of the optional parameters are supplied and they all match their expected value. # object = mock() # object.expects(:method_1).with(1, 2, optionally(3, 4)) # object.method_1(1, 2, 3, 4) # # no error raised # # @example One of the actual optional parameters does not match the expected value. # object = mock() # object.expects(:method_1).with(1, 2, optionally(3, 4)) # object.method_1(1, 2, 3, 5) # # error raised, because optional parameters did not match def optionally(*matchers) Optionally.new(*matchers) end # Parameter matcher which allows optional parameters to be specified. class Optionally < Base # @private def initialize(*parameters) @matchers = parameters.map(&:to_matcher) end # @private def matches?(available_parameters) index = 0 while !available_parameters.empty? && (index < @matchers.length) matcher = @matchers[index] return false unless matcher.matches?(available_parameters) index += 1 end true end # @private def mocha_inspect "optionally(#{@matchers.map(&:mocha_inspect).join(', ')})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb000066400000000000000000000037641464615054400263110ustar00rootroot00000000000000require 'mocha/configuration' require 'mocha/deprecation' require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # @private class PositionalOrKeywordHash < Base def initialize(value, expectation) @value = value @expectation = expectation end def matches?(available_parameters) parameter, is_last_parameter = extract_parameter(available_parameters) return false unless HasEntries.new(@value).matches?([parameter]) if is_last_parameter && !same_type_of_hash?(parameter, @value) return false if Mocha.configuration.strict_keyword_argument_matching? deprecation_warning(parameter, @value) if Mocha::RUBY_V27_PLUS end true end def mocha_inspect @value.mocha_inspect end private def extract_parameter(available_parameters) [available_parameters.shift, available_parameters.empty?] end def same_type_of_hash?(actual, expected) ruby2_keywords_hash?(actual) == ruby2_keywords_hash?(expected) end def deprecation_warning(actual, expected) details1 = "Expectation #{expectation_definition} expected #{hash_type(expected)} (#{expected.mocha_inspect}),".squeeze(' ') details2 = "but received #{hash_type(actual)} (#{actual.mocha_inspect})." sentence1 = 'These will stop matching when strict keyword argument matching is enabled.' sentence2 = 'See the documentation for Mocha::Configuration#strict_keyword_argument_matching=.' Deprecation.warning([details1, details2, sentence1, sentence2].join(' ')) end def hash_type(hash) ruby2_keywords_hash?(hash) ? 'keyword arguments' : 'positional hash' end def ruby2_keywords_hash?(hash) hash.is_a?(Hash) && ::Hash.ruby2_keywords_hash?(hash) end def expectation_definition return nil unless @expectation "defined at #{@expectation.definition_location}" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/regexp_matches.rb000066400000000000000000000026171464615054400236530ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' module Mocha module ParameterMatchers # Matches any object that matches +regexp+. # # @param [Regexp] regexp regular expression to match. # @return [RegexpMatches] parameter matcher. # # @see Expectation#with # # @example Actual parameter is matched by specified regular expression. # object = mock() # object.expects(:method_1).with(regexp_matches(/e/)) # object.method_1('hello') # # no error raised # # @example Actual parameter is not matched by specified regular expression. # object = mock() # object.expects(:method_1).with(regexp_matches(/a/)) # object.method_1('hello') # # error raised, because method_1 was not called with a parameter that matched the # # regular expression def regexp_matches(regexp) RegexpMatches.new(regexp) end # Parameter matcher which matches if specified regular expression matches actual paramter. class RegexpMatches < Base # @private def initialize(regexp) @regexp = regexp end # @private def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:=~) parameter =~ @regexp end # @private def mocha_inspect "regexp_matches(#{@regexp.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/responds_with.rb000066400000000000000000000060011464615054400235340ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' require 'mocha/parameter_matchers/all_of' require 'yaml' module Mocha module ParameterMatchers # @overload def responds_with(message, result) # Matches any object that responds to +message+ with +result+. To put it another way, it tests the quack, not the duck. # @param [Symbol] message method to invoke. # @param [Object] result expected result of sending +message+. # @overload def responds_with(messages_vs_results) # Matches any object that responds to all the messages with the corresponding results as specified by +messages_vs_results+. # @param [Hash] messages_vs_results +Hash+ of messages vs results. # @raise [ArgumentError] if +messages_vs_results+ does not contain at least one entry. # # @return [RespondsWith] parameter matcher. # # @see Expectation#with # # @example Actual parameter responds with "FOO" when :upcase is invoked. # object = mock() # object.expects(:method_1).with(responds_with(:upcase, "FOO")) # object.method_1("foo") # # no error raised, because "foo".upcase == "FOO" # # @example Actual parameter does not respond with "FOO" when :upcase is invoked. # object = mock() # object.expects(:method_1).with(responds_with(:upcase, "BAR")) # object.method_1("foo") # # error raised, because "foo".upcase != "BAR" # # @example Actual parameter responds with "FOO" when :upcase is invoked and "oof" when :reverse is invoked. # object = mock() # object.expects(:method_1).with(responds_with(upcase: "FOO", reverse: "oof")) # object.method_1("foo") # # no error raised, because "foo".upcase == "FOO" and "foo".reverse == "oof" def responds_with(*options) case options.length when 0 raise ArgumentError, 'No arguments. Expecting at least one.' when 1 option = options.first raise ArgumentError, 'Argument is not a Hash.' unless option.is_a?(Hash) raise ArgumentError, 'Argument has no entries.' if option.empty? matchers = option.map { |message, result| RespondsWith.new(message, result) } AllOf.new(*matchers) when 2 message, result = options RespondsWith.new(message, result) else raise ArgumentError, 'Too many arguments; use either a single argument (must be a Hash) or two arguments (a message and a result).' end end # Parameter matcher which matches if actual parameter returns expected result when specified method is invoked. class RespondsWith < Base # @private def initialize(message, result) @message = message @result = result end # @private def matches?(available_parameters) parameter = available_parameters.shift @result.to_matcher.matches?([parameter.__send__(@message)]) end # @private def mocha_inspect "responds_with(#{@message.mocha_inspect}, #{@result.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameter_matchers/yaml_equivalent.rb000066400000000000000000000027551464615054400240570ustar00rootroot00000000000000require 'mocha/parameter_matchers/base' require 'yaml' module Mocha module ParameterMatchers # Matches any YAML that represents the specified +object+ # # @param [Object] object object whose YAML to compare. # @return [YamlEquivalent] parameter matcher. # # @see Expectation#with # # @example Actual parameter is YAML equivalent of specified +object+. # object = mock() # object.expects(:method_1).with(yaml_equivalent(1, 2, 3)) # object.method_1("--- \n- 1\n- 2\n- 3\n") # # no error raised # # @example Actual parameter is not YAML equivalent of specified +object+. # object = mock() # object.expects(:method_1).with(yaml_equivalent(1, 2, 3)) # object.method_1("--- \n- 1\n- 2\n") # # error raised, because method_1 was not called with YAML representing the specified Array def yaml_equivalent(object) YamlEquivalent.new(object) end # Parameter matcher which matches if actual parameter is YAML equivalent of specified object. class YamlEquivalent < Base # @private def initialize(object) @object = object end # @private def matches?(available_parameters) parameter = available_parameters.shift # rubocop:disable Security/YAMLLoad @object == YAML.load(parameter) # rubocop:enable Security/YAMLLoad end # @private def mocha_inspect "yaml_equivalent(#{@object.mocha_inspect})" end end end end mocha-2.4.2/lib/mocha/parameters_matcher.rb000066400000000000000000000017001464615054400206450ustar00rootroot00000000000000require 'mocha/inspect' require 'mocha/parameter_matchers' module Mocha class ParametersMatcher def initialize(expected_parameters = [ParameterMatchers::AnyParameters.new], expectation = nil, &matching_block) @expected_parameters = expected_parameters @expectation = expectation @matching_block = matching_block end def match?(actual_parameters = []) if @matching_block @matching_block.call(*actual_parameters) else parameters_match?(actual_parameters) end end def parameters_match?(actual_parameters) matchers.all? { |matcher| matcher.matches?(actual_parameters) } && actual_parameters.empty? end def mocha_inspect signature = matchers.mocha_inspect signature = signature.gsub(/^\[|\]$/, '') "(#{signature})" end def matchers @expected_parameters.map { |p| p.to_matcher(expectation: @expectation, top_level: true) } end end end mocha-2.4.2/lib/mocha/raised_exception.rb000066400000000000000000000002561464615054400203310ustar00rootroot00000000000000module Mocha class RaisedException def initialize(exception) @exception = exception end def mocha_inspect "raised #{@exception}" end end end mocha-2.4.2/lib/mocha/receivers.rb000066400000000000000000000013731464615054400167740ustar00rootroot00000000000000module Mocha class ObjectReceiver def initialize(object) @object = object end def mocks object = @object mocks = [] while object mocha = object.mocha(false) mocks << mocha if mocha object = object.is_a?(Class) ? object.superclass : nil end mocks end end class AnyInstanceReceiver def initialize(klass) @klass = klass end def mocks klass = @klass mocks = [] while klass mocha = klass.any_instance.mocha(false) mocks << mocha if mocha klass = klass.superclass end mocks end end class DefaultReceiver def initialize(mock) @mock = mock end def mocks [@mock] end end end mocha-2.4.2/lib/mocha/return_values.rb000066400000000000000000000010251464615054400176750ustar00rootroot00000000000000require 'mocha/single_return_value' module Mocha class ReturnValues def self.build(*values) new(*values.map { |value| SingleReturnValue.new(value) }) end attr_accessor :values def initialize(*values) @values = values end def next(invocation) case @values.length when 0 then nil when 1 then @values.first.evaluate(invocation) else @values.shift.evaluate(invocation) end end def +(other) self.class.new(*(@values + other.values)) end end end mocha-2.4.2/lib/mocha/ruby_version.rb000066400000000000000000000001411464615054400175230ustar00rootroot00000000000000module Mocha RUBY_V27_PLUS = Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.7') end mocha-2.4.2/lib/mocha/sequence.rb000066400000000000000000000017651464615054400166220ustar00rootroot00000000000000module Mocha # Used to constrain the order in which expectations can occur. # # @see API#sequence # @see Expectation#in_sequence class Sequence # @private class InSequenceOrderingConstraint def initialize(sequence, index) @sequence = sequence @index = index end def allows_invocation_now? @sequence.satisfied_to_index?(@index) end def mocha_inspect "in sequence #{@sequence.mocha_inspect}" end end # @private def initialize(name) @name = name @expectations = [] end # @private def constrain_as_next_in_sequence(expectation) index = @expectations.length @expectations << expectation expectation.add_ordering_constraint(InSequenceOrderingConstraint.new(self, index)) end # @private def satisfied_to_index?(index) @expectations[0...index].all?(&:satisfied?) end # @private def mocha_inspect @name.mocha_inspect.to_s end end end mocha-2.4.2/lib/mocha/single_return_value.rb000066400000000000000000000003231464615054400210530ustar00rootroot00000000000000require 'mocha/is_a' module Mocha class SingleReturnValue def initialize(value) @value = value end def evaluate(invocation) invocation.returned(@value) @value end end end mocha-2.4.2/lib/mocha/state_machine.rb000066400000000000000000000075071464615054400176160ustar00rootroot00000000000000module Mocha # A state machine that is used to constrain the order of invocations. # An invocation can be constrained to occur when a state {#is}, or {#is_not}, active. class StateMachine # Provides the ability to determine whether a {StateMachine} is in a specified state at some point in the future. class StatePredicate # @private def initialize(state_machine, state, description, &active_check) @state_machine = state_machine @state = state @description = description @active_check = active_check end # @private def active? @active_check.call(@state_machine.current_state, @state) end # @private def mocha_inspect "#{@state_machine.name} #{@description} #{@state.mocha_inspect}" end end # Provides a mechanism to change the state of a {StateMachine} at some point in the future. class State < StatePredicate # @private def activate @state_machine.current_state = @state end end # @private attr_reader :name # @private attr_accessor :current_state # @private def initialize(name) @name = name @current_state = nil end # Put the {StateMachine} into the state specified by +initial_state_name+. # # @param [String] initial_state_name name of initial state # @return [StateMachine] state machine, thereby allowing invocations of other {StateMachine} methods to be chained. def starts_as(initial_state_name) become(initial_state_name) self end # Put the {StateMachine} into the +next_state_name+. # # @param [String] next_state_name name of new state def become(next_state_name) @current_state = next_state_name end # Provides mechanisms to (a) determine whether the {StateMachine} is in a given state; or (b) to change the {StateMachine} into the given state. # # @param [String] state_name name of expected/desired state. # @return [StatePredicate,State] (a) state predicate which, when queried, will indicate whether the {StateMachine} is in the given state; or (b) state which, when activated, will change the {StateMachine} into the given state. # # @overload def is(expected_state_name) # Provides a mechanism to determine whether the {StateMachine} is in the state specified by +expected_state_name+ at some point in the future # @param [String] expected_state_name name of expected state. # @return [StatePredicate] state predicate which, when queried, will indicate whether the {StateMachine} is in the state specified by +expected_state_name+ # # @overload def is(desired_state_name) # Provides a mechanism to change the {StateMachine} into the state specified by +desired_state_name+ at some point in the future. # @param [String] desired_state_name name of desired new state. # @return [State] state which, when activated, will change the {StateMachine} into the state with the specified +desired_state_name+. def is(state_name) State.new(self, state_name, 'is') { |current, given| current == given } end # Provides a mechanism to determine whether the {StateMachine} is *not* in the state specified by +unexpected_state_name+ at some point in the future. # # @param [String] unexpected_state_name name of unexpected state. # @return [StatePredicate] state predicate which, when queried, will indicate whether the {StateMachine} is *not* in the state specified by +unexpected_state_name+. def is_not(unexpected_state_name) # rubocop:disable Naming/PredicateName StatePredicate.new(self, unexpected_state_name, 'is not') { |current, given| current != given } end # @private def mocha_inspect %(#{@name} #{@current_state ? "is #{@current_state.mocha_inspect}" : 'has no current state'}) end end end mocha-2.4.2/lib/mocha/stubbed_method.rb000066400000000000000000000042231464615054400177720ustar00rootroot00000000000000require 'ruby2_keywords' require 'mocha/ruby_version' module Mocha class StubbedMethod PrependedModule = Class.new(Module) attr_reader :stubbee, :method_name def initialize(stubbee, method_name) @stubbee = stubbee @original_method = nil @original_visibility = nil @method_name = method_name.to_sym end def stub hide_original_method define_new_method end def unstub remove_new_method mock.unstub(method_name.to_sym) return if mock.any_expectations? reset_mocha end def mock mock_owner.mocha end def reset_mocha mock_owner.reset_mocha end def hide_original_method return unless original_method_owner.__method_exists__?(method_name) store_original_method_visibility use_prepended_module_for_stub_method end def define_new_method self_in_scope = self method_name_in_scope = method_name stub_method_owner.send(:define_method, method_name) do |*args, &block| self_in_scope.mock.handle_method_call(method_name_in_scope, args, block) end stub_method_owner.send(:ruby2_keywords, method_name) retain_original_visibility(stub_method_owner) end def remove_new_method stub_method_owner.send(:remove_method, method_name) end def matches?(other) return false unless other.class == self.class (stubbee.object_id == other.stubbee.object_id) && (method_name == other.method_name) end alias_method :==, :eql? def to_s "#{stubbee}.#{method_name}" end private def retain_original_visibility(method_owner) return unless @original_visibility Module.instance_method(@original_visibility).bind(method_owner).call(method_name) end def store_original_method_visibility @original_visibility = original_method_owner.__method_visibility__(method_name) end def use_prepended_module_for_stub_method @stub_method_owner = PrependedModule.new original_method_owner.__send__ :prepend, @stub_method_owner end def stub_method_owner @stub_method_owner ||= original_method_owner end end end mocha-2.4.2/lib/mocha/stubbing_error.rb000066400000000000000000000003421464615054400200260ustar00rootroot00000000000000require 'mocha/error_with_filtered_backtrace' module Mocha # Exception raised when stubbing a particular method is not allowed. # # @see Configuration.prevent class StubbingError < ErrorWithFilteredBacktrace; end end mocha-2.4.2/lib/mocha/test_unit.rb000066400000000000000000000002771464615054400170250ustar00rootroot00000000000000require 'mocha/ruby_version' require 'mocha/integration/test_unit' unless Mocha::Integration::TestUnit.activate raise "Test::Unit must be loaded *before* `require 'mocha/test_unit'`." end mocha-2.4.2/lib/mocha/thrower.rb000066400000000000000000000003431464615054400164730ustar00rootroot00000000000000module Mocha class Thrower def initialize(tag, object = nil) @tag = tag @object = object end def evaluate(invocation) invocation.threw(@tag, @object) throw @tag, @object end end end mocha-2.4.2/lib/mocha/thrown_object.rb000066400000000000000000000003351464615054400176510ustar00rootroot00000000000000module Mocha class ThrownObject def initialize(tag, value = nil) @tag = tag @value = value end def mocha_inspect "threw (#{@tag.mocha_inspect}, #{@value.mocha_inspect})" end end end mocha-2.4.2/lib/mocha/version.rb000066400000000000000000000000541464615054400164650ustar00rootroot00000000000000module Mocha VERSION = '2.4.2'.freeze end mocha-2.4.2/lib/mocha/yield_parameters.rb000066400000000000000000000006461464615054400203400ustar00rootroot00000000000000module Mocha class YieldParameters def initialize @parameter_groups = [] end def next_invocation case @parameter_groups.length when 0 then [] when 1 then @parameter_groups.first else @parameter_groups.shift end end def add(*parameter_groups) @parameter_groups << parameter_groups.map do |pg| pg.is_a?(Array) ? pg : [pg] end end end end mocha-2.4.2/mocha.gemspec000066400000000000000000000016031464615054400152530ustar00rootroot00000000000000lib = File.expand_path('../lib/', __FILE__) $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib) require 'mocha/version' Gem::Specification.new do |s| s.name = 'mocha' s.version = Mocha::VERSION s.licenses = ['MIT', 'BSD-2-Clause'] s.required_ruby_version = '>= 2.1' s.authors = ['James Mead'] s.description = 'Mocking and stubbing library with JMock/SchMock syntax, which allows mocking and stubbing of methods on real (non-mock) classes.' s.email = 'mocha-developer@googlegroups.com' s.files = Dir.chdir(File.expand_path('..', __FILE__)) do `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(docs|test)/}) } end s.files.delete('.circleci/config.yml') s.files.delete('.gitignore') s.homepage = 'https://mocha.jamesmead.org' s.require_paths = ['lib'] s.summary = 'Mocking and stubbing library' s.add_runtime_dependency 'ruby2_keywords', '>= 0.0.5' end mocha-2.4.2/test/000077500000000000000000000000001464615054400135765ustar00rootroot00000000000000mocha-2.4.2/test/acceptance/000077500000000000000000000000001464615054400156645ustar00rootroot00000000000000mocha-2.4.2/test/acceptance/acceptance_test_helper.rb000066400000000000000000000015111464615054400226730ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'test_runner' require 'mocha/configuration' require 'mocha/mockery' require 'introspection' if Mocha::Detection::Minitest.testcase && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit') require 'mocha/minitest' else require 'mocha/test_unit' end module AcceptanceTest class FakeLogger attr_reader :warnings def initialize @warnings = [] end def warn(message) @warnings << message end end attr_reader :logger include TestRunner def setup_acceptance_test Mocha::Configuration.reset_configuration @logger = FakeLogger.new mockery = Mocha::Mockery.instance mockery.logger = @logger end def teardown_acceptance_test Mocha::Configuration.reset_configuration end include Introspection::Assertions end mocha-2.4.2/test/acceptance/array_flatten_test.rb000066400000000000000000000012751464615054400221100ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class ArrayFlattenTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_flattens_array_containing_mock_which_responds_like_active_record_model model = Class.new do # Ref: https://github.com/rails/rails/blob/7db044f38594eb43e1d241cc82025155666cc6f1/activerecord/lib/active_record/core.rb#L734-L745 def to_ary nil end private :to_ary end.new test_result = run_as_test do m = mock.responds_like(model) assert_equal [m], [m].flatten end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/bug_18914_test.rb000066400000000000000000000012651464615054400205770ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Bug18914Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end class AlwaysEql def my_method true end def ==(_other) true end def eql?(_other) true end end def test_should_not_allow_stubbing_of_non_mock_instance_disrupted_by_legitimate_overriding_of_eql_method always_eql1 = AlwaysEql.new always_eql1.stubs(:my_method).returns(false) always_eql2 = AlwaysEql.new always_eql2.stubs(:my_method).returns(false) assert_equal false, always_eql2.my_method end end mocha-2.4.2/test/acceptance/bug_21465_test.rb000066400000000000000000000011741464615054400205710ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Bug21465Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_expected_method_name_to_be_a_string test_result = run_as_test do mock = mock() mock.expects('wibble') mock.wibble end assert_passed(test_result) end def test_should_allow_stubbed_method_name_to_be_a_string test_result = run_as_test do mock = mock() mock.stubs('wibble') mock.wibble end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/bug_21563_test.rb000066400000000000000000000007151464615054400205700ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Bug21563Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_of_verified_method test_result = run_as_test do object = Object.new object.stubs(:verified?).returns(false) assert !object.verified? end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/display_matching_invocations_alongside_expectations_test.rb000066400000000000000000000047451464615054400320300ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class DisplayMatchingInvocationsAlongsideExpectationsTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test Mocha.configuration.display_matching_invocations_on_failure = true end def test_should_display_results test_result = run_as_test do foo = mock('foo') foo.expects(:bar).with(1).returns('a') foo.stubs(:bar).with(any_parameters).returns('f').raises(StandardError).throws(:tag, 'value') foo.bar(1, 2) assert_raises(StandardError) { foo.bar(3, 4) } assert_throws(:tag) { foo.bar(5, 6) } end assert_invocations( test_result, '- allowed any number of times, invoked 3 times: #.bar(any_parameters)', ' - #.bar(1, 2) # => "f"', ' - #.bar(3, 4) # => raised StandardError', ' - #.bar(5, 6) # => threw (:tag, "value")' ) end def test_should_display_yields test_result = run_as_test do foo = mock('foo') foo.expects(:bar).with(1).returns('a') foo.stubs(:bar).with(any_parameters).multiple_yields('bc', %w[d e]).returns('f').raises(StandardError).throws(:tag, 'value') foo.bar(1, 2) { |_ignored| } assert_raises(StandardError) { foo.bar(3, 4) { |_ignored| } } assert_throws(:tag) { foo.bar(5, 6) { |_ignored| } } end assert_invocations( test_result, '- allowed any number of times, invoked 3 times: #.bar(any_parameters)', ' - #.bar(1, 2) { ... } # => "f" after yielding ("bc"), then ("d", "e")', ' - #.bar(3, 4) { ... } # => raised StandardError after yielding ("bc"), then ("d", "e")', ' - #.bar(5, 6) { ... } # => threw (:tag, "value") after yielding ("bc"), then ("d", "e")' ) end def test_should_display_empty_yield_and_return test_result = run_as_test do foo = mock('foo') foo.expects(:bar).with(1).returns('a') foo.stubs(:bar).with(any_parameters).yields foo.bar(1, 2) { |_ignored| } end assert_invocations( test_result, '- allowed any number of times, invoked once: #.bar(any_parameters)', ' - #.bar(1, 2) { ... } # => nil after yielding ()' ) end def assert_invocations(test_result, *invocations) assert_failed(test_result) assert_equal invocations.unshift('satisfied expectations:'), test_result.failure_message_lines[-invocations.size..-1] end end mocha-2.4.2/test/acceptance/exception_rescue_test.rb000066400000000000000000000021151464615054400226130ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class ExceptionRescueTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_unexpected_invocation_exception_is_not_caught_by_standard_rescue test_result = run_as_test do mock = mock('mock') begin mock.some_method rescue StandardError => e flunk "should not rescue #{e.class}" end end assert_failed(test_result) assert_equal 'unexpected invocation: #.some_method()', test_result.failure_message_lines[0] end def test_invocation_never_expected_exception_is_not_caught_by_standard_rescue test_result = run_as_test do mock = mock('mock') mock.expects(:some_method).never begin mock.some_method rescue StandardError => e flunk "should not rescue #{e.class}" end end assert_failed(test_result) assert_equal 'unexpected invocation: #.some_method()', test_result.failure_message_lines[0] end end mocha-2.4.2/test/acceptance/expectations_on_multiple_methods_test.rb000066400000000000000000000026241464615054400261140ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class ExpectationsOnMultipleMethodsTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_expect_calls_to_multiple_methods instance = Class.new do def my_instance_method_1 :original_return_value_1 end def my_instance_method_2 :original_return_value_2 end end.new test_result = run_as_test do instance.expects( my_instance_method_1: :new_return_value_1, my_instance_method_2: :new_return_value_2 ) assert_equal :new_return_value_1, instance.my_instance_method_1 assert_equal :new_return_value_2, instance.my_instance_method_2 end assert_passed(test_result) end def test_should_stub_calls_to_multiple_methods instance = Class.new do def my_instance_method_1 :original_return_value_1 end def my_instance_method_2 :original_return_value_2 end end.new test_result = run_as_test do instance.stubs( my_instance_method_1: :new_return_value_1, my_instance_method_2: :new_return_value_2 ) assert_equal :new_return_value_1, instance.my_instance_method_1 assert_equal :new_return_value_2, instance.my_instance_method_2 end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/expected_invocation_count_test.rb000066400000000000000000000165441464615054400245240ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class ExpectedInvocationCountTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_pass_if_method_is_never_expected_and_is_never_called test_result = run_as_test do mock = mock('mock') mock.expects(:method).never 0.times { mock.method } end assert_passed(test_result) end def test_should_fail_fast_if_method_is_never_expected_but_is_called_once test_result = run_as_test do mock = mock('mock') mock.expects(:method).never 1.times { mock.method } end assert_failed(test_result) assert_equal [ 'unexpected invocation: #.method()', 'unsatisfied expectations:', '- expected never, invoked once: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_pass_if_method_is_expected_twice_and_is_called_twice test_result = run_as_test do mock = mock('mock') mock.expects(:method).twice 2.times { mock.method } end assert_passed(test_result) end def test_should_fail_if_method_is_expected_twice_but_is_called_once test_result = run_as_test do mock = mock('mock') mock.expects(:method).twice 1.times { mock.method } end assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly twice, invoked once: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_fail_fast_if_method_is_expected_twice_but_is_called_three_times test_result = run_as_test do mock = mock('mock') mock.expects(:method).twice 3.times { mock.method } end assert_failed(test_result) assert_equal [ 'unexpected invocation: #.method()', 'unsatisfied expectations:', '- expected exactly twice, invoked 3 times: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_twice test_result = run_as_test do mock = mock('mock') mock.expects(:method).times(2..4) 2.times { mock.method } end assert_passed(test_result) end def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_three_times test_result = run_as_test do mock = mock('mock') mock.expects(:method).times(2..4) 3.times { mock.method } end assert_passed(test_result) end def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_four_times test_result = run_as_test do mock = mock('mock') mock.expects(:method).times(2..4) 4.times { mock.method } end assert_passed(test_result) end def test_should_fail_if_method_is_expected_between_two_and_four_times_and_is_called_once test_result = run_as_test do mock = mock('mock') mock.expects(:method).times(2..4) 1.times { mock.method } end assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected between 2 and 4 times, invoked once: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_fail_fast_if_method_is_expected_between_two_and_four_times_and_is_called_five_times test_result = run_as_test do mock = mock('mock') mock.expects(:method).times(2..4) 5.times { mock.method } end assert_failed(test_result) assert_equal [ 'unexpected invocation: #.method()', 'unsatisfied expectations:', '- expected between 2 and 4 times, invoked 5 times: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_pass_if_method_is_expected_at_least_once_and_is_called_once test_result = run_as_test do mock = mock('mock') mock.expects(:method).at_least_once 1.times { mock.method } end assert_passed(test_result) end def test_should_pass_if_method_is_expected_at_least_once_and_is_called_twice test_result = run_as_test do mock = mock('mock') mock.expects(:method).at_least_once 2.times { mock.method } end assert_passed(test_result) end def test_should_fail_if_method_is_expected_at_least_once_but_is_never_called test_result = run_as_test do mock = mock('mock') mock.expects(:method).at_least_once 0.times { mock.method } end assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected at least once, invoked never: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_pass_if_method_is_expected_at_most_once_and_is_never_called test_result = run_as_test do mock = mock('mock') mock.expects(:method).at_most_once 0.times { mock.method } end assert_passed(test_result) end def test_should_pass_if_method_is_expected_at_most_once_and_called_once test_result = run_as_test do mock = mock('mock') mock.expects(:method).at_most_once 1.times { mock.method } end assert_passed(test_result) end def test_should_fail_fast_if_method_is_expected_at_most_once_but_is_called_twice test_result = run_as_test do mock = mock('mock') mock.expects(:method).at_most_once 2.times { mock.method } end assert_failed(test_result) assert_equal [ 'unexpected invocation: #.method()', 'unsatisfied expectations:', '- expected at most once, invoked twice: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_pass_if_method_is_never_expected_and_is_never_called_even_if_everything_is_stubbed test_result = run_as_test do stub = stub_everything('stub') stub.expects(:method).never 0.times { stub.method } end assert_passed(test_result) end def test_should_fail_fast_if_method_is_never_expected_but_is_called_once_even_if_everything_is_stubbed test_result = run_as_test do stub = stub_everything('stub') stub.expects(:method).never 1.times { stub.method } end assert_failed(test_result) assert_equal [ 'unexpected invocation: #.method()', 'unsatisfied expectations:', '- expected never, invoked once: #.method(any_parameters)' ], test_result.failure_message_lines end def test_should_fail_fast_if_there_is_no_matching_expectation test_result = run_as_test do mock = mock('mock') mock.expects(:method).with(1) 1.times { mock.method } end assert_failed(test_result) assert_equal [ 'unexpected invocation: #.method()', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(1)' ], test_result.failure_message_lines end def test_should_pass_if_cardinality_is_satisfied_using_calls_made_both_before_and_after_updating_cardinality test_result = run_as_test do mock = mock('mock') expectation = mock.expects(:method) mock.method expectation.twice mock.method end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/failure_messages_test.rb000066400000000000000000000043771464615054400226010ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class FailureMessagesTest < Mocha::TestCase OBJECT_ADDRESS_PATTERN = '0x[0-9A-Fa-f]{1,12}'.freeze include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end class Foo; end def test_should_display_class_name_when_expectation_was_on_class test_result = run_as_test do Foo.expects(:bar) end assert_match Regexp.new('FailureMessagesTest::Foo'), test_result.failures[0].message end def test_should_display_class_name_and_address_when_expectation_was_on_instance test_result = run_as_test do Foo.new.expects(:bar) end assert_match Regexp.new("#"), test_result.failures[0].message end def test_should_display_class_name_and_any_instance_prefix_when_expectation_was_on_any_instance test_result = run_as_test do Foo.any_instance.expects(:bar) end assert_match Regexp.new('#'), test_result.failures[0].message end def test_should_display_mock_name_when_expectation_was_on_named_mock test_result = run_as_test do foo = mock('foo') foo.expects(:bar) end assert_match Regexp.new('#'), test_result.failures[0].message end def test_should_display_mock_address_when_expectation_was_on_unnamed_mock test_result = run_as_test do foo = mock foo.expects(:bar) end assert_match Regexp.new("#"), test_result.failures[0].message end def test_should_display_string_when_expectation_was_on_string test_result = run_as_test do 'Foo'.expects(:bar) end assert_match Regexp.new(%("Foo")), test_result.failures[0].message end def test_should_display_that_block_was_expected test_result = run_as_test do foo = mock foo.expects(:bar).with_block_given end assert_match Regexp.new(' with block given$'), test_result.failures[0].message end def test_should_display_that_block_was_not_expected test_result = run_as_test do foo = mock foo.expects(:bar).with_no_block_given end assert_match Regexp.new(' with no block given$'), test_result.failures[0].message end end mocha-2.4.2/test/acceptance/issue_272_test.rb000066400000000000000000000020271464615054400207730ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Issue272Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end module Mod private def foo 'original-foo' end def bar 'original-bar' end end class Klass extend Mod class << self public :foo public :bar end end def test_private_methods_in_module_used_to_extend_class_and_made_public test_result = run_as_test do Klass.stubs(:foo).returns('stubbed-foo') # hangs in next line executing: # `@original_method = stubbee._method(method)` # in Mocha::StubbedMethod#hide_original_method # but only in Ruby v2.3, not v2.2 Klass.stubs(:bar).returns('stubbed-bar') assert_equal 'stubbed-foo', Klass.foo assert_equal 'stubbed-bar', Klass.bar end assert_passed(test_result) assert_equal 'original-foo', Klass.foo assert_equal 'original-bar', Klass.bar end end mocha-2.4.2/test/acceptance/issue_457_test.rb000066400000000000000000000012061464615054400207760ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Issue457Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_only_inspect_objects_when_necessary test_result = run_as_test do klass = Class.new do def message raise 'Not inspectable in this state!' end def inspect message end end instance = klass.new instance.stubs(:message).returns('message') assert_equal 'message', instance.inspect end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/issue_524_test.rb000066400000000000000000000013531464615054400207740ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Issue524Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_expects_returns_last_expectation test_result = run_as_test do object = mock object.expects(method_1: 1, method_2: 2).twice object.method_1 object.method_2 object.method_2 end assert_passed(test_result) end def test_stubs_returns_last_expectation test_result = run_as_test do object = mock object.stubs(method_1: 1, method_2: 2).twice object.method_1 object.method_2 object.method_2 end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/issue_65_test.rb000066400000000000000000000025431464615054400207160ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Issue65Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_expectations_on_class_methods_on_same_class_should_be_verified_in_consecutive_tests klass = Class.new do def self.foo; end def self.bar; end end test1 = run_as_test do klass.expects(:foo) klass.foo end assert_passed(test1) test2 = run_as_test do klass.expects(:bar) end assert_failed(test2) end def test_expectations_on_any_instance_methods_on_same_class_should_be_verified_in_consecutive_tests klass = Class.new do def foo; end def bar; end end test1 = run_as_test do klass.any_instance.expects(:foo) klass.new.foo end assert_passed(test1) test2 = run_as_test do klass.any_instance.expects(:bar) end assert_failed(test2) end def test_expectations_on_instance_methods_on_same_object_should_be_verified_in_consecutive_tests instance = Class.new do def foo; end def bar; end end.new test1 = run_as_test do instance.expects(:foo) instance.foo end assert_passed(test1) test2 = run_as_test do instance.expects(:bar) end assert_failed(test2) end end mocha-2.4.2/test/acceptance/issue_70_test.rb000066400000000000000000000025011464615054400207040ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Issue70Test < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_expectations_instance_method instance = Class.new do def expectations :original_return_value end end.new test_result = run_as_test do instance.stubs(:expectations).returns(:stubbed_return_value) assert_equal :stubbed_return_value, instance.expectations end assert_passed(test_result) end def test_should_stub_expectations_class_method klass = Class.new do def self.expectations :original_return_value end end test_result = run_as_test do klass.stubs(:expectations).returns(:stubbed_return_value) assert_equal :stubbed_return_value, klass.expectations end assert_passed(test_result) end def test_should_stub_expectations_any_instance_method klass = Class.new do def expectations :original_return_value end end instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:expectations).returns(:stubbed_return_value) assert_equal :stubbed_return_value, instance.expectations end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/keyword_argument_matching_test.rb000066400000000000000000000203771464615054400245210ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'deprecation_disabler' require 'execution_point' require 'mocha/deprecation' class KeywordArgumentMatchingTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_match_hash_parameter_with_keyword_args test_name = __method__ test_result = run_as_test do mock = mock() mock.expects(:method).with(key: 42); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end if Mocha::RUBY_V27_PLUS location = "#{execution_point.file_name}:#{execution_point.line_number}:in `block in #{test_name}'" assert_includes Mocha::Deprecation.messages.last, "Expectation defined at #{location} expected keyword arguments (key: 42)" assert_includes Mocha::Deprecation.messages.last, 'but received positional hash ({:key => 42})' end end assert_passed(test_result) end if Mocha::RUBY_V27_PLUS def test_should_not_match_hash_parameter_with_keyword_args_when_strict_keyword_matching_is_enabled test_result = run_as_test do mock = mock() mock.expects(:method).with(key: 42) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end end assert_failed(test_result) end end def test_should_match_hash_parameter_with_splatted_keyword_args test_name = __method__ test_result = run_as_test do mock = mock() mock.expects(:method).with(**{ key: 42 }); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end if Mocha::RUBY_V27_PLUS location = "#{execution_point.file_name}:#{execution_point.line_number}:in `block in #{test_name}'" assert_includes Mocha::Deprecation.messages.last, "Expectation defined at #{location} expected keyword arguments (key: 42)" assert_includes Mocha::Deprecation.messages.last, 'but received positional hash ({:key => 42})' end end assert_passed(test_result) end if Mocha::RUBY_V27_PLUS def test_should_not_match_hash_parameter_with_splatted_keyword_args_when_strict_keyword_matching_is_enabled test_result = run_as_test do mock = mock() mock.expects(:method).with(**{ key: 42 }) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end end assert_failed(test_result) end end def test_should_match_splatted_hash_parameter_with_keyword_args test_result = run_as_test do mock = mock() mock.expects(:method).with(key: 42) mock.method(**{ key: 42 }) end assert_passed(test_result) end def test_should_match_splatted_hash_parameter_with_splatted_hash test_result = run_as_test do mock = mock() mock.expects(:method).with(**{ key: 42 }) mock.method(**{ key: 42 }) end assert_passed(test_result) end def test_should_match_positional_and_keyword_args_with_last_positional_hash test_name = __method__ test_result = run_as_test do mock = mock() mock.expects(:method).with(1, { key: 42 }); execution_point = ExecutionPoint.current # rubocop:disable Style/BracesAroundHashParameters DeprecationDisabler.disable_deprecations do mock.method(1, key: 42) end if Mocha::RUBY_V27_PLUS location = "#{execution_point.file_name}:#{execution_point.line_number}:in `block in #{test_name}'" assert_includes Mocha::Deprecation.messages.last, "Expectation defined at #{location} expected positional hash ({:key => 42})" assert_includes Mocha::Deprecation.messages.last, 'but received keyword arguments (key: 42)' end end assert_passed(test_result) end if Mocha::RUBY_V27_PLUS def test_should_not_match_positional_and_keyword_args_with_last_positional_hash_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock() mock.expects(:method).with(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method(1, key: 42) end end assert_failed(test_result) end end def test_should_match_last_positional_hash_with_keyword_args test_name = __method__ test_result = run_as_test do mock = mock() mock.expects(:method).with(1, key: 42); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end if Mocha::RUBY_V27_PLUS location = "#{execution_point.file_name}:#{execution_point.line_number}:in `block in #{test_name}'" assert_includes Mocha::Deprecation.messages.last, "Expectation defined at #{location} expected keyword arguments (key: 42)" assert_includes Mocha::Deprecation.messages.last, 'but received positional hash ({:key => 42})' end end assert_passed(test_result) end if Mocha::RUBY_V27_PLUS def test_should_not_match_last_positional_hash_with_keyword_args_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock() mock.expects(:method).with(1, key: 42) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end end assert_failed(test_result) end end def test_should_match_positional_and_keyword_args_with_keyword_args test_result = run_as_test do mock = mock() mock.expects(:method).with(1, key: 42) mock.method(1, key: 42) end assert_passed(test_result) end def test_should_match_hash_parameter_with_hash_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:key)) mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end assert_passed(test_result) end def test_should_match_splatted_hash_parameter_with_hash_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:key)) mock.method(**{ key: 42 }) end assert_passed(test_result) end def test_should_match_positional_and_keyword_args_with_hash_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(1, has_key(:key)) mock.method(1, key: 42) end assert_passed(test_result) end def test_should_match_keyword_args_with_nested_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(key: is_a(Integer)) mock.method(key: 42) end assert_passed(test_result) end def test_should_match_keyword_args_with_matcher_built_using_keyword_args test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entry(:k1, k2: 'v2')) mock.method(k1: { k2: 'v2' }) end assert_passed(test_result) end def test_should_not_match_keyword_args_with_matcher_built_using_keyword_args test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entry(:k1, k2: 'v2')) mock.method(k1: { k2: 'v2', k3: 'v3' }) end assert_failed(test_result) end def test_should_match_last_positional_hash_with_hash_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(1, has_key(:key)) mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end assert_passed(test_result) end if Mocha::RUBY_V27_PLUS def test_should_not_match_non_hash_args_with_keyword_args test_result = run_as_test do mock = mock() mock.expects(:method).with(**{ key: 1 }) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method([2]) end end assert_failed(test_result) end end end mocha-2.4.2/test/acceptance/mocha_example_test.rb000066400000000000000000000053151464615054400220560ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class MochaExampleTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end class Rover def initialize(left_track, right_track, steps_per_metre, steps_per_degree) @left_track = left_track @right_track = right_track @steps_per_metre = steps_per_metre @steps_per_degree = steps_per_degree end def forward(metres) @left_track.step(metres * @steps_per_metre) @right_track.step(metres * @steps_per_metre) wait end def backward(metres) forward(-metres) end def left(degrees) @left_track.step(-degrees * @steps_per_degree) @right_track.step(+degrees * @steps_per_degree) wait end def right(degrees) left(-degrees) end def wait while @left_track.moving? || @right_track.moving?; end end end def test_should_step_both_tracks_forward_ten_steps left_track = mock('left_track') right_track = mock('right_track') steps_per_metre = 5 rover = Rover.new(left_track, right_track, steps_per_metre, nil) left_track.expects(:step).with(10) right_track.expects(:step).with(10) left_track.stubs(:moving?).returns(false) right_track.stubs(:moving?).returns(false) rover.forward(2) end def test_should_step_both_tracks_backward_ten_steps left_track = mock('left_track') right_track = mock('right_track') steps_per_metre = 5 rover = Rover.new(left_track, right_track, steps_per_metre, nil) left_track.expects(:step).with(-10) right_track.expects(:step).with(-10) left_track.stubs(:moving?).returns(false) right_track.stubs(:moving?).returns(false) rover.backward(2) end def test_should_step_left_track_forwards_five_steps_and_right_track_backwards_five_steps left_track = mock('left_track') right_track = mock('right_track') steps_per_degree = 5.0 / 90.0 rover = Rover.new(left_track, right_track, nil, steps_per_degree) left_track.expects(:step).with(+5) right_track.expects(:step).with(-5) left_track.stubs(:moving?).returns(false) right_track.stubs(:moving?).returns(false) rover.right(90) end def test_should_step_left_track_backwards_five_steps_and_right_track_forwards_five_steps left_track = mock('left_track') right_track = mock('right_track') steps_per_degree = 5.0 / 90.0 rover = Rover.new(left_track, right_track, nil, steps_per_degree) left_track.expects(:step).with(-5) right_track.expects(:step).with(+5) left_track.stubs(:moving?).returns(false) right_track.stubs(:moving?).returns(false) rover.left(90) end end mocha-2.4.2/test/acceptance/mocha_test_result_test.rb000066400000000000000000000043161464615054400230000ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'execution_point' class MochaTestResultTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_include_expectation_verification_in_assertion_count test_result = run_as_test do object = mock object.expects(:message) object.message end assert_equal 1, test_result.assertion_count end def test_should_include_assertions_in_assertion_count test_result = run_as_test do assert true end assert_equal 1, test_result.assertion_count end def test_should_not_include_stubbing_expectation_verification_in_assertion_count test_result = run_as_test do object = mock object.stubs(:message) object.message end assert_equal 0, test_result.assertion_count end def test_should_include_expectation_verification_failure_in_failure_count test_result = run_as_test do object = mock object.expects(:message) end assert_equal 1, test_result.failure_count end def test_should_include_unexpected_verification_failure_in_failure_count test_result = run_as_test do object = mock object.message end assert_equal 1, test_result.failure_count end def test_should_include_assertion_failure_in_failure_count test_result = run_as_test do flunk end assert_equal 1, test_result.failure_count end def test_should_display_backtrace_indicating_line_number_where_unexpected_method_was_called execution_point = nil test_result = run_as_test do object = mock execution_point = ExecutionPoint.current; object.message end assert_equal 1, test_result.failure_count assert_equal execution_point, ExecutionPoint.new(test_result.failures[0].location) end def test_should_display_backtrace_indicating_line_number_where_failing_assertion_was_called execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; flunk end assert_equal 1, test_result.failure_count assert_equal execution_point, ExecutionPoint.new(test_result.failures[0].location) end end mocha-2.4.2/test/acceptance/mock_test.rb000066400000000000000000000113001464615054400201740ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class MockTest < Mocha::TestCase include AcceptanceTest include Mocha def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_build_mock_and_explicitly_add_an_expectation_which_is_satisfied test_result = run_as_test do foo = mock foo.expects(:bar) foo.bar end assert_passed(test_result) end def test_should_build_mock_and_explicitly_add_an_expectation_which_is_not_satisfied test_result = run_as_test do foo = mock foo.expects(:bar) end assert_failed(test_result) end def test_should_build_string_named_mock_and_explicitly_add_an_expectation_which_is_satisfied test_result = run_as_test do foo = mock('foo') foo.expects(:bar) foo.bar end assert_passed(test_result) end def test_should_build_symbol_named_mock_and_explicitly_add_an_expectation_which_is_satisfied test_result = run_as_test do foo = mock(:foo) foo.expects(:bar) foo.bar end assert_passed(test_result) end def test_should_build_string_named_mock_and_explicitly_add_an_expectation_which_is_not_satisfied test_result = run_as_test do foo = mock('foo') foo.expects(:bar) end assert_failed(test_result) end def test_should_build_symbol_named_mock_and_explicitly_add_an_expectation_which_is_not_satisfied test_result = run_as_test do foo = mock(:foo) foo.expects(:bar) end assert_failed(test_result) end def test_should_build_mock_incorporating_two_expectations_which_are_satisifed test_result = run_as_test do foo = mock(bar: 'bar', baz: 'baz') foo.bar foo.baz end assert_passed(test_result) end def test_should_build_mock_incorporating_two_expectations_the_first_of_which_is_not_satisifed test_result = run_as_test do foo = mock(bar: 'bar', baz: 'baz') foo.baz end assert_failed(test_result) end def test_should_build_mock_incorporating_two_expectations_the_second_of_which_is_not_satisifed test_result = run_as_test do foo = mock(bar: 'bar', baz: 'baz') foo.bar end assert_failed(test_result) end def test_should_build_string_named_mock_incorporating_two_expectations_which_are_satisifed test_result = run_as_test do foo = mock('foo', bar: 'bar', baz: 'baz') foo.bar foo.baz end assert_passed(test_result) end def test_should_build_symbol_named_mock_incorporating_two_expectations_which_are_satisifed test_result = run_as_test do foo = mock(:foo, bar: 'bar', baz: 'baz') foo.bar foo.baz end assert_passed(test_result) end def test_should_build_string_named_mock_incorporating_two_expectations_the_first_of_which_is_not_satisifed test_result = run_as_test do foo = mock('foo', bar: 'bar', baz: 'baz') foo.baz end assert_failed(test_result) end def test_should_build_symbol_named_mock_incorporating_two_expectations_the_first_of_which_is_not_satisifed test_result = run_as_test do foo = mock(:foo, bar: 'bar', baz: 'baz') foo.baz end assert_failed(test_result) end def test_should_build_string_named_mock_incorporating_two_expectations_the_second_of_which_is_not_satisifed test_result = run_as_test do foo = mock('foo', bar: 'bar', baz: 'baz') foo.bar end assert_failed(test_result) end def test_should_build_symbol_named_mock_incorporating_two_expectations_the_second_of_which_is_not_satisifed test_result = run_as_test do foo = mock(:foo, bar: 'bar', baz: 'baz') foo.bar end assert_failed(test_result) end class Foo class << self attr_accessor :logger end def use_the_mock self.class.logger.log('Foo was here') end end def test_should_raise_stubbing_error_if_mock_receives_invocations_in_another_test use_mock_test_result = run_as_test do Foo.logger = mock('Logger') Foo.logger.expects(:log).with('Foo was here') Foo.new.use_the_mock end assert_passed(use_mock_test_result) reuse_mock_test_result = run_as_test do Foo.logger.expects(:log).with('Foo was here') e = assert_raises(Mocha::StubbingError) { Foo.new.use_the_mock } assert e.message.include?('# was instantiated in FakeTest#test_me but it is receiving invocations within another test.') assert e.message.include?('This can lead to unintended interactions between tests and hence unexpected test failures.') assert e.message.include?('Ensure that every test correctly cleans up any state that it introduces.') end assert_passed(reuse_mock_test_result) end end mocha-2.4.2/test/acceptance/mocked_methods_dispatch_test.rb000066400000000000000000000040771464615054400241240ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class MockedMethodDispatchTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_find_latest_matching_expectation test_result = run_as_test do mock = mock() mock.stubs(:method).returns(1) mock.stubs(:method).returns(2) assert_equal 2, mock.method assert_equal 2, mock.method assert_equal 2, mock.method end assert_passed(test_result) end def test_should_find_latest_expectation_which_has_not_stopped_matching test_result = run_as_test do mock = mock() mock.stubs(:method).returns(1) mock.stubs(:method).once.returns(2) assert_equal 2, mock.method assert_equal 1, mock.method assert_equal 1, mock.method end assert_passed(test_result) end def test_should_keep_finding_later_stub_and_so_never_satisfy_earlier_expectation test_result = run_as_test do mock = mock() mock.expects(:method).returns(1) mock.stubs(:method).returns(2) assert_equal 2, mock.method assert_equal 2, mock.method assert_equal 2, mock.method end assert_failed(test_result) end def test_should_find_later_expectation_until_it_stops_matching_then_find_earlier_stub test_result = run_as_test do mock = mock() mock.stubs(:method).returns(1) mock.expects(:method).returns(2) assert_equal 2, mock.method assert_equal 1, mock.method assert_equal 1, mock.method end assert_passed(test_result) end def test_should_find_latest_expectation_with_range_of_expected_invocation_count_which_has_not_stopped_matching test_result = run_as_test do mock = mock() mock.stubs(:method).returns(1) mock.stubs(:method).times(2..3).returns(2) assert_equal 2, mock.method assert_equal 2, mock.method assert_equal 2, mock.method assert_equal 1, mock.method assert_equal 1, mock.method end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/multiple_expectations_failure_message_test.rb000066400000000000000000000053641464615054400271140ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class FailureMessageTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_include_unexpected_invocation_in_unsatisfied_expectation_message test_result = run_as_test do mock = mock('mock') mock.expects(:method_one).once 2.times { mock.method_one } end assert_failed(test_result) assert_equal [ 'unexpected invocation: #.method_one()', 'unsatisfied expectations:', '- expected exactly once, invoked twice: #.method_one(any_parameters)' ], test_result.failure_message_lines end def test_should_report_satisfied_expectations_as_well_as_unsatisfied_expectations test_result = run_as_test do mock = mock('mock') mock.expects(:method_one).once mock.expects(:method_two).twice 1.times { mock.method_one } 1.times { mock.method_two } end assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly twice, invoked once: #.method_two(any_parameters)', 'satisfied expectations:', '- expected exactly once, invoked once: #.method_one(any_parameters)' ], test_result.failure_message_lines end def test_should_report_multiple_satisfied_expectations test_result = run_as_test do mock = mock('mock') mock.expects(:method_one).once mock.expects(:method_two).twice mock.expects(:method_three).times(3) 1.times { mock.method_one } 2.times { mock.method_two } 2.times { mock.method_three } end assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly 3 times, invoked twice: #.method_three(any_parameters)', 'satisfied expectations:', '- expected exactly twice, invoked twice: #.method_two(any_parameters)', '- expected exactly once, invoked once: #.method_one(any_parameters)' ], test_result.failure_message_lines end def test_should_include_state_in_unsatisfied_expectation_message test_result = run_as_test do mock = mock('mock') readiness = states('readiness') mock.expects(:method_one).once.then(readiness.is('ready')) end assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method_one(any_parameters)', 'states:', '- readiness has no current state' ], test_result.failure_message_lines end end mocha-2.4.2/test/acceptance/multiple_yielding_test.rb000066400000000000000000000030471464615054400227730ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class MultipleYieldingTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_yields_values_multiple_times_when_stubbed_method_is_invoked test_result = run_as_test do m = mock('m') m.stubs(:foo).multiple_yields([1], [2, 3]) yielded = [] m.foo { |*args| yielded << args } assert_equal [[1], [2, 3]], yielded end assert_passed(test_result) end def test_yields_values_multiple_times_when_multiple_yields_arguments_are_not_arrays test_result = run_as_test do m = mock('m') m.stubs(:foo).multiple_yields(1, { b: 2 }, '3') yielded = [] m.foo { |*args| yielded << args } assert_equal [[1], [{ b: 2 }], ['3']], yielded end assert_passed(test_result) end def test_raises_local_jump_error_if_instructed_to_multiple_yield_but_no_block_given test_result = run_as_test do m = mock('m') m.stubs(:foo).multiple_yields([]) assert_raises(LocalJumpError) { m.foo } end assert_passed(test_result) end def test_yields_different_values_on_consecutive_invocations test_result = run_as_test do m = mock('m') m.stubs(:foo).multiple_yields([0], [1, 2]).then.multiple_yields([3], [4, 5]) yielded = [] m.foo { |*args| yielded << args } m.foo { |*args| yielded << args } assert_equal [[0], [1, 2], [3], [4, 5]], yielded end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/optional_parameters_test.rb000066400000000000000000000036611464615054400233260ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class OptionalParameterMatcherTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_pass_if_all_required_parameters_match_and_no_optional_parameters_are_supplied test_result = run_as_test do mock = mock() mock.expects(:method).with(1, 2, optionally(3, 4)) mock.method(1, 2) end assert_passed(test_result) end def test_should_pass_if_all_required_and_optional_parameters_match_and_some_optional_parameters_are_supplied test_result = run_as_test do mock = mock() mock.expects(:method).with(1, 2, optionally(3, 4)) mock.method(1, 2, 3) end assert_passed(test_result) end def test_should_pass_if_all_required_and_optional_parameters_match_and_all_optional_parameters_are_supplied test_result = run_as_test do mock = mock() mock.expects(:method).with(1, 2, optionally(3, 4)) mock.method(1, 2, 3, 4) end assert_passed(test_result) end def test_should_fail_if_all_required_and_optional_parameters_match_but_too_many_optional_parameters_are_supplied test_result = run_as_test do mock = mock() mock.expects(:method).with(1, 2, optionally(3, 4)) mock.method(1, 2, 3, 4, 5) end assert_failed(test_result) end def test_should_fail_if_all_required_parameters_match_but_some_optional_parameters_do_not_match test_result = run_as_test do mock = mock() mock.expects(:method).with(1, 2, optionally(3, 4)) mock.method(1, 2, 4) end assert_failed(test_result) end def test_should_fail_if_all_required_parameters_match_but_no_optional_parameters_match test_result = run_as_test do mock = mock() mock.expects(:method).with(1, 2, optionally(3, 4)) mock.method(1, 2, 4, 5) end assert_failed(test_result) end end mocha-2.4.2/test/acceptance/parameter_matcher_test.rb000066400000000000000000000214331464615054400227360ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class ParameterMatcherTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_match_hash_parameter_with_specified_key test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:key_1)) mock.method(key_1: 'value_1', key_2: 'value_2') end assert_passed(test_result) end def test_should_not_match_hash_parameter_with_specified_key test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:key_1)) mock.method(key_2: 'value_2') end assert_failed(test_result) end def test_should_match_hash_parameter_with_specified_value test_result = run_as_test do mock = mock() mock.expects(:method).with(has_value('value_1')) mock.method(key_1: 'value_1', key_2: 'value_2') end assert_passed(test_result) end def test_should_not_match_hash_parameter_with_specified_value test_result = run_as_test do mock = mock() mock.expects(:method).with(has_value('value_1')) mock.method(key_2: 'value_2') end assert_failed(test_result) end def test_should_match_hash_parameter_with_specified_key_value_pair test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entry(:key_1, 'value_1')) mock.method(key_1: 'value_1', key_2: 'value_2') end assert_passed(test_result) end def test_should_not_match_hash_parameter_with_specified_key_value_pair test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entry(:key_1, 'value_2')) mock.method(key_1: 'value_1', key_2: 'value_2') end assert_failed(test_result) end def test_should_match_hash_parameter_with_specified_hash_entry test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entry(key_1: 'value_1')) mock.method(key_1: 'value_1', key_2: 'value_2') end assert_passed(test_result) end def test_should_not_match_hash_parameter_with_specified_hash_entry test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entry(key_1: 'value_2')) mock.method(key_1: 'value_1', key_2: 'value_2') end assert_failed(test_result) end def test_should_match_hash_parameter_with_specified_entries test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entries(key_1: 'value_1', key_2: 'value_2')) mock.method(key_1: 'value_1', key_2: 'value_2', key_3: 'value_3') end assert_passed(test_result) end def test_should_not_match_hash_parameter_with_specified_entries test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entries(key_1: 'value_1', key_2: 'value_2')) mock.method(key_1: 'value_1', key_2: 'value_3') end assert_failed(test_result) end def test_should_match_parameter_that_matches_regular_expression test_result = run_as_test do mock = mock() mock.expects(:method).with(regexp_matches(/meter/)) mock.method('this parameter should match') end assert_passed(test_result) end def test_should_not_match_parameter_that_does_not_match_regular_expression test_result = run_as_test do mock = mock() mock.expects(:method).with(regexp_matches(/something different/)) mock.method('this parameter should not match') end assert_failed(test_result) end def test_should_match_hash_parameter_with_specified_entries_using_nested_matchers test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entries(:key_1 => regexp_matches(/value_1/), kind_of(Symbol) => 'value_2')) mock.method(key_1: 'value_1', key_2: 'value_2', key_3: 'value_3') end assert_passed(test_result) end def test_should_not_match_hash_parameter_with_specified_entries_using_nested_matchers test_result = run_as_test do mock = mock() mock.expects(:method).with(has_entries(:key_1 => regexp_matches(/value_1/), kind_of(String) => 'value_2')) mock.method(key_1: 'value_2', key_2: 'value_3') end assert_failed(test_result) end def test_should_match_parameter_that_matches_any_value test_result = run_as_test do mock = mock() mock.expects(:method).with(any_of('value_1', 'value_2')).times(2) mock.method('value_1') mock.method('value_2') end assert_passed(test_result) end def test_should_not_match_parameter_that_does_not_match_any_value test_result = run_as_test do mock = mock() mock.expects(:method).with(any_of('value_1', 'value_2')) mock.method('value_3') end assert_failed(test_result) end def test_should_match_parameter_that_matches_any_of_the_given_matchers test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:foo) | has_key(:bar)).times(2) mock.method(foo: 'fooval') mock.method(bar: 'barval') end assert_passed(test_result) end def test_should_not_match_parameter_that_does_not_match_any_of_the_given_matchers test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:foo) | has_key(:bar)) mock.method(baz: 'bazval') end assert_failed(test_result) end def test_should_match_parameter_that_matches_all_values test_result = run_as_test do mock = mock() mock.expects(:method).with(all_of('value_1', 'value_1')) mock.method('value_1') end assert_passed(test_result) end def test_should_not_match_parameter_that_does_not_match_all_values test_result = run_as_test do mock = mock() mock.expects(:method).with(all_of('value_1', 'value_2')) mock.method('value_1') end assert_failed(test_result) end def test_should_match_parameter_that_matches_all_matchers test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:foo) & has_key(:bar)) mock.method(foo: 'fooval', bar: 'barval') end assert_passed(test_result) end def test_should_not_match_parameter_that_does_not_match_all_matchers test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:foo) & has_key(:bar)) mock.method(foo: 'fooval', baz: 'bazval') end assert_failed(test_result) end def test_should_match_parameter_that_responds_with_specified_value klass = Class.new do def quack 'quack' end end duck = klass.new test_result = run_as_test do mock = mock() mock.expects(:method).with(responds_with(:quack, 'quack')) mock.method(duck) end assert_passed(test_result) end def test_should_not_match_parameter_that_does_not_respond_with_specified_value klass = Class.new do def quack 'woof' end end duck = klass.new test_result = run_as_test do mock = mock() mock.expects(:method).with(responds_with(:quack, 'quack')) mock.method(duck) end assert_failed(test_result) end def test_should_match_parameter_that_is_equivalent_uri test_result = run_as_test do mock = mock() mock.expects(:method).with(equivalent_uri('http://example.com/foo?b=2&a=1')) mock.method('http://example.com/foo?a=1&b=2') end assert_passed(test_result) end def test_should_not_match_parameter_that_is_not_equivalent test_result = run_as_test do mock = mock() mock.expects(:method).with(equivalent_uri('http://example.com/foo?a=1')) mock.method('http://example.com/foo?a=1&b=2') end assert_failed(test_result) end def test_should_match_parameter_when_value_is_divisible_by_four test_result = run_as_test do mock = mock() mock.expects(:method).with { |actual_value| (actual_value % 4).zero? } mock.method(8) end assert_passed(test_result) end def test_should_not_match_parameter_when_value_is_not_divisible_by_four test_result = run_as_test do mock = mock() mock.expects(:method).with { |actual_value| (actual_value % 4).zero? } mock.method(9) end assert_failed(test_result) end def test_should_match_parameters_when_values_add_up_to_ten test_result = run_as_test do mock = mock() matcher = lambda { |*values| values.inject(0) { |sum, n| sum + n } == 10 } mock.expects(:method).with(&matcher) mock.method(1, 2, 3, 4) end assert_passed(test_result) end def test_should_not_match_parameters_when_values_do_not_add_up_to_ten test_result = run_as_test do mock = mock() matcher = lambda { |*values| values.inject(0) { |sum, n| sum + n } == 10 } mock.expects(:method).with(&matcher) mock.method(1, 2, 3, 4, 5) end assert_failed(test_result) end end mocha-2.4.2/test/acceptance/partial_mocks_test.rb000066400000000000000000000020541464615054400221010ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class PartialMockTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_pass_if_all_expectations_are_satisfied test_result = run_as_test do partial_mock_one = 'partial_mock_one' partial_mock_two = 'partial_mock_two' partial_mock_one.expects(:first) partial_mock_one.expects(:second) partial_mock_two.expects(:third) partial_mock_one.first partial_mock_one.second partial_mock_two.third end assert_passed(test_result) end def test_should_fail_if_all_expectations_are_not_satisfied test_result = run_as_test do partial_mock_one = 'partial_mock_one' partial_mock_two = 'partial_mock_two' partial_mock_one.expects(:first) partial_mock_one.expects(:second) partial_mock_two.expects(:third) partial_mock_one.first partial_mock_two.third end assert_failed(test_result) end end mocha-2.4.2/test/acceptance/positional_and_keyword_has_inspect_test.rb000066400000000000000000000131051464615054400263770ustar00rootroot00000000000000class PositionalAndKeywordHashInspectTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_single_hash_parameters_in_invocation_and_expectation_print_correctly test_result = run_as_test do mock = mock('mock') mock.expects(:method).with({ foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end assert_equal [ 'unexpected invocation: #.method({:key => 42})', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method({:foo => 42})' ], test_result.failure_message_lines end def test_unexpected_keyword_arguments_in_invocation_and_expectation_print_correctly test_result = run_as_test do mock = mock('mock') mock.expects(:method).with(foo: 42) mock.method(key: 42) end if Mocha::RUBY_V27_PLUS assert_equal [ 'unexpected invocation: #.method(key: 42)', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(foo: 42)' ], test_result.failure_message_lines else assert_equal [ 'unexpected invocation: #.method({:key => 42})', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method({:foo => 42})' ], test_result.failure_message_lines end end def test_last_hash_parameters_in_invocation_and_expectation_print_correctly test_result = run_as_test do mock = mock('mock') mock.expects(:method).with(1, { foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end assert_equal [ 'unexpected invocation: #.method(1, {:key => 42})', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(1, {:foo => 42})' ], test_result.failure_message_lines end def test_unexpected_keyword_arguments_with_other_positionals_in_invocation_and_expectation_print_correctly test_result = run_as_test do mock = mock('mock') mock.expects(:method).with(1, foo: 42) mock.method(1, key: 42) end if Mocha::RUBY_V27_PLUS assert_equal [ 'unexpected invocation: #.method(1, key: 42)', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(1, foo: 42)' ], test_result.failure_message_lines else assert_equal [ 'unexpected invocation: #.method(1, {:key => 42})', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(1, {:foo => 42})' ], test_result.failure_message_lines end end if Mocha::RUBY_V27_PLUS def test_single_hash_parameters_in_invocation_and_expectation_print_correctly_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock('mock') mock.expects(:method).with({ foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end end assert_equal [ 'unexpected invocation: #.method({:key => 42})', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method({:foo => 42})' ], test_result.failure_message_lines end def test_unexpected_keyword_arguments_in_invocation_and_expectation_print_correctly_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock('mock') mock.expects(:method).with(foo: 42) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method(key: 42) end end assert_equal [ 'unexpected invocation: #.method(key: 42)', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(foo: 42)' ], test_result.failure_message_lines end def test_last_hash_parameters_in_invocation_and_expectation_print_correctly_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock('mock') mock.expects(:method).with(1, { foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters end end assert_equal [ 'unexpected invocation: #.method(1, {:key => 42})', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(1, {:foo => 42})' ], test_result.failure_message_lines end def test_unexpected_keyword_arguments_with_other_positionals_in_invocation_and_expectation_print_correctly_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock('mock') mock.expects(:method).with(1, foo: 42) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method(1, key: 42) end end assert_equal [ 'unexpected invocation: #.method(1, key: 42)', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.method(1, foo: 42)' ], test_result.failure_message_lines end end end mocha-2.4.2/test/acceptance/prepend_test.rb000066400000000000000000000033661464615054400207150ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/ruby_version' class PrependTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end module Mod1 def my_method super + ' World' end end module Mod2 def my_method super + ' Wide' end end class Klass1 prepend Mod1 prepend Mod2 def my_method 'Hello' end end class Klass2 class << self prepend Mod1 prepend Mod2 def my_method 'Hello' end end end def test_stubbing_any_instance_with_multiple_prepended_methods assert_snapshot_unchanged(Klass1) do test_result = run_as_test do Klass1.any_instance.stubs(:my_method).returns('Bye World') assert_equal 'Bye World', Klass1.new.my_method end assert_passed(test_result) end assert_equal 'Hello World Wide', Klass1.new.my_method end def test_stubbing_instance_with_multiple_prepended_methods object = Klass1.new assert_snapshot_unchanged(object) do test_result = run_as_test do object.stubs(:my_method).returns('Bye World') assert_equal 'Bye World', object.my_method assert_equal 'Hello World Wide', Klass1.new.my_method end assert_passed(test_result) end assert_equal 'Hello World Wide', object.my_method end def test_stubbing_a_prepended_class_method assert_snapshot_unchanged(Klass2) do test_result = run_as_test do Klass2.stubs(:my_method).returns('Bye World') assert_equal 'Bye World', Klass2.my_method end assert_passed(test_result) end assert_equal 'Hello World Wide', Klass2.my_method end end mocha-2.4.2/test/acceptance/prevent_use_of_mocha_outside_test_test.rb000066400000000000000000000051251464615054400262400ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/not_initialized_error' class PreventUseOfMochaOutsideTestTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test mocha_teardown end def teardown teardown_acceptance_test end def test_should_raise_exception_when_mock_called_outside_test assert_raises(Mocha::NotInitializedError) { mock('object') } end def test_should_raise_exception_when_stub_called_outside_test assert_raises(Mocha::NotInitializedError) { stub('object') } end def test_should_raise_exception_when_stub_everything_called_outside_test assert_raises(Mocha::NotInitializedError) { stub_everything('object') } end def test_should_raise_exception_when_states_called_outside_test assert_raises(Mocha::NotInitializedError) { states('state-machine') } end def test_should_raise_exception_when_expects_called_on_instance_outside_test instance = Class.new.new assert_raises(Mocha::NotInitializedError) { instance.expects(:expected_method) } end def test_should_raise_exception_when_expects_called_on_class_outside_test klass = Class.new assert_raises(Mocha::NotInitializedError) { klass.expects(:expected_method) } end def test_should_raise_exception_when_expects_called_on_any_instance_outside_test klass = Class.new assert_raises(Mocha::NotInitializedError) { klass.any_instance.expects(:expected_method) } end def test_should_raise_exception_when_stubs_called_on_instance_outside_test instance = Class.new.new assert_raises(Mocha::NotInitializedError) { instance.stubs(:expected_method) } end def test_should_raise_exception_when_stubs_called_on_class_outside_test klass = Class.new assert_raises(Mocha::NotInitializedError) { klass.stubs(:expected_method) } end def test_should_raise_exception_when_stubs_called_on_any_instance_outside_test klass = Class.new assert_raises(Mocha::NotInitializedError) { klass.any_instance.stubs(:expected_method) } end def test_should_raise_exception_when_unstub_called_on_instance_outside_test instance = Class.new.new assert_raises(Mocha::NotInitializedError) { instance.unstub(:expected_method) } end def test_should_raise_exception_when_unstub_called_on_class_outside_test klass = Class.new assert_raises(Mocha::NotInitializedError) { klass.unstub(:expected_method) } end def test_should_raise_exception_when_unstub_called_on_any_instance_outside_test klass = Class.new assert_raises(Mocha::NotInitializedError) { klass.any_instance.unstub(:expected_method) } end end mocha-2.4.2/test/acceptance/raise_exception_test.rb000066400000000000000000000020101464615054400224220ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class RaiseExceptionTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_raise_exception exception_class = Class.new(StandardError) test_result = run_as_test do foo = stub('foo') foo.stubs(:bar).raises(exception_class, 'my-message') exception = assert_raises(exception_class) { foo.bar } assert_equal 'my-message', exception.message end assert_passed(test_result) end def test_should_raise_two_different_exceptions exception_one_class = Class.new(StandardError) exception_two_class = Class.new(StandardError) test_result = run_as_test do foo = stub('foo') foo.stubs(:bar).raises(exception_one_class).then.raises(exception_two_class) assert_raises(exception_one_class) { foo.bar } assert_raises(exception_two_class) { foo.bar } end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/responds_like_test.rb000066400000000000000000000263631464615054400221230ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class RespondsLikeTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end # mock def test_mock_does_not_respond_when_method_is_not_stubbed test_result = run_as_test do m = mock assert !m.respond_to?(:foo, false) assert !m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_raises_unexpected_invocation_exception_when_method_is_not_stubbed test_result = run_as_test do m = mock assert_raises(Minitest::Assertion) { m.foo } end assert_passed(test_result) end def test_mock_does_respond_when_method_is_stubbed test_result = run_as_test do m = mock m.stubs(:foo) assert m.respond_to?(:foo, false) assert m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_does_not_raise_exception_when_method_is_stubbed test_result = run_as_test do m = mock m.stubs(:foo) assert_nil m.foo end assert_passed(test_result) end # mock which responds like object with public method def test_mock_which_responds_like_object_with_public_method_does_respond_when_method_is_not_stubbed object = Class.new do def foo; end public :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert m.respond_to?(:foo, false) assert m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_which_responds_like_object_with_public_method_raises_unexpected_invocation_exception_when_method_is_not_stubbed object = Class.new do def foo; end public :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert_raises(Minitest::Assertion) { m.foo } end assert_passed(test_result) end def test_mock_which_responds_like_object_with_public_method_raises_no_method_error_when_another_method_is_invoked object = Class.new do def foo; end public :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert_raises(NoMethodError) { m.bar } end assert_passed(test_result) end def test_mock_which_responds_like_object_with_public_method_does_respond_when_method_is_stubbed object = Class.new do def foo; end public :foo end.new test_result = run_as_test do m = mock.responds_like(object) m.stubs(:foo) assert m.respond_to?(:foo, false) assert m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_which_responds_like_object_with_public_method_does_not_raise_exception_when_method_is_stubbed object = Class.new do def foo; end public :foo end.new test_result = run_as_test do m = mock.responds_like(object) m.stubs(:foo) assert_nil m.foo end assert_passed(test_result) end # mock which responds like object with protected method def test_mock_which_responds_like_object_with_protected_method_does_not_respond_when_method_is_not_stubbed object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert !m.respond_to?(:foo, false) assert !m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_which_responds_like_object_with_protected_method_raises_no_method_error_when_method_is_not_stubbed object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert_raises(NoMethodError) { m.foo } # vs Minitest::Assertion for public method end assert_passed(test_result) end def test_mock_which_responds_like_object_with_protected_method_raises_no_method_error_when_another_method_is_invoked object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert_raises(NoMethodError) { m.bar } end assert_passed(test_result) end def test_mock_which_responds_like_object_with_protected_method_does_not_respond_when_method_is_stubbed object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do m = mock.responds_like(object) m.stubs(:foo) assert !m.respond_to?(:foo, false) assert !m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_which_responds_like_object_with_protected_method_raises_no_method_error_when_method_is_stubbed object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do m = mock.responds_like(object) m.stubs(:foo) assert_raises(NoMethodError) { m.foo } # vs no exception for public method end assert_passed(test_result) end # mock which responds like object with private method def test_mock_which_responds_like_object_with_private_method_does_not_respond_when_method_is_not_stubbed object = Class.new do def foo; end private :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert !m.respond_to?(:foo, false) assert !m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_which_responds_like_object_with_private_method_raises_no_method_error_when_method_is_not_stubbed object = Class.new do def foo; end private :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert_raises(NoMethodError) { m.foo } # vs Minitest::Assertion for public method end assert_passed(test_result) end def test_mock_which_responds_like_object_with_private_method_raises_no_method_error_when_another_method_is_invoked object = Class.new do def foo; end private :foo end.new test_result = run_as_test do m = mock.responds_like(object) assert_raises(NoMethodError) { m.bar } end assert_passed(test_result) end def test_mock_which_responds_like_object_with_private_method_does_not_respond_when_method_is_stubbed object = Class.new do def foo; end private :foo end.new test_result = run_as_test do m = mock.responds_like(object) m.stubs(:foo) assert !m.respond_to?(:foo, false) assert !m.respond_to?(:foo, true) end assert_passed(test_result) end def test_mock_which_responds_like_object_with_private_method_raises_no_method_error_when_method_is_stubbed object = Class.new do def foo; end private :foo end.new test_result = run_as_test do m = mock.responds_like(object) m.stubs(:foo) assert_raises(NoMethodError) { m.foo } # vs no exception for public method end assert_passed(test_result) end # object with public method def test_object_with_public_method_does_respond_when_method_is_not_stubbed object = Class.new do def foo; end public :foo end.new test_result = run_as_test do assert object.respond_to?(:foo, false) assert object.respond_to?(:foo, true) end assert_passed(test_result) end def test_object_with_public_method_invokes_original_method_when_method_is_not_stubbed object = Class.new do def foo 'original' end public :foo end.new test_result = run_as_test do assert_equal 'original', object.foo end assert_passed(test_result) end def test_object_with_public_method_does_respond_when_method_is_stubbed object = Class.new do def foo; end public :foo end.new test_result = run_as_test do object.stubs(:foo) assert object.respond_to?(:foo, false) assert object.respond_to?(:foo, true) end assert_passed(test_result) end def test_object_with_public_method_invokes_stubbed_method_when_method_is_stubbed object = Class.new do def foo; end public :foo end.new test_result = run_as_test do object.stubs(:foo).returns('stubbed') assert_equal 'stubbed', object.foo end assert_passed(test_result) end # object with protected method def test_object_with_protected_method_invokes_stubbed_method_when_method_is_stubbed object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do object.stubs(:foo).returns('stubbed') e = assert_raises(NoMethodError) { object.foo } assert_match(/^protected method/, e.message) assert_equal 'stubbed', object.send(:foo) end assert_passed(test_result) end def test_object_with_protected_method_does_respond_privately_when_method_is_not_stubbed object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do assert !object.respond_to?(:foo, false) assert object.respond_to?(:foo, true) end assert_passed(test_result) end def test_object_with_protected_method_invokes_original_method_when_method_is_not_stubbed object = Class.new do def foo 'original' end protected :foo end.new test_result = run_as_test do e = assert_raises(NoMethodError) { object.foo } assert_match(/^protected method/, e.message) assert_equal 'original', object.send(:foo) end assert_passed(test_result) end def test_object_with_protected_method_does_respond_privately_when_method_is_stubbed object = Class.new do def foo; end protected :foo end.new test_result = run_as_test do object.stubs(:foo) assert !object.respond_to?(:foo, false) assert object.respond_to?(:foo, true) end assert_passed(test_result) end # object with private method def test_object_with_private_method_does_respond_privately_when_method_is_not_stubbed object = Class.new do def foo; end private :foo end.new test_result = run_as_test do assert !object.respond_to?(:foo, false) assert object.respond_to?(:foo, true) end assert_passed(test_result) end def test_object_with_private_method_invokes_original_method_when_method_is_not_stubbed object = Class.new do def foo 'original' end private :foo end.new test_result = run_as_test do e = assert_raises(NoMethodError) { object.foo } assert_match(/^private method/, e.message) assert_equal 'original', object.send(:foo) end assert_passed(test_result) end def test_object_with_private_method_does_respond_privately_when_method_is_stubbed object = Class.new do def foo; end private :foo end.new test_result = run_as_test do object.stubs(:foo) assert !object.respond_to?(:foo, false) assert object.respond_to?(:foo, true) end assert_passed(test_result) end def test_object_with_private_method_invokes_stubbed_method_when_method_is_stubbed object = Class.new do def foo; end private :foo end.new test_result = run_as_test do object.stubs(:foo).returns('stubbed') e = assert_raises(NoMethodError) { object.foo } assert_match(/^private method/, e.message) assert_equal 'stubbed', object.send(:foo) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/return_value_test.rb000066400000000000000000000024161464615054400217660ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class ReturnValueTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_build_mock_and_explicitly_add_an_expectation_with_a_return_value test_result = run_as_test do foo = mock('foo') foo.expects(:bar).returns('bar') assert_equal 'bar', foo.bar end assert_passed(test_result) end def test_should_build_mock_incorporating_two_expectations_with_return_values test_result = run_as_test do foo = mock('foo', bar: 'bar', baz: 'baz') assert_equal 'bar', foo.bar assert_equal 'baz', foo.baz end assert_passed(test_result) end def test_should_build_stub_and_explicitly_add_an_expectation_with_a_return_value test_result = run_as_test do foo = stub('foo') foo.stubs(:bar).returns('bar') assert_equal 'bar', foo.bar end assert_passed(test_result) end def test_should_build_stub_incorporating_two_expectations_with_return_values test_result = run_as_test do foo = stub('foo', bar: 'bar', baz: 'baz') assert_equal 'bar', foo.bar assert_equal 'baz', foo.baz end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/sequence_block_test.rb000066400000000000000000000102651464615054400222360ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class SequenceBlockTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_constrain_invocations_to_occur_in_expected_order test_result = run_as_test do mock = mock() sequence('one') do mock.expects(:first) mock.expects(:second) end mock.second mock.first end assert_failed(test_result) assert_match 'second() invoked out of order', test_result.failures.first.message end def test_should_allow_invocations_in_sequence test_result = run_as_test do mock = mock() sequence('one') do mock.expects(:first) mock.expects(:second) end mock.first mock.second end assert_passed(test_result) end def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_different_mocks test_result = run_as_test do mock_one = mock('1') mock_two = mock('2') sequence('one') do mock_one.expects(:first) mock_two.expects(:second) end mock_two.second mock_one.first end assert_failed(test_result) end def test_should_allow_invocations_in_sequence_even_if_expected_on_different_mocks test_result = run_as_test do mock_one = mock('1') mock_two = mock('2') sequence('one') do mock_one.expects(:first) mock_two.expects(:second) end mock_one.first mock_two.second end assert_passed(test_result) end def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_partial_mocks test_result = run_as_test do partial_mock_one = '1' partial_mock_two = '2' sequence('one') do partial_mock_one.expects(:first) partial_mock_two.expects(:second) end partial_mock_two.second partial_mock_one.first end assert_failed(test_result) assert_match 'second() invoked out of order', test_result.failures.first.message end def test_should_allow_invocations_in_sequence_even_if_expected_on_partial_mocks test_result = run_as_test do partial_mock_one = '1' partial_mock_two = '2' sequence('one') do partial_mock_one.expects(:first) partial_mock_two.expects(:second) end partial_mock_one.first partial_mock_two.second end assert_passed(test_result) end def test_should_allow_stub_expectations_to_be_skipped_in_sequence test_result = run_as_test do mock = mock() sequence('one') do mock.expects(:first) mock.stubs(:second) mock.expects(:third) end mock.first mock.third end assert_passed(test_result) end def test_should_regard_nested_sequences_as_independent_of_each_other test_result = run_as_test do mock = mock() sequence('one') do mock.expects(:first) mock.expects(:second) sequence('two') do mock.expects(:third) mock.expects(:fourth) end end mock.first mock.third mock.second mock.fourth end assert_passed(test_result) end def test_should_include_sequence_in_failure_message test_result = run_as_test do mock = mock() sequence('one') do mock.expects(:first) mock.expects(:second) end mock.second mock.first end assert_failed(test_result) assert_match Regexp.new(%(in sequence "one")), test_result.failures.first.message end def test_should_allow_expectations_to_be_in_more_than_one_sequence test_result = run_as_test do mock = mock() sequence_one = sequence('one') mock.expects(:first).in_sequence(sequence_one) sequence('two') do mock.expects(:second) mock.expects(:third).in_sequence(sequence_one) end mock.first mock.third mock.second end assert_failed(test_result) assert_match Regexp.new(%(in sequence "one")), test_result.failures.first.message assert_match Regexp.new(%(in sequence "two")), test_result.failures.first.message end end mocha-2.4.2/test/acceptance/sequence_test.rb000066400000000000000000000124101464615054400210560ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class SequenceTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_constrain_invocations_to_occur_in_expected_order test_result = run_as_test do mock = mock() sequence = sequence('one') mock.expects(:first).in_sequence(sequence) mock.expects(:second).in_sequence(sequence) mock.second mock.first end assert_failed(test_result) assert_match 'second() invoked out of order', test_result.failures.first.message end def test_should_allow_invocations_in_sequence test_result = run_as_test do mock = mock() sequence = sequence('one') mock.expects(:first).in_sequence(sequence) mock.expects(:second).in_sequence(sequence) mock.first mock.second end assert_passed(test_result) end def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_different_mocks test_result = run_as_test do mock_one = mock('1') mock_two = mock('2') sequence = sequence('one') mock_one.expects(:first).in_sequence(sequence) mock_two.expects(:second).in_sequence(sequence) mock_two.second mock_one.first end assert_failed(test_result) end def test_should_allow_invocations_in_sequence_even_if_expected_on_different_mocks test_result = run_as_test do mock_one = mock('1') mock_two = mock('2') sequence = sequence('one') mock_one.expects(:first).in_sequence(sequence) mock_two.expects(:second).in_sequence(sequence) mock_one.first mock_two.second end assert_passed(test_result) end def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_partial_mocks test_result = run_as_test do partial_mock_one = '1' partial_mock_two = '2' sequence = sequence('one') partial_mock_one.expects(:first).in_sequence(sequence) partial_mock_two.expects(:second).in_sequence(sequence) partial_mock_two.second partial_mock_one.first end assert_failed(test_result) assert_match 'second() invoked out of order', test_result.failures.first.message end def test_should_allow_invocations_in_sequence_even_if_expected_on_partial_mocks test_result = run_as_test do partial_mock_one = '1' partial_mock_two = '2' sequence = sequence('one') partial_mock_one.expects(:first).in_sequence(sequence) partial_mock_two.expects(:second).in_sequence(sequence) partial_mock_one.first partial_mock_two.second end assert_passed(test_result) end def test_should_allow_stub_expectations_to_be_skipped_in_sequence test_result = run_as_test do mock = mock() sequence = sequence('one') mock.expects(:first).in_sequence(sequence) mock.stubs(:second).in_sequence(sequence) mock.expects(:third).in_sequence(sequence) mock.first mock.third end assert_passed(test_result) end def test_should_regard_sequences_as_independent_of_each_other test_result = run_as_test do mock = mock() sequence_one = sequence('one') sequence_two = sequence('two') mock.expects(:first).in_sequence(sequence_one) mock.expects(:second).in_sequence(sequence_one) mock.expects(:third).in_sequence(sequence_two) mock.expects(:fourth).in_sequence(sequence_two) mock.first mock.third mock.second mock.fourth end assert_passed(test_result) end def test_should_include_sequence_in_failure_message test_result = run_as_test do mock = mock() sequence = sequence('one') mock.expects(:first).in_sequence(sequence) mock.expects(:second).in_sequence(sequence) mock.second mock.first end assert_failed(test_result) assert_match Regexp.new(%(in sequence "one")), test_result.failures.first.message end def test_should_allow_expectations_to_be_in_more_than_one_sequence test_result = run_as_test do mock = mock() sequence_one = sequence('one') sequence_two = sequence('two') mock.expects(:first).in_sequence(sequence_one) mock.expects(:second).in_sequence(sequence_two) mock.expects(:third).in_sequence(sequence_one).in_sequence(sequence_two) mock.first mock.third mock.second end assert_failed(test_result) assert_match Regexp.new(%(in sequence "one")), test_result.failures.first.message assert_match Regexp.new(%(in sequence "two")), test_result.failures.first.message end def test_should_have_shortcut_for_expectations_to_be_in_more_than_one_sequence test_result = run_as_test do mock = mock() sequence_one = sequence('one') sequence_two = sequence('two') mock.expects(:first).in_sequence(sequence_one) mock.expects(:second).in_sequence(sequence_two) mock.expects(:third).in_sequence(sequence_one, sequence_two) mock.first mock.third mock.second end assert_failed(test_result) assert_match Regexp.new(%(in sequence "one")), test_result.failures.first.message assert_match Regexp.new(%(in sequence "two")), test_result.failures.first.message end end mocha-2.4.2/test/acceptance/states_test.rb000066400000000000000000000031241464615054400205530ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StatesTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_constrain_expectations_to_occur_within_a_given_state test_result = run_as_test do mock = mock() readiness = states('readiness') mock.stubs(:first).when(readiness.is('ready')) mock.stubs(:second).then(readiness.is('ready')) mock.first end assert_failed(test_result) end def test_should_allow_expectations_to_occur_in_correct_state test_result = run_as_test do mock = mock() readiness = states('readiness') mock.stubs(:first).when(readiness.is('ready')) mock.stubs(:second).then(readiness.is('ready')) mock.second mock.first end assert_passed(test_result) end def test_should_be_able_to_start_in_a_specific_state test_result = run_as_test do mock = mock() readiness = states('readiness') mock.stubs(:first).when(readiness.is('ready')) readiness.starts_as('ready') mock.first end assert_passed(test_result) end def test_should_switch_state_when_method_raises_an_exception test_result = run_as_test do mock = mock() readiness = states('readiness') mock.expects(:first).raises.then(readiness.is('ready')) mock.expects(:second).when(readiness.is('ready')) begin mock.first rescue StandardError nil end mock.second end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb000066400000000000000000000034271464615054400307440ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubAnyInstanceMethodDefinedOnSuperclassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_method_and_leave_it_unchanged_after_test superklass = Class.new do def my_superclass_method :original_return_value end public :my_superclass_method end klass = Class.new(superklass) instance = klass.new assert_snapshot_unchanged(instance) do test_result = run_as_test do superklass.any_instance.stubs(:my_superclass_method).returns(:new_return_value) assert_equal :new_return_value, instance.my_superclass_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_superclass_method end def test_expect_method_on_any_instance_of_superclass_even_if_preceded_by_test_expecting_method_on_any_instance_of_subclass superklass = Class.new do def self.inspect 'superklass' end def my_instance_method; end end klass = Class.new(superklass) do def self.inspect 'klass' end def my_instance_method; end end test_result = run_as_tests( test_1: lambda { klass.any_instance.expects(:my_instance_method) klass.new.my_instance_method }, test_2: lambda { superklass.any_instance.expects(:my_instance_method) } ) assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.my_instance_method(any_parameters)' ], test_result.failure_message_lines end end mocha-2.4.2/test/acceptance/stub_any_instance_method_test.rb000066400000000000000000000210321464615054400243160ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubAnyInstanceMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_within_test klass = Class.new do def my_instance_method :original_return_value end end instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility instance, :my_instance_method, :public assert_equal :new_return_value, instance.my_instance_method end assert_passed(test_result) end def test_should_leave_stubbed_public_method_unchanged_after_test klass = Class.new do def my_instance_method :original_return_value end public :my_instance_method def self.public(*args); end end instance = klass.new run_as_test do klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) end assert(instance.public_methods(false).any? { |m| m.to_s == 'my_instance_method' }) assert_equal :original_return_value, instance.my_instance_method end def test_should_leave_stubbed_public_method_unchanged_after_test_when_it_was_originally_private_in_owning_module module_with_private_method = Module.new do def my_included_method :original_return_value end private :my_included_method end klass = Class.new do include module_with_private_method public :my_included_method end instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:my_included_method).returns(:new_return_value) assert_equal :new_return_value, instance.my_included_method end assert_passed(test_result) assert_equal :original_return_value, instance.my_included_method end def test_should_leave_stubbed_protected_method_unchanged_after_test klass = Class.new do def my_instance_method :original_return_value end protected :my_instance_method def self.protected(*args); end def my_unprotected_instance_method my_instance_method end end instance = klass.new run_as_test do klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) end assert(instance.protected_methods(false).any? { |m| m.to_s == 'my_instance_method' }) assert_equal :original_return_value, instance.my_unprotected_instance_method end def test_should_stub_protected_method_within_test klass = Class.new do def my_instance_method :original_return_value end protected :my_instance_method def self.protected(*args); end def my_unprotected_instance_method my_instance_method end end instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility instance, :my_instance_method, :protected end assert_passed(test_result) end def test_should_leave_stubbed_private_method_unchanged_after_test klass = Class.new do def my_instance_method :original_return_value end private :my_instance_method def self.private(*args); end end instance = klass.new run_as_test do klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) end assert(instance.private_methods(false).any? { |m| m.to_s == 'my_instance_method' }) assert_equal :original_return_value, instance.send(:my_instance_method) end def test_should_stub_private_method_within_test klass = Class.new do def my_instance_method :original_return_value end private :my_instance_method def self.private(*args); end end instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility instance, :my_instance_method, :private end assert_passed(test_result) end def test_should_reset_expectations_after_test klass = Class.new do def my_instance_method :original_return_value end end run_as_test do klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) end assert_equal 0, klass.any_instance.mocha.__expectations__.length end def test_should_be_able_to_stub_a_public_superclass_method superklass = Class.new do def my_superclass_method :original_return_value end public :my_superclass_method end klass = Class.new(superklass) instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:my_superclass_method).returns(:new_return_value) assert_method_visibility instance, :my_superclass_method, :public assert_equal :new_return_value, instance.my_superclass_method end assert_passed(test_result) assert(instance.public_methods(true).any? { |m| m.to_s == 'my_superclass_method' }) assert(klass.public_methods(false).none? { |m| m.to_s == 'my_superclass_method' }) assert_equal :original_return_value, instance.my_superclass_method end def test_should_be_able_to_stub_a_protected_superclass_method superklass = Class.new do def my_superclass_method :original_return_value end protected :my_superclass_method end klass = Class.new(superklass) instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:my_superclass_method).returns(:new_return_value) assert_method_visibility instance, :my_superclass_method, :protected assert_equal :new_return_value, instance.send(:my_superclass_method) end assert_passed(test_result) assert(instance.protected_methods(true).any? { |m| m.to_s == 'my_superclass_method' }) assert(klass.protected_methods(false).none? { |m| m.to_s == 'my_superclass_method' }) assert_equal :original_return_value, instance.send(:my_superclass_method) end def test_should_be_able_to_stub_a_private_superclass_method superklass = Class.new do def my_superclass_method :original_return_value end private :my_superclass_method end klass = Class.new(superklass) instance = klass.new test_result = run_as_test do klass.any_instance.stubs(:my_superclass_method).returns(:new_return_value) assert_method_visibility instance, :my_superclass_method, :private assert_equal :new_return_value, instance.send(:my_superclass_method) end assert_passed(test_result) assert(instance.private_methods(true).any? { |m| m.to_s == 'my_superclass_method' }) assert(klass.private_methods(false).none? { |m| m.to_s == 'my_superclass_method' }) assert_equal :original_return_value, instance.send(:my_superclass_method) end def test_should_be_able_to_stub_method_if_ruby19_public_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_klass = Class.new do class << self def public_instance_methods(_include_superclass = true) [:my_instance_method] end end end test_result = run_as_test do ruby19_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_klass.new.my_instance_method end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_protected_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_klass = Class.new do class << self def protected_instance_methods(_include_superclass = true) [:my_instance_method] end end end test_result = run_as_test do ruby19_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_klass.new.send(:my_instance_method) end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_private_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_klass = Class.new do class << self def private_instance_methods(_include_superclass = true) [:my_instance_method] end end end test_result = run_as_test do ruby19_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_klass.new.send(:my_instance_method) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb000066400000000000000000000035341464615054400336570ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubClassMethodDefinedOnActiveRecordAssociationProxyTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_be_able_to_stub_method_if_ruby19_public_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_klass = Class.new do class << self def public_methods(_include_superclass = true) [:my_class_method] end end end test_result = run_as_test do ruby19_klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_klass.my_class_method end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_protected_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_klass = Class.new do class << self def protected_methods(_include_superclass = true) [:my_class_method] end end end test_result = run_as_test do ruby19_klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_klass.my_class_method end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_private_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_klass = Class.new do class << self def private_methods(_include_superclass = true) [:my_class_method] end end end test_result = run_as_test do ruby19_klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_klass.my_class_method end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stub_class_method_defined_on_class_test.rb000066400000000000000000000044771464615054400263250ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubClassMethodDefinedOnClassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end # rubocop:disable Lint/DuplicateMethods def test_should_stub_public_method_and_leave_it_unchanged_after_test klass = Class.new do class << self def my_class_method :original_return_value end public :my_class_method def self.public(*args); end end end assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_method_visibility klass, :my_class_method, :public assert_equal :new_return_value, klass.my_class_method end assert_passed(test_result) end assert_equal :original_return_value, klass.my_class_method end def test_should_stub_protected_method_and_leave_it_unchanged_after_test klass = Class.new do class << self def my_class_method :original_return_value end protected :my_class_method def self.protected(*args); end end end assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_method_visibility klass, :my_class_method, :protected assert_equal :new_return_value, klass.send(:my_class_method) end assert_passed(test_result) end assert_equal :original_return_value, klass.send(:my_class_method) end def test_should_stub_private_method_and_leave_it_unchanged_after_test klass = Class.new do class << self def my_class_method :original_return_value end private :my_class_method def self.private(*args); end end end assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_method_visibility klass, :my_class_method, :private assert_equal :new_return_value, klass.send(:my_class_method) end assert_passed(test_result) end assert_equal :original_return_value, klass.send(:my_class_method) end # rubocop:enable Lint/DuplicateMethods end mocha-2.4.2/test/acceptance/stub_class_method_defined_on_module_test.rb000066400000000000000000000037241464615054400264770ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubClassMethodDefinedOnModuleTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_and_leave_it_unchanged_after_test mod = Module.new do def my_class_method :original_return_value end public :my_class_method end klass = Class.new do extend mod end assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, klass.my_class_method end assert_passed(test_result) end assert_equal :original_return_value, klass.my_class_method end def test_should_stub_protected_method_and_leave_it_unchanged_after_test mod = Module.new do def my_class_method :original_return_value end protected :my_class_method end klass = Class.new do extend mod end assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, klass.send(:my_class_method) end assert_passed(test_result) end assert_equal :original_return_value, klass.send(:my_class_method) end def test_should_stub_private_method_and_leave_it_unchanged_after_test mod = Module.new do def my_class_method :original_return_value end private :my_class_method end klass = Class.new do extend mod end assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, klass.send(:my_class_method) end assert_passed(test_result) end assert_equal :original_return_value, klass.send(:my_class_method) end end mocha-2.4.2/test/acceptance/stub_class_method_defined_on_superclass_test.rb000066400000000000000000000101311464615054400273640ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubClassMethodDefinedOnSuperclassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end # rubocop:disable Lint/DuplicateMethods def test_should_stub_public_method_on_child_class_and_leave_it_unchanged_after_test superklass = Class.new do class << self def my_class_method :original_return_value end public :my_class_method end end klass = Class.new(superklass) assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, klass.my_class_method end assert_passed(test_result) end assert_equal :original_return_value, klass.my_class_method end def test_should_stub_protected_method_on_child_class_and_leave_it_unchanged_after_test superklass = Class.new do class << self def my_class_method :original_return_value end protected :my_class_method end end klass = Class.new(superklass) assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, klass.send(:my_class_method) end assert_passed(test_result) end assert_equal :original_return_value, klass.send(:my_class_method) end def test_should_stub_private_method_on_child_class_and_leave_it_unchanged_after_test superklass = Class.new do class << self def my_class_method :original_return_value end private :my_class_method end end klass = Class.new(superklass) assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, klass.send(:my_class_method) end assert_passed(test_result) end assert_equal :original_return_value, klass.send(:my_class_method) end def test_should_stub_method_on_superclass_and_leave_it_unchanged_after_test superklass = Class.new do class << self def my_class_method :original_return_value end public :my_class_method end end klass = Class.new(superklass) assert_snapshot_unchanged(klass) do test_result = run_as_test do superklass.stubs(:my_class_method).returns(:new_return_value) assert_equal :new_return_value, klass.my_class_method end assert_passed(test_result) end assert_equal :original_return_value, klass.my_class_method end def test_stub_on_earliest_receiver_should_take_priority superklass = Class.new do class << self def my_class_method :original_return_value end end end klass = Class.new(superklass) test_result = run_as_test do klass.stubs(:my_class_method).returns(:klass_return_value) superklass.stubs(:my_class_method).returns(:superklass_return_value) assert_equal :klass_return_value, klass.my_class_method end assert_passed(test_result) end def test_expect_method_on_superclass_even_if_preceded_by_test_expecting_method_on_subclass superklass = Class.new do def self.inspect 'superklass' end def self.my_class_method; end end klass = Class.new(superklass) do def self.inspect 'klass' end def self.my_class_method; end end test_result = run_as_tests( test_1: lambda { klass.expects(:my_class_method) klass.my_class_method }, test_2: lambda { superklass.expects(:my_class_method) } ) assert_failed(test_result) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly once, invoked never: superklass.my_class_method(any_parameters)' ], test_result.failure_message_lines end # rubocop:enable Lint/DuplicateMethods end mocha-2.4.2/test/acceptance/stub_everything_test.rb000066400000000000000000000023251464615054400224730ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubEverythingTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_build_stub_and_explicitly_add_an_expectation test_result = run_as_test do foo = stub_everything foo.stubs(:bar) foo.bar foo.unexpected_invocation end assert_passed(test_result) end def test_should_build_named_stub_and_explicitly_add_an_expectation test_result = run_as_test do foo = stub_everything('foo') foo.stubs(:bar) foo.bar foo.unexpected_invocation end assert_passed(test_result) end def test_should_build_stub_incorporating_two_expectations test_result = run_as_test do foo = stub_everything(bar: 'bar', baz: 'baz') foo.bar foo.baz foo.unexpected_invocation end assert_passed(test_result) end def test_should_build_named_stub_incorporating_two_expectations test_result = run_as_test do foo = stub_everything('foo', bar: 'bar', baz: 'baz') foo.bar foo.baz foo.unexpected_invocation end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb000066400000000000000000000032531464615054400343540ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnActiveRecordAssociationProxyTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_be_able_to_stub_method_if_ruby19_public_methods_include_method_but_method_does_not_exist ruby19_instance = Class.new do def public_methods(_include_superclass = true) [:my_instance_method] end end.new test_result = run_as_test do ruby19_instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_instance.my_instance_method end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_protected_methods_include_method_but_method_does_not_exist ruby19_instance = Class.new do def protected_methods(_include_superclass = true) [:my_instance_method] end end.new test_result = run_as_test do ruby19_instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_instance.my_instance_method end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_private_methods_include_method_but_method_does_not_exist ruby19_instance = Class.new do def private_methods(_include_superclass = true) [:my_instance_method] end end.new test_result = run_as_test do ruby19_instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_instance.my_instance_method end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb000066400000000000000000000041331464615054400313150ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnClassAndAliasedTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_and_leave_it_unchanged_after_test instance = Class.new do def my_instance_method :original_return_value end public :my_instance_method alias_method :my_aliased_method, :my_instance_method end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_aliased_method).returns(:new_return_value) assert_equal :new_return_value, instance.my_aliased_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_aliased_method end def test_should_stub_protected_method_and_leave_it_unchanged_after_test instance = Class.new do def my_instance_method :original_return_value end protected :my_instance_method alias_method :my_aliased_method, :my_instance_method end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_aliased_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_aliased_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_aliased_method) end def test_should_stub_private_method_and_leave_it_unchanged_after_test instance = Class.new do def my_instance_method :original_return_value end private :my_instance_method alias_method :my_aliased_method, :my_instance_method end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_aliased_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_aliased_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_aliased_method) end end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_class_test.rb000066400000000000000000000042051464615054400270110ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnClassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_and_leave_it_unchanged_after_test instance = Class.new do def my_instance_method :original_return_value end public :my_instance_method end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility instance, :my_instance_method, :public assert_equal :new_return_value, instance.my_instance_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_instance_method end def test_should_stub_protected_method_and_leave_it_unchanged_after_test instance = Class.new do def my_instance_method :original_return_value end protected :my_instance_method end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility instance, :my_instance_method, :protected assert_equal :new_return_value, instance.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_instance_method) end def test_should_stub_private_method_and_leave_it_unchanged_after_test instance = Class.new do def my_instance_method :original_return_value end private :my_instance_method end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility instance, :my_instance_method, :private assert_equal :new_return_value, instance.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_instance_method) end end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb000066400000000000000000000104321464615054400305300ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnKernelModuleTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_and_leave_it_unchanged_after_test Kernel.module_eval do def my_instance_method :original_return_value end public :my_instance_method end instance = Class.new.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, instance.my_instance_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_instance_method ensure Kernel.module_eval { remove_method :my_instance_method } end def test_should_stub_protected_method_and_leave_it_unchanged_after_test Kernel.module_eval do def my_instance_method :original_return_value end protected :my_instance_method end instance = Class.new.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_instance_method) ensure Kernel.module_eval { remove_method :my_instance_method } end def test_should_stub_private_method_and_leave_it_unchanged_after_test Kernel.module_eval do def my_instance_method :original_return_value end private :my_instance_method end instance = Class.new.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_instance_method) ensure Kernel.module_eval { remove_method :my_instance_method } end def test_should_stub_public_module_method_and_leave_it_unchanged_after_test Kernel.module_eval do def my_instance_method :original_return_value end public :my_instance_method end mod = Module.new assert_snapshot_unchanged(mod) do test_result = run_as_test do mod.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility mod, :my_instance_method, :public assert_equal :new_return_value, mod.my_instance_method end assert_passed(test_result) end assert_equal :original_return_value, mod.my_instance_method ensure Kernel.module_eval { remove_method :my_instance_method } end def test_should_stub_protected_module_method_and_leave_it_unchanged_after_test Kernel.module_eval do def my_instance_method :original_return_value end protected :my_instance_method end mod = Module.new assert_snapshot_unchanged(mod) do test_result = run_as_test do mod.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility mod, :my_instance_method, :protected assert_equal :new_return_value, mod.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, mod.send(:my_instance_method) ensure Kernel.module_eval { remove_method :my_instance_method } end def test_should_stub_private_module_method_and_leave_it_unchanged_after_test Kernel.module_eval do def my_instance_method :original_return_value end private :my_instance_method end mod = Module.new assert_snapshot_unchanged(mod) do test_result = run_as_test do mod.stubs(:my_instance_method).returns(:new_return_value) assert_method_visibility mod, :my_instance_method, :private assert_equal :new_return_value, mod.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, mod.send(:my_instance_method) ensure Kernel.module_eval { remove_method :my_instance_method } end end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_module_test.rb000066400000000000000000000043701464615054400271740ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnModuleTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_and_leave_it_unchanged_after_test mod = Module.new do def my_module_method :original_return_value end public :my_module_method end instance = Class.new do include mod end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_module_method).returns(:new_return_value) assert_method_visibility instance, :my_module_method, :public assert_equal :new_return_value, instance.my_module_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_module_method end def test_should_stub_protected_method_and_leave_it_unchanged_after_test mod = Module.new do def my_module_method :original_return_value end protected :my_module_method end instance = Class.new do include mod end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_module_method).returns(:new_return_value) assert_method_visibility instance, :my_module_method, :protected assert_equal :new_return_value, instance.send(:my_module_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_module_method) end def test_should_stub_private_method_and_leave_it_unchanged_after_test mod = Module.new do def my_module_method :original_return_value end private :my_module_method end instance = Class.new do include mod end.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_module_method).returns(:new_return_value) assert_method_visibility instance, :my_module_method, :private assert_equal :new_return_value, instance.send(:my_module_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_module_method) end end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_object_class_test.rb000066400000000000000000000044231464615054400303410ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnObjectClassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end # rubocop:disable Lint/DuplicateMethods def test_should_stub_public_method_and_leave_it_unchanged_after_test Object.class_eval do def my_instance_method :original_return_value end public :my_instance_method end instance = Class.new.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, instance.my_instance_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_instance_method ensure Object.class_eval { remove_method :my_instance_method } end def test_should_stub_protected_method_and_leave_it_unchanged_after_test Object.class_eval do def my_instance_method :original_return_value end protected :my_instance_method end instance = Class.new.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_instance_method) ensure Object.class_eval { remove_method :my_instance_method } end def test_should_stub_private_method_and_leave_it_unchanged_after_test Object.class_eval do def my_instance_method :original_return_value end private :my_instance_method end instance = Class.new.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_instance_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_instance_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_instance_method) ensure Object.class_eval { remove_method :my_instance_method } end # rubocop:enable Lint/DuplicateMethods end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb000066400000000000000000000040221464615054400310700ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnSingletonClassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_and_leave_it_unchanged_after_test instance = Class.new.new class << instance def my_singleton_method :original_return_value end public :my_singleton_method end assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_singleton_method).returns(:stubbed_return_value) assert_equal :stubbed_return_value, instance.my_singleton_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_singleton_method end def test_should_stub_protected_method_and_leave_it_unchanged_after_test instance = Class.new.new class << instance def my_singleton_method :original_return_value end protected :my_singleton_method end assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_singleton_method).returns(:stubbed_return_value) assert_equal :stubbed_return_value, instance.send(:my_singleton_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_singleton_method) end def test_should_stub_private_method_and_leave_it_unchanged_after_test instance = Class.new.new class << instance def my_singleton_method :original_return_value end private :my_singleton_method end assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_singleton_method).returns(:stubbed_return_value) assert_equal :stubbed_return_value, instance.send(:my_singleton_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_singleton_method) end end mocha-2.4.2/test/acceptance/stub_instance_method_defined_on_superclass_test.rb000066400000000000000000000041671464615054400300770ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubInstanceMethodDefinedOnSuperclassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_public_method_and_leave_it_unchanged_after_test superklass = Class.new do def my_superclass_method :original_return_value end public :my_superclass_method end klass = Class.new(superklass) instance = klass.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_superclass_method).returns(:new_return_value) assert_equal :new_return_value, instance.my_superclass_method end assert_passed(test_result) end assert_equal :original_return_value, instance.my_superclass_method end def test_should_stub_protected_method_and_leave_it_unchanged_after_test superklass = Class.new do def my_superclass_method :original_return_value end protected :my_superclass_method end klass = Class.new(superklass) instance = klass.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_superclass_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_superclass_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_superclass_method) end def test_should_stub_private_method_and_leave_it_unchanged_after_test superklass = Class.new do def my_superclass_method :original_return_value end private :my_superclass_method end klass = Class.new(superklass) instance = klass.new assert_snapshot_unchanged(instance) do test_result = run_as_test do instance.stubs(:my_superclass_method).returns(:new_return_value) assert_equal :new_return_value, instance.send(:my_superclass_method) end assert_passed(test_result) end assert_equal :original_return_value, instance.send(:my_superclass_method) end end mocha-2.4.2/test/acceptance/stub_method_defined_on_module_and_aliased_test.rb000066400000000000000000000016461464615054400276170ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubMethodDefinedOnModuleAndAliasedTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_stubbing_class_method_defined_by_aliasing_module_instance_method mod = Module.new do def module_instance_method 'module-instance-method' end end klass = Class.new do extend mod class << self alias_method :aliased_module_instance_method, :module_instance_method end end assert_snapshot_unchanged(klass) do test_result = run_as_test do klass.stubs(:aliased_module_instance_method).returns('stubbed-aliased-module-instance-method') assert_equal 'stubbed-aliased-module-instance-method', klass.aliased_module_instance_method end assert_passed(test_result) end end end mocha-2.4.2/test/acceptance/stub_module_method_test.rb000066400000000000000000000112161464615054400231330ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubModuleMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end # rubocop:disable Lint/DuplicateMethods def test_should_stub_method_within_test mod = Module.new do def self.my_module_method :original_return_value end end test_result = run_as_test do mod.stubs(:my_module_method).returns(:new_return_value) assert_equal :new_return_value, mod.my_module_method end assert_passed(test_result) end def test_should_leave_stubbed_public_method_unchanged_after_test mod = Module.new do class << self def my_module_method :original_return_value end public :my_module_method end end run_as_test do mod.stubs(:my_module_method).returns(:new_return_value) end assert(mod.public_methods(false).any? { |m| m.to_s == 'my_module_method' }) assert_equal :original_return_value, mod.my_module_method end def test_should_leave_stubbed_protected_method_unchanged_after_test mod = Module.new do class << self def my_module_method :original_return_value end protected :my_module_method def my_unprotected_module_method my_module_method end end end run_as_test do mod.stubs(:my_module_method).returns(:new_return_value) end assert(mod.protected_methods(false).any? { |m| m.to_s == 'my_module_method' }) assert_equal :original_return_value, mod.my_unprotected_module_method end def test_should_leave_stubbed_private_method_unchanged_after_test mod = Module.new do class << self def my_module_method :original_return_value end private :my_module_method end end run_as_test do mod.stubs(:my_module_method).returns(:new_return_value) end assert(mod.private_methods(false).any? { |m| m.to_s == 'my_module_method' }) assert_equal :original_return_value, mod.send(:my_module_method) end def test_should_reset_expectations_after_test mod = Module.new do def self.my_module_method :original_return_value end end run_as_test do mod.stubs(:my_module_method) end assert_equal 0, mod.mocha.__expectations__.length end def test_should_be_able_to_stub_a_superclass_method supermod = Module.new do def self.my_superclass_method :original_return_value end end mod = Module.new do include supermod end test_result = run_as_test do mod.stubs(:my_superclass_method).returns(:new_return_value) assert_equal :new_return_value, mod.my_superclass_method end assert_passed(test_result) assert(supermod.public_methods.any? { |m| m.to_s == 'my_superclass_method' }) assert(mod.public_methods(false).none? { |m| m.to_s == 'my_superclass_method' }) assert_equal :original_return_value, supermod.my_superclass_method end def test_should_be_able_to_stub_method_if_ruby19_public_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_mod = Module.new do class << self def public_methods(_include_superclass = true) [:my_module_method] end end end test_result = run_as_test do ruby19_mod.stubs(:my_module_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_mod.my_module_method end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_protected_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_mod = Module.new do class << self def protected_methods(_include_superclass = true) [:my_module_method] end end end test_result = run_as_test do ruby19_mod.stubs(:my_module_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_mod.my_module_method end assert_passed(test_result) end def test_should_be_able_to_stub_method_if_ruby19_private_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy ruby19_mod = Module.new do class << self def private_methods(_include_superclass = true) [:my_module_method] end end end test_result = run_as_test do ruby19_mod.stubs(:my_module_method).returns(:new_return_value) assert_equal :new_return_value, ruby19_mod.my_module_method end assert_passed(test_result) end # rubocop:enable Lint/DuplicateMethods end mocha-2.4.2/test/acceptance/stub_test.rb000066400000000000000000000020371464615054400202270ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_build_stub_and_explicitly_add_an_expectation test_result = run_as_test do foo = stub foo.stubs(:bar) foo.bar end assert_passed(test_result) end def test_should_build_named_stub_and_explicitly_add_an_expectation test_result = run_as_test do foo = stub('foo') foo.stubs(:bar) foo.bar end assert_passed(test_result) end def test_should_build_stub_incorporating_two_expectations test_result = run_as_test do foo = stub(bar: 'bar', baz: 'baz') foo.bar foo.baz end assert_passed(test_result) end def test_should_build_named_stub_incorporating_two_expectations test_result = run_as_test do foo = stub('foo', bar: 'bar', baz: 'baz') foo.bar foo.baz end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubba_example_test.rb000066400000000000000000000045121464615054400222450ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class Widget def model 'original_model' end class << self def find(_options) [] end def create(_attributes) Widget.new end end end module Thingy def self.wotsit :hoojamaflip end end class StubbaExampleTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_stub_instance_method widget = Widget.new widget.expects(:model).returns('different_model') assert_equal 'different_model', widget.model end def test_should_stub_module_method should_stub_module_method end def test_should_stub_module_method_again should_stub_module_method end def test_should_stub_class_method should_stub_class_method end def test_should_stub_class_method_again should_stub_class_method end def test_should_stub_instance_method_on_any_instance_of_a_class should_stub_instance_method_on_any_instance_of_a_class end def test_should_stub_instance_method_on_any_instance_of_a_class_again should_stub_instance_method_on_any_instance_of_a_class end def test_should_stub_two_different_class_methods should_stub_two_different_class_methods end def test_should_stub_two_different_class_methods_again should_stub_two_different_class_methods end private def should_stub_module_method Thingy.expects(:wotsit).returns(:dooda) assert_equal :dooda, Thingy.wotsit end def should_stub_class_method widgets = [Widget.new] Widget.expects(:find).with(:all).returns(widgets) assert_equal widgets, Widget.find(:all) end def should_stub_two_different_class_methods found_widgets = [Widget.new] created_widget = Widget.new Widget.expects(:find).with(:all).returns(found_widgets) Widget.expects(:create).with(model: 'wombat').returns(created_widget) assert_equal found_widgets, Widget.find(:all) assert_equal created_widget, Widget.create(model: 'wombat') end def should_stub_instance_method_on_any_instance_of_a_class Widget.any_instance.expects(:model).at_least_once.returns('another_model') widget1 = Widget.new widget2 = Widget.new assert_equal 'another_model', widget1.model assert_equal 'another_model', widget2.model end end mocha-2.4.2/test/acceptance/stubba_test_result_test.rb000066400000000000000000000034121464615054400231650ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'execution_point' class StubbaTestResultTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_include_expectation_verification_in_assertion_count test_result = run_as_test do object = Class.new do def message; end end.new object.expects(:message) object.message end assert_equal 1, test_result.assertion_count end def test_should_include_assertions_in_assertion_count test_result = run_as_test do assert true end assert_equal 1, test_result.assertion_count end def test_should_not_include_stubbing_expectation_verification_in_assertion_count test_result = run_as_test do object = Class.new do def message; end end.new object.stubs(:message) object.message end assert_equal 0, test_result.assertion_count end def test_should_include_expectation_verification_failure_in_failure_count test_result = run_as_test do object = Class.new do def message; end end.new object.expects(:message) end assert_equal 1, test_result.failure_count end def test_should_include_assertion_failure_in_failure_count test_result = run_as_test do flunk end assert_equal 1, test_result.failure_count end def test_should_display_backtrace_indicating_line_number_where_failing_assertion_was_called execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; flunk end assert_equal 1, test_result.failure_count assert_equal execution_point, ExecutionPoint.new(test_result.failures[0].location) end end mocha-2.4.2/test/acceptance/stubbing_error_backtrace_test.rb000066400000000000000000000043531464615054400243020ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'execution_point' class StubbingErrorBacktraceTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_non_existent_method_was_made execution_point = nil object = Object.new Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } test_result = run_as_test do execution_point = ExecutionPoint.current; object.stubs(:non_existent_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_non_public_method_was_made execution_point = nil object = Class.new do def non_public_method; end private :non_public_method end.new Mocha.configure { |c| c.stubbing_non_public_method = :prevent } test_result = run_as_test do execution_point = ExecutionPoint.current; object.stubs(:non_public_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_method_on_non_mock_object_was_made execution_point = nil object = Object.new Mocha.configure { |c| c.stubbing_method_on_non_mock_object = :prevent } test_result = run_as_test do execution_point = ExecutionPoint.current; object.stubs(:any_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_display_backtrace_indicating_line_number_where_method_was_unnecessarily_stubbed execution_point = nil object = Object.new Mocha.configure { |c| c.stubbing_method_unnecessarily = :prevent } test_result = run_as_test do execution_point = ExecutionPoint.current; object.stubs(:unused_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end end mocha-2.4.2/test/acceptance/stubbing_frozen_object_test.rb000066400000000000000000000052031464615054400237760ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'execution_point' class StubbingFrozenObjectTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_fail_fast_if_attempting_to_stub_method_on_frozen_object object = Object.new object.freeze execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; object.stubs(:stubbed_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_fail_fast_if_attempting_to_expect_method_on_frozen_object object = Object.new object.freeze execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; object.expects(:stubbed_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_fail_fast_if_attempting_to_stub_method_on_frozen_class klass = Class.new klass.freeze execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; klass.stubs(:stubbed_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_fail_fast_if_attempting_to_expect_method_on_frozen_class klass = Class.new klass.freeze execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; klass.expects(:stubbed_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_fail_fast_if_attempting_to_stub_method_on_any_instance_of_frozen_class klass = Class.new klass.freeze execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; klass.any_instance.stubs(:stubbed_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end def test_should_fail_fast_if_attempting_to_expect_method_on_any_instance_of_frozen_class klass = Class.new klass.freeze execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; klass.any_instance.expects(:stubbed_method) end assert_errored(test_result) assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace) end end mocha-2.4.2/test/acceptance/stubbing_method_accepting_block_parameter_test.rb000066400000000000000000000026121464615054400276550ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubbingMethodAcceptingBlockParameterTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_stubbing_class_method_accepting_block_parameter_should_restore_original_method klass = Class.new do def self.my_class_method(&block) block.call end end test_result = run_as_test do klass.stubs(:my_class_method) end assert_passed(test_result) assert_equal :return_value, (klass.my_class_method { :return_value }) end def test_stubbing_instance_method_accepting_block_parameter_should_restore_original_method instance = Class.new do def my_instance_method yield end end.new test_result = run_as_test do instance.stubs(:my_instance_method) end assert_passed(test_result) assert_equal :return_value, (instance.my_instance_method { :return_value }) end def test_stubbing_any_instance_method_accepting_block_parameter_should_restore_original_method klass = Class.new do def my_instance_method yield end end test_result = run_as_test do klass.any_instance.stubs(:my_instance_method) end assert_passed(test_result) assert_equal :return_value, (klass.new.my_instance_method { :return_value }) end end mocha-2.4.2/test/acceptance/stubbing_method_unnecessarily_test.rb000066400000000000000000000040211464615054400253660ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingMethodUnnecessarilyTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_method_unnecessarily Mocha.configure { |c| c.stubbing_method_unnecessarily = :allow } test_result = run_as_test do mock = mock('mock') mock.stubs(:public_method) end assert_passed(test_result) assert !@logger.warnings.include?('stubbing method unnecessarily: #.public_method(any_parameters)') end def test_should_warn_when_stubbing_method_unnecessarily Mocha.configure { |c| c.stubbing_method_unnecessarily = :warn } test_result = run_as_test do mock = mock('mock') mock.stubs(:public_method) end assert_passed(test_result) assert @logger.warnings.include?('stubbing method unnecessarily: #.public_method(any_parameters)') end def test_should_prevent_stubbing_method_unnecessarily Mocha.configure { |c| c.stubbing_method_unnecessarily = :prevent } test_result = run_as_test do mock = mock('mock') mock.stubs(:public_method) end assert_errored(test_result) assert test_result.error_messages.include?('Mocha::StubbingError: stubbing method unnecessarily: #.public_method(any_parameters)') end def test_should_default_to_allow_stubbing_method_unnecessarily test_result = run_as_test do mock = mock('mock') mock.stubs(:public_method) end assert_passed(test_result) assert !@logger.warnings.include?('stubbing method unnecessarily: #.public_method(any_parameters)') end def test_should_allow_stubbing_method_when_stubbed_method_is_invoked Mocha.configure { |c| c.stubbing_method_unnecessarily = :prevent } test_result = run_as_test do mock = mock('mock') mock.stubs(:public_method) mock.public_method end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubbing_nil_test.rb000066400000000000000000000035341464615054400217340ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingNilTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end if RUBY_VERSION < '2.2.0' def test_should_allow_stubbing_method_on_nil Mocha.configure { |c| c.stubbing_method_on_nil = :allow } test_result = run_as_test do nil.stubs(:stubbed_method) end assert_passed(test_result) assert !@logger.warnings.include?('stubbing method on nil: nil.stubbed_method') end def test_should_warn_on_stubbing_method_on_nil Mocha.configure { |c| c.stubbing_method_on_nil = :warn } test_result = run_as_test do nil.stubs(:stubbed_method) end assert_passed(test_result) assert @logger.warnings.include?('stubbing method on nil: nil.stubbed_method') end def test_should_prevent_stubbing_method_on_nil Mocha.configure { |c| c.stubbing_method_on_nil = :prevent } test_result = run_as_test do nil.stubs(:stubbed_method) end assert_errored(test_result) assert test_result.error_messages.include?('Mocha::StubbingError: stubbing method on nil: nil.stubbed_method') end def test_should_default_to_prevent_stubbing_method_on_non_mock_object test_result = run_as_test do nil.stubs(:stubbed_method) end assert_errored(test_result) assert test_result.error_messages.include?('Mocha::StubbingError: stubbing method on nil: nil.stubbed_method') end def test_should_allow_stubbing_method_on_non_nil_object Mocha.configure { |c| c.stubbing_method_on_nil = :prevent } object = Object.new test_result = run_as_test do object.stubs(:stubbed_method) end assert_passed(test_result) end end end mocha-2.4.2/test/acceptance/stubbing_non_existent_any_instance_method_test.rb000066400000000000000000000122521464615054400277570ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingNonExistentAnyInstanceMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_non_existent_any_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :allow } klass = Class.new test_result = run_as_test do klass.any_instance.stubs(:non_existent_method) end assert !@logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method") assert_passed(test_result) end def test_should_warn_when_stubbing_non_existent_any_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :warn } klass = Class.new test_result = run_as_test do klass.any_instance.stubs(:non_existent_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method") end def test_should_prevent_stubbing_non_existent_any_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new test_result = run_as_test do klass.any_instance.stubs(:non_existent_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method") end def test_should_default_to_allow_stubbing_non_existent_any_instance_method klass = Class.new test_result = run_as_test do klass.any_instance.stubs(:non_existent_method) end assert !@logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method") assert_passed(test_result) end def test_should_allow_stubbing_existing_public_any_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def existing_public_method; end public :existing_public_method end test_result = run_as_test do klass.any_instance.stubs(:existing_public_method) end assert_passed(test_result) end def test_should_allow_stubbing_method_to_which_any_instance_responds Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def respond_to?(method, _include_all = false) (method == :method_to_which_instance_responds) end end test_result = run_as_test do klass.any_instance.stubs(:method_to_which_instance_responds) end assert_passed(test_result) end def test_should_default_to_allowing_stubbing_method_if_responds_to_depends_on_calling_initialize klass = Class.new do def initialize(attrs = {}) @attributes = attrs end def respond_to?(method, _include_all = false) @attributes.key?(method) ? @attributes[method] : super end end test_result = run_as_test do klass.any_instance.stubs(:foo) end assert_passed(test_result) end def test_should_allow_stubbing_existing_protected_any_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def existing_protected_method; end protected :existing_protected_method end test_result = run_as_test do klass.any_instance.stubs(:existing_protected_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_private_any_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def existing_private_method; end private :existing_private_method end test_result = run_as_test do klass.any_instance.stubs(:existing_private_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_public_any_instance_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do def existing_public_method; end public :existing_public_method end klass = Class.new(superklass) test_result = run_as_test do klass.any_instance.stubs(:existing_public_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_protected_any_instance_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do def existing_protected_method; end protected :existing_protected_method end klass = Class.new(superklass) test_result = run_as_test do klass.any_instance.stubs(:existing_protected_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_private_any_instance_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do def existing_private_method; end private :existing_private_method end klass = Class.new(superklass) test_result = run_as_test do klass.any_instance.stubs(:existing_private_method) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubbing_non_existent_class_method_test.rb000066400000000000000000000114041464615054400264070ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingNonExistentClassMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_non_existent_class_method Mocha.configure { |c| c.stubbing_non_existent_method = :allow } klass = Class.new test_result = run_as_test do klass.stubs(:non_existent_method) end assert !@logger.warnings.include?("stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method") assert_passed(test_result) end def test_should_warn_when_stubbing_non_existent_class_method Mocha.configure { |c| c.stubbing_non_existent_method = :warn } klass = Class.new test_result = run_as_test do klass.stubs(:non_existent_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method") end def test_should_prevent_stubbing_non_existent_class_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new test_result = run_as_test do klass.stubs(:non_existent_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method") end def test_should_default_to_allow_stubbing_non_existent_class_method klass = Class.new test_result = run_as_test do klass.stubs(:non_existent_method) end assert !@logger.warnings.include?("stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method") assert_passed(test_result) end # rubocop:disable Lint/DuplicateMethods def test_should_allow_stubbing_existing_public_class_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do class << self def existing_public_method; end public :existing_public_method end end test_result = run_as_test do klass.stubs(:existing_public_method) end assert_passed(test_result) end def test_should_allow_stubbing_method_to_which_class_responds Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do class << self def respond_to?(method, _include_all = false) (method == :method_to_which_class_responds) end end end test_result = run_as_test do klass.stubs(:method_to_which_class_responds) end assert_passed(test_result) end def test_should_allow_stubbing_existing_protected_class_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do class << self def existing_protected_method; end protected :existing_protected_method end end test_result = run_as_test do klass.stubs(:existing_protected_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_private_class_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do class << self def existing_private_method; end private :existing_private_method end end test_result = run_as_test do klass.stubs(:existing_private_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_public_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do class << self def existing_public_method; end public :existing_public_method end end klass = Class.new(superklass) test_result = run_as_test do klass.stubs(:existing_public_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_protected_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do class << self def existing_protected_method; end protected :existing_protected_method end end klass = Class.new(superklass) test_result = run_as_test do klass.stubs(:existing_protected_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_private_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do class << self def existing_private_method; end protected :existing_private_method end end klass = Class.new(superklass) test_result = run_as_test do klass.stubs(:existing_private_method) end assert_passed(test_result) end # rubocop:enable Lint/DuplicateMethods end mocha-2.4.2/test/acceptance/stubbing_non_existent_instance_method_test.rb000066400000000000000000000112751464615054400271140ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingNonExistentInstanceMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_non_existent_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :allow } instance = Class.new.new test_result = run_as_test do instance.stubs(:non_existent_method) end assert !@logger.warnings.include?("stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method") assert_passed(test_result) end def test_should_warn_when_stubbing_non_existent_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :warn } instance = Class.new.new test_result = run_as_test do instance.stubs(:non_existent_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method") end def test_should_prevent_stubbing_non_existent_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } instance = Class.new.new test_result = run_as_test do instance.stubs(:non_existent_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method") end def test_should_default_to_allow_stubbing_non_existent_instance_method instance = Class.new.new test_result = run_as_test do instance.stubs(:non_existent_method) end assert !@logger.warnings.include?("stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method") assert_passed(test_result) end def test_should_allow_stubbing_existing_public_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def existing_public_method; end public :existing_public_method end instance = klass.new test_result = run_as_test do instance.stubs(:existing_public_method) end assert_passed(test_result) end def test_should_allow_stubbing_method_to_which_instance_responds Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def respond_to?(method, _include_all = false) (method == :method_to_which_instance_responds) end end instance = klass.new test_result = run_as_test do instance.stubs(:method_to_which_instance_responds) end assert_passed(test_result) end def test_should_allow_stubbing_existing_protected_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def existing_protected_method; end protected :existing_protected_method end instance = klass.new test_result = run_as_test do instance.stubs(:existing_protected_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_private_instance_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do def existing_private_method; end private :existing_private_method end instance = klass.new test_result = run_as_test do instance.stubs(:existing_private_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_public_instance_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do def existing_public_method; end public :existing_public_method end instance = Class.new(superklass).new test_result = run_as_test do instance.stubs(:existing_public_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_protected_instance_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do def existing_protected_method; end protected :existing_protected_method end instance = Class.new(superklass).new test_result = run_as_test do instance.stubs(:existing_protected_method) end assert_passed(test_result) end def test_should_allow_stubbing_existing_private_instance_superclass_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } superklass = Class.new do def existing_private_method; end private :existing_private_method end instance = Class.new(superklass).new test_result = run_as_test do instance.stubs(:existing_private_method) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubbing_non_public_any_instance_method_test.rb000066400000000000000000000104311464615054400273670ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingNonPublicAnyInstanceMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_private_any_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :allow } klass = Class.new do def private_method; end private :private_method end test_result = run_as_test do klass.any_instance.stubs(:private_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method") end def test_should_allow_stubbing_protected_any_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :allow } klass = Class.new do def protected_method; end protected :protected_method end test_result = run_as_test do klass.any_instance.stubs(:protected_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method") end def test_should_warn_when_stubbing_private_any_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :warn } klass = Class.new do def private_method; end private :private_method end test_result = run_as_test do klass.any_instance.stubs(:private_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method") end def test_should_warn_when_stubbing_protected_any_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :warn } klass = Class.new do def protected_method; end protected :protected_method end test_result = run_as_test do klass.any_instance.stubs(:protected_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method") end def test_should_prevent_stubbing_private_any_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } klass = Class.new do def private_method; end private :private_method end test_result = run_as_test do klass.any_instance.stubs(:private_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method") end def test_should_prevent_stubbing_protected_any_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } klass = Class.new do def protected_method; end protected :protected_method end test_result = run_as_test do klass.any_instance.stubs(:protected_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method") end def test_should_default_to_allow_stubbing_private_any_instance_method klass = Class.new do def private_method; end private :private_method end test_result = run_as_test do klass.any_instance.stubs(:private_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method") end def test_should_default_to_allow_stubbing_protected_any_instance_method klass = Class.new do def protected_method; end protected :protected_method end test_result = run_as_test do klass.any_instance.stubs(:protected_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method") end def test_should_allow_stubbing_public_any_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } klass = Class.new do def public_method; end public :public_method end test_result = run_as_test do klass.any_instance.stubs(:public_method) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubbing_non_public_class_method_test.rb000066400000000000000000000114711464615054400260260ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingNonPublicClassMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end # rubocop:disable Lint/DuplicateMethods def test_should_allow_stubbing_private_class_method Mocha.configure { |c| c.stubbing_non_public_method = :allow } klass = Class.new do class << self def private_method; end private :private_method end end test_result = run_as_test do klass.stubs(:private_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.private_method") end def test_should_allow_stubbing_protected_class_method Mocha.configure { |c| c.stubbing_non_public_method = :allow } klass = Class.new do class << self def protected_method; end protected :protected_method end end test_result = run_as_test do klass.stubs(:protected_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.protected_method") end def test_should_warn_when_stubbing_private_class_method Mocha.configure { |c| c.stubbing_non_public_method = :warn } klass = Class.new do class << self def private_method; end private :private_method end end test_result = run_as_test do klass.stubs(:private_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.private_method") end def test_should_warn_when_stubbing_protected_class_method Mocha.configure { |c| c.stubbing_non_public_method = :warn } klass = Class.new do class << self def protected_method; end protected :protected_method end end test_result = run_as_test do klass.stubs(:protected_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.protected_method") end def test_should_prevent_stubbing_private_class_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } klass = Class.new do class << self def private_method; end private :private_method end end test_result = run_as_test do klass.stubs(:private_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.mocha_inspect}.private_method") end def test_should_prevent_stubbing_protected_class_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } klass = Class.new do class << self def protected_method; end protected :protected_method end end test_result = run_as_test do klass.stubs(:protected_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.mocha_inspect}.protected_method") end def test_should_default_to_allow_stubbing_private_class_method klass = Class.new do class << self def private_method; end private :private_method end end test_result = run_as_test do klass.stubs(:private_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.private_method") end def test_should_default_to_allow_stubbing_protected_class_method klass = Class.new do class << self def protected_method; end protected :protected_method end end test_result = run_as_test do klass.stubs(:protected_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.protected_method") end def test_should_allow_stubbing_public_class_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } klass = Class.new do class << self def public_method; end public :public_method end end test_result = run_as_test do klass.stubs(:public_method) end assert_passed(test_result) end # rubocop:enable Lint/DuplicateMethods def test_should_allow_stubbing_method_to_which_class_responds Mocha.configure { |c| c.stubbing_non_public_method = :prevent } klass = Class.new do class << self def respond_to?(method, _include_all = false) (method == :method_to_which_class_responds) end end end test_result = run_as_test do klass.stubs(:method_to_which_class_responds) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubbing_non_public_instance_method_test.rb000066400000000000000000000110631464615054400265220ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingNonPublicInstanceMethodTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_private_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :allow } instance = Class.new do def private_method; end private :private_method end.new test_result = run_as_test do instance.stubs(:private_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.private_method") end def test_should_allow_stubbing_protected_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :allow } instance = Class.new do def protected_method; end protected :protected_method end.new test_result = run_as_test do instance.stubs(:protected_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.protected_method") end def test_should_warn_when_stubbing_private_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :warn } instance = Class.new do def private_method; end private :private_method end.new test_result = run_as_test do instance.stubs(:private_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.private_method") end def test_should_warn_when_stubbing_protected_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :warn } instance = Class.new do def protected_method; end protected :protected_method end.new test_result = run_as_test do instance.stubs(:protected_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.protected_method") end def test_should_prevent_stubbing_private_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } instance = Class.new do def private_method; end private :private_method end.new test_result = run_as_test do instance.stubs(:private_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{instance.mocha_inspect}.private_method") end def test_should_prevent_stubbing_protected_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } instance = Class.new do def protected_method; end protected :protected_method end.new test_result = run_as_test do instance.stubs(:protected_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{instance.mocha_inspect}.protected_method") end def test_should_default_to_allow_stubbing_private_instance_method instance = Class.new do def private_method; end private :private_method end.new test_result = run_as_test do instance.stubs(:private_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.private_method") end def test_should_default_to_allow_stubbing_protected_instance_method instance = Class.new do def protected_method; end protected :protected_method end.new test_result = run_as_test do instance.stubs(:protected_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.protected_method") end def test_should_allow_stubbing_public_instance_method Mocha.configure { |c| c.stubbing_non_public_method = :prevent } instance = Class.new do def public_method; end public :public_method end.new test_result = run_as_test do instance.stubs(:public_method) end assert_passed(test_result) end def test_should_allow_stubbing_method_to_which_instance_responds Mocha.configure { |c| c.stubbing_non_public_method = :prevent } instance = Class.new do def respond_to?(method, _include_all = false) (method == :method_to_which_instance_responds) end end.new test_result = run_as_test do instance.stubs(:method_to_which_instance_responds) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubbing_on_non_mock_object_test.rb000066400000000000000000000044471464615054400250030ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) require 'mocha/configuration' class StubbingOnNonMockObjectTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_allow_stubbing_method_on_non_mock_object Mocha.configure { |c| c.stubbing_method_on_non_mock_object = :allow } non_mock_object = Class.new do def existing_method; end end test_result = run_as_test do non_mock_object.stubs(:existing_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method") end def test_should_warn_on_stubbing_method_on_non_mock_object Mocha.configure { |c| c.stubbing_method_on_non_mock_object = :warn } non_mock_object = Class.new do def existing_method; end end test_result = run_as_test do non_mock_object.stubs(:existing_method) end assert_passed(test_result) assert @logger.warnings.include?("stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method") end def test_should_prevent_stubbing_method_on_non_mock_object Mocha.configure { |c| c.stubbing_method_on_non_mock_object = :prevent } non_mock_object = Class.new do def existing_method; end end test_result = run_as_test do non_mock_object.stubs(:existing_method) end assert_errored(test_result) assert test_result.error_messages.include?("Mocha::StubbingError: stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method") end def test_should_default_to_allow_stubbing_method_on_non_mock_object non_mock_object = Class.new do def existing_method; end end test_result = run_as_test do non_mock_object.stubs(:existing_method) end assert_passed(test_result) assert !@logger.warnings.include?("stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method") end def test_should_allow_stubbing_method_on_mock_object Mocha.configure { |c| c.stubbing_method_on_non_mock_object = :prevent } test_result = run_as_test do mock = mock('mock') mock.stubs(:any_method) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb000066400000000000000000000013771464615054400323760ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class StubbingSameClassMethodOnParentAndChildClassTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_stubbing_same_method_on_parent_and_child_classes parent_class = Class.new do def self.foo 'Parent.foo' end end child_class = Class.new(parent_class) test_result = run_as_tests( test_1: lambda { parent_class.stubs(:foo).returns('stubbed Parent.foo') child_class.stubs(:foo).returns('stubbed Child.foo') }, test_2: lambda { parent_class.foo child_class.foo } ) assert_passed(test_result) end end mocha-2.4.2/test/acceptance/throw_test.rb000066400000000000000000000017601464615054400204170ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class ThrowTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_should_throw_tag test_result = run_as_test do foo = stub('foo') foo.stubs(:bar).throws(:tag) assert_throws(:tag) { foo.bar } end assert_passed(test_result) end def test_should_throw_with_return_value test_result = run_as_test do foo = stub('foo') foo.stubs(:bar).throws(:tag, 'return-value') return_value = catch(:tag) { foo.bar } assert_equal 'return-value', return_value end assert_passed(test_result) end def test_should_throw_two_different_tags test_result = run_as_test do foo = stub('foo') foo.stubs(:bar).throws(:tag_one).then.throws(:tag_two) assert_throws(:tag_one) { foo.bar } assert_throws(:tag_two) { foo.bar } end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/unexpected_invocation_test.rb000066400000000000000000000011631464615054400236460ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class UnexpectedInvocationTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_avoid_recursion_when_unexpected_invocation_exception_message_depends_on_uninspectable_object test_result = run_as_test do instance = Class.new.new instance.expects(:inspect).never instance.inspect(1, 2, 'foo') end assert_failed(test_result) assert_equal 'unexpected invocation: inspect(1, 2, foo)', test_result.failure_message_lines[0] end end mocha-2.4.2/test/acceptance/unstubbing_test.rb000066400000000000000000000134561464615054400214410ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class UnstubbingTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_unstubbing_an_instance_method_should_restore_original_behaviour klass = Class.new do def my_instance_method :original_return_value end end test_result = run_as_test do object = klass.new object.stubs(:my_instance_method).returns(:new_return_value) object.unstub(:my_instance_method) assert_equal :original_return_value, object.my_instance_method end assert_passed(test_result) end def test_unstubbing_a_class_method_should_restore_original_behaviour klass = Class.new do def self.my_class_method :original_return_value end end test_result = run_as_test do klass.stubs(:my_class_method).returns(:new_return_value) klass.unstub(:my_class_method) assert_equal :original_return_value, klass.my_class_method end assert_passed(test_result) end def test_unstubbing_a_module_method_should_restore_original_behaviour mod = Module.new do def self.my_module_method :original_return_value end end test_result = run_as_test do mod.stubs(:my_module_method).returns(:new_return_value) mod.unstub(:my_module_method) assert_equal :original_return_value, mod.my_module_method end assert_passed(test_result) end def test_unstubbing_a_module_method_defined_like_fileutils_in_ruby_2_0_should_restore_original_behaviour mod = Module.new do def my_module_method :original_return_value end private :my_module_method extend self class << self public :my_module_method end end test_result = run_as_test do mod.stubs(:my_module_method).returns(:new_return_value) mod.unstub(:my_module_method) assert_equal :original_return_value, mod.my_module_method end assert_passed(test_result) end def test_unstubbing_an_any_instance_method_should_restore_original_behaviour klass = Class.new do def my_instance_method :original_return_value end end test_result = run_as_test do object = klass.new klass.any_instance.stubs(:my_instance_method).returns(:new_return_value) klass.any_instance.unstub(:my_instance_method) assert_equal :original_return_value, object.my_instance_method end assert_passed(test_result) end def test_unstubbing_multiple_methods_should_restore_original_behaviour klass = Class.new do def my_first_instance_method :original_return_value end def my_second_instance_method :original_return_value end end test_result = run_as_test do object = klass.new object.stubs(:my_first_instance_method).returns(:new_return_value) object.stubs(:my_second_instance_method).returns(:new_return_value) object.unstub(:my_first_instance_method, :my_second_instance_method) assert_equal :original_return_value, object.my_first_instance_method assert_equal :original_return_value, object.my_second_instance_method end assert_passed(test_result) end def test_unstubbing_a_method_multiple_times_should_restore_original_behaviour klass = Class.new do def my_instance_method :original_return_value end end test_result = run_as_test do object = klass.new object.stubs(:my_instance_method).returns(:new_return_value) object.unstub(:my_instance_method) object.unstub(:my_instance_method) assert_equal :original_return_value, object.my_instance_method end assert_passed(test_result) end def test_unstubbing_a_non_stubbed_method_should_do_nothing klass = Class.new do def my_instance_method :original_return_value end end test_result = run_as_test do object = klass.new object.unstub(:my_instance_method) assert_equal :original_return_value, object.my_instance_method end assert_passed(test_result) end def test_unstubbing_a_method_which_was_stubbed_multiple_times_should_restore_orginal_behaviour klass = Class.new do def my_instance_method :original_return_value end end test_result = run_as_test do object = klass.new object.stubs(:my_instance_method).with(:first).returns(:first_new_return_value) object.stubs(:my_instance_method).with(:second).returns(:second_new_return_value) object.unstub(:my_instance_method) assert_equal :original_return_value, object.my_instance_method end assert_passed(test_result) end def test_unstubbing_a_method_should_not_unstub_other_stubbed_methods klass = Class.new do def my_first_instance_method :first_return_value end def my_second_instance_method :second_return_value end end test_result = run_as_test do object = klass.new object.stubs(:my_first_instance_method).returns(:first_new_return_value) object.stubs(:my_second_instance_method).returns(:second_new_return_value) object.unstub(:my_first_instance_method) assert_equal :first_return_value, object.my_first_instance_method assert_equal :second_new_return_value, object.my_second_instance_method end assert_passed(test_result) end def test_unstubbing_a_method_should_remove_all_expectations_for_that_method klass = Class.new do def my_instance_method :original_return_value end end test_result = run_as_test do object = klass.new object.expects(:my_instance_method).with(:first) object.expects(:my_instance_method).with(:second) object.unstub(:my_instance_method) end assert_passed(test_result) end end mocha-2.4.2/test/acceptance/yielding_test.rb000066400000000000000000000036731464615054400210650ustar00rootroot00000000000000require File.expand_path('../acceptance_test_helper', __FILE__) class YieldingTest < Mocha::TestCase include AcceptanceTest def setup setup_acceptance_test end def teardown teardown_acceptance_test end def test_yields_when_stubbed_method_is_invoked test_result = run_as_test do m = mock('m') m.stubs(:foo).yields yielded = false m.foo { yielded = true } assert yielded end assert_passed(test_result) end def test_raises_local_jump_error_if_instructed_to_yield_but_no_block_given test_result = run_as_test do m = mock('m') m.stubs(:foo).yields assert_raises(LocalJumpError) { m.foo } end assert_passed(test_result) end def test_yields_when_block_expected_and_block_given test_result = run_as_test do m = mock('m') m.stubs(:foo).with_block_given.yields m.stubs(:foo).with_no_block_given.returns(:bar) yielded = false m.foo { yielded = true } assert yielded end assert_passed(test_result) end def test_returns_when_no_block_expected_and_no_block_given test_result = run_as_test do m = mock('m') m.stubs(:foo).with_block_given.yields m.stubs(:foo).with_no_block_given.returns(:bar) assert_equal :bar, m.foo end assert_passed(test_result) end def test_yields_values_when_stubbed_method_is_invoked test_result = run_as_test do m = mock('m') m.stubs(:foo).yields(0, 1) yielded = [] m.foo { |*args| yielded << args } assert_equal [[0, 1]], yielded end assert_passed(test_result) end def test_yields_different_values_on_consecutive_invocations test_result = run_as_test do m = mock('m') m.stubs(:foo).yields(0, 1).then.yields(2, 3) yielded = [] m.foo { |*args| yielded << args } m.foo { |*args| yielded << args } assert_equal [[0, 1], [2, 3]], yielded end assert_passed(test_result) end end mocha-2.4.2/test/assertions.rb000066400000000000000000000003111464615054400163100ustar00rootroot00000000000000module Assertions def assert_method_visibility(object, method_name, visibility) assert object.send("#{visibility}_methods").include?(method_name), "#{method_name} is not #{visibility}" end end mocha-2.4.2/test/deprecation_disabler.rb000066400000000000000000000004611464615054400202660ustar00rootroot00000000000000require 'mocha/deprecation' module DeprecationDisabler def disable_deprecations original_mode = Mocha::Deprecation.mode Mocha::Deprecation.mode = :disabled begin yield ensure Mocha::Deprecation.mode = original_mode end end module_function :disable_deprecations end mocha-2.4.2/test/execution_point.rb000066400000000000000000000013131464615054400173350ustar00rootroot00000000000000class ExecutionPoint attr_reader :backtrace def self.current new(caller) end def initialize(backtrace) @backtrace = backtrace end def first_relevant_line_of_backtrace @backtrace && (@backtrace.reject { |l| %r{\Aorg/jruby/}.match(l) }.first || 'unknown:0') end def file_name /\A(.*?):\d+/.match(first_relevant_line_of_backtrace)[1] end def line_number Integer(/\A.*?:(\d+)/.match(first_relevant_line_of_backtrace)[1]) end def ==(other) return false unless other.is_a?(ExecutionPoint) (file_name == other.file_name) && (line_number == other.line_number) end def to_s "file: #{file_name}; line: #{line_number}" end def inspect to_s end end mocha-2.4.2/test/integration/000077500000000000000000000000001464615054400161215ustar00rootroot00000000000000mocha-2.4.2/test/integration/minitest_test.rb000066400000000000000000000002651464615054400213440ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/minitest' require 'integration/shared_tests' class MinitestTest < Mocha::TestCase include SharedTests end mocha-2.4.2/test/integration/shared_tests.rb000066400000000000000000000155621464615054400211470ustar00rootroot00000000000000require 'test_runner' require 'execution_point' # rubocop:disable Metrics/ModuleLength module SharedTests include TestRunner def test_assertion_satisfied test_result = run_as_test do assert true end assert_passed(test_result) end def test_assertion_unsatisfied execution_point = nil test_result = run_as_test do execution_point = ExecutionPoint.current; flunk end assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) end def test_mock_object_unexpected_invocation execution_point = nil test_result = run_as_test do mock = mock('not expecting invocation') execution_point = ExecutionPoint.current; mock.unexpected end assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal ['unexpected invocation: #.unexpected()'], test_result.failure_message_lines end def test_mock_object_explicitly_unexpected_invocation execution_point = nil test_result = run_as_test do mock = mock('not expecting invocation') mock.expects(:unexpected).never execution_point = ExecutionPoint.current; mock.unexpected end assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal [ 'unexpected invocation: #.unexpected()', 'unsatisfied expectations:', '- expected never, invoked once: #.unexpected(any_parameters)' ], test_result.failure_message_lines end def test_mock_object_unsatisfied_expectation execution_point = nil test_result = run_as_test do mock = mock('expecting invocation') execution_point = ExecutionPoint.current; mock.expects(:expected) end assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.expected(any_parameters)' ], test_result.failure_message_lines end def test_mock_object_unexpected_invocation_in_setup execution_point = nil test_result = run_as_tests( setup: lambda { mock = mock('not expecting invocation') execution_point = ExecutionPoint.current; mock.unexpected }, test_me: lambda { assert true } ) assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal ['unexpected invocation: #.unexpected()'], test_result.failure_message_lines end def test_mock_object_unsatisfied_expectation_in_setup execution_point = nil test_result = run_as_tests( setup: lambda { mock = mock('expecting invocation') execution_point = ExecutionPoint.current; mock.expects(:expected) }, test_me: lambda { assert true } ) assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', '- expected exactly once, invoked never: #.expected(any_parameters)' ], test_result.failure_message_lines end def test_mock_object_unexpected_invocation_in_teardown execution_point = nil test_result = run_as_tests( test_me: lambda { assert true }, teardown: lambda { mock = mock('not expecting invocation') execution_point = ExecutionPoint.current; mock.unexpected } ) assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal ['unexpected invocation: #.unexpected()'], test_result.failure_message_lines end def test_real_object_explicitly_unexpected_invocation execution_point = nil object = Object.new test_result = run_as_test do object.expects(:unexpected).never execution_point = ExecutionPoint.current; object.unexpected end assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal [ "unexpected invocation: #{object.mocha_inspect}.unexpected()", 'unsatisfied expectations:', "- expected never, invoked once: #{object.mocha_inspect}.unexpected(any_parameters)" ], test_result.failure_message_lines end def test_real_object_unsatisfied_expectation execution_point = nil object = Object.new test_result = run_as_test do execution_point = ExecutionPoint.current; object.expects(:expected) end assert_failed(test_result) failure = test_result.failures.first assert_equal execution_point, ExecutionPoint.new(failure.location) assert_equal [ 'not all expectations were satisfied', 'unsatisfied expectations:', "- expected exactly once, invoked never: #{object.mocha_inspect}.expected(any_parameters)" ], test_result.failure_message_lines end def test_real_object_expectation_does_not_leak_into_subsequent_test execution_point = nil klass = Class.new test_result = run_as_tests( test_1: lambda { klass.expects(:foo) klass.foo }, test_2: lambda { execution_point = ExecutionPoint.current; klass.foo } ) assert_errored(test_result) exception = test_result.errors.first.exception assert_equal execution_point, ExecutionPoint.new(exception.backtrace) assert_match(/undefined method `foo'/, exception.message) end def test_leaky_mock origin = nil leaky_mock = nil execution_point = nil test_result = run_as_tests( test_1: lambda { origin = mocha_test_name leaky_mock ||= begin bad_mock = mock(:leaky) bad_mock.expects(:call) bad_mock end leaky_mock.call }, test_2: lambda { leaky_mock ||= begin bad_mock = mock(:leaky) bad_mock.expects(:call) bad_mock end execution_point = ExecutionPoint.current; leaky_mock.call } ) assert_errored(test_result) exception = test_result.errors.first.exception assert_equal execution_point, ExecutionPoint.new(exception.backtrace) expected = /# was instantiated in #{Regexp.escape(origin)} but it is receiving invocations within another test/ assert_match(expected, exception.message) end end # rubocop:enable Metrics/ModuleLength mocha-2.4.2/test/integration/test_unit_test.rb000066400000000000000000000002661464615054400215270ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/test_unit' require 'integration/shared_tests' class TestUnitTest < Mocha::TestCase include SharedTests end mocha-2.4.2/test/method_definer.rb000066400000000000000000000010411464615054400170730ustar00rootroot00000000000000module MethodDefiner def define_instance_method(object, method_symbol, &block) object.singleton_class.send(:define_method, method_symbol, block) end def replace_instance_method(object, method_symbol, &block) raise "Cannot replace #{method_symbol} as #{self} does not respond to it." unless object.respond_to?(method_symbol) define_instance_method(object, method_symbol, &block) end def define_instance_accessor(object, *symbols) symbols.each { |symbol| object.singleton_class.send(:attr_accessor, symbol) } end end mocha-2.4.2/test/minitest_result.rb000066400000000000000000000016351464615054400173620ustar00rootroot00000000000000require 'forwardable' class MinitestResult class Failure extend Forwardable def_delegators :@failure, :message, :backtrace def initialize(failure) @failure = failure end def location Minitest.filter_backtrace(backtrace) end end def initialize(tests) @tests = tests end def failures @tests.map(&:failures).flatten.select { |r| r.instance_of?(Minitest::Assertion) }.map { |f| Failure.new(f) } end def failure_count failures.length end def failure_message_lines failures.map { |f| f.message.split("\n") }.flatten end def errors @tests.map(&:failures).flatten.select { |r| r.instance_of?(Minitest::UnexpectedError) } end def error_count errors.length end def error_messages errors.map { |e| e.message.split("\n") }.flatten end def assertion_count @tests.inject(0) { |total, test| total + test.assertions } end end mocha-2.4.2/test/minitest_result_pre_v5.rb000066400000000000000000000047701464615054400206450ustar00rootroot00000000000000require 'stringio' require 'mocha/detection/minitest' class MinitestResult minitest_version = Gem::Version.new(Mocha::Detection::Minitest.version) if Gem::Requirement.new('<= 4.6.1').satisfied_by?(minitest_version) FAILURE_PATTERN = /(Failure)\:\n([^\(]+)\(([^\)]+)\) \[([^\]]+)\]\:\n(.*)\n/m ERROR_PATTERN = /(Error)\:\n([^\(]+)\(([^\)]+)\)\:\n(.+?)\n/m PATTERN_INDICES = { method: 2, testcase: 3 }.freeze else FAILURE_PATTERN = /(Failure)\:\n.([^#]+)\#([^ ]+) \[([^\]]+)\]\:\n(.*)\n/m ERROR_PATTERN = /(Error)\:\n.([^#]+)\#([^ ]+)\:\n(.+?)\n/m PATTERN_INDICES = { method: 3, testcase: 2 }.freeze end def self.parse_failure(raw) matches = FAILURE_PATTERN.match(raw) return nil unless matches Failure.new(matches[PATTERN_INDICES[:method]], matches[PATTERN_INDICES[:testcase]], [matches[4]], matches[5]) end def self.parse_error(raw) matches = ERROR_PATTERN.match(raw) return nil unless matches backtrace = raw.gsub(ERROR_PATTERN, '').split("\n").map(&:strip) Error.new(matches[PATTERN_INDICES[:method]], matches[PATTERN_INDICES[:testcase]], matches[4], backtrace) end class Failure attr_reader :method, :test_case, :location, :message def initialize(method, test_case, location, message) @method = method @test_case = test_case @location = location @message = message end end class Error class Exception attr_reader :message, :backtrace def initialize(message, location) @message = message @backtrace = location end end attr_reader :method, :test_case, :exception def initialize(method, test_case, message, backtrace) @method = method @test_case = test_case @exception = Exception.new(message, backtrace) end end def initialize(runner, tests) @runner = runner @tests = tests end def failure_count @runner.failures end def assertion_count @tests.inject(0) { |total, test| total + test._assertions } end def error_count @runner.errors end def passed? @tests.all?(&:passed?) end def failures @runner.report.map { |puked| MinitestResult.parse_failure(puked) }.compact end def errors @runner.report.map { |puked| MinitestResult.parse_error(puked) }.compact end def failure_messages failures.map(&:message) end def failure_message_lines failure_messages.map { |message| message.split("\n") }.flatten end def error_messages errors.map { |e| e.exception.message } end end mocha-2.4.2/test/simple_counter.rb000066400000000000000000000001731464615054400171540ustar00rootroot00000000000000class SimpleCounter attr_reader :count def initialize @count = 0 end def increment @count += 1 end end mocha-2.4.2/test/test_helper.rb000066400000000000000000000034531464615054400164460ustar00rootroot00000000000000unless defined?(STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS) STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS = Object.instance_methods + Object.private_instance_methods end $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__))) $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit')) $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit', 'parameter_matchers')) $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), 'acceptance')) require 'mocha/detection/minitest' begin require 'minitest' # rubocop:disable Lint/HandleExceptions rescue LoadError end # rubocop:enable Lint/HandleExceptions module Mocha; end if (minitest_testcase = Mocha::Detection::Minitest.testcase) && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit') begin require 'minitest/autorun' rescue LoadError Minitest::Unit.autorun end # rubocop:disable Style/ClassAndModuleChildren class Mocha::TestCase < minitest_testcase def assert_nothing_raised(exception = StandardError) yield rescue exception => e flunk "Unexpected exception raised: #{e}" end alias_method :assert_not_nil, :refute_nil alias_method :assert_raise, :assert_raises alias_method :assert_not_same, :refute_same alias_method :assert_no_match, :refute_match end # rubocop:enable Style/ClassAndModuleChildren else require 'test/unit' # rubocop:disable Style/ClassAndModuleChildren class Mocha::TestCase < Test::Unit::TestCase def test_dummy # Some versions (?) of Test::Unit try to run this base class as a test case # and it fails because it has no test methods, so I'm adding a dummy test. end end # rubocop:enable Style/ClassAndModuleChildren end mocha-2.4.2/test/test_runner.rb000066400000000000000000000043271464615054400165010ustar00rootroot00000000000000require 'assertions' require 'mocha/detection/minitest' module TestRunner def run_as_test(&block) run_as_tests(test_me: block) end # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def run_as_tests(methods = {}) base_class = Mocha::TestCase test_class = Class.new(base_class) do def self.name; 'FakeTest' end include Assertions methods.each do |(method_name, proc)| define_method(method_name, proc) end end tests = methods.keys.select { |m| m.to_s[/^test/] }.map { |m| test_class.new(m) } if Mocha::Detection::Minitest.testcase && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit') minitest_version = Gem::Version.new(Mocha::Detection::Minitest.version) if Gem::Requirement.new('>= 5.0.0').satisfied_by?(minitest_version) require File.expand_path('../minitest_result', __FILE__) tests.each(&:run) Minitest::Runnable.runnables.delete(test_class) test_result = MinitestResult.new(tests) elsif Gem::Requirement.new('> 0.0.0', '< 5.0.0').satisfied_by?(minitest_version) require File.expand_path('../minitest_result_pre_v5', __FILE__) runner = Minitest::Unit.new tests.each do |test| test.run(runner) end test_result = MinitestResult.new(runner, tests) end else require File.expand_path('../test_unit_result', __FILE__) test_result = TestUnitResult.build_test_result tests.each do |test| test.run(test_result) {} end end test_result end # rubocop:enable Metrics/AbcSize, Metrics/MethodLength def assert_passed(test_result) flunk "Test errored unexpectedly with message: #{test_result.errors.map(&:exception)}" if test_result.error_count > 0 flunk "Test failed unexpectedly with message: #{test_result.failures}" if test_result.failure_count > 0 end def assert_failed(test_result) flunk "Test errored unexpectedly with message: #{test_result.errors.map(&:exception)}" if test_result.error_count > 0 flunk 'Test passed unexpectedly' unless test_result.failure_count > 0 end def assert_errored(test_result) flunk 'Test did not error as expected' unless test_result.error_count > 0 end end mocha-2.4.2/test/test_unit_result.rb000066400000000000000000000007301464615054400175370ustar00rootroot00000000000000require 'test/unit/testresult' class TestUnitResult def self.build_test_result test_result = Test::Unit::TestResult.new class << test_result attr_reader :failures, :errors def failure_messages failures.map(&:message) end def failure_message_lines failure_messages.map { |message| message.split("\n") }.flatten end def error_messages errors.map(&:message) end end test_result end end mocha-2.4.2/test/unit/000077500000000000000000000000001464615054400145555ustar00rootroot00000000000000mocha-2.4.2/test/unit/any_instance_method_test.rb000066400000000000000000000101711464615054400221540ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/ruby_version' require 'method_definer' require 'mocha/class_methods' require 'mocha/mockery' require 'mocha/mock' require 'mocha/any_instance_method' class AnyInstanceMethodTest < Mocha::TestCase include MethodDefiner include Mocha def class_with_method(method, result = nil) Class.new do extend ClassMethods define_method(method) { result } if method end end def test_should_not_raise_error_hiding_method_that_isnt_defined klass = class_with_method(:irrelevant) method = AnyInstanceMethod.new(klass, :method_x) assert_nothing_raised { method.hide_original_method } end def test_should_define_a_new_method klass = class_with_method(:method_x) method = AnyInstanceMethod.new(klass, :method_x) mocha = build_mock mocha.expects(:method_x).with(:param1, :param2).returns(:result) any_instance = Object.new define_instance_method(any_instance, :mocha) { mocha } define_instance_method(klass, :any_instance) { any_instance } method.hide_original_method method.define_new_method instance = klass.new result = instance.method_x(:param1, :param2) assert_equal :result, result assert mocha.__verified__? end def test_should_include_the_filename_and_line_number_in_exceptions klass = class_with_method(:method_x) method = AnyInstanceMethod.new(klass, :method_x) mocha = build_mock mocha.stubs(:method_x).raises(Exception) any_instance = Object.new define_instance_method(any_instance, :mocha) { mocha } define_instance_method(klass, :any_instance) { any_instance } method.hide_original_method method.define_new_method expected_filename = 'stubbed_method.rb' expected_line_number = 47 exception = assert_raises(Exception) { klass.new.method_x } matching_line = exception.backtrace.find do |line| filename, line_number, _context = line.split(':') filename.include?(expected_filename) && line_number.to_i == expected_line_number end assert_not_nil matching_line, "Expected to find #{expected_filename}:#{expected_line_number} in the backtrace:\n #{exception.backtrace.join("\n")}" end def test_remove_new_method_restores_original_method klass = class_with_method(:method_x, :original_result) method = AnyInstanceMethod.new(klass, :method_x) method.hide_original_method method.define_new_method method.remove_new_method instance = klass.new assert instance.respond_to?(:method_x) assert_equal :original_result, instance.method_x end def test_should_call_remove_new_method klass = class_with_method(:method_x) any_instance = build_mock any_instance_mocha = build_mock any_instance.stubs(:mocha).returns(any_instance_mocha) define_instance_method(klass, :any_instance) { any_instance } method = AnyInstanceMethod.new(klass, :method_x) replace_instance_method(method, :reset_mocha) {} define_instance_accessor(method, :remove_called) replace_instance_method(method, :remove_new_method) { self.remove_called = true } method.unstub assert method.remove_called end def test_should_call_mock_unstub klass = class_with_method(:method_x) method = AnyInstanceMethod.new(klass, :method_x) replace_instance_method(method, :remove_new_method) {} mocha = Class.new do class << self attr_accessor :unstub_method end def self.unstub(method) self.unstub_method = method end end define_instance_method(mocha, :any_expectations?) { true } replace_instance_method(method, :mock) { mocha } method.unstub assert_equal mocha.unstub_method, :method_x end def test_should_return_any_instance_mocha_for_stubbee mocha = Object.new any_instance = Object.new define_instance_method(any_instance, :mocha) { mocha } stubbee = class_with_method(:method_x) define_instance_method(stubbee, :any_instance) { any_instance } method = AnyInstanceMethod.new(stubbee, :method_name) assert_equal stubbee.any_instance.mocha, method.mock end private def build_mock Mock.new(Mockery.new) end end mocha-2.4.2/test/unit/array_inspect_test.rb000066400000000000000000000010301464615054400207760ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/inspect' class ArrayInspectTest < Mocha::TestCase def test_should_return_string_representation_of_array array = [1, 2] assert_equal '[1, 2]', array.mocha_inspect end def test_should_return_unwrapped_array_when_wrapped_is_false array = [1, 2] assert_equal '1, 2', array.mocha_inspect(false) end def test_should_use_mocha_inspect_on_each_item array = [1, 2, 'chris'] assert_equal %([1, 2, "chris"]), array.mocha_inspect end end mocha-2.4.2/test/unit/backtrace_filter_test.rb000066400000000000000000000016261464615054400214320ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/backtrace_filter' class BacktraceFilterTest < Mocha::TestCase include Mocha def test_should_exclude_mocha_locations_from_backtrace mocha_lib = '/username/workspace/mocha_wibble/lib/' backtrace = [mocha_lib + 'exclude/me/1', mocha_lib + 'exclude/me/2', '/keep/me', mocha_lib + 'exclude/me/3'] filter = BacktraceFilter.new(mocha_lib) assert_equal ['/keep/me'], filter.filtered(backtrace) end def test_should_determine_path_for_mocha_lib_directory assert_match Regexp.new('/lib/$'), BacktraceFilter::LIB_DIRECTORY end def test_should_handle_special_characters lib_directory = '/tmp/bundle/ruby/3.2.0+3/gems/mocha-2.0.2/lib/' filter = BacktraceFilter.new(lib_directory) backtrace = ['/keep/me', "#{lib_directory}mocha/deprecation.rb"] assert_equal ['/keep/me'], filter.filtered(backtrace) end end mocha-2.4.2/test/unit/cardinality_test.rb000066400000000000000000000056311464615054400204510ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/cardinality' require 'mocha/invocation' require 'mocha/return_values' require 'mocha/yield_parameters' class CardinalityTest < Mocha::TestCase include Mocha def new_invocation Invocation.new(:irrelevant, :irrelevant) end def test_should_allow_invocations_if_invocation_count_has_not_yet_reached_maximum cardinality = Cardinality.new(2, 3) assert cardinality.invocations_allowed? cardinality << new_invocation assert cardinality.invocations_allowed? cardinality << new_invocation assert cardinality.invocations_allowed? cardinality << new_invocation assert !cardinality.invocations_allowed? end def test_should_be_satisfied_if_invocations_so_far_have_reached_required_threshold cardinality = Cardinality.new(2, 3) assert !cardinality.satisfied? cardinality << new_invocation assert !cardinality.satisfied? cardinality << new_invocation assert cardinality.satisfied? cardinality << new_invocation assert cardinality.satisfied? end def test_should_describe_cardinality_defined_using_at_least assert_equal 'allowed any number of times', Cardinality.new.at_least(0).anticipated_times assert_equal 'expected at least once', Cardinality.new.at_least(1).anticipated_times assert_equal 'expected at least twice', Cardinality.new.at_least(2).anticipated_times assert_equal 'expected at least 3 times', Cardinality.new.at_least(3).anticipated_times end def test_should_describe_cardinality_defined_using_at_most assert_equal 'expected at most once', Cardinality.new.at_most(1).anticipated_times assert_equal 'expected at most twice', Cardinality.new.at_most(2).anticipated_times assert_equal 'expected at most 3 times', Cardinality.new.at_most(3).anticipated_times end def test_should_describe_cardinality_defined_using_exactly assert_equal 'expected never', Cardinality.new.exactly(0).anticipated_times assert_equal 'expected exactly once', Cardinality.new.exactly(1).anticipated_times assert_equal 'expected exactly twice', Cardinality.new.exactly(2).anticipated_times assert_equal 'expected exactly 3 times', Cardinality.new.exactly(3).anticipated_times end def test_should_describe_cardinality_defined_using_times_with_range assert_equal 'expected between 2 and 4 times', Cardinality.new.times(2..4).anticipated_times assert_equal 'expected between 1 and 3 times', Cardinality.new.times(1..3).anticipated_times end def test_should_need_verifying assert Cardinality.new.exactly(2).needs_verifying? assert Cardinality.new.at_least(3).needs_verifying? assert Cardinality.new.at_most(2).needs_verifying? assert Cardinality.new.times(4).needs_verifying? assert Cardinality.new.times(2..4).needs_verifying? end def test_should_not_need_verifying assert_equal false, Cardinality.new.at_least(0).needs_verifying? end end mocha-2.4.2/test/unit/central_test.rb000066400000000000000000000043171464615054400175760ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/central' require 'mocha/mockery' require 'mocha/mock' class CentralTest < Mocha::TestCase include Mocha def test_should_start_with_empty_stubba_methods stubba = Central.new assert_equal [], stubba.stubba_methods end def test_should_stub_method_if_not_already_stubbed method = build_mock method.expects(:stub) stubba = Central.new stubba.stub(method) assert method.__verified__? end def test_should_not_stub_method_if_already_stubbed method = build_mock method.stubs(:matches?).returns(true) method.expects(:stub).times(0) stubba = Central.new stubba.stubba_methods = [method] stubba.stub(method) assert method.__verified__? end def test_should_record_method method = build_mock method.expects(:stub) stubba = Central.new stubba.stub(method) assert_equal [method], stubba.stubba_methods end def test_should_unstub_specified_method stubba = Central.new method1 = build_mock method1.stubs(:matches?).returns(false) method2 = build_mock method2.stubs(:matches?).returns(true) method2.expects(:unstub) stubba.stubba_methods = [method1, method2] stubba.unstub(method2) assert_equal [method1], stubba.stubba_methods assert method2.__verified__? end def test_should_not_unstub_specified_method_if_not_already_stubbed stubba = Central.new method1 = build_mock method1.stubs(:matches?).returns(false) method2 = build_mock method2.expects(:unstub).never stubba.stubba_methods = [method1] stubba.unstub(method2) assert_equal [method1], stubba.stubba_methods assert method2.__verified__? end def test_should_unstub_all_methods stubba = Central.new method1 = build_mock method1.stubs(:matches?).returns(true) method1.expects(:unstub) method2 = build_mock method2.stubs(:matches?).returns(true) method2.expects(:unstub) stubba.stubba_methods = [method1, method2] stubba.unstub_all assert_equal [], stubba.stubba_methods assert method1.__verified__? assert method2.__verified__? end private def build_mock Mock.new(Mockery.new) end end mocha-2.4.2/test/unit/change_state_side_effect_test.rb000066400000000000000000000014111464615054400231030ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/change_state_side_effect' class ChangeStateSideEffectTest < Mocha::TestCase include Mocha class FakeState attr_reader :active attr_writer :description def activate @active = true end def mocha_inspect @description end end def test_should_activate_the_given_state state = FakeState.new side_effect = ChangeStateSideEffect.new(state) side_effect.perform assert state.active end def test_should_describe_itself_in_terms_of_the_activated_state state = FakeState.new state.description = 'the-new-state' side_effect = ChangeStateSideEffect.new(state) assert_equal 'then the-new-state', side_effect.mocha_inspect end end mocha-2.4.2/test/unit/class_methods_test.rb000066400000000000000000000040051464615054400207700ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/class_methods' require 'mocha/object_methods' require 'mocha/mockery' require 'mocha/names' class ClassMethodsTest < Mocha::TestCase def setup Mocha::Mockery.setup @klass = Class.new.extend(Mocha::ClassMethods, Mocha::ObjectMethods) end def teardown Mocha::Mockery.teardown end def test_should_build_any_instance_object any_instance = @klass.any_instance assert_not_nil any_instance assert any_instance.is_a?(Mocha::ClassMethods::AnyInstance) end def test_should_return_same_any_instance_object any_instance1 = @klass.any_instance any_instance2 = @klass.any_instance assert_equal any_instance1, any_instance2 end def test_any_instance_should_build_mocha_referring_to_klass mocha = @klass.any_instance.mocha assert_not_nil mocha assert mocha.is_a?(Mocha::Mock) expected_name = Mocha::ImpersonatingAnyInstanceName.new(@klass).mocha_inspect assert_equal expected_name, mocha.mocha_inspect end def test_any_instance_should_not_build_mocha_if_instantiate_is_false assert_nil @klass.any_instance.mocha(false) end def test_any_instance_should_reuse_existing_mocha mocha1 = @klass.any_instance.mocha mocha2 = @klass.any_instance.mocha assert_equal mocha1, mocha2 end def test_any_instance_should_reuse_existing_mocha_even_if_instantiate_is_false mocha1 = @klass.any_instance.mocha mocha2 = @klass.any_instance.mocha(false) assert_equal mocha1, mocha2 end def test_should_use_stubba_class_method_for_class assert_equal Mocha::InstanceMethod, @klass.stubba_method end def test_should_use_stubba_class_method_for_any_instance assert_equal Mocha::AnyInstanceMethod, @klass.any_instance.stubba_method end def test_should_stub_self_for_class assert_equal @klass, @klass.stubba_object end def test_should_stub_relevant_class_for_any_instance any_instance = @klass.any_instance assert_equal @klass, any_instance.stubba_object end end mocha-2.4.2/test/unit/configuration_test.rb000066400000000000000000000042621464615054400210140ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/configuration' require 'mocha/ruby_version' class ConfigurationTest < Mocha::TestCase def teardown Mocha::Configuration.reset_configuration end def test_allow_temporarily_changes_config_when_given_block Mocha.configure { |c| c.stubbing_method_unnecessarily = :warn } yielded = false Mocha::Configuration.override(stubbing_method_unnecessarily: :allow) do yielded = true assert_equal :allow, Mocha.configuration.stubbing_method_unnecessarily end assert yielded assert_equal :warn, Mocha.configuration.stubbing_method_unnecessarily end def test_prevent_temporarily_changes_config_when_given_block Mocha.configure { |c| c.stubbing_method_unnecessarily = :allow } yielded = false Mocha::Configuration.override(stubbing_method_unnecessarily: :prevent) do yielded = true assert_equal :prevent, Mocha.configuration.stubbing_method_unnecessarily end assert yielded assert_equal :allow, Mocha.configuration.stubbing_method_unnecessarily end def test_warn_when_temporarily_changes_config_when_given_block Mocha.configure { |c| c.stubbing_method_unnecessarily = :allow } yielded = false Mocha::Configuration.override(stubbing_method_unnecessarily: :warn) do yielded = true assert_equal :warn, Mocha.configuration.stubbing_method_unnecessarily end assert yielded assert_equal :allow, Mocha.configuration.stubbing_method_unnecessarily end def test_strict_keyword_argument_matching_works_is_false_by_default assert !Mocha.configuration.strict_keyword_argument_matching? end if Mocha::RUBY_V27_PLUS def test_enabling_strict_keyword_argument_matching_works_in_ruby_2_7_and_above Mocha.configure { |c| c.strict_keyword_argument_matching = true } assert Mocha.configuration.strict_keyword_argument_matching? end else def test_enabling_strict_keyword_argument_matching_raises_error_if_below_ruby_2_7 assert_raises(RuntimeError, 'Strict keyword argument matching requires Ruby 2.7 and above.') do Mocha.configure { |c| c.strict_keyword_argument_matching = true } end end end end mocha-2.4.2/test/unit/date_time_inspect_test.rb000066400000000000000000000010751464615054400216240ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/inspect' class DateTimeInspectTest < Mocha::TestCase def test_should_use_include_date_in_seconds time = Time.now assert_equal "#{time.inspect} (#{time.to_f} secs)", time.mocha_inspect end def test_should_use_to_s_for_date date = Date.new(2006, 1, 1) assert_equal date.to_s, date.mocha_inspect end def test_should_use_to_s_for_datetime datetime = DateTime.new(2006, 1, 1) # rubocop:disable Style/DateTime assert_equal datetime.to_s, datetime.mocha_inspect end end mocha-2.4.2/test/unit/exception_raiser_test.rb000066400000000000000000000032371464615054400215110ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/invocation' require 'mocha/exception_raiser' require 'timeout' class ExceptionRaiserTest < Mocha::TestCase include Mocha def new_invocation Invocation.new(:irrelevant, :irrelevant) end def test_should_raise_exception_with_specified_class_and_default_message exception_class = Class.new(StandardError) raiser = ExceptionRaiser.new(exception_class, nil) exception = assert_raises(exception_class) { raiser.evaluate(new_invocation) } assert_equal exception_class.to_s, exception.message end def test_should_raise_exception_with_specified_class_and_message exception_class = Class.new(StandardError) raiser = ExceptionRaiser.new(exception_class, 'message') exception = assert_raises(exception_class) { raiser.evaluate(new_invocation) } assert_equal 'message', exception.message end def test_should_raise_exception_instance exception_class = Class.new(StandardError) raiser = ExceptionRaiser.new(exception_class.new('message'), nil) exception = assert_raises(exception_class) { raiser.evaluate(new_invocation) } assert_equal 'message', exception.message end def test_should_raise_interrupt_exception_with_default_message_so_it_works_in_ruby_1_8_6 raiser = ExceptionRaiser.new(Interrupt, nil) assert_raises(Interrupt) { raiser.evaluate(new_invocation) } end def test_should_raise_subclass_of_interrupt_exception_with_default_message_so_it_works_in_ruby_1_8_6 exception_class = Class.new(Interrupt) raiser = ExceptionRaiser.new(exception_class, nil) assert_raises(exception_class) { raiser.evaluate(new_invocation) } end end mocha-2.4.2/test/unit/expectation_list_test.rb000066400000000000000000000074551464615054400215320ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/expectation_list' require 'mocha/expectation' require 'mocha/invocation' require 'set' require 'method_definer' class ExpectationListTest < Mocha::TestCase include MethodDefiner include Mocha def test_should_return_added_expectation expectation_list = ExpectationList.new expectation = Expectation.new(nil, :my_method) assert_same expectation, expectation_list.add(expectation) end def test_should_find_matching_expectation expectation_list = ExpectationList.new expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2) expectation2 = Expectation.new(nil, :my_method).with(:argument3, :argument4) expectation_list.add(expectation1) expectation_list.add(expectation2) assert_same expectation1, expectation_list.match(Invocation.new(:irrelevant, :my_method, [:argument1, :argument2])) end def test_should_remove_all_expectations_matching_method_name expectation_list = ExpectationList.new expectation1 = Expectation.new(nil, :method_one).with(:argument1, :argument2) expectation2 = Expectation.new(nil, :method_one).with(:argument3, :argument4) expectation3 = Expectation.new(nil, :method_two) expectation_list.add(expectation1) expectation_list.add(expectation2) expectation_list.add(expectation3) expectation_list.remove_all_matching_method(:method_one) assert_nil expectation_list.match(Invocation.new(:irrelevant, :method_one, :argument1, :argument2)) assert_nil expectation_list.match(Invocation.new(:irrelevant, :method_one, :argument3, :argument4)) assert_same expectation3, expectation_list.match(Invocation.new(:irrelevant, :method_two)) end def test_should_find_most_recent_matching_expectation expectation_list = ExpectationList.new expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2) expectation2 = Expectation.new(nil, :my_method).with(:argument1, :argument2) expectation_list.add(expectation1) expectation_list.add(expectation2) assert_same expectation2, expectation_list.match(Invocation.new(:irrelevant, :my_method, [:argument1, :argument2])) end def test_should_find_matching_expectation_allowing_invocation expectation_list = ExpectationList.new expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2) expectation2 = Expectation.new(nil, :my_method).with(:argument3, :argument4) define_instance_method(expectation1, :invocations_allowed?) { true } define_instance_method(expectation2, :invocations_allowed?) { true } expectation_list.add(expectation1) expectation_list.add(expectation2) assert_same expectation1, expectation_list.match_allowing_invocation(Invocation.new(:irrelevant, :my_method, [:argument1, :argument2])) end def test_should_find_most_recent_matching_expectation_allowing_invocation expectation_list = ExpectationList.new expectation1 = Expectation.new(nil, :my_method) expectation2 = Expectation.new(nil, :my_method) define_instance_method(expectation1, :invocations_allowed?) { true } define_instance_method(expectation2, :invocations_allowed?) { false } expectation_list.add(expectation1) expectation_list.add(expectation2) assert_same expectation1, expectation_list.match_allowing_invocation(Invocation.new(:irrelevant, :my_method)) end def test_should_combine_two_expectation_lists_into_one expectation_list1 = ExpectationList.new expectation_list2 = ExpectationList.new expectation1 = Expectation.new(nil, :my_method) expectation2 = Expectation.new(nil, :my_method) expectation_list1.add(expectation1) expectation_list2.add(expectation2) expectation_list = expectation_list1 + expectation_list2 assert_equal [expectation1, expectation2], expectation_list.to_a end end mocha-2.4.2/test/unit/expectation_test.rb000066400000000000000000000413271464615054400204730ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/expectation' require 'mocha/invocation' require 'mocha/sequence' require 'execution_point' require 'simple_counter' class ExpectationTest < Mocha::TestCase include Mocha def new_expectation Expectation.new(nil, :expected_method) end def invoke(expectation, &block) expectation.invoke(Invocation.new(:irrelevant, :expected_method, [], block)) end def test_should_match_calls_to_same_method_with_any_parameters assert new_expectation.match?(Invocation.new(:irrelevant, :expected_method, [1, 2, 3])) end def test_should_match_calls_to_same_method_with_exactly_zero_parameters assert new_expectation.with.match?(Invocation.new(:irrelevant, :expected_method)) end def test_should_not_match_calls_to_same_method_with_more_than_zero_parameters assert !new_expectation.with.match?(Invocation.new(:irrelevant, :expected_method, [1, 2, 3])) end def test_should_match_calls_to_same_method_with_expected_parameter_values assert new_expectation.with(1, 2, 3).match?(Invocation.new(:irrelevant, :expected_method, [1, 2, 3])) end def test_should_match_calls_to_same_method_with_parameters_constrained_as_expected expectation = new_expectation.with { |x, y, z| x + y == z } assert expectation.match?(Invocation.new(:irrelevant, :expected_method, [1, 2, 3])) end def test_should_not_match_calls_to_different_method_with_parameters_constrained_as_expected expectation = new_expectation.with { |x, y, z| x + y == z } assert !expectation.match?(Invocation.new(:irrelevant, :different_method, [1, 2, 3])) end def test_should_not_match_calls_to_different_methods_with_no_parameters assert !new_expectation.match?(Invocation.new(:irrelevant, :unexpected_method)) end def test_should_not_match_calls_to_same_method_with_too_few_parameters assert !new_expectation.with(1, 2, 3).match?(Invocation.new(:irrelevant, :expected_method, [1, 2])) end def test_should_not_match_calls_to_same_method_with_too_many_parameters assert !new_expectation.with(1, 2).match?(Invocation.new(:irrelevant, :expected_method, [1, 2, 3])) end def test_should_not_match_calls_to_same_method_with_unexpected_parameter_values assert !new_expectation.with(1, 2, 3).match?(Invocation.new(:irrelevant, :expected_method, [1, 0, 3])) end def test_should_not_match_calls_to_same_method_with_parameters_not_constrained_as_expected expectation = new_expectation.with { |x, y, z| x + y == z } assert !expectation.match?(Invocation.new(:irrelevant, :expected_method, [1, 0, 3])) end def test_should_allow_invocations_until_expected_invocation_count_is_one_and_actual_invocation_count_would_be_two expectation = new_expectation.times(1) assert expectation.invocations_allowed? invoke(expectation) assert !expectation.invocations_allowed? end def test_should_allow_invocations_until_expected_invocation_count_is_two_and_actual_invocation_count_would_be_three expectation = new_expectation.times(2) 2.times do assert expectation.invocations_allowed? invoke(expectation) end assert !expectation.invocations_allowed? end def test_should_allow_invocations_until_expected_invocation_count_is_a_range_from_two_to_three_and_actual_invocation_count_would_be_four expectation = new_expectation.times(2..3) 3.times do assert expectation.invocations_allowed? invoke(expectation) end assert !expectation.invocations_allowed? end def test_should_store_provided_backtrace backtrace = Object.new assert_equal backtrace, Expectation.new(nil, :expected_method, backtrace).backtrace end def test_should_default_backtrace_to_caller execution_point = ExecutionPoint.current; expectation = Expectation.new(nil, :expected_method) assert_equal execution_point, ExecutionPoint.new(expectation.backtrace) end def test_should_not_yield yielded = false invoke(new_expectation) { yielded = true } assert_equal false, yielded end def test_should_yield_no_parameters yielded_parameters = nil invoke(new_expectation.yields) { |*parameters| yielded_parameters = parameters } assert_equal [], yielded_parameters end def test_yields_should_raise_local_jump_error_when_the_caller_does_not_provide_a_block assert_raises(LocalJumpError) { invoke(new_expectation.yields(:foo)) } end def test_multiple_yields_should_raise_local_jump_error_when_caller_does_not_provide_block assert_raises(LocalJumpError) { invoke(new_expectation.multiple_yields(:foo, 1, [2, 3])) } end def test_should_yield_with_specified_parameters yielded_parameters = nil invoke(new_expectation.yields(1, 2, 3)) { |*parameters| yielded_parameters = parameters } assert_equal [1, 2, 3], yielded_parameters end def test_should_yield_different_parameters_on_consecutive_invocations expectation = new_expectation.yields(1, 2, 3).yields(4, 5) yielded_parameters = [] invoke(expectation) { |*parameters| yielded_parameters << parameters } invoke(expectation) { |*parameters| yielded_parameters << parameters } assert_equal [[1, 2, 3], [4, 5]], yielded_parameters end def test_should_yield_multiple_times_for_single_invocation yielded_parameters = [] invoke(new_expectation.multiple_yields([1, 2, 3], [4, 5])) { |*parameters| yielded_parameters << parameters } assert_equal [[1, 2, 3], [4, 5]], yielded_parameters end def test_should_yield_multiple_times_for_first_invocation_and_once_for_second_invocation expectation = new_expectation.multiple_yields([1, 2, 3], [4, 5]).then.yields(6, 7) yielded_parameters = [] invoke(expectation) { |*parameters| yielded_parameters << parameters } invoke(expectation) { |*parameters| yielded_parameters << parameters } assert_equal [[1, 2, 3], [4, 5], [6, 7]], yielded_parameters end def test_should_return_specified_value assert_equal 99, invoke(new_expectation.returns(99)) end def test_should_return_same_specified_value_multiple_times expectation = new_expectation.returns(99) assert_equal 99, invoke(expectation) assert_equal 99, invoke(expectation) end def test_should_return_specified_values_on_consecutive_calls expectation = new_expectation.returns(99, 100, 101) assert_equal 99, invoke(expectation) assert_equal 100, invoke(expectation) assert_equal 101, invoke(expectation) end def test_should_return_specified_values_on_consecutive_calls_even_if_values_are_modified values = [99, 100, 101] expectation = new_expectation.returns(*values) values.shift assert_equal 99, invoke(expectation) assert_equal 100, invoke(expectation) assert_equal 101, invoke(expectation) end def test_should_return_nil_by_default assert_nil invoke(new_expectation) end def test_should_return_nil_if_no_value_specified assert_nil invoke(new_expectation.returns) end def test_should_raise_runtime_exception assert_raises(RuntimeError) { invoke(new_expectation.raises) } end def test_should_raise_custom_exception exception = Class.new(Exception) assert_raises(exception) { invoke(new_expectation.raises(exception)) } end def test_should_raise_same_instance_of_custom_exception exception_klass = Class.new(StandardError) expected_exception = exception_klass.new actual_exception = assert_raises(exception_klass) { invoke(new_expectation.raises(expected_exception)) } assert_same expected_exception, actual_exception end def test_should_use_the_default_exception_message exception = assert_raises(Exception) { invoke(new_expectation.raises(Exception)) } assert_equal Exception.new.message, exception.message end def test_should_raise_custom_exception_with_message exception_msg = 'exception message' exception = assert_raises(Exception) { invoke(new_expectation.raises(Exception, exception_msg)) } assert_equal exception_msg, exception.message end def test_should_return_values_then_raise_exception expectation = new_expectation.returns(1, 2).then.raises assert_equal 1, invoke(expectation) assert_equal 2, invoke(expectation) assert_raises(RuntimeError) { invoke(expectation) } end def test_should_raise_exception_then_return_values expectation = new_expectation.raises.then.returns(1, 2) assert_raises(RuntimeError) { invoke(expectation) } assert_equal 1, invoke(expectation) assert_equal 2, invoke(expectation) end def test_should_verify_successfully_if_expected_call_was_made expectation = new_expectation invoke(expectation) assert expectation.verified? end def test_should_not_verify_successfully_if_call_expected_once_but_invoked_twice expectation = new_expectation.once invoke(expectation) invoke(expectation) assert !expectation.verified? end def test_should_not_verify_successfully_if_call_expected_once_but_not_invoked assert !new_expectation.once.verified? end def test_should_verify_successfully_if_call_expected_once_and_invoked_once expectation = new_expectation.once invoke(expectation) assert expectation.verified? end def test_should_not_verify_successfully_if_call_expected_twice_and_invoked_three_times expectation = new_expectation.twice invoke(expectation) invoke(expectation) invoke(expectation) assert !expectation.verified? end def test_should_not_verify_successfully_if_call_expected_twice_but_invoked_once expectation = new_expectation.twice invoke(expectation) assert !expectation.verified? end def test_should_verify_successfully_if_call_expected_twice_and_invoked_twice expectation = new_expectation.twice invoke(expectation) invoke(expectation) assert expectation.verified? end def test_should_verify_successfully_if_expected_call_was_made_at_least_once expectation = new_expectation.at_least_once 3.times { invoke(expectation) } assert expectation.verified? end def test_should_not_verify_successfully_if_expected_call_was_not_made_at_least_once expectation = new_expectation.with(1, 2, 3).at_least_once assert !expectation.verified? assert_match(/expected at least once, invoked never/i, expectation.mocha_inspect) end def test_should_verify_successfully_if_expected_call_was_made_expected_number_of_times expectation = new_expectation.times(2) 2.times { invoke(expectation) } assert expectation.verified? end def test_should_not_verify_successfully_if_expected_call_was_made_too_few_times expectation = new_expectation.times(2) 1.times { invoke(expectation) } assert !expectation.verified? assert_match(/expected exactly twice, invoked once/i, expectation.mocha_inspect) end def test_should_not_verify_successfully_if_expected_call_was_made_too_many_times expectation = new_expectation.times(2) 3.times { invoke(expectation) } assert !expectation.verified? end def test_should_increment_assertion_counter_for_expectation_because_it_does_need_verifyng expectation = new_expectation invoke(expectation) assertion_counter = SimpleCounter.new expectation.verified?(assertion_counter) assert_equal 1, assertion_counter.count end def test_should_not_increment_assertion_counter_for_stub_because_it_does_not_need_verifying assertion_counter = SimpleCounter.new Expectation.new(nil, :expected_method).at_least(0).verified?(assertion_counter) assert_equal 0, assertion_counter.count end def test_should_store_backtrace_from_point_where_expectation_was_created execution_point = ExecutionPoint.current; expectation = Expectation.new(nil, :expected_method) assert_equal execution_point, ExecutionPoint.new(expectation.backtrace) end class FakeMock def initialize(name) @name = name end def mocha_inspect @name end end def test_should_raise_error_with_message_indicating_which_method_was_expected_to_be_called_on_which_mock_object_with_which_parameters_and_in_what_sequences mock = FakeMock.new('mock') sequence_one = Sequence.new('one') sequence_two = Sequence.new('two') expectation = Expectation.new(mock, :expected_method).with(1, 2, { 'a' => true }, { b: false }, [1, 2, 3]).in_sequence(sequence_one, sequence_two) assert !expectation.verified? assert_match %{mock.expected_method(1, 2, {"a" => true}, {:b => false}, [1, 2, 3]); in sequence "one"; in sequence "two"}, expectation.mocha_inspect end class FakeConstraint def initialize(allows_invocation_now) @allows_invocation_now = allows_invocation_now end def allows_invocation_now? @allows_invocation_now end end def test_should_be_in_correct_order_if_all_ordering_constraints_allow_invocation_now constraint_one = FakeConstraint.new(true) constraint_two = FakeConstraint.new(true) expectation = Expectation.new(nil, :method_one) expectation.add_ordering_constraint(constraint_one) expectation.add_ordering_constraint(constraint_two) assert expectation.in_correct_order? end def test_should_not_be_in_correct_order_if_one_ordering_constraint_does_not_allow_invocation_now constraint_one = FakeConstraint.new(true) constraint_two = FakeConstraint.new(false) expectation = Expectation.new(nil, :method_one) expectation.add_ordering_constraint(constraint_one) expectation.add_ordering_constraint(constraint_two) assert !expectation.in_correct_order? end def test_should_match_if_all_ordering_constraints_allow_invocation_now constraint_one = FakeConstraint.new(true) constraint_two = FakeConstraint.new(true) expectation = Expectation.new(nil, :method_one) expectation.add_ordering_constraint(constraint_one) expectation.add_ordering_constraint(constraint_two) assert expectation.match?(Invocation.new(:irrelevant, :method_one)) end def test_should_not_match_if_one_ordering_constraints_does_not_allow_invocation_now constraint_one = FakeConstraint.new(true) constraint_two = FakeConstraint.new(false) expectation = Expectation.new(nil, :method_one) expectation.add_ordering_constraint(constraint_one) expectation.add_ordering_constraint(constraint_two) assert !expectation.match?(Invocation.new(:irrelevant, :method_one)) end def test_should_not_be_satisfied_when_required_invocation_has_not_been_made assert !Expectation.new(nil, :method_one).times(1).satisfied? end def test_should_be_satisfied_when_required_invocation_has_been_made expectation = Expectation.new(nil, :method_one).times(1) invoke(expectation) assert expectation.satisfied? end def test_should_not_be_satisfied_when_minimum_number_of_invocations_has_not_been_made expectation = Expectation.new(nil, :method_one).at_least(2) invoke(expectation) assert !expectation.satisfied? end def test_should_be_satisfied_when_minimum_number_of_invocations_has_been_made expectation = Expectation.new(nil, :method_one).at_least(2) 2.times { invoke(expectation) } assert expectation.satisfied? end class FakeSequence attr_reader :expectations def initialize @expectations = [] end def constrain_as_next_in_sequence(expectation) @expectations << expectation end end def test_should_tell_sequences_to_constrain_expectation_as_next_in_sequence sequence_one = FakeSequence.new sequence_two = FakeSequence.new expectation = Expectation.new(nil, :method_one) assert_equal expectation, expectation.in_sequence(sequence_one, sequence_two) assert_equal [expectation], sequence_one.expectations assert_equal [expectation], sequence_two.expectations end class FakeState def initialize @active = false end def activate @active = true end def active? @active end end def test_should_change_state_when_expectation_is_invoked state = FakeState.new expectation = Expectation.new(nil, :method_one) expectation.then(state) invoke(expectation) assert state.active? end def test_should_match_when_state_is_active state = FakeState.new expectation = Expectation.new(nil, :method_one) expectation.when(state) assert !expectation.match?(Invocation.new(:irrelevant, :method_one)) state.activate assert expectation.match?(Invocation.new(:irrelevant, :method_one)) end def test_should_include_default_representation_of_object_in_inspect object = Object.new class << object define_method(:inspect) { 'mock' } end assert_match Regexp.new('^#$'), Expectation.new(object, :method_one).inspect end def test_should_include_output_of_mocha_inspect_in_inspect object = Object.new class << object define_method(:inspect) { 'mock' } end expectation = Expectation.new(object, :method_one) assert expectation.inspect.include?(expectation.mocha_inspect) end end mocha-2.4.2/test/unit/hash_inspect_test.rb000066400000000000000000000015641464615054400206170ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/inspect' class HashInspectTest < Mocha::TestCase def test_should_return_string_representation_of_hash hash = { a: true, b: false } assert_equal '{:a => true, :b => false}', hash.mocha_inspect end if Mocha::RUBY_V27_PLUS def test_should_return_unwrapped_keyword_style_hash_when_keyword_hash hash = Hash.ruby2_keywords_hash(a: true, b: false) assert_equal 'a: true, b: false', hash.mocha_inspect end def test_should_return_unwrapped_hash_when_keyword_hash_keys_are_not_symbols hash = Hash.ruby2_keywords_hash('a' => true, 'b' => false) assert_equal '"a" => true, "b" => false', hash.mocha_inspect end end def test_should_use_mocha_inspect_on_each_key_and_value hash = { a: 'mocha' } assert_equal %({:a => "mocha"}), hash.mocha_inspect end end mocha-2.4.2/test/unit/hooks_test.rb000066400000000000000000000015211464615054400172630ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/hooks' require 'mocha/mockery' class HooksTest < Mocha::TestCase # rubocop:disable Style/ClassAndModuleChildren class Mocha::Mockery class << self attr_writer :instances end end # rubocop:enable Style/ClassAndModuleChildren class FakeMockery def verify(*args); end def teardown(_origin = nil) raise 'exception within Mockery#teardown' end end def test_ensure_mockery_instance_is_reset_even_when_an_exception_is_raised_in_mockery_teardown fake_test_case = Object.new.extend(Mocha::Hooks) mockery = FakeMockery.new Mocha::Mockery.instances = [mockery] begin fake_test_case.mocha_teardown rescue StandardError nil end assert_kind_of Mocha::Mockery::Null, Mocha::Mockery.instance end end mocha-2.4.2/test/unit/in_state_ordering_constraint_test.rb000066400000000000000000000020201464615054400240760ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/in_state_ordering_constraint' class InStateOrderingConstraintTest < Mocha::TestCase include Mocha class FakeStatePredicate attr_writer :active, :description def active? @active end def mocha_inspect @description end end def test_should_allow_invocation_when_state_is_active state_predicate = FakeStatePredicate.new ordering_constraint = InStateOrderingConstraint.new(state_predicate) state_predicate.active = true assert ordering_constraint.allows_invocation_now? state_predicate.active = false assert !ordering_constraint.allows_invocation_now? end def test_should_describe_itself_in_terms_of_the_state_predicates_description state_predicate = FakeStatePredicate.new ordering_constraint = InStateOrderingConstraint.new(state_predicate) state_predicate.description = 'the-state-predicate' assert_equal 'when the-state-predicate', ordering_constraint.mocha_inspect end end mocha-2.4.2/test/unit/instance_method_test.rb000066400000000000000000000166631464615054400213210ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/ruby_version' require 'method_definer' require 'mocha/class_methods' require 'mocha/mockery' require 'mocha/mock' require 'mocha/instance_method' class InstanceMethodTest < Mocha::TestCase include MethodDefiner include Mocha def class_with_method(method, result = nil) Class.new do extend ClassMethods singleton_class.extend(ClassMethods) singleton_class.send(:define_method, method) { result } if method end end def test_should_not_raise_error_hiding_method_that_isnt_defined klass = class_with_method(:irrelevant) method = InstanceMethod.new(klass, :method_x) assert_nothing_raised { method.hide_original_method } end def test_should_not_raise_error_hiding_method_in_class_that_implements_method_called_method klass = class_with_method(:method) method = InstanceMethod.new(klass, :method) assert_nothing_raised { method.hide_original_method } end def test_should_define_a_new_method_which_should_call_mocha_method_missing klass = class_with_method(:method_x) mocha = build_mock define_instance_method(klass, :mocha) { mocha } mocha.expects(:method_x).with(:param1, :param2).returns(:result) method = InstanceMethod.new(klass, :method_x) method.hide_original_method method.define_new_method result = klass.method_x(:param1, :param2) assert_equal :result, result assert mocha.__verified__? end def test_should_include_the_filename_and_line_number_in_exceptions klass = class_with_method(:method_x) mocha = build_mock define_instance_method(klass, :mocha) { mocha } mocha.stubs(:method_x).raises(Exception) method = InstanceMethod.new(klass, :method_x) method.hide_original_method method.define_new_method expected_filename = 'stubbed_method.rb' expected_line_number = 47 exception = assert_raises(Exception) { klass.method_x } matching_line = exception.backtrace.find do |line| filename, line_number, _context = line.split(':') filename.include?(expected_filename) && line_number.to_i == expected_line_number end assert_not_nil matching_line, "Expected to find #{expected_filename}:#{expected_line_number} in the backtrace:\n #{exception.backtrace.join("\n")}" end def test_should_remove_new_method klass = class_with_method(:method_x) method = InstanceMethod.new(klass, :method_x) method.remove_new_method assert_equal false, klass.respond_to?(:method_x) end def test_remove_new_method_restores_original_method klass = class_with_method(:method_x, :original_result) klass.singleton_class.send(:alias_method, :_method, :method) method = InstanceMethod.new(klass, :method_x) method.hide_original_method method.define_new_method method.remove_new_method assert klass.respond_to?(:method_x) assert_equal :original_result, klass.method_x end def test_remove_new_method_restores_original_method_accepting_a_block_parameter klass = Class.new do extend ClassMethods singleton_class.extend(ClassMethods) def self.method_x(&block) block.call if block_given? end end klass.singleton_class.send(:alias_method, :_method, :method) method = InstanceMethod.new(klass, :method_x) method.hide_original_method method.define_new_method method.remove_new_method block_called = false klass.method_x { block_called = true } assert block_called end def test_should_call_hide_original_method klass = class_with_method(:method_x) method = InstanceMethod.new(klass, :method_x) method.hide_original_method define_instance_accessor(method, :hide_called) replace_instance_method(method, :hide_original_method) { self.hide_called = true } method.stub assert method.hide_called end def test_should_call_define_new_method klass = class_with_method(:method_x) method = InstanceMethod.new(klass, :method_x) define_instance_accessor(method, :define_called) replace_instance_method(method, :define_new_method) { self.define_called = true } method.stub assert method.define_called end def test_should_call_remove_new_method klass = class_with_method(:method_x) method = InstanceMethod.new(klass, :method_x) mocha = build_mock define_instance_method(klass, :mocha) { mocha } replace_instance_method(method, :reset_mocha) {} define_instance_accessor(method, :remove_called) replace_instance_method(method, :remove_new_method) { self.remove_called = true } method.unstub assert method.remove_called end def test_should_call_mocha_unstub klass = class_with_method(:method_x) method = InstanceMethod.new(klass, :method_x) mocha = Class.new do class << self attr_accessor :unstub_method end def self.unstub(method) self.unstub_method = method end end define_instance_method(mocha, :any_expectations?) { true } replace_instance_method(method, :mock) { mocha } method.unstub assert_equal mocha.unstub_method, :method_x end def test_should_call_stubbee_reset_mocha_if_no_expectations_remaining klass = class_with_method(:method_x) method = InstanceMethod.new(klass, :method_x) replace_instance_method(method, :remove_new_method) {} mocha = Class.new define_instance_method(mocha, :unstub) { |method_name| } define_instance_method(mocha, :any_expectations?) { false } replace_instance_method(method, :mock) { mocha } stubbee = Class.new do attr_accessor :reset_mocha_called def reset_mocha self.reset_mocha_called = true end end.new replace_instance_method(method, :stubbee) { stubbee } method.unstub assert stubbee.reset_mocha_called end def test_should_return_mock_for_stubbee mocha = Object.new stubbee = Object.new define_instance_method(stubbee, :mocha) { mocha } method = InstanceMethod.new(stubbee, :method_name) assert_equal mocha, method.mock end def test_should_not_match_if_other_object_has_a_different_class method = InstanceMethod.new(Object.new, :method) other_object = Object.new assert !method.matches?(other_object) end def test_should_not_match_if_other_instance_method_has_different_stubbee stubbee1 = Object.new stubbee2 = Object.new method1 = InstanceMethod.new(stubbee1, :method) method2 = InstanceMethod.new(stubbee2, :method) assert !method1.matches?(method2) end def test_should_not_match_if_other_instance_method_has_different_method stubbee = Object.new method1 = InstanceMethod.new(stubbee, :method_1) method2 = InstanceMethod.new(stubbee, :method_2) assert !method1.matches?(method2) end def test_should_match_if_other_instance_method_has_same_stubbee_and_same_method_so_no_attempt_is_made_to_stub_a_method_twice stubbee = Object.new method1 = InstanceMethod.new(stubbee, :method) method2 = InstanceMethod.new(stubbee, :method) assert method1.matches?(method2) end def test_should_match_if_other_instance_method_has_same_stubbee_and_same_method_but_stubbee_equal_method_lies_like_active_record_association_proxy stubbee = Class.new do extend ClassMethods def equal?(_other) false end end.new method1 = InstanceMethod.new(stubbee, :method) method2 = InstanceMethod.new(stubbee, :method) assert method1.matches?(method2) end private def build_mock Mock.new(Mockery.new) end end mocha-2.4.2/test/unit/method_matcher_test.rb000066400000000000000000000016031464615054400211240ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/method_matcher' class MethodMatcherTest < Mocha::TestCase include Mocha def test_should_match_if_actual_method_name_is_same_as_expected_method_name method_matcher = MethodMatcher.new(:method_name) assert method_matcher.match?(:method_name) end def test_should_match_if_actual_method_name_is_expected_method_name_as_string method_matcher = MethodMatcher.new(:method_name) assert method_matcher.match?('method_name') end def test_should_not_match_if_actual_method_name_is_not_same_as_expected_method_name method_matcher = MethodMatcher.new(:method_name) assert !method_matcher.match?(:different_method_name) end def test_should_describe_what_method_is_expected method_matcher = MethodMatcher.new(:method_name) assert_equal 'method_name', method_matcher.mocha_inspect end end mocha-2.4.2/test/unit/mock_test.rb000066400000000000000000000244671464615054400171070ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/macos_version' require 'mocha/mockery' require 'mocha/mock' require 'mocha/expectation_error_factory' require 'set' require 'simple_counter' class MockTest < Mocha::TestCase include Mocha def test_should_set_single_expectation mock = build_mock mock.expects(:method1).returns(1) assert_nothing_raised(ExpectationErrorFactory.exception_class) do assert_equal 1, mock.method1 end end def test_should_build_and_store_expectations mock = build_mock expectation = mock.expects(:method1) assert_not_nil expectation assert_equal [expectation], mock.__expectations__.to_a end def test_should_not_stub_everything_by_default mock = build_mock assert_equal false, mock.everything_stubbed end def test_should_stub_everything mock = build_mock mock.stub_everything assert_equal true, mock.everything_stubbed end def test_should_be_able_to_extend_mock_object_with_module mock = build_mock assert_nothing_raised(ExpectationErrorFactory.exception_class) { mock.extend(Module.new) } end def test_should_be_equal mock = build_mock assert_equal true, mock.eql?(mock) end MACOS_EXCLUDED_METHODS = MACOS && MACOS_VERSION >= MACOS_MOJAVE_VERSION ? [:syscall] : [] EXCLUDED_METHODS = [ :object_id, :method_missing, :singleton_method_undefined, :initialize, :String, :singleton_method_added, *MACOS_EXCLUDED_METHODS ].freeze OBJECT_METHODS = STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS.reject do |m| (m =~ /^__.*__$/) || EXCLUDED_METHODS.include?(m) end def test_should_be_able_to_mock_standard_object_methods mock = build_mock OBJECT_METHODS.each { |method| mock.__expects__(method.to_sym).returns(method) } OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) } assert mock.__verified__? end def test_should_be_able_to_stub_standard_object_methods mock = build_mock OBJECT_METHODS.each { |method| mock.__stubs__(method.to_sym).returns(method) } OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) } end def test_should_create_and_add_expectations mock = build_mock expectation1 = mock.expects(:method1) expectation2 = mock.expects(:method2) assert_equal [expectation1, expectation2].to_set, mock.__expectations__.to_set end def test_should_pass_backtrace_into_expectation mock = build_mock backtrace = Object.new expectation = mock.expects(:method1, backtrace) assert_equal backtrace, expectation.backtrace end def test_should_pass_backtrace_into_stub mock = build_mock backtrace = Object.new stub = mock.stubs(:method1, backtrace) assert_equal backtrace, stub.backtrace end def test_should_create_and_add_stubs mock = build_mock stub1 = mock.stubs(:method1) stub2 = mock.stubs(:method2) assert_equal [stub1, stub2].to_set, mock.__expectations__.to_set end def test_should_invoke_expectation_and_return_result mock = build_mock mock.expects(:my_method).returns(:result) result = mock.my_method assert_equal :result, result end def test_should_not_raise_error_if_stubbing_everything mock = build_mock mock.stub_everything result = nil assert_nothing_raised(ExpectationErrorFactory.exception_class) do result = mock.unexpected_method end assert_nil result end def test_should_raise_assertion_error_for_unexpected_method_call mock = build_mock error = assert_raises(ExpectationErrorFactory.exception_class) do mock.unexpected_method_called(:my_method, :argument1, :argument2) end assert_match(/unexpected invocation/, error.message) assert_match(/my_method/, error.message) assert_match(/argument1/, error.message) assert_match(/argument2/, error.message) end def test_should_not_verify_successfully_because_not_all_expectations_have_been_satisfied mock = build_mock mock.expects(:method1) mock.expects(:method2) mock.method1 assert !mock.__verified__? end def test_should_increment_assertion_counter_for_every_verified_expectation mock = build_mock mock.expects(:method1) mock.method1 mock.expects(:method2) mock.method2 assertion_counter = SimpleCounter.new mock.__verified__?(assertion_counter) assert_equal 2, assertion_counter.count end def test_should_yield_supplied_parameters_to_block mock = build_mock parameters_for_yield = [1, 2, 3] mock.expects(:method1).yields(*parameters_for_yield) yielded_parameters = nil mock.method1 { |*parameters| yielded_parameters = parameters } assert_equal parameters_for_yield, yielded_parameters end def test_should_set_up_multiple_expectations_with_return_values mock = build_mock mock.expects(method1: :result1, method2: :result2) assert_equal :result1, mock.method1 assert_equal :result2, mock.method2 end def test_should_set_up_multiple_stubs_with_return_values mock = build_mock mock.stubs(method1: :result1, method2: :result2) assert_equal :result1, mock.method1 assert_equal :result2, mock.method2 end def test_should_keep_returning_specified_value_for_stubs mock = build_mock mock.stubs(:method1).returns(1) assert_equal 1, mock.method1 assert_equal 1, mock.method1 end def test_should_keep_returning_specified_value_for_expects mock = build_mock mock.expects(:method1).times(2).returns(1) assert_equal 1, mock.method1 assert_equal 1, mock.method1 end def test_should_match_most_recent_call_to_expects mock = build_mock mock.expects(:method1).returns(0) mock.expects(:method1).returns(1) assert_equal 1, mock.method1 end def test_should_match_most_recent_call_to_stubs mock = build_mock mock.stubs(:method1).returns(0) mock.stubs(:method1).returns(1) assert_equal 1, mock.method1 end def test_should_match_most_recent_call_to_stubs_or_expects mock = build_mock mock.stubs(:method1).returns(0) mock.expects(:method1).returns(1) assert_equal 1, mock.method1 end def test_should_match_most_recent_call_to_expects_or_stubs mock = build_mock mock.expects(:method1).returns(0) mock.stubs(:method1).returns(1) assert_equal 1, mock.method1 end def test_should_respond_to_expected_method mock = build_mock mock.expects(:method1) assert_equal true, mock.respond_to?(:method1) end def test_should_respond_to_expected_method_as_string mock = build_mock mock.expects(:method1) assert_equal true, mock.respond_to?('method1') end def test_should_not_respond_to_unexpected_method mock = build_mock assert_equal false, mock.respond_to?(:method1) end def test_should_respond_to_methods_which_the_responder_does_responds_to instance = Class.new do define_method(:invoked_method) {} end.new mock = build_mock mock.responds_like(instance) assert_equal true, mock.respond_to?(:invoked_method) end def test_should_not_respond_to_methods_which_the_responder_does_not_responds_to instance = Class.new.new mock = build_mock mock.responds_like(instance) assert_equal false, mock.respond_to?(:invoked_method) end def test_should_respond_to_methods_which_the_responder_instance_does_responds_to klass = Class.new do define_method(:invoked_method) {} end mock = build_mock mock.responds_like_instance_of(klass) assert_equal true, mock.respond_to?(:invoked_method) end def test_should_not_respond_to_methods_which_the_responder_instance_does_not_responds_to klass = Class.new mock = build_mock mock.responds_like_instance_of(klass) assert_equal false, mock.respond_to?(:invoked_method) end def test_respond_like_should_return_itself_to_allow_method_chaining mock = build_mock assert_same mock.responds_like(Object.new), mock end def test_respond_like_instance_of_should_return_itself_to_allow_method_chaining mock = build_mock assert_same mock.responds_like_instance_of(Object), mock end def test_should_not_raise_no_method_error_if_mock_is_not_restricted_to_respond_like_a_responder mock = build_mock mock.stubs(:invoked_method) assert_nothing_raised(NoMethodError) { mock.invoked_method } end def test_should_not_raise_no_method_error_if_responder_does_respond_to_invoked_method instance = Class.new do define_method(:invoked_method) {} end.new mock = build_mock mock.responds_like(instance) mock.stubs(:invoked_method) assert_nothing_raised(NoMethodError) { mock.invoked_method } end def test_should_raise_no_method_error_if_responder_does_not_respond_to_invoked_method instance = Class.new do define_method(:mocha_inspect) { 'mocha_inspect' } end.new mock = build_mock mock.responds_like(instance) mock.stubs(:invoked_method) assert_raises(NoMethodError) { mock.invoked_method } end def test_should_raise_no_method_error_with_message_indicating_that_mock_is_constrained_to_respond_like_responder instance = Class.new do define_method(:mocha_inspect) { 'mocha_inspect' } end.new mock = build_mock mock.responds_like(instance) mock.stubs(:invoked_method) begin mock.invoked_method rescue NoMethodError => e assert_match(/which responds like mocha_inspect/, e.message) end end def test_should_handle_respond_to_with_private_methods_param_without_error mock = build_mock assert_nothing_raised { mock.respond_to?(:object_id, false) } end def test_should_respond_to_any_method_if_stubbing_everything mock = build_mock mock.stub_everything assert mock.respond_to?(:abc) assert mock.respond_to?(:xyz) end def test_should_remove_expectations_for_unstubbed_methods mock = build_mock mock.expects(:method1) mock.expects(:method2) mock.unstub(:method1, :method2) e = assert_raises(ExpectationErrorFactory.exception_class) { mock.method1 } assert_match(/unexpected invocation/, e.message) e = assert_raises(ExpectationErrorFactory.exception_class) { mock.method2 } assert_match(/unexpected invocation/, e.message) end def test_expectation_is_defined_on_mock mock = build_mock mock.expects(:method1) assert defined? mock.method1 end private def build_mock Mock.new(Mockery.new) end end mocha-2.4.2/test/unit/mockery_test.rb000066400000000000000000000116621464615054400176200ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/mockery' require 'mocha/state_machine' require 'mocha/expectation_error_factory' class MockeryTest < Mocha::TestCase include Mocha def setup Mockery.setup end def teardown Mockery.teardown end def test_should_return_null_mockery_if_not_setup Mockery.teardown mockery = Mockery.instance assert_not_nil mockery assert_kind_of Mockery::Null, mockery end def test_should_return_instance_of_mockery mockery = Mockery.instance assert_not_nil mockery assert_kind_of Mockery, mockery end def test_should_cache_instance_of_mockery mockery1 = Mockery.instance mockery2 = Mockery.instance assert_same mockery1, mockery2 end def test_should_expire_mockery_instance_cache mockery1 = Mockery.instance Mockery.teardown mockery2 = Mockery.instance assert_not_same mockery1, mockery2 end def test_should_raise_expectation_error_because_not_all_expectations_are_satisfied mockery = Mockery.new mock1 = mockery.named_mock('mock-1') mock1.expects(:method_1) mock2 = mockery.named_mock('mock-2') mock2.expects(:method_2) 1.times { mock1.method_1 } 0.times { mock2.method_2 } assert_raises(ExpectationErrorFactory.exception_class) { mockery.verify } end def test_should_reset_list_of_mocks_on_teardown mockery = Mockery.new mock = mockery.unnamed_mock mock.expects(:my_method) mockery.teardown assert_nothing_raised(ExpectationErrorFactory.exception_class) { mockery.verify } end def test_should_build_instance_of_stubba_on_instantiation mockery = Mockery.new assert_not_nil mockery.stubba assert_kind_of Central, mockery.stubba end def test_should_build_new_instance_of_stubba_on_teardown mockery = Mockery.new stubba1 = mockery.stubba mockery.teardown stubba2 = mockery.stubba assert_not_same stubba1, stubba2 end def test_should_build_and_store_new_state_machine mockery = Mockery.new mockery.new_state_machine('state-machine-name') assert_equal 1, mockery.state_machines.length assert_kind_of StateMachine, mockery.state_machines[0] end def test_should_reset_list_of_state_machines_on_teardown mockery = Mockery.new mockery.new_state_machine('state-machine-name') mockery.teardown assert_equal 0, mockery.state_machines.length end class FakeMethod def stub; end def unstub; end def matches?(_other) true end end def test_should_unstub_all_methods_on_teardown mockery = Mockery.new stubba = mockery.stubba stubba.stub(FakeMethod.new) mockery.teardown assert stubba.stubba_methods.empty? end def test_should_display_object_id_for_mocha_inspect_if_mock_has_no_name mockery = Mockery.new mock = mockery.unnamed_mock assert_match Regexp.new('^#$'), mock.mocha_inspect end def test_should_display_object_id_for_inspect_if_mock_has_no_name mockery = Mockery.new mock = mockery.unnamed_mock assert_match Regexp.new('^#$'), mock.inspect end def test_should_display_name_for_mocha_inspect_if_mock_has_string_name mockery = Mockery.new mock = mockery.named_mock('named_mock') assert_equal '#', mock.mocha_inspect end def test_should_display_name_for_mocha_inspect_if_mock_has_symbol_name mockery = Mockery.new mock = mockery.named_mock(:named_mock) assert_equal '#', mock.mocha_inspect end def test_should_display_name_for_inspect_if_mock_has_string_name mockery = Mockery.new mock = mockery.named_mock('named_mock') assert_equal '#', mock.inspect end def test_should_display_name_for_inspect_if_mock_has_symbol_name mockery = Mockery.new mock = mockery.named_mock(:named_mock) assert_equal '#', mock.inspect end def test_should_display_impersonated_object_for_mocha_inspect mockery = Mockery.new instance = Object.new mock = mockery.mock_impersonating(instance) assert_equal instance.mocha_inspect.to_s, mock.mocha_inspect end def test_should_display_impersonated_object_for_inspect mockery = Mockery.new instance = Object.new mock = mockery.mock_impersonating(instance) assert_equal instance.mocha_inspect.to_s, mock.inspect end class FakeClass; end def test_should_display_any_instance_prefix_followed_by_class_whose_instances_are_being_impersonated_for_mocha_inspect mockery = Mockery.new mock = mockery.mock_impersonating_any_instance_of(FakeClass) assert_equal '#', mock.mocha_inspect end def test_should_display_any_instance_prefix_followed_by_class_whose_instances_are_being_impersonated_for_inspect mockery = Mockery.new mock = mockery.mock_impersonating_any_instance_of(FakeClass) assert_equal '#', mock.inspect end end mocha-2.4.2/test/unit/module_methods_test.rb000066400000000000000000000006471464615054400211600ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/object_methods' class ModuleMethodsTest < Mocha::TestCase def setup @module = Module.new.extend(Mocha::ObjectMethods) end def test_should_use_stubba_module_method_for_module assert_equal Mocha::InstanceMethod, @module.stubba_method end def test_should_stub_self_for_module assert_equal @module, @module.stubba_object end end mocha-2.4.2/test/unit/object_inspect_test.rb000077500000000000000000000027241464615054400211440ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/inspect' require 'method_definer' class ObjectInspectTest < Mocha::TestCase include MethodDefiner def test_should_return_default_string_representation_of_object_not_including_instance_variables object = Object.new class << object attr_accessor :attribute end object.attribute = 'instance_variable' assert_match Regexp.new('^#$'), object.mocha_inspect assert_no_match(/instance_variable/, object.mocha_inspect) end def test_should_return_customized_string_representation_of_object object = Object.new class << object define_method(:inspect) { 'custom_inspect' } end assert_equal 'custom_inspect', object.mocha_inspect end def test_should_use_underscored_id_instead_of_object_id_or_id_so_that_they_can_be_stubbed calls = [] object = Object.new replace_instance_method(object, :object_id) do calls << :object_id return 1 end replace_instance_method(object, :__id__) do calls << :__id__ return 1 end replace_instance_method(object, :inspect) { 'object-description' } object.mocha_inspect assert_equal [:__id__], calls.uniq end def test_should_not_call_object_instance_format_method object = Object.new class << object def format(*) 'internal_format' end end assert_no_match(/internal_format/, object.mocha_inspect) end end mocha-2.4.2/test/unit/object_methods_test.rb000066400000000000000000000032651464615054400211400ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/object_methods' require 'mocha/mockery' require 'mocha/mock' require 'mocha/expectation_error_factory' require 'mocha/names' class ObjectMethodsTest < Mocha::TestCase def setup Mocha::Mockery.setup @object = Object.new.extend(Mocha::ObjectMethods) end def teardown Mocha::Mockery.teardown end def test_should_build_mocha_referring_to_self mocha = @object.mocha assert_not_nil mocha assert mocha.is_a?(Mocha::Mock) expected_name = Mocha::ImpersonatingName.new(@object).mocha_inspect assert_equal expected_name, mocha.mocha_inspect end def test_should_not_build_mocha_if_instantiate_is_false assert_nil @object.mocha(false) end def test_should_reuse_existing_mocha mocha1 = @object.mocha mocha2 = @object.mocha assert_equal mocha1, mocha2 end def test_should_reuse_existing_mocha_even_if_instantiate_is_false mocha1 = @object.mocha mocha2 = @object.mocha(false) assert_equal mocha1, mocha2 end def test_should_reset_mocha assert_nil @object.reset_mocha end def test_should_use_stubba_instance_method_for_object assert_equal Mocha::InstanceMethod, @object.stubba_method end def test_should_stub_self_for_object assert_equal @object, @object.stubba_object end def test_nobody_expects_the_spanish_inquisition assert_raises(Mocha::ExpectationErrorFactory.exception_class) { @object.expects(:the_spanish_inquisition) } end def test_should_alias_object_method klass = Class.new { def self.method_x; end } klass.extend(Mocha::ObjectMethods) assert_equal klass._method(:method_x), klass.method(:method_x) end end mocha-2.4.2/test/unit/parameter_matchers/000077500000000000000000000000001464615054400204235ustar00rootroot00000000000000mocha-2.4.2/test/unit/parameter_matchers/all_of_test.rb000066400000000000000000000015371464615054400232510ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/all_of' require 'mocha/inspect' require 'stub_matcher' class AllOfTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_if_all_matchers_match matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(true), Stub::Matcher.new(true)) assert matcher.matches?(['any_old_value']) end def test_should_not_match_if_any_matcher_does_not_match matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(false), Stub::Matcher.new(true)) assert !matcher.matches?(['any_old_value']) end def test_should_describe_matcher matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(false), Stub::Matcher.new(true)) assert_equal 'all_of(matcher(true), matcher(false), matcher(true))', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/any_of_test.rb000066400000000000000000000015341464615054400232650ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/any_of' require 'mocha/inspect' require 'stub_matcher' class AnyOfTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_if_any_matchers_match matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(true), Stub::Matcher.new(false)) assert matcher.matches?(['any_old_value']) end def test_should_not_match_if_no_matchers_match matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(false), Stub::Matcher.new(false)) assert !matcher.matches?(['any_old_value']) end def test_should_describe_matcher matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(true), Stub::Matcher.new(false)) assert_equal 'any_of(matcher(false), matcher(true), matcher(false))', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/anything_test.rb000066400000000000000000000007301464615054400236300ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/anything' require 'mocha/inspect' class AnythingTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_anything matcher = anything assert matcher.matches?([:something]) assert matcher.matches?([{ 'x' => 'y' }]) end def test_should_describe_matcher matcher = anything assert_equal 'anything', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/equals_test.rb000066400000000000000000000010631464615054400233010ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/equals' require 'mocha/inspect' class EqualsTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_object_that_equals_value matcher = equals('x') assert matcher.matches?(['x']) end def test_should_not_match_object_that_does_not_equal_value matcher = equals('x') assert !matcher.matches?(['y']) end def test_should_describe_matcher matcher = equals('x') assert_equal %("x"), matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/equivalent_uri_test.rb000066400000000000000000000027171464615054400250520ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/equivalent_uri' class EquivalentUriMatchesTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_identical_uri matcher = equivalent_uri('http://example.com/foo?a=1&b=2') assert matcher.matches?(['http://example.com/foo?a=1&b=2']) end def test_should_match_uri_with_rearranged_query_string matcher = equivalent_uri('http://example.com/foo?b=2&a=1') assert matcher.matches?(['http://example.com/foo?a=1&b=2']) end def test_should_not_match_uri_with_different_query_string matcher = equivalent_uri('http://example.com/foo?a=1') assert !matcher.matches?(['http://example.com/foo?a=1&b=2']) end def test_should_not_match_uri_when_no_query_string_expected matcher = equivalent_uri('http://example.com/foo') assert !matcher.matches?(['http://example.com/foo?a=1&b=2']) end def test_should_not_match_uri_with_different_domain matcher = equivalent_uri('http://a.example.com/foo?a=1&b=2') assert !matcher.matches?(['http://b.example.com/foo?a=1&b=2']) end def test_should_match_uri_without_scheme_and_domain matcher = equivalent_uri('/foo?a=1&b=2') assert matcher.matches?(['/foo?a=1&b=2']) end def test_should_match_uri_with_query_string_containing_blank_value matcher = equivalent_uri('http://example.com/foo?a=&b=2') assert matcher.matches?(['http://example.com/foo?a=&b=2']) end end mocha-2.4.2/test/unit/parameter_matchers/has_entries_test.rb000066400000000000000000000042541464615054400243200ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/has_entries' require 'mocha/parameter_matchers/instance_methods' require 'mocha/inspect' class HasEntriesTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_hash_including_specified_entries matcher = has_entries(key_1: 'value_1', key_2: 'value_2') assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2', key_3: 'value_3' }]) end def test_should_not_match_hash_not_including_specified_entries matcher = has_entries(key_1: 'value_2', key_2: 'value_2', key_3: 'value_3') assert !matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_describe_matcher matcher = has_entries(key_1: 'value_1', key_2: 'value_2') description = matcher.mocha_inspect matches = /has_entries\((.*)\)/.match(description) assert_not_nil matches[0] # rubocop:disable Security/Eval entries = eval(matches[1], binding, __FILE__, __LINE__) # rubocop:enable Security/Eval assert_equal 'value_1', entries[:key_1] assert_equal 'value_2', entries[:key_2] end def test_should_match_hash_including_specified_entries_with_nested_key_matchers matcher = has_entries(equals(:key_1) => 'value_1', equals(:key_2) => 'value_2') assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2', key_3: 'value_3' }]) end def test_should_not_match_hash_not_including_specified_entries_with_nested_key_matchers matcher = has_entries(equals(:key_1) => 'value_2', equals(:key_2) => 'value_2', equals(:key_3) => 'value_3') assert !matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_match_hash_including_specified_entries_with_nested_value_matchers matcher = has_entries(key_1: equals('value_1'), key_2: equals('value_2')) assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2', key_3: 'value_3' }]) end def test_should_not_match_hash_not_including_specified_entries_with_nested_value_matchers matcher = has_entries(key_1: equals('value_2'), key_2: equals('value_2'), key_3: equals('value_3')) assert !matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end end mocha-2.4.2/test/unit/parameter_matchers/has_entry_test.rb000066400000000000000000000113121464615054400240010ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/has_entry' require 'mocha/parameter_matchers/instance_methods' require 'mocha/parameter_matchers/equals' require 'mocha/inspect' class HasEntryTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_hash_including_specified_key_value_pair matcher = has_entry(:key_1, 'value_1') assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_not_match_hash_not_including_specified_key_value_pair matcher = has_entry(:key_1, 'value_2') assert !matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_match_hash_including_specified_entry matcher = has_entry(key_1: 'value_1') assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_not_match_hash_not_including_specified_entry matcher = has_entry(key_1: 'value_2') assert !matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_describe_matcher_with_key_value_pair matcher = has_entry(:key_1, 'value_1') assert_equal %{has_entry(:key_1 => "value_1")}, matcher.mocha_inspect end def test_should_describe_matcher_with_entry matcher = has_entry(key_1: 'value_1') assert_equal %{has_entry(:key_1 => "value_1")}, matcher.mocha_inspect end def test_should_match_hash_including_specified_entry_with_nested_key_matcher matcher = has_entry(equals(:key_1) => 'value_1') assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_match_hash_including_specified_entry_with_nested_value_matcher matcher = has_entry(key_1: equals('value_1')) assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_not_match_hash_not_including_specified_entry_with_nested_key_matcher matcher = has_entry(equals(:key_1) => 'value_2') assert !matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_not_match_hash_not_including_specified_entry_with_nested_value_matcher matcher = has_entry(key_1: equals('value_2')) assert !matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_not_match_object_that_doesnt_respond_to_keys matcher = has_entry(key_1: equals('value_2')) object = Class.new do def [](_key) 'value_2' end end.new assert !matcher.matches?([object]) end def test_should_not_match_object_that_doesnt_respond_to_square_bracket matcher = has_entry(key_1: equals('value_2')) object = Class.new do def keys [:key_1] end end.new assert !matcher.matches?([object]) end def test_should_raise_argument_error_if_single_argument_is_not_a_hash e = assert_raises(ArgumentError) do has_entry([]) end assert_equal 'Argument is not a Hash.', e.message end def test_should_raise_argument_error_if_no_entries_are_supplied e = assert_raises(ArgumentError) do has_entry({}) end assert_equal 'Argument has no entries.', e.message end def test_should_raise_argument_error_if_no_arguments_are_supplied e = assert_raises(ArgumentError) { has_entry } assert_equal 'No arguments. Expecting at least one.', e.message end def test_should_raise_argument_error_if_multiple_entries_are_supplied e = assert_raises(ArgumentError) do has_entry(key_1: 'value_1', key_2: 'value_2') end assert_equal 'Argument has multiple entries. Use Mocha::ParameterMatchers#has_entries instead.', e.message end def test_should_raise_argument_error_if_more_than_two_arguments_are_supplied e = assert_raises(ArgumentError) do has_entry(1, 2, 3) end assert_equal 'Too many arguments; use either a single argument (must be a Hash) or two arguments (a key and a value).', e.message end def test_should_match_array_as_key matcher = has_entry([:key_1, :key_2] => 'value_1') assert matcher.matches?([{ [:key_1, :key_2] => 'value_1', key_3: 'value_2' }]) end def test_should_match_array_as_value matcher = has_entry(key_1: %w[value_1 value_2]) assert matcher.matches?([{ key_1: %w[value_1 value_2] }]) end def test_should_match_hash_as_value_and_key matcher = has_entry({ key_1: 'value_1', key_2: 'value_2' } => { key_3: 'value_3', key_4: 'value_4' }) assert matcher.matches?([{ { key_1: 'value_1', key_2: 'value_2' } => { key_3: 'value_3', key_4: 'value_4' }, key_5: 'value_5' }]) end def test_should_match_matcher_as_value_and_key matcher = has_entry(has_entry(key_1: 'value_1') => has_entry(key_3: 'value_3')) assert matcher.matches?([{ { key_1: 'value_1', key_2: 'value_2' } => { key_3: 'value_3', key_4: 'value_4' }, key_5: 'value_5' }]) end end mocha-2.4.2/test/unit/parameter_matchers/has_key_test.rb000066400000000000000000000030541464615054400234340ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/has_key' require 'mocha/parameter_matchers/instance_methods' require 'mocha/inspect' class HasKeyTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_hash_including_specified_key matcher = has_key(:key_1) assert matcher.matches?([{ key_1: 1, key_2: 2 }]) end def test_should_not_match_hash_not_including_specified_key matcher = has_key(:key_1) assert !matcher.matches?([{ key_2: 2 }]) end def test_should_describe_matcher matcher = has_key(:key) assert_equal 'has_key(:key)', matcher.mocha_inspect end def test_should_match_hash_including_specified_key_with_nested_key_matcher matcher = has_key(equals(:key_1)) assert matcher.matches?([{ key_1: 1, key_2: 2 }]) end def test_should_not_match_hash_not_including_specified_key_with_nested_key_matcher matcher = has_key(equals(:key_1)) assert !matcher.matches?([{ key_2: 2 }]) end def test_should_not_raise_error_on_empty_arguments matcher = has_key(:key) assert_nothing_raised { matcher.matches?([]) } end def test_should_not_match_on_empty_arguments matcher = has_key(:key) assert !matcher.matches?([]) end def test_should_not_raise_error_on_argument_that_does_not_respond_to_keys matcher = has_key(:key) assert_nothing_raised { matcher.matches?([:key]) } end def test_should_not_match_on_argument_that_does_not_respond_to_keys matcher = has_key(:key) assert !matcher.matches?([:key]) end end mocha-2.4.2/test/unit/parameter_matchers/has_keys_test.rb000066400000000000000000000040161464615054400236160ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/has_keys' require 'mocha/parameter_matchers/instance_methods' require 'mocha/inspect' class HasKeysTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_hash_including_specified_keys matcher = has_keys(:key_1, :key_2) assert matcher.matches?([{ key_1: 1, key_2: 2, key_3: 3 }]) end def test_should_not_match_hash_not_including_specified_keys matcher = has_keys(:key_1, :key_2) assert !matcher.matches?([{ key_3: 3 }]) end def test_should_not_match_hash_not_including_all_keys matcher = has_keys(:key_1, :key_2) assert !matcher.matches?([{ key_1: 1, key_3: 3 }]) end def test_should_describe_matcher matcher = has_keys(:key_1, :key_2) assert_equal 'has_keys(:key_1, :key_2)', matcher.mocha_inspect end def test_should_match_hash_including_specified_key_with_nested_key_matcher matcher = has_keys(equals(:key_1), equals(:key_2)) assert matcher.matches?([{ key_1: 1, key_2: 2 }]) end def test_should_not_match_hash_not_including_specified_keys_with_nested_key_matchers matcher = has_keys(equals(:key_1), equals(:key2)) assert !matcher.matches?([{ key_2: 2 }]) end def test_should_not_raise_error_on_empty_arguments matcher = has_keys(:key_1, :key_2) assert_nothing_raised { matcher.matches?([]) } end def test_should_not_match_on_empty_arguments matcher = has_keys(:key_1, :key_2) assert !matcher.matches?([]) end def test_should_not_raise_error_on_argument_that_does_not_respond_to_keys matcher = has_keys(:key_1, :key_2) assert_nothing_raised { matcher.matches?([:key_1]) } end def test_should_not_match_on_argument_that_does_not_respond_to_keys matcher = has_keys(:key_1, :key_2) assert !matcher.matches?([:key_1]) end def test_should_raise_argument_error_if_no_keys_are_supplied e = assert_raises(ArgumentError) { has_keys } assert_equal 'No arguments. Expecting at least one.', e.message end end mocha-2.4.2/test/unit/parameter_matchers/has_value_test.rb000066400000000000000000000033401464615054400237560ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/has_value' require 'mocha/parameter_matchers/instance_methods' require 'mocha/parameter_matchers/equals' require 'mocha/inspect' class HasValueTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_hash_including_specified_value matcher = has_value('value_1') assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_not_match_hash_not_including_specified_value matcher = has_value('value_1') assert !matcher.matches?([{ key_2: 'value_2' }]) end def test_should_describe_matcher matcher = has_value('value_1') assert_equal %{has_value("value_1")}, matcher.mocha_inspect end def test_should_match_hash_including_specified_value_with_nested_value_matcher matcher = has_value(equals('value_1')) assert matcher.matches?([{ key_1: 'value_1', key_2: 'value_2' }]) end def test_should_not_match_hash_not_including_specified_value_with_nested_value_matcher matcher = has_value(equals('value_1')) assert !matcher.matches?([{ key_2: 'value_2' }]) end def test_should_not_raise_error_on_empty_arguments matcher = has_value('value_1') assert_nothing_raised { matcher.matches?([]) } end def test_should_not_match_empty_arguments matcher = has_value('value_1') assert !matcher.matches?([]) end def test_should_not_raise_error_on_argument_that_does_not_respond_to_values matcher = has_value('value_1') assert_nothing_raised { matcher.matches?(['value_1']) } end def test_should_not_match_on_argument_that_does_not_respond_to_values matcher = has_value('value_1') assert !matcher.matches?(['value_1']) end end mocha-2.4.2/test/unit/parameter_matchers/includes_test.rb000066400000000000000000000063301464615054400236170ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/includes' require 'mocha/parameter_matchers/instance_methods' require 'mocha/parameter_matchers/has_key' require 'mocha/parameter_matchers/regexp_matches' require 'mocha/inspect' class IncludesTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_object_including_value matcher = includes(:x) assert matcher.matches?([[:x, :y, :z]]) end def test_should_match_object_including_array_value matcher = includes([:x]) assert matcher.matches?([[[:x], [:y], [:z]]]) end def test_should_match_object_including_all_values matcher = includes(:x, :y, :z) assert matcher.matches?([[:x, :y, :z]]) end def test_should_not_match_object_that_does_not_include_value matcher = includes(:not_included) assert !matcher.matches?([[:x, :y, :z]]) end def test_should_not_match_object_that_does_not_include_any_one_value matcher = includes(:x, :y, :z, :not_included) assert !matcher.matches?([[:x, :y, :z]]) end def test_should_describe_matcher_with_one_item matcher = includes(:x) assert_equal 'includes(:x)', matcher.mocha_inspect end def test_should_describe_matcher_with_multiple_items matcher = includes(:x, :y, :z) assert_equal 'includes(:x, :y, :z)', matcher.mocha_inspect end def test_should_not_raise_error_on_emtpy_arguments matcher = includes(:x) assert_nothing_raised { matcher.matches?([]) } end def test_should_not_match_on_empty_arguments matcher = includes(:x) assert !matcher.matches?([]) end def test_should_not_raise_error_on_argument_that_does_not_respond_to_include matcher = includes(:x) assert_nothing_raised { matcher.matches?([:x]) } end def test_should_not_match_on_argument_that_does_not_respond_to_include matcher = includes(:x) assert !matcher.matches?([:x]) end def test_should_match_object_including_value_which_matches_nested_matcher matcher = includes(has_key(:key)) assert matcher.matches?([[:non_matching_element, { key: 'value' }]]) end def test_should_not_match_object_which_doesnt_include_value_that_matches_nested_matcher matcher = includes(has_key(:key)) assert !matcher.matches?([[:non_matching_element, { other_key: 'other-value' }]]) end def test_should_match_string_argument_containing_substring matcher = includes('bar') assert matcher.matches?(['foobarbaz']) end def test_should_not_match_string_argument_without_substring matcher = includes('bar') assert !matcher.matches?(['foobaz']) end def test_should_match_hash_argument_containing_given_key matcher = includes(:key) assert matcher.matches?([{ thing: 1, key: 2 }]) end def test_should_not_match_hash_argument_missing_given_key matcher = includes(:key) assert !matcher.matches?([{ thing: 1, other: :key }]) end def test_should_match_hash_when_nested_matcher_matches_key matcher = includes(regexp_matches(/ar/)) assert matcher.matches?([{ 'foo' => 1, 'bar' => 2 }]) end def test_should_not_match_hash_when_nested_matcher_doesn_not_match_key matcher = includes(regexp_matches(/az/)) assert !matcher.matches?([{ 'foo' => 1, 'bar' => 2 }]) end end mocha-2.4.2/test/unit/parameter_matchers/instance_of_test.rb000066400000000000000000000012151464615054400242760ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/instance_of' require 'mocha/inspect' class InstanceOfTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_object_that_is_an_instance_of_specified_class matcher = instance_of(String) assert matcher.matches?(['string']) end def test_should_not_match_object_that_is_not_an_instance_of_specified_class matcher = instance_of(String) assert !matcher.matches?([99]) end def test_should_describe_matcher matcher = instance_of(String) assert_equal 'instance_of(String)', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/is_a_test.rb000066400000000000000000000011151464615054400227200ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/is_a' require 'mocha/inspect' class IsATest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_object_that_is_a_specified_class matcher = is_a(Integer) assert matcher.matches?([99]) end def test_should_not_match_object_that_is_not_a_specified_class matcher = is_a(Integer) assert !matcher.matches?(['string']) end def test_should_describe_matcher matcher = is_a(Integer) assert_equal 'is_a(Integer)', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/kind_of_test.rb000066400000000000000000000011571464615054400234240ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/kind_of' require 'mocha/inspect' class KindOfTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_object_that_is_a_kind_of_specified_class matcher = kind_of(Integer) assert matcher.matches?([99]) end def test_should_not_match_object_that_is_not_a_kind_of_specified_class matcher = kind_of(Integer) assert !matcher.matches?(['string']) end def test_should_describe_matcher matcher = kind_of(Integer) assert_equal 'kind_of(Integer)', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/not_test.rb000066400000000000000000000012241464615054400226060ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/not' require 'mocha/inspect' require 'stub_matcher' class NotTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_if_matcher_does_not_match matcher = Not(Stub::Matcher.new(false)) assert matcher.matches?(['any_old_value']) end def test_should_not_match_if_matcher_does_match matcher = Not(Stub::Matcher.new(true)) assert !matcher.matches?(['any_old_value']) end def test_should_describe_matcher matcher = Not(Stub::Matcher.new(true)) assert_equal 'Not(matcher(true))', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/positional_or_keyword_hash_test.rb000066400000000000000000000147671464615054400274560ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'deprecation_disabler' require 'execution_point' require 'mocha/parameter_matchers/positional_or_keyword_hash' require 'mocha/parameter_matchers/instance_methods' require 'mocha/inspect' require 'mocha/expectation' class PositionalOrKeywordHashTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_describe_matcher matcher = { key_1: 1, key_2: 2 }.to_matcher assert_equal '{:key_1 => 1, :key_2 => 2}', matcher.mocha_inspect end def test_should_match_non_last_hash_arg_with_hash_arg matcher = { key_1: 1, key_2: 2 }.to_matcher assert matcher.matches?([{ key_1: 1, key_2: 2 }, %w[a b]]) end def test_should_not_match_non_hash_arg_with_hash_arg matcher = { key_1: 1, key_2: 2 }.to_matcher assert !matcher.matches?([%w[a b]]) end def test_should_match_hash_arg_with_hash_arg matcher = { key_1: 1, key_2: 2 }.to_matcher assert matcher.matches?([{ key_1: 1, key_2: 2 }]) end def test_should_match_keyword_args_with_keyword_args matcher = Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 }).to_matcher # rubocop:disable Style/BracesAroundHashParameters assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters end def test_should_match_keyword_args_with_matchers_using_keyword_args matcher = Hash.ruby2_keywords_hash({ key_1: is_a(String), key_2: is_a(Integer) }).to_matcher(top_level: true) # rubocop:disable Style/BracesAroundHashParameters assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 'foo', key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters end def test_should_match_hash_arg_with_keyword_args_but_display_deprecation_warning_if_appropriate expectation = Mocha::Expectation.new(self, :foo); execution_point = ExecutionPoint.current matcher = Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 }).to_matcher(expectation: expectation, top_level: true) # rubocop:disable Style/BracesAroundHashParameters DeprecationDisabler.disable_deprecations do assert matcher.matches?([{ key_1: 1, key_2: 2 }]) end return unless Mocha::RUBY_V27_PLUS message = Mocha::Deprecation.messages.last location = "#{execution_point.file_name}:#{execution_point.line_number}:in `new'" assert_includes message, "Expectation defined at #{location} expected keyword arguments (key_1: 1, key_2: 2)" assert_includes message, 'but received positional hash ({:key_1 => 1, :key_2 => 2})' assert_includes message, 'These will stop matching when strict keyword argument matching is enabled.' assert_includes message, 'See the documentation for Mocha::Configuration#strict_keyword_argument_matching=.' end def test_should_match_keyword_args_with_hash_arg_but_display_deprecation_warning_if_appropriate expectation = Mocha::Expectation.new(self, :foo); execution_point = ExecutionPoint.current matcher = { key_1: 1, key_2: 2 }.to_matcher(expectation: expectation, top_level: true) DeprecationDisabler.disable_deprecations do assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters end return unless Mocha::RUBY_V27_PLUS message = Mocha::Deprecation.messages.last location = "#{execution_point.file_name}:#{execution_point.line_number}:in `new'" assert_includes message, "Expectation defined at #{location} expected positional hash ({:key_1 => 1, :key_2 => 2})" assert_includes message, 'but received keyword arguments (key_1: 1, key_2: 2)' assert_includes message, 'These will stop matching when strict keyword argument matching is enabled.' assert_includes message, 'See the documentation for Mocha::Configuration#strict_keyword_argument_matching=.' end if Mocha::RUBY_V27_PLUS def test_should_match_non_last_hash_arg_with_hash_arg_when_strict_keyword_args_is_enabled matcher = { key_1: 1, key_2: 2 }.to_matcher Mocha::Configuration.override(strict_keyword_argument_matching: true) do assert matcher.matches?([{ key_1: 1, key_2: 2 }, %w[a b]]) end end def test_should_not_match_non_hash_arg_with_hash_arg_when_strict_keyword_args_is_enabled matcher = { key_1: 1, key_2: 2 }.to_matcher Mocha::Configuration.override(strict_keyword_argument_matching: true) do assert !matcher.matches?([%w[a b]]) end end def test_should_match_hash_arg_with_hash_arg_when_strict_keyword_args_is_enabled matcher = { key_1: 1, key_2: 2 }.to_matcher Mocha::Configuration.override(strict_keyword_argument_matching: true) do assert matcher.matches?([{ key_1: 1, key_2: 2 }]) end end def test_should_match_keyword_args_with_keyword_args_when_strict_keyword_args_is_enabled matcher = Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 }).to_matcher # rubocop:disable Style/BracesAroundHashParameters Mocha::Configuration.override(strict_keyword_argument_matching: true) do assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters end end def test_should_not_match_hash_arg_with_keyword_args_when_strict_keyword_args_is_enabled matcher = Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 }).to_matcher(top_level: true) # rubocop:disable Style/BracesAroundHashParameters Mocha::Configuration.override(strict_keyword_argument_matching: true) do assert !matcher.matches?([{ key_1: 1, key_2: 2 }]) end end def test_should_not_match_keyword_args_with_hash_arg_when_strict_keyword_args_is_enabled matcher = { key_1: 1, key_2: 2 }.to_matcher(top_level: true) Mocha::Configuration.override(strict_keyword_argument_matching: true) do assert !matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters end end def test_should_display_deprecation_warning_even_if_parent_expectation_is_nil expectation = nil matcher = { key_1: 1, key_2: 2 }.to_matcher(expectation: expectation, top_level: true) DeprecationDisabler.disable_deprecations do matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters end message = Mocha::Deprecation.messages.last assert_includes message, 'Expectation expected positional hash ({:key_1 => 1, :key_2 => 2})' assert_includes message, 'but received keyword arguments (key_1: 1, key_2: 2)' end end end mocha-2.4.2/test/unit/parameter_matchers/regexp_matches_test.rb000066400000000000000000000026301464615054400250060ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/regexp_matches' require 'mocha/inspect' class RegexpMatchesTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_parameter_matching_regular_expression matcher = regexp_matches(/oo/) assert matcher.matches?(['foo']) end def test_should_not_match_parameter_not_matching_regular_expression matcher = regexp_matches(/oo/) assert !matcher.matches?(['bar']) end def test_should_describe_matcher matcher = regexp_matches(/oo/) assert_equal 'regexp_matches(/oo/)', matcher.mocha_inspect end def test_should_not_raise_error_on_empty_arguments matcher = regexp_matches(/oo/) assert_nothing_raised { matcher.matches?([]) } end def test_should_not_match_on_empty_arguments matcher = regexp_matches(/oo/) assert !matcher.matches?([]) end def test_should_not_raise_error_on_argument_that_does_not_respond_to_equals_tilde matcher = regexp_matches(/oo/) assert_nothing_raised { matcher.matches?([object_not_responding_to_equals_tilde]) } end def test_should_not_match_on_argument_that_does_not_respond_to_equals_tilde matcher = regexp_matches(/oo/) assert !matcher.matches?([object_not_responding_to_equals_tilde]) end private def object_not_responding_to_equals_tilde Class.new { undef =~ if respond_to?(:=~) }.new end end mocha-2.4.2/test/unit/parameter_matchers/responds_with_test.rb000066400000000000000000000027071464615054400247050ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/responds_with' require 'mocha/parameter_matchers/instance_methods' require 'mocha/inspect' class RespondsWithTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_parameter_responding_with_expected_value matcher = responds_with(:upcase, 'FOO') assert matcher.matches?(['foo']) end def test_should_not_match_parameter_responding_with_unexpected_value matcher = responds_with(:upcase, 'FOO') assert !matcher.matches?(['bar']) end def test_should_match_parameter_responding_with_nested_responds_with_matcher matcher = responds_with(:foo, responds_with(:bar, 'baz')) object = Class.new do def foo Class.new do def bar 'baz' end end.new end end.new assert matcher.matches?([object]) end def test_should_describe_matcher matcher = responds_with(:foo, :bar) assert_equal 'responds_with(:foo, :bar)', matcher.mocha_inspect end def test_should_match_parameter_responding_with_expected_values_for_given_messages matcher = responds_with(upcase: 'FOO', reverse: 'oof') assert matcher.matches?(['foo']) end def test_should_describe_matcher_with_multiple_messages_vs_results matcher = responds_with(foo: :bar, baz: 123) assert_equal 'all_of(responds_with(:foo, :bar), responds_with(:baz, 123))', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameter_matchers/stub_matcher.rb000066400000000000000000000005351464615054400234330ustar00rootroot00000000000000module Stub class Matcher attr_accessor :value def initialize(matches) @matches = matches end def matches?(available_parameters) value = available_parameters.shift @value = value @matches end def mocha_inspect "matcher(#{@matches})" end def to_matcher self end end end mocha-2.4.2/test/unit/parameter_matchers/yaml_equivalent_test.rb000066400000000000000000000013221464615054400252040ustar00rootroot00000000000000require File.expand_path('../../../test_helper', __FILE__) require 'mocha/parameter_matchers/yaml_equivalent' require 'mocha/inspect' class YamlEquivalentTest < Mocha::TestCase include Mocha::ParameterMatchers def test_should_match_parameter_matching_yaml_representation_of_object matcher = yaml_equivalent([1, 2, 3]) assert matcher.matches?(["--- \n- 1\n- 2\n- 3\n"]) end def test_should_not_match_parameter_matching_yaml_representation_of_object matcher = yaml_equivalent([1, 2, 3]) assert !matcher.matches?(["--- \n- 4\n- 5\n"]) end def test_should_describe_matcher matcher = yaml_equivalent([1, 2, 3]) assert_equal 'yaml_equivalent([1, 2, 3])', matcher.mocha_inspect end end mocha-2.4.2/test/unit/parameters_matcher_test.rb000066400000000000000000000104201464615054400220040ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/parameters_matcher' class ParametersMatcherTest < Mocha::TestCase include Mocha def test_should_match_any_actual_parameters_if_no_expected_parameters_specified parameters_matcher = ParametersMatcher.new assert parameters_matcher.match?([1, 2, 3]) end def test_should_match_if_actual_parameters_are_same_as_expected_parameters parameters_matcher = ParametersMatcher.new([4, 5, 6]) assert parameters_matcher.match?([4, 5, 6]) end def test_should_not_match_if_actual_parameters_are_different_from_expected_parameters parameters_matcher = ParametersMatcher.new([4, 5, 6]) assert !parameters_matcher.match?([1, 2, 3]) end def test_should_not_match_if_there_are_less_actual_parameters_than_expected_parameters parameters_matcher = ParametersMatcher.new([4, 5, 6]) assert !parameters_matcher.match?([4, 5]) end def test_should_not_match_if_there_are_more_actual_parameters_than_expected_parameters parameters_matcher = ParametersMatcher.new([4, 5]) assert !parameters_matcher.match?([4, 5, 6]) end def test_should_not_match_if_not_all_required_parameters_are_supplied optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert !parameters_matcher.match?([4]) end def test_should_match_if_all_required_parameters_match_and_no_optional_parameters_are_supplied optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert parameters_matcher.match?([4, 5]) end def test_should_match_if_all_required_and_optional_parameters_match_and_some_optional_parameters_are_supplied optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert parameters_matcher.match?([4, 5, 6]) end def test_should_match_if_all_required_and_optional_parameters_match_and_all_optional_parameters_are_supplied optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert parameters_matcher.match?([4, 5, 6, 7]) end def test_should_not_match_if_all_required_and_optional_parameters_match_but_too_many_optional_parameters_are_supplied optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert !parameters_matcher.match?([4, 5, 6, 7, 8]) end def test_should_not_match_if_all_required_parameters_match_but_some_optional_parameters_do_not_match optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert !parameters_matcher.match?([4, 5, 6, 0]) end def test_should_not_match_if_some_required_parameters_do_not_match_although_all_optional_parameters_do_match optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert !parameters_matcher.match?([4, 0, 6]) end def test_should_not_match_if_all_required_parameters_match_but_no_optional_parameters_match optionals = ParameterMatchers::Optionally.new(6, 7) parameters_matcher = ParametersMatcher.new([4, 5, optionals]) assert !parameters_matcher.match?([4, 5, 0, 0]) end def test_should_match_if_actual_parameters_satisfy_matching_block parameters_matcher = ParametersMatcher.new { |x, y| x + y == 3 } assert parameters_matcher.match?([1, 2]) end def test_should_not_match_if_actual_parameters_do_not_satisfy_matching_block parameters_matcher = ParametersMatcher.new { |x, y| x + y == 3 } assert !parameters_matcher.match?([2, 3]) end def test_should_remove_outer_array_braces params = [1, 2, [3, 4]] parameters_matcher = ParametersMatcher.new(params) assert_equal '(1, 2, [3, 4])', parameters_matcher.mocha_inspect end def test_should_display_numeric_arguments_as_is params = [1, 2, 3] parameters_matcher = ParametersMatcher.new(params) assert_equal '(1, 2, 3)', parameters_matcher.mocha_inspect end def test_should_indicate_that_matcher_will_match_any_actual_parameters parameters_matcher = ParametersMatcher.new assert_equal '(any_parameters)', parameters_matcher.mocha_inspect end end mocha-2.4.2/test/unit/receivers_test.rb000066400000000000000000000040701464615054400201310ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/receivers' class ObjectReceiverTest < Mocha::TestCase include Mocha class FakeObject def initialize(mocha) @mocha = mocha end def mocha(_instantiate) @mocha end def is_a?(_klass) false end end class FakeClass attr_reader :superclass def initialize(superclass, mocha) @superclass = superclass @mocha = mocha end def mocha(_instantiate) @mocha end def is_a?(klass) klass == Class end end def test_mocks_returns_mock_for_object object = FakeObject.new(:mocha) receiver = ObjectReceiver.new(object) assert_equal [:mocha], receiver.mocks end def test_mocks_returns_mocks_for_class_and_its_superclasses grandparent = FakeClass.new(nil, :grandparent_mocha) parent = FakeClass.new(grandparent, :parent_mocha) klass = FakeClass.new(parent, :mocha) receiver = ObjectReceiver.new(klass) assert_equal [:mocha, :parent_mocha, :grandparent_mocha], receiver.mocks end end class AnyInstanceReceiverTest < Mocha::TestCase include Mocha class FakeAnyInstanceClass class AnyInstance def initialize(mocha) @mocha = mocha end def mocha(_instantiate) @mocha end end attr_reader :superclass def initialize(superclass, mocha) @superclass = superclass @mocha = mocha end def any_instance AnyInstance.new(@mocha) end end def test_mocks_returns_mocks_for_class_and_its_superclasses grandparent = FakeAnyInstanceClass.new(nil, :grandparent_mocha) parent = FakeAnyInstanceClass.new(grandparent, :parent_mocha) klass = FakeAnyInstanceClass.new(parent, :mocha) receiver = AnyInstanceReceiver.new(klass) assert_equal [:mocha, :parent_mocha, :grandparent_mocha], receiver.mocks end end class DefaultReceiverTest < Mocha::TestCase include Mocha def test_mocks_returns_mock mock = :mocha receiver = DefaultReceiver.new(mock) assert_equal [:mocha], receiver.mocks end end mocha-2.4.2/test/unit/return_values_test.rb000066400000000000000000000045021464615054400210400ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/invocation' require 'mocha/return_values' class ReturnValuesTest < Mocha::TestCase include Mocha def new_invocation Invocation.new(:irrelevant, :irrelevant) end def test_should_return_nil values = ReturnValues.new assert_nil values.next(new_invocation) end def test_should_keep_returning_nil values = ReturnValues.new values.next(new_invocation) assert_nil values.next(new_invocation) assert_nil values.next(new_invocation) end def test_should_return_evaluated_single_return_value values = ReturnValues.new(SingleReturnValue.new('value')) assert_equal 'value', values.next(new_invocation) end def test_should_keep_returning_evaluated_single_return_value values = ReturnValues.new(SingleReturnValue.new('value')) values.next(new_invocation) assert_equal 'value', values.next(new_invocation) assert_equal 'value', values.next(new_invocation) end def test_should_return_consecutive_evaluated_single_return_values values = ReturnValues.new(SingleReturnValue.new('value_1'), SingleReturnValue.new('value_2')) assert_equal 'value_1', values.next(new_invocation) assert_equal 'value_2', values.next(new_invocation) end def test_should_keep_returning_last_of_consecutive_evaluated_single_return_values values = ReturnValues.new(SingleReturnValue.new('value_1'), SingleReturnValue.new('value_2')) values.next(new_invocation) values.next(new_invocation) assert_equal 'value_2', values.next(new_invocation) assert_equal 'value_2', values.next(new_invocation) end def test_should_build_single_return_values_for_each_values values = ReturnValues.build('value_1', 'value_2', 'value_3').values assert_equal 'value_1', values[0].evaluate(new_invocation) assert_equal 'value_2', values[1].evaluate(new_invocation) assert_equal 'value_3', values[2].evaluate(new_invocation) end def test_should_combine_two_sets_of_return_values values1 = ReturnValues.build('value_1') values2 = ReturnValues.build('value_2a', 'value_2b') values = (values1 + values2).values assert_equal 'value_1', values[0].evaluate(new_invocation) assert_equal 'value_2a', values[1].evaluate(new_invocation) assert_equal 'value_2b', values[2].evaluate(new_invocation) end end mocha-2.4.2/test/unit/sequence_test.rb000066400000000000000000000072511464615054400177560ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/sequence' require 'mocha/expectation' class SequenceTest < Mocha::TestCase include Mocha class FakeExpectation attr_reader :ordering_constraints def initialize(satisfied = false) @satisfied = satisfied @ordering_constraints = [] end def add_ordering_constraint(ordering_constraint) @ordering_constraints << ordering_constraint end def satisfied? @satisfied end end def test_should_be_satisfied_if_no_expectations_added sequence = Sequence.new('name') assert sequence.satisfied_to_index?(0) end def test_should_be_satisfied_if_one_unsatisfied_expectations_added_but_it_is_not_included_by_index sequence = Sequence.new('name') expectation = FakeExpectation.new(false) sequence.constrain_as_next_in_sequence(expectation) assert sequence.satisfied_to_index?(0) end def test_should_not_be_satisfied_if_one_unsatisfied_expectations_added_and_it_is_included_by_index sequence = Sequence.new('name') expectation = FakeExpectation.new(false) sequence.constrain_as_next_in_sequence(expectation) assert !sequence.satisfied_to_index?(1) end def test_should_be_satisfied_if_one_satisfied_expectations_added_and_it_is_included_by_index sequence = Sequence.new('name') expectation = FakeExpectation.new(true) sequence.constrain_as_next_in_sequence(expectation) assert sequence.satisfied_to_index?(1) end def test_should_not_be_satisfied_if_one_satisfied_and_one_unsatisfied_expectation_added_and_both_are_included_by_index sequence = Sequence.new('name') expectation_one = FakeExpectation.new(true) expectation_two = FakeExpectation.new(false) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert !sequence.satisfied_to_index?(2) end def test_should_be_satisfied_if_two_satisfied_expectations_added_and_both_are_included_by_index sequence = Sequence.new('name') expectation_one = FakeExpectation.new(true) expectation_two = FakeExpectation.new(true) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert sequence.satisfied_to_index?(2) end def test_should_add_ordering_constraint_to_expectation sequence = Sequence.new('name') expectation = FakeExpectation.new sequence.constrain_as_next_in_sequence(expectation) assert_equal 1, expectation.ordering_constraints.length end def test_should_not_allow_invocation_of_second_method_when_first_n_sequence_has_not_been_invoked sequence = Sequence.new('name') expectation_one = FakeExpectation.new(false) expectation_two = FakeExpectation.new(false) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert !expectation_two.ordering_constraints[0].allows_invocation_now? end def test_should_allow_invocation_of_second_method_when_first_in_sequence_has_been_invoked sequence = Sequence.new('name') expectation_one = FakeExpectation.new(true) expectation_two = FakeExpectation.new(false) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert expectation_two.ordering_constraints[0].allows_invocation_now? end def test_should_describe_ordering_constraint_as_being_part_of_named_sequence sequence = Sequence.new('wibble') expectation = FakeExpectation.new sequence.constrain_as_next_in_sequence(expectation) assert_equal %(in sequence "wibble"), expectation.ordering_constraints[0].mocha_inspect end end mocha-2.4.2/test/unit/single_return_value_test.rb000066400000000000000000000006161464615054400222200ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/invocation' require 'mocha/single_return_value' class SingleReturnValueTest < Mocha::TestCase include Mocha def new_invocation Invocation.new(:irrelevant, :irrelevant) end def test_should_return_value value = SingleReturnValue.new('value') assert_equal 'value', value.evaluate(new_invocation) end end mocha-2.4.2/test/unit/state_machine_test.rb000066400000000000000000000060641464615054400207530ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/state_machine' class StateMachineTest < Mocha::TestCase include Mocha def test_should_initially_be_in_no_state state_machine = StateMachine.new('name') any_state.each do |state| assert !state_machine.is(state).active? assert state_machine.is_not(state).active? end end def test_should_be_able_to_enter_a_state state_machine = StateMachine.new('name') state = 'A' other_states = any_state.reject { |s| s == state } state_machine.is(state).activate assert state_machine.is(state).active? assert !state_machine.is_not(state).active? other_states.each do |s| assert !state_machine.is(s).active? assert state_machine.is_not(s).active? end end def test_should_be_able_to_change_state state_machine = StateMachine.new('name') state = 'B' other_states = any_state.reject { |s| s == state } state_machine.is('A').activate state_machine.is(state).activate assert state_machine.is(state).active? assert !state_machine.is_not(state).active? other_states.each do |s| assert !state_machine.is(s).active? assert state_machine.is_not(s).active? end end def test_should_be_put_into_an_initial_state state_machine = StateMachine.new('name') initial_state = 'A' other_states = any_state.reject { |s| s == initial_state } state_machine.starts_as(initial_state) assert state_machine.is(initial_state).active? assert !state_machine.is_not(initial_state).active? other_states.each do |state| assert !state_machine.is(state).active? assert state_machine.is_not(state).active? end end def test_should_be_put_into_a_new_state next_state = 'B' other_states = any_state.reject { |s| s == next_state } state_machine = StateMachine.new('name').starts_as('A') state_machine.become(next_state) assert state_machine.is(next_state).active? assert !state_machine.is_not(next_state).active? other_states.each do |state| assert !state_machine.is(state).active? assert state_machine.is_not(state).active? end end def test_should_describe_itself_as_name_and_current_state state_machine = StateMachine.new('state_machine_name') assert_equal 'state_machine_name has no current state', state_machine.mocha_inspect inspectable_state = Class.new { define_method(:mocha_inspect) { "'inspectable_state'" } }.new state_machine.is(inspectable_state).activate assert_equal "state_machine_name is 'inspectable_state'", state_machine.mocha_inspect end def test_should_have_self_describing_states state_machine = StateMachine.new('state_machine_name') inspectable_state = Class.new { define_method(:mocha_inspect) { "'inspectable_state'" } }.new assert_equal "state_machine_name is 'inspectable_state'", state_machine.is(inspectable_state).mocha_inspect assert_equal "state_machine_name is not 'inspectable_state'", state_machine.is_not(inspectable_state).mocha_inspect end def any_state %w[A B C D] end end mocha-2.4.2/test/unit/string_inspect_test.rb000066400000000000000000000004011464615054400211670ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/inspect' class StringInspectTest < Mocha::TestCase def test_should_use_default_inspect_method string = 'my_string' assert_equal %("my_string"), string.mocha_inspect end end mocha-2.4.2/test/unit/thrower_test.rb000066400000000000000000000011051464615054400176300ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/invocation' require 'mocha/thrower' class ThrowerTest < Mocha::TestCase include Mocha def new_invocation Invocation.new(:irrelevant, :irrelevant) end def test_should_throw_tag thrower = Thrower.new(:tag) assert_throws(:tag) { thrower.evaluate(new_invocation) } end def test_should_throw_tag_with_return_value thrower = Thrower.new(:tag, 'return-value') return_value = catch(:tag) { thrower.evaluate(new_invocation) } assert_equal 'return-value', return_value end end mocha-2.4.2/test/unit/yield_parameters_test.rb000066400000000000000000000052171464615054400214770ustar00rootroot00000000000000require File.expand_path('../../test_helper', __FILE__) require 'mocha/yield_parameters' class YieldParametersTest < Mocha::TestCase include Mocha def test_should_return_null_yield_parameter_group_by_default assert_next_invocation_yields(YieldParameters.new, []) end def test_should_return_single_yield_parameter_group yield_parameters = YieldParameters.new yield_parameters.add([1, 2, 3]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3]]) end def test_should_keep_returning_single_yield_parameter_group yield_parameters = YieldParameters.new yield_parameters.add([1, 2, 3]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3]]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3]]) end def test_should_return_consecutive_single_yield_parameter_groups yield_parameters = YieldParameters.new yield_parameters.add([1, 2, 3]) yield_parameters.add([4, 5]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3]]) assert_next_invocation_yields(yield_parameters, [[4, 5]]) end def test_should_return_multiple_yield_parameter_group yield_parameters = YieldParameters.new yield_parameters.add([1, 2, 3], [4, 5]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3], [4, 5]]) end def test_should_return_multiple_yield_parameter_group_when_arguments_are_not_arrays yield_parameters = YieldParameters.new yield_parameters.add(1, { b: 2 }, 3) assert_next_invocation_yields(yield_parameters, [[1], [{ b: 2 }], [3]]) end def test_should_keep_returning_multiple_yield_parameter_group yield_parameters = YieldParameters.new yield_parameters.add([1, 2, 3], [4, 5]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3], [4, 5]]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3], [4, 5]]) end def test_should_return_consecutive_multiple_yield_parameter_groups yield_parameters = YieldParameters.new yield_parameters.add([1, 2, 3], [4, 5]) yield_parameters.add([6, 7], [8, 9, 0]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3], [4, 5]]) assert_next_invocation_yields(yield_parameters, [[6, 7], [8, 9, 0]]) end def test_should_return_consecutive_single_and_multiple_yield_parameter_groups yield_parameters = YieldParameters.new yield_parameters.add([1, 2, 3]) yield_parameters.add([4, 5, 6], [7, 8]) assert_next_invocation_yields(yield_parameters, [[1, 2, 3]]) assert_next_invocation_yields(yield_parameters, [[4, 5, 6], [7, 8]]) end private def assert_next_invocation_yields(yield_parameters, expected) assert_equal expected, yield_parameters.next_invocation end end