mocha 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/Rakefile +3 -1
  2. data/examples/misc.rb +44 -36
  3. data/examples/stubba.rb +1 -1
  4. data/lib/mocha/auto_verify.rb +38 -31
  5. data/lib/mocha/central.rb +1 -1
  6. data/lib/mocha/class_method.rb +5 -1
  7. data/lib/mocha/expectation.rb +63 -61
  8. data/lib/mocha/expectation_error.rb +9 -0
  9. data/lib/mocha/expectation_list.rb +11 -10
  10. data/lib/mocha/method_matcher.rb +21 -0
  11. data/lib/mocha/missing_expectation.rb +5 -15
  12. data/lib/mocha/mock.rb +28 -26
  13. data/lib/mocha/parameter_matchers.rb +17 -1
  14. data/lib/mocha/parameter_matchers/all_of.rb +6 -3
  15. data/lib/mocha/parameter_matchers/any_of.rb +6 -3
  16. data/lib/mocha/parameter_matchers/any_parameters.rb +40 -0
  17. data/lib/mocha/parameter_matchers/anything.rb +5 -2
  18. data/lib/mocha/parameter_matchers/base.rb +15 -0
  19. data/lib/mocha/parameter_matchers/equals.rb +42 -0
  20. data/lib/mocha/parameter_matchers/has_entries.rb +42 -0
  21. data/lib/mocha/parameter_matchers/has_entry.rb +20 -4
  22. data/lib/mocha/parameter_matchers/has_key.rb +5 -2
  23. data/lib/mocha/parameter_matchers/has_value.rb +5 -2
  24. data/lib/mocha/parameter_matchers/includes.rb +5 -2
  25. data/lib/mocha/parameter_matchers/instance_of.rb +5 -2
  26. data/lib/mocha/parameter_matchers/is_a.rb +42 -0
  27. data/lib/mocha/parameter_matchers/kind_of.rb +5 -2
  28. data/lib/mocha/parameter_matchers/not.rb +42 -0
  29. data/lib/mocha/parameter_matchers/object.rb +9 -0
  30. data/lib/mocha/parameter_matchers/optionally.rb +33 -0
  31. data/lib/mocha/parameter_matchers/regexp_matches.rb +5 -2
  32. data/lib/mocha/parameters_matcher.rb +37 -0
  33. data/lib/mocha/pretty_parameters.rb +1 -1
  34. data/lib/mocha/return_values.rb +7 -4
  35. data/lib/mocha/sequence.rb +42 -0
  36. data/lib/mocha/yield_parameters.rb +3 -3
  37. data/test/acceptance/expected_invocation_count_acceptance_test.rb +8 -8
  38. data/test/acceptance/mock_with_initializer_block_acceptance_test.rb +44 -0
  39. data/test/acceptance/optional_parameters_acceptance_test.rb +63 -0
  40. data/test/acceptance/parameter_matcher_acceptance_test.rb +38 -2
  41. data/test/acceptance/partial_mocks_acceptance_test.rb +40 -0
  42. data/test/acceptance/sequence_acceptance_test.rb +179 -0
  43. data/test/integration/mocha_test_result_integration_test.rb +3 -3
  44. data/test/integration/stubba_integration_test.rb +2 -2
  45. data/test/integration/stubba_test_result_integration_test.rb +2 -2
  46. data/test/test_runner.rb +2 -2
  47. data/test/unit/any_instance_method_test.rb +2 -0
  48. data/test/unit/auto_verify_test.rb +10 -3
  49. data/test/unit/central_test.rb +1 -1
  50. data/test/unit/class_method_test.rb +4 -0
  51. data/test/unit/expectation_error_test.rb +24 -0
  52. data/test/unit/expectation_list_test.rb +6 -0
  53. data/test/unit/expectation_test.rb +111 -27
  54. data/test/unit/method_matcher_test.rb +23 -0
  55. data/test/unit/missing_expectation_test.rb +24 -27
  56. data/test/unit/mock_test.rb +29 -22
  57. data/test/unit/object_inspect_test.rb +4 -2
  58. data/test/unit/parameter_matchers/all_of_test.rb +2 -2
  59. data/test/unit/parameter_matchers/any_of_test.rb +2 -2
  60. data/test/unit/parameter_matchers/anything_test.rb +2 -2
  61. data/test/unit/parameter_matchers/has_entries_test.rb +30 -0
  62. data/test/unit/parameter_matchers/has_entry_test.rb +20 -5
  63. data/test/unit/parameter_matchers/has_key_test.rb +2 -2
  64. data/test/unit/parameter_matchers/has_value_test.rb +2 -2
  65. data/test/unit/parameter_matchers/includes_test.rb +2 -2
  66. data/test/unit/parameter_matchers/instance_of_test.rb +2 -2
  67. data/test/unit/parameter_matchers/is_a_test.rb +25 -0
  68. data/test/unit/parameter_matchers/kind_of_test.rb +3 -3
  69. data/test/unit/parameter_matchers/not_test.rb +26 -0
  70. data/test/unit/parameter_matchers/regexp_matches_test.rb +2 -2
  71. data/test/unit/parameter_matchers/stub_matcher.rb +2 -1
  72. data/test/unit/parameters_matcher_test.rb +121 -0
  73. data/test/unit/sequence_test.rb +104 -0
  74. metadata +35 -6
  75. 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 respond_to?(method_name)
14
- @expectations.any? { |expectation| expectation.method_name == method_name }
14
+ def matches_method?(method_name)
15
+ @expectations.any? { |expectation| expectation.matches_method?(method_name) }
15
16
  end
16
17
 
17
- def detect(method_name, *arguments)
18
- expectations = @expectations.reverse.select { |expectation| expectation.match?(method_name, *arguments) }
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 similar(method_name)
24
- @expectations.select { |expectation| expectation.method_name == method_name }
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 size
40
- @expectations.size
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
- msg = error_message(0, 1)
14
- similar_expectations_list = @mock.similar_expectations(@method_name).collect { |expectation| expectation.method_signature }.join("\n")
15
- msg << "\nSimilar expectations:\n#{similar_expectations_list}" unless similar_expectations_list.empty?
16
- error = ExpectationError.new(msg)
17
- error.set_backtrace(filtered_backtrace)
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
@@ -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
- add_expectation(Expectation.new(self, method_name, backtrace).returns(return_value))
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
- add_expectation(Expectation.new(self, method_name_or_hash, backtrace))
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
- add_expectation(Stub.new(self, method_name, backtrace).returns(return_value))
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
- add_expectation(Stub.new(self, method_name_or_hash, backtrace))
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 stub_everything then
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.respond_to?(symbol)
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 similar_expectations(method_name)
193
- @expectations.similar(method_name)
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
- Dir[File.expand_path(File.join(File.dirname(__FILE__), 'parameter_matchers', "*.rb"))].each { |lib| require lib }
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 ==(parameter)
28
- @matchers.all? { |matcher| matcher == parameter }
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 ==(parameter)
33
- @matchers.any? { |matcher| matcher == parameter }
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 ==(parameter)
20
+ def matches?(available_parameters)
21
+ available_parameters.shift
19
22
  return true
20
23
  end
21
24
 
@@ -0,0 +1,15 @@
1
+ module Mocha
2
+
3
+ module ParameterMatchers
4
+
5
+ class Base # :nodoc:
6
+
7
+ def to_matcher
8
+ self
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -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