dchelimsky-rspec 1.1.12 → 1.1.99.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/History.txt +35 -0
  2. data/License.txt +1 -1
  3. data/Manifest.txt +22 -73
  4. data/README.txt +2 -2
  5. data/Rakefile +32 -7
  6. data/TODO.txt +9 -4
  7. data/bin/spec +1 -1
  8. data/cucumber.yml +2 -0
  9. data/examples/failing/spec_helper.rb +1 -1
  10. data/examples/passing/filtered_formatter.rb +18 -0
  11. data/examples/passing/filtered_formatter_example.rb +31 -0
  12. data/examples/passing/spec_helper.rb +1 -1
  13. data/examples/ruby1.9.compatibility/access_to_constants_spec.rb +17 -18
  14. data/features/before_and_after_blocks/before_and_after_blocks.feature +4 -4
  15. data/features/example_groups/autogenerated_docstrings.feature +2 -2
  16. data/features/example_groups/example_group_with_should_methods.feature +1 -1
  17. data/features/example_groups/nested_groups.feature +1 -1
  18. data/features/interop/examples_and_tests_together.feature +1 -1
  19. data/features/interop/test_but_not_test_unit.feature +1 -1
  20. data/features/interop/test_case_with_should_methods.feature +1 -1
  21. data/features/mock_framework_integration/use_flexmock.feature +22 -4
  22. data/features/mock_framework_integration/use_mocha.feature +27 -0
  23. data/features/mock_framework_integration/use_rr.feature +27 -0
  24. data/features/step_definitions/running_rspec.rb +5 -3
  25. data/features/support/env.rb +1 -1
  26. data/features-pending/cli/conditional_exclusion.feature +39 -0
  27. data/lib/{adapters → spec/adapters}/mock_frameworks/flexmock.rb +1 -0
  28. data/lib/{adapters → spec/adapters}/mock_frameworks/mocha.rb +1 -0
  29. data/lib/{adapters → spec/adapters}/mock_frameworks/rr.rb +1 -0
  30. data/lib/{adapters → spec/adapters}/mock_frameworks/rspec.rb +0 -1
  31. data/lib/spec/autorun.rb +3 -0
  32. data/lib/spec/example/before_and_after_hooks.rb +5 -20
  33. data/lib/spec/example/example_description.rb +15 -0
  34. data/lib/spec/example/example_group.rb +0 -15
  35. data/lib/spec/example/example_group_factory.rb +34 -46
  36. data/lib/spec/example/example_group_hierarchy.rb +53 -0
  37. data/lib/spec/example/example_group_methods.rb +96 -211
  38. data/lib/spec/example/example_methods.rb +62 -81
  39. data/lib/spec/example/module_reopening_fix.rb +23 -1
  40. data/lib/spec/example/predicate_matchers.rb +47 -0
  41. data/lib/spec/example/subject.rb +91 -0
  42. data/lib/spec/example.rb +4 -0
  43. data/lib/spec/expectations/extensions.rb +0 -1
  44. data/lib/spec/expectations/handler.rb +6 -1
  45. data/lib/spec/expectations.rb +1 -1
  46. data/lib/spec/interop/test/unit/testcase.rb +5 -22
  47. data/lib/spec/interop/test.rb +1 -0
  48. data/lib/spec/matchers/be.rb +2 -7
  49. data/lib/spec/matchers/be_close.rb +20 -5
  50. data/lib/spec/matchers/change.rb +5 -3
  51. data/lib/spec/matchers/eql.rb +24 -6
  52. data/lib/spec/matchers/equal.rb +24 -6
  53. data/lib/spec/matchers/exist.rb +21 -5
  54. data/lib/spec/matchers/generated_descriptions.rb +2 -2
  55. data/lib/spec/matchers/has.rb +28 -11
  56. data/lib/spec/matchers/match.rb +25 -7
  57. data/lib/spec/matchers/match_array.rb +1 -1
  58. data/lib/spec/matchers/method_missing.rb +2 -2
  59. data/lib/spec/matchers/operator_matcher.rb +12 -5
  60. data/lib/spec/matchers/raise_error.rb +1 -1
  61. data/lib/spec/matchers/respond_to.rb +1 -1
  62. data/lib/spec/matchers/satisfy.rb +5 -5
  63. data/lib/spec/matchers/throw_symbol.rb +1 -3
  64. data/lib/spec/mocks/argument_expectation.rb +1 -1
  65. data/lib/spec/mocks/argument_matchers.rb +233 -0
  66. data/lib/spec/mocks/error_generator.rb +2 -6
  67. data/lib/spec/mocks/message_expectation.rb +3 -11
  68. data/lib/spec/mocks/mock.rb +1 -1
  69. data/lib/spec/mocks/proxy.rb +5 -1
  70. data/lib/spec/runner/configuration.rb +3 -3
  71. data/lib/spec/runner/drb_command_line.rb +2 -1
  72. data/lib/spec/runner/example_group_runner.rb +2 -1
  73. data/lib/spec/runner/formatter/base_text_formatter.rb +28 -17
  74. data/lib/spec/runner/formatter/failing_example_groups_formatter.rb +3 -5
  75. data/lib/spec/runner/formatter/html_formatter.rb +2 -3
  76. data/lib/spec/runner/formatter/nested_text_formatter.rb +7 -25
  77. data/lib/spec/runner/formatter/progress_bar_formatter.rb +1 -1
  78. data/lib/spec/runner/formatter/specdoc_formatter.rb +1 -7
  79. data/lib/spec/runner/heckle_runner_unsupported.rb +1 -1
  80. data/lib/spec/runner/option_parser.rb +16 -19
  81. data/lib/spec/runner/options.rb +28 -26
  82. data/lib/spec/runner/reporter.rb +8 -9
  83. data/lib/spec/runner.rb +6 -28
  84. data/lib/spec/test/unit.rb +10 -0
  85. data/lib/spec/version.rb +2 -2
  86. data/{features/support → resources}/helpers/cmdline.rb +2 -2
  87. data/resources/rake/verify_rcov.rake +1 -1
  88. data/resources/spec/example_group_with_should_methods.rb +1 -1
  89. data/resources/spec/simple_spec.rb +1 -1
  90. data/resources/test/spec_and_test_together.rb +2 -3
  91. data/resources/test/spec_including_test_but_not_unit.rb +1 -1
  92. data/resources/test/test_case_with_should_methods.rb +2 -3
  93. data/rspec.gemspec +5 -5
  94. data/spec/spec/dsl/main_spec.rb +3 -3
  95. data/spec/spec/example/example_group_class_definition_spec.rb +11 -14
  96. data/spec/spec/example/example_group_factory_spec.rb +31 -44
  97. data/spec/spec/example/example_group_methods_spec.rb +86 -52
  98. data/spec/spec/example/example_group_spec.rb +16 -75
  99. data/spec/spec/example/example_matcher_spec.rb +10 -10
  100. data/spec/spec/example/example_methods_spec.rb +101 -241
  101. data/spec/spec/example/nested_example_group_spec.rb +2 -2
  102. data/spec/spec/example/pending_module_spec.rb +1 -1
  103. data/spec/spec/example/shared_example_group_spec.rb +2 -2
  104. data/spec/spec/interop/test/unit/resources/spec_that_fails.rb +2 -2
  105. data/spec/spec/interop/test/unit/resources/spec_that_passes.rb +2 -2
  106. data/spec/spec/interop/test/unit/resources/spec_with_errors.rb +2 -2
  107. data/spec/spec/interop/test/unit/resources/spec_with_options_hash.rb +2 -2
  108. data/spec/spec/interop/test/unit/resources/test_case_that_fails.rb +2 -2
  109. data/spec/spec/interop/test/unit/resources/test_case_that_passes.rb +2 -2
  110. data/spec/spec/interop/test/unit/resources/test_case_with_errors.rb +2 -2
  111. data/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb +2 -2
  112. data/spec/spec/matchers/change_spec.rb +8 -0
  113. data/spec/spec/matchers/exist_spec.rb +8 -4
  114. data/spec/spec/matchers/handler_spec.rb +8 -1
  115. data/spec/spec/matchers/matcher_methods_spec.rb +1 -1
  116. data/spec/spec/mocks/{bug_report_496.rb → bug_report_496_spec.rb} +0 -0
  117. data/spec/spec/mocks/failing_argument_matchers_spec.rb +95 -0
  118. data/spec/spec/mocks/nil_expectation_warning_spec.rb +1 -1
  119. data/spec/spec/mocks/passing_argument_matchers_spec.rb +145 -0
  120. data/spec/spec/runner/configuration_spec.rb +12 -12
  121. data/spec/spec/runner/formatter/base_text_formatter_spec.rb +72 -1
  122. data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +8 -8
  123. data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +4 -4
  124. data/spec/spec/runner/formatter/html_formatted-1.8.6.html +8 -8
  125. data/spec/spec/runner/formatter/html_formatted-1.8.7.html +38 -26
  126. data/spec/spec/runner/formatter/html_formatted-1.9.1.html +61 -53
  127. data/spec/spec/runner/formatter/html_formatter_spec.rb +100 -48
  128. data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +20 -34
  129. data/spec/spec/runner/formatter/profile_formatter_spec.rb +1 -1
  130. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +8 -6
  131. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +6 -6
  132. data/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +20 -20
  133. data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +38 -26
  134. data/spec/spec/runner/formatter/{spec_mate_formatter_spec.rb → text_mate_formatter_spec.rb} +10 -8
  135. data/spec/spec/runner/heckle_runner_spec.rb +1 -1
  136. data/spec/spec/runner/option_parser_spec.rb +15 -13
  137. data/spec/spec/runner/options_spec.rb +34 -0
  138. data/spec/spec/runner/reporter_spec.rb +65 -61
  139. data/spec/spec/runner/spec_drb.opts +1 -0
  140. data/spec/spec/runner_spec.rb +7 -5
  141. data/spec/spec_helper.rb +23 -0
  142. metadata +25 -76
  143. data/examples/passing/legacy_spec.rb +0 -11
  144. data/features/support/helpers/story_helper.rb +0 -13
  145. data/lib/spec/expectations/extensions/string_and_symbol.rb +0 -17
  146. data/resources/spec/spec_with_flexmock.rb +0 -19
  147. data/spec/spec/spec_spec.rb +0 -21
@@ -4,23 +4,18 @@ module Spec
4
4
  module ExampleGroupMethods
5
5
  class << self
6
6
  attr_accessor :matcher_class
7
-
8
- def description_text(*args)
9
- args.inject("") do |description, arg|
10
- description << " " unless (description == "" || arg.to_s =~ /^(\s|\.|#)/)
11
- description << arg.to_s
12
- end
13
- end
14
-
15
- def example_group_creation_listeners
16
- @example_group_creation_listeners ||= []
17
- end
18
7
  end
19
8
 
20
9
  include Spec::Example::BeforeAndAfterHooks
10
+ include Spec::Example::Subject::ExampleGroupMethods
11
+ include Spec::Example::PredicateMatchers
21
12
 
22
- attr_reader :description_options, :spec_path
23
- alias :options :description_options
13
+ attr_reader :options, :spec_path
14
+
15
+ def inherited(klass) # :nodoc:
16
+ super
17
+ ExampleGroupFactory.register_example_group(klass)
18
+ end
24
19
 
25
20
  # Provides the backtrace up to where this example_group was declared.
26
21
  def backtrace
@@ -36,21 +31,6 @@ WARNING
36
31
  backtrace
37
32
  end
38
33
 
39
- def description_args
40
- @description_args ||= []
41
- end
42
-
43
- def inherited(klass)
44
- super
45
- register_example_group(klass)
46
- end
47
-
48
- def register_example_group(klass)
49
- ExampleGroupMethods.example_group_creation_listeners.each do |l|
50
- l.register_example_group(klass)
51
- end
52
- end
53
-
54
34
  # Makes the describe/it syntax available from a class. For example:
55
35
  #
56
36
  # class StackSpec < Spec::ExampleGroup
@@ -70,9 +50,9 @@ WARNING
70
50
  Spec::Example::add_spec_path_to(args)
71
51
  options = args.last
72
52
  if options[:shared]
73
- create_shared_example_group(*args, &example_group_block)
53
+ ExampleGroupFactory.create_shared_example_group(*args, &example_group_block)
74
54
  else
75
- create_example_group_subclass(*args, &example_group_block)
55
+ subclass(*args, &example_group_block)
76
56
  end
77
57
  else
78
58
  set_description(*args)
@@ -80,26 +60,6 @@ WARNING
80
60
  end
81
61
  alias :context :describe
82
62
 
83
- def create_shared_example_group(*args, &example_group_block) # :nodoc:
84
- SharedExampleGroup.register(*args, &example_group_block)
85
- end
86
-
87
- # Creates a new subclass of self, with a name "under" our own name.
88
- # Example:
89
- #
90
- # x = Foo::Bar.subclass('Zap'){}
91
- # x.name # => Foo::Bar::Zap_1
92
- # x.superclass.name # => Foo::Bar
93
- def create_example_group_subclass(*args, &example_group_block) # :nodoc:
94
- @class_count ||= 0
95
- @class_count += 1
96
- klass = const_set("Subclass_#{@class_count}", Class.new(self))
97
- klass.set_description(*args)
98
- example_group_block = ExampleGroupFactory.include_constants_in(args.last[:scope], &example_group_block)
99
- klass.module_eval(&example_group_block)
100
- klass
101
- end
102
-
103
63
  # Use this to pull in examples from shared example groups.
104
64
  def it_should_behave_like(*shared_example_groups)
105
65
  shared_example_groups.each do |group|
@@ -107,44 +67,13 @@ WARNING
107
67
  end
108
68
  end
109
69
 
110
- # :call-seq:
111
- # predicate_matchers[matcher_name] = method_on_object
112
- # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
113
- #
114
- # Dynamically generates a custom matcher that will match
115
- # a predicate on your class. RSpec provides a couple of these
116
- # out of the box:
117
- #
118
- # exist (for state expectations)
119
- # File.should exist("path/to/file")
120
- #
121
- # an_instance_of (for mock argument matchers)
122
- # mock.should_receive(:message).with(an_instance_of(String))
123
- #
124
- # == Examples
125
- #
126
- # class Fish
127
- # def can_swim?
128
- # true
129
- # end
130
- # end
131
- #
132
- # describe Fish do
133
- # predicate_matchers[:swim] = :can_swim?
134
- # it "should swim" do
135
- # Fish.new.should swim
136
- # end
137
- # end
138
- def predicate_matchers
139
- @predicate_matchers ||= {}
140
- end
141
-
142
70
  # Creates an instance of the current example group class and adds it to
143
71
  # a collection of examples of the current example group.
144
- def example(description=nil, options={}, &implementation)
145
- e = new(description, options, &implementation)
146
- example_objects << e
147
- e
72
+ def example(description=nil, options={}, backtrace=nil, &implementation)
73
+ example_description = ExampleDescription.new(description, options, backtrace || caller(0)[1])
74
+ example_descriptions << example_description
75
+ example_implementations[example_description] = implementation
76
+ example_description
148
77
  end
149
78
 
150
79
  alias_method :it, :example
@@ -157,105 +86,101 @@ WARNING
157
86
 
158
87
  alias_method :xit, :xexample
159
88
  alias_method :xspecify, :xexample
160
-
89
+
161
90
  def run(run_options)
162
91
  examples = examples_to_run(run_options)
163
- run_options.reporter.add_example_group(self) unless examples.empty?
92
+ notify(run_options.reporter) unless examples.empty?
164
93
  return true if examples.empty?
165
94
  return dry_run(examples, run_options) if run_options.dry_run?
166
95
 
167
- plugin_mock_framework(run_options)
168
- define_methods_from_predicate_matchers(run_options)
96
+ define_methods_from_predicate_matchers
169
97
 
170
98
  success, before_all_instance_variables = run_before_all(run_options)
171
99
  success, after_all_instance_variables = execute_examples(success, before_all_instance_variables, examples, run_options)
172
100
  success = run_after_all(success, after_all_instance_variables, run_options)
173
101
  end
174
102
 
103
+ def set_description(*args)
104
+ @description_args, @options = Spec::Example.args_and_options(*args)
105
+ @backtrace = caller(1)
106
+ @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
107
+ self
108
+ end
109
+
110
+ def notify(listener) # :nodoc:
111
+ listener.add_example_group(self)
112
+ end
113
+
175
114
  def description
176
- result = ExampleGroupMethods.description_text(*description_parts)
177
- (result.nil? || result == "") ? to_s : result
115
+ @description ||= build_description_from(*description_parts) || to_s
178
116
  end
179
117
 
180
118
  def described_type
181
- description_parts.reverse.find {|part| part.is_a?(Module)}
119
+ @described_type ||= description_parts.reverse.find {|part| part.is_a?(Module)}
182
120
  end
183
121
 
184
- # Defines an explicit subject for an example group which can then be the
185
- # implicit receiver (through delegation) of calls to +should+.
186
- #
187
- # == Examples
188
- #
189
- # describe CheckingAccount, "with $50" do
190
- # subject { CheckingAccount.new(:amount => 50, :currency => :USD) }
191
- # it { should have_a_balance_of(50, :USD)}
192
- # it { should_not be_overdrawn}
193
- # end
194
- #
195
- # See +ExampleMethods#should+ for more information about this approach.
196
- def subject(&block)
197
- @_subject_block = block
122
+ def described_class
123
+ @described_class ||= Class === described_type ? described_type : nil
198
124
  end
199
125
 
200
- def subject_block
201
- @_subject_block || lambda {nil}
126
+ def description_args
127
+ @description_args ||= []
202
128
  end
203
129
 
204
130
  def description_parts #:nodoc:
205
- example_group_hierarchy.inject([]) do |parts, example_group_class|
131
+ @description_parts ||= example_group_hierarchy.inject([]) do |parts, example_group_class|
206
132
  [parts << example_group_class.description_args].flatten
207
133
  end
208
134
  end
209
-
210
- def set_description(*args)
211
- args, options = Spec::Example.args_and_options(*args)
212
- @description_args = args
213
- @description_options = options
214
- @description_text = ExampleGroupMethods.description_text(*args)
215
- @backtrace = caller(1)
216
- @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
217
- self
135
+
136
+ def example_descriptions # :nodoc:
137
+ @example_descriptions ||= []
218
138
  end
219
139
 
140
+ def example_implementations # :nodoc:
141
+ @example_implementations ||= {}
142
+ end
143
+
220
144
  def examples(run_options=nil) #:nodoc:
221
- examples = example_objects.dup
222
- add_method_examples(examples)
223
- (run_options && run_options.reverse) ? examples.reverse : examples
145
+ (run_options && run_options.reverse) ? example_descriptions.reverse : example_descriptions
224
146
  end
225
147
 
226
148
  def number_of_examples #:nodoc:
227
- examples.length
228
- end
229
-
230
- # Only used from RSpec's own examples
231
- def reset # :nodoc:
232
- @before_all_parts = nil
233
- @after_all_parts = nil
234
- @before_each_parts = nil
235
- @after_each_parts = nil
149
+ example_descriptions.length
236
150
  end
237
151
 
238
- def run_before_each(example)
239
- example.eval_each_fail_fast(all_before_each_parts)
152
+ def example_group_hierarchy
153
+ @example_group_hierarchy ||= ExampleGroupHierarchy.new(self)
240
154
  end
241
155
 
242
- def all_before_each_parts
243
- unless @all_before_each_parts
244
- @all_before_each_parts = []
245
- example_group_hierarchy.each do |example_group_class|
246
- @all_before_each_parts += example_group_class.before_each_parts
156
+ def filtered_description(filter)
157
+ build_description_from(
158
+ *nested_descriptions.collect do |description|
159
+ description =~ filter ? $1 : description
247
160
  end
248
- end
249
- @all_before_each_parts
161
+ )
250
162
  end
163
+
164
+ def nested_descriptions
165
+ example_group_hierarchy.nested_descriptions
166
+ end
167
+
168
+ def include_constants_in(mod)
169
+ include mod if (Spec::Ruby.version.to_f >= 1.9) & (Module === mod) & !(Class === mod)
170
+ end
171
+
172
+ private
251
173
 
252
- def run_after_each(example)
253
- example_group_hierarchy.reverse.each do |example_group_class|
254
- example.eval_each_fail_slow(example_group_class.after_each_parts)
255
- end
174
+ def subclass(*args, &example_group_block)
175
+ @class_count ||= 0
176
+ @class_count += 1
177
+ klass = const_set("Subclass_#{@class_count}", Class.new(self))
178
+ klass.set_description(*args)
179
+ klass.include_constants_in(args.last[:scope])
180
+ klass.module_eval(&example_group_block)
181
+ klass
256
182
  end
257
183
 
258
- private
259
184
  def dry_run(examples, run_options)
260
185
  examples.each do |example|
261
186
  run_options.reporter.example_started(example)
@@ -264,14 +189,13 @@ WARNING
264
189
  end
265
190
 
266
191
  def run_before_all(run_options)
192
+ return [true,{}] if example_group_hierarchy.before_all_parts.empty?
267
193
  before_all = new("before(:all)")
268
194
  begin
269
- example_group_hierarchy.each do |example_group_class|
270
- before_all.eval_each_fail_fast(example_group_class.before_all_parts)
271
- end
195
+ example_group_hierarchy.run_before_all(before_all)
272
196
  return [true, before_all.instance_variable_hash]
273
197
  rescue Exception => e
274
- run_options.reporter.failure(before_all, e)
198
+ run_options.reporter.example_failed(ExampleDescription.new("before(:all)"), e)
275
199
  return [false, before_all.instance_variable_hash]
276
200
  end
277
201
  end
@@ -280,29 +204,30 @@ WARNING
280
204
  return [success, instance_variables] unless success
281
205
 
282
206
  after_all_instance_variables = instance_variables
283
- examples.each do |example_group_instance|
207
+
208
+ examples.each do |example|
209
+ example_group_instance = new(example.description,example.options,&example_implementations[example])
284
210
  success &= example_group_instance.execute(run_options, instance_variables)
285
211
  after_all_instance_variables = example_group_instance.instance_variable_hash
286
212
  end
213
+
287
214
  return [success, after_all_instance_variables]
288
215
  end
289
-
216
+
290
217
  def run_after_all(success, instance_variables, run_options)
218
+ return success if example_group_hierarchy.after_all_parts.empty?
291
219
  after_all = new("after(:all)")
292
220
  after_all.set_instance_variables_from_hash(instance_variables)
293
- example_group_hierarchy.reverse.each do |example_group_class|
294
- after_all.eval_each_fail_slow(example_group_class.after_all_parts)
295
- end
221
+ example_group_hierarchy.run_after_all(after_all)
296
222
  return success
297
223
  rescue Exception => e
298
- run_options.reporter.failure(after_all, e)
224
+ run_options.reporter.example_failed(ExampleDescription.new("after(:all)"), e)
299
225
  return false
300
226
  end
301
-
227
+
302
228
  def examples_to_run(run_options)
303
- all_examples = examples(run_options)
304
- return all_examples unless specified_examples?(run_options)
305
- all_examples.reject do |example|
229
+ return example_descriptions unless specified_examples?(run_options)
230
+ example_descriptions.reject do |example|
306
231
  matcher = ExampleGroupMethods.matcher_class.
307
232
  new(description.to_s, example.description)
308
233
  !matcher.matches?(run_options.examples)
@@ -310,68 +235,21 @@ WARNING
310
235
  end
311
236
 
312
237
  def specified_examples?(run_options)
313
- run_options.examples && !run_options.examples.empty?
238
+ !run_options.examples.empty?
314
239
  end
315
240
 
316
- def example_objects
317
- @example_objects ||= []
318
- end
319
-
320
- class ExampleGroupHierarchy < Array
321
- def initialize(example_group_class)
322
- current_class = example_group_class
323
- while current_class.kind_of?(ExampleGroupMethods)
324
- unshift(current_class)
325
- break unless current_class.respond_to? :superclass
326
- current_class = current_class.superclass
327
- end
328
- end
241
+ def method_added(name) # :nodoc:
242
+ example(name.to_s, {}, caller(0)[1]) {__send__ name.to_s} if example_method?(name.to_s)
329
243
  end
330
244
 
331
- def example_group_hierarchy
332
- @example_group_hierarchy ||= ExampleGroupHierarchy.new(self)
333
- end
334
-
335
- def plugin_mock_framework(run_options)
336
- case mock_framework = run_options.mock_framework
337
- when Module
338
- include mock_framework
339
- else
340
- require mock_framework
341
- include Spec::Adapters::MockFramework
342
- end
343
- end
344
-
345
- def define_methods_from_predicate_matchers(run_options) # :nodoc:
346
- all_predicate_matchers = predicate_matchers.merge(
347
- run_options.predicate_matchers
348
- )
349
- all_predicate_matchers.each_pair do |matcher_method, method_on_object|
350
- define_method matcher_method do |*args|
351
- eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
352
- end
353
- end
354
- end
355
-
356
- def add_method_examples(examples)
357
- instance_methods.each do |method_name|
358
- if example_method?(method_name)
359
- examples << new(method_name) do
360
- __send__(method_name)
361
- end
362
- end
363
- end
364
- end
365
-
366
245
  def example_method?(method_name)
367
246
  should_method?(method_name)
368
247
  end
369
248
 
370
249
  def should_method?(method_name)
371
250
  !(method_name =~ /^should(_not)?$/) &&
372
- method_name =~ /^should/ && (
373
- [-1,0].include?(instance_method(method_name).arity)
374
- )
251
+ method_name =~ /^should/ &&
252
+ instance_method(method_name).arity < 1
375
253
  end
376
254
 
377
255
  def include_shared_example_group(shared_example_group)
@@ -387,6 +265,13 @@ WARNING
387
265
  end
388
266
  end
389
267
 
268
+ def build_description_from(*args)
269
+ text = args.inject("") do |description, arg|
270
+ description << " " unless (description == "" || arg.to_s =~ /^(\s|\.|#)/)
271
+ description << arg.to_s
272
+ end
273
+ text == "" ? nil : text
274
+ end
390
275
  end
391
276
 
392
277
  end
@@ -2,54 +2,41 @@ module Spec
2
2
  module Example
3
3
  module ExampleMethods
4
4
 
5
- extend ModuleReopeningFix
6
-
7
- def subject # :nodoc: this is somewhat experimental
8
- @subject ||= ( instance_variable_get(subject_variable_name) ||
9
- instance_eval(&self.class.subject_block) ||
10
- (described_class ? described_class.new : nil) )
11
- end
12
-
13
- # When +should+ is called with no explicit receiver, the call is
14
- # delegated to the *subject* of the example group. This could be either
15
- # an explicit subject generated by calling the block passed to
16
- # +ExampleGroupMethods#subject+, or, if the group is describing a class,
17
- # an implicitly generated instance of that class.
18
- def should(matcher=nil)
19
- if matcher
20
- subject.should(matcher)
21
- else
22
- subject.should
23
- end
24
- end
25
-
26
- # Just like +should+, +should_not+ delegates to the subject (implicit or
27
- # explicit) of the example group.
28
- def should_not(matcher)
29
- subject.should_not(matcher)
30
- end
5
+ extend Spec::Example::ModuleReopeningFix
6
+ include Spec::Example::Subject::ExampleMethods
31
7
 
32
8
  def violated(message="")
33
9
  raise Spec::Expectations::ExpectationNotMetError.new(message)
34
10
  end
35
11
 
12
+ # Declared description for this example:
13
+ #
14
+ # describe Account do
15
+ # it "should start with a balance of 0" do
16
+ # ...
17
+ #
18
+ # description
19
+ # => "should start with a balance of 0"
36
20
  def description
37
21
  @_defined_description || ::Spec::Matchers.generated_description || "NO NAME"
38
22
  end
39
23
 
40
- def options
24
+ def options # :nodoc:
41
25
  @_options
42
26
  end
43
27
 
44
- def execute(options, instance_variables)
45
- options.reporter.example_started(self)
28
+ def execute(run_options, instance_variables) # :nodoc:
29
+ # FIXME - there is no reason to have example_started pass a name
30
+ # - in fact, it would introduce bugs in cases where no docstring
31
+ # is passed to it()
32
+ run_options.reporter.example_started("")
46
33
  set_instance_variables_from_hash(instance_variables)
47
34
 
48
35
  execution_error = nil
49
- Timeout.timeout(options.timeout) do
36
+ Timeout.timeout(run_options.timeout) do
50
37
  begin
51
38
  before_each_example
52
- eval_block
39
+ instance_eval(&@_implementation)
53
40
  rescue Exception => e
54
41
  execution_error ||= e
55
42
  end
@@ -60,28 +47,19 @@ module Spec
60
47
  end
61
48
  end
62
49
 
63
- options.reporter.example_finished(self, execution_error)
50
+ run_options.reporter.example_finished(ExampleDescription.new(description, options), execution_error)
64
51
  success = execution_error.nil? || ExamplePendingError === execution_error
65
52
  end
66
53
 
67
- def instance_variable_hash # :nodoc:
68
- instance_variables.inject({}) do |variable_hash, variable_name|
69
- variable_hash[variable_name] = instance_variable_get(variable_name)
70
- variable_hash
71
- end
54
+ def eval_each_fail_fast(blocks) # :nodoc:
55
+ blocks.each {|block| instance_eval(&block)}
72
56
  end
73
57
 
74
- def eval_each_fail_fast(examples) # :nodoc:
75
- examples.each do |example|
76
- instance_eval(&example)
77
- end
78
- end
79
-
80
- def eval_each_fail_slow(examples) # :nodoc:
58
+ def eval_each_fail_slow(blocks) # :nodoc:
81
59
  first_exception = nil
82
- examples.each do |example|
60
+ blocks.each do |block|
83
61
  begin
84
- instance_eval(&example)
62
+ instance_eval(&block)
85
63
  rescue Exception => e
86
64
  first_exception ||= e
87
65
  end
@@ -89,31 +67,22 @@ module Spec
89
67
  raise first_exception if first_exception
90
68
  end
91
69
 
92
- # Concats the class description with the example description.
93
- #
94
- # describe Account do
95
- # it "should start with a balance of 0" do
96
- # ...
97
- #
98
- # full_description
99
- # => "Account should start with a balance of 0"
100
- def full_description
101
- "#{self.class.description} #{self.description}"
70
+ def instance_variable_hash # :nodoc:
71
+ instance_variables.inject({}) do |variable_hash, variable_name|
72
+ variable_hash[variable_name] = instance_variable_get(variable_name)
73
+ variable_hash
74
+ end
102
75
  end
103
-
76
+
104
77
  def set_instance_variables_from_hash(ivars) # :nodoc:
105
78
  ivars.each do |variable_name, value|
106
79
  # Ruby 1.9 requires variable.to_s on the next line
107
- unless ['@_implementation', '@_defined_description', '@_matcher_description', '@method_name'].include?(variable_name.to_s)
80
+ unless ['@_defined_description', '@_options', '@_implementation', '@method_name'].include?(variable_name.to_s)
108
81
  instance_variable_set variable_name, value
109
82
  end
110
83
  end
111
84
  end
112
85
 
113
- def eval_block # :nodoc:
114
- instance_eval(&@_implementation)
115
- end
116
-
117
86
  # Provides the backtrace up to where this example was declared.
118
87
  def backtrace
119
88
  @_backtrace
@@ -127,42 +96,54 @@ from a future version. Please use ExampleMethods#backtrace instead.
127
96
  WARNING
128
97
  backtrace
129
98
  end
99
+
100
+ # Run all the before(:each) blocks for this example
101
+ def run_before_each
102
+ example_group_hierarchy.run_before_each(self)
103
+ end
104
+
105
+ # Run all the after(:each) blocks for this example
106
+ def run_after_each
107
+ example_group_hierarchy.run_after_each(self)
108
+ end
130
109
 
131
- private
110
+ def initialize(description, options={}, &implementation)
111
+ @_options = options
112
+ @_defined_description = description
113
+ @_implementation = implementation || pending_implementation
114
+ @_backtrace = caller
115
+ end
116
+
117
+ private
118
+
132
119
  include Matchers
133
120
  include Pending
134
121
 
135
- def before_each_example
122
+ def before_each_example # :nodoc:
136
123
  setup_mocks_for_rspec
137
- self.class.run_before_each(self)
124
+ run_before_each
138
125
  end
139
126
 
140
- def after_each_example
141
- self.class.run_after_each(self)
127
+ def after_each_example # :nodoc:
128
+ run_after_each
142
129
  verify_mocks_for_rspec
143
130
  ensure
144
131
  teardown_mocks_for_rspec
145
132
  end
146
133
 
147
- def subject_variable_name
148
- '@' << (described_class ? underscore(described_class.name) : '__this_does_not_exist')
134
+ def described_class # :nodoc:
135
+ self.class.described_class
149
136
  end
150
-
151
- def described_class
152
- Class === described_type ? described_type : nil
137
+
138
+ def example_group_hierarchy
139
+ self.class.example_group_hierarchy
153
140
  end
154
141
 
155
- def described_type
156
- self.class.described_type
142
+ def pending_implementation
143
+ error = Spec::Example::NotYetImplementedError.new(caller)
144
+ lambda { raise(error) }
157
145
  end
158
146
 
159
- def underscore(camel_cased_word)
160
- camel_cased_word.to_s.gsub(/::/, '_').
161
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
162
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
163
- tr("-", "_").
164
- downcase
165
- end
166
147
  end
167
148
  end
168
149
  end