evented-spec 0.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/.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"
|