Updated to latest rspec
[gitorious:georgyos-clone.git] / vendor / plugins / rspec / lib / spec / example / example_group_methods.rb
1 module Spec
2   module Example
3
4     module ExampleGroupMethods
5       class << self
6         def description_text(*args)
7           args.inject("") do |result, arg|
8             result << " " unless (result == "" || arg.to_s =~ /^(\s|\.|#)/)
9             result << arg.to_s
10           end
11         end
12       end
13
14       attr_reader :description_text, :description_args, :description_options, :spec_path, :registration_binding_block
15
16       def inherited(klass)
17         super
18         klass.register {}
19         Spec::Runner.register_at_exit_hook
20       end
21       
22       # Makes the describe/it syntax available from a class. For example:
23       #
24       #   class StackSpec < Spec::ExampleGroup
25       #     describe Stack, "with no elements"
26       #
27       #     before
28       #       @stack = Stack.new
29       #     end
30       #
31       #     it "should raise on pop" do
32       #       lambda{ @stack.pop }.should raise_error
33       #     end
34       #   end
35       #
36       def describe(*args, &example_group_block)
37         args << {} unless Hash === args.last
38         if example_group_block
39           params = args.last
40           params[:spec_path] = eval("caller(0)[1]", example_group_block) unless params[:spec_path]
41           if params[:shared]
42             SharedExampleGroup.new(*args, &example_group_block)
43           else
44             self.subclass("Subclass") do
45               describe(*args)
46               module_eval(&example_group_block)
47             end
48           end
49         else
50           set_description(*args)
51           before_eval
52           self
53         end
54       end
55       alias :context :describe
56
57       # Use this to pull in examples from shared example groups.
58       # See Spec::Runner for information about shared example groups.
59       def it_should_behave_like(shared_example_group)
60         case shared_example_group
61         when SharedExampleGroup
62           include shared_example_group
63         else
64           example_group = SharedExampleGroup.find_shared_example_group(shared_example_group)
65           unless example_group
66             raise RuntimeError.new("Shared Example Group '#{shared_example_group}' can not be found")
67           end
68           include(example_group)
69         end
70       end
71
72       # :call-seq:
73       #   predicate_matchers[matcher_name] = method_on_object
74       #   predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
75       #
76       # Dynamically generates a custom matcher that will match
77       # a predicate on your class. RSpec provides a couple of these
78       # out of the box:
79       #
80       #   exist (or state expectations)
81       #     File.should exist("path/to/file")
82       #
83       #   an_instance_of (for mock argument constraints)
84       #     mock.should_receive(:message).with(an_instance_of(String))
85       #
86       # == Examples
87       #
88       #   class Fish
89       #     def can_swim?
90       #       true
91       #     end
92       #   end
93       #
94       #   describe Fish do
95       #     predicate_matchers[:swim] = :can_swim?
96       #     it "should swim" do
97       #       Fish.new.should swim
98       #     end
99       #   end
100       def predicate_matchers
101         @predicate_matchers ||= {:an_instance_of => :is_a?}
102       end
103
104       # Creates an instance of Spec::Example::Example and adds
105       # it to a collection of examples of the current example group.
106       def it(description=nil, &implementation)
107         e = new(description, &implementation)
108         example_objects << e
109         e
110       end
111
112       alias_method :specify, :it
113
114       # Use this to temporarily disable an example.
115       def xit(description=nil, opts={}, &block)
116         Kernel.warn("Example disabled: #{description}")
117       end
118       alias_method :xspecify, :xit
119
120       def run
121         examples = examples_to_run
122         reporter.add_example_group(self)
123         return true if examples.empty?
124         return dry_run(examples) if dry_run?
125
126         plugin_mock_framework
127         define_methods_from_predicate_matchers
128
129         success, before_all_instance_variables = run_before_all
130         success, after_all_instance_variables  = execute_examples(success, before_all_instance_variables, examples)
131         success                                = run_after_all(success, after_all_instance_variables)
132       end
133
134       def description
135         result = ExampleGroupMethods.description_text(*description_parts)
136         if result.nil? || result == ""
137           return to_s
138         else
139           result
140         end
141       end
142
143       def described_type
144         description_parts.find {|part| part.is_a?(Module)}
145       end
146
147       def description_parts #:nodoc:
148         parts = []
149         execute_in_class_hierarchy do |example_group|
150           parts << example_group.description_args
151         end
152         parts.flatten.compact
153       end
154
155       def set_description(*args)
156         args, options = args_and_options(*args)
157         @description_args = args
158         @description_options = options
159         @description_text = ExampleGroupMethods.description_text(*args)
160         @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
161         if described_type.class == Module
162           @described_module = described_type
163         end
164         self
165       end
166       
167       attr_reader :described_module
168
169       def examples #:nodoc:
170         examples = example_objects.dup
171         add_method_examples(examples)
172         rspec_options.reverse ? examples.reverse : examples
173       end
174
175       def number_of_examples #:nodoc:
176         examples.length
177       end
178
179       # Registers a block to be executed before each example.
180       # This method prepends +block+ to existing before blocks.
181       def prepend_before(*args, &block)
182         scope, options = scope_and_options(*args)
183         parts = before_parts_from_scope(scope)
184         parts.unshift(block)
185       end
186
187       # Registers a block to be executed before each example.
188       # This method appends +block+ to existing before blocks.
189       def append_before(*args, &block)
190         scope, options = scope_and_options(*args)
191         parts = before_parts_from_scope(scope)
192         parts << block
193       end
194       alias_method :before, :append_before
195
196       # Registers a block to be executed after each example.
197       # This method prepends +block+ to existing after blocks.
198       def prepend_after(*args, &block)
199         scope, options = scope_and_options(*args)
200         parts = after_parts_from_scope(scope)
201         parts.unshift(block)
202       end
203       alias_method :after, :prepend_after
204
205       # Registers a block to be executed after each example.
206       # This method appends +block+ to existing after blocks.
207       def append_after(*args, &block)
208         scope, options = scope_and_options(*args)
209         parts = after_parts_from_scope(scope)
210         parts << block
211       end
212
213       def remove_after(scope, &block)
214         after_each_parts.delete(block)
215       end
216
217       # Deprecated. Use before(:each)
218       def setup(&block)
219         before(:each, &block)
220       end
221
222       # Deprecated. Use after(:each)
223       def teardown(&block)
224         after(:each, &block)
225       end
226
227       def before_all_parts # :nodoc:
228         @before_all_parts ||= []
229       end
230
231       def after_all_parts # :nodoc:
232         @after_all_parts ||= []
233       end
234
235       def before_each_parts # :nodoc:
236         @before_each_parts ||= []
237       end
238
239       def after_each_parts # :nodoc:
240         @after_each_parts ||= []
241       end
242
243       # Only used from RSpec's own examples
244       def reset # :nodoc:
245         @before_all_parts = nil
246         @after_all_parts = nil
247         @before_each_parts = nil
248         @after_each_parts = nil
249       end
250
251       def register(&registration_binding_block)
252         @registration_binding_block = registration_binding_block
253         rspec_options.add_example_group self
254       end
255
256       def unregister #:nodoc:
257         rspec_options.remove_example_group self
258       end
259
260       def registration_backtrace
261         eval("caller", registration_binding_block.binding)
262       end
263
264       def run_before_each(example)
265         execute_in_class_hierarchy do |example_group|
266           example.eval_each_fail_fast(example_group.before_each_parts)
267         end
268       end
269
270       def run_after_each(example)
271         execute_in_class_hierarchy(:superclass_first) do |example_group|
272           example.eval_each_fail_slow(example_group.after_each_parts)
273         end
274       end
275
276     private
277       def dry_run(examples)
278         examples.each do |example|
279           rspec_options.reporter.example_started(example)
280           rspec_options.reporter.example_finished(example)
281         end
282         return true
283       end
284
285       def run_before_all
286         before_all = new("before(:all)")
287         begin
288           execute_in_class_hierarchy do |example_group|
289             before_all.eval_each_fail_fast(example_group.before_all_parts)
290           end
291           return [true, before_all.instance_variable_hash]
292         rescue Exception => e
293           reporter.failure(before_all, e)
294           return [false, before_all.instance_variable_hash]
295         end
296       end
297
298       def execute_examples(success, instance_variables, examples)
299         return [success, instance_variables] unless success
300
301         after_all_instance_variables = instance_variables
302         examples.each do |example_group_instance|
303           success &= example_group_instance.execute(rspec_options, instance_variables)
304           after_all_instance_variables = example_group_instance.instance_variable_hash
305         end
306         return [success, after_all_instance_variables]
307       end
308
309       def run_after_all(success, instance_variables)
310         after_all = new("after(:all)")
311         after_all.set_instance_variables_from_hash(instance_variables)
312         execute_in_class_hierarchy(:superclass_first) do |example_group|
313           after_all.eval_each_fail_slow(example_group.after_all_parts)
314         end
315         return success
316       rescue Exception => e
317         reporter.failure(after_all, e)
318         return false
319       end
320
321       def examples_to_run
322         all_examples = examples
323         return all_examples unless specified_examples?
324         all_examples.reject do |example|
325           matcher = ExampleMatcher.new(description.to_s, example.description)
326           !matcher.matches?(specified_examples)
327         end
328       end
329
330       def specified_examples?
331         specified_examples && !specified_examples.empty?
332       end
333
334       def specified_examples
335         rspec_options.examples
336       end
337
338       def reporter
339         rspec_options.reporter
340       end
341
342       def dry_run?
343         rspec_options.dry_run
344       end
345
346       def example_objects
347         @example_objects ||= []
348       end
349
350       def execute_in_class_hierarchy(superclass_last=false)
351         classes = []
352         current_class = self
353         while is_example_group?(current_class)
354           superclass_last ? classes << current_class : classes.unshift(current_class)
355           current_class = current_class.superclass
356         end
357         superclass_last ? classes << ExampleMethods : classes.unshift(ExampleMethods)
358
359         classes.each do |example_group|
360           yield example_group
361         end
362       end
363
364       def is_example_group?(klass)
365         Module === klass && klass.kind_of?(ExampleGroupMethods)
366       end
367
368       def plugin_mock_framework
369         case mock_framework = Spec::Runner.configuration.mock_framework
370         when Module
371           include mock_framework
372         else
373           require Spec::Runner.configuration.mock_framework
374           include Spec::Plugins::MockFramework
375         end
376       end
377
378       def define_methods_from_predicate_matchers # :nodoc:
379         all_predicate_matchers = predicate_matchers.merge(
380           Spec::Runner.configuration.predicate_matchers
381         )
382         all_predicate_matchers.each_pair do |matcher_method, method_on_object|
383           define_method matcher_method do |*args|
384             eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
385           end
386         end
387       end
388
389       def scope_and_options(*args)
390         args, options = args_and_options(*args)
391         scope = (args[0] || :each), options
392       end
393
394       def before_parts_from_scope(scope)
395         case scope
396         when :each; before_each_parts
397         when :all; before_all_parts
398         when :suite; rspec_options.before_suite_parts
399         end
400       end
401
402       def after_parts_from_scope(scope)
403         case scope
404         when :each; after_each_parts
405         when :all; after_all_parts
406         when :suite; rspec_options.after_suite_parts
407         end
408       end
409
410       def before_eval
411       end
412
413       def add_method_examples(examples)
414         instance_methods.sort.each do |method_name|
415           if example_method?(method_name)
416             examples << new(method_name) do
417               __send__(method_name)
418             end
419           end
420         end
421       end
422
423       def example_method?(method_name)
424         should_method?(method_name)
425       end
426
427       def should_method?(method_name)
428         !(method_name =~ /^should(_not)?$/) &&
429         method_name =~ /^should/ && (
430           instance_method(method_name).arity == 0 ||
431           instance_method(method_name).arity == -1
432         )
433       end
434     end
435
436   end
437 end