mocha 0.5.5 → 0.5.6
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/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
|