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