evented-spec 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +30 -0
- data/HISTORY +97 -0
- data/LICENSE +20 -0
- data/README.textile +162 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/lib/amqp-spec.rb +5 -0
- data/lib/evented-spec.rb +2 -0
- data/lib/evented-spec/amqp.rb +27 -0
- data/lib/evented-spec/evented_example.rb +61 -0
- data/lib/evented-spec/evented_example/amqp_example.rb +52 -0
- data/lib/evented-spec/evented_example/coolio_example.rb +97 -0
- data/lib/evented-spec/evented_example/em_example.rb +87 -0
- data/lib/evented-spec/rspec.rb +267 -0
- data/lib/evented-spec/util.rb +32 -0
- data/lib/evented-spec/version.rb +8 -0
- data/spec/cool_io_spec.rb +72 -0
- data/spec/em_defaults_spec.rb +132 -0
- data/spec/em_hooks_spec.rb +231 -0
- data/spec/em_metadata_spec.rb +43 -0
- data/spec/failing_rspec_spec.rb +63 -0
- data/spec/rspec_amqp_spec.rb +116 -0
- data/spec/rspec_em_spec.rb +53 -0
- data/spec/shared_examples.rb +194 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/util_spec.rb +51 -0
- data/tasks/common.rake +18 -0
- data/tasks/doc.rake +14 -0
- data/tasks/gem.rake +40 -0
- data/tasks/git.rake +34 -0
- data/tasks/spec.rake +15 -0
- data/tasks/version.rake +71 -0
- metadata +149 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module EventedSpec
|
2
|
+
# Miscellanous utility methods used throughout the code.
|
3
|
+
module Util
|
4
|
+
extend self
|
5
|
+
|
6
|
+
# Creates a deep clone of an object. Different from normal Object#clone
|
7
|
+
# method which is shallow clone (doesn't traverse hashes and arrays,
|
8
|
+
# cloning their contents).
|
9
|
+
#
|
10
|
+
# @param Object to clone
|
11
|
+
# @return Deep clone of the given object
|
12
|
+
def deep_clone(value)
|
13
|
+
case value
|
14
|
+
when Hash
|
15
|
+
value.inject({}) do |result, kv|
|
16
|
+
result[kv[0]] = deep_clone(kv[1])
|
17
|
+
result
|
18
|
+
end
|
19
|
+
when Array
|
20
|
+
value.inject([]) do |result, item|
|
21
|
+
result << deep_clone(item)
|
22
|
+
end
|
23
|
+
else
|
24
|
+
begin
|
25
|
+
value.clone
|
26
|
+
rescue TypeError
|
27
|
+
value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end # deep_clone
|
31
|
+
end # module Util
|
32
|
+
end # module EventedSpec
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe EventedSpec::SpecHelper, "Cool.io bindings" do
|
5
|
+
include EventedSpec::SpecHelper
|
6
|
+
default_timeout 0.1
|
7
|
+
let(:event_loop) { Coolio::Loop.default }
|
8
|
+
|
9
|
+
after(:each) {
|
10
|
+
event_loop.instance_variable_get(:@running).should be_false
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "#coolio" do
|
14
|
+
it "should execute given block in the right scope" do
|
15
|
+
coolio do
|
16
|
+
@variable = true
|
17
|
+
done
|
18
|
+
end
|
19
|
+
@variable.should be_true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should start default cool.io loop and give control" do
|
23
|
+
coolio do
|
24
|
+
event_loop.instance_variable_get(:@running).should be_true
|
25
|
+
done
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should stop the event loop afterwards" do
|
30
|
+
coolio do
|
31
|
+
@do_something_useful = true
|
32
|
+
done
|
33
|
+
end
|
34
|
+
event_loop.instance_variable_get(:@running).should be_false
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should raise SpecTimeoutExceededError when #done is not issued" do
|
38
|
+
expect {
|
39
|
+
coolio do
|
40
|
+
end
|
41
|
+
}.to raise_error(EventedSpec::SpecHelper::SpecTimeoutExceededError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should propagate mismatched rspec expectations" do
|
45
|
+
expect {
|
46
|
+
coolio do
|
47
|
+
:fail.should == :win
|
48
|
+
end
|
49
|
+
}.to raise_error(RSPEC::Expectations::ExpectationNotMetError)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
describe "#done" do
|
55
|
+
it "should execute given block" do
|
56
|
+
coolio do
|
57
|
+
done(0.05) do
|
58
|
+
@variable = true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
@variable.should be_true
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should cancel timeout" do
|
65
|
+
expect {
|
66
|
+
coolio do
|
67
|
+
done(0.2)
|
68
|
+
end
|
69
|
+
}.to_not raise_error
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EventedSpec::SpecHelper, " .default_options" do
|
4
|
+
include EventedSpec::SpecHelper
|
5
|
+
root_default_options = {:root_key => 1}
|
6
|
+
default_options root_default_options
|
7
|
+
|
8
|
+
it 'subsequent and nested groups should not change root default options' do
|
9
|
+
root_default_options.should == {:root_key => 1}
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'example has access to default options' do
|
13
|
+
default_options.should == root_default_options
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'defaults can be changed inside example, diverging from example group defaults' do
|
17
|
+
default_options[:example_key] = :example_value
|
18
|
+
default_options.should have_key :example_key
|
19
|
+
default_options.should_not == root_default_options
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'changing example defaults has no effect on subsequent examples' do
|
23
|
+
default_options.should_not have_key :example_key
|
24
|
+
default_options.should == root_default_options
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'inside nested example group 1' do
|
28
|
+
nested_default_options = default_options
|
29
|
+
|
30
|
+
it 'nested group defaults start as a copy of enclosing group default_options' do
|
31
|
+
nested_default_options.should == root_default_options
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'example has access to default options' do
|
35
|
+
default_options.should == nested_default_options
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'can be changed, thus diverging from example group default_options' do
|
39
|
+
default_options[:example_key] = :example_value
|
40
|
+
default_options.should have_key :example_key
|
41
|
+
default_options.should_not == root_default_options
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'changing example default_options has no effect on subsequent examples' do
|
45
|
+
default_options.should_not have_key :example_key
|
46
|
+
default_options.should == root_default_options
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'inside deeply nested example group 1' do
|
50
|
+
nested_default_options = default_options
|
51
|
+
|
52
|
+
it 'nested group defaults start as a copy of enclosing group default_options' do
|
53
|
+
nested_default_options.should == root_default_options
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'example has access to default options' do
|
57
|
+
default_options.should == nested_default_options
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'can be changed in example, thus diverging from example group default_options' do
|
61
|
+
default_options[:example_key] = :example_value
|
62
|
+
default_options.should have_key :example_key
|
63
|
+
default_options.should_not == nested_default_options
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'changing example default_options has no effect on subsequent examples' do
|
67
|
+
default_options.should_not have_key :example_key
|
68
|
+
default_options.should == nested_default_options
|
69
|
+
end
|
70
|
+
end # inside deeply nested example group 1
|
71
|
+
end # inside nested example group 1
|
72
|
+
|
73
|
+
context 'inside nested example group 2' do
|
74
|
+
default_options[:nested_key] = :nested_value
|
75
|
+
nested_default_options = default_options
|
76
|
+
|
77
|
+
it 'changing default options inside nested group works' do
|
78
|
+
nested_default_options.should have_key :nested_key
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'changing default_options in nested group affects example default_options' do
|
82
|
+
default_options.should == nested_default_options
|
83
|
+
default_options.should_not == root_default_options
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'can be changed in example, thus diverging from example group default_options' do
|
87
|
+
default_options[:example_key] = :example_value
|
88
|
+
default_options.should have_key :example_key
|
89
|
+
default_options.should have_key :nested_key
|
90
|
+
default_options.should_not == nested_default_options
|
91
|
+
default_options.should_not == root_default_options
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'changing example default_options has no effect on subsequent examples' do
|
95
|
+
default_options.should == nested_default_options
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'inside deeply nested example group 2' do
|
99
|
+
default_options[:deeply_nested_key] = :deeply_nested_value
|
100
|
+
deeply_nested_default_options = default_options
|
101
|
+
|
102
|
+
it 'inherits default options from enclosing group' do
|
103
|
+
deeply_nested_default_options.should have_key :nested_key
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'changing default options inside deeply nested group works' do
|
107
|
+
deeply_nested_default_options.should have_key :deeply_nested_key
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'changing default_options in nested group affects example group default_options' do
|
111
|
+
default_options.should == deeply_nested_default_options
|
112
|
+
default_options.should have_key :nested_key
|
113
|
+
default_options.should have_key :deeply_nested_key
|
114
|
+
default_options.should_not == nested_default_options
|
115
|
+
default_options.should_not == root_default_options
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'can be changed in example, thus diverging from example group default_options' do
|
119
|
+
default_options[:example_key] = :example_value
|
120
|
+
default_options.should have_key :example_key
|
121
|
+
default_options.should have_key :nested_key
|
122
|
+
default_options.should have_key :deeply_nested_key
|
123
|
+
default_options.should_not == nested_default_options
|
124
|
+
default_options.should_not == root_default_options
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'changing example default_options has no effect on subsequent examples' do
|
128
|
+
default_options.should == deeply_nested_default_options
|
129
|
+
end
|
130
|
+
end # inside deeply nested example group 2
|
131
|
+
end # inside nested example group 2
|
132
|
+
end # describe AMQP, "default_options"
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Registers specific hook type as being called,
|
4
|
+
# sets expectations about EM reactor and AMQP connection state
|
5
|
+
module HookHelper
|
6
|
+
def hook(type, reactor, connection)
|
7
|
+
@hooks_called << type.to_sym if type
|
8
|
+
if :reactor_running == reactor
|
9
|
+
EM.reactor_running?.should be_true
|
10
|
+
else
|
11
|
+
EM.reactor_running?.should be_false
|
12
|
+
end
|
13
|
+
if :amqp_connected == connection
|
14
|
+
AMQP.connection.should be_connected
|
15
|
+
else
|
16
|
+
if AMQP.connection
|
17
|
+
AMQP.connection.connected?.should be_false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
shared_examples_for 'hooked em specs' do
|
24
|
+
it 'should execute em_before' do
|
25
|
+
em do
|
26
|
+
@hooks_called.should include :em_before
|
27
|
+
@hooks_called.should_not include :em_after
|
28
|
+
done
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should execute em_after if business exception is raised' do
|
33
|
+
# Expectation is set in after{} hook
|
34
|
+
em do
|
35
|
+
expect {
|
36
|
+
raise StandardError
|
37
|
+
}.to raise_error
|
38
|
+
done
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should execute em_after if RSpec expectation fails' do
|
43
|
+
# Expectation is set in after{} hook
|
44
|
+
em do
|
45
|
+
expect { :this.should == :fail
|
46
|
+
}.to raise_error RSPEC::Expectations::ExpectationNotMetError
|
47
|
+
done
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
shared_examples_for 'hooked amqp specs' do
|
53
|
+
it 'should execute em_before' do
|
54
|
+
amqp do
|
55
|
+
@hooks_called.should include :em_before
|
56
|
+
@hooks_called.should_not include :em_after
|
57
|
+
@hooks_called.should include :amqp_before
|
58
|
+
@hooks_called.should_not include :amqp_after
|
59
|
+
done
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should execute em_after if business exception is raised' do
|
64
|
+
# Expectation is set in after{} hook
|
65
|
+
amqp do
|
66
|
+
expect {
|
67
|
+
raise StandardError
|
68
|
+
}.to raise_error
|
69
|
+
done
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should execute em_after if RSpec expectation fails' do
|
74
|
+
# Expectation is set in after{} hook
|
75
|
+
amqp do
|
76
|
+
expect { :this.should == :fail
|
77
|
+
}.to raise_error RSPEC::Expectations::ExpectationNotMetError
|
78
|
+
done
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe EventedSpec::SpecHelper, ".em_before/.em_after" do
|
84
|
+
before { @hooks_called = [] }
|
85
|
+
include HookHelper
|
86
|
+
describe AMQP, " tested with EventedSpec::SpecHelper" do
|
87
|
+
include EventedSpec::SpecHelper
|
88
|
+
default_options AMQP_OPTS if defined? AMQP_OPTS
|
89
|
+
|
90
|
+
before { hook :before, :reactor_not_running, :amqp_not_connected }
|
91
|
+
em_before { hook :em_before, :reactor_running, :amqp_not_connected }
|
92
|
+
em_after { hook(:em_after, :reactor_running, :amqp_not_connected) }
|
93
|
+
|
94
|
+
context 'for non-evented specs' do
|
95
|
+
after {
|
96
|
+
@hooks_called.should == [:before]
|
97
|
+
hook :after, :reactor_not_running, :amqp_not_connected }
|
98
|
+
|
99
|
+
it 'should NOT execute em_before or em_after' do
|
100
|
+
@hooks_called.should_not include :em_before
|
101
|
+
@hooks_called.should_not include :em_after
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should NOT execute em_after if business exception is raised' do
|
105
|
+
expect { raise StandardError
|
106
|
+
}.to raise_error
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should execute em_after if RSpec expectation fails' do
|
110
|
+
expect { :this.should == :fail
|
111
|
+
}.to raise_error RSPEC::Expectations::ExpectationNotMetError
|
112
|
+
end
|
113
|
+
end # context 'for non-evented specs'
|
114
|
+
|
115
|
+
context 'for evented specs' do #, pending: true do
|
116
|
+
after do
|
117
|
+
@hooks_called.should include :before, :em_before, :em_after
|
118
|
+
hook :after, :reactor_not_running, :amqp_not_connected
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'with em block' do
|
122
|
+
|
123
|
+
it_should_behave_like 'hooked em specs'
|
124
|
+
|
125
|
+
it 'should not run nested em hooks' do
|
126
|
+
em do
|
127
|
+
@hooks_called.should_not include :context_em_before, :context_before
|
128
|
+
done
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should not run hooks from unrelated group' do
|
133
|
+
em do
|
134
|
+
@hooks_called.should_not include :amqp_context_em_before,
|
135
|
+
:amqp_context_before,
|
136
|
+
:amqp_before,
|
137
|
+
:context_amqp_before
|
138
|
+
done
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'inside nested example group' do
|
143
|
+
before { hook :context_before, :reactor_not_running, :amqp_not_connected }
|
144
|
+
em_before { hook :context_em_before, :reactor_running, :amqp_not_connected }
|
145
|
+
em_after { hook :context_em_after, :reactor_running, :amqp_not_connected }
|
146
|
+
|
147
|
+
after do
|
148
|
+
@hooks_called.should include :before,
|
149
|
+
:context_before,
|
150
|
+
:em_before,
|
151
|
+
:context_em_before,
|
152
|
+
:context_em_after,
|
153
|
+
:em_after
|
154
|
+
hook :after, :reactor_not_running, :amqp_not_connected
|
155
|
+
end
|
156
|
+
|
157
|
+
it_should_behave_like 'hooked em specs'
|
158
|
+
|
159
|
+
it 'should fire all nested :before hooks, but no :after hooks' do
|
160
|
+
em do
|
161
|
+
@hooks_called.should == [:before,
|
162
|
+
:context_before,
|
163
|
+
:em_before,
|
164
|
+
:context_em_before]
|
165
|
+
done
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end # context 'inside nested example group'
|
170
|
+
end # context 'with em block'
|
171
|
+
|
172
|
+
context 'with amqp block' do
|
173
|
+
amqp_before { hook :amqp_before, :reactor_running, :amqp_connected }
|
174
|
+
amqp_after { hook :amqp_after, :reactor_running, :amqp_connected }
|
175
|
+
|
176
|
+
it_should_behave_like 'hooked amqp specs'
|
177
|
+
|
178
|
+
it 'should not run nested em hooks' do
|
179
|
+
amqp do
|
180
|
+
@hooks_called.should_not include :amqp_context_before,
|
181
|
+
:amqp_context_em_before,
|
182
|
+
:context_amqp_before
|
183
|
+
done
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should not run hooks from unrelated group' do
|
188
|
+
amqp do
|
189
|
+
@hooks_called.should_not include :context_em_before, :context_before
|
190
|
+
done
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'inside nested example group' do
|
195
|
+
before { hook :amqp_context_before, :reactor_not_running, :amqp_not_connected }
|
196
|
+
em_before { hook :amqp_context_em_before, :reactor_running, :amqp_not_connected }
|
197
|
+
em_after { hook :amqp_context_em_after, :reactor_running, :amqp_not_connected }
|
198
|
+
amqp_before { hook :context_amqp_before, :reactor_running, :amqp_connected }
|
199
|
+
amqp_after { hook :context_amqp_after, :reactor_running, :amqp_connected }
|
200
|
+
|
201
|
+
after { @hooks_called.should == [:before,
|
202
|
+
:amqp_context_before,
|
203
|
+
:em_before,
|
204
|
+
:amqp_context_em_before,
|
205
|
+
:amqp_before,
|
206
|
+
:context_amqp_before,
|
207
|
+
:context_amqp_after,
|
208
|
+
:amqp_after,
|
209
|
+
:amqp_context_em_after,
|
210
|
+
:em_after]
|
211
|
+
hook :after, :reactor_not_running, :amqp_not_connected }
|
212
|
+
|
213
|
+
it_should_behave_like 'hooked amqp specs'
|
214
|
+
|
215
|
+
it 'should fire all :before hooks in correct order' do
|
216
|
+
amqp do
|
217
|
+
@hooks_called.should == [:before,
|
218
|
+
:amqp_context_before,
|
219
|
+
:em_before,
|
220
|
+
:amqp_context_em_before,
|
221
|
+
:amqp_before,
|
222
|
+
:context_amqp_before]
|
223
|
+
done
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
end # context 'inside nested example group'
|
228
|
+
end # context 'with amqp block'
|
229
|
+
end # context 'for evented specs'
|
230
|
+
end # describe EventedSpec, " tested with EventedSpec::SpecHelper"
|
231
|
+
end # describe EventedSpec, " with em_before/em_after"
|