mspec 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|