rspec 1.1.4 → 1.1.5

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 (157) hide show
  1. data/{CHANGES → History.txt} +116 -64
  2. data/Manifest.txt +403 -0
  3. data/{MIT-LICENSE → README.txt} +43 -0
  4. data/Rakefile +39 -212
  5. data/{TODO → TODO.txt} +0 -0
  6. data/bin/autospec +4 -0
  7. data/bin/spec +1 -1
  8. data/examples/pure/yielding_example.rb +33 -0
  9. data/examples/stories/game-of-life/.loadpath +5 -0
  10. data/examples/stories/game-of-life/behaviour/everything.rb +1 -1
  11. data/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story +17 -17
  12. data/init.rb +9 -0
  13. data/lib/autotest/discover.rb +1 -1
  14. data/lib/autotest/rspec.rb +3 -29
  15. data/lib/spec.rb +10 -12
  16. data/lib/spec/adapters.rb +1 -0
  17. data/lib/spec/adapters/ruby_engine.rb +26 -0
  18. data/lib/spec/adapters/ruby_engine/mri.rb +8 -0
  19. data/lib/spec/adapters/ruby_engine/rubinius.rb +8 -0
  20. data/lib/spec/example/errors.rb +6 -0
  21. data/lib/spec/example/example_group_methods.rb +17 -14
  22. data/lib/spec/example/example_matcher.rb +2 -0
  23. data/lib/spec/example/example_methods.rb +4 -9
  24. data/lib/spec/example/module_inclusion_warnings.rb +2 -1
  25. data/lib/spec/expectations/extensions/object.rb +2 -2
  26. data/lib/spec/expectations/handler.rb +8 -16
  27. data/lib/spec/extensions/main.rb +2 -17
  28. data/lib/spec/matchers.rb +8 -2
  29. data/lib/spec/matchers/be.rb +0 -3
  30. data/lib/spec/matchers/change.rb +44 -40
  31. data/lib/spec/matchers/has.rb +1 -1
  32. data/lib/spec/matchers/have.rb +17 -12
  33. data/lib/spec/matchers/operator_matcher.rb +10 -4
  34. data/lib/spec/matchers/simple_matcher.rb +113 -10
  35. data/lib/spec/mocks.rb +1 -1
  36. data/lib/spec/mocks/argument_constraints.rb +185 -0
  37. data/lib/spec/mocks/argument_expectation.rb +35 -173
  38. data/lib/spec/mocks/framework.rb +1 -1
  39. data/lib/spec/mocks/message_expectation.rb +30 -5
  40. data/lib/spec/mocks/methods.rb +14 -2
  41. data/lib/spec/mocks/mock.rb +4 -0
  42. data/lib/spec/mocks/proxy.rb +46 -5
  43. data/lib/spec/mocks/spec_methods.rb +9 -1
  44. data/lib/spec/rake/spectask.rb +14 -22
  45. data/lib/spec/rake/verify_rcov.rb +3 -3
  46. data/lib/spec/runner.rb +18 -6
  47. data/lib/spec/runner/backtrace_tweaker.rb +6 -7
  48. data/lib/spec/runner/command_line.rb +6 -17
  49. data/lib/spec/runner/drb_command_line.rb +1 -1
  50. data/lib/spec/runner/formatter/base_formatter.rb +3 -1
  51. data/lib/spec/runner/formatter/base_text_formatter.rb +5 -9
  52. data/lib/spec/runner/formatter/html_formatter.rb +1 -1
  53. data/lib/spec/runner/formatter/nested_text_formatter.rb +1 -1
  54. data/lib/spec/runner/formatter/progress_bar_formatter.rb +2 -2
  55. data/lib/spec/runner/formatter/specdoc_formatter.rb +1 -1
  56. data/lib/spec/runner/formatter/story/html_formatter.rb +62 -16
  57. data/lib/spec/runner/formatter/story/plain_text_formatter.rb +68 -16
  58. data/lib/spec/runner/formatter/story/progress_bar_formatter.rb +42 -0
  59. data/lib/spec/runner/heckle_runner.rb +2 -2
  60. data/lib/spec/runner/option_parser.rb +2 -1
  61. data/lib/spec/runner/options.rb +18 -9
  62. data/lib/spec/runner/reporter.rb +24 -4
  63. data/lib/spec/runner/spec_parser.rb +1 -1
  64. data/lib/spec/story/runner.rb +1 -2
  65. data/lib/spec/story/runner/story_mediator.rb +14 -0
  66. data/lib/spec/story/runner/story_parser.rb +20 -0
  67. data/lib/spec/story/step.rb +40 -28
  68. data/lib/spec/story/step_mother.rb +2 -1
  69. data/lib/spec/story/world.rb +6 -2
  70. data/lib/spec/version.rb +13 -22
  71. data/rake_tasks/failing_examples_with_html.rake +1 -1
  72. data/rake_tasks/verify_rcov.rake +2 -2
  73. data/rspec.gemspec +33 -0
  74. data/spec/autotest/rspec_spec.rb +90 -141
  75. data/spec/spec/adapters/ruby_engine_spec.rb +16 -0
  76. data/spec/spec/example/base_formatter_spec.rb +112 -0
  77. data/spec/spec/example/example_group_factory_spec.rb +2 -2
  78. data/spec/spec/example/example_group_methods_spec.rb +55 -4
  79. data/spec/spec/example/example_group_spec.rb +4 -3
  80. data/spec/spec/example/example_methods_spec.rb +18 -14
  81. data/spec/spec/example/pending_module_spec.rb +38 -0
  82. data/spec/spec/example/shared_example_group_spec.rb +1 -1
  83. data/spec/spec/expectations/extensions/object_spec.rb +0 -12
  84. data/spec/spec/extensions/main_spec.rb +3 -8
  85. data/spec/spec/matchers/change_spec.rb +16 -6
  86. data/spec/spec/matchers/handler_spec.rb +58 -37
  87. data/spec/spec/matchers/has_spec.rb +10 -0
  88. data/spec/spec/matchers/have_spec.rb +105 -2
  89. data/spec/spec/matchers/operator_matcher_spec.rb +35 -2
  90. data/spec/spec/matchers/simple_matcher_spec.rb +64 -2
  91. data/spec/spec/mocks/any_number_of_times_spec.rb +7 -0
  92. data/spec/spec/mocks/bug_report_496.rb +17 -0
  93. data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +7 -1
  94. data/spec/spec/mocks/hash_including_matcher_spec.rb +45 -24
  95. data/spec/spec/mocks/mock_spec.rb +55 -10
  96. data/spec/spec/mocks/nil_expectation_warning_spec.rb +54 -0
  97. data/spec/spec/mocks/null_object_mock_spec.rb +14 -0
  98. data/spec/spec/mocks/options_hash_spec.rb +18 -28
  99. data/spec/spec/mocks/partial_mock_spec.rb +2 -0
  100. data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +20 -6
  101. data/spec/spec/mocks/stub_spec.rb +7 -0
  102. data/spec/spec/runner/command_line_spec.rb +5 -12
  103. data/spec/spec/runner/drb_command_line_spec.rb +13 -6
  104. data/spec/spec/runner/formatter/html_formatter_spec.rb +2 -1
  105. data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +3 -3
  106. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +20 -2
  107. data/spec/spec/runner/formatter/spec_mate_formatter_spec.rb +2 -1
  108. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +3 -3
  109. data/spec/spec/runner/formatter/story/html_formatter_spec.rb +76 -2
  110. data/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb +161 -0
  111. data/spec/spec/runner/formatter/story/progress_bar_formatter_spec.rb +82 -0
  112. data/spec/spec/runner/heckle_runner_spec.rb +8 -8
  113. data/spec/spec/runner/option_parser_spec.rb +21 -6
  114. data/spec/spec/runner/output_one_time_fixture_runner.rb +1 -1
  115. data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +6 -0
  116. data/spec/spec/runner/reporter_spec.rb +51 -5
  117. data/spec/spec/runner/spec_parser_spec.rb +4 -4
  118. data/spec/spec/story/runner/plain_text_story_runner_spec.rb +2 -5
  119. data/spec/spec/story/runner/story_mediator_spec.rb +10 -0
  120. data/spec/spec/story/runner/story_parser_spec.rb +23 -6
  121. data/spec/spec/story/scenario_spec.rb +1 -3
  122. data/spec/spec/story/step_mother_spec.rb +12 -0
  123. data/spec/spec/story/step_spec.rb +57 -4
  124. data/spec/spec/story/story_spec.rb +1 -3
  125. data/spec/spec/story/world_spec.rb +1 -1
  126. data/spec/spec_helper.rb +21 -68
  127. data/stories/all.rb +1 -1
  128. data/stories/configuration/before_blocks.story +21 -0
  129. data/stories/configuration/stories.rb +7 -0
  130. data/stories/example_groups/stories.rb +3 -4
  131. data/stories/resources/spec/before_blocks_example.rb +32 -0
  132. data/stories/stories/multiline_steps.story +23 -0
  133. data/stories/stories/steps/multiline_steps.rb +13 -0
  134. data/stories/stories/stories.rb +6 -0
  135. data/story_server/prototype/javascripts/builder.js +136 -0
  136. data/story_server/prototype/javascripts/controls.js +972 -0
  137. data/story_server/prototype/javascripts/dragdrop.js +976 -0
  138. data/story_server/prototype/javascripts/effects.js +1117 -0
  139. data/story_server/prototype/javascripts/prototype.js +4140 -0
  140. data/story_server/prototype/javascripts/rspec.js +149 -0
  141. data/story_server/prototype/javascripts/scriptaculous.js +58 -0
  142. data/story_server/prototype/javascripts/slider.js +276 -0
  143. data/story_server/prototype/javascripts/sound.js +55 -0
  144. data/story_server/prototype/javascripts/unittest.js +568 -0
  145. data/story_server/prototype/lib/server.rb +24 -0
  146. data/story_server/prototype/stories.html +176 -0
  147. data/story_server/prototype/stylesheets/rspec.css +136 -0
  148. data/story_server/prototype/stylesheets/test.css +90 -0
  149. metadata +166 -166
  150. data/README +0 -36
  151. data/UPGRADE +0 -7
  152. data/bin/spec_translator +0 -8
  153. data/lib/spec/mocks/argument_constraint_matchers.rb +0 -31
  154. data/lib/spec/translator.rb +0 -114
  155. data/spec/spec/example/example_spec.rb +0 -53
  156. data/spec/spec/runner/execution_context_spec.rb +0 -37
  157. data/spec/spec/translator_spec.rb +0 -265
@@ -1,6 +1,6 @@
1
1
  require 'spec/mocks/framework'
2
2
  require 'spec/mocks/methods'
3
- require 'spec/mocks/argument_constraint_matchers'
3
+ require 'spec/mocks/argument_constraints'
4
4
  require 'spec/mocks/spec_methods'
5
5
  require 'spec/mocks/proxy'
6
6
  require 'spec/mocks/mock'
@@ -0,0 +1,185 @@
1
+ module Spec
2
+ module Mocks
3
+
4
+ # ArgumentConstraints are messages that you can include in message
5
+ # expectations to match arguments against a broader check than simple
6
+ # equality.
7
+ #
8
+ # With the exception of any_args() and no_args(), the constraints
9
+ # are all positional - they match against the arg in the given position.
10
+ module ArgumentConstraints
11
+
12
+ class AnyArgsConstraint
13
+ def description
14
+ "any args"
15
+ end
16
+ end
17
+
18
+ class AnyArgConstraint
19
+ def initialize(ignore)
20
+ end
21
+
22
+ def ==(other)
23
+ true
24
+ end
25
+ end
26
+
27
+ class NoArgsConstraint
28
+ def description
29
+ "no args"
30
+ end
31
+
32
+ def ==(args)
33
+ args == []
34
+ end
35
+ end
36
+
37
+ class RegexpArgConstraint
38
+ def initialize(regexp)
39
+ @regexp = regexp
40
+ end
41
+
42
+ def ==(value)
43
+ return value =~ @regexp unless value.is_a?(Regexp)
44
+ value == @regexp
45
+ end
46
+ end
47
+
48
+ class BooleanArgConstraint
49
+ def initialize(ignore)
50
+ end
51
+
52
+ def ==(value)
53
+ TrueClass === value || FalseClass === value
54
+ end
55
+ end
56
+
57
+ class HashIncludingConstraint
58
+ def initialize(expected)
59
+ @expected = expected
60
+ end
61
+
62
+ def ==(actual)
63
+ @expected.each do | key, value |
64
+ return false unless actual.has_key?(key) && value == actual[key]
65
+ end
66
+ true
67
+ rescue NoMethodError => ex
68
+ return false
69
+ end
70
+
71
+ def description
72
+ "hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
73
+ end
74
+ end
75
+
76
+ class DuckTypeArgConstraint
77
+ def initialize(*methods_to_respond_to)
78
+ @methods_to_respond_to = methods_to_respond_to
79
+ end
80
+
81
+ def ==(value)
82
+ @methods_to_respond_to.all? { |sym| value.respond_to?(sym) }
83
+ end
84
+ end
85
+
86
+ class MatcherConstraint
87
+ def initialize(matcher)
88
+ @matcher = matcher
89
+ end
90
+
91
+ def ==(value)
92
+ @matcher.matches?(value)
93
+ end
94
+ end
95
+
96
+ class EqualityProxy
97
+ def initialize(given)
98
+ @given = given
99
+ end
100
+
101
+ def ==(expected)
102
+ @given == expected
103
+ end
104
+ end
105
+
106
+ module Deprecated
107
+ class NumericArgConstraint
108
+ def initialize(ignore)
109
+ end
110
+
111
+ def ==(value)
112
+ value.is_a?(Numeric)
113
+ end
114
+ end
115
+
116
+ class StringArgConstraint
117
+ def initialize(ignore)
118
+ end
119
+
120
+ def ==(value)
121
+ String === value
122
+ end
123
+ end
124
+ end
125
+
126
+ # :call-seq:
127
+ # object.should_receive(:message).with(any_args())
128
+ #
129
+ # Passes if object receives :message with any args at all. This is
130
+ # really a more explicit variation of object.should_receive(:message)
131
+ def any_args
132
+ AnyArgsConstraint.new
133
+ end
134
+
135
+ # :call-seq:
136
+ # object.should_receive(:message).with(anything())
137
+ #
138
+ # Passes as long as there is an argument.
139
+ def anything
140
+ AnyArgConstraint.new(nil)
141
+ end
142
+
143
+ # :call-seq:
144
+ # object.should_receive(:message).with(no_args)
145
+ #
146
+ # Passes if no arguments are passed along with the message
147
+ def no_args
148
+ NoArgsConstraint.new
149
+ end
150
+
151
+ # :call-seq:
152
+ # object.should_receive(:message).with(duck_type(:hello))
153
+ # object.should_receive(:message).with(duck_type(:hello, :goodbye))
154
+ #
155
+ # Passes if the argument responds to the specified messages.
156
+ #
157
+ # == Examples
158
+ #
159
+ # array = []
160
+ # display = mock('display')
161
+ # display.should_receive(:present_names).with(duck_type(:length, :each))
162
+ # => passes
163
+ def duck_type(*args)
164
+ DuckTypeArgConstraint.new(*args)
165
+ end
166
+
167
+ # :call-seq:
168
+ # object.should_receive(:message).with(boolean())
169
+ #
170
+ # Passes if the argument is boolean.
171
+ def boolean
172
+ BooleanArgConstraint.new(nil)
173
+ end
174
+
175
+ # :call-seq:
176
+ # object.should_receive(:message).with(hash_including(:this => that))
177
+ #
178
+ # Passes if the argument is a hash that includes the specified key/value
179
+ # pairs. If the hash includes other keys, it will still pass.
180
+ def hash_including(expected={})
181
+ HashIncludingConstraint.new(expected)
182
+ end
183
+ end
184
+ end
185
+ end
@@ -1,175 +1,40 @@
1
1
  module Spec
2
2
  module Mocks
3
-
4
- class MatcherConstraint
5
- def initialize(matcher)
6
- @matcher = matcher
7
- end
8
-
9
- def matches?(value)
10
- @matcher.matches?(value)
11
- end
12
- end
13
-
14
- class LiteralArgConstraint
15
- def initialize(literal)
16
- @literal_value = literal
17
- end
18
-
19
- def matches?(value)
20
- @literal_value == value
21
- end
22
- end
23
-
24
- class RegexpArgConstraint
25
- def initialize(regexp)
26
- @regexp = regexp
27
- end
28
-
29
- def matches?(value)
30
- return value =~ @regexp unless value.is_a?(Regexp)
31
- value == @regexp
32
- end
33
- end
34
-
35
- class AnyArgConstraint
36
- def initialize(ignore)
37
- end
38
-
39
- def ==(other)
40
- true
41
- end
42
-
43
- # TODO - need this?
44
- def matches?(value)
45
- true
46
- end
47
- end
48
-
49
- class AnyArgsConstraint
50
- def description
51
- "any args"
52
- end
53
- end
54
-
55
- class NoArgsConstraint
56
- def description
57
- "no args"
58
- end
59
-
60
- def ==(args)
61
- args == []
62
- end
63
- end
64
-
65
- class NumericArgConstraint
66
- def initialize(ignore)
67
- end
68
-
69
- def matches?(value)
70
- value.is_a?(Numeric)
71
- end
72
- end
73
3
 
74
- class BooleanArgConstraint
75
- def initialize(ignore)
76
- end
77
-
78
- def ==(value)
79
- matches?(value)
80
- end
81
-
82
- def matches?(value)
83
- return true if value.is_a?(TrueClass)
84
- return true if value.is_a?(FalseClass)
85
- false
86
- end
87
- end
88
-
89
- class StringArgConstraint
90
- def initialize(ignore)
91
- end
92
-
93
- def matches?(value)
94
- value.is_a?(String)
95
- end
96
- end
97
-
98
- class DuckTypeArgConstraint
99
- def initialize(*methods_to_respond_to)
100
- @methods_to_respond_to = methods_to_respond_to
101
- end
102
-
103
- def matches?(value)
104
- @methods_to_respond_to.all? { |sym| value.respond_to?(sym) }
105
- end
106
-
107
- def description
108
- "duck_type"
109
- end
110
- end
111
-
112
- class HashIncludingConstraint
113
- def initialize(expected)
114
- @expected = expected
115
- end
116
-
117
- def ==(actual)
118
- @expected.each do | key, value |
119
- # check key for case that value evaluates to nil
120
- return false unless actual.has_key?(key) && actual[key] == value
121
- end
122
- true
123
- rescue NoMethodError => ex
124
- return false
125
- end
126
-
127
- def matches?(value)
128
- self == value
129
- end
130
-
131
- def description
132
- "hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
133
- end
134
-
135
- end
136
-
137
-
138
4
  class ArgumentExpectation
139
5
  attr_reader :args
140
- @@constraint_classes = Hash.new { |hash, key| LiteralArgConstraint}
141
- @@constraint_classes[:anything] = AnyArgConstraint
142
- @@constraint_classes[:numeric] = NumericArgConstraint
143
- @@constraint_classes[:boolean] = BooleanArgConstraint
144
- @@constraint_classes[:string] = StringArgConstraint
6
+ @@constraint_classes = Hash.new
7
+ @@constraint_classes[:anything] = ArgumentConstraints::AnyArgConstraint
8
+ @@constraint_classes[:boolean] = ArgumentConstraints::BooleanArgConstraint
9
+ @@constraint_classes[:numeric] = ArgumentConstraints::Deprecated::NumericArgConstraint
10
+ @@constraint_classes[:string] = ArgumentConstraints::Deprecated::StringArgConstraint
145
11
 
146
- def initialize(args)
12
+ def initialize(args, &block)
147
13
  @args = args
14
+ @constraints_block = block
15
+
148
16
  if [:any_args] == args
149
- @expected_params = nil
150
- warn_deprecated(:any_args.inspect, "any_args()")
151
- elsif args.length == 1 && args[0].is_a?(AnyArgsConstraint) then @expected_params = nil
17
+ @expected_args = nil
18
+ warn_constraint_symbol_deprecated(:any_args.inspect, "any_args()")
19
+ elsif ArgumentConstraints::AnyArgsConstraint === args.first
20
+ @expected_args = nil
152
21
  elsif [:no_args] == args
153
- @expected_params = []
154
- warn_deprecated(:no_args.inspect, "no_args()")
155
- elsif args.length == 1 && args[0].is_a?(NoArgsConstraint) then @expected_params = []
156
- else @expected_params = process_arg_constraints(args)
157
- end
158
- end
159
-
160
- def process_arg_constraints(constraints)
161
- constraints.collect do |constraint|
162
- convert_constraint(constraint)
22
+ @expected_args = []
23
+ warn_constraint_symbol_deprecated(:no_args.inspect, "no_args()")
24
+ elsif ArgumentConstraints::NoArgsConstraint === args.first
25
+ @expected_args = []
26
+ else
27
+ @expected_args = args.collect {|arg| constraint_for(arg)}
163
28
  end
164
29
  end
165
30
 
166
- def warn_deprecated(deprecated_method, instead)
167
- Kernel.warn "The #{deprecated_method} constraint is deprecated. Use #{instead} instead."
31
+ def warn_constraint_symbol_deprecated(deprecated_method, instead)
32
+ Kernel.warn "The #{deprecated_method} constraint is deprecated and will be removed after RSpec 1.1.5. Use #{instead} instead."
168
33
  end
169
34
 
170
- def convert_constraint(constraint)
171
- if [:anything, :numeric, :boolean, :string].include?(constraint)
172
- case constraint
35
+ def constraint_for(arg)
36
+ if [:anything, :numeric, :boolean, :string].include?(arg)
37
+ case arg
173
38
  when :anything
174
39
  instead = "anything()"
175
40
  when :boolean
@@ -179,30 +44,27 @@ module Spec
179
44
  when :string
180
45
  instead = "an_instance_of(String)"
181
46
  end
182
- warn_deprecated(constraint.inspect, instead)
183
- return @@constraint_classes[constraint].new(constraint)
47
+ warn_constraint_symbol_deprecated(arg.inspect, instead)
48
+ return @@constraint_classes[arg].new(arg)
184
49
  end
185
- return MatcherConstraint.new(constraint) if is_matcher?(constraint)
186
- return RegexpArgConstraint.new(constraint) if constraint.is_a?(Regexp)
187
- return LiteralArgConstraint.new(constraint)
50
+ return ArgumentConstraints::MatcherConstraint.new(arg) if is_matcher?(arg)
51
+ return ArgumentConstraints::RegexpArgConstraint.new(arg) if arg.is_a?(Regexp)
52
+ return ArgumentConstraints::EqualityProxy.new(arg)
188
53
  end
189
54
 
190
55
  def is_matcher?(obj)
191
56
  return obj.respond_to?(:matches?) && obj.respond_to?(:description)
192
57
  end
193
58
 
194
- def check_args(args)
195
- return true if @expected_params.nil?
196
- return true if @expected_params == args
197
- return constraints_match?(args)
59
+ def args_match?(given_args)
60
+ if @constraints_block
61
+ @constraints_block.call(*given_args)
62
+ return true
63
+ end
64
+
65
+ @expected_args.nil? || @expected_args == given_args
198
66
  end
199
67
 
200
- def constraints_match?(args)
201
- return false if args.length != @expected_params.length
202
- @expected_params.each_index { |i| return false unless @expected_params[i].matches?(args[i]) }
203
- return true
204
- end
205
-
206
68
  end
207
69
 
208
70
  end
@@ -3,7 +3,7 @@
3
3
  # object in the system.
4
4
 
5
5
  require 'spec/mocks/methods'
6
- require 'spec/mocks/argument_constraint_matchers'
6
+ require 'spec/mocks/argument_constraints'
7
7
  require 'spec/mocks/spec_methods'
8
8
  require 'spec/mocks/proxy'
9
9
  require 'spec/mocks/mock'
@@ -3,6 +3,10 @@ module Spec
3
3
 
4
4
  class BaseExpectation
5
5
  attr_reader :sym
6
+ attr_writer :expected_received_count, :method_block, :expected_from, :args_to_yield
7
+ protected :expected_received_count=, :method_block=, :expected_from=, :args_to_yield=
8
+ attr_accessor :error_generator
9
+ protected :error_generator, :error_generator=
6
10
 
7
11
  def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={})
8
12
  @error_generator = error_generator
@@ -13,7 +17,7 @@ module Spec
13
17
  @return_block = nil
14
18
  @actual_received_count = 0
15
19
  @expected_received_count = expected_received_count
16
- @args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new])
20
+ @args_expectation = ArgumentExpectation.new([ArgumentConstraints::AnyArgsConstraint.new])
17
21
  @consecutive = false
18
22
  @exception_to_raise = nil
19
23
  @symbol_to_throw = nil
@@ -23,6 +27,23 @@ module Spec
23
27
  @args_to_yield = []
24
28
  end
25
29
 
30
+ def build_child(expected_from, method_block, expected_received_count, opts={})
31
+ child = clone
32
+ child.expected_from = expected_from
33
+ child.method_block = method_block
34
+ child.expected_received_count = expected_received_count
35
+ new_gen = error_generator.clone
36
+ new_gen.opts = opts
37
+ child.error_generator = new_gen
38
+ child.args_to_yield = @args_to_yield.clone
39
+ child
40
+ end
41
+
42
+ def error_generator_opts=(opts={})
43
+ @error_generator.opts = opts
44
+ end
45
+ protected :error_generator_opts=
46
+
26
47
  def expected_args
27
48
  @args_expectation.args
28
49
  end
@@ -68,7 +89,7 @@ module Spec
68
89
  end
69
90
 
70
91
  def matches(sym, args)
71
- @sym == sym and @args_expectation.check_args(args)
92
+ @sym == sym and @args_expectation.args_match?(args)
72
93
  end
73
94
 
74
95
  def invoke(args, block)
@@ -103,6 +124,11 @@ module Spec
103
124
  @actual_received_count += 1
104
125
  end
105
126
  end
127
+
128
+ def called_max_times?
129
+ @expected_received_count != :any &&
130
+ @actual_received_count >= @expected_received_count
131
+ end
106
132
 
107
133
  protected
108
134
 
@@ -152,7 +178,7 @@ module Spec
152
178
  class MessageExpectation < BaseExpectation
153
179
 
154
180
  def matches_name_but_not_args(sym, args)
155
- @sym == sym and not @args_expectation.check_args(args)
181
+ @sym == sym and not @args_expectation.args_match?(args)
156
182
  end
157
183
 
158
184
  def verify_messages_received
@@ -202,8 +228,7 @@ module Spec
202
228
  end
203
229
 
204
230
  def with(*args, &block)
205
- @method_block = block if block
206
- @args_expectation = ArgumentExpectation.new(args)
231
+ @args_expectation = ArgumentExpectation.new(args, &block)
207
232
  self
208
233
  end
209
234