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.
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