mocha 0.5.6 → 0.9.0
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/README +4 -4
- data/RELEASE +45 -0
- data/Rakefile +55 -33
- data/lib/mocha.rb +1 -0
- data/lib/mocha/any_instance_method.rb +24 -4
- data/lib/mocha/backtrace_filter.rb +17 -0
- data/lib/mocha/cardinality.rb +92 -0
- data/lib/mocha/central.rb +1 -9
- data/lib/mocha/change_state_side_effect.rb +19 -0
- data/lib/mocha/class_method.rb +25 -5
- data/lib/mocha/configuration.rb +60 -0
- data/lib/mocha/exception_raiser.rb +1 -1
- data/lib/mocha/expectation.rb +109 -48
- data/lib/mocha/expectation_error.rb +6 -6
- data/lib/mocha/expectation_list.rb +10 -14
- data/lib/mocha/in_state_ordering_constraint.rb +19 -0
- data/lib/mocha/instance_method.rb +9 -0
- data/lib/mocha/logger.rb +15 -0
- data/lib/mocha/mock.rb +19 -14
- data/lib/mocha/mockery.rb +166 -0
- data/lib/mocha/module_method.rb +17 -0
- data/lib/mocha/names.rb +53 -0
- data/lib/mocha/object.rb +26 -9
- data/lib/mocha/parameter_matchers.rb +2 -1
- data/lib/mocha/parameter_matchers/all_of.rb +3 -3
- data/lib/mocha/parameter_matchers/any_of.rb +3 -3
- data/lib/mocha/parameter_matchers/anything.rb +1 -1
- data/lib/mocha/parameter_matchers/has_entries.rb +4 -1
- data/lib/mocha/parameter_matchers/has_entry.rb +3 -2
- data/lib/mocha/parameter_matchers/has_key.rb +1 -1
- data/lib/mocha/parameter_matchers/has_value.rb +1 -1
- data/lib/mocha/parameter_matchers/not.rb +2 -2
- data/lib/mocha/parameter_matchers/object.rb +1 -1
- data/lib/mocha/parameter_matchers/optionally.rb +22 -0
- data/lib/mocha/parameter_matchers/regexp_matches.rb +2 -2
- data/lib/mocha/parameter_matchers/responds_with.rb +43 -0
- data/lib/mocha/parameter_matchers/yaml_equivalent.rb +43 -0
- data/lib/mocha/single_return_value.rb +2 -9
- data/lib/mocha/standalone.rb +151 -17
- data/lib/mocha/state_machine.rb +91 -0
- data/lib/mocha/stubbing_error.rb +16 -0
- data/lib/mocha/test_case_adapter.rb +76 -22
- data/lib/stubba.rb +2 -1
- data/test/acceptance/acceptance_test_helper.rb +38 -0
- data/test/acceptance/bug_18914_test.rb +43 -0
- data/test/acceptance/{expected_invocation_count_acceptance_test.rb → expected_invocation_count_test.rb} +29 -20
- data/test/acceptance/failure_messages_test.rb +64 -0
- data/test/acceptance/{mocha_acceptance_test.rb → mocha_example_test.rb} +5 -5
- data/test/{integration/mocha_test_result_integration_test.rb → acceptance/mocha_test_result_test.rb} +19 -40
- data/test/acceptance/mock_test.rb +100 -0
- data/test/acceptance/{mock_with_initializer_block_acceptance_test.rb → mock_with_initializer_block_test.rb} +12 -5
- data/test/acceptance/{mocked_methods_dispatch_acceptance_test.rb → mocked_methods_dispatch_test.rb} +12 -5
- data/test/acceptance/{optional_parameters_acceptance_test.rb → optional_parameters_test.rb} +11 -4
- data/test/acceptance/{parameter_matcher_acceptance_test.rb → parameter_matcher_test.rb} +67 -5
- data/test/acceptance/{partial_mocks_acceptance_test.rb → partial_mocks_test.rb} +12 -5
- data/test/acceptance/return_value_test.rb +52 -0
- data/test/acceptance/{sequence_acceptance_test.rb → sequence_test.rb} +13 -6
- data/test/acceptance/{standalone_acceptance_test.rb → standalone_test.rb} +19 -11
- 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 +165 -0
- data/test/acceptance/stub_module_method_test.rb +163 -0
- data/test/acceptance/stub_test.rb +52 -0
- data/test/acceptance/{stubba_acceptance_test.rb → stubba_example_test.rb} +1 -1
- data/test/{integration/stubba_test_result_integration_test.rb → acceptance/stubba_test_result_test.rb} +17 -36
- 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 +155 -0
- data/test/acceptance/stubbing_non_existent_instance_method_test.rb +145 -0
- data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +130 -0
- data/test/acceptance/stubbing_non_public_class_method_test.rb +161 -0
- data/test/acceptance/stubbing_non_public_instance_method_test.rb +141 -0
- data/test/acceptance/stubbing_on_non_mock_object_test.rb +64 -0
- data/test/execution_point.rb +3 -1
- data/test/simple_counter.rb +13 -0
- data/test/test_helper.rb +0 -1
- data/test/test_runner.rb +6 -4
- data/test/unit/any_instance_method_test.rb +1 -1
- data/test/unit/array_inspect_test.rb +1 -1
- data/test/unit/backtrace_filter_test.rb +19 -0
- data/test/unit/cardinality_test.rb +56 -0
- data/test/unit/central_test.rb +4 -63
- data/test/unit/change_state_side_effect_test.rb +41 -0
- data/test/unit/class_method_test.rb +38 -1
- data/test/unit/date_time_inspect_test.rb +1 -1
- data/test/unit/{expectation_raiser_test.rb → exception_raiser_test.rb} +14 -0
- data/test/unit/expectation_list_test.rb +4 -22
- data/test/unit/expectation_test.rb +70 -94
- data/test/unit/in_state_ordering_constraint_test.rb +43 -0
- data/test/unit/mock_test.rb +16 -37
- data/test/unit/mockery_test.rb +149 -0
- data/test/unit/{no_yield_test.rb → no_yields_test.rb} +0 -0
- data/test/unit/object_test.rb +6 -89
- data/test/unit/parameter_matchers/equals_test.rb +25 -0
- data/test/unit/parameter_matchers/has_entries_test.rb +22 -1
- data/test/unit/parameter_matchers/has_entry_test.rb +24 -2
- data/test/unit/parameter_matchers/has_key_test.rb +11 -0
- data/test/unit/parameter_matchers/has_value_test.rb +12 -0
- data/test/unit/parameter_matchers/regexp_matches_test.rb +1 -1
- data/test/unit/parameter_matchers/responds_with_test.rb +25 -0
- data/test/unit/parameter_matchers/stub_matcher.rb +4 -0
- data/test/unit/parameter_matchers/yaml_equivalent_test.rb +25 -0
- data/test/unit/single_return_value_test.rb +0 -19
- data/test/unit/state_machine_test.rb +98 -0
- metadata +108 -69
- data/lib/mocha/auto_verify.rb +0 -118
- data/lib/mocha/infinite_range.rb +0 -25
- data/lib/mocha/missing_expectation.rb +0 -17
- data/lib/mocha/setup_and_teardown.rb +0 -23
- data/lib/mocha/stub.rb +0 -18
- data/test/integration/stubba_integration_test.rb +0 -89
- data/test/unit/auto_verify_test.rb +0 -129
- data/test/unit/expectation_error_test.rb +0 -24
- data/test/unit/infinite_range_test.rb +0 -53
- data/test/unit/missing_expectation_test.rb +0 -42
- data/test/unit/setup_and_teardown_test.rb +0 -76
- data/test/unit/stub_test.rb +0 -24
data/README
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
= Mocha
|
2
2
|
|
3
|
-
Mocha is a library for mocking and stubbing using a syntax like that of JMock[http://www.jmock.org]
|
3
|
+
Mocha is a library for mocking and stubbing using a syntax like that of JMock[http://www.jmock.org].
|
4
4
|
|
5
|
-
|
5
|
+
It can be used with many testing frameworks e.g. Test::Unit[http://www.ruby-doc.org/core/classes/Test/Unit.html], RSpec[http://rspec.info/], test/spec[http://chneukirchen.org/repos/testspec/README], expectations[http://expectations.rubyforge.org/], Dust[http://dust.rubyforge.org/] and even JtestR[http://jtestr.codehaus.org/].
|
6
6
|
|
7
|
-
Mocha provides a unified, simple and readable syntax for both traditional mocking and
|
7
|
+
Mocha provides a unified, simple and readable syntax for both traditional mocking and partial mocking.
|
8
8
|
|
9
|
-
Mocha
|
9
|
+
Mocha was harvested from projects at Reevoo[http://www.reevoo.com] by me (James[http://blog.floehopper.org]) and my colleagues Ben[http://www.techbelly.com/], Chris[http://blog.seagul.co.uk] and Paul[http://po-ru.com].
|
10
10
|
|
11
11
|
== Download and Installation
|
12
12
|
|
data/RELEASE
CHANGED
@@ -1,3 +1,48 @@
|
|
1
|
+
= 0.9.0
|
2
|
+
|
3
|
+
* Configurable warnings or errors
|
4
|
+
* when a method on a non-public method is stubbed
|
5
|
+
* when a method on a non-existent method is stubbed
|
6
|
+
* when a method on a non-mock object is stubbed
|
7
|
+
* when a method is stubbed unnecessarily (i.e. the stubbed method is not called during the test)
|
8
|
+
|
9
|
+
* Improved error messages
|
10
|
+
* User-friendly list of unsatisfied expectations, satisfied expectations and state machines.
|
11
|
+
* Improved readability of cardinality description.
|
12
|
+
* Display sensible failure message for any_instance expectations e.g. "#<AnyInstance:Foo>.bar - expected calls: 1, actual calls: 0"
|
13
|
+
|
14
|
+
* Parameter matchers
|
15
|
+
* New to this release
|
16
|
+
* optionally (allows matching of optional parameters if available)
|
17
|
+
* yaml_equivalent (allows matching of YAML that represents the specified object)
|
18
|
+
* responds_with (tests the quack not the duck)
|
19
|
+
* Nesting of parameter matchers is now supported.
|
20
|
+
|
21
|
+
* 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.
|
22
|
+
|
23
|
+
* Added JMock-style sequences for constraining the order of expected invocations. See Standalone#sequence and Expectation#in_sequence.
|
24
|
+
|
25
|
+
* Added JMock-style states for constraining the order of expected invocations. See Standalone#states, Expectation#then, Expectation#when and StateMachine.
|
26
|
+
|
27
|
+
* Compatibility with versions of Ruby
|
28
|
+
* Compatibility with Ruby v1.9. All test errors and warnings fixed.
|
29
|
+
* Nasty fix so that TestCaseAdaptor works consistently with earlier versions of Test::Unit as well as more recent versions.
|
30
|
+
* 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.
|
31
|
+
* 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.
|
32
|
+
|
33
|
+
* Added deprecation warning in stubba.rb which is no longer needed and will be removed.
|
34
|
+
|
35
|
+
* Supply positioning information to evals to improve any error messages. See http://ola-bini.blogspot.com/2008/01/ruby-antipattern-using-eval-without.html
|
36
|
+
|
37
|
+
* Bug fixes
|
38
|
+
* 18914 in revision 296 - http://rubyforge.org/tracker/index.php?func=detail&aid=18914&group_id=1917&atid=7477
|
39
|
+
* 18917 in revision 295 - http://rubyforge.org/tracker/index.php?func=detail&aid=18917&group_id=1917&atid=7477
|
40
|
+
* 18336 in revision 287 - http://rubyforge.org/tracker/index.php?func=detail&aid=18336&group_id=1917&atid=7477
|
41
|
+
* 17835 in revision 255 - http://rubyforge.org/tracker/index.php?func=detail&aid=17835&group_id=1917&atid=7477
|
42
|
+
* 17412 in revision 242 - http://rubyforge.org/tracker/index.php?func=detail&aid=17412&group_id=1917&atid=7477
|
43
|
+
* 15977 in revision 198 - http://rubyforge.org/tracker/index.php?func=detail&aid=15977&group_id=1917&atid=7477
|
44
|
+
* 11885 in revision 156 - http://rubyforge.org/tracker/index.php?func=detail&aid=11885&group_id=1917&atid=7477
|
45
|
+
|
1
46
|
= 0.5.5 (r167)
|
2
47
|
|
3
48
|
- Renamed Matches parameter matcher to RegexpMatches for clarity.
|
data/Rakefile
CHANGED
@@ -5,50 +5,72 @@ require 'rake/testtask'
|
|
5
5
|
require 'rake/contrib/sshpublisher'
|
6
6
|
|
7
7
|
module Mocha
|
8
|
-
VERSION = "0.
|
8
|
+
VERSION = "0.9.0"
|
9
9
|
end
|
10
10
|
|
11
11
|
desc "Run all tests"
|
12
|
-
task
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
task 'default' => ['test:units', 'test:acceptance']
|
13
|
+
|
14
|
+
namespace 'test' do
|
15
|
+
|
16
|
+
unit_tests = FileList['test/unit/**/*_test.rb']
|
17
|
+
acceptance_tests = FileList['test/acceptance/*_test.rb']
|
18
|
+
|
19
|
+
desc "Run unit tests"
|
20
|
+
Rake::TestTask.new('units') do |t|
|
21
|
+
t.libs << 'test'
|
22
|
+
t.test_files = unit_tests
|
23
|
+
t.verbose = true
|
24
|
+
t.warning = true
|
25
|
+
end
|
23
26
|
|
24
|
-
desc "Run
|
25
|
-
Rake::TestTask.new(
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
27
|
+
desc "Run acceptance tests"
|
28
|
+
Rake::TestTask.new('acceptance') do |t|
|
29
|
+
t.libs << 'test'
|
30
|
+
t.test_files = acceptance_tests
|
31
|
+
t.verbose = true
|
32
|
+
t.warning = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# require 'rcov/rcovtask'
|
36
|
+
# Rcov::RcovTask.new('coverage') do |t|
|
37
|
+
# t.libs << 'test'
|
38
|
+
# t.test_files = unit_tests + acceptance_tests
|
39
|
+
# t.verbose = true
|
40
|
+
# t.warning = true
|
41
|
+
# t.rcov_opts << '--sort coverage'
|
42
|
+
# t.rcov_opts << '--xref'
|
43
|
+
# end
|
31
44
|
|
32
|
-
desc "Run acceptance tests"
|
33
|
-
Rake::TestTask.new(:test_acceptance) do |t|
|
34
|
-
t.libs << 'test'
|
35
|
-
t.test_files = FileList['test/acceptance/*_test.rb']
|
36
|
-
t.verbose = true
|
37
|
-
t.warning = true
|
38
45
|
end
|
39
46
|
|
40
47
|
desc 'Generate RDoc'
|
41
|
-
Rake::RDocTask.new do |task|
|
48
|
+
Rake::RDocTask.new('rdoc') do |task|
|
42
49
|
task.main = 'README'
|
43
50
|
task.title = "Mocha #{Mocha::VERSION}"
|
44
51
|
task.rdoc_dir = 'doc'
|
45
52
|
task.template = File.expand_path(File.join(File.dirname(__FILE__), "templates", "html_with_google_analytics"))
|
46
|
-
task.rdoc_files.include(
|
53
|
+
task.rdoc_files.include(
|
54
|
+
'README',
|
55
|
+
'RELEASE',
|
56
|
+
'COPYING',
|
57
|
+
'MIT-LICENSE',
|
58
|
+
'agiledox.txt',
|
59
|
+
'lib/mocha/standalone.rb',
|
60
|
+
'lib/mocha/mock.rb',
|
61
|
+
'lib/mocha/expectation.rb',
|
62
|
+
'lib/mocha/object.rb',
|
63
|
+
'lib/mocha/parameter_matchers.rb',
|
64
|
+
'lib/mocha/parameter_matchers',
|
65
|
+
'lib/mocha/state_machine.rb',
|
66
|
+
'lib/mocha/configuration.rb',
|
67
|
+
'lib/mocha/stubbing_error.rb'
|
68
|
+
)
|
47
69
|
end
|
48
|
-
task
|
70
|
+
task 'rdoc' => 'examples'
|
49
71
|
|
50
72
|
desc "Upload RDoc to RubyForge"
|
51
|
-
task
|
73
|
+
task 'publish_rdoc' => ['rdoc', 'examples'] do
|
52
74
|
Rake::SshDirPublisher.new("jamesmead@rubyforge.org", "/var/www/gforge-projects/mocha", "doc").upload
|
53
75
|
end
|
54
76
|
|
@@ -69,7 +91,7 @@ file 'agiledox.txt' do
|
|
69
91
|
end
|
70
92
|
|
71
93
|
desc "Convert example ruby files to syntax-highlighted html"
|
72
|
-
task
|
94
|
+
task 'examples' do
|
73
95
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "vendor", "coderay-0.7.4.215", "lib"))
|
74
96
|
require 'coderay'
|
75
97
|
mkdir_p 'doc/examples'
|
@@ -119,16 +141,16 @@ Rake::GemPackageTask.new(specification) do |package|
|
|
119
141
|
package.need_tar = true
|
120
142
|
end
|
121
143
|
|
122
|
-
task
|
144
|
+
task 'verify_user' do
|
123
145
|
raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
|
124
146
|
end
|
125
147
|
|
126
|
-
task
|
148
|
+
task 'verify_password' do
|
127
149
|
raise "RUBYFORGE_PASSWORD environment variable not set!" unless ENV['RUBYFORGE_PASSWORD']
|
128
150
|
end
|
129
151
|
|
130
152
|
desc "Publish package files on RubyForge."
|
131
|
-
task
|
153
|
+
task 'publish_packages' => ['verify_user', 'verify_password', 'package'] do
|
132
154
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "vendor", "meta_project-0.4.15", "lib"))
|
133
155
|
require 'meta_project'
|
134
156
|
require 'rake/contrib/xforge'
|
data/lib/mocha.rb
CHANGED
@@ -15,21 +15,41 @@ module Mocha
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def hide_original_method
|
18
|
-
|
18
|
+
if method_exists?(method)
|
19
|
+
begin
|
20
|
+
stubbee.class_eval("alias_method :#{hidden_method}, :#{method}", __FILE__, __LINE__)
|
21
|
+
rescue NameError
|
22
|
+
# deal with nasties like ActiveRecord::Associations::AssociationProxy
|
23
|
+
end
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
def define_new_method
|
22
|
-
stubbee.class_eval
|
28
|
+
stubbee.class_eval("def #{method}(*args, &block); self.class.any_instance.mocha.method_missing(:#{method}, *args, &block); end", __FILE__, __LINE__)
|
23
29
|
end
|
24
30
|
|
25
31
|
def remove_new_method
|
26
|
-
stubbee.class_eval
|
32
|
+
stubbee.class_eval("remove_method :#{method}", __FILE__, __LINE__)
|
27
33
|
end
|
28
34
|
|
29
35
|
def restore_original_method
|
30
|
-
|
36
|
+
if method_exists?(hidden_method)
|
37
|
+
begin
|
38
|
+
stubbee.class_eval("alias_method :#{method}, :#{hidden_method}; remove_method :#{hidden_method}", __FILE__, __LINE__)
|
39
|
+
rescue NameError
|
40
|
+
# deal with nasties like ActiveRecord::Associations::AssociationProxy
|
41
|
+
end
|
42
|
+
end
|
31
43
|
end
|
32
44
|
|
45
|
+
def method_exists?(method)
|
46
|
+
existing_methods = []
|
47
|
+
existing_methods += stubbee.public_instance_methods(false)
|
48
|
+
existing_methods += stubbee.protected_instance_methods(false)
|
49
|
+
existing_methods += stubbee.private_instance_methods(false)
|
50
|
+
existing_methods.any? { |m| m.to_s == method.to_s }
|
51
|
+
end
|
52
|
+
|
33
53
|
end
|
34
54
|
|
35
55
|
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,92 @@
|
|
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
|
24
|
+
new(range_or_count.first, range_or_count.last)
|
25
|
+
else
|
26
|
+
new(range_or_count, range_or_count)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(required, maximum)
|
33
|
+
@required, @maximum = required, maximum
|
34
|
+
end
|
35
|
+
|
36
|
+
def invocations_allowed?(invocation_count)
|
37
|
+
invocation_count < maximum
|
38
|
+
end
|
39
|
+
|
40
|
+
def satisfied?(invocations_so_far)
|
41
|
+
invocations_so_far >= required
|
42
|
+
end
|
43
|
+
|
44
|
+
def needs_verifying?
|
45
|
+
!allowed_any_number_of_times?
|
46
|
+
end
|
47
|
+
|
48
|
+
def verified?(invocation_count)
|
49
|
+
(invocation_count >= required) && (invocation_count <= maximum)
|
50
|
+
end
|
51
|
+
|
52
|
+
def allowed_any_number_of_times?
|
53
|
+
required == 0 && infinite?(maximum)
|
54
|
+
end
|
55
|
+
|
56
|
+
def used?(invocation_count)
|
57
|
+
(invocation_count > 0) || (maximum == 0)
|
58
|
+
end
|
59
|
+
|
60
|
+
def mocha_inspect
|
61
|
+
if allowed_any_number_of_times?
|
62
|
+
"allowed any number of times"
|
63
|
+
else
|
64
|
+
if required == 0 && maximum == 0
|
65
|
+
"expected never"
|
66
|
+
elsif required == maximum
|
67
|
+
"expected exactly #{times(required)}"
|
68
|
+
elsif infinite?(maximum)
|
69
|
+
"expected at least #{times(required)}"
|
70
|
+
elsif required == 0
|
71
|
+
"expected at most #{times(maximum)}"
|
72
|
+
else
|
73
|
+
"expected between #{required} and #{times(maximum)}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
attr_reader :required, :maximum
|
81
|
+
|
82
|
+
def times(number)
|
83
|
+
number == 1 ? "once" : "#{number} times"
|
84
|
+
end
|
85
|
+
|
86
|
+
def infinite?(number)
|
87
|
+
number.respond_to?(:infinite?) && number.infinite?
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/lib/mocha/central.rb
CHANGED
@@ -11,18 +11,10 @@ module Mocha
|
|
11
11
|
def stub(method)
|
12
12
|
unless stubba_methods.include?(method)
|
13
13
|
method.stub
|
14
|
-
stubba_methods.push
|
14
|
+
stubba_methods.push(method)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def verify_all(&block)
|
19
|
-
unique_mocks.each { |mock| mock.verify(&block) }
|
20
|
-
end
|
21
|
-
|
22
|
-
def unique_mocks
|
23
|
-
stubba_methods.inject({}) { |mocks, method| mocks[method.mock.__id__] = method.mock; mocks }.values
|
24
|
-
end
|
25
|
-
|
26
18
|
def unstub_all
|
27
19
|
while stubba_methods.length > 0
|
28
20
|
method = stubba_methods.pop
|
data/lib/mocha/class_method.rb
CHANGED
@@ -26,19 +26,31 @@ module Mocha
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def hide_original_method
|
29
|
-
|
29
|
+
if method_exists?(method)
|
30
|
+
begin
|
31
|
+
stubbee.__metaclass__.class_eval("alias_method :#{hidden_method}, :#{method}", __FILE__, __LINE__)
|
32
|
+
rescue NameError
|
33
|
+
# deal with nasties like ActiveRecord::Associations::AssociationProxy
|
34
|
+
end
|
35
|
+
end
|
30
36
|
end
|
31
37
|
|
32
38
|
def define_new_method
|
33
|
-
stubbee.__metaclass__.class_eval
|
39
|
+
stubbee.__metaclass__.class_eval("def #{method}(*args, &block); mocha.method_missing(:#{method}, *args, &block); end", __FILE__, __LINE__)
|
34
40
|
end
|
35
41
|
|
36
42
|
def remove_new_method
|
37
|
-
stubbee.__metaclass__.class_eval
|
43
|
+
stubbee.__metaclass__.class_eval("remove_method :#{method}", __FILE__, __LINE__)
|
38
44
|
end
|
39
45
|
|
40
46
|
def restore_original_method
|
41
|
-
|
47
|
+
if method_exists?(hidden_method)
|
48
|
+
begin
|
49
|
+
stubbee.__metaclass__.class_eval("alias_method :#{method}, :#{hidden_method}; remove_method :#{hidden_method}", __FILE__, __LINE__)
|
50
|
+
rescue NameError
|
51
|
+
# deal with nasties like ActiveRecord::Associations::AssociationProxy
|
52
|
+
end
|
53
|
+
end
|
42
54
|
end
|
43
55
|
|
44
56
|
def hidden_method
|
@@ -52,7 +64,7 @@ module Mocha
|
|
52
64
|
|
53
65
|
def eql?(other)
|
54
66
|
return false unless (other.class == self.class)
|
55
|
-
(stubbee == other.stubbee) and (method == other.method)
|
67
|
+
(stubbee.object_id == other.stubbee.object_id) and (method == other.method)
|
56
68
|
end
|
57
69
|
|
58
70
|
alias_method :==, :eql?
|
@@ -60,6 +72,14 @@ module Mocha
|
|
60
72
|
def to_s
|
61
73
|
"#{stubbee}.#{method}"
|
62
74
|
end
|
75
|
+
|
76
|
+
def method_exists?(method)
|
77
|
+
existing_methods = []
|
78
|
+
existing_methods += stubbee.public_methods(true) - stubbee.superclass.public_methods(true)
|
79
|
+
existing_methods += stubbee.protected_methods(true) - stubbee.superclass.protected_methods(true)
|
80
|
+
existing_methods += stubbee.private_methods(true) - stubbee.superclass.private_methods(true)
|
81
|
+
existing_methods.any? { |m| m.to_s == method.to_s }
|
82
|
+
end
|
63
83
|
|
64
84
|
end
|
65
85
|
|