mocha 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +3 -0
- data/README +148 -0
- data/lib/auto_mocha.rb +1 -0
- data/lib/auto_mocha/auto_mock.rb +54 -0
- data/lib/auto_mocha/mock_class.rb +38 -0
- data/lib/mocha.rb +1 -0
- data/lib/mocha/expectation.rb +116 -0
- data/lib/mocha/infinite_range.rb +27 -0
- data/lib/mocha/inspect.rb +37 -0
- data/lib/mocha/metaclass.rb +7 -0
- data/lib/mocha/mock.rb +30 -0
- data/lib/mocha/mock_methods.rb +55 -0
- data/lib/mocha/pretty_parameters.rb +28 -0
- data/lib/stubba.rb +2 -0
- data/lib/stubba/any_instance_method.rb +31 -0
- data/lib/stubba/class_method.rb +61 -0
- data/lib/stubba/instance_method.rb +22 -0
- data/lib/stubba/object.rb +77 -0
- data/lib/stubba/stubba.rb +27 -0
- data/lib/stubba/test_case.rb +65 -0
- data/test/all_tests.rb +100 -0
- data/test/auto_mocha/auto_mock_test.rb +85 -0
- data/test/auto_mocha/mock_class_test.rb +179 -0
- data/test/auto_mock_acceptance_test.rb +36 -0
- data/test/method_definer.rb +18 -0
- data/test/mocha/expectation_test.rb +216 -0
- data/test/mocha/infinite_range_test.rb +50 -0
- data/test/mocha/inspect_test.rb +79 -0
- data/test/mocha/mock_methods_test.rb +141 -0
- data/test/mocha/mock_test.rb +64 -0
- data/test/mocha/pretty_parameters_test.rb +32 -0
- data/test/mocha_acceptance_test.rb +112 -0
- data/test/stubba/any_instance_method_test.rb +113 -0
- data/test/stubba/class_method_test.rb +149 -0
- data/test/stubba/instance_method_test.rb +97 -0
- data/test/stubba/object_test.rb +147 -0
- data/test/stubba/stubba_test.rb +62 -0
- data/test/stubba/test_case_test.rb +41 -0
- data/test/stubba_acceptance_test.rb +107 -0
- data/test/stubba_integration_test.rb +59 -0
- data/test/stubba_replacer.rb +13 -0
- data/test/test_helper.rb +4 -0
- metadata +91 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'mocha/expectation'
|
2
|
+
|
3
|
+
module Mocha
|
4
|
+
module MockMethods
|
5
|
+
|
6
|
+
def expectations
|
7
|
+
@expectations ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def expects(symbol)
|
11
|
+
expectations << Expectation.new(symbol)
|
12
|
+
expectations.last
|
13
|
+
end
|
14
|
+
|
15
|
+
def stubs(symbol)
|
16
|
+
expectations << Stub.new(symbol)
|
17
|
+
expectations.last
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(symbol, *arguments, &block)
|
21
|
+
matching_expectation = matching_expectation(symbol, *arguments)
|
22
|
+
if matching_expectation then
|
23
|
+
matching_expectation.invoke
|
24
|
+
else
|
25
|
+
begin
|
26
|
+
super_method_missing(symbol, *arguments, &block)
|
27
|
+
rescue NoMethodError
|
28
|
+
unexpected_method_called(symbol, *arguments)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def super_method_missing(symbol, *arguments, &block)
|
34
|
+
raise NoMethodError
|
35
|
+
end
|
36
|
+
|
37
|
+
def unexpected_method_called(symbol, *arguments)
|
38
|
+
MissingExpectation.new(symbol, expectations).with(*arguments).verify
|
39
|
+
end
|
40
|
+
|
41
|
+
def matching_expectation(symbol, *arguments)
|
42
|
+
expectations.detect { |expectation| expectation.match?(symbol, *arguments) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def expectations_matching(method_names)
|
46
|
+
expectations.select { |expectation| method_names.include?(expectation.method_name) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def verify(*method_names)
|
50
|
+
for_verification = method_names.empty? ? expectations : expectations_matching(method_names)
|
51
|
+
for_verification.each { |expectation| expectation.verify }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'mocha/inspect'
|
2
|
+
|
3
|
+
module Mocha
|
4
|
+
|
5
|
+
class PrettyParameters
|
6
|
+
|
7
|
+
def initialize(params)
|
8
|
+
@params = params
|
9
|
+
@params_string = params.mocha_inspect
|
10
|
+
end
|
11
|
+
|
12
|
+
def pretty
|
13
|
+
remove_outer_array_braces!
|
14
|
+
remove_outer_hash_braces!
|
15
|
+
@params_string
|
16
|
+
end
|
17
|
+
|
18
|
+
def remove_outer_array_braces!
|
19
|
+
@params_string = @params_string.gsub(/^\[|\]$/, '')
|
20
|
+
end
|
21
|
+
|
22
|
+
def remove_outer_hash_braces!
|
23
|
+
@params_string = @params_string.gsub(/^\{|\}$/, '') if @params.size == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/stubba.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'stubba/class_method'
|
2
|
+
|
3
|
+
module Stubba
|
4
|
+
|
5
|
+
class AnyInstanceMethod < ClassMethod
|
6
|
+
|
7
|
+
def unstub
|
8
|
+
remove_new_method
|
9
|
+
restore_original_method
|
10
|
+
object.any_instance.reset_mocha
|
11
|
+
end
|
12
|
+
|
13
|
+
def hide_original_method
|
14
|
+
object.class_eval "alias_method :#{hidden_method}, :#{method}" if object.method_defined?(method)
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_new_method
|
18
|
+
object.class_eval "def #{method}(*args, &block); self.class.any_instance.mocha.method_missing(:#{method}, *args, &block); end"
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove_new_method
|
22
|
+
object.class_eval "remove_method :#{method}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def restore_original_method
|
26
|
+
object.class_eval "alias_method :#{method}, :#{hidden_method}; remove_method :#{hidden_method}" if object.method_defined?(hidden_method)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'mocha/metaclass'
|
2
|
+
|
3
|
+
module Stubba
|
4
|
+
|
5
|
+
class ClassMethod
|
6
|
+
|
7
|
+
attr_reader :object, :method
|
8
|
+
|
9
|
+
def initialize(object, method)
|
10
|
+
@object, @method = object, method
|
11
|
+
end
|
12
|
+
|
13
|
+
def stub
|
14
|
+
hide_original_method
|
15
|
+
define_new_method
|
16
|
+
end
|
17
|
+
|
18
|
+
def unstub
|
19
|
+
remove_new_method
|
20
|
+
restore_original_method
|
21
|
+
object.reset_mocha
|
22
|
+
end
|
23
|
+
|
24
|
+
def hide_original_method
|
25
|
+
object.metaclass.class_eval "alias_method :#{hidden_method}, :#{method}" if object.metaclass.method_defined?(method)
|
26
|
+
end
|
27
|
+
|
28
|
+
def define_new_method
|
29
|
+
object.metaclass.class_eval "def #{method}(*args, &block); mocha.method_missing(:#{method}, *args, &block); end"
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_new_method
|
33
|
+
object.metaclass.class_eval "remove_method :#{method}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def restore_original_method
|
37
|
+
object.metaclass.class_eval "alias_method :#{method}, :#{hidden_method}; remove_method :#{hidden_method}" if object.metaclass.method_defined?(hidden_method)
|
38
|
+
end
|
39
|
+
|
40
|
+
def hidden_method
|
41
|
+
"__stubba__#{method.to_s.sub('!', '_exclamation_mark').sub('?', '_question_mark')}__stubba__"
|
42
|
+
end
|
43
|
+
|
44
|
+
def cannot_replace_method_error
|
45
|
+
Test::Unit::AssertionFailedError.new("Cannot replace #{method} because it is not defined in #{object}.")
|
46
|
+
end
|
47
|
+
|
48
|
+
def eql?(other)
|
49
|
+
return false unless (other.class == self.class)
|
50
|
+
(object == other.object) and (method == other.method)
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_method :==, :eql?
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
"#{object}.#{method}"
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'stubba/class_method'
|
2
|
+
|
3
|
+
module Stubba
|
4
|
+
|
5
|
+
class InstanceMethod < ClassMethod
|
6
|
+
|
7
|
+
def stub
|
8
|
+
raise cannot_replace_method_error unless exists?
|
9
|
+
define_new_method
|
10
|
+
end
|
11
|
+
|
12
|
+
def unstub
|
13
|
+
# intentionally empty
|
14
|
+
end
|
15
|
+
|
16
|
+
def exists?
|
17
|
+
object.respond_to?(method)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'mocha/mock'
|
2
|
+
require 'stubba/instance_method'
|
3
|
+
require 'stubba/class_method'
|
4
|
+
require 'stubba/any_instance_method'
|
5
|
+
|
6
|
+
class Object
|
7
|
+
|
8
|
+
def mocha
|
9
|
+
@mocha ||= Mocha::Mock.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def reset_mocha
|
13
|
+
@mocha = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def stubba_method
|
17
|
+
Stubba::InstanceMethod
|
18
|
+
end
|
19
|
+
|
20
|
+
def stubba_object
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def expects(symbol)
|
25
|
+
method = stubba_method.new(stubba_object, symbol)
|
26
|
+
$stubba.stub(method)
|
27
|
+
mocha.expects(symbol)
|
28
|
+
end
|
29
|
+
|
30
|
+
def stubs(symbol)
|
31
|
+
method = stubba_method.new(stubba_object, symbol)
|
32
|
+
$stubba.stub(method)
|
33
|
+
mocha.stubs(symbol)
|
34
|
+
end
|
35
|
+
|
36
|
+
def verify(*method_names)
|
37
|
+
mocha.verify(*method_names)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
class Module
|
43
|
+
|
44
|
+
def stubba_method
|
45
|
+
Stubba::ClassMethod
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
class Class
|
51
|
+
|
52
|
+
def stubba_method
|
53
|
+
Stubba::ClassMethod
|
54
|
+
end
|
55
|
+
|
56
|
+
class AnyInstance
|
57
|
+
|
58
|
+
def initialize(klass)
|
59
|
+
@stubba_object = klass
|
60
|
+
end
|
61
|
+
|
62
|
+
def stubba_method
|
63
|
+
Stubba::AnyInstanceMethod
|
64
|
+
end
|
65
|
+
|
66
|
+
def stubba_object
|
67
|
+
@stubba_object
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
def any_instance
|
73
|
+
@any_instance ||= AnyInstance.new(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Stubba
|
2
|
+
|
3
|
+
class Stubba
|
4
|
+
|
5
|
+
attr_accessor :stubba_methods
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
self.stubba_methods = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def stub(method)
|
12
|
+
unless stubba_methods.include?(method)
|
13
|
+
method.stub
|
14
|
+
stubba_methods.push method
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def unstub_all
|
19
|
+
while stubba_methods.size > 0
|
20
|
+
method = stubba_methods.pop
|
21
|
+
method.unstub
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'stubba/stubba'
|
2
|
+
|
3
|
+
class Test::Unit::TestCase
|
4
|
+
|
5
|
+
def self.method_added(method)
|
6
|
+
# disable until we finish messing about
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup_with_stubba
|
10
|
+
$stubba = Stubba::Stubba.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown_with_stubba
|
14
|
+
$stubba.unstub_all
|
15
|
+
$stubba = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
if method_defined?(:setup) then
|
19
|
+
alias_method :setup_pre_stubba, :setup
|
20
|
+
define_method(:setup_post_stubba) do
|
21
|
+
setup_pre_stubba
|
22
|
+
setup_with_stubba
|
23
|
+
end
|
24
|
+
else
|
25
|
+
define_method(:setup_post_stubba) do
|
26
|
+
setup_with_stubba
|
27
|
+
end
|
28
|
+
end
|
29
|
+
alias_method :setup, :setup_post_stubba
|
30
|
+
|
31
|
+
if method_defined?(:teardown) then
|
32
|
+
alias_method :teardown_pre_stubba, :teardown
|
33
|
+
define_method(:teardown_post_stubba) do
|
34
|
+
teardown_with_stubba
|
35
|
+
teardown_pre_stubba
|
36
|
+
end
|
37
|
+
else
|
38
|
+
define_method(:teardown_post_stubba) do
|
39
|
+
teardown_with_stubba
|
40
|
+
end
|
41
|
+
end
|
42
|
+
alias_method :teardown, :teardown_post_stubba
|
43
|
+
|
44
|
+
def self.method_added(method)
|
45
|
+
case method
|
46
|
+
when :setup
|
47
|
+
unless method_defined?(:setup_without_stubba)
|
48
|
+
alias_method :setup_without_stubba, :setup
|
49
|
+
define_method(:setup) do
|
50
|
+
setup_post_stubba
|
51
|
+
setup_without_stubba
|
52
|
+
end
|
53
|
+
end
|
54
|
+
when :teardown
|
55
|
+
unless method_defined?(:teardown_without_stubba)
|
56
|
+
alias_method :teardown_without_stubba, :teardown
|
57
|
+
define_method(:teardown) do
|
58
|
+
teardown_without_stubba
|
59
|
+
teardown_post_stubba
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/test/all_tests.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'stubba/test_case' # only works if loaded before any derived test cases
|
3
|
+
|
4
|
+
require 'test/unit/ui/console/testrunner'
|
5
|
+
|
6
|
+
require 'mocha/inspect_test'
|
7
|
+
require 'mocha/pretty_parameters_test'
|
8
|
+
require 'mocha/expectation_test'
|
9
|
+
require 'mocha/infinite_range_test'
|
10
|
+
require 'mocha/mock_methods_test'
|
11
|
+
require 'mocha/mock_test'
|
12
|
+
|
13
|
+
class MochaUnitTests
|
14
|
+
|
15
|
+
def self.suite
|
16
|
+
suite = Test::Unit::TestSuite.new('MochaUnitTests')
|
17
|
+
suite << InspectTest.suite
|
18
|
+
suite << PrettyParametersTest.suite
|
19
|
+
suite << ExpectationTest.suite
|
20
|
+
suite << InfiniteRangeTest.suite
|
21
|
+
suite << MockMethodsTest.suite
|
22
|
+
suite << MockTest.suite
|
23
|
+
suite
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
Test::Unit::UI::Console::TestRunner.run(MochaUnitTests)
|
29
|
+
|
30
|
+
require 'auto_mocha/mock_class_test'
|
31
|
+
require 'auto_mocha/auto_mock_test'
|
32
|
+
|
33
|
+
class AutoMochaUnitTests
|
34
|
+
|
35
|
+
def self.suite
|
36
|
+
suite = Test::Unit::TestSuite.new('AutoMochaUnitTests')
|
37
|
+
suite << AutoMockTest.suite
|
38
|
+
suite << MockClassTest.suite
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
Test::Unit::UI::Console::TestRunner.run(AutoMochaUnitTests)
|
44
|
+
|
45
|
+
require 'stubba/stubba_test'
|
46
|
+
require 'stubba/class_method_test'
|
47
|
+
require 'stubba/instance_method_test'
|
48
|
+
require 'stubba/any_instance_method_test'
|
49
|
+
require 'stubba/test_case_test'
|
50
|
+
|
51
|
+
class StubbaUnitTests
|
52
|
+
|
53
|
+
def self.suite
|
54
|
+
suite = Test::Unit::TestSuite.new('StubbaUnitTests')
|
55
|
+
suite << StubbaTest.suite
|
56
|
+
suite << ClassMethodTest.suite
|
57
|
+
suite << InstanceMethodTest.suite
|
58
|
+
suite << AnyInstanceMethodTest.suite
|
59
|
+
suite << TestCaseTest.suite
|
60
|
+
suite
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
Test::Unit::UI::Console::TestRunner.run(StubbaUnitTests)
|
66
|
+
|
67
|
+
require 'stubba/object_test'
|
68
|
+
|
69
|
+
class IsolatedStubbaUnitTests # avoid loading stubba_object until now which breaks other stubba unit tests
|
70
|
+
|
71
|
+
def self.suite
|
72
|
+
suite = Test::Unit::TestSuite.new('IsolatedStubbaUnitTests')
|
73
|
+
suite << ObjectTest.suite
|
74
|
+
suite
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
Test::Unit::UI::Console::TestRunner.run(IsolatedStubbaUnitTests)
|
80
|
+
|
81
|
+
require 'stubba_integration_test'
|
82
|
+
Test::Unit::UI::Console::TestRunner.run(StubbaIntegrationTest)
|
83
|
+
|
84
|
+
require 'mocha_acceptance_test'
|
85
|
+
require 'stubba_acceptance_test'
|
86
|
+
require 'auto_mock_acceptance_test'
|
87
|
+
|
88
|
+
class AcceptanceTests
|
89
|
+
|
90
|
+
def self.suite
|
91
|
+
suite = Test::Unit::TestSuite.new('AcceptanceTests')
|
92
|
+
suite << MochaAcceptanceTest.suite
|
93
|
+
suite << StubbaAcceptanceTest.suite
|
94
|
+
suite << AutoMockAcceptanceTest.suite
|
95
|
+
suite
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
Test::Unit::UI::Console::TestRunner.run(AcceptanceTests)
|