1 require File.dirname(__FILE__) + '/../spec_helper'
2 require 'mspec/expectations/expectations'
3 require 'mspec/matchers/base'
4 require 'mspec/runner/mspec'
5 require 'mspec/mocks/mock'
6 require 'mspec/runner/context'
8 describe ContextState, "#describe" do
10 @state = ContextState.new "C#m"
11 @proc = lambda { ScratchPad.record :a }
15 it "evaluates the passed block" do
16 @state.describe(&@proc)
17 ScratchPad.recorded.should == :a
20 it "evaluates the passed block via #protect" do
21 @state.should_receive(:protect).with("C#m", @proc, false)
22 @state.describe(&@proc)
25 it "registers #parent as the current MSpec ContextState" do
26 parent = ContextState.new ""
27 @state.parent = parent
28 MSpec.should_receive(:register_current).with(parent)
32 it "registers self with MSpec when #shared? is true" do
33 state = ContextState.new "something shared", :shared => true
34 MSpec.should_receive(:register_shared).with(state)
39 describe ContextState, "#shared?" do
40 it "returns false when the ContextState is not shared" do
41 ContextState.new("").shared?.should be_false
44 it "returns true when the ContextState is shared" do
45 ContextState.new("", {:shared => true}).shared?.should be_true
49 describe ContextState, "#to_s" do
50 it "returns a description string for self when passed a Module" do
51 ContextState.new(Object).to_s.should == "Object"
54 it "returns a description string for self when passed a String" do
55 ContextState.new("SomeClass").to_s.should == "SomeClass"
58 it "returns a description string for self when passed a Module, String" do
59 ContextState.new(Object, "when empty").to_s.should == "Object when empty"
62 it "returns a description string for self when passed a Module and String beginning with '#'" do
63 ContextState.new(Object, "#to_s").to_s.should == "Object#to_s"
66 it "returns a description string for self when passed a Module and String beginning with '.'" do
67 ContextState.new(Object, ".to_s").to_s.should == "Object.to_s"
70 it "returns a description string for self when passed a Module and String beginning with '::'" do
71 ContextState.new(Object, "::to_s").to_s.should == "Object::to_s"
75 describe ContextState, "#description" do
77 @state = ContextState.new "when empty"
78 @parent = ContextState.new "Toplevel"
81 it "returns a composite description string from self and all parents" do
82 @parent.description.should == "Toplevel"
83 @state.description.should == "when empty"
84 @state.parent = @parent
85 @state.description.should == "Toplevel when empty"
89 describe ContextState, "#it" do
91 @state = ContextState.new ""
95 it "creates an ExampleState instance for the block" do
96 ex = ExampleState.new("", "", &@proc)
97 ExampleState.should_receive(:new).with(@state, "it", @proc).and_return(ex)
98 @state.describe(&@proc)
99 @state.it("it", &@proc)
103 describe ContextState, "#examples" do
105 @state = ContextState.new ""
108 it "returns a list of all examples in this ContextState" do
109 @state.it("first") { }
110 @state.it("second") { }
111 @state.examples.size.should == 2
115 describe ContextState, "#before" do
117 @state = ContextState.new ""
121 it "records the block for :each" do
122 @state.before(:each, &@proc)
123 @state.before(:each).should == [@proc]
126 it "records the block for :all" do
127 @state.before(:all, &@proc)
128 @state.before(:all).should == [@proc]
132 describe ContextState, "#after" do
134 @state = ContextState.new ""
138 it "records the block for :each" do
139 @state.after(:each, &@proc)
140 @state.after(:each).should == [@proc]
143 it "records the block for :all" do
144 @state.after(:all, &@proc)
145 @state.after(:all).should == [@proc]
149 describe ContextState, "#pre" do
155 parent = ContextState.new ""
156 parent.before(:each, &@c)
157 parent.before(:all, &@c)
159 @state = ContextState.new ""
160 @state.parent = parent
163 it "returns before(:each) actions in the order they were defined" do
164 @state.before(:each, &@a)
165 @state.before(:each, &@b)
166 @state.pre(:each).should == [@c, @a, @b]
169 it "returns before(:all) actions in the order they were defined" do
170 @state.before(:all, &@a)
171 @state.before(:all, &@b)
172 @state.pre(:all).should == [@c, @a, @b]
176 describe ContextState, "#post" do
182 parent = ContextState.new ""
183 parent.after(:each, &@c)
184 parent.after(:all, &@c)
186 @state = ContextState.new ""
187 @state.parent = parent
190 it "returns after(:each) actions in the reverse order they were defined" do
191 @state.after(:each, &@a)
192 @state.after(:each, &@b)
193 @state.post(:each).should == [@b, @a, @c]
196 it "returns after(:all) actions in the reverse order they were defined" do
197 @state.after(:all, &@a)
198 @state.after(:all, &@b)
199 @state.post(:all).should == [@b, @a, @c]
203 describe ContextState, "#protect" do
206 @a = lambda { ScratchPad << :a }
207 @b = lambda { ScratchPad << :b }
208 @c = lambda { raise Exception, "Fail!" }
211 it "returns true and does execute any blocks if check is true and MSpec.pretend_mode? is true" do
212 MSpec.stub!(:pretend_mode?).and_return(true)
213 ContextState.new("").protect("message", [@a, @b]).should be_true
214 ScratchPad.recorded.should == []
217 it "executes the blocks if MSpec.pretend_mode? is false" do
218 MSpec.stub!(:pretend_mode?).and_return(false)
219 ContextState.new("").protect("message", [@a, @b])
220 ScratchPad.recorded.should == [:a, :b]
223 it "executes the blocks if check is false" do
224 ContextState.new("").protect("message", [@a, @b], false)
225 ScratchPad.recorded.should == [:a, :b]
228 it "returns true if none of the blocks raise an exception" do
229 ContextState.new("").protect("message", [@a, @b]).should be_true
232 it "returns false if any of the blocks raise an exception" do
233 ContextState.new("").protect("message", [@a, @c, @b]).should be_false
237 describe ContextState, "#parent=" do
239 @state = ContextState.new ""
240 @parent = mock("describe")
241 @parent.stub!(:parent).and_return(nil)
242 @parent.stub!(:child)
245 it "does not set self as a child of parent if shared" do
246 @parent.should_not_receive(:child)
247 state = ContextState.new "", :shared => true
248 state.parent = @parent
251 it "sets self as a child of parent" do
252 @parent.should_receive(:child).with(@state)
253 @state.parent = @parent
256 it "creates the list of parents" do
257 @state.parent = @parent
258 @state.parents.should == [@parent, @state]
262 describe ContextState, "#parent" do
264 @state = ContextState.new ""
265 @parent = mock("describe")
266 @parent.stub!(:parent).and_return(nil)
267 @parent.stub!(:child)
270 it "returns nil if parent has not been set" do
271 @state.parent.should be_nil
274 it "returns the parent" do
275 @state.parent = @parent
276 @state.parent.should == @parent
280 describe ContextState, "#parents" do
282 @first = ContextState.new ""
283 @second = ContextState.new ""
284 @parent = mock("describe")
285 @parent.stub!(:parent).and_return(nil)
286 @parent.stub!(:child)
289 it "returns a list of all enclosing ContextState instances" do
290 @first.parent = @parent
291 @second.parent = @first
292 @second.parents.should == [@parent, @first, @second]
296 describe ContextState, "#child" do
298 @first = ContextState.new ""
299 @second = ContextState.new ""
300 @parent = mock("describe")
301 @parent.stub!(:parent).and_return(nil)
302 @parent.stub!(:child)
305 it "adds the ContextState to the list of contained ContextStates" do
307 @first.children.should == [@second]
311 describe ContextState, "#children" do
313 @parent = ContextState.new ""
314 @first = ContextState.new ""
315 @second = ContextState.new ""
318 it "returns the list of directly contained ContextStates" do
319 @first.parent = @parent
320 @second.parent = @first
321 @parent.children.should == [@first]
322 @first.children.should == [@second]
326 describe ContextState, "#state" do
328 MSpec.store :before, []
329 MSpec.store :after, []
331 @state = ContextState.new ""
334 it "returns nil if no spec is being executed" do
335 @state.state.should == nil
338 it "returns a ExampleState instance if an example is being executed" do
339 ScratchPad.record @state
341 @state.it("") { ScratchPad.record ScratchPad.recorded.state }
343 @state.state.should == nil
344 ScratchPad.recorded.should be_kind_of(ExampleState)
348 describe ContextState, "#process" do
350 MSpec.store :before, []
351 MSpec.store :after, []
352 MSpec.stub!(:register_current)
354 @state = ContextState.new ""
357 @a = lambda { ScratchPad << :a }
358 @b = lambda { ScratchPad << :b }
362 it "calls each before(:all) block" do
363 @state.before(:all, &@a)
364 @state.before(:all, &@b)
367 ScratchPad.recorded.should == [:a, :b]
370 it "calls each after(:all) block" do
371 @state.after(:all, &@a)
372 @state.after(:all, &@b)
375 ScratchPad.recorded.should == [:b, :a]
378 it "calls each it block" do
379 @state.it("one", &@a)
380 @state.it("two", &@b)
382 ScratchPad.recorded.should == [:a, :b]
385 it "does not call the #it block if #filtered? returns true" do
386 @state.it("one", &@a)
387 @state.it("two", &@b)
388 @state.examples.first.stub!(:filtered?).and_return(true)
390 ScratchPad.recorded.should == [:b]
393 it "calls each before(:each) block" do
394 @state.before(:each, &@a)
395 @state.before(:each, &@b)
398 ScratchPad.recorded.should == [:a, :b]
401 it "calls each after(:each) block" do
402 @state.after(:each, &@a)
403 @state.after(:each, &@b)
406 ScratchPad.recorded.should == [:b, :a]
409 it "calls Mock.cleanup for each it block" do
412 Mock.should_receive(:cleanup).twice
416 it "calls Mock.verify_count for each it block" do
419 Mock.should_receive(:verify_count).twice
423 it "calls the describe block" do
425 @state.describe { ScratchPad << :a }
427 ScratchPad.recorded.should == [:a]
430 it "creates a new ExampleState instance for each example" do
431 ScratchPad.record @state
433 @state.it("it") { ScratchPad.record ScratchPad.recorded.state }
435 ScratchPad.recorded.should be_kind_of(ExampleState)
438 it "clears the expectations flag before evaluating the #it block" do
439 MSpec.clear_expectations
440 MSpec.should_receive(:clear_expectations)
441 @state.it("it") { ScratchPad.record MSpec.expectation? }
443 ScratchPad.recorded.should be_false
446 it "shuffles the spec list if MSpec.randomize? is true" do
448 MSpec.should_receive(:shuffle)
451 MSpec.randomize false
454 it "sets the current MSpec ContextState" do
455 MSpec.should_receive(:register_current).with(@state)
459 it "resets the current MSpec ContextState to nil when there are examples" do
460 MSpec.should_receive(:register_current).with(nil)
465 it "resets the current MSpec ContextState to nil when there are no examples" do
466 MSpec.should_receive(:register_current).with(nil)
470 it "call #process on children when there are examples" do
471 child = ContextState.new ""
472 child.should_receive(:process)
478 it "call #process on children when there are no examples" do
479 child = ContextState.new ""
480 child.should_receive(:process)
486 describe ContextState, "#process" do
488 MSpec.store :exception, []
490 @state = ContextState.new ""
493 action = mock("action")
494 def action.exception(exc)
495 ScratchPad.record :exception if exc.exception.is_a? ExpectationNotFoundError
497 MSpec.register :exception, action
499 MSpec.clear_expectations
504 MSpec.store :exception, nil
507 it "raises an ExpectationNotFoundError if an #it block does not contain an expectation" do
510 ScratchPad.recorded.should == :exception
513 it "does not raise an ExpectationNotFoundError if an #it block does contain an expectation" do
514 @state.it("it") { MSpec.expectation }
516 ScratchPad.recorded.should be_nil
519 it "does not raise an ExpectationNotFoundError if the #it block causes a failure" do
520 @state.it("it") { raise Exception, "Failed!" }
522 ScratchPad.recorded.should be_nil
526 describe ContextState, "#process" do
528 MSpec.store :example, []
530 @state = ContextState.new ""
533 example = mock("example")
534 def example.example(state, spec)
535 ScratchPad << state << spec
537 MSpec.register :example, example
543 MSpec.store :example, nil
546 it "calls registered example actions with the current ExampleState and block" do
547 @state.it("") { MSpec.expectation }
550 ScratchPad.recorded.first.should be_kind_of(ExampleState)
551 ScratchPad.recorded.last.should be_kind_of(Proc)
554 it "does not call registered example actions if the example has no block" do
555 @state.it("empty example")
557 ScratchPad.recorded.should == []
561 describe ContextState, "#process" do
563 MSpec.store :before, []
564 MSpec.store :after, []
566 @state = ContextState.new ""
568 @state.it("") { MSpec.expectation }
572 MSpec.store :before, nil
573 MSpec.store :after, nil
576 it "calls registered before actions with the current ExampleState instance" do
577 before = mock("before")
578 before.should_receive(:before).and_return {
579 ScratchPad.record :before
580 @spec_state = @state.state
582 MSpec.register :before, before
584 ScratchPad.recorded.should == :before
585 @spec_state.should be_kind_of(ExampleState)
588 it "calls registered after actions with the current ExampleState instance" do
589 after = mock("after")
590 after.should_receive(:after).and_return {
591 ScratchPad.record :after
592 @spec_state = @state.state
594 MSpec.register :after, after
596 ScratchPad.recorded.should == :after
597 @spec_state.should be_kind_of(ExampleState)
601 describe ContextState, "#process" do
603 MSpec.store :enter, []
604 MSpec.store :leave, []
606 @state = ContextState.new "C#m"
608 @state.it("") { MSpec.expectation }
612 MSpec.store :enter, nil
613 MSpec.store :leave, nil
616 it "calls registered enter actions with the current #describe string" do
617 enter = mock("enter")
618 enter.should_receive(:enter).with("C#m").and_return { ScratchPad.record :enter }
619 MSpec.register :enter, enter
621 ScratchPad.recorded.should == :enter
624 it "calls registered leave actions" do
625 leave = mock("leave")
626 leave.should_receive(:leave).and_return { ScratchPad.record :leave }
627 MSpec.register :leave, leave
629 ScratchPad.recorded.should == :leave
633 describe ContextState, "#process when an exception is raised in before(:all)" do
635 MSpec.store :before, []
636 MSpec.store :after, []
638 @state = ContextState.new ""
641 @a = lambda { ScratchPad << :a }
642 @b = lambda { ScratchPad << :b }
645 @state.before(:all) { raise Exception, "Fail!" }
649 MSpec.store :before, nil
650 MSpec.store :after, nil
653 it "does not call before(:each)" do
654 @state.before(:each, &@a)
657 ScratchPad.recorded.should == []
660 it "does not call the it block" do
661 @state.it("one", &@a)
663 ScratchPad.recorded.should == []
666 it "does not call after(:each)" do
667 @state.after(:each, &@a)
670 ScratchPad.recorded.should == []
673 it "does not call after(:each)" do
674 @state.after(:all, &@a)
677 ScratchPad.recorded.should == []
680 it "does not call Mock.verify_count" do
682 Mock.should_not_receive(:verify_count)
686 it "calls Mock.cleanup" do
688 Mock.should_receive(:cleanup)
693 describe ContextState, "#process when an exception is raised in before(:each)" do
695 MSpec.store :before, []
696 MSpec.store :after, []
698 @state = ContextState.new ""
701 @a = lambda { ScratchPad << :a }
702 @b = lambda { ScratchPad << :b }
705 @state.before(:each) { raise Exception, "Fail!" }
709 MSpec.store :before, nil
710 MSpec.store :after, nil
713 it "does not call the it block" do
714 @state.it("one", &@a)
716 ScratchPad.recorded.should == []
719 it "does not call after(:each)" do
720 @state.after(:each, &@a)
723 ScratchPad.recorded.should == []
726 it "does not call Mock.verify_count" do
728 Mock.should_not_receive(:verify_count)
733 describe ContextState, "#process in pretend mode" do
735 MSpec.register_mode :pretend
739 MSpec.register_mode nil
744 MSpec.store :before, []
745 MSpec.store :after, []
747 @state = ContextState.new ""
753 MSpec.store :before, nil
754 MSpec.store :after, nil
757 it "calls registered before actions with the current ExampleState instance" do
758 before = mock("before")
759 before.should_receive(:before).and_return {
760 ScratchPad.record :before
761 @spec_state = @state.state
763 MSpec.register :before, before
765 ScratchPad.recorded.should == :before
766 @spec_state.should be_kind_of(ExampleState)
769 it "calls registered after actions with the current ExampleState instance" do
770 after = mock("after")
771 after.should_receive(:after).and_return {
772 ScratchPad.record :after
773 @spec_state = @state.state
775 MSpec.register :after, after
777 ScratchPad.recorded.should == :after
778 @spec_state.should be_kind_of(ExampleState)
782 describe ContextState, "#process in pretend mode" do
784 MSpec.register_mode :pretend
788 MSpec.register_mode nil
792 MSpec.store :before, []
793 MSpec.store :after, []
795 @state = ContextState.new ""
798 @a = lambda { ScratchPad << :a }
799 @b = lambda { ScratchPad << :b }
803 it "calls the describe block" do
805 @state.describe { ScratchPad << :a }
807 ScratchPad.recorded.should == [:a]
810 it "does not call any before(:all) block" do
811 @state.before(:all, &@a)
812 @state.before(:all, &@b)
815 ScratchPad.recorded.should == []
818 it "does not call any after(:all) block" do
819 @state.after(:all, &@a)
820 @state.after(:all, &@b)
823 ScratchPad.recorded.should == []
826 it "does not call any it block" do
827 @state.it("one", &@a)
828 @state.it("two", &@b)
830 ScratchPad.recorded.should == []
833 it "does not call any before(:each) block" do
834 @state.before(:each, &@a)
835 @state.before(:each, &@b)
838 ScratchPad.recorded.should == []
841 it "does not call any after(:each) block" do
842 @state.after(:each, &@a)
843 @state.after(:each, &@b)
846 ScratchPad.recorded.should == []
849 it "does not call Mock.cleanup" do
852 Mock.should_not_receive(:cleanup)
857 describe ContextState, "#process in pretend mode" do
859 MSpec.register_mode :pretend
863 MSpec.register_mode nil
867 MSpec.store :enter, []
868 MSpec.store :leave, []
870 @state = ContextState.new ""
876 MSpec.store :enter, nil
877 MSpec.store :leave, nil
880 it "calls registered enter actions with the current #describe string" do
881 enter = mock("enter")
882 enter.should_receive(:enter).and_return { ScratchPad.record :enter }
883 MSpec.register :enter, enter
885 ScratchPad.recorded.should == :enter
888 it "calls registered leave actions" do
889 leave = mock("leave")
890 leave.should_receive(:leave).and_return { ScratchPad.record :leave }
891 MSpec.register :leave, leave
893 ScratchPad.recorded.should == :leave
897 describe ContextState, "#it_should_behave_like" do
899 @shared = ContextState.new("", :shared => true)
900 MSpec.stub!(:retrieve_shared).and_return(@shared)
902 @state = ContextState.new ""
907 it "raises an Exception if unable to find the shared ContextState" do
908 MSpec.should_receive(:retrieve_shared).and_return(nil)
909 lambda { @state.it_should_behave_like "this" }.should raise_error(Exception)
912 it "adds examples from the shared ContextState" do
913 @shared.it "some", &@a
914 @shared.it "thing", &@b
915 @state.it_should_behave_like ""
916 @state.examples.should include(*@shared.examples)
919 it "sets the containing ContextState for the examples" do
920 @shared.it "some", &@a
921 @shared.it "thing", &@b
922 @shared.examples.each { |ex| ex.should_receive(:context=).with(@state) }
923 @state.it_should_behave_like ""
926 it "adds before(:all) blocks from the shared ContextState" do
927 @shared.before :all, &@a
928 @shared.before :all, &@b
929 @state.it_should_behave_like ""
930 @state.before(:all).should include(*@shared.before(:all))
933 it "adds before(:each) blocks from the shared ContextState" do
934 @shared.before :each, &@a
935 @shared.before :each, &@b
936 @state.it_should_behave_like ""
937 @state.before(:each).should include(*@shared.before(:each))
940 it "adds after(:each) blocks from the shared ContextState" do
941 @shared.after :each, &@a
942 @shared.after :each, &@b
943 @state.it_should_behave_like ""
944 @state.after(:each).should include(*@shared.after(:each))
947 it "adds after(:all) blocks from the shared ContextState" do
948 @shared.after :all, &@a
949 @shared.after :all, &@b
950 @state.it_should_behave_like ""
951 @state.after(:all).should include(*@shared.after(:all))
955 describe ContextState, "#filter_examples" do
957 @state = ContextState.new ""
962 it "removes examples that are filtered" do
963 @state.examples.first.stub!(:filtered?).and_return(true)
964 @state.examples.size.should == 2
965 @state.filter_examples
966 @state.examples.size.should == 1
969 it "returns true if there are remaining examples to evaluate" do
970 @state.examples.first.stub!(:filtered?).and_return(true)
971 @state.filter_examples.should be_true
974 it "returns false if there are no remaining examples to evaluate" do
975 @state.examples.first.stub!(:filtered?).and_return(true)
976 @state.examples.last.stub!(:filtered?).and_return(true)
977 @state.filter_examples.should be_false