4 module ExampleGroupMethods
6 def description_text(*args)
7 args.inject("") do |result, arg|
8 result << " " unless (result == "" || arg.to_s =~ /^(\s|\.|#)/)
14 attr_reader :description_text, :description_args, :description_options, :spec_path
21 # Makes the describe/it syntax available from a class. For example:
23 # class StackSpec < Spec::ExampleGroup
24 # describe Stack, "with no elements"
30 # it "should raise on pop" do
31 # lambda{ @stack.pop }.should raise_error
35 def describe(*args, &example_group_block)
36 if example_group_block
37 self.subclass("Subclass") do
39 module_eval(&example_group_block)
42 set_description(*args)
48 # Use this to pull in examples from shared example groups.
49 # See Spec::Runner for information about shared example groups.
50 def it_should_behave_like(shared_example_group)
51 case shared_example_group
52 when SharedExampleGroup
53 include shared_example_group
55 example_group = SharedExampleGroup.find_shared_example_group(shared_example_group)
57 raise RuntimeError.new("Shared Example Group '#{shared_example_group}' can not be found")
59 include(example_group)
64 # predicate_matchers[matcher_name] = method_on_object
65 # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
67 # Dynamically generates a custom matcher that will match
68 # a predicate on your class. RSpec provides a couple of these
71 # exist (or state expectations)
72 # File.should exist("path/to/file")
74 # an_instance_of (for mock argument constraints)
75 # mock.should_receive(:message).with(an_instance_of(String))
86 # predicate_matchers[:swim] = :can_swim?
88 # Fish.new.should swim
91 def predicate_matchers
92 @predicate_matchers ||= {:an_instance_of => :is_a?}
95 # Creates an instance of Spec::Example::Example and adds
96 # it to a collection of examples of the current example group.
97 def it(description=nil, &implementation)
98 e = new(description, &implementation)
103 alias_method :specify, :it
105 # Use this to temporarily disable an example.
106 def xit(description=nil, opts={}, &block)
107 Kernel.warn("Example disabled: #{description}")
111 examples = examples_to_run
112 return true if examples.empty?
113 reporter.add_example_group(self)
114 return dry_run(examples) if dry_run?
116 plugin_mock_framework
117 define_methods_from_predicate_matchers
119 success, before_all_instance_variables = run_before_all
120 success, after_all_instance_variables = execute_examples(success, before_all_instance_variables, examples)
121 success = run_after_all(success, after_all_instance_variables)
125 result = ExampleGroupMethods.description_text(*description_parts)
126 if result.nil? || result == ""
134 description_parts.find {|part| part.is_a?(Module)}
137 def description_parts #:nodoc:
139 execute_in_class_hierarchy do |example_group|
140 parts << example_group.description_args
142 parts.flatten.compact
145 def set_description(*args)
146 args, options = args_and_options(*args)
147 @description_args = args
148 @description_options = options
149 @description_text = ExampleGroupMethods.description_text(*args)
150 @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
151 if described_type.class == Module
152 include described_type
157 def examples #:nodoc:
158 examples = example_objects.dup
159 add_method_examples(examples)
160 rspec_options.reverse ? examples.reverse : examples
163 def number_of_examples #:nodoc:
167 # Registers a block to be executed before each example.
168 # This method prepends +block+ to existing before blocks.
169 def prepend_before(*args, &block)
170 scope, options = scope_and_options(*args)
171 parts = before_parts_from_scope(scope)
175 # Registers a block to be executed before each example.
176 # This method appends +block+ to existing before blocks.
177 def append_before(*args, &block)
178 scope, options = scope_and_options(*args)
179 parts = before_parts_from_scope(scope)
182 alias_method :before, :append_before
184 # Registers a block to be executed after each example.
185 # This method prepends +block+ to existing after blocks.
186 def prepend_after(*args, &block)
187 scope, options = scope_and_options(*args)
188 parts = after_parts_from_scope(scope)
191 alias_method :after, :prepend_after
193 # Registers a block to be executed after each example.
194 # This method appends +block+ to existing after blocks.
195 def append_after(*args, &block)
196 scope, options = scope_and_options(*args)
197 parts = after_parts_from_scope(scope)
201 def remove_after(scope, &block)
202 after_each_parts.delete(block)
205 # Deprecated. Use before(:each)
207 before(:each, &block)
210 # Deprecated. Use after(:each)
215 def before_all_parts # :nodoc:
216 @before_all_parts ||= []
219 def after_all_parts # :nodoc:
220 @after_all_parts ||= []
223 def before_each_parts # :nodoc:
224 @before_each_parts ||= []
227 def after_each_parts # :nodoc:
228 @after_each_parts ||= []
231 # Only used from RSpec's own examples
233 @before_all_parts = nil
234 @after_all_parts = nil
235 @before_each_parts = nil
236 @after_each_parts = nil
240 rspec_options.add_example_group self
243 def unregister #:nodoc:
244 rspec_options.remove_example_group self
247 def run_before_each(example)
248 execute_in_class_hierarchy do |example_group|
249 example.eval_each_fail_fast(example_group.before_each_parts)
253 def run_after_each(example)
254 execute_in_class_hierarchy(:superclass_first) do |example_group|
255 example.eval_each_fail_slow(example_group.after_each_parts)
260 def dry_run(examples)
261 examples.each do |example|
262 rspec_options.reporter.example_started(example)
263 rspec_options.reporter.example_finished(example)
269 before_all = new("before(:all)")
271 execute_in_class_hierarchy do |example_group|
272 before_all.eval_each_fail_fast(example_group.before_all_parts)
274 return [true, before_all.instance_variable_hash]
275 rescue Exception => e
276 reporter.failure(before_all, e)
277 return [false, before_all.instance_variable_hash]
281 def execute_examples(success, instance_variables, examples)
282 return [success, instance_variables] unless success
284 after_all_instance_variables = instance_variables
285 examples.each do |example_group_instance|
286 success &= example_group_instance.execute(rspec_options, instance_variables)
287 after_all_instance_variables = example_group_instance.instance_variable_hash
289 return [success, after_all_instance_variables]
292 def run_after_all(success, instance_variables)
293 after_all = new("after(:all)")
294 after_all.set_instance_variables_from_hash(instance_variables)
295 execute_in_class_hierarchy(:superclass_first) do |example_group|
296 after_all.eval_each_fail_slow(example_group.after_all_parts)
299 rescue Exception => e
300 reporter.failure(after_all, e)
305 all_examples = examples
306 return all_examples unless specified_examples?
307 all_examples.reject do |example|
308 matcher = ExampleMatcher.new(description.to_s, example.description)
309 !matcher.matches?(specified_examples)
313 def specified_examples?
314 specified_examples && !specified_examples.empty?
317 def specified_examples
318 rspec_options.examples
322 rspec_options.reporter
326 rspec_options.dry_run
330 @example_objects ||= []
333 def execute_in_class_hierarchy(superclass_last=false)
336 while is_example_group?(current_class)
337 superclass_last ? classes << current_class : classes.unshift(current_class)
338 current_class = current_class.superclass
340 superclass_last ? classes << ExampleMethods : classes.unshift(ExampleMethods)
342 classes.each do |example_group|
347 def is_example_group?(klass)
348 Module === klass && klass.kind_of?(ExampleGroupMethods)
351 def plugin_mock_framework
352 case mock_framework = Spec::Runner.configuration.mock_framework
354 include mock_framework
356 require Spec::Runner.configuration.mock_framework
357 include Spec::Plugins::MockFramework
361 def define_methods_from_predicate_matchers # :nodoc:
362 all_predicate_matchers = predicate_matchers.merge(
363 Spec::Runner.configuration.predicate_matchers
365 all_predicate_matchers.each_pair do |matcher_method, method_on_object|
366 define_method matcher_method do |*args|
367 eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
372 def scope_and_options(*args)
373 args, options = args_and_options(*args)
374 scope = (args[0] || :each), options
377 def before_parts_from_scope(scope)
379 when :each; before_each_parts
380 when :all; before_all_parts
384 def after_parts_from_scope(scope)
386 when :each; after_each_parts
387 when :all; after_all_parts
394 def add_method_examples(examples)
395 instance_methods.sort.each do |method_name|
396 if example_method?(method_name)
397 examples << new(method_name) do
398 __send__(method_name)
404 def example_method?(method_name)
405 should_method?(method_name)
408 def should_method?(method_name)
409 !(method_name =~ /^should(_not)?$/) &&
410 method_name =~ /^should/ && (
411 instance_method(method_name).arity == 0 ||
412 instance_method(method_name).arity == -1