mspec 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +93 -0
- data/lib/mspec/commands/mspec-ci.rb +2 -0
- data/lib/mspec/matchers.rb +4 -3
- data/lib/mspec/matchers/equal_element.rb +78 -0
- data/lib/mspec/runner/context.rb +138 -52
- data/lib/mspec/runner/example.rb +17 -20
- data/lib/mspec/runner/mspec.rb +38 -13
- data/lib/mspec/runner/object.rb +5 -1
- data/lib/mspec/runner/shared.rb +6 -6
- data/lib/mspec/version.rb +1 -1
- data/spec/commands/mspec_ci_spec.rb +14 -0
- data/spec/matchers/equal_element_spec.rb +75 -0
- data/spec/runner/actions/debug_spec.rb +2 -1
- data/spec/runner/actions/gdb_spec.rb +1 -1
- data/spec/runner/actions/tag_spec.rb +7 -4
- data/spec/runner/context_spec.rb +422 -57
- data/spec/runner/example_spec.rb +53 -37
- data/spec/runner/exception_spec.rb +9 -5
- data/spec/runner/formatters/dotted_spec.rb +4 -3
- data/spec/runner/formatters/html_spec.rb +4 -3
- data/spec/runner/formatters/specdoc_spec.rb +3 -2
- data/spec/runner/formatters/summary_spec.rb +2 -1
- data/spec/runner/formatters/unit_spec.rb +2 -1
- data/spec/runner/formatters/yaml_spec.rb +2 -1
- data/spec/runner/mspec_spec.rb +87 -23
- data/spec/runner/shared_spec.rb +14 -28
- metadata +3 -1
data/lib/mspec/runner/mspec.rb
CHANGED
@@ -18,18 +18,21 @@ module MSpec
|
|
18
18
|
@mode = nil
|
19
19
|
@load = nil
|
20
20
|
@unload = nil
|
21
|
+
@current = nil
|
22
|
+
@shared = {}
|
21
23
|
@exception = nil
|
22
24
|
@randomize = nil
|
23
25
|
@expectation = nil
|
24
26
|
@expectations = false
|
25
27
|
|
26
|
-
def self.describe(mod,
|
27
|
-
|
28
|
+
def self.describe(mod, options=nil, &block)
|
29
|
+
state = ContextState.new mod, options
|
30
|
+
state.parent = current
|
28
31
|
|
29
|
-
|
30
|
-
|
32
|
+
MSpec.register_current state
|
33
|
+
state.describe(&block)
|
31
34
|
|
32
|
-
|
35
|
+
state.process unless state.shared? or current
|
33
36
|
end
|
34
37
|
|
35
38
|
def self.process
|
@@ -62,6 +65,8 @@ module MSpec
|
|
62
65
|
begin
|
63
66
|
@env.instance_eval(&block)
|
64
67
|
return true
|
68
|
+
rescue SystemExit
|
69
|
+
raise
|
65
70
|
rescue Exception => exc
|
66
71
|
register_exit 1
|
67
72
|
actions :exception, ExceptionState.new(current && current.state, location, exc)
|
@@ -69,14 +74,42 @@ module MSpec
|
|
69
74
|
end
|
70
75
|
end
|
71
76
|
|
77
|
+
# Sets the toplevel ContextState to +state+.
|
78
|
+
def self.register_current(state)
|
79
|
+
store :current, state
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sets the toplevel ContextState to +nil+.
|
83
|
+
def self.clear_current
|
84
|
+
store :current, nil
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns the toplevel ContextState.
|
88
|
+
def self.current
|
89
|
+
retrieve :current
|
90
|
+
end
|
91
|
+
|
92
|
+
# Stores the shared ContextState keyed by description.
|
93
|
+
def self.register_shared(state)
|
94
|
+
@shared[state.to_s] = state
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the shared ContextState matching description.
|
98
|
+
def self.retrieve_shared(desc)
|
99
|
+
@shared[desc.to_s]
|
100
|
+
end
|
101
|
+
|
102
|
+
# Stores the exit code used by the runner scripts.
|
72
103
|
def self.register_exit(code)
|
73
104
|
store :exit, code
|
74
105
|
end
|
75
106
|
|
107
|
+
# Retrieves the stored exit code.
|
76
108
|
def self.exit_code
|
77
109
|
retrieve(:exit).to_i
|
78
110
|
end
|
79
111
|
|
112
|
+
# Stores the list of files to be evaluated.
|
80
113
|
def self.register_files(files)
|
81
114
|
store :files, files
|
82
115
|
end
|
@@ -141,14 +174,6 @@ module MSpec
|
|
141
174
|
end
|
142
175
|
end
|
143
176
|
|
144
|
-
def self.stack
|
145
|
-
@stack ||= []
|
146
|
-
end
|
147
|
-
|
148
|
-
def self.current
|
149
|
-
stack.last
|
150
|
-
end
|
151
|
-
|
152
177
|
def self.verify_mode?
|
153
178
|
@mode == :verify
|
154
179
|
end
|
data/lib/mspec/runner/object.rb
CHANGED
@@ -7,7 +7,7 @@ class Object
|
|
7
7
|
MSpec.current.after at, &block
|
8
8
|
end
|
9
9
|
|
10
|
-
def describe(mod, msg=nil, &block)
|
10
|
+
def describe(mod, msg=nil, options=nil, &block)
|
11
11
|
MSpec.describe mod, msg, &block
|
12
12
|
end
|
13
13
|
|
@@ -15,6 +15,10 @@ class Object
|
|
15
15
|
MSpec.current.it msg, &block
|
16
16
|
end
|
17
17
|
|
18
|
+
def it_should_behave_like(desc)
|
19
|
+
MSpec.current.it_should_behave_like desc
|
20
|
+
end
|
21
|
+
|
18
22
|
alias_method :context, :describe
|
19
23
|
alias_method :specify, :it
|
20
24
|
end
|
data/lib/mspec/runner/shared.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'mspec/runner/mspec'
|
2
2
|
|
3
3
|
class Object
|
4
|
-
def
|
5
|
-
|
6
|
-
|
4
|
+
def it_behaves_like(desc, meth, obj=nil)
|
5
|
+
send :before, :all do
|
6
|
+
@method = meth
|
7
|
+
@object = obj if obj
|
8
|
+
end
|
7
9
|
|
8
|
-
|
9
|
-
p = MSpec.retrieve behavior.to_sym
|
10
|
-
p[*args]
|
10
|
+
send :it_should_behave_like, desc.to_s
|
11
11
|
end
|
12
12
|
end
|
data/lib/mspec/version.rb
CHANGED
@@ -121,6 +121,20 @@ describe MSpecCI, "#run" do
|
|
121
121
|
@script.run
|
122
122
|
end
|
123
123
|
|
124
|
+
it "registers a tag filter for 'critical'" do
|
125
|
+
filter = mock("critical filter")
|
126
|
+
TagFilter.should_receive(:new).with(:exclude, 'critical').and_return(filter)
|
127
|
+
filter.should_receive(:register)
|
128
|
+
@script.run
|
129
|
+
end
|
130
|
+
|
131
|
+
it "registers a tag filter for 'unsupported'" do
|
132
|
+
filter = mock("unsupported filter")
|
133
|
+
TagFilter.should_receive(:new).with(:exclude, 'unsupported').and_return(filter)
|
134
|
+
filter.should_receive(:register)
|
135
|
+
@script.run
|
136
|
+
end
|
137
|
+
|
124
138
|
it "processes the files" do
|
125
139
|
MSpec.should_receive(:process)
|
126
140
|
@script.run
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'mspec/expectations/expectations'
|
3
|
+
require 'mspec/matchers/equal_element'
|
4
|
+
|
5
|
+
describe EqualElementMatcher do
|
6
|
+
it "matches if it finds an element with the passed name, no matter what attributes/content" do
|
7
|
+
EqualElementMatcher.new("A").matches?('<A></A>').should be_true
|
8
|
+
EqualElementMatcher.new("A").matches?('<A HREF="http://example.com"></A>').should be_true
|
9
|
+
EqualElementMatcher.new("A").matches?('<A HREF="http://example.com"></A>').should be_true
|
10
|
+
|
11
|
+
EqualElementMatcher.new("BASE").matches?('<BASE></A>').should be_false
|
12
|
+
EqualElementMatcher.new("BASE").matches?('<A></BASE>').should be_false
|
13
|
+
EqualElementMatcher.new("BASE").matches?('<A></A>').should be_false
|
14
|
+
EqualElementMatcher.new("BASE").matches?('<A HREF="http://example.com"></A>').should be_false
|
15
|
+
EqualElementMatcher.new("BASE").matches?('<A HREF="http://example.com"></A>').should be_false
|
16
|
+
end
|
17
|
+
|
18
|
+
it "matches if it finds an element with the passed name and the passed attributes" do
|
19
|
+
EqualElementMatcher.new("A", {}).matches?('<A></A>').should be_true
|
20
|
+
EqualElementMatcher.new("A", nil).matches?('<A HREF="http://example.com"></A>').should be_true
|
21
|
+
EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A HREF="http://example.com"></A>').should be_true
|
22
|
+
|
23
|
+
EqualElementMatcher.new("A", {}).matches?('<A HREF="http://example.com"></A>').should be_false
|
24
|
+
EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A></A>').should be_false
|
25
|
+
EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A HREF="http://test.com"></A>').should be_false
|
26
|
+
EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A HREF="http://example.com" HREF="http://example.com"></A>').should be_false
|
27
|
+
end
|
28
|
+
|
29
|
+
it "matches if it finds an element with the passed name, the passed attributes and the passed content" do
|
30
|
+
EqualElementMatcher.new("A", {}, "").matches?('<A></A>').should be_true
|
31
|
+
EqualElementMatcher.new("A", {"HREF" => "http://example.com"}, "Example").matches?('<A HREF="http://example.com">Example</A>').should be_true
|
32
|
+
|
33
|
+
EqualElementMatcher.new("A", {}, "Test").matches?('<A></A>').should be_false
|
34
|
+
EqualElementMatcher.new("A", {"HREF" => "http://example.com"}, "Example").matches?('<A HREF="http://example.com"></A>').should be_false
|
35
|
+
EqualElementMatcher.new("A", {"HREF" => "http://example.com"}, "Example").matches?('<A HREF="http://example.com">Test</A>').should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can match unclosed elements" do
|
39
|
+
EqualElementMatcher.new("BASE", nil, nil, :not_closed => true).matches?('<BASE>').should be_true
|
40
|
+
EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, nil, :not_closed => true).matches?('<BASE HREF="http://example.com">').should be_true
|
41
|
+
EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, "Example", :not_closed => true).matches?('<BASE HREF="http://example.com">Example').should be_true
|
42
|
+
|
43
|
+
EqualElementMatcher.new("BASE", {}, nil, :not_closed => true).matches?('<BASE HREF="http://example.com">').should be_false
|
44
|
+
EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, "", :not_closed => true).matches?('<BASE HREF="http://example.com">Example').should be_false
|
45
|
+
EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, "Test", :not_closed => true).matches?('<BASE HREF="http://example.com">Example').should be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "provides a useful failure message" do
|
49
|
+
equal_element = EqualElementMatcher.new("A", {}, "Test")
|
50
|
+
equal_element.matches?('<A></A>').should be_false
|
51
|
+
equal_element.failure_message.should == [%{Expected "<A></A>"\n}, %{to be a 'A' element with no attributes and "Test" as content}]
|
52
|
+
|
53
|
+
equal_element = EqualElementMatcher.new("A", {}, "")
|
54
|
+
equal_element.matches?('<A>Test</A>').should be_false
|
55
|
+
equal_element.failure_message.should == [%{Expected "<A>Test</A>"\n}, %{to be a 'A' element with no attributes and no content}]
|
56
|
+
|
57
|
+
equal_element = EqualElementMatcher.new("A", "HREF" => "http://www.example.com")
|
58
|
+
equal_element.matches?('<A>Test</A>').should be_false
|
59
|
+
equal_element.failure_message.should == [%{Expected "<A>Test</A>"\n}, %{to be a 'A' element with HREF="http://www.example.com" and any content}]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "provides a useful negative failure message" do
|
63
|
+
equal_element = EqualElementMatcher.new("A", {}, "Test")
|
64
|
+
equal_element.matches?('<A></A>').should be_false
|
65
|
+
equal_element.negative_failure_message.should == [%{Expected "<A></A>"\n}, %{not to be a 'A' element with no attributes and "Test" as content}]
|
66
|
+
|
67
|
+
equal_element = EqualElementMatcher.new("A", {}, "")
|
68
|
+
equal_element.matches?('<A>Test</A>').should be_false
|
69
|
+
equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"\n}, %{not to be a 'A' element with no attributes and no content}]
|
70
|
+
|
71
|
+
equal_element = EqualElementMatcher.new("A", "HREF" => "http://www.example.com")
|
72
|
+
equal_element.matches?('<A>Test</A>').should be_false
|
73
|
+
equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"\n}, %{not to be a 'A' element with HREF="http://www.example.com" and any content}]
|
74
|
+
end
|
75
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
2
|
require 'mspec/runner/actions/debug'
|
3
3
|
require 'mspec/runner/mspec'
|
4
|
+
require 'mspec/runner/context'
|
4
5
|
require 'mspec/runner/example'
|
5
6
|
|
6
7
|
describe DebugAction do
|
@@ -18,7 +19,7 @@ end
|
|
18
19
|
describe DebugAction, "#before" do
|
19
20
|
before :each do
|
20
21
|
MSpec.stub!(:read_tags).and_return([])
|
21
|
-
@state = ExampleState.new "Catch#me", "if you can"
|
22
|
+
@state = ExampleState.new ContextState.new("Catch#me"), "if you can"
|
22
23
|
end
|
23
24
|
|
24
25
|
it "does not invoke the debugger if the description does not match" do
|
@@ -18,7 +18,7 @@ end
|
|
18
18
|
describe GdbAction, "#before" do
|
19
19
|
before :each do
|
20
20
|
MSpec.stub!(:read_tags).and_return([])
|
21
|
-
@state = ExampleState.new "Catch#me", "if you can"
|
21
|
+
@state = ExampleState.new ContextState.new("Catch#me"), "if you can"
|
22
22
|
end
|
23
23
|
|
24
24
|
it "does not invoke the debugger if the description does not match" do
|
@@ -94,7 +94,7 @@ describe TagAction, "#before" do
|
|
94
94
|
action.exception?.should be_false
|
95
95
|
action.exception ExceptionState.new(nil, nil, Exception.new("Fail!"))
|
96
96
|
action.exception?.should be_true
|
97
|
-
action.before(ExampleState.new("describe", "it"))
|
97
|
+
action.before(ExampleState.new(ContextState.new("describe"), "it"))
|
98
98
|
action.exception?.should be_false
|
99
99
|
end
|
100
100
|
end
|
@@ -111,7 +111,8 @@ end
|
|
111
111
|
describe TagAction, "#after when action is :add" do
|
112
112
|
before :each do
|
113
113
|
MSpec.stub!(:read_tags).and_return([])
|
114
|
-
|
114
|
+
context = ContextState.new "Catch#me"
|
115
|
+
@state = ExampleState.new context, "if you can"
|
115
116
|
@tag = SpecTag.new "tag(comment):Catch#me if you can"
|
116
117
|
SpecTag.stub!(:new).and_return(@tag)
|
117
118
|
@exception = ExceptionState.new nil, nil, Exception.new("failed")
|
@@ -159,7 +160,8 @@ end
|
|
159
160
|
describe TagAction, "#after when action is :del" do
|
160
161
|
before :each do
|
161
162
|
MSpec.stub!(:read_tags).and_return([])
|
162
|
-
|
163
|
+
context = ContextState.new "Catch#me"
|
164
|
+
@state = ExampleState.new context, "if you can"
|
163
165
|
@tag = SpecTag.new "tag(comment):Catch#me if you can"
|
164
166
|
SpecTag.stub!(:new).and_return(@tag)
|
165
167
|
@exception = ExceptionState.new nil, nil, Exception.new("failed")
|
@@ -207,7 +209,8 @@ end
|
|
207
209
|
describe TagAction, "#finish" do
|
208
210
|
before :each do
|
209
211
|
$stdout = @out = IOStub.new
|
210
|
-
|
212
|
+
context = ContextState.new "Catch#me"
|
213
|
+
@state = ExampleState.new context, "if you can"
|
211
214
|
MSpec.stub!(:write_tag).and_return(true)
|
212
215
|
MSpec.stub!(:delete_tag).and_return(true)
|
213
216
|
end
|
data/spec/runner/context_spec.rb
CHANGED
@@ -5,43 +5,198 @@ require 'mspec/runner/mspec'
|
|
5
5
|
require 'mspec/mocks/mock'
|
6
6
|
require 'mspec/runner/context'
|
7
7
|
|
8
|
-
describe ContextState do
|
8
|
+
describe ContextState, "#describe" do
|
9
9
|
before :each do
|
10
|
-
@state = ContextState.new
|
10
|
+
@state = ContextState.new "C#m"
|
11
|
+
@proc = lambda { ScratchPad.record :a }
|
12
|
+
ScratchPad.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
it "evaluates the passed block" do
|
16
|
+
@state.describe(&@proc)
|
17
|
+
ScratchPad.recorded.should == :a
|
18
|
+
end
|
19
|
+
|
20
|
+
it "evaluates the passed block via #protect" do
|
21
|
+
@state.should_receive(:protect).with("C#m", @proc, false)
|
22
|
+
@state.describe(&@proc)
|
23
|
+
end
|
24
|
+
|
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)
|
29
|
+
@state.describe { }
|
30
|
+
end
|
31
|
+
|
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)
|
35
|
+
state.describe { }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe ContextState, "#shared?" do
|
40
|
+
it "returns false when the ContextState is not shared" do
|
41
|
+
ContextState.new("").shared?.should be_false
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns true when the ContextState is shared" do
|
45
|
+
ContextState.new("", {:shared => true}).shared?.should be_true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
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"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "returns a description string for self when passed a String" do
|
55
|
+
ContextState.new("SomeClass").to_s.should == "SomeClass"
|
56
|
+
end
|
57
|
+
|
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"
|
60
|
+
end
|
61
|
+
|
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"
|
64
|
+
end
|
65
|
+
|
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"
|
68
|
+
end
|
69
|
+
|
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"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe ContextState, "#description" do
|
76
|
+
before :each do
|
77
|
+
@state = ContextState.new "when empty"
|
78
|
+
@parent = ContextState.new "Toplevel"
|
79
|
+
end
|
80
|
+
|
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"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe ContextState, "#it" do
|
90
|
+
before :each do
|
91
|
+
@state = ContextState.new ""
|
11
92
|
@proc = lambda { }
|
12
93
|
end
|
13
94
|
|
14
|
-
it "
|
15
|
-
|
16
|
-
|
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)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe ContextState, "#examples" do
|
104
|
+
before :each do
|
105
|
+
@state = ContextState.new ""
|
106
|
+
end
|
107
|
+
|
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
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe ContextState, "#before" do
|
116
|
+
before :each do
|
117
|
+
@state = ContextState.new ""
|
118
|
+
@proc = lambda { }
|
17
119
|
end
|
18
120
|
|
19
|
-
it "records
|
121
|
+
it "records the block for :each" do
|
20
122
|
@state.before(:each, &@proc)
|
21
|
-
@state.
|
123
|
+
@state.before(:each).should == [@proc]
|
22
124
|
end
|
23
125
|
|
24
|
-
it "records
|
25
|
-
@state.
|
26
|
-
@state.
|
126
|
+
it "records the block for :all" do
|
127
|
+
@state.before(:all, &@proc)
|
128
|
+
@state.before(:all).should == [@proc]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe ContextState, "#after" do
|
133
|
+
before :each do
|
134
|
+
@state = ContextState.new ""
|
135
|
+
@proc = lambda { }
|
27
136
|
end
|
28
137
|
|
29
|
-
it "records
|
138
|
+
it "records the block for :each" do
|
30
139
|
@state.after(:each, &@proc)
|
31
|
-
@state.
|
140
|
+
@state.after(:each).should == [@proc]
|
141
|
+
end
|
142
|
+
|
143
|
+
it "records the block for :all" do
|
144
|
+
@state.after(:all, &@proc)
|
145
|
+
@state.after(:all).should == [@proc]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe ContextState, "#pre" do
|
150
|
+
before :each do
|
151
|
+
@a = lambda { }
|
152
|
+
@b = lambda { }
|
153
|
+
@c = lambda { }
|
154
|
+
|
155
|
+
parent = ContextState.new ""
|
156
|
+
parent.before(:each, &@c)
|
157
|
+
parent.before(:all, &@c)
|
158
|
+
|
159
|
+
@state = ContextState.new ""
|
160
|
+
@state.parent = parent
|
161
|
+
end
|
162
|
+
|
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]
|
167
|
+
end
|
168
|
+
|
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]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe ContextState, "#post" do
|
177
|
+
before :each do
|
178
|
+
@a = lambda { }
|
179
|
+
@b = lambda { }
|
180
|
+
@c = lambda { }
|
181
|
+
|
182
|
+
parent = ContextState.new ""
|
183
|
+
parent.after(:each, &@c)
|
184
|
+
parent.after(:all, &@c)
|
185
|
+
|
186
|
+
@state = ContextState.new ""
|
187
|
+
@state.parent = parent
|
32
188
|
end
|
33
189
|
|
34
|
-
it "
|
35
|
-
@state.
|
36
|
-
|
37
|
-
|
38
|
-
proc.should == @proc
|
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]
|
39
194
|
end
|
40
195
|
|
41
|
-
it "
|
42
|
-
@state.
|
43
|
-
@state.
|
44
|
-
@state.
|
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]
|
45
200
|
end
|
46
201
|
end
|
47
202
|
|
@@ -55,27 +210,116 @@ describe ContextState, "#protect" do
|
|
55
210
|
|
56
211
|
it "returns true and does execute any blocks if check is true and MSpec.pretend_mode? is true" do
|
57
212
|
MSpec.stub!(:pretend_mode?).and_return(true)
|
58
|
-
ContextState.new.protect("message", [@a, @b]).should be_true
|
213
|
+
ContextState.new("").protect("message", [@a, @b]).should be_true
|
59
214
|
ScratchPad.recorded.should == []
|
60
215
|
end
|
61
216
|
|
62
217
|
it "executes the blocks if MSpec.pretend_mode? is false" do
|
63
218
|
MSpec.stub!(:pretend_mode?).and_return(false)
|
64
|
-
ContextState.new.protect("message", [@a, @b])
|
219
|
+
ContextState.new("").protect("message", [@a, @b])
|
65
220
|
ScratchPad.recorded.should == [:a, :b]
|
66
221
|
end
|
67
222
|
|
68
223
|
it "executes the blocks if check is false" do
|
69
|
-
ContextState.new.protect("message", [@a, @b], false)
|
224
|
+
ContextState.new("").protect("message", [@a, @b], false)
|
70
225
|
ScratchPad.recorded.should == [:a, :b]
|
71
226
|
end
|
72
227
|
|
73
228
|
it "returns true if none of the blocks raise an exception" do
|
74
|
-
ContextState.new.protect("message", [@a, @b]).should be_true
|
229
|
+
ContextState.new("").protect("message", [@a, @b]).should be_true
|
75
230
|
end
|
76
231
|
|
77
232
|
it "returns false if any of the blocks raise an exception" do
|
78
|
-
ContextState.new.protect("message", [@a, @c, @b]).should be_false
|
233
|
+
ContextState.new("").protect("message", [@a, @c, @b]).should be_false
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe ContextState, "#parent=" do
|
238
|
+
before :each do
|
239
|
+
@state = ContextState.new ""
|
240
|
+
@parent = mock("describe")
|
241
|
+
@parent.stub!(:parent).and_return(nil)
|
242
|
+
@parent.stub!(:child)
|
243
|
+
end
|
244
|
+
|
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
|
249
|
+
end
|
250
|
+
|
251
|
+
it "sets self as a child of parent" do
|
252
|
+
@parent.should_receive(:child).with(@state)
|
253
|
+
@state.parent = @parent
|
254
|
+
end
|
255
|
+
|
256
|
+
it "creates the list of parents" do
|
257
|
+
@state.parent = @parent
|
258
|
+
@state.parents.should == [@parent, @state]
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe ContextState, "#parent" do
|
263
|
+
before :each do
|
264
|
+
@state = ContextState.new ""
|
265
|
+
@parent = mock("describe")
|
266
|
+
@parent.stub!(:parent).and_return(nil)
|
267
|
+
@parent.stub!(:child)
|
268
|
+
end
|
269
|
+
|
270
|
+
it "returns nil if parent has not been set" do
|
271
|
+
@state.parent.should be_nil
|
272
|
+
end
|
273
|
+
|
274
|
+
it "returns the parent" do
|
275
|
+
@state.parent = @parent
|
276
|
+
@state.parent.should == @parent
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
describe ContextState, "#parents" do
|
281
|
+
before :each do
|
282
|
+
@first = ContextState.new ""
|
283
|
+
@second = ContextState.new ""
|
284
|
+
@parent = mock("describe")
|
285
|
+
@parent.stub!(:parent).and_return(nil)
|
286
|
+
@parent.stub!(:child)
|
287
|
+
end
|
288
|
+
|
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]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe ContextState, "#child" do
|
297
|
+
before :each do
|
298
|
+
@first = ContextState.new ""
|
299
|
+
@second = ContextState.new ""
|
300
|
+
@parent = mock("describe")
|
301
|
+
@parent.stub!(:parent).and_return(nil)
|
302
|
+
@parent.stub!(:child)
|
303
|
+
end
|
304
|
+
|
305
|
+
it "adds the ContextState to the list of contained ContextStates" do
|
306
|
+
@first.child @second
|
307
|
+
@first.children.should == [@second]
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
describe ContextState, "#children" do
|
312
|
+
before :each do
|
313
|
+
@parent = ContextState.new ""
|
314
|
+
@first = ContextState.new ""
|
315
|
+
@second = ContextState.new ""
|
316
|
+
end
|
317
|
+
|
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]
|
79
323
|
end
|
80
324
|
end
|
81
325
|
|
@@ -84,7 +328,7 @@ describe ContextState, "#state" do
|
|
84
328
|
MSpec.store :before, []
|
85
329
|
MSpec.store :after, []
|
86
330
|
|
87
|
-
@state = ContextState.new
|
331
|
+
@state = ContextState.new ""
|
88
332
|
end
|
89
333
|
|
90
334
|
it "returns nil if no spec is being executed" do
|
@@ -93,7 +337,7 @@ describe ContextState, "#state" do
|
|
93
337
|
|
94
338
|
it "returns a ExampleState instance if an example is being executed" do
|
95
339
|
ScratchPad.record @state
|
96
|
-
@state.describe
|
340
|
+
@state.describe { }
|
97
341
|
@state.it("") { ScratchPad.record ScratchPad.recorded.state }
|
98
342
|
@state.process
|
99
343
|
@state.state.should == nil
|
@@ -105,9 +349,10 @@ describe ContextState, "#process" do
|
|
105
349
|
before :each do
|
106
350
|
MSpec.store :before, []
|
107
351
|
MSpec.store :after, []
|
352
|
+
MSpec.stub!(:register_current)
|
108
353
|
|
109
|
-
@state = ContextState.new
|
110
|
-
@state.describe
|
354
|
+
@state = ContextState.new ""
|
355
|
+
@state.describe { }
|
111
356
|
|
112
357
|
@a = lambda { ScratchPad << :a }
|
113
358
|
@b = lambda { ScratchPad << :b }
|
@@ -127,7 +372,7 @@ describe ContextState, "#process" do
|
|
127
372
|
@state.after(:all, &@b)
|
128
373
|
@state.it("") { }
|
129
374
|
@state.process
|
130
|
-
ScratchPad.recorded.should == [:
|
375
|
+
ScratchPad.recorded.should == [:b, :a]
|
131
376
|
end
|
132
377
|
|
133
378
|
it "calls each it block" do
|
@@ -137,6 +382,14 @@ describe ContextState, "#process" do
|
|
137
382
|
ScratchPad.recorded.should == [:a, :b]
|
138
383
|
end
|
139
384
|
|
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)
|
389
|
+
@state.process
|
390
|
+
ScratchPad.recorded.should == [:b]
|
391
|
+
end
|
392
|
+
|
140
393
|
it "calls each before(:each) block" do
|
141
394
|
@state.before(:each, &@a)
|
142
395
|
@state.before(:each, &@b)
|
@@ -150,7 +403,7 @@ describe ContextState, "#process" do
|
|
150
403
|
@state.after(:each, &@b)
|
151
404
|
@state.it("") { }
|
152
405
|
@state.process
|
153
|
-
ScratchPad.recorded.should == [:
|
406
|
+
ScratchPad.recorded.should == [:b, :a]
|
154
407
|
end
|
155
408
|
|
156
409
|
it "calls Mock.cleanup for each it block" do
|
@@ -169,14 +422,14 @@ describe ContextState, "#process" do
|
|
169
422
|
|
170
423
|
it "calls the describe block" do
|
171
424
|
ScratchPad.record []
|
172
|
-
@state.describe
|
425
|
+
@state.describe { ScratchPad << :a }
|
173
426
|
@state.process
|
174
427
|
ScratchPad.recorded.should == [:a]
|
175
428
|
end
|
176
429
|
|
177
430
|
it "creates a new ExampleState instance for each example" do
|
178
431
|
ScratchPad.record @state
|
179
|
-
@state.describe
|
432
|
+
@state.describe { }
|
180
433
|
@state.it("it") { ScratchPad.record ScratchPad.recorded.state }
|
181
434
|
@state.process
|
182
435
|
ScratchPad.recorded.should be_kind_of(ExampleState)
|
@@ -197,14 +450,45 @@ describe ContextState, "#process" do
|
|
197
450
|
@state.process
|
198
451
|
MSpec.randomize false
|
199
452
|
end
|
453
|
+
|
454
|
+
it "sets the current MSpec ContextState" do
|
455
|
+
MSpec.should_receive(:register_current).with(@state)
|
456
|
+
@state.process
|
457
|
+
end
|
458
|
+
|
459
|
+
it "resets the current MSpec ContextState to nil when there are examples" do
|
460
|
+
MSpec.should_receive(:register_current).with(nil)
|
461
|
+
@state.it("") { }
|
462
|
+
@state.process
|
463
|
+
end
|
464
|
+
|
465
|
+
it "resets the current MSpec ContextState to nil when there are no examples" do
|
466
|
+
MSpec.should_receive(:register_current).with(nil)
|
467
|
+
@state.process
|
468
|
+
end
|
469
|
+
|
470
|
+
it "call #process on children when there are examples" do
|
471
|
+
child = ContextState.new ""
|
472
|
+
child.should_receive(:process)
|
473
|
+
@state.child child
|
474
|
+
@state.it("") { }
|
475
|
+
@state.process
|
476
|
+
end
|
477
|
+
|
478
|
+
it "call #process on children when there are no examples" do
|
479
|
+
child = ContextState.new ""
|
480
|
+
child.should_receive(:process)
|
481
|
+
@state.child child
|
482
|
+
@state.process
|
483
|
+
end
|
200
484
|
end
|
201
485
|
|
202
486
|
describe ContextState, "#process" do
|
203
487
|
before :each do
|
204
488
|
MSpec.store :exception, []
|
205
489
|
|
206
|
-
@state = ContextState.new
|
207
|
-
@state.describe
|
490
|
+
@state = ContextState.new ""
|
491
|
+
@state.describe { }
|
208
492
|
|
209
493
|
action = mock("action")
|
210
494
|
def action.exception(exc)
|
@@ -243,8 +527,8 @@ describe ContextState, "#process" do
|
|
243
527
|
before :each do
|
244
528
|
MSpec.store :example, []
|
245
529
|
|
246
|
-
@state = ContextState.new
|
247
|
-
@state.describe
|
530
|
+
@state = ContextState.new ""
|
531
|
+
@state.describe { }
|
248
532
|
|
249
533
|
example = mock("example")
|
250
534
|
def example.example(state, spec)
|
@@ -279,8 +563,8 @@ describe ContextState, "#process" do
|
|
279
563
|
MSpec.store :before, []
|
280
564
|
MSpec.store :after, []
|
281
565
|
|
282
|
-
@state = ContextState.new
|
283
|
-
@state.describe
|
566
|
+
@state = ContextState.new ""
|
567
|
+
@state.describe { }
|
284
568
|
@state.it("") { MSpec.expectation }
|
285
569
|
end
|
286
570
|
|
@@ -314,16 +598,13 @@ describe ContextState, "#process" do
|
|
314
598
|
end
|
315
599
|
end
|
316
600
|
|
317
|
-
describe ContextState, "#process" do
|
318
|
-
end
|
319
|
-
|
320
601
|
describe ContextState, "#process" do
|
321
602
|
before :each do
|
322
603
|
MSpec.store :enter, []
|
323
604
|
MSpec.store :leave, []
|
324
605
|
|
325
|
-
@state = ContextState.new
|
326
|
-
@state.describe
|
606
|
+
@state = ContextState.new "C#m"
|
607
|
+
@state.describe { }
|
327
608
|
@state.it("") { MSpec.expectation }
|
328
609
|
end
|
329
610
|
|
@@ -334,7 +615,7 @@ describe ContextState, "#process" do
|
|
334
615
|
|
335
616
|
it "calls registered enter actions with the current #describe string" do
|
336
617
|
enter = mock("enter")
|
337
|
-
enter.should_receive(:enter).and_return { ScratchPad.record :enter }
|
618
|
+
enter.should_receive(:enter).with("C#m").and_return { ScratchPad.record :enter }
|
338
619
|
MSpec.register :enter, enter
|
339
620
|
@state.process
|
340
621
|
ScratchPad.recorded.should == :enter
|
@@ -354,8 +635,8 @@ describe ContextState, "#process when an exception is raised in before(:all)" do
|
|
354
635
|
MSpec.store :before, []
|
355
636
|
MSpec.store :after, []
|
356
637
|
|
357
|
-
@state = ContextState.new
|
358
|
-
@state.describe
|
638
|
+
@state = ContextState.new ""
|
639
|
+
@state.describe { }
|
359
640
|
|
360
641
|
@a = lambda { ScratchPad << :a }
|
361
642
|
@b = lambda { ScratchPad << :b }
|
@@ -414,8 +695,8 @@ describe ContextState, "#process when an exception is raised in before(:each)" d
|
|
414
695
|
MSpec.store :before, []
|
415
696
|
MSpec.store :after, []
|
416
697
|
|
417
|
-
@state = ContextState.new
|
418
|
-
@state.describe
|
698
|
+
@state = ContextState.new ""
|
699
|
+
@state.describe { }
|
419
700
|
|
420
701
|
@a = lambda { ScratchPad << :a }
|
421
702
|
@b = lambda { ScratchPad << :b }
|
@@ -463,8 +744,8 @@ describe ContextState, "#process in pretend mode" do
|
|
463
744
|
MSpec.store :before, []
|
464
745
|
MSpec.store :after, []
|
465
746
|
|
466
|
-
@state = ContextState.new
|
467
|
-
@state.describe
|
747
|
+
@state = ContextState.new ""
|
748
|
+
@state.describe { }
|
468
749
|
@state.it("") { }
|
469
750
|
end
|
470
751
|
|
@@ -511,8 +792,8 @@ describe ContextState, "#process in pretend mode" do
|
|
511
792
|
MSpec.store :before, []
|
512
793
|
MSpec.store :after, []
|
513
794
|
|
514
|
-
@state = ContextState.new
|
515
|
-
@state.describe
|
795
|
+
@state = ContextState.new ""
|
796
|
+
@state.describe { }
|
516
797
|
|
517
798
|
@a = lambda { ScratchPad << :a }
|
518
799
|
@b = lambda { ScratchPad << :b }
|
@@ -521,7 +802,7 @@ describe ContextState, "#process in pretend mode" do
|
|
521
802
|
|
522
803
|
it "calls the describe block" do
|
523
804
|
ScratchPad.record []
|
524
|
-
@state.describe
|
805
|
+
@state.describe { ScratchPad << :a }
|
525
806
|
@state.process
|
526
807
|
ScratchPad.recorded.should == [:a]
|
527
808
|
end
|
@@ -586,8 +867,8 @@ describe ContextState, "#process in pretend mode" do
|
|
586
867
|
MSpec.store :enter, []
|
587
868
|
MSpec.store :leave, []
|
588
869
|
|
589
|
-
@state = ContextState.new
|
590
|
-
@state.describe
|
870
|
+
@state = ContextState.new ""
|
871
|
+
@state.describe { }
|
591
872
|
@state.it("") { }
|
592
873
|
end
|
593
874
|
|
@@ -612,3 +893,87 @@ describe ContextState, "#process in pretend mode" do
|
|
612
893
|
ScratchPad.recorded.should == :leave
|
613
894
|
end
|
614
895
|
end
|
896
|
+
|
897
|
+
describe ContextState, "#it_should_behave_like" do
|
898
|
+
before :each do
|
899
|
+
@shared = ContextState.new("", :shared => true)
|
900
|
+
MSpec.stub!(:retrieve_shared).and_return(@shared)
|
901
|
+
|
902
|
+
@state = ContextState.new ""
|
903
|
+
@a = lambda { }
|
904
|
+
@b = lambda { }
|
905
|
+
end
|
906
|
+
|
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)
|
910
|
+
end
|
911
|
+
|
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)
|
917
|
+
end
|
918
|
+
|
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 ""
|
924
|
+
end
|
925
|
+
|
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))
|
931
|
+
end
|
932
|
+
|
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))
|
938
|
+
end
|
939
|
+
|
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))
|
945
|
+
end
|
946
|
+
|
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))
|
952
|
+
end
|
953
|
+
end
|
954
|
+
|
955
|
+
describe ContextState, "#filter_examples" do
|
956
|
+
before :each do
|
957
|
+
@state = ContextState.new ""
|
958
|
+
@state.it("one") { }
|
959
|
+
@state.it("two") { }
|
960
|
+
end
|
961
|
+
|
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
|
967
|
+
end
|
968
|
+
|
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
|
972
|
+
end
|
973
|
+
|
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
|
978
|
+
end
|
979
|
+
end
|