rspec 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +90 -1
- data/EXAMPLES.rd +28 -6
- data/MIT-LICENSE +20 -0
- data/README +18 -12
- data/Rakefile +60 -54
- data/examples/custom_formatter.rb +4 -4
- data/examples/helper_method_example.rb +11 -0
- data/examples/mocking_example.rb +19 -2
- data/examples/partial_mock_example.rb +28 -0
- data/examples/stack_spec.rb +8 -8
- data/examples/stubbing_example.rb +50 -9
- data/examples/test_case_spec.rb +6 -6
- data/lib/spec.rb +1 -2
- data/lib/spec/callback.rb +0 -0
- data/lib/spec/expectations.rb +3 -6
- data/lib/spec/expectations/diff.rb +23 -47
- data/lib/spec/expectations/differs/default.rb +62 -0
- data/lib/spec/expectations/{exceptions.rb → errors.rb} +0 -0
- data/lib/spec/expectations/extensions.rb +4 -0
- data/lib/spec/expectations/extensions/inspect_for_expectation_not_met_error.rb +14 -0
- data/lib/spec/expectations/extensions/numeric.rb +5 -0
- data/lib/spec/expectations/{expectations.rb → extensions/object.rb} +3 -6
- data/lib/spec/expectations/extensions/symbol.rb +5 -0
- data/lib/spec/expectations/should.rb +4 -0
- data/lib/spec/expectations/should/base.rb +42 -0
- data/lib/spec/expectations/should/have.rb +79 -0
- data/lib/spec/expectations/should/not.rb +72 -0
- data/lib/spec/expectations/should/should.rb +83 -0
- data/lib/spec/expectations/sugar.rb +6 -25
- data/lib/spec/mocks.rb +5 -1
- data/lib/spec/mocks/argument_expectation.rb +15 -1
- data/lib/spec/mocks/error_generator.rb +72 -0
- data/lib/spec/mocks/{exceptions.rb → errors.rb} +0 -0
- data/lib/spec/mocks/extensions/object.rb +3 -0
- data/lib/spec/mocks/message_expectation.rb +80 -73
- data/lib/spec/mocks/mock.rb +4 -69
- data/lib/spec/mocks/mock_handler.rb +158 -0
- data/lib/spec/mocks/mock_methods.rb +44 -0
- data/lib/spec/mocks/order_group.rb +10 -2
- data/lib/spec/rake/spectask.rb +20 -18
- data/lib/spec/rake/{rcov_verify.rb → verify_rcov.rb} +2 -2
- data/lib/spec/runner.rb +3 -1
- data/lib/spec/runner/backtrace_tweaker.rb +2 -1
- data/lib/spec/runner/context.rb +10 -16
- data/lib/spec/runner/context_eval.rb +40 -40
- data/lib/spec/runner/execution_context.rb +1 -12
- data/lib/spec/runner/{kernel_ext.rb → extensions/kernel.rb} +2 -2
- data/lib/spec/runner/{instance_exec.rb → extensions/object.rb} +0 -0
- data/lib/spec/runner/formatter/base_text_formatter.rb +25 -18
- data/lib/spec/runner/formatter/html_formatter.rb +81 -101
- data/lib/spec/runner/formatter/progress_bar_formatter.rb +9 -9
- data/lib/spec/runner/formatter/rdoc_formatter.rb +6 -6
- data/lib/spec/runner/formatter/specdoc_formatter.rb +7 -6
- data/lib/spec/runner/option_parser.rb +41 -5
- data/lib/spec/runner/reporter.rb +3 -15
- data/lib/spec/runner/spec_should_raise_handler.rb +74 -0
- data/lib/spec/runner/specification.rb +33 -14
- data/lib/spec/version.rb +6 -3
- data/vendor/watir/README.txt +1 -1
- metadata +34 -68
- data/bin/test2spec +0 -112
- data/examples/helper_method_spec.rb +0 -12
- data/lib/spec/expectations/have_helper.rb +0 -41
- data/lib/spec/expectations/helper.rb +0 -4
- data/lib/spec/expectations/should_base.rb +0 -52
- data/lib/spec/expectations/should_helper.rb +0 -93
- data/lib/spec/expectations/should_negator.rb +0 -71
- data/lib/spec/test_to_spec/ruby2ruby.rb +0 -492
- data/lib/spec/test_to_spec/sexp_transformer.rb +0 -196
- data/lib/spec/test_to_spec/test_case_ext.rb +0 -22
- data/lib/spec/test_to_spec/translation_test_runner.rb +0 -147
- data/test/spec/expectations/arbitrary_operator_test.rb +0 -55
- data/test/spec/expectations/arbitrary_predicate_test.rb +0 -163
- data/test/spec/expectations/containment_test.rb +0 -129
- data/test/spec/expectations/diff_test.rb +0 -62
- data/test/spec/expectations/identity_test.rb +0 -75
- data/test/spec/expectations/object_equality_test.rb +0 -65
- data/test/spec/expectations/raising_test.rb +0 -106
- data/test/spec/expectations/regex_matching_test.rb +0 -36
- data/test/spec/expectations/should_have_test.rb +0 -169
- data/test/spec/expectations/should_satisfy_test.rb +0 -37
- data/test/spec/expectations/sugar_test.rb +0 -93
- data/test/spec/expectations/supported_symbols_test.rb +0 -33
- data/test/spec/expectations/throwing_test.rb +0 -55
- data/test/spec/expectations/true_false_special_case_test.rb +0 -85
- data/test/spec/expectations/typing_test.rb +0 -108
- data/test/spec/mocks/mock_arg_constraints_test.rb +0 -113
- data/test/spec/mocks/mock_counts_test.rb +0 -431
- data/test/spec/mocks/mock_ordering_test.rb +0 -109
- data/test/spec/mocks/mock_test.rb +0 -220
- data/test/spec/mocks/null_object_test.rb +0 -37
- data/test/spec/runner/backtrace_tweaker_test.rb +0 -90
- data/test/spec/runner/context_matching_test.rb +0 -35
- data/test/spec/runner/context_runner_test.rb +0 -62
- data/test/spec/runner/context_test.rb +0 -191
- data/test/spec/runner/execution_context_test.rb +0 -45
- data/test/spec/runner/formatter/failure_dump_test.rb +0 -94
- data/test/spec/runner/formatter/html_formatter_test.rb +0 -48
- data/test/spec/runner/formatter/progress_bar_formatter_test.rb +0 -56
- data/test/spec/runner/formatter/rdoc_formatter_test.rb +0 -51
- data/test/spec/runner/formatter/specdoc_formatter_test.rb +0 -57
- data/test/spec/runner/kernel_ext_test.rb +0 -13
- data/test/spec/runner/option_parser_test.rb +0 -141
- data/test/spec/runner/reporter_test.rb +0 -128
- data/test/spec/runner/spec_matcher_test.rb +0 -47
- data/test/spec/runner/specification_test.rb +0 -121
- data/test/spec/test_to_spec/ruby_to_ruby_test.rb +0 -79
- data/test/spec/test_to_spec/sexp_transformer_assertion_test.rb +0 -207
- data/test/spec/test_to_spec/sexp_transformer_test.rb +0 -303
- data/test/spec/test_to_spec/test_case_ext_test.rb +0 -25
- data/test/spec/test_to_spec/testfiles/test_unit_api_spec.rb +0 -75
- data/test/spec/test_to_spec/testfiles/test_unit_api_test.rb +0 -70
- data/test/test_classes.rb +0 -102
- 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
|
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
|
31
|
-
|
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
|
data/lib/spec/mocks.rb
CHANGED
@@ -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/
|
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
|
File without changes
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module Spec
|
2
2
|
module Mocks
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(
|
8
|
-
@
|
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
|
-
@
|
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
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
37
|
-
|
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
|
-
|
43
|
-
|
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
|
-
|
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
|
-
|
79
|
+
@error_generator.raise_missing_block_error @args_to_yield
|
102
80
|
end
|
103
81
|
if @args_to_yield.length != block.arity
|
104
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
-
@
|
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(
|
202
|
-
super
|
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
|