rspec 0.6.4 → 0.7.0

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 (114) hide show
  1. data/CHANGES +90 -1
  2. data/EXAMPLES.rd +28 -6
  3. data/MIT-LICENSE +20 -0
  4. data/README +18 -12
  5. data/Rakefile +60 -54
  6. data/examples/custom_formatter.rb +4 -4
  7. data/examples/helper_method_example.rb +11 -0
  8. data/examples/mocking_example.rb +19 -2
  9. data/examples/partial_mock_example.rb +28 -0
  10. data/examples/stack_spec.rb +8 -8
  11. data/examples/stubbing_example.rb +50 -9
  12. data/examples/test_case_spec.rb +6 -6
  13. data/lib/spec.rb +1 -2
  14. data/lib/spec/callback.rb +0 -0
  15. data/lib/spec/expectations.rb +3 -6
  16. data/lib/spec/expectations/diff.rb +23 -47
  17. data/lib/spec/expectations/differs/default.rb +62 -0
  18. data/lib/spec/expectations/{exceptions.rb → errors.rb} +0 -0
  19. data/lib/spec/expectations/extensions.rb +4 -0
  20. data/lib/spec/expectations/extensions/inspect_for_expectation_not_met_error.rb +14 -0
  21. data/lib/spec/expectations/extensions/numeric.rb +5 -0
  22. data/lib/spec/expectations/{expectations.rb → extensions/object.rb} +3 -6
  23. data/lib/spec/expectations/extensions/symbol.rb +5 -0
  24. data/lib/spec/expectations/should.rb +4 -0
  25. data/lib/spec/expectations/should/base.rb +42 -0
  26. data/lib/spec/expectations/should/have.rb +79 -0
  27. data/lib/spec/expectations/should/not.rb +72 -0
  28. data/lib/spec/expectations/should/should.rb +83 -0
  29. data/lib/spec/expectations/sugar.rb +6 -25
  30. data/lib/spec/mocks.rb +5 -1
  31. data/lib/spec/mocks/argument_expectation.rb +15 -1
  32. data/lib/spec/mocks/error_generator.rb +72 -0
  33. data/lib/spec/mocks/{exceptions.rb → errors.rb} +0 -0
  34. data/lib/spec/mocks/extensions/object.rb +3 -0
  35. data/lib/spec/mocks/message_expectation.rb +80 -73
  36. data/lib/spec/mocks/mock.rb +4 -69
  37. data/lib/spec/mocks/mock_handler.rb +158 -0
  38. data/lib/spec/mocks/mock_methods.rb +44 -0
  39. data/lib/spec/mocks/order_group.rb +10 -2
  40. data/lib/spec/rake/spectask.rb +20 -18
  41. data/lib/spec/rake/{rcov_verify.rb → verify_rcov.rb} +2 -2
  42. data/lib/spec/runner.rb +3 -1
  43. data/lib/spec/runner/backtrace_tweaker.rb +2 -1
  44. data/lib/spec/runner/context.rb +10 -16
  45. data/lib/spec/runner/context_eval.rb +40 -40
  46. data/lib/spec/runner/execution_context.rb +1 -12
  47. data/lib/spec/runner/{kernel_ext.rb → extensions/kernel.rb} +2 -2
  48. data/lib/spec/runner/{instance_exec.rb → extensions/object.rb} +0 -0
  49. data/lib/spec/runner/formatter/base_text_formatter.rb +25 -18
  50. data/lib/spec/runner/formatter/html_formatter.rb +81 -101
  51. data/lib/spec/runner/formatter/progress_bar_formatter.rb +9 -9
  52. data/lib/spec/runner/formatter/rdoc_formatter.rb +6 -6
  53. data/lib/spec/runner/formatter/specdoc_formatter.rb +7 -6
  54. data/lib/spec/runner/option_parser.rb +41 -5
  55. data/lib/spec/runner/reporter.rb +3 -15
  56. data/lib/spec/runner/spec_should_raise_handler.rb +74 -0
  57. data/lib/spec/runner/specification.rb +33 -14
  58. data/lib/spec/version.rb +6 -3
  59. data/vendor/watir/README.txt +1 -1
  60. metadata +34 -68
  61. data/bin/test2spec +0 -112
  62. data/examples/helper_method_spec.rb +0 -12
  63. data/lib/spec/expectations/have_helper.rb +0 -41
  64. data/lib/spec/expectations/helper.rb +0 -4
  65. data/lib/spec/expectations/should_base.rb +0 -52
  66. data/lib/spec/expectations/should_helper.rb +0 -93
  67. data/lib/spec/expectations/should_negator.rb +0 -71
  68. data/lib/spec/test_to_spec/ruby2ruby.rb +0 -492
  69. data/lib/spec/test_to_spec/sexp_transformer.rb +0 -196
  70. data/lib/spec/test_to_spec/test_case_ext.rb +0 -22
  71. data/lib/spec/test_to_spec/translation_test_runner.rb +0 -147
  72. data/test/spec/expectations/arbitrary_operator_test.rb +0 -55
  73. data/test/spec/expectations/arbitrary_predicate_test.rb +0 -163
  74. data/test/spec/expectations/containment_test.rb +0 -129
  75. data/test/spec/expectations/diff_test.rb +0 -62
  76. data/test/spec/expectations/identity_test.rb +0 -75
  77. data/test/spec/expectations/object_equality_test.rb +0 -65
  78. data/test/spec/expectations/raising_test.rb +0 -106
  79. data/test/spec/expectations/regex_matching_test.rb +0 -36
  80. data/test/spec/expectations/should_have_test.rb +0 -169
  81. data/test/spec/expectations/should_satisfy_test.rb +0 -37
  82. data/test/spec/expectations/sugar_test.rb +0 -93
  83. data/test/spec/expectations/supported_symbols_test.rb +0 -33
  84. data/test/spec/expectations/throwing_test.rb +0 -55
  85. data/test/spec/expectations/true_false_special_case_test.rb +0 -85
  86. data/test/spec/expectations/typing_test.rb +0 -108
  87. data/test/spec/mocks/mock_arg_constraints_test.rb +0 -113
  88. data/test/spec/mocks/mock_counts_test.rb +0 -431
  89. data/test/spec/mocks/mock_ordering_test.rb +0 -109
  90. data/test/spec/mocks/mock_test.rb +0 -220
  91. data/test/spec/mocks/null_object_test.rb +0 -37
  92. data/test/spec/runner/backtrace_tweaker_test.rb +0 -90
  93. data/test/spec/runner/context_matching_test.rb +0 -35
  94. data/test/spec/runner/context_runner_test.rb +0 -62
  95. data/test/spec/runner/context_test.rb +0 -191
  96. data/test/spec/runner/execution_context_test.rb +0 -45
  97. data/test/spec/runner/formatter/failure_dump_test.rb +0 -94
  98. data/test/spec/runner/formatter/html_formatter_test.rb +0 -48
  99. data/test/spec/runner/formatter/progress_bar_formatter_test.rb +0 -56
  100. data/test/spec/runner/formatter/rdoc_formatter_test.rb +0 -51
  101. data/test/spec/runner/formatter/specdoc_formatter_test.rb +0 -57
  102. data/test/spec/runner/kernel_ext_test.rb +0 -13
  103. data/test/spec/runner/option_parser_test.rb +0 -141
  104. data/test/spec/runner/reporter_test.rb +0 -128
  105. data/test/spec/runner/spec_matcher_test.rb +0 -47
  106. data/test/spec/runner/specification_test.rb +0 -121
  107. data/test/spec/test_to_spec/ruby_to_ruby_test.rb +0 -79
  108. data/test/spec/test_to_spec/sexp_transformer_assertion_test.rb +0 -207
  109. data/test/spec/test_to_spec/sexp_transformer_test.rb +0 -303
  110. data/test/spec/test_to_spec/test_case_ext_test.rb +0 -25
  111. data/test/spec/test_to_spec/testfiles/test_unit_api_spec.rb +0 -75
  112. data/test/spec/test_to_spec/testfiles/test_unit_api_test.rb +0 -70
  113. data/test/test_classes.rb +0 -102
  114. data/test/test_helper.rb +0 -32
@@ -0,0 +1,79 @@
1
+ module Spec
2
+ module Expectations
3
+ module Should
4
+ class Have < Base
5
+
6
+ def initialize(target, relativity=:exactly, expected=nil, negate=false)
7
+ @target = target
8
+ @expected = expected == :no ? 0 : expected
9
+ @at_least = (relativity == :at_least)
10
+ @at_most = (relativity == :at_most)
11
+ @negate = negate
12
+ end
13
+
14
+ def exactly(expected_number=nil)
15
+ @at_least = false
16
+ @at_most = false
17
+ @expected = expected_number == :no ? 0 : expected_number
18
+ self
19
+ end
20
+
21
+ def at_least(expected_number=nil)
22
+ @at_least = true
23
+ @at_most = false
24
+ @expected = expected_number == :no ? 0 : expected_number
25
+ self
26
+ end
27
+
28
+ def at_most(expected_number=nil)
29
+ @at_least = false
30
+ @at_most = true
31
+ @expected = expected_number == :no ? 0 : expected_number
32
+ self
33
+ end
34
+
35
+ def method_missing(sym, *args)
36
+ if @target.respond_to?(sym)
37
+ fail_with_message(build_message(sym, args)) unless as_specified?(sym, args)
38
+ elsif @target.respond_to?("has_#{sym}?")
39
+ if @negate
40
+ return unless @target.send("has_#{sym}?", *args)
41
+ fail_with_message msg(sym, args, "should not have")
42
+ else
43
+ return if @target.send("has_#{sym}?", *args)
44
+ fail_with_message msg(sym, args, "should have")
45
+ end
46
+ else
47
+ raise NoMethodError.new("#{@target.inspect} does not respond to `#{sym}' or `has_#{sym}?'")
48
+ end
49
+ end
50
+
51
+ def msg(sym, args, text)
52
+ "#{@target.inspect_for_expectation_not_met_error} #{text} #{sym}: #{args.collect{|arg| arg.inspect_for_expectation_not_met_error}.join(', ')}"
53
+ end
54
+
55
+ def actual_size(collection)
56
+ return collection.length if collection.respond_to? :length
57
+ return collection.size if collection.respond_to? :size
58
+ end
59
+
60
+ def build_message(sym, args)
61
+ message = "#{@target.inspect_for_expectation_not_met_error} should have"
62
+ message += " at least" if @at_least
63
+ message += " at most" if @at_most
64
+ message += " #{@expected} #{sym} (has #{actual_size(collection(sym, args))})"
65
+ end
66
+
67
+ def as_specified?(sym, args)
68
+ return actual_size(collection(sym, args)) >= @expected if @at_least
69
+ return actual_size(collection(sym, args)) <= @expected if @at_most
70
+ return actual_size(collection(sym, args)) == @expected
71
+ end
72
+
73
+ def collection(sym, args)
74
+ @target.send(sym, *args)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,72 @@
1
+ module Spec
2
+ module Expectations
3
+ module Should
4
+ class Not < Base
5
+
6
+ def initialize(target)
7
+ @target = target
8
+ @be_seen = false
9
+ end
10
+
11
+ def have(expected_number=nil)
12
+ Have.new(@target, :exactly, expected_number, true)
13
+ end
14
+
15
+ def satisfy
16
+ fail_with_message "Supplied expectation was satisfied, but should not have been" if (yield @target)
17
+ end
18
+
19
+ def be(expected = :no_arg)
20
+ @be_seen = true
21
+ return self if (expected == :no_arg)
22
+ fail_with_message(default_message("should not be", expected)) if (@target.equal?(expected))
23
+ end
24
+
25
+ def an_instance_of expected_class
26
+ fail_with_message(default_message("should not be an instance of", expected_class)) if @target.instance_of? expected_class
27
+ end
28
+
29
+ def a_kind_of expected_class
30
+ fail_with_message(default_message("should not be a kind of", expected_class)) if @target.kind_of? expected_class
31
+ end
32
+
33
+ def respond_to message
34
+ fail_with_message(default_message("should not respond to", message)) if @target.respond_to? message
35
+ end
36
+
37
+ def match(expected)
38
+ fail_with_message(default_message("should not match", expected)) if (@target =~ expected)
39
+ end
40
+
41
+ def raise(exception=Exception, message=nil)
42
+ begin
43
+ @target.call
44
+ rescue exception => e
45
+ return unless message.nil? || e.message == message || (message.is_a?(Regexp) && e.message =~ message)
46
+ fail_with_message("#{default_message("should not raise", exception)}") if e.instance_of? exception
47
+ fail_with_message("#{default_message("should not raise", exception)} but raised #{e.inspect}") unless e.instance_of? exception
48
+ rescue
49
+ true
50
+ end
51
+ end
52
+
53
+ def throw(symbol=:___this_is_a_symbol_that_will_likely_never_occur___)
54
+ begin
55
+ catch symbol do
56
+ @target.call
57
+ return true
58
+ end
59
+ fail_with_message(default_message("should not throw", symbol.inspect))
60
+ rescue NameError
61
+ true
62
+ end
63
+ end
64
+
65
+ def __delegate_method_missing_to_target original_sym, actual_sym, *args
66
+ return unless @target.__send__(actual_sym, *args)
67
+ fail_with_message(default_message("should not#{@be_seen ? ' be' : ''} #{original_sym}" + (args.empty? ? '' : (' ' + args.join(', ')))))
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,83 @@
1
+ module Spec
2
+ module Expectations
3
+ module Should
4
+ class Should < Base
5
+
6
+ def initialize(target)
7
+ @target = target
8
+ @be_seen = false
9
+ end
10
+
11
+ def have(expected_number=nil)
12
+ Have.new(@target, :exactly, expected_number)
13
+ end
14
+
15
+ def not
16
+ Not.new(@target)
17
+ end
18
+
19
+ def satisfy
20
+ return if yield(@target)
21
+ fail_with_message "Supplied expectation was not satisfied"
22
+ end
23
+
24
+ def be(expected = :___no_arg)
25
+ @be_seen = true
26
+ return self if (expected == :___no_arg)
27
+ fail_with_message(default_message("should be", expected)) unless (@target.equal?(expected))
28
+ end
29
+
30
+ def an_instance_of(expected_class)
31
+ fail_with_message(default_message("should be an instance of", expected_class)) unless @target.instance_of? expected_class
32
+ end
33
+
34
+ def a_kind_of(expected_class)
35
+ fail_with_message(default_message("should be a kind of", expected_class)) unless @target.kind_of? expected_class
36
+ end
37
+
38
+ def respond_to(message)
39
+ fail_with_message(default_message("should respond to", message)) unless @target.respond_to? message
40
+ end
41
+
42
+ def __delegate_method_missing_to_target(original_sym, actual_sym, *args)
43
+ return if @target.send(actual_sym, *args)
44
+ message = default_message("should#{@be_seen ? ' be' : ''} #{original_sym}", args[0])
45
+ fail_with_message(message)
46
+ end
47
+
48
+ def match(expected)
49
+ fail_with_message(default_message("should match", expected)) unless (@target =~ expected)
50
+ end
51
+
52
+ def raise(exception=Exception, message=nil)
53
+ begin
54
+ @target.call
55
+ rescue exception => e
56
+ unless message.nil?
57
+ if message.is_a?(Regexp)
58
+ e.message.should_match message
59
+ else
60
+ e.message.should_eql message
61
+ end
62
+ end
63
+ return
64
+ rescue => e
65
+ fail_with_message("#{default_message("should raise", exception)} but raised #{e.inspect}")
66
+ end
67
+ fail_with_message("#{default_message("should raise", exception)} but raised nothing")
68
+ end
69
+
70
+ def throw(symbol)
71
+ begin
72
+ catch symbol do
73
+ @target.call
74
+ fail_with_message(default_message("should throw", symbol.inspect))
75
+ end
76
+ rescue NameError
77
+ fail_with_message(default_message("should throw", symbol.inspect))
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -2,42 +2,23 @@ module Spec
2
2
  module Expectations
3
3
  # This module adds syntactic sugar that allows usage of should_* instead of should.*
4
4
  module UnderscoreSugar
5
- module SweetTooth; end
6
-
7
5
  def handle_underscores_for_rspec!
8
6
  original_method_missing = instance_method(:method_missing)
9
7
  class_eval do
10
- include SweetTooth # This is meant to add a signature to the object that sugarization occurred.
11
8
  def method_missing(sym, *args, &block)
12
9
  _method_missing(sym, args, block)
13
10
  end
14
11
 
15
12
  define_method :_method_missing do |sym, args, block|
16
- return original_method_missing.bind(self).call(sym, *args, &block) unless __sweetened?(sym)
17
-
18
- object = self
19
- calls = sym.to_s.split("_")
20
- while calls.length > 1
21
- remainder = calls.join("_")
22
- break if (object.respond_to?(remainder))
23
- call = calls.shift
24
- object = object.__send__(call)
25
- break if call == "be"
26
- end
27
- return object.__send__(calls.join("_"), *args, &block)
13
+ return original_method_missing.bind(self).call(sym, *args, &block) unless sym.to_s =~ /^should_/
14
+ return Spec::Expectations::Should::Should.new(self).__send__(__strip_should(sym), *args, &block)
28
15
  end
29
-
30
- def __sweetened?(sym) #:nodoc:
31
- return true if sym.to_s =~ /^should_/
16
+
17
+ def __strip_should sym
18
+ sym.to_s[7..-1]
32
19
  end
33
20
  end
34
21
  end
35
22
  end
36
23
  end
37
- end
38
-
39
- class Module
40
- include Spec::Expectations::UnderscoreSugar
41
- end
42
-
43
- Object.handle_underscores_for_rspec!
24
+ end
@@ -1,5 +1,9 @@
1
+ require 'spec/mocks/mock_methods'
2
+ require 'spec/mocks/mock_handler'
1
3
  require 'spec/mocks/mock'
2
4
  require 'spec/mocks/argument_expectation'
3
5
  require 'spec/mocks/message_expectation'
4
6
  require 'spec/mocks/order_group'
5
- require 'spec/mocks/exceptions'
7
+ require 'spec/mocks/errors'
8
+ require 'spec/mocks/error_generator'
9
+ require 'spec/mocks/extensions/object'
@@ -11,6 +11,17 @@ module Spec
11
11
  end
12
12
  end
13
13
 
14
+ class RegexpArgConstraint
15
+ def initialize(regexp)
16
+ @regexp = regexp
17
+ end
18
+
19
+ def matches?(value)
20
+ return value =~ @regexp unless value.is_a?(Regexp)
21
+ value == @regexp
22
+ end
23
+ end
24
+
14
25
  class AnyArgConstraint
15
26
  def initialize(ignore)
16
27
  end
@@ -60,7 +71,7 @@ module Spec
60
71
  end
61
72
 
62
73
  class ArgumentExpectation
63
-
74
+ attr_reader :args
64
75
  @@constraint_classes = Hash.new { |hash, key| LiteralArgConstraint}
65
76
  @@constraint_classes[:anything] = AnyArgConstraint
66
77
  @@constraint_classes[:numeric] = NumericArgConstraint
@@ -68,6 +79,7 @@ module Spec
68
79
  @@constraint_classes[:string] = StringArgConstraint
69
80
 
70
81
  def initialize(args)
82
+ @args = *args
71
83
  if [:any_args] == args then @expected_params = nil
72
84
  elsif [:no_args] == args then @expected_params = []
73
85
  else @expected_params = process_arg_constraints(args)
@@ -83,7 +95,9 @@ module Spec
83
95
  def convert_constraint(constraint)
84
96
  return @@constraint_classes[constraint].new(constraint) if constraint.is_a?(Symbol)
85
97
  return constraint if constraint.is_a?(DuckTypeArgConstraint)
98
+ return RegexpArgConstraint.new(constraint) if constraint.is_a?(Regexp)
86
99
  return LiteralArgConstraint.new(constraint)
100
+
87
101
  end
88
102
 
89
103
  def check_args(args)
@@ -0,0 +1,72 @@
1
+ module Spec
2
+ module Mocks
3
+ class ErrorGenerator
4
+ attr_writer :opts
5
+
6
+ def initialize target, name
7
+ @target = target
8
+ @name = name
9
+ end
10
+
11
+ def opts
12
+ @opts ||= {}
13
+ end
14
+
15
+ def raise_unexpected_message_error sym, *args
16
+ __raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}"
17
+ end
18
+
19
+ def raise_expectation_error sym, expected_received_count, actual_received_count, *args
20
+ __raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}"
21
+ end
22
+
23
+ def raise_out_of_order_error sym
24
+ __raise "#{intro} received :#{sym} out of order"
25
+ end
26
+
27
+ def raise_block_failed_error sym, detail
28
+ __raise "#{intro} received :#{sym} but passed block failed with: #{detail}"
29
+ end
30
+
31
+ def raise_missing_block_error args_to_yield
32
+ __raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
33
+ end
34
+
35
+ def raise_wrong_arity_error args_to_yield, arity
36
+ __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
37
+ end
38
+
39
+ private
40
+ def intro
41
+ @name ? "Mock '#{@name}'" : @target.to_s
42
+ end
43
+
44
+ def __raise message
45
+ message = opts[:message] unless opts[:message].nil?
46
+ Kernel::raise(Spec::Mocks::MockExpectationError, message)
47
+ end
48
+
49
+ def arg_message *args
50
+ return "" if [:any_args] == args
51
+ return if args.empty?
52
+ " with [" + arg_list(*args) + "]"
53
+ end
54
+
55
+ def arg_list(*args)
56
+ args.collect{|arg| arg.inspect}.join(", ")
57
+ end
58
+
59
+ def count_message(count)
60
+ return "at least #{pretty_print(count.abs)}" if count < 0
61
+ return pretty_print(count)
62
+ end
63
+
64
+ def pretty_print(count)
65
+ return "once" if count == 1
66
+ return "twice" if count == 2
67
+ return "#{count} times"
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,3 @@
1
+ class Object
2
+ include Spec::Mocks::MockMethods
3
+ end
@@ -1,11 +1,12 @@
1
1
  module Spec
2
2
  module Mocks
3
3
 
4
- # Represents the expection of the reception of a message
5
- class MessageExpectation
6
-
7
- def initialize(mock_name, expectation_ordering, expected_from, sym, method_block, expected_received_count=1)
8
- @mock_name = mock_name
4
+ class BaseExpectation
5
+ attr_reader :sym
6
+
7
+ def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={})
8
+ @error_generator = error_generator
9
+ @error_generator.opts = opts
9
10
  @expected_from = expected_from
10
11
  @sym = sym
11
12
  @method_block = method_block
@@ -16,61 +17,36 @@ module Spec
16
17
  @consecutive = false
17
18
  @exception_to_raise = nil
18
19
  @symbol_to_throw = nil
19
- @ordering = expectation_ordering
20
- @ordered = false
20
+ @order_group = expectation_ordering
21
21
  @at_least = nil
22
22
  @at_most = nil
23
23
  @args_to_yield = nil
24
24
  end
25
-
26
- def matches(sym, args)
27
- @sym == sym and @args_expectation.check_args(args)
28
- end
29
-
30
- def make_count_message(count)
31
- return "at least #{pretty_print(count.abs)}" if count < 0
32
- return pretty_print(count) if count > 0
33
- return "never"
25
+
26
+ def and_return(*values, &return_block)
27
+ Kernel::raise AmbiguousReturnError unless @method_block.nil?
28
+ if values.size == 0
29
+ value = nil
30
+ elsif values.size == 1
31
+ value = values[0]
32
+ else
33
+ value = values
34
+ @consecutive = true
35
+ @expected_received_count = values.size if @expected_received_count < values.size
36
+ end
37
+ @return_block = block_given? ? return_block : lambda { value }
34
38
  end
35
39
 
36
- def pretty_print(count)
37
- return "once" if count == 1
38
- return "twice" if count == 2
39
- return "#{count} times"
40
+ def and_raise(exception=Exception)
41
+ @exception_to_raise = exception
40
42
  end
41
43
 
42
- # This method is called at the end of a spec, after teardown.
43
- def verify_messages_received
44
- # TODO: this doesn't provide good enough error messages to fix the error.
45
- # Error msg should tell exactly what went wrong. (AH).
46
-
47
- return if @expected_received_count == :any
48
- return if (@at_least) && (@received_count >= @expected_received_count)
49
- return if (@at_most) && (@received_count <= @expected_received_count)
50
- return if @expected_received_count == @received_count
51
-
52
- count_message = make_count_message(@expected_received_count)
53
-
54
- message = "Mock '#{@mock_name}' expected '#{@sym}' #{count_message}, but received it #{@received_count} times"
55
- begin
56
- Kernel::raise(Spec::Mocks::MockExpectationError, message)
57
- rescue => error
58
- error.backtrace.insert(0, @expected_from)
59
- Kernel::raise error
60
- end
61
- end
62
-
63
- def handle_order_constraint
64
- return unless @ordered
65
- return @ordering.consume(self) if @ordering.ready_for?(self)
66
- message = "Mock '#{@mock_name}' received '#{@sym}' out of order"
67
- Kernel::raise(Spec::Mocks::MockExpectationError, message)
44
+ def matches(sym, args)
45
+ @sym == sym and @args_expectation.check_args(args)
68
46
  end
69
47
 
70
- # This method is called when a method is invoked on a mock
71
48
  def invoke(args, block)
72
-
73
- handle_order_constraint
49
+ @order_group.handle_order_constraint self
74
50
 
75
51
  begin
76
52
  Kernel::raise @exception_to_raise.new unless @exception_to_raise.nil?
@@ -80,6 +56,8 @@ module Spec
80
56
  return invoke_method_block(args)
81
57
  elsif !@args_to_yield.nil?
82
58
  return invoke_with_yield(block)
59
+ elsif @consecutive
60
+ return invoke_consecutive_return_block(args, block)
83
61
  else
84
62
  return invoke_return_block(args, block)
85
63
  end
@@ -92,32 +70,57 @@ module Spec
92
70
  begin
93
71
  @method_block.call(*args)
94
72
  rescue Spec::Expectations::ExpectationNotMetError => detail
95
- Kernel::raise Spec::Mocks::MockExpectationError, "Call expectation violated with: " + detail
73
+ @error_generator.raise_block_failed_error @sym, detail.message
96
74
  end
97
75
  end
98
76
 
99
77
  def invoke_with_yield(block)
100
78
  if block.nil?
101
- Kernel::raise Spec::Mocks::MockExpectationError, "Expected block to be passed"
79
+ @error_generator.raise_missing_block_error @args_to_yield
102
80
  end
103
81
  if @args_to_yield.length != block.arity
104
- Kernel::raise Spec::Mocks::MockExpectationError, "Wrong arity of passed block. Expected #{@args_to_yield.size}"
82
+ @error_generator.raise_wrong_arity_error @args_to_yield, block.arity
105
83
  end
106
84
  block.call(*@args_to_yield)
107
85
  end
108
-
86
+
87
+ def invoke_consecutive_return_block(args, block)
88
+ args << block unless block.nil?
89
+ value = @return_block.call(*args)
90
+
91
+ index = [@received_count, value.size-1].min
92
+ value[index]
93
+ end
94
+
109
95
  def invoke_return_block(args, block)
110
96
  args << block unless block.nil?
111
97
  value = @return_block.call(*args)
112
98
 
113
- if @consecutive
114
- index = [@received_count, value.size-1].min
115
- value[index]
116
- else
117
- value
99
+ value
100
+ end
101
+ end
102
+
103
+ class MessageExpectation < BaseExpectation
104
+
105
+ def matches_name_but_not_args(sym, args)
106
+ @sym == sym and not @args_expectation.check_args(args)
107
+ end
108
+
109
+ def verify_messages_received
110
+ return if @expected_received_count == :any
111
+ return if (@at_least) && (@received_count >= @expected_received_count)
112
+ return if (@at_most) && (@received_count <= @expected_received_count)
113
+ return if @expected_received_count == @received_count
114
+
115
+ begin
116
+ @error_generator.raise_expectation_error @sym, @expected_received_count, @received_count, @args_expectation.args
117
+ rescue => error
118
+ error.backtrace.insert(0, @expected_from)
119
+ Kernel::raise error
118
120
  end
119
121
  end
120
122
 
123
+
121
124
  def with(*args)
122
125
  @args_expectation = ArgumentExpectation.new(args)
123
126
  self
@@ -156,7 +159,6 @@ module Spec
156
159
  self
157
160
  end
158
161
 
159
- #TODO - replace this w/ not syntax in mock
160
162
  def never
161
163
  @expected_received_count = 0
162
164
  self
@@ -172,16 +174,6 @@ module Spec
172
174
  self
173
175
  end
174
176
 
175
- def and_return(value=nil, &return_block)
176
- Kernel::raise AmbiguousReturnError unless @method_block.nil?
177
- @consecutive = value.instance_of? Array
178
- @return_block = block_given? ? return_block : lambda { value }
179
- end
180
-
181
- def and_raise(exception=Exception)
182
- @exception_to_raise = exception
183
- end
184
-
185
177
  def and_throw(symbol)
186
178
  @symbol_to_throw = symbol
187
179
  end
@@ -191,16 +183,31 @@ module Spec
191
183
  end
192
184
 
193
185
  def ordered
194
- @ordering.register(self)
186
+ @order_group.register(self)
195
187
  @ordered = true
196
188
  self
197
189
  end
190
+
191
+ def negative_expectation_for? sym
192
+ return false
193
+ end
198
194
  end
199
195
 
200
196
  class NegativeMessageExpectation < MessageExpectation
201
- def initialize(mock_name, expectation_ordering, expected_from, sym, method_block)
202
- super mock_name, expectation_ordering, expected_from, sym, method_block, 0
197
+ def initialize(message, expectation_ordering, expected_from, sym, method_block)
198
+ super message, expectation_ordering, expected_from, sym, method_block, 0
199
+ end
200
+
201
+ def negative_expectation_for? sym
202
+ return @sym == sym
203
+ end
204
+ end
205
+
206
+ class MethodStub < BaseExpectation
207
+ def initialize(message, expectation_ordering, expected_from, sym, method_block)
208
+ super message, expectation_ordering, expected_from, sym, method_block, 0
209
+ @expected_received_count = :any
203
210
  end
204
211
  end
205
212
  end
206
- end
213
+ end