changelog shortlog tags changeset manifest revisions annotate raw

vendor/plugins/rspec/lib/spec/example/example_group_methods.rb

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