mocha-macruby 0.9.8.20100129120100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +3 -0
- data/MIT-LICENSE +7 -0
- data/README +39 -0
- data/RELEASE +294 -0
- data/Rakefile +214 -0
- data/examples/misc.rb +43 -0
- data/examples/mocha.rb +25 -0
- data/examples/stubba.rb +64 -0
- data/lib/mocha.rb +3 -0
- data/lib/mocha/any_instance_method.rb +59 -0
- data/lib/mocha/api.rb +173 -0
- data/lib/mocha/argument_iterator.rb +21 -0
- data/lib/mocha/backtrace_filter.rb +17 -0
- data/lib/mocha/cardinality.rb +95 -0
- data/lib/mocha/central.rb +27 -0
- data/lib/mocha/change_state_side_effect.rb +19 -0
- data/lib/mocha/class_method.rb +117 -0
- data/lib/mocha/configuration.rb +79 -0
- data/lib/mocha/deprecation.rb +22 -0
- data/lib/mocha/exception_raiser.rb +17 -0
- data/lib/mocha/expectation.rb +476 -0
- data/lib/mocha/expectation_error.rb +15 -0
- data/lib/mocha/expectation_list.rb +50 -0
- data/lib/mocha/in_state_ordering_constraint.rb +19 -0
- data/lib/mocha/inspect.rb +67 -0
- data/lib/mocha/instance_method.rb +16 -0
- data/lib/mocha/integration.rb +38 -0
- data/lib/mocha/integration/mini_test.rb +21 -0
- data/lib/mocha/integration/mini_test/assertion_counter.rb +23 -0
- data/lib/mocha/integration/mini_test/version_131_and_above.rb +50 -0
- data/lib/mocha/integration/test_unit.rb +40 -0
- data/lib/mocha/integration/test_unit/assertion_counter.rb +23 -0
- data/lib/mocha/integration/test_unit/gem_version_200.rb +49 -0
- data/lib/mocha/integration/test_unit/gem_version_201_and_above.rb +49 -0
- data/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb +48 -0
- data/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb +50 -0
- data/lib/mocha/is_a.rb +9 -0
- data/lib/mocha/logger.rb +15 -0
- data/lib/mocha/metaclass.rb +13 -0
- data/lib/mocha/method_matcher.rb +21 -0
- data/lib/mocha/mock.rb +200 -0
- data/lib/mocha/mockery.rb +181 -0
- data/lib/mocha/module_method.rb +16 -0
- data/lib/mocha/multiple_yields.rb +20 -0
- data/lib/mocha/names.rb +53 -0
- data/lib/mocha/no_yields.rb +11 -0
- data/lib/mocha/object.rb +187 -0
- data/lib/mocha/parameter_matchers.rb +27 -0
- data/lib/mocha/parameter_matchers/all_of.rb +42 -0
- data/lib/mocha/parameter_matchers/any_of.rb +47 -0
- data/lib/mocha/parameter_matchers/any_parameters.rb +40 -0
- data/lib/mocha/parameter_matchers/anything.rb +33 -0
- data/lib/mocha/parameter_matchers/base.rb +15 -0
- data/lib/mocha/parameter_matchers/equals.rb +42 -0
- data/lib/mocha/parameter_matchers/has_entries.rb +45 -0
- data/lib/mocha/parameter_matchers/has_entry.rb +57 -0
- data/lib/mocha/parameter_matchers/has_key.rb +43 -0
- data/lib/mocha/parameter_matchers/has_value.rb +43 -0
- data/lib/mocha/parameter_matchers/includes.rb +41 -0
- data/lib/mocha/parameter_matchers/instance_of.rb +42 -0
- data/lib/mocha/parameter_matchers/is_a.rb +42 -0
- data/lib/mocha/parameter_matchers/kind_of.rb +42 -0
- data/lib/mocha/parameter_matchers/not.rb +42 -0
- data/lib/mocha/parameter_matchers/object.rb +15 -0
- data/lib/mocha/parameter_matchers/optionally.rb +55 -0
- data/lib/mocha/parameter_matchers/regexp_matches.rb +44 -0
- data/lib/mocha/parameter_matchers/responds_with.rb +43 -0
- data/lib/mocha/parameter_matchers/yaml_equivalent.rb +43 -0
- data/lib/mocha/parameters_matcher.rb +37 -0
- data/lib/mocha/pretty_parameters.rb +28 -0
- data/lib/mocha/return_values.rb +31 -0
- data/lib/mocha/sequence.rb +42 -0
- data/lib/mocha/single_return_value.rb +17 -0
- data/lib/mocha/single_yield.rb +18 -0
- data/lib/mocha/standalone.rb +1 -0
- data/lib/mocha/state_machine.rb +91 -0
- data/lib/mocha/stubbing_error.rb +16 -0
- data/lib/mocha/unexpected_invocation.rb +18 -0
- data/lib/mocha/yield_parameters.rb +31 -0
- data/lib/mocha_standalone.rb +2 -0
- data/lib/stubba.rb +4 -0
- data/test/acceptance/acceptance_test_helper.rb +38 -0
- data/test/acceptance/api_test.rb +139 -0
- data/test/acceptance/bug_18914_test.rb +43 -0
- data/test/acceptance/bug_21465_test.rb +34 -0
- data/test/acceptance/bug_21563_test.rb +25 -0
- data/test/acceptance/expected_invocation_count_test.rb +196 -0
- data/test/acceptance/failure_messages_test.rb +64 -0
- data/test/acceptance/minitest_test.rb +153 -0
- data/test/acceptance/mocha_example_test.rb +98 -0
- data/test/acceptance/mocha_test_result_test.rb +84 -0
- data/test/acceptance/mock_test.rb +100 -0
- data/test/acceptance/mock_with_initializer_block_test.rb +51 -0
- data/test/acceptance/mocked_methods_dispatch_test.rb +78 -0
- data/test/acceptance/optional_parameters_test.rb +70 -0
- data/test/acceptance/parameter_matcher_test.rb +209 -0
- data/test/acceptance/partial_mocks_test.rb +47 -0
- data/test/acceptance/return_value_test.rb +52 -0
- data/test/acceptance/sequence_test.rb +186 -0
- data/test/acceptance/states_test.rb +70 -0
- data/test/acceptance/stub_any_instance_method_test.rb +195 -0
- data/test/acceptance/stub_class_method_test.rb +203 -0
- data/test/acceptance/stub_everything_test.rb +56 -0
- data/test/acceptance/stub_instance_method_test.rb +203 -0
- data/test/acceptance/stub_module_method_test.rb +163 -0
- data/test/acceptance/stub_test.rb +52 -0
- data/test/acceptance/stubba_example_test.rb +102 -0
- data/test/acceptance/stubba_test.rb +15 -0
- data/test/acceptance/stubba_test_result_test.rb +66 -0
- data/test/acceptance/stubbing_error_backtrace_test.rb +64 -0
- data/test/acceptance/stubbing_method_unnecessarily_test.rb +65 -0
- data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +130 -0
- data/test/acceptance/stubbing_non_existent_class_method_test.rb +157 -0
- data/test/acceptance/stubbing_non_existent_instance_method_test.rb +147 -0
- data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +130 -0
- data/test/acceptance/stubbing_non_public_class_method_test.rb +163 -0
- data/test/acceptance/stubbing_non_public_instance_method_test.rb +143 -0
- data/test/acceptance/stubbing_on_non_mock_object_test.rb +64 -0
- data/test/deprecation_disabler.rb +15 -0
- data/test/execution_point.rb +36 -0
- data/test/method_definer.rb +24 -0
- data/test/simple_counter.rb +13 -0
- data/test/test_helper.rb +25 -0
- data/test/test_runner.rb +33 -0
- data/test/unit/any_instance_method_test.rb +126 -0
- data/test/unit/array_inspect_test.rb +16 -0
- data/test/unit/backtrace_filter_test.rb +19 -0
- data/test/unit/cardinality_test.rb +56 -0
- data/test/unit/central_test.rb +65 -0
- data/test/unit/change_state_side_effect_test.rb +41 -0
- data/test/unit/class_method_test.rb +295 -0
- data/test/unit/configuration_test.rb +38 -0
- data/test/unit/date_time_inspect_test.rb +21 -0
- data/test/unit/exception_raiser_test.rb +42 -0
- data/test/unit/expectation_list_test.rb +57 -0
- data/test/unit/expectation_test.rb +480 -0
- data/test/unit/hash_inspect_test.rb +16 -0
- data/test/unit/in_state_ordering_constraint_test.rb +43 -0
- data/test/unit/metaclass_test.rb +22 -0
- data/test/unit/method_matcher_test.rb +23 -0
- data/test/unit/mock_test.rb +302 -0
- data/test/unit/mockery_test.rb +149 -0
- data/test/unit/multiple_yields_test.rb +18 -0
- data/test/unit/no_yields_test.rb +18 -0
- data/test/unit/object_inspect_test.rb +37 -0
- data/test/unit/object_test.rb +82 -0
- data/test/unit/parameter_matchers/all_of_test.rb +26 -0
- data/test/unit/parameter_matchers/any_of_test.rb +26 -0
- data/test/unit/parameter_matchers/anything_test.rb +21 -0
- data/test/unit/parameter_matchers/equals_test.rb +25 -0
- data/test/unit/parameter_matchers/has_entries_test.rb +51 -0
- data/test/unit/parameter_matchers/has_entry_test.rb +82 -0
- data/test/unit/parameter_matchers/has_key_test.rb +55 -0
- data/test/unit/parameter_matchers/has_value_test.rb +57 -0
- data/test/unit/parameter_matchers/includes_test.rb +44 -0
- data/test/unit/parameter_matchers/instance_of_test.rb +25 -0
- data/test/unit/parameter_matchers/is_a_test.rb +25 -0
- data/test/unit/parameter_matchers/kind_of_test.rb +25 -0
- data/test/unit/parameter_matchers/not_test.rb +26 -0
- data/test/unit/parameter_matchers/regexp_matches_test.rb +46 -0
- data/test/unit/parameter_matchers/responds_with_test.rb +25 -0
- data/test/unit/parameter_matchers/stub_matcher.rb +27 -0
- data/test/unit/parameter_matchers/yaml_equivalent_test.rb +25 -0
- data/test/unit/parameters_matcher_test.rb +121 -0
- data/test/unit/return_values_test.rb +63 -0
- data/test/unit/sequence_test.rb +104 -0
- data/test/unit/single_return_value_test.rb +14 -0
- data/test/unit/single_yield_test.rb +18 -0
- data/test/unit/state_machine_test.rb +98 -0
- data/test/unit/string_inspect_test.rb +11 -0
- data/test/unit/yield_parameters_test.rb +93 -0
- metadata +240 -0
data/examples/misc.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'mocha'
|
3
|
+
|
4
|
+
class MiscExampleTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_mocking_a_class_method
|
7
|
+
product = Product.new
|
8
|
+
Product.expects(:find).with(1).returns(product)
|
9
|
+
assert_equal product, Product.find(1)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_mocking_an_instance_method_on_a_real_object
|
13
|
+
product = Product.new
|
14
|
+
product.expects(:save).returns(true)
|
15
|
+
assert product.save
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_stubbing_instance_methods_on_real_objects
|
19
|
+
prices = [stub(:pence => 1000), stub(:pence => 2000)]
|
20
|
+
product = Product.new
|
21
|
+
product.stubs(:prices).returns(prices)
|
22
|
+
assert_equal [1000, 2000], product.prices.collect {|p| p.pence}
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_stubbing_an_instance_method_on_all_instances_of_a_class
|
26
|
+
Product.any_instance.stubs(:name).returns('stubbed_name')
|
27
|
+
product = Product.new
|
28
|
+
assert_equal 'stubbed_name', product.name
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_traditional_mocking
|
32
|
+
object = mock()
|
33
|
+
object.expects(:expected_method).with(:p1, :p2).returns(:result)
|
34
|
+
assert_equal :result, object.expected_method(:p1, :p2)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_shortcuts
|
38
|
+
object = stub(:method1 => :result1, :method2 => :result2)
|
39
|
+
assert_equal :result1, object.method1
|
40
|
+
assert_equal :result2, object.method2
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/examples/mocha.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class Enterprise
|
2
|
+
|
3
|
+
def initialize(dilithium)
|
4
|
+
@dilithium = dilithium
|
5
|
+
end
|
6
|
+
|
7
|
+
def go(warp_factor)
|
8
|
+
warp_factor.times { @dilithium.nuke(:anti_matter) }
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'test/unit'
|
14
|
+
require 'mocha'
|
15
|
+
|
16
|
+
class EnterpriseTest < Test::Unit::TestCase
|
17
|
+
|
18
|
+
def test_should_boldly_go
|
19
|
+
dilithium = mock()
|
20
|
+
dilithium.expects(:nuke).with(:anti_matter).at_least_once # auto-verified at end of test
|
21
|
+
enterprise = Enterprise.new(dilithium)
|
22
|
+
enterprise.go(2)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/examples/stubba.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
class Order
|
2
|
+
|
3
|
+
attr_accessor :shipped_on
|
4
|
+
|
5
|
+
def total_cost
|
6
|
+
line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost
|
7
|
+
end
|
8
|
+
|
9
|
+
def total_weight
|
10
|
+
line_items.inject(0) { |total, line_item| total + line_item.weight }
|
11
|
+
end
|
12
|
+
|
13
|
+
def shipping_cost
|
14
|
+
total_weight * 5 + 10
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
|
19
|
+
def find_all
|
20
|
+
# Database.connection.execute('select * from orders...
|
21
|
+
end
|
22
|
+
|
23
|
+
def number_shipped_since(date)
|
24
|
+
find_all.select { |order| order.shipped_on > date }.length
|
25
|
+
end
|
26
|
+
|
27
|
+
def unshipped_value
|
28
|
+
find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'test/unit'
|
36
|
+
require 'mocha'
|
37
|
+
|
38
|
+
class OrderTest < Test::Unit::TestCase
|
39
|
+
|
40
|
+
# illustrates stubbing instance method
|
41
|
+
def test_should_calculate_shipping_cost_based_on_total_weight
|
42
|
+
order = Order.new
|
43
|
+
order.stubs(:total_weight).returns(10)
|
44
|
+
assert_equal 60, order.shipping_cost
|
45
|
+
end
|
46
|
+
|
47
|
+
# illustrates stubbing class method
|
48
|
+
def test_should_count_number_of_orders_shipped_after_specified_date
|
49
|
+
now = Time.now; week_in_secs = 7 * 24 * 60 * 60
|
50
|
+
order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs
|
51
|
+
order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs
|
52
|
+
Order.stubs(:find_all).returns([order_1, order_2])
|
53
|
+
assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs)
|
54
|
+
end
|
55
|
+
|
56
|
+
# illustrates stubbing instance method for all instances of a class
|
57
|
+
def test_should_calculate_value_of_unshipped_orders
|
58
|
+
Order.stubs(:find_all).returns([Order.new, Order.new, Order.new])
|
59
|
+
Order.any_instance.stubs(:shipped_on).returns(nil)
|
60
|
+
Order.any_instance.stubs(:total_cost).returns(10)
|
61
|
+
assert_equal 30, Order.unshipped_value
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/lib/mocha.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'mocha/class_method'
|
2
|
+
|
3
|
+
module Mocha
|
4
|
+
|
5
|
+
class AnyInstanceMethod < ClassMethod
|
6
|
+
|
7
|
+
def unstub
|
8
|
+
remove_new_method
|
9
|
+
restore_original_method
|
10
|
+
stubbee.any_instance.reset_mocha
|
11
|
+
end
|
12
|
+
|
13
|
+
def mock
|
14
|
+
stubbee.any_instance.mocha
|
15
|
+
end
|
16
|
+
|
17
|
+
def hide_original_method
|
18
|
+
if method_exists?(method)
|
19
|
+
begin
|
20
|
+
stubbee.send(:alias_method, hidden_method, method)
|
21
|
+
rescue NameError
|
22
|
+
# deal with nasties like ActiveRecord::Associations::AssociationProxy
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def define_new_method
|
28
|
+
stubbee.class_eval(%{
|
29
|
+
def #{method}(*args, &block)
|
30
|
+
self.class.any_instance.mocha.method_missing(:#{method}, *args, &block)
|
31
|
+
end
|
32
|
+
}, __FILE__, __LINE__)
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove_new_method
|
36
|
+
stubbee.send(:remove_method, method)
|
37
|
+
end
|
38
|
+
|
39
|
+
def restore_original_method
|
40
|
+
if method_exists?(hidden_method)
|
41
|
+
begin
|
42
|
+
stubbee.send(:alias_method, method, hidden_method)
|
43
|
+
stubbee.send(:remove_method, hidden_method)
|
44
|
+
rescue NameError
|
45
|
+
# deal with nasties like ActiveRecord::Associations::AssociationProxy
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_exists?(method)
|
51
|
+
return true if stubbee.public_instance_methods(false).include?(method)
|
52
|
+
return true if stubbee.protected_instance_methods(false).include?(method)
|
53
|
+
return true if stubbee.private_instance_methods(false).include?(method)
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/mocha/api.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'mocha/parameter_matchers'
|
2
|
+
require 'mocha/mockery'
|
3
|
+
require 'mocha/sequence'
|
4
|
+
|
5
|
+
module Mocha # :nodoc:
|
6
|
+
|
7
|
+
# Methods added to Test::Unit::TestCase or equivalent.
|
8
|
+
module API
|
9
|
+
|
10
|
+
include ParameterMatchers
|
11
|
+
|
12
|
+
# :call-seq: mock(name, &block) -> mock object
|
13
|
+
# mock(expected_methods = {}, &block) -> mock object
|
14
|
+
# mock(name, expected_methods = {}, &block) -> mock object
|
15
|
+
#
|
16
|
+
# Creates a mock object.
|
17
|
+
#
|
18
|
+
# +name+ is a +String+ identifier for the mock object.
|
19
|
+
#
|
20
|
+
# +expected_methods+ is a +Hash+ with expected method name symbols as keys and corresponding return values as values.
|
21
|
+
#
|
22
|
+
# Note that (contrary to expectations set up by #stub) these expectations <b>must</b> be fulfilled during the test.
|
23
|
+
# def test_product
|
24
|
+
# product = mock('ipod_product', :manufacturer => 'ipod', :price => 100)
|
25
|
+
# assert_equal 'ipod', product.manufacturer
|
26
|
+
# assert_equal 100, product.price
|
27
|
+
# # an error will be raised unless both Product#manufacturer and Product#price have been called
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# +block+ is an optional block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs.
|
31
|
+
# def test_product
|
32
|
+
# product = mock('ipod_product') do
|
33
|
+
# expects(:manufacturer).returns('ipod')
|
34
|
+
# expects(:price).returns(100)
|
35
|
+
# end
|
36
|
+
# assert_equal 'ipod', product.manufacturer
|
37
|
+
# assert_equal 100, product.price
|
38
|
+
# # an error will be raised unless both Product#manufacturer and Product#price have been called
|
39
|
+
# end
|
40
|
+
def mock(*arguments, &block)
|
41
|
+
name = arguments.shift if arguments.first.is_a?(String)
|
42
|
+
expectations = arguments.shift || {}
|
43
|
+
mock = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block)
|
44
|
+
mock.expects(expectations)
|
45
|
+
mock
|
46
|
+
end
|
47
|
+
|
48
|
+
# :call-seq: stub(name, &block) -> mock object
|
49
|
+
# stub(stubbed_methods = {}, &block) -> mock object
|
50
|
+
# stub(name, stubbed_methods = {}, &block) -> mock object
|
51
|
+
#
|
52
|
+
# Creates a mock object.
|
53
|
+
#
|
54
|
+
# +name+ is a +String+ identifier for the mock object.
|
55
|
+
#
|
56
|
+
# +stubbed_methods+ is a +Hash+ with stubbed method name symbols as keys and corresponding return values as values.
|
57
|
+
# Note that (contrary to expectations set up by #mock) these expectations <b>need not</b> be fulfilled during the test.
|
58
|
+
# def test_product
|
59
|
+
# product = stub('ipod_product', :manufacturer => 'ipod', :price => 100)
|
60
|
+
# assert_equal 'ipod', product.manufacturer
|
61
|
+
# assert_equal 100, product.price
|
62
|
+
# # an error will not be raised even if Product#manufacturer and Product#price have not been called
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# +block+ is an optional block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs.
|
66
|
+
# def test_product
|
67
|
+
# product = stub('ipod_product') do
|
68
|
+
# stubs(:manufacturer).returns('ipod')
|
69
|
+
# stubs(:price).returns(100)
|
70
|
+
# end
|
71
|
+
# assert_equal 'ipod', product.manufacturer
|
72
|
+
# assert_equal 100, product.price
|
73
|
+
# # an error will not be raised even if Product#manufacturer and Product#price have not been called
|
74
|
+
# end
|
75
|
+
def stub(*arguments, &block)
|
76
|
+
name = arguments.shift if arguments.first.is_a?(String)
|
77
|
+
expectations = arguments.shift || {}
|
78
|
+
stub = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block)
|
79
|
+
stub.stubs(expectations)
|
80
|
+
stub
|
81
|
+
end
|
82
|
+
|
83
|
+
# :call-seq: stub_everything(name, &block) -> mock object
|
84
|
+
# stub_everything(stubbed_methods = {}, &block) -> mock object
|
85
|
+
# stub_everything(name, stubbed_methods = {}, &block) -> mock object
|
86
|
+
#
|
87
|
+
# Creates a mock object that accepts calls to any method.
|
88
|
+
#
|
89
|
+
# By default it will return +nil+ for any method call.
|
90
|
+
#
|
91
|
+
# +block+ is a block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs.
|
92
|
+
#
|
93
|
+
# +name+ and +stubbed_methods+ work in the same way as for #stub.
|
94
|
+
# def test_product
|
95
|
+
# product = stub_everything('ipod_product', :price => 100)
|
96
|
+
# assert_nil product.manufacturer
|
97
|
+
# assert_nil product.any_old_method
|
98
|
+
# assert_equal 100, product.price
|
99
|
+
# end
|
100
|
+
def stub_everything(*arguments, &block)
|
101
|
+
name = arguments.shift if arguments.first.is_a?(String)
|
102
|
+
expectations = arguments.shift || {}
|
103
|
+
stub = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block)
|
104
|
+
stub.stub_everything
|
105
|
+
stub.stubs(expectations)
|
106
|
+
stub
|
107
|
+
end
|
108
|
+
|
109
|
+
# :call-seq: sequence(name) -> sequence
|
110
|
+
#
|
111
|
+
# Returns a new sequence that is used to constrain the order in which expectations can occur.
|
112
|
+
#
|
113
|
+
# Specify that an expected invocation must occur in within a named +sequence+ by using Expectation#in_sequence.
|
114
|
+
#
|
115
|
+
# See also Expectation#in_sequence.
|
116
|
+
# breakfast = sequence('breakfast')
|
117
|
+
#
|
118
|
+
# egg = mock('egg')
|
119
|
+
# egg.expects(:crack).in_sequence(breakfast)
|
120
|
+
# egg.expects(:fry).in_sequence(breakfast)
|
121
|
+
# egg.expects(:eat).in_sequence(breakfast)
|
122
|
+
def sequence(name)
|
123
|
+
Sequence.new(name)
|
124
|
+
end
|
125
|
+
|
126
|
+
# :call-seq: states(name) -> state_machine
|
127
|
+
#
|
128
|
+
# Returns a new +state_machine+ that is used to constrain the order in which expectations can occur.
|
129
|
+
#
|
130
|
+
# Specify the initial +state+ of the +state_machine+ by using StateMachine#starts_as.
|
131
|
+
#
|
132
|
+
# Specify that an expected invocation should change the +state+ of the +state_machine+ by using Expectation#then.
|
133
|
+
#
|
134
|
+
# Specify that an expected invocation should be constrained to occur within a particular +state+ by using Expectation#when.
|
135
|
+
#
|
136
|
+
# A test can contain multiple +state_machines+.
|
137
|
+
#
|
138
|
+
# See also Expectation#then, Expectation#when and StateMachine.
|
139
|
+
# power = states('power').starts_as('off')
|
140
|
+
#
|
141
|
+
# radio = mock('radio')
|
142
|
+
# radio.expects(:switch_on).then(power.is('on'))
|
143
|
+
# radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
|
144
|
+
# radio.expects(:adjust_volume).with(+5).when(power.is('on'))
|
145
|
+
# radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
|
146
|
+
# radio.expects(:adjust_volume).with(-5).when(power.is('on'))
|
147
|
+
# radio.expects(:switch_off).then(power.is('off'))
|
148
|
+
def states(name)
|
149
|
+
Mockery.instance.new_state_machine(name)
|
150
|
+
end
|
151
|
+
|
152
|
+
def mocha_setup # :nodoc:
|
153
|
+
end
|
154
|
+
|
155
|
+
def mocha_verify(assertion_counter = nil) # :nodoc:
|
156
|
+
Mockery.instance.verify(assertion_counter)
|
157
|
+
end
|
158
|
+
|
159
|
+
def mocha_teardown # :nodoc:
|
160
|
+
Mockery.instance.teardown
|
161
|
+
Mockery.reset_instance
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.const_missing(name)
|
167
|
+
return super unless name == :Standalone
|
168
|
+
require 'mocha/deprecation'
|
169
|
+
Deprecation.warning "Mocha::Standalone has been renamed to Mocha::API"
|
170
|
+
return API
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Mocha
|
2
|
+
|
3
|
+
class ArgumentIterator
|
4
|
+
|
5
|
+
def initialize(argument)
|
6
|
+
@argument = argument
|
7
|
+
end
|
8
|
+
|
9
|
+
def each(&block)
|
10
|
+
if @argument.is_a?(Hash) then
|
11
|
+
@argument.each do |method_name, return_value|
|
12
|
+
block.call(method_name, return_value)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
block.call(@argument)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Mocha
|
2
|
+
|
3
|
+
class BacktraceFilter
|
4
|
+
|
5
|
+
LIB_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), "..")) + File::SEPARATOR
|
6
|
+
|
7
|
+
def initialize(lib_directory = LIB_DIRECTORY)
|
8
|
+
@lib_directory = lib_directory
|
9
|
+
end
|
10
|
+
|
11
|
+
def filtered(backtrace)
|
12
|
+
backtrace.reject { |location| Regexp.new(@lib_directory).match(File.expand_path(location)) }
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Mocha
|
2
|
+
|
3
|
+
class Cardinality
|
4
|
+
|
5
|
+
INFINITY = 1 / 0.0
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def exactly(count)
|
10
|
+
new(count, count)
|
11
|
+
end
|
12
|
+
|
13
|
+
def at_least(count)
|
14
|
+
new(count, INFINITY)
|
15
|
+
end
|
16
|
+
|
17
|
+
def at_most(count)
|
18
|
+
new(0, count)
|
19
|
+
end
|
20
|
+
|
21
|
+
def times(range_or_count)
|
22
|
+
case range_or_count
|
23
|
+
when Range then new(range_or_count.first, range_or_count.last)
|
24
|
+
else new(range_or_count, range_or_count)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(required, maximum)
|
31
|
+
@required, @maximum = required, maximum
|
32
|
+
end
|
33
|
+
|
34
|
+
def invocations_allowed?(invocation_count)
|
35
|
+
invocation_count < maximum
|
36
|
+
end
|
37
|
+
|
38
|
+
def satisfied?(invocations_so_far)
|
39
|
+
invocations_so_far >= required
|
40
|
+
end
|
41
|
+
|
42
|
+
def needs_verifying?
|
43
|
+
!allowed_any_number_of_times?
|
44
|
+
end
|
45
|
+
|
46
|
+
def verified?(invocation_count)
|
47
|
+
(invocation_count >= required) && (invocation_count <= maximum)
|
48
|
+
end
|
49
|
+
|
50
|
+
def allowed_any_number_of_times?
|
51
|
+
required == 0 && infinite?(maximum)
|
52
|
+
end
|
53
|
+
|
54
|
+
def used?(invocation_count)
|
55
|
+
(invocation_count > 0) || (maximum == 0)
|
56
|
+
end
|
57
|
+
|
58
|
+
def mocha_inspect
|
59
|
+
if allowed_any_number_of_times?
|
60
|
+
"allowed any number of times"
|
61
|
+
else
|
62
|
+
if required == 0 && maximum == 0
|
63
|
+
"expected never"
|
64
|
+
elsif required == maximum
|
65
|
+
"expected exactly #{times(required)}"
|
66
|
+
elsif infinite?(maximum)
|
67
|
+
"expected at least #{times(required)}"
|
68
|
+
elsif required == 0
|
69
|
+
"expected at most #{times(maximum)}"
|
70
|
+
else
|
71
|
+
"expected between #{required} and #{times(maximum)}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
attr_reader :required, :maximum
|
79
|
+
|
80
|
+
def times(number)
|
81
|
+
case number
|
82
|
+
when 0 then "no times"
|
83
|
+
when 1 then "once"
|
84
|
+
when 2 then "twice"
|
85
|
+
else "#{number} times"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def infinite?(number)
|
90
|
+
number.respond_to?(:infinite?) && number.infinite?
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|