dchelimsky-rspec 1.1.12 → 1.1.99.1

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