rspec 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/CHANGES +57 -32
  2. data/EXAMPLES.rd +0 -0
  3. data/Rakefile +22 -21
  4. data/bin/spec +9 -11
  5. data/doc/README +1 -3
  6. data/doc/plugin/syntax.rb +27 -5
  7. data/doc/src/core_team.page +22 -0
  8. data/doc/src/default.css +11 -11
  9. data/doc/src/default.template +0 -1
  10. data/doc/src/documentation/index.page +183 -8
  11. data/doc/src/documentation/meta.info +7 -7
  12. data/doc/src/documentation/mocks.page +168 -109
  13. data/doc/src/documentation/underscores.page +20 -0
  14. data/doc/src/examples.page +2 -1
  15. data/doc/src/images/David_and_Aslak.jpg +0 -0
  16. data/doc/src/images/Whats_That_Dude.jpg +0 -0
  17. data/doc/src/index.page +70 -3
  18. data/doc/src/meta.info +18 -11
  19. data/doc/src/tools/index.page +40 -134
  20. data/doc/src/tools/meta.info +9 -3
  21. data/doc/src/tools/rails.page +3 -1
  22. data/doc/src/tools/rake.page +20 -3
  23. data/doc/src/tools/rcov.page +19 -0
  24. data/doc/src/tools/spec.page +99 -0
  25. data/doc/src/tools/test2rspec.page +2 -4
  26. data/doc/src/tutorials/index.page +52 -0
  27. data/doc/src/tutorials/meta.info +31 -0
  28. data/doc/src/tutorials/notes.txt +252 -0
  29. data/doc/src/tutorials/stack.rb +11 -0
  30. data/doc/src/tutorials/stack_01.page +224 -0
  31. data/doc/src/tutorials/stack_02.page +180 -0
  32. data/doc/src/tutorials/stack_03.page +291 -0
  33. data/doc/src/tutorials/stack_04.page +203 -0
  34. data/doc/src/tutorials/stack_04.page.orig +123 -0
  35. data/doc/src/tutorials/stack_05.page +90 -0
  36. data/doc/src/tutorials/stack_05.page.orig +124 -0
  37. data/doc/src/tutorials/stack_06.page +359 -0
  38. data/doc/src/tutorials/stack_06.page.orig +359 -0
  39. data/doc/src/tutorials/stack_spec.rb +41 -0
  40. data/examples/airport_spec.rb +4 -4
  41. data/examples/{spec_framework_spec.rb → bdd_framework_spec.rb} +6 -7
  42. data/examples/mocking_spec.rb +0 -5
  43. data/examples/stack_spec.rb +6 -7
  44. data/examples/sugar_spec.rb +14 -0
  45. data/lib/spec/api.rb +5 -2
  46. data/lib/spec/api/helper/should_base.rb +17 -22
  47. data/lib/spec/api/helper/should_helper.rb +4 -3
  48. data/lib/spec/api/helper/should_negator.rb +3 -2
  49. data/lib/spec/api/mocks/argument_expectation.rb +104 -0
  50. data/lib/spec/api/{mock.rb → mocks/message_expectation.rb} +47 -96
  51. data/lib/spec/api/mocks/mock.rb +63 -0
  52. data/lib/spec/api/mocks/order_group.rb +21 -0
  53. data/lib/spec/api/sugar.rb +47 -0
  54. data/lib/spec/rake/rcov_verify.rb +45 -0
  55. data/lib/spec/rake/spectask.rb +41 -56
  56. data/lib/spec/runner.rb +4 -1
  57. data/lib/spec/runner/backtrace_tweaker.rb +24 -3
  58. data/lib/spec/runner/base_text_formatter.rb +28 -0
  59. data/lib/spec/runner/context.rb +21 -18
  60. data/lib/spec/runner/context_runner.rb +20 -31
  61. data/lib/spec/runner/execution_context.rb +3 -3
  62. data/lib/spec/runner/kernel_ext.rb +10 -1
  63. data/lib/spec/runner/option_parser.rb +32 -14
  64. data/lib/spec/runner/progress_bar_formatter.rb +21 -0
  65. data/lib/spec/runner/rdoc_formatter.rb +15 -5
  66. data/lib/spec/runner/reporter.rb +100 -0
  67. data/lib/spec/runner/specdoc_formatter.rb +20 -0
  68. data/lib/spec/runner/specification.rb +42 -22
  69. data/lib/spec/version.rb +1 -1
  70. data/test/rcov/rcov_testtask.rb +1 -0
  71. data/test/spec/api/duck_type_test.rb +4 -4
  72. data/test/spec/api/helper/raising_test.rb +37 -17
  73. data/test/spec/api/{mock_arg_constraints_test.rb → mocks/mock_arg_constraints_test.rb} +10 -4
  74. data/test/spec/api/mocks/mock_ordering_test.rb +62 -0
  75. data/test/spec/api/{mock_test.rb → mocks/mock_test.rb} +30 -7
  76. data/test/spec/api/mocks/null_object_test.rb +31 -0
  77. data/test/spec/api/sugar_test.rb +71 -0
  78. data/test/spec/runner/backtrace_tweaker_test.rb +52 -4
  79. data/test/spec/runner/context_runner_test.rb +41 -21
  80. data/test/spec/runner/context_test.rb +60 -32
  81. data/test/spec/runner/execution_context_test.rb +4 -3
  82. data/test/spec/runner/failure_dump_test.rb +92 -0
  83. data/test/spec/runner/kernel_ext_test.rb +1 -2
  84. data/test/spec/runner/option_parser_test.rb +48 -28
  85. data/test/spec/runner/progress_bar_formatter_test.rb +48 -0
  86. data/test/spec/runner/rdoc_formatter_test.rb +31 -4
  87. data/test/spec/runner/reporter_test.rb +103 -0
  88. data/test/spec/runner/specdoc_formatter_test.rb +50 -0
  89. data/test/spec/runner/specification_test.rb +49 -11
  90. data/test/test_helper.rb +1 -4
  91. metadata +46 -15
  92. data/doc/src/community.page +0 -7
  93. data/doc/src/documentation/api.page +0 -185
  94. data/doc/src/why_rspec.page +0 -7
  95. data/examples/empty_stack_spec.rb +0 -22
  96. data/examples/team_spec.rb +0 -30
  97. data/lib/spec/api/duck_type.rb +0 -16
  98. data/lib/spec/runner/simple_text_reporter.rb +0 -88
  99. data/test/rcov/rcov_verify.rb +0 -28
  100. data/test/spec/runner/simple_text_reporter_test.rb +0 -123
@@ -0,0 +1,41 @@
1
+ require 'stack'
2
+
3
+ context "A new stack" do
4
+ setup do
5
+ @stack = Stack.new
6
+ end
7
+
8
+ specify "should be empty" do
9
+ @stack.should_be_empty
10
+ end
11
+ end
12
+
13
+ context "An empty stack" do
14
+ setup do
15
+ @stack = Stack.new
16
+ end
17
+
18
+ specify "should keep its mouth shut when you send it 'push'" do
19
+ lambda { @stack.push Object.new }.should.not.raise
20
+ end
21
+ end
22
+
23
+ context "A stack with one item" do
24
+ setup do
25
+ @stack = Stack.new
26
+ @stack.push "one item"
27
+ end
28
+
29
+ specify "should not be empty" do
30
+ @stack.should_not_be_empty
31
+ end
32
+
33
+ specify "should return top when you send it 'top'" do
34
+ @stack.top.should_equal "one item"
35
+ end
36
+
37
+ specify "should not be empty after 'top'" do
38
+ @stack.top
39
+ @stack.should_not_be_empty
40
+ end
41
+ end
@@ -6,7 +6,7 @@ class Airport
6
6
  end
7
7
 
8
8
  def need?(thing)
9
- thing != :cables
9
+ false unless [:cables, :electricity].include? thing
10
10
  end
11
11
  end
12
12
 
@@ -25,16 +25,16 @@ topic "Airport at home" do
25
25
  end
26
26
 
27
27
  fact "should always work" do
28
- @airport.should.be.working
28
+ @airport.should_be_working
29
29
  end
30
30
 
31
31
  must "not need cables" do
32
- @airport.should.not.need :cables
32
+ @airport.should_not_need :cables
33
33
  end
34
34
 
35
35
  must "not need electricity" do
36
36
  # This will fail...
37
- @airport.should.not.need :electricity
37
+ @airport.should_not_need :electricity
38
38
  end
39
39
 
40
40
  teardown do
@@ -1,28 +1,27 @@
1
1
  require File.dirname(__FILE__) + '/../lib/spec'
2
2
 
3
- class SpecFramework
3
+ class BddFramework
4
4
  def intuitive?
5
5
  true
6
6
  end
7
7
 
8
8
  def adopted_quickly?
9
- false
9
+ true
10
10
  end
11
11
  end
12
12
 
13
- context "Spec framework" do
13
+ context "BDD framework" do
14
14
 
15
15
  setup do
16
- @spec_framework = SpecFramework.new
16
+ @bdd_framework = BddFramework.new
17
17
  end
18
18
 
19
19
  specify "should be adopted quickly" do
20
- #this will fail
21
- @spec_framework.should.be.adopted_quickly
20
+ @bdd_framework.should_be_adopted_quickly
22
21
  end
23
22
 
24
23
  specify "should be intuitive" do
25
- @spec_framework.should.be.intuitive
24
+ @bdd_framework.should_be_intuitive
26
25
  end
27
26
 
28
27
  end
@@ -8,9 +8,4 @@ context "Mocker" do
8
8
  mock.poke
9
9
  end
10
10
 
11
- specify "should fail when expected message not received" do
12
- mock = mock("poke me")
13
- mock.should.receive(:poke)
14
- end
15
-
16
11
  end
@@ -8,11 +8,11 @@ context "An empty stack" do
8
8
  end
9
9
 
10
10
  specify "should accept an item when sent push" do
11
- lambda { @stack.push Object.new }.should.not.raise
11
+ lambda { @stack.push Object.new }.should_not_raise
12
12
  end
13
13
 
14
14
  specify "should complain when sent top" do
15
- lambda { @stack.top }.should.raise StackUnderflowError
15
+ lambda { @stack.top }.should_raise StackUnderflowError
16
16
  end
17
17
 
18
18
  specify "should complain when sent pop" do
@@ -21,7 +21,8 @@ context "An empty stack" do
21
21
 
22
22
  end
23
23
 
24
- context "A stack with one item" do
24
+ context "A stack with one item" do
25
+
25
26
  setup do
26
27
  @stack = Stack.new
27
28
  @stack.push 3
@@ -52,6 +53,7 @@ end
52
53
  end
53
54
 
54
55
  context "An almost full stack (with one item less than capacity)" do
56
+
55
57
  setup do
56
58
  @stack = Stack.new
57
59
  (1..9).each { |i| @stack.push i }
@@ -110,7 +112,4 @@ context "A full stack" do
110
112
  @stack.pop.should.be 9
111
113
  end
112
114
 
113
- end
114
-
115
-
116
-
115
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../lib/spec'
2
+
3
+ context "Underscore sugar" do
4
+ specify "should be available for regular objects" do
5
+ 1.should_equal 1
6
+ lambda { 1.should_not_equal 1 }.should_raise
7
+ end
8
+
9
+ specify "should be available for mocks" do
10
+ sweetened = mock "sweetened"
11
+ sweetened.should_receive :salt
12
+ sweetened.salt
13
+ end
14
+ end
@@ -1,5 +1,8 @@
1
1
  require 'spec/api/exceptions'
2
- require 'spec/api/mock'
3
- require 'spec/api/duck_type'
2
+ require 'spec/api/mocks/argument_expectation'
3
+ require 'spec/api/mocks/order_group'
4
+ require 'spec/api/mocks/message_expectation'
5
+ require 'spec/api/mocks/mock'
4
6
  require 'spec/api/expectations'
5
7
  require 'spec/api/helper'
8
+ require 'spec/api/sugar'
@@ -1,38 +1,33 @@
1
+ class TrueClass; def inspect_for_expectation_not_met_error; "<true>" end end
2
+ class FalseClass; def inspect_for_expectation_not_met_error; "<false>" end end
3
+ class NilClass; def inspect_for_expectation_not_met_error; "nil" end end
4
+ class Class; def inspect_for_expectation_not_met_error; "<#{name}>" end end
5
+ class Proc; def inspect_for_expectation_not_met_error; "<Proc>" end end
6
+ class Array; def inspect_for_expectation_not_met_error; "#{inspect}" end end
7
+ class String; def inspect_for_expectation_not_met_error; "#{inspect}" end end
8
+ class Object
9
+ def inspect_for_expectation_not_met_error
10
+ return "#{self.class} #{inspect}" if inspect.include? "<"
11
+ return "#{self.class} <#{inspect}>" unless inspect.include? "<"
12
+ end
13
+ end
14
+
1
15
  module Spec
2
16
 
3
17
  class ShouldBase
4
18
 
5
19
  def default_message(expectation, expected=:no_expectation_specified)
6
- message = wrap(@target)
7
- message += " #{expectation}"
20
+ message = "#{@target.inspect_for_expectation_not_met_error} #{expectation}"
8
21
  if (expected != :no_expectation_specified)
9
- message += " " + wrap(expected)
22
+ message << " " << expected.inspect_for_expectation_not_met_error
10
23
  end
11
24
  message
12
25
  end
13
-
14
- def wrap(obj)
15
- if obj == true
16
- "<true>"
17
- elsif obj == false
18
- "<false>"
19
- elsif obj.nil?
20
- "nil"
21
- elsif obj.kind_of? Proc
22
- "<Proc>"
23
- elsif (obj.kind_of? Array) || (obj.kind_of? String)
24
- "#{obj.inspect}"
25
- elsif obj.inspect.include? "<"
26
- "#{obj.class} #{obj.inspect}"
27
- else
28
- "#{obj.class} <#{obj.inspect}>"
29
- end
30
- end
31
26
 
32
27
  def fail_with_message(message)
33
28
  Kernel::raise(Spec::Api::ExpectationNotMetError.new(message))
34
29
  end
35
-
30
+
36
31
  end
37
32
 
38
33
  end
@@ -64,11 +64,12 @@ module Spec
64
64
  def raise(exception=Exception)
65
65
  begin
66
66
  @target.call
67
- fail_with_message(default_message("should raise", exception.inspect))
68
67
  rescue exception
69
- rescue
70
- fail_with_message(default_message("should raise", exception.inspect))
68
+ return
69
+ rescue => e
70
+ fail_with_message("#{default_message("should raise", exception)} but raised #{e.inspect}")
71
71
  end
72
+ fail_with_message("#{default_message("should raise", exception)} but raised nothing")
72
73
  end
73
74
 
74
75
  def throw(symbol)
@@ -48,8 +48,9 @@ module Spec
48
48
  def raise(exception=Exception)
49
49
  begin
50
50
  @target.call
51
- rescue exception
52
- fail_with_message(default_message("should not raise", exception.inspect))
51
+ rescue exception => e
52
+ fail_with_message("#{default_message("should not raise", exception)}") if e.instance_of? exception
53
+ fail_with_message("#{default_message("should not raise", exception)} but raised #{e.inspect}") unless e.instance_of? exception
53
54
  rescue
54
55
  true
55
56
  end
@@ -0,0 +1,104 @@
1
+ module Spec
2
+ module Api
3
+
4
+ class LiteralArgConstraint
5
+ def initialize(literal)
6
+ @literal_value = literal
7
+ end
8
+
9
+ def matches?(value)
10
+ @literal_value == value
11
+ end
12
+ end
13
+
14
+ class AnyArgConstraint
15
+ def initialize(ignore)
16
+ end
17
+
18
+ def matches?(value)
19
+ true
20
+ end
21
+ end
22
+
23
+ class NumericArgConstraint
24
+ def initialize(ignore)
25
+ end
26
+
27
+ def matches?(value)
28
+ value.is_a?(Numeric)
29
+ end
30
+ end
31
+
32
+ class BooleanArgConstraint
33
+ def initialize(ignore)
34
+ end
35
+
36
+ def matches?(value)
37
+ return true if value.is_a?(TrueClass)
38
+ return true if value.is_a?(FalseClass)
39
+ false
40
+ end
41
+ end
42
+
43
+ class StringArgConstraint
44
+ def initialize(ignore)
45
+ end
46
+
47
+ def matches?(value)
48
+ value.is_a?(String)
49
+ end
50
+ end
51
+
52
+ class DuckTypeArgConstraint
53
+ def initialize(*methods_to_respond_do)
54
+ @methods_to_respond_do = methods_to_respond_do
55
+ end
56
+
57
+ def matches?(value)
58
+ @methods_to_respond_do.all? { |sym| value.respond_to?(sym) }
59
+ end
60
+ end
61
+
62
+ class ArgumentExpectation
63
+
64
+ @@constraint_classes = Hash.new { |hash, key| LiteralArgConstraint}
65
+ @@constraint_classes[:anything] = AnyArgConstraint
66
+ @@constraint_classes[:numeric] = NumericArgConstraint
67
+ @@constraint_classes[:boolean] = BooleanArgConstraint
68
+ @@constraint_classes[:string] = StringArgConstraint
69
+
70
+ def initialize(args)
71
+ if args == [:any_args] then @expected_params = nil
72
+ elsif args == [:no_args] then @expected_params = []
73
+ else @expected_params = process_arg_constraints(args)
74
+ end
75
+ end
76
+
77
+ def process_arg_constraints(constraints)
78
+ constraints.collect do |constraint|
79
+ convert_constraint(constraint)
80
+ end
81
+ end
82
+
83
+ def convert_constraint(constraint)
84
+ return @@constraint_classes[constraint].new(constraint) if constraint.is_a?(Symbol)
85
+ return constraint if constraint.is_a?(DuckTypeArgConstraint)
86
+ return LiteralArgConstraint.new(constraint)
87
+ end
88
+
89
+ def check_args(args)
90
+ return true if @expected_params.nil?
91
+ return true if @expected_params == args
92
+ return constraints_match?(args)
93
+ end
94
+
95
+ def constraints_match?(args)
96
+ return false if args.length != @expected_params.length
97
+ @expected_params.each_index { |i| return false unless @expected_params[i].matches?(args[i]) }
98
+ return true
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+ end
@@ -1,65 +1,10 @@
1
1
  module Spec
2
2
  module Api
3
- class Mock
4
-
5
- DEFAULT_OPTIONS = {
6
- :null_object => false
7
- }
8
- # Creates a new mock with a +name+ (that will be used in error messages only)
9
- # Options:
10
- # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it.
11
- def initialize(name, options={})
12
- @name = name
13
- @options = DEFAULT_OPTIONS.dup.merge(options)
14
- @expectations = []
15
- end
16
-
17
- def should
18
- self
19
- end
20
-
21
- def receive(sym, &block)
22
- expected_from = caller(1)[0]
23
- expectation = MessageExpectation.new(@name, expected_from, sym, block_given? ? block : nil)
24
- @expectations << expectation
25
- expectation
26
- end
27
-
28
- def __verify
29
- @expectations.each do |expectation|
30
- expectation.verify_messages_received
31
- end
32
- end
33
-
34
- def method_missing(sym, *args, &block)
35
- # TODO: use find_expectation(sym, args) which will lookup based on sym, args and strict mode.
36
- if expectation = find_matching_expectation(sym, *args)
37
- expectation.verify_message(args, block)
38
- else
39
- begin
40
- # act as null object if method is missing and we ignore them. return value too!
41
- @options[:null_object] ? self : super(sym, *args, &block)
42
- rescue NoMethodError
43
-
44
- arg_message = args.collect{|arg| "<#{arg}:#{arg.class.name}>"}.join(", ")
45
-
46
- Kernel::raise Spec::Api::MockExpectationError, "Mock '#{@name}' received unexpected message '#{sym.to_s}' with [#{arg_message}]"
47
- end
48
- end
49
- end
50
-
51
- private
52
-
53
- def find_matching_expectation(sym, *args)
54
- expectation = @expectations.find {|expectation| expectation.matches(sym, args)}
55
- end
56
-
57
- end
58
3
 
59
4
  # Represents the expection of the reception of a message
60
5
  class MessageExpectation
61
-
62
- def initialize(mock_name, expected_from, sym, block)
6
+
7
+ def initialize(mock_name, expectation_ordering, expected_from, sym, block)
63
8
  @mock_name = mock_name
64
9
  @expected_from = expected_from
65
10
  @sym = sym
@@ -67,33 +12,21 @@ module Spec
67
12
  @block = proc {}
68
13
  @received_count = 0
69
14
  @expected_received_count = 1
70
- @expected_params = nil
15
+ @args_expectation = ArgumentExpectation.new([:any_args])
71
16
  @consecutive = false
72
17
  @exception_to_raise = nil
73
18
  @symbol_to_throw = nil
74
19
  @any_seen = false
75
20
  @at_seen = false
76
21
  @and_seen = false
22
+ @ordering = expectation_ordering
23
+ @ordered = false
77
24
  end
78
25
 
79
26
  def matches(sym, args)
80
- @sym == sym and (@expected_params.nil? or @expected_params == args or constraints_match?(args))
81
- end
82
-
83
- def constraints_match?(args)
84
- return true if @expected_params.length == 1 and @expected_params[0] == :any_args
85
- return false if args.length != @expected_params.length
86
- @expected_params.each_index do |i|
87
- next if @expected_params[i] == :anything
88
- next if @expected_params[i] == :numeric and args[i].is_a?Numeric
89
- next if @expected_params[i] == :boolean and args[i].is_a?TrueClass or args[i].is_a?FalseClass
90
- next if @expected_params[i] == :string and args[i].is_a?String
91
- next if @expected_params[i].is_a? DuckType and @expected_params[i].walks_like? args[i]
92
- return false unless args[i] == @expected_params[i]
93
- end
94
- return true
27
+ @sym == sym and @args_expectation.check_args(args)
95
28
  end
96
-
29
+
97
30
  def make_count_message(count)
98
31
  return "at least #{pretty_print(count.abs)}" if count < 0
99
32
  return pretty_print(count) if count > 0
@@ -105,53 +38,63 @@ module Spec
105
38
  return "twice" if count == 2
106
39
  return "#{count} times"
107
40
  end
108
-
41
+
109
42
  # This method is called at the end of a spec, after teardown.
110
43
  def verify_messages_received
111
44
  # TODO: this doesn't provide good enough error messages to fix the error.
112
45
  # Error msg should tell exactly what went wrong. (AH).
113
-
46
+
114
47
  return if @expected_received_count == :any
115
48
  return if (@expected_received_count < 0) && (@received_count >= @expected_received_count.abs)
116
49
  return if @expected_received_count == @received_count
117
50
 
118
- expected_signature = nil
119
- if @expected_params.nil?
120
- expected_signature = @sym
121
- else
122
- params = @expected_params.collect{|param| "<#{param}:#{param.class.name}>"}.join(", ")
123
- expected_signature = "#{@sym}(#{params})"
124
- end
125
-
126
51
  count_message = make_count_message(@expected_received_count)
127
52
 
128
- message = "Mock '#{@mock_name}' expected #{expected_signature} #{count_message}, but received it #{@received_count} times"
53
+ message = "Mock '#{@mock_name}' expected '#{@sym}' #{count_message}, but received it #{@received_count} times"
129
54
  begin
130
- Kernel::raise Spec::Api::MockExpectationError, message
55
+ Kernel::raise(Spec::Api::MockExpectationError, message)
131
56
  rescue => error
132
57
  error.backtrace.insert(0, @expected_from)
133
58
  Kernel::raise error
134
59
  end
135
60
  end
136
61
 
62
+ def handle_order_constraint
63
+ return unless @ordered
64
+ return @ordering.consume(@self) if @ordering.ready_for?(self)
65
+ message = "Mock '#{@mock_name}' received '#{@sym}' out of order"
66
+ Kernel::raise(Spec::Api::MockExpectationError, message)
67
+ end
68
+
137
69
  # This method is called when a method is invoked on a mock
138
70
  def verify_message(args, block)
71
+
72
+ handle_order_constraint
73
+
139
74
  unless @method_block.nil?
140
75
  begin
141
76
  result = @method_block.call(*args)
142
77
  rescue Spec::Api::ExpectationNotMetError => detail
143
- Kernel::raise Spec::Api::MockExpectationError, "Call expectation violated with: " + $!
78
+ Kernel::raise Spec::Api::MockExpectationError, "Call expectation violated with: " + detail
144
79
  end
145
80
  @received_count += 1
146
81
  return result
147
82
  end
148
83
 
149
- args << block unless block.nil?
150
- @received_count += 1
151
-
152
84
  Kernel::raise @exception_to_raise.new unless @exception_to_raise.nil?
153
85
  Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil?
154
-
86
+ unless @args_to_yield.nil?
87
+ if block.nil?
88
+ Kernel::raise Spec::Api::MockExpectationError, "Expected block to be passed"
89
+ end
90
+ if @args_to_yield.length != block.arity
91
+ Kernel::raise Spec::Api::MockExpectationError, "Wrong arity of passed block. Expected #{@args_to_yield.size}"
92
+ end
93
+ block.call @args_to_yield
94
+ end
95
+
96
+ args << block unless block.nil?
97
+ @received_count += 1
155
98
  value = @block.call(*args)
156
99
 
157
100
  return value unless @consecutive
@@ -160,11 +103,7 @@ module Spec
160
103
  end
161
104
 
162
105
  def with(*args)
163
- if args == [:any_args] then @expected_params = nil
164
- elsif args == [:no_args] then @expected_params = []
165
- else @expected_params = args
166
- end
167
-
106
+ @args_expectation = ArgumentExpectation.new(args)
168
107
  self
169
108
  end
170
109
 
@@ -249,6 +188,18 @@ module Spec
249
188
  @and_seen = false
250
189
  @symbol_to_throw = symbol
251
190
  end
191
+
192
+ def ordered
193
+ @ordering.register(self)
194
+ @ordered = true
195
+ self
196
+ end
197
+
198
+ def yield(*args)
199
+ return self unless @and_seen
200
+ @and_seen = false
201
+ @args_to_yield = args
202
+ end
252
203
 
253
204
  end
254
205
  end