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,8 +1,11 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
1
3
  module Mocha
2
4
 
3
5
  module ParameterMatchers
4
6
 
5
7
  # :call-seq: has_entry(key, value) -> parameter_matcher
8
+ # has_entry(key => value) -> parameter_matcher
6
9
  #
7
10
  # Matches +Hash+ containing entry with +key+ and +value+.
8
11
  # object = mock()
@@ -11,20 +14,33 @@ module Mocha
11
14
  # # no error raised
12
15
  #
13
16
  # object = mock()
17
+ # object.expects(:method_1).with(has_entry('key_1' => 1))
18
+ # object.method_1('key_1' => 1, 'key_2' => 2)
19
+ # # no error raised
20
+ #
21
+ # object = mock()
14
22
  # object.expects(:method_1).with(has_entry('key_1', 1))
15
23
  # object.method_1('key_1' => 2, 'key_2' => 1)
16
24
  # # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1
17
- def has_entry(key, value)
25
+ #
26
+ # object = mock()
27
+ # object.expects(:method_1).with(has_entry('key_1' => 1))
28
+ # object.method_1('key_1' => 2, 'key_2' => 1)
29
+ # # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1
30
+ def has_entry(*options)
31
+ key, value = options.shift, options.shift
32
+ key, value = key.to_a[0][0..1] if key.is_a?(Hash)
18
33
  HasEntry.new(key, value)
19
34
  end
20
-
21
- class HasEntry # :nodoc:
35
+
36
+ class HasEntry < Base # :nodoc:
22
37
 
23
38
  def initialize(key, value)
24
39
  @key, @value = key, value
25
40
  end
26
41
 
27
- def ==(parameter)
42
+ def matches?(available_parameters)
43
+ parameter = available_parameters.shift
28
44
  parameter[@key] == @value
29
45
  end
30
46
 
@@ -1,3 +1,5 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
1
3
  module Mocha
2
4
 
3
5
  module ParameterMatchers
@@ -18,13 +20,14 @@ module Mocha
18
20
  HasKey.new(key)
19
21
  end
20
22
 
21
- class HasKey # :nodoc:
23
+ class HasKey < Base # :nodoc:
22
24
 
23
25
  def initialize(key)
24
26
  @key = key
25
27
  end
26
28
 
27
- def ==(parameter)
29
+ def matches?(available_parameters)
30
+ parameter = available_parameters.shift
28
31
  parameter.keys.include?(@key)
29
32
  end
30
33
 
@@ -1,3 +1,5 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
1
3
  module Mocha
2
4
 
3
5
  module ParameterMatchers
@@ -18,13 +20,14 @@ module Mocha
18
20
  HasValue.new(value)
19
21
  end
20
22
 
21
- class HasValue # :nodoc:
23
+ class HasValue < Base # :nodoc:
22
24
 
23
25
  def initialize(value)
24
26
  @value = value
25
27
  end
26
28
 
27
- def ==(parameter)
29
+ def matches?(available_parameters)
30
+ parameter = available_parameters.shift
28
31
  parameter.values.include?(@value)
29
32
  end
30
33
 
@@ -1,3 +1,5 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
1
3
  module Mocha
2
4
 
3
5
  module ParameterMatchers
@@ -16,13 +18,14 @@ module Mocha
16
18
  Includes.new(item)
17
19
  end
18
20
 
19
- class Includes # :nodoc:
21
+ class Includes < Base # :nodoc:
20
22
 
21
23
  def initialize(item)
22
24
  @item = item
23
25
  end
24
26
 
25
- def ==(parameter)
27
+ def matches?(available_parameters)
28
+ parameter = available_parameters.shift
26
29
  return parameter.include?(@item)
27
30
  end
28
31
 
@@ -1,3 +1,5 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
1
3
  module Mocha
2
4
 
3
5
  module ParameterMatchers
@@ -18,13 +20,14 @@ module Mocha
18
20
  InstanceOf.new(klass)
19
21
  end
20
22
 
21
- class InstanceOf # :nodoc:
23
+ class InstanceOf < Base # :nodoc:
22
24
 
23
25
  def initialize(klass)
24
26
  @klass = klass
25
27
  end
26
28
 
27
- def ==(parameter)
29
+ def matches?(available_parameters)
30
+ parameter = available_parameters.shift
28
31
  parameter.instance_of?(@klass)
29
32
  end
30
33
 
@@ -0,0 +1,42 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
3
+ module Mocha
4
+
5
+ module ParameterMatchers
6
+
7
+ # :call-seq: is_a(klass) -> parameter_matcher
8
+ #
9
+ # Matches any object that is a +klass+
10
+ # object = mock()
11
+ # object.expects(:method_1).with(is_a(Integer))
12
+ # object.method_1(99)
13
+ # # no error raised
14
+ #
15
+ # object = mock()
16
+ # object.expects(:method_1).with(is_a(Integer))
17
+ # object.method_1('string')
18
+ # # error raised, because method_1 was not called with an Integer
19
+ def is_a(klass)
20
+ IsA.new(klass)
21
+ end
22
+
23
+ class IsA < Base # :nodoc:
24
+
25
+ def initialize(klass)
26
+ @klass = klass
27
+ end
28
+
29
+ def matches?(available_parameters)
30
+ parameter = available_parameters.shift
31
+ parameter.is_a?(@klass)
32
+ end
33
+
34
+ def mocha_inspect
35
+ "is_a(#{@klass.mocha_inspect})"
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -1,3 +1,5 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
1
3
  module Mocha
2
4
 
3
5
  module ParameterMatchers
@@ -18,13 +20,14 @@ module Mocha
18
20
  KindOf.new(klass)
19
21
  end
20
22
 
21
- class KindOf # :nodoc:
23
+ class KindOf < Base # :nodoc:
22
24
 
23
25
  def initialize(klass)
24
26
  @klass = klass
25
27
  end
26
28
 
27
- def ==(parameter)
29
+ def matches?(available_parameters)
30
+ parameter = available_parameters.shift
28
31
  parameter.kind_of?(@klass)
29
32
  end
30
33
 
@@ -0,0 +1,42 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
3
+ module Mocha
4
+
5
+ module ParameterMatchers
6
+
7
+ # :call-seq: Not(matcher) -> parameter_matcher
8
+ #
9
+ # Matches if +matcher+ does not match.
10
+ # object = mock()
11
+ # object.expects(:method_1).with(Not(includes(1)))
12
+ # object.method_1([0, 2, 3])
13
+ # # no error raised
14
+ #
15
+ # object = mock()
16
+ # object.expects(:method_1).with(Not(includes(1)))
17
+ # object.method_1([0, 1, 2, 3])
18
+ # # error raised, because method_1 was not called with object not including 1
19
+ def Not(matcher)
20
+ Not.new(matcher)
21
+ end
22
+
23
+ class Not < Base # :nodoc:
24
+
25
+ def initialize(matcher)
26
+ @matcher = matcher
27
+ end
28
+
29
+ def matches?(available_parameters)
30
+ parameter = available_parameters.shift
31
+ !@matcher.matches?([parameter])
32
+ end
33
+
34
+ def mocha_inspect
35
+ "Not(#{@matcher.mocha_inspect})"
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,9 @@
1
+ require 'mocha/parameter_matchers/equals'
2
+
3
+ class Object
4
+
5
+ def to_matcher
6
+ Mocha::ParameterMatchers::Equals.new(self)
7
+ end
8
+
9
+ end
@@ -0,0 +1,33 @@
1
+ module Mocha
2
+
3
+ module ParameterMatchers
4
+
5
+ def optionally(*matchers)
6
+ Optionally.new(*matchers)
7
+ end
8
+
9
+ class Optionally < Base # :nodoc:
10
+
11
+ def initialize(*parameters)
12
+ @matchers = parameters.map { |parameter| parameter.to_matcher }
13
+ end
14
+
15
+ def matches?(available_parameters)
16
+ index = 0
17
+ while (available_parameters.length > 0) && (index < @matchers.length) do
18
+ matcher = @matchers[index]
19
+ return false unless matcher.matches?(available_parameters)
20
+ index += 1
21
+ end
22
+ return true
23
+ end
24
+
25
+ def mocha_inspect
26
+ "optionally(#{@matchers.map { |matcher| matcher.mocha_inspect }.join(", ") })"
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -1,3 +1,5 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
1
3
  module Mocha
2
4
 
3
5
  module ParameterMatchers
@@ -19,13 +21,14 @@ module Mocha
19
21
  RegexpMatches.new(regexp)
20
22
  end
21
23
 
22
- class RegexpMatches # :nodoc:
24
+ class RegexpMatches < Base # :nodoc:
23
25
 
24
26
  def initialize(regexp)
25
27
  @regexp = regexp
26
28
  end
27
29
 
28
- def ==(parameter)
30
+ def matches?(available_parameters)
31
+ parameter = available_parameters.shift
29
32
  parameter =~ @regexp
30
33
  end
31
34
 
@@ -0,0 +1,37 @@
1
+ require 'mocha/inspect'
2
+ require 'mocha/parameter_matchers'
3
+
4
+ module Mocha
5
+
6
+ class ParametersMatcher
7
+
8
+ def initialize(expected_parameters = [ParameterMatchers::AnyParameters.new], &matching_block)
9
+ @expected_parameters, @matching_block = expected_parameters, matching_block
10
+ end
11
+
12
+ def match?(actual_parameters = [])
13
+ if @matching_block
14
+ return @matching_block.call(*actual_parameters)
15
+ else
16
+ return parameters_match?(actual_parameters)
17
+ end
18
+ end
19
+
20
+ def parameters_match?(actual_parameters)
21
+ matchers.all? { |matcher| matcher.matches?(actual_parameters) } && (actual_parameters.length == 0)
22
+ end
23
+
24
+ def mocha_inspect
25
+ signature = matchers.mocha_inspect
26
+ signature = signature.gsub(/^\[|\]$/, '')
27
+ signature = signature.gsub(/^\{|\}$/, '') if matchers.length == 1
28
+ "(#{signature})"
29
+ end
30
+
31
+ def matchers
32
+ @expected_parameters.map { |parameter| parameter.to_matcher }
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -20,7 +20,7 @@ module Mocha
20
20
  end
21
21
 
22
22
  def remove_outer_hash_braces!
23
- @params_string = @params_string.gsub(/^\{|\}$/, '') if @params.size == 1
23
+ @params_string = @params_string.gsub(/^\{|\}$/, '') if @params.length == 1
24
24
  end
25
25
 
26
26
  end
@@ -15,10 +15,13 @@ module Mocha # :nodoc:
15
15
  end
16
16
 
17
17
  def next
18
- case @values.size
19
- when 0: nil
20
- when 1: @values.first.evaluate
21
- else @values.shift.evaluate
18
+ case @values.length
19
+ when 0
20
+ nil
21
+ when 1
22
+ @values.first.evaluate
23
+ else
24
+ @values.shift.evaluate
22
25
  end
23
26
  end
24
27
 
@@ -0,0 +1,42 @@
1
+ module Mocha # :nodoc:
2
+
3
+ class Sequence
4
+
5
+ class InSequenceOrderingConstraint
6
+
7
+ def initialize(sequence, index)
8
+ @sequence, @index = sequence, index
9
+ end
10
+
11
+ def allows_invocation_now?
12
+ @sequence.satisfied_to_index?(@index)
13
+ end
14
+
15
+ def mocha_inspect
16
+ "in sequence #{@sequence.mocha_inspect}"
17
+ end
18
+
19
+ end
20
+
21
+ def initialize(name)
22
+ @name = name
23
+ @expectations = []
24
+ end
25
+
26
+ def constrain_as_next_in_sequence(expectation)
27
+ index = @expectations.length
28
+ @expectations << expectation
29
+ expectation.add_ordering_constraint(InSequenceOrderingConstraint.new(self, index))
30
+ end
31
+
32
+ def satisfied_to_index?(index)
33
+ @expectations[0...index].all? { |expectation| expectation.satisfied? }
34
+ end
35
+
36
+ def mocha_inspect
37
+ "#{@name.mocha_inspect}"
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -11,9 +11,9 @@ module Mocha # :nodoc:
11
11
  end
12
12
 
13
13
  def next_invocation
14
- case @parameter_groups.size
15
- when 0: NoYields.new
16
- when 1: @parameter_groups.first
14
+ case @parameter_groups.length
15
+ when 0; NoYields.new
16
+ when 1; @parameter_groups.first
17
17
  else @parameter_groups.shift
18
18
  end
19
19
  end
@@ -23,7 +23,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
23
23
  end
24
24
  assert_failed(test_result)
25
25
  failure_messages = test_result.failures.map { |failure| failure.message }
26
- assert_equal ['#<Mock:mock>.method - expected calls: 0, actual calls: 1'], failure_messages
26
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 0, actual calls: 1'], failure_messages
27
27
  end
28
28
 
29
29
  def test_should_pass_if_method_is_expected_twice_and_is_called_twice
@@ -43,7 +43,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
43
43
  end
44
44
  assert_failed(test_result)
45
45
  failure_messages = test_result.failures.map { |failure| failure.message }
46
- assert_equal ['#<Mock:mock>.method - expected calls: 2, actual calls: 1'], failure_messages
46
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2, actual calls: 1'], failure_messages
47
47
  end
48
48
 
49
49
  def test_should_fail_if_method_is_expected_twice_but_is_called_three_times
@@ -54,7 +54,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
54
54
  end
55
55
  assert_failed(test_result)
56
56
  failure_messages = test_result.failures.map { |failure| failure.message }
57
- assert_equal ['#<Mock:mock>.method - expected calls: 2, actual calls: 3'], failure_messages
57
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2, actual calls: 3'], failure_messages
58
58
  end
59
59
 
60
60
  def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_twice
@@ -92,7 +92,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
92
92
  end
93
93
  assert_failed(test_result)
94
94
  failure_messages = test_result.failures.map { |failure| failure.message }
95
- assert_equal ['#<Mock:mock>.method - expected calls: 2..4, actual calls: 1'], failure_messages
95
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2..4, actual calls: 1'], failure_messages
96
96
  end
97
97
 
98
98
  def test_should_fail_if_method_is_expected_between_two_and_four_times_and_is_called_five_times
@@ -103,7 +103,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
103
103
  end
104
104
  assert_failed(test_result)
105
105
  failure_messages = test_result.failures.map { |failure| failure.message }
106
- assert_equal ['#<Mock:mock>.method - expected calls: 2..4, actual calls: 5'], failure_messages
106
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2..4, actual calls: 5'], failure_messages
107
107
  end
108
108
 
109
109
  def test_should_pass_if_method_is_expected_at_least_once_and_is_called_once
@@ -132,7 +132,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
132
132
  end
133
133
  assert_failed(test_result)
134
134
  failure_messages = test_result.failures.map { |failure| failure.message }
135
- assert_equal ['#<Mock:mock>.method - expected calls: at least 1, actual calls: 0'], failure_messages
135
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: at least 1, actual calls: 0'], failure_messages
136
136
  end
137
137
 
138
138
  def test_should_pass_if_method_is_expected_at_most_once_and_is_never_called
@@ -161,7 +161,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
161
161
  end
162
162
  assert_failed(test_result)
163
163
  failure_messages = test_result.failures.map { |failure| failure.message }
164
- assert_equal ['#<Mock:mock>.method - expected calls: at most 1, actual calls: 2'], failure_messages
164
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: at most 1, actual calls: 2'], failure_messages
165
165
  end
166
166
 
167
167
  def test_should_pass_if_method_is_never_expected_and_is_never_called_even_if_everything_is_stubbed
@@ -181,7 +181,7 @@ class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
181
181
  end
182
182
  assert_failed(test_result)
183
183
  failure_messages = test_result.failures.map { |failure| failure.message }
184
- assert_equal ['#<Mock:stub>.method - expected calls: 0, actual calls: 1'], failure_messages
184
+ assert_equal ['#<Mock:stub>.method(any_parameters) - expected calls: 0, actual calls: 1'], failure_messages
185
185
  end
186
186
 
187
187
  end