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
data/.gitignore
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## PROJECT::GENERAL
|
17
|
+
*.rbc
|
18
|
+
*.class
|
19
|
+
coverage
|
20
|
+
config
|
21
|
+
rdoc
|
22
|
+
pkg
|
23
|
+
log
|
24
|
+
.idea
|
25
|
+
.rvmrc
|
26
|
+
.bundle
|
27
|
+
Gemfile.lock
|
28
|
+
|
29
|
+
## PROJECT::SPECIFIC
|
30
|
+
spec/amqp.yml
|
data/HISTORY
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
== 0.0.0 / 2010-10-13
|
2
|
+
|
3
|
+
* Birthday!
|
4
|
+
|
5
|
+
== 0.0.1 / 2010-10-13
|
6
|
+
|
7
|
+
* Initial code import from EM-Spec and AMQPHelper
|
8
|
+
|
9
|
+
== 0.0.2 / 2010-10-13
|
10
|
+
|
11
|
+
* Minimal functionality implemented
|
12
|
+
|
13
|
+
== 0.0.4 / 2010-10-14
|
14
|
+
|
15
|
+
* Problems with default_options resolved
|
16
|
+
|
17
|
+
== 0.1.0 / 2010-10-15
|
18
|
+
|
19
|
+
* Monkeypatched start/stop_connection directly into AMQP
|
20
|
+
|
21
|
+
== 0.1.2 / 2010-10-15
|
22
|
+
|
23
|
+
* Cleanup in AMQP.cleanup
|
24
|
+
|
25
|
+
== 0.1.3 / 2010-10-15
|
26
|
+
|
27
|
+
* Make sure Thread.current[:mq] state is cleaned after each example
|
28
|
+
|
29
|
+
== 0.1.7 / 2010-10-15
|
30
|
+
|
31
|
+
* em interface improved for timeout arg
|
32
|
+
|
33
|
+
== 0.1.11 / 2010-10-18
|
34
|
+
|
35
|
+
* Optional delay added to done
|
36
|
+
|
37
|
+
== 0.2.0 / 2010-10-28
|
38
|
+
|
39
|
+
* Rspec 2 support added
|
40
|
+
|
41
|
+
== 0.2.2 / 2010-10-31
|
42
|
+
|
43
|
+
* Metadata in Rspec 1
|
44
|
+
|
45
|
+
== 0.2.7 / 2010-11-04
|
46
|
+
|
47
|
+
* Make AMQP.cleanup_state more thorough
|
48
|
+
|
49
|
+
== 0.2.8 / 2010-11-15
|
50
|
+
|
51
|
+
* syncronize method added for wrapping async calls
|
52
|
+
|
53
|
+
== 0.2.9 / 2010-11-16
|
54
|
+
|
55
|
+
* Fallback to a separate default timeout
|
56
|
+
|
57
|
+
== 0.3.0 / 2010-11-16
|
58
|
+
|
59
|
+
* Hooks em_before/em_after implemented
|
60
|
+
|
61
|
+
== 0.3.1 / 2010-11-17
|
62
|
+
|
63
|
+
* Documentation cleanup
|
64
|
+
|
65
|
+
== 0.3.2 / 2010-11-23
|
66
|
+
|
67
|
+
* EM hooks now working as they should - bugs fixed
|
68
|
+
|
69
|
+
== 0.3.3 / 2010-11-24
|
70
|
+
|
71
|
+
* Spec timeout refactored
|
72
|
+
|
73
|
+
== 0.3.4 / 2010-11-26
|
74
|
+
|
75
|
+
* amqp_before/after hooks added
|
76
|
+
|
77
|
+
== 0.3.5 / 2011-01-07
|
78
|
+
|
79
|
+
* Drop-in support for legacy em-spec based examples added
|
80
|
+
|
81
|
+
== 0.3.6 / 2011-01-07
|
82
|
+
|
83
|
+
* Changed Gemfile to avoid circular dependency on AMQP
|
84
|
+
|
85
|
+
== 0.3.7 / 2011-01-07
|
86
|
+
|
87
|
+
* Changed Gemspec to avoid circular dependency on AMQP
|
88
|
+
|
89
|
+
== 0.3.8 / 2011-01-25
|
90
|
+
|
91
|
+
* MRI 1.8.7 support added
|
92
|
+
|
93
|
+
== 0.4.0 / 2011-03-13
|
94
|
+
|
95
|
+
* Forked into evented-spec.
|
96
|
+
* cool.io support
|
97
|
+
* Using amqp 0.8.* API instead of 0.7.*
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Arvicco
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
h2. About evented-spec
|
2
|
+
|
3
|
+
Evented-spec is a set of helpers to help you test your asynchronous code.
|
4
|
+
|
5
|
+
EventMachine/Cool.io-based code, including asynchronous "AMQP library":https://github.com/ruby-amqp/ruby-amqp is notoriously difficult to test. To the point that many people recommend using either "mocks":https://github.com/danielsdeleo/moqueue or "synchronous libraries":https://github.com/ruby-amqp/bunny instead of EM-based libraries in unit tests. This is not always an option, however -- sometimes your code just has to run inside the event loop, and you want to test a real thing, not just mocks.
|
6
|
+
|
7
|
+
"em-spec":https://github.com/tmm1/em-spec gem made it easier to write evented specs, but it has several drawbacks. First, it is not easy to manage both EM.run and AMQP.start loops at the same time. Second, AMQP is not properly stopped and deactivated upon exceptions and timeouts, resulting in state leak between examples and multiple mystereous failures. amqp-spec, and, subsequently, evented-spec add more helpers to keep your specs from being bloated.
|
8
|
+
|
9
|
+
h2. Usage
|
10
|
+
|
11
|
+
To get started with evented-spec you need to include one of the helper modules in your example groups, e.g.:
|
12
|
+
|
13
|
+
bc. describe "eventmachine-based client" do
|
14
|
+
include EventedSpec::SpecHelper
|
15
|
+
it "should allow you to start a reactor" do
|
16
|
+
em do
|
17
|
+
EventMachine.reactor_running?.should be_true
|
18
|
+
done
|
19
|
+
end
|
20
|
+
end
|
21
|
+
context "nested contexts" do
|
22
|
+
it "don't require another include" do
|
23
|
+
em do
|
24
|
+
EventMachine.add_timer(0.1) { @timer_run = true }
|
25
|
+
done(0.3)
|
26
|
+
end
|
27
|
+
@timer_run.should be_true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Particular modules and methods are explained below.
|
33
|
+
|
34
|
+
h3. #done
|
35
|
+
|
36
|
+
We have no means to know when your work with reactor is finished, so whatever it is you need to call @done@ at some point. It optionally accepts a timeout and a block that is executed right before event reactor loop is stopped. If you don't call @done@, your specs are going to fail by timeout.
|
37
|
+
|
38
|
+
h3. EventedSpec::SpecHelper
|
39
|
+
|
40
|
+
@EventedSpec::SpecHelper@ is for semi-manual managing of reactor life-cycle. It includes three helpers: for EventMachine, Coolio and AMQP.
|
41
|
+
|
42
|
+
@em@ stands for EventMachine. It takes a block, which is run after reactor starts.
|
43
|
+
|
44
|
+
@amqp@ stands for AMQP. It takes a block, which is run after amqp connects with broker using given or default options.
|
45
|
+
|
46
|
+
@coolio@ stands for cool.io. It takes a block, which is run after reactor starts.
|
47
|
+
|
48
|
+
All three accept a hash of options. Look into method documentation to learn more.
|
49
|
+
|
50
|
+
h3. EventedSpec::EMSpec, EventedSpec::AMQPSpec
|
51
|
+
|
52
|
+
@EventedSpec::EMSpec@ wraps every example in em block, so it might save you a couple of lines per example. @EventedSpec::AMQPSpec@ wraps every example in amqp block.
|
53
|
+
|
54
|
+
Also note that every example group including @EMSpec@ or @AMQPSpec@ automatically includes @SpecHelper@.
|
55
|
+
|
56
|
+
Example:
|
57
|
+
|
58
|
+
bc. describe "eventmachine specs" do
|
59
|
+
include EventedSpec::EMSpec
|
60
|
+
it "should run in a reactor" do
|
61
|
+
EventMachine.reactor_running?.should be_true
|
62
|
+
done # don't forget to finish your specs properly!
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
h3. default_options, default_timeout
|
68
|
+
|
69
|
+
You can also pass some default options to specs (like amqp settings), they're specific to domain you're using evented-spec in.
|
70
|
+
|
71
|
+
@default_timeout@ sets time (in seconds) for specs to time out
|
72
|
+
|
73
|
+
bc. describe "using default_timeout" do
|
74
|
+
include EventedSpec::SpecHelper
|
75
|
+
default_timeout 0.5
|
76
|
+
it "should prevent specs from hanging up" do
|
77
|
+
em do
|
78
|
+
1.should == 1 # this spec is going to fail with timeout error because #done is not called
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
h2. Hooks
|
85
|
+
|
86
|
+
There are 4 hooks available to evented specs:
|
87
|
+
|
88
|
+
* @em_before@ -- launches after reactor started, before example runs
|
89
|
+
* @em_after@ -- launches right before reactor is stopped, after example runs
|
90
|
+
* @amqp_before@ -- launches after amqp connects, before example runs
|
91
|
+
* @amqp_after@ -- launches before amqp disconnects, after example runs
|
92
|
+
|
93
|
+
So, the order of hooks is as follows: @before(:all)@, @before(:each)@,
|
94
|
+
@em_before@, @amqp_before@, example, @amqp_after@, @em_after@, @after(:each)@,
|
95
|
+
@after(:all)@
|
96
|
+
|
97
|
+
bc. describe "using amqp hooks" do
|
98
|
+
include EventedSpec::AMQPSpec
|
99
|
+
default_timeout 0.5
|
100
|
+
amqp_before do
|
101
|
+
AMQP.connection.should_not be_nil
|
102
|
+
end
|
103
|
+
let(:data) { "Test string" }
|
104
|
+
it "should do something useful" do
|
105
|
+
AMQP::Channel.new do |channel, _|
|
106
|
+
exchange = channel.direct("amqp-test-exchange")
|
107
|
+
queue = channel.queue("amqp-test-queue").bind(exchange)
|
108
|
+
queue.subscribe do |hdr, msg|
|
109
|
+
hdr.should be_an AMQP::Header
|
110
|
+
msg.should == data
|
111
|
+
done { queue.unsubscribe; queue.delete }
|
112
|
+
end
|
113
|
+
EM.add_timer(0.2) do
|
114
|
+
exchange.publish data
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
h2. AMQP gem compatibility
|
121
|
+
|
122
|
+
AMQP spec helpers are for newer version of AMQP gem, 0.8. If you need spec-helpers for AMQP gem 0.7, take a look at "amqp-spec":https://github.com/ruby-amqp/amqp-spec, API is mostly the same.
|
123
|
+
|
124
|
+
h2. Words of warning on blocking the reactor
|
125
|
+
|
126
|
+
Evented specs are currently run inside of reactor thread. What this effectively means is that you *should not block* during spec execution.
|
127
|
+
|
128
|
+
For example, the following *will not* work:
|
129
|
+
|
130
|
+
bc. describe "using amqp" do
|
131
|
+
include EventedSpec::AMQPSpec
|
132
|
+
it "should do something useful" do
|
133
|
+
channel = AMQP::Channel.new
|
134
|
+
sleep 0.2 # voila, you're blocking the reactor
|
135
|
+
channel.should be_open # no, it should not
|
136
|
+
done
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
What you *should* do instead is use callbacks:
|
141
|
+
|
142
|
+
bc. describe "using amqp" do
|
143
|
+
include EventedSpec::AMQPSpec
|
144
|
+
it "should do something useful" do
|
145
|
+
AMQP::Channel.new do |channel, _|
|
146
|
+
channel.should be_open
|
147
|
+
done
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
h2. See also
|
153
|
+
|
154
|
+
You can see evented-spec in use in spec suites for our amqp gems, "amq-client":https://github.com/ruby-amqp/amq-client/tree/master/spec and "amqp":https://github.com/ruby-amqp/amqp/tree/master/spec.
|
155
|
+
|
156
|
+
h2. Links
|
157
|
+
|
158
|
+
* "cool.io":http://coolio.github.com/
|
159
|
+
* "amqp-spec":https://github.com/ruby-amqp/amqp-spec
|
160
|
+
* "eventmachine":http://eventmachine.rubyforge.org/
|
161
|
+
* "amqp":https://github.com/ruby-amqp/amqp
|
162
|
+
* "amq-client":https://github.com/ruby-amqp/amq-client
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
NAME = 'amqp-spec'
|
3
|
+
BASE_PATH = Pathname.new(__FILE__).dirname
|
4
|
+
LIB_PATH = BASE_PATH + 'lib'
|
5
|
+
PKG_PATH = BASE_PATH + 'pkg'
|
6
|
+
DOC_PATH = BASE_PATH + 'rdoc'
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift LIB_PATH.to_s
|
9
|
+
require 'version'
|
10
|
+
|
11
|
+
CLASS_NAME = EventedSpec::AMQPSpec
|
12
|
+
VERSION = CLASS_NAME::VERSION
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'rake'
|
16
|
+
rescue LoadError
|
17
|
+
require 'rubygems'
|
18
|
+
gem 'rake', '~> 0.8.3.1'
|
19
|
+
require 'rake'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Load rakefile tasks
|
23
|
+
Dir['tasks/*.rake'].sort.each { |file| load file }
|
24
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.0
|
data/lib/amqp-spec.rb
ADDED
data/lib/evented-spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Monkey patching some methods into AMQP to make it more testable
|
2
|
+
module AMQP
|
3
|
+
# Initializes new AMQP client/connection without starting another EM loop
|
4
|
+
def self.start_connection(opts={}, &block)
|
5
|
+
self.connection = connect opts, &block
|
6
|
+
end
|
7
|
+
|
8
|
+
# Closes AMQP connection gracefully
|
9
|
+
def self.stop_connection
|
10
|
+
if AMQP.connection and not AMQP.connection.closing?
|
11
|
+
@closing = true
|
12
|
+
self.connection.close {
|
13
|
+
yield if block_given?
|
14
|
+
self.connection = nil
|
15
|
+
cleanup_state
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Cleans up AMQP state after AMQP connection closes
|
21
|
+
def self.cleanup_state
|
22
|
+
Thread.list.each { |thread| thread[:mq] = nil }
|
23
|
+
Thread.list.each { |thread| thread[:mq_id] = nil }
|
24
|
+
self.connection = nil
|
25
|
+
@closing = false
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module EventedSpec
|
2
|
+
module SpecHelper
|
3
|
+
# Represents example running inside some type of event loop.
|
4
|
+
# You are not going to use or interact with this class and its descendants directly.
|
5
|
+
#
|
6
|
+
# @abstract
|
7
|
+
class EventedExample
|
8
|
+
# Default options to use with the examples
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
:spec_timeout => 1
|
11
|
+
}
|
12
|
+
|
13
|
+
# Create new evented example
|
14
|
+
def initialize(opts, example_group_instance, &block)
|
15
|
+
@opts, @example_group_instance, @block = DEFAULT_OPTIONS.merge(opts), example_group_instance, block
|
16
|
+
end
|
17
|
+
|
18
|
+
# Called from #run_event_loop when event loop is stopped,
|
19
|
+
# but before the example returns.
|
20
|
+
# Descendant classes may redefine to clean up type-specific state.
|
21
|
+
#
|
22
|
+
# @abstract
|
23
|
+
def finish_example
|
24
|
+
raise @spec_exception if @spec_exception
|
25
|
+
end
|
26
|
+
|
27
|
+
# Run the example.
|
28
|
+
#
|
29
|
+
# @abstract
|
30
|
+
def run
|
31
|
+
raise NotImplementedError, "you should implement #run in #{self.class.name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sets timeout for currently running example
|
35
|
+
#
|
36
|
+
# @abstract
|
37
|
+
def timeout(spec_timeout)
|
38
|
+
raise NotImplementedError, "you should implement #timeout in #{self.class.name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Breaks the event loop and finishes the spec.
|
42
|
+
#
|
43
|
+
# @abstract
|
44
|
+
def done(delay=nil, &block)
|
45
|
+
raise NotImplementedError, "you should implement #done method in #{self.class.name}"
|
46
|
+
end
|
47
|
+
|
48
|
+
# Override this method in your descendants
|
49
|
+
#
|
50
|
+
# @note delay may be nil, implying you need to execute the block immediately.
|
51
|
+
# @abstract
|
52
|
+
def delayed(delay = nil, &block)
|
53
|
+
raise NotImplementedError, "you should implement #delayed method in #{self.class.name}"
|
54
|
+
end # delayed(delay, &block)
|
55
|
+
end # class EventedExample
|
56
|
+
end # module SpecHelper
|
57
|
+
end # module AMQP
|
58
|
+
|
59
|
+
require 'evented-spec/evented_example/em_example'
|
60
|
+
require 'evented-spec/evented_example/amqp_example'
|
61
|
+
require 'evented-spec/evented_example/coolio_example'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module EventedSpec
|
2
|
+
module SpecHelper
|
3
|
+
# Represents spec running inside AMQP.start loop
|
4
|
+
# See {EventedExample} for details and method descriptions.
|
5
|
+
class AMQPExample < EMExample
|
6
|
+
# Run @block inside the AMQP.start loop.
|
7
|
+
# See {EventedExample#run}
|
8
|
+
def run
|
9
|
+
run_em_loop do
|
10
|
+
AMQP.start_connection(@opts) do
|
11
|
+
run_em_hooks :amqp_before
|
12
|
+
@example_group_instance.instance_eval(&@block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Breaks the event loop and finishes the spec. It yields to any given block first,
|
18
|
+
# then stops AMQP, EM event loop and cleans up AMQP state.
|
19
|
+
#
|
20
|
+
# See {EventedExample#done}
|
21
|
+
def done(delay = nil)
|
22
|
+
delayed(delay) do
|
23
|
+
yield if block_given?
|
24
|
+
EM.next_tick do
|
25
|
+
run_em_hooks :amqp_after
|
26
|
+
if AMQP.connection && !AMQP.closing?
|
27
|
+
AMQP.stop_connection do
|
28
|
+
# Cannot call finish_em_loop before connection is marked as closed
|
29
|
+
# This callback is called before that happens.
|
30
|
+
EM.next_tick { finish_em_loop }
|
31
|
+
end
|
32
|
+
else
|
33
|
+
# Need this branch because if AMQP couldn't connect,
|
34
|
+
# the callback would never trigger
|
35
|
+
AMQP.cleanup_state
|
36
|
+
EM.next_tick { finish_em_loop }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Called from run_event_loop when event loop is finished, before any exceptions
|
43
|
+
# is raised or example returns. We ensure AMQP state cleanup here.
|
44
|
+
#
|
45
|
+
# See {EventedExample#run}
|
46
|
+
def finish_example
|
47
|
+
AMQP.cleanup_state
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end # class AMQPExample < EventedExample
|
51
|
+
end # module SpecHelper
|
52
|
+
end # module EventedExample
|