mocha 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -1
- data/examples/misc.rb +44 -36
- data/examples/stubba.rb +1 -1
- data/lib/mocha/auto_verify.rb +38 -31
- data/lib/mocha/central.rb +1 -1
- data/lib/mocha/class_method.rb +5 -1
- data/lib/mocha/expectation.rb +63 -61
- data/lib/mocha/expectation_error.rb +9 -0
- data/lib/mocha/expectation_list.rb +11 -10
- data/lib/mocha/method_matcher.rb +21 -0
- data/lib/mocha/missing_expectation.rb +5 -15
- data/lib/mocha/mock.rb +28 -26
- data/lib/mocha/parameter_matchers.rb +17 -1
- data/lib/mocha/parameter_matchers/all_of.rb +6 -3
- data/lib/mocha/parameter_matchers/any_of.rb +6 -3
- data/lib/mocha/parameter_matchers/any_parameters.rb +40 -0
- data/lib/mocha/parameter_matchers/anything.rb +5 -2
- 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 +42 -0
- data/lib/mocha/parameter_matchers/has_entry.rb +20 -4
- data/lib/mocha/parameter_matchers/has_key.rb +5 -2
- data/lib/mocha/parameter_matchers/has_value.rb +5 -2
- data/lib/mocha/parameter_matchers/includes.rb +5 -2
- data/lib/mocha/parameter_matchers/instance_of.rb +5 -2
- data/lib/mocha/parameter_matchers/is_a.rb +42 -0
- data/lib/mocha/parameter_matchers/kind_of.rb +5 -2
- data/lib/mocha/parameter_matchers/not.rb +42 -0
- data/lib/mocha/parameter_matchers/object.rb +9 -0
- data/lib/mocha/parameter_matchers/optionally.rb +33 -0
- data/lib/mocha/parameter_matchers/regexp_matches.rb +5 -2
- data/lib/mocha/parameters_matcher.rb +37 -0
- data/lib/mocha/pretty_parameters.rb +1 -1
- data/lib/mocha/return_values.rb +7 -4
- data/lib/mocha/sequence.rb +42 -0
- data/lib/mocha/yield_parameters.rb +3 -3
- data/test/acceptance/expected_invocation_count_acceptance_test.rb +8 -8
- data/test/acceptance/mock_with_initializer_block_acceptance_test.rb +44 -0
- data/test/acceptance/optional_parameters_acceptance_test.rb +63 -0
- data/test/acceptance/parameter_matcher_acceptance_test.rb +38 -2
- data/test/acceptance/partial_mocks_acceptance_test.rb +40 -0
- data/test/acceptance/sequence_acceptance_test.rb +179 -0
- data/test/integration/mocha_test_result_integration_test.rb +3 -3
- data/test/integration/stubba_integration_test.rb +2 -2
- data/test/integration/stubba_test_result_integration_test.rb +2 -2
- data/test/test_runner.rb +2 -2
- data/test/unit/any_instance_method_test.rb +2 -0
- data/test/unit/auto_verify_test.rb +10 -3
- data/test/unit/central_test.rb +1 -1
- data/test/unit/class_method_test.rb +4 -0
- data/test/unit/expectation_error_test.rb +24 -0
- data/test/unit/expectation_list_test.rb +6 -0
- data/test/unit/expectation_test.rb +111 -27
- data/test/unit/method_matcher_test.rb +23 -0
- data/test/unit/missing_expectation_test.rb +24 -27
- data/test/unit/mock_test.rb +29 -22
- data/test/unit/object_inspect_test.rb +4 -2
- data/test/unit/parameter_matchers/all_of_test.rb +2 -2
- data/test/unit/parameter_matchers/any_of_test.rb +2 -2
- data/test/unit/parameter_matchers/anything_test.rb +2 -2
- data/test/unit/parameter_matchers/has_entries_test.rb +30 -0
- data/test/unit/parameter_matchers/has_entry_test.rb +20 -5
- data/test/unit/parameter_matchers/has_key_test.rb +2 -2
- data/test/unit/parameter_matchers/has_value_test.rb +2 -2
- data/test/unit/parameter_matchers/includes_test.rb +2 -2
- data/test/unit/parameter_matchers/instance_of_test.rb +2 -2
- data/test/unit/parameter_matchers/is_a_test.rb +25 -0
- data/test/unit/parameter_matchers/kind_of_test.rb +3 -3
- data/test/unit/parameter_matchers/not_test.rb +26 -0
- data/test/unit/parameter_matchers/regexp_matches_test.rb +2 -2
- data/test/unit/parameter_matchers/stub_matcher.rb +2 -1
- data/test/unit/parameters_matcher_test.rb +121 -0
- data/test/unit/sequence_test.rb +104 -0
- metadata +35 -6
- data/test/unit/pretty_parameters_test.rb +0 -32
@@ -1,6 +1,15 @@
|
|
1
1
|
module Mocha
|
2
2
|
|
3
3
|
class ExpectationError < StandardError
|
4
|
+
|
5
|
+
LIB_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), "..")) + File::SEPARATOR
|
6
|
+
|
7
|
+
def initialize(message = nil, backtrace = [], lib_directory = LIB_DIRECTORY)
|
8
|
+
super(message)
|
9
|
+
filtered_backtrace = backtrace.reject { |location| Regexp.new(lib_directory).match(File.expand_path(location)) }
|
10
|
+
set_backtrace(filtered_backtrace)
|
11
|
+
end
|
12
|
+
|
4
13
|
end
|
5
14
|
|
6
15
|
end
|
@@ -8,20 +8,21 @@ module Mocha # :nodoc:
|
|
8
8
|
|
9
9
|
def add(expectation)
|
10
10
|
@expectations << expectation
|
11
|
+
expectation
|
11
12
|
end
|
12
13
|
|
13
|
-
def
|
14
|
-
@expectations.any? { |expectation| expectation.method_name
|
14
|
+
def matches_method?(method_name)
|
15
|
+
@expectations.any? { |expectation| expectation.matches_method?(method_name) }
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
-
|
19
|
-
expectation = expectations.detect { |expectation| expectation.invocations_allowed? }
|
20
|
-
expectation || expectations.first
|
18
|
+
def similar(method_name)
|
19
|
+
@expectations.select { |expectation| expectation.matches_method?(method_name) }
|
21
20
|
end
|
22
21
|
|
23
|
-
def
|
24
|
-
@expectations.select { |
|
22
|
+
def detect(method_name, *arguments)
|
23
|
+
expectations = @expectations.reverse.select { |e| e.match?(method_name, *arguments) }
|
24
|
+
expectation = expectations.detect { |e| e.invocations_allowed? }
|
25
|
+
expectation || expectations.first
|
25
26
|
end
|
26
27
|
|
27
28
|
def verify(&block)
|
@@ -36,8 +37,8 @@ module Mocha # :nodoc:
|
|
36
37
|
@expectations.to_set
|
37
38
|
end
|
38
39
|
|
39
|
-
def
|
40
|
-
@expectations.
|
40
|
+
def length
|
41
|
+
@expectations.length
|
41
42
|
end
|
42
43
|
|
43
44
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Mocha
|
2
|
+
|
3
|
+
class MethodMatcher
|
4
|
+
|
5
|
+
attr_reader :expected_method_name
|
6
|
+
|
7
|
+
def initialize(expected_method_name)
|
8
|
+
@expected_method_name = expected_method_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def match?(actual_method_name)
|
12
|
+
@expected_method_name == actual_method_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def mocha_inspect
|
16
|
+
"#{@expected_method_name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -4,22 +4,12 @@ module Mocha # :nodoc:
|
|
4
4
|
|
5
5
|
class MissingExpectation < Expectation # :nodoc:
|
6
6
|
|
7
|
-
def initialize(mock, method_name)
|
8
|
-
super
|
9
|
-
@invoked_count = true
|
10
|
-
end
|
11
|
-
|
12
7
|
def verify
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
raise error if @invoked_count
|
19
|
-
end
|
20
|
-
|
21
|
-
def similar_expectations
|
22
|
-
@mock.similar_expectations(method_name)
|
8
|
+
message = error_message(0, 1)
|
9
|
+
similar_expectations = @mock.expectations.similar(@method_matcher.expected_method_name)
|
10
|
+
method_signatures = similar_expectations.map { |expectation| expectation.method_signature }
|
11
|
+
message << "\nSimilar expectations:\n#{method_signatures.join("\n")}" unless method_signatures.empty?
|
12
|
+
raise ExpectationError.new(message, backtrace)
|
23
13
|
end
|
24
14
|
|
25
15
|
end
|
data/lib/mocha/mock.rb
CHANGED
@@ -11,19 +11,6 @@ module Mocha # :nodoc:
|
|
11
11
|
# Methods return an Expectation which can be further modified by methods on Expectation.
|
12
12
|
class Mock
|
13
13
|
|
14
|
-
# :stopdoc:
|
15
|
-
|
16
|
-
def initialize(stub_everything = false, name = nil)
|
17
|
-
@stub_everything = stub_everything
|
18
|
-
@mock_name = name
|
19
|
-
@expectations = ExpectationList.new
|
20
|
-
@responder = nil
|
21
|
-
end
|
22
|
-
|
23
|
-
attr_reader :stub_everything, :expectations
|
24
|
-
|
25
|
-
# :startdoc:
|
26
|
-
|
27
14
|
# :call-seq: expects(method_name) -> expectation
|
28
15
|
# expects(method_names) -> last expectation
|
29
16
|
#
|
@@ -51,10 +38,12 @@ module Mocha # :nodoc:
|
|
51
38
|
def expects(method_name_or_hash, backtrace = nil)
|
52
39
|
if method_name_or_hash.is_a?(Hash) then
|
53
40
|
method_name_or_hash.each do |method_name, return_value|
|
54
|
-
|
41
|
+
ensure_method_not_already_defined(method_name)
|
42
|
+
@expectations.add(Expectation.new(self, method_name, backtrace).returns(return_value))
|
55
43
|
end
|
56
44
|
else
|
57
|
-
|
45
|
+
ensure_method_not_already_defined(method_name_or_hash)
|
46
|
+
@expectations.add(Expectation.new(self, method_name_or_hash, backtrace))
|
58
47
|
end
|
59
48
|
end
|
60
49
|
|
@@ -82,10 +71,12 @@ module Mocha # :nodoc:
|
|
82
71
|
def stubs(method_name_or_hash, backtrace = nil)
|
83
72
|
if method_name_or_hash.is_a?(Hash) then
|
84
73
|
method_name_or_hash.each do |method_name, return_value|
|
85
|
-
|
74
|
+
ensure_method_not_already_defined(method_name)
|
75
|
+
@expectations.add(Stub.new(self, method_name, backtrace).returns(return_value))
|
86
76
|
end
|
87
77
|
else
|
88
|
-
|
78
|
+
ensure_method_not_already_defined(method_name_or_hash)
|
79
|
+
@expectations.add(Stub.new(self, method_name_or_hash, backtrace))
|
89
80
|
end
|
90
81
|
end
|
91
82
|
|
@@ -135,6 +126,16 @@ module Mocha # :nodoc:
|
|
135
126
|
end
|
136
127
|
|
137
128
|
# :stopdoc:
|
129
|
+
|
130
|
+
def initialize(name = nil, &block)
|
131
|
+
@mock_name = name
|
132
|
+
@expectations = ExpectationList.new
|
133
|
+
@everything_stubbed = false
|
134
|
+
@responder = nil
|
135
|
+
instance_eval(&block) if block
|
136
|
+
end
|
137
|
+
|
138
|
+
attr_reader :everything_stubbed, :expectations
|
138
139
|
|
139
140
|
alias_method :__expects__, :expects
|
140
141
|
|
@@ -144,11 +145,12 @@ module Mocha # :nodoc:
|
|
144
145
|
|
145
146
|
def add_expectation(expectation)
|
146
147
|
@expectations.add(expectation)
|
147
|
-
method_name = expectation.method_name
|
148
|
-
self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name)
|
149
|
-
expectation
|
150
148
|
end
|
151
|
-
|
149
|
+
|
150
|
+
def stub_everything
|
151
|
+
@everything_stubbed = true
|
152
|
+
end
|
153
|
+
|
152
154
|
def method_missing(symbol, *arguments, &block)
|
153
155
|
if @responder and not @responder.respond_to?(symbol)
|
154
156
|
raise NoMethodError, "undefined method `#{symbol}' for #{self.mocha_inspect} which responds like #{@responder.mocha_inspect}"
|
@@ -156,7 +158,7 @@ module Mocha # :nodoc:
|
|
156
158
|
matching_expectation = @expectations.detect(symbol, *arguments)
|
157
159
|
if matching_expectation then
|
158
160
|
matching_expectation.invoke(&block)
|
159
|
-
elsif
|
161
|
+
elsif @everything_stubbed then
|
160
162
|
return
|
161
163
|
else
|
162
164
|
unexpected_method_called(symbol, *arguments)
|
@@ -167,7 +169,7 @@ module Mocha # :nodoc:
|
|
167
169
|
if @responder then
|
168
170
|
@responder.respond_to?(symbol)
|
169
171
|
else
|
170
|
-
@expectations.
|
172
|
+
@expectations.matches_method?(symbol)
|
171
173
|
end
|
172
174
|
end
|
173
175
|
|
@@ -188,9 +190,9 @@ module Mocha # :nodoc:
|
|
188
190
|
def inspect
|
189
191
|
mocha_inspect
|
190
192
|
end
|
191
|
-
|
192
|
-
def
|
193
|
-
|
193
|
+
|
194
|
+
def ensure_method_not_already_defined(method_name)
|
195
|
+
self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name)
|
194
196
|
end
|
195
197
|
|
196
198
|
# :startdoc:
|
@@ -5,5 +5,21 @@ module Mocha
|
|
5
5
|
|
6
6
|
end
|
7
7
|
|
8
|
+
require 'mocha/parameter_matchers/object'
|
8
9
|
|
9
|
-
|
10
|
+
require 'mocha/parameter_matchers/all_of'
|
11
|
+
require 'mocha/parameter_matchers/any_of'
|
12
|
+
require 'mocha/parameter_matchers/any_parameters'
|
13
|
+
require 'mocha/parameter_matchers/anything'
|
14
|
+
require 'mocha/parameter_matchers/equals'
|
15
|
+
require 'mocha/parameter_matchers/has_entry'
|
16
|
+
require 'mocha/parameter_matchers/has_entries'
|
17
|
+
require 'mocha/parameter_matchers/has_key'
|
18
|
+
require 'mocha/parameter_matchers/has_value'
|
19
|
+
require 'mocha/parameter_matchers/includes'
|
20
|
+
require 'mocha/parameter_matchers/instance_of'
|
21
|
+
require 'mocha/parameter_matchers/is_a'
|
22
|
+
require 'mocha/parameter_matchers/kind_of'
|
23
|
+
require 'mocha/parameter_matchers/not'
|
24
|
+
require 'mocha/parameter_matchers/optionally'
|
25
|
+
require 'mocha/parameter_matchers/regexp_matches'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mocha/parameter_matchers/base'
|
2
|
+
|
1
3
|
module Mocha
|
2
4
|
|
3
5
|
module ParameterMatchers
|
@@ -18,14 +20,15 @@ module Mocha
|
|
18
20
|
AllOf.new(*matchers)
|
19
21
|
end
|
20
22
|
|
21
|
-
class AllOf # :nodoc:
|
23
|
+
class AllOf < Base # :nodoc:
|
22
24
|
|
23
25
|
def initialize(*matchers)
|
24
26
|
@matchers = matchers
|
25
27
|
end
|
26
28
|
|
27
|
-
def
|
28
|
-
|
29
|
+
def matches?(available_parameters)
|
30
|
+
parameter = available_parameters.shift
|
31
|
+
@matchers.all? { |matcher| matcher.matches?([parameter]) }
|
29
32
|
end
|
30
33
|
|
31
34
|
def mocha_inspect
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mocha/parameter_matchers/base'
|
2
|
+
|
1
3
|
module Mocha
|
2
4
|
|
3
5
|
module ParameterMatchers
|
@@ -23,14 +25,15 @@ module Mocha
|
|
23
25
|
AnyOf.new(*matchers)
|
24
26
|
end
|
25
27
|
|
26
|
-
class AnyOf # :nodoc:
|
28
|
+
class AnyOf < Base # :nodoc:
|
27
29
|
|
28
30
|
def initialize(*matchers)
|
29
31
|
@matchers = matchers
|
30
32
|
end
|
31
33
|
|
32
|
-
def
|
33
|
-
|
34
|
+
def matches?(available_parameters)
|
35
|
+
parameter = available_parameters.shift
|
36
|
+
@matchers.any? { |matcher| matcher.matches?([parameter]) }
|
34
37
|
end
|
35
38
|
|
36
39
|
def mocha_inspect
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'mocha/parameter_matchers/base'
|
2
|
+
|
3
|
+
module Mocha
|
4
|
+
|
5
|
+
module ParameterMatchers
|
6
|
+
|
7
|
+
# :call-seq: any_parameters() -> parameter_matcher
|
8
|
+
#
|
9
|
+
# Matches any parameters.
|
10
|
+
# object = mock()
|
11
|
+
# object.expects(:method_1).with(any_parameters)
|
12
|
+
# object.method_1(1, 2, 3, 4)
|
13
|
+
# # no error raised
|
14
|
+
#
|
15
|
+
# object = mock()
|
16
|
+
# object.expects(:method_1).with(any_parameters)
|
17
|
+
# object.method_1(5, 6, 7, 8, 9, 0)
|
18
|
+
# # no error raised
|
19
|
+
def any_parameters
|
20
|
+
AnyParameters.new
|
21
|
+
end
|
22
|
+
|
23
|
+
class AnyParameters < Base # :nodoc:
|
24
|
+
|
25
|
+
def matches?(available_parameters)
|
26
|
+
while available_parameters.length > 0 do
|
27
|
+
available_parameters.shift
|
28
|
+
end
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
|
32
|
+
def mocha_inspect
|
33
|
+
"any_parameters"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mocha/parameter_matchers/base'
|
2
|
+
|
1
3
|
module Mocha
|
2
4
|
|
3
5
|
module ParameterMatchers
|
@@ -13,9 +15,10 @@ module Mocha
|
|
13
15
|
Anything.new
|
14
16
|
end
|
15
17
|
|
16
|
-
class Anything # :nodoc:
|
18
|
+
class Anything < Base # :nodoc:
|
17
19
|
|
18
|
-
def
|
20
|
+
def matches?(available_parameters)
|
21
|
+
available_parameters.shift
|
19
22
|
return true
|
20
23
|
end
|
21
24
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'mocha/parameter_matchers/base'
|
2
|
+
|
3
|
+
module Mocha
|
4
|
+
|
5
|
+
module ParameterMatchers
|
6
|
+
|
7
|
+
# :call-seq: equals(value) -> parameter_matcher
|
8
|
+
#
|
9
|
+
# Matches +Object+ equalling +value+.
|
10
|
+
# object = mock()
|
11
|
+
# object.expects(:method_1).with(equals(2))
|
12
|
+
# object.method_1(2)
|
13
|
+
# # no error raised
|
14
|
+
#
|
15
|
+
# object = mock()
|
16
|
+
# object.expects(:method_1).with(equals(2))
|
17
|
+
# object.method_1(3)
|
18
|
+
# # error raised, because method_1 was not called with Object equalling 3
|
19
|
+
def equals(value)
|
20
|
+
Equals.new(value)
|
21
|
+
end
|
22
|
+
|
23
|
+
class Equals < Base # :nodoc:
|
24
|
+
|
25
|
+
def initialize(value)
|
26
|
+
@value = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def matches?(available_parameters)
|
30
|
+
parameter = available_parameters.shift
|
31
|
+
parameter == @value
|
32
|
+
end
|
33
|
+
|
34
|
+
def mocha_inspect
|
35
|
+
@value.mocha_inspect
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'mocha/parameter_matchers/base'
|
2
|
+
|
3
|
+
module Mocha
|
4
|
+
|
5
|
+
module ParameterMatchers
|
6
|
+
|
7
|
+
# :call-seq: has_entries(entries) -> parameter_matcher
|
8
|
+
#
|
9
|
+
# Matches +Hash+ containing all +entries+.
|
10
|
+
# object = mock()
|
11
|
+
# object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
|
12
|
+
# object.method_1('key_1' => 1, 'key_2' => 2, 'key_3' => 3)
|
13
|
+
# # no error raised
|
14
|
+
#
|
15
|
+
# object = mock()
|
16
|
+
# object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
|
17
|
+
# object.method_1('key_1' => 1, 'key_2' => 99)
|
18
|
+
# # error raised, because method_1 was not called with Hash containing entries: 'key_1' => 1, 'key_2' => 2
|
19
|
+
def has_entries(entries)
|
20
|
+
HasEntries.new(entries)
|
21
|
+
end
|
22
|
+
|
23
|
+
class HasEntries < Base # :nodoc:
|
24
|
+
|
25
|
+
def initialize(entries)
|
26
|
+
@entries = entries
|
27
|
+
end
|
28
|
+
|
29
|
+
def matches?(available_parameters)
|
30
|
+
parameter = available_parameters.shift
|
31
|
+
@entries.all? { |key, value| parameter[key] == value }
|
32
|
+
end
|
33
|
+
|
34
|
+
def mocha_inspect
|
35
|
+
"has_entries(#{@entries.mocha_inspect})"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|