1 require File.dirname(__FILE__) + '/../../spec_helper'
5 describe ExampleGroup do
6 attr_reader :options, :example_group, :result, :reporter
8 @original_rspec_options = $rspec_options
12 @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new)
13 $rspec_options = @options
14 options.formatters << mock("formatter", :null_object => true)
15 options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true)
16 @reporter = FakeReporter.new(@options)
17 options.reporter = reporter
18 @example_group = Class.new(ExampleGroup) do
22 class << example_group
29 $rspec_options = @original_rspec_options
33 describe ExampleGroup, ".describe" do
34 attr_reader :child_example_group
36 @child_example_group = @example_group.describe("Another ExampleGroup") do
43 it "should create a subclass of the ExampleGroup when passed a block" do
44 child_example_group.superclass.should == @example_group
45 @options.example_groups.should include(child_example_group)
48 it "should not inherit examples" do
49 child_example_group.examples.length.should == 1
53 describe ExampleGroup, ".it" do
54 it "should should create an example instance" do
57 }.should change { @example_group.examples.length }.by(1)
61 describe ExampleGroup, ".xit" do
66 it "should NOT should create an example instance" do
68 @example_group.xit("")
69 }.should_not change(@example_group.examples, :length)
72 it "should warn that it is disabled" do
73 Kernel.should_receive(:warn).with("Example disabled: foo")
74 @example_group.xit("foo")
78 describe ExampleGroup, ".suite" do
79 it "should return an empty ExampleSuite when there is no description" do
80 ExampleGroup.description.should be_nil
81 ExampleGroup.suite.should be_instance_of(ExampleSuite)
82 ExampleGroup.suite.tests.should be_empty
85 it "should return an ExampleSuite with Examples" do
86 behaviour = Class.new(ExampleGroup) do
92 suite = behaviour.suite
93 suite.tests.length.should == 1
94 suite.tests.first._example.description.should == "should pass"
97 it "should include methods that begin with test and has an arity of 0 in suite" do
98 behaviour = Class.new(ExampleGroup) do
100 def test_any_args(*args)
107 raise "This is not a real test"
110 raise "This is not a real test"
113 suite = behaviour.suite
114 suite.tests.length.should == 2
115 descriptions = suite.tests.collect {|test| test._example.description}.sort
116 descriptions.should == ["test_any_args", "test_something"]
117 suite.run.should be_true
120 it "should include methods that begin with should and has an arity of 0 in suite" do
121 behaviour = Class.new(ExampleGroup) do
126 def should_any_args(*args)
132 def should_not_something
136 raise "This is not a real example"
139 raise "This is not a real example"
142 behaviour = behaviour.dup
143 suite = behaviour.suite
144 suite.tests.length.should == 4
145 descriptions = suite.tests.collect {|test| test._example.description}.sort
146 descriptions.should include("shouldCamelCase")
147 descriptions.should include("should_any_args")
148 descriptions.should include("should_something")
149 descriptions.should include("should_not_something")
152 it "should not include methods that begin with test_ and has an arity > 0 in suite" do
153 behaviour = Class.new(ExampleGroup) do
155 def test_invalid(foo)
158 def testInvalidCamelCase(foo)
162 suite = behaviour.suite
163 suite.tests.length.should == 0
166 it "should not include methods that begin with should_ and has an arity > 0 in suite" do
167 behaviour = Class.new(ExampleGroup) do
169 def should_invalid(foo)
172 def shouldInvalidCamelCase(foo)
175 def should_not_invalid(foo)
179 suite = behaviour.suite
180 suite.tests.length.should == 0
184 describe ExampleGroup, ".description" do
185 it "should return the same description instance for each call" do
186 @example_group.description.should eql(@example_group.description)
190 describe ExampleGroup, ".remove_after" do
191 it "should unregister a given after(:each) block" do
192 after_all_ran = false
193 @example_group.it("example") {}
194 proc = Proc.new { after_all_ran = true }
195 ExampleGroup.after(:each, &proc)
196 suite = @example_group.suite
198 after_all_ran.should be_true
200 after_all_ran = false
201 ExampleGroup.remove_after(:each, &proc)
202 suite = @example_group.suite
204 after_all_ran.should be_false
208 describe ExampleGroup, ".include" do
209 it "should have accessible class methods from included module" do
210 mod1_method_called = false
212 class_methods = Module.new do
213 define_method :mod1_method do
214 mod1_method_called = true
218 metaclass.class_eval do
219 define_method(:included) do |receiver|
220 receiver.extend class_methods
225 mod2_method_called = false
227 class_methods = Module.new do
228 define_method :mod2_method do
229 mod2_method_called = true
233 metaclass.class_eval do
234 define_method(:included) do |receiver|
235 receiver.extend class_methods
240 @example_group.include mod1, mod2
242 @example_group.mod1_method
243 @example_group.mod2_method
244 mod1_method_called.should be_true
245 mod2_method_called.should be_true
249 describe ExampleGroup, ".number_of_examples" do
250 it "should count number of specs" do
252 @example_group.it("one") {}
253 @example_group.it("two") {}
254 @example_group.it("three") {}
255 @example_group.it("four") {}
256 end.should change {@example_group.number_of_examples}.by(4)
260 describe ExampleGroup, ".class_eval" do
261 it "should allow constants to be defined" do
262 behaviour = Class.new(ExampleGroup) do
265 it "should reference FOO" do
269 suite = behaviour.suite
271 Object.const_defined?(:FOO).should == false
275 describe ExampleGroup, '.register' do
276 it "should add ExampleGroup to set of ExampleGroups to be run" do
277 example_group.register
278 options.example_groups.should include(example_group)
282 describe ExampleGroup, '.unregister' do
284 example_group.register
285 options.example_groups.should include(example_group)
288 it "should remove ExampleGroup from set of ExampleGroups to be run" do
289 example_group.unregister
290 options.example_groups.should_not include(example_group)
295 class ExampleModuleScopingSpec < ExampleGroup
296 describe ExampleGroup, " via a class definition"
307 it "should understand module scoping" do
313 it "should allow class variables to be defined" do
318 class ExampleClassVariablePollutionSpec < ExampleGroup
319 describe ExampleGroup, " via a class definition without a class variable"
321 it "should not retain class variables from other Example classes" do
324 end.should raise_error
328 describe ExampleGroup, '.run functional example' do
351 it "should run before(:all), before(:each), example, after(:each), after(:all) in order" do
372 describe ExampleGroup, "#initialize" do
374 it "should have copy of behaviour" do
375 the_behaviour.superclass.should == ExampleGroup
379 describe ExampleGroup, "#pending" do
380 it "should raise a Pending error when its block fails" do
383 pending("something") do
385 raise "something wrong with my example"
387 }.should raise_error(Spec::Example::ExamplePendingError, "something")
388 block_ran.should == true
391 it "should raise Spec::Example::PendingExampleFixedError when its block does not fail" do
394 pending("something") do
397 }.should raise_error(Spec::Example::PendingExampleFixedError, "Expected pending 'something' to fail. No Error was raised.")
398 block_ran.should == true
402 describe ExampleGroup, "#run" do
404 @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new)
405 @original_rspec_options = $rspec_options
406 $rspec_options = @options
410 $rspec_options = @original_rspec_options
413 it "should not run when there are no examples" do
414 behaviour = Class.new(ExampleGroup) do
417 behaviour.examples.should be_empty
419 reporter = mock("Reporter")
420 reporter.should_not_receive(:add_example_group)
421 suite = behaviour.suite
426 class ExampleSubclass < ExampleGroup
429 describe ExampleGroup, "subclasses" do
431 ExampleGroupFactory.reset
434 it "should have access to the described_type" do
435 behaviour = Class.new(ExampleSubclass) do
438 behaviour.send(:described_type).should == Array
442 describe Enumerable do
444 ["4", "2", "1"].each(&block)
447 it "should be included in examples because it is a module" do
448 map{|e| e.to_i}.should == [4,2,1]
452 describe "An", Enumerable, "as a second argument" do
454 ["4", "2", "1"].each(&block)
457 it "should be included in examples because it is a module" do
458 map{|e| e.to_i}.should == [4,2,1]
463 it "should not be included in examples because it is not a module" do
464 lambda{self.map}.should raise_error(NoMethodError, /undefined method `map' for/)