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