tengine_event 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Gemfile.lock +48 -30
- data/lib/tengine/event/sender.rb +3 -3
- data/lib/tengine/mq/suite.rb +113 -68
- data/lib/tengine/mq/suite/default_config.rb +52 -0
- data/spec/actual_publisher1.rb +54 -0
- data/spec/actual_publisher2.rb +142 -0
- data/spec/actual_spec.rb +103 -0
- data/spec/amqp_spec.rb +144 -0
- data/spec/eventmachine_spec.rb +68 -0
- data/spec/mq_config.yml.example +13 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/test_em.rb +25 -0
- data/spec/support/test_rabbitmq.rb +184 -0
- data/spec/tengine/event/model_notifiable_spec.rb +80 -0
- data/spec/tengine/event/sender_spec.rb +124 -0
- data/spec/tengine/event_spec.rb +419 -0
- data/spec/tengine/mq/connect_actually_spec.rb +38 -0
- data/spec/tengine/mq/suite_spec.rb +945 -0
- data/spec/tengine_spec.rb +17 -0
- metadata +69 -54
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'timeout'
|
4
|
+
require 'eventmachine'
|
5
|
+
|
6
|
+
describe "Eventmachine" do
|
7
|
+
|
8
|
+
describe "#defer" do
|
9
|
+
|
10
|
+
it "2 cascaded defers" do
|
11
|
+
buffer = []
|
12
|
+
blocks = []
|
13
|
+
EM.run_test do
|
14
|
+
blocks[4] = lambda{|a| buffer << [4, a]; EM.stop }
|
15
|
+
blocks[3] = lambda{ buffer << 3; 3 }
|
16
|
+
blocks[2] = lambda{|a| buffer << [2, a]; EM.defer(blocks[3], blocks[4])}
|
17
|
+
blocks[1] = lambda{ buffer << 1; 1 }
|
18
|
+
blocks[0] = lambda{ buffer << 0; EM.defer(blocks[1], blocks[2])}
|
19
|
+
blocks[0].call
|
20
|
+
end
|
21
|
+
buffer.should == [0, 1, [2, 1], 3, [4, 3]]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "4 cascaded defers" do
|
25
|
+
buffer = []
|
26
|
+
blocks = []
|
27
|
+
EM.run_test do
|
28
|
+
blocks[8] = lambda{|a| buffer << [8, a]; EM.stop }
|
29
|
+
blocks[7] = lambda{ buffer << 7; 7 }
|
30
|
+
blocks[6] = lambda{|a| buffer << [6, a]; EM.defer(blocks[7], blocks[8])}
|
31
|
+
blocks[5] = lambda{ buffer << 5; 5 }
|
32
|
+
blocks[4] = lambda{|a| buffer << [4, a]; EM.defer(blocks[5], blocks[6])}
|
33
|
+
blocks[3] = lambda{ buffer << 3; 3 }
|
34
|
+
blocks[2] = lambda{|a| buffer << [2, a]; EM.defer(blocks[3], blocks[4])}
|
35
|
+
blocks[1] = lambda{ buffer << 1; 1 }
|
36
|
+
blocks[0] = lambda{ buffer << 0; EM.defer(blocks[1], blocks[2])}
|
37
|
+
blocks[0].call
|
38
|
+
end
|
39
|
+
buffer.should == [0, 1, [2, 1], 3, [4, 3], 5, [6, 5], 7, [8, 7]]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "15 cascaded defers" do
|
43
|
+
buffer = []
|
44
|
+
blocks = []
|
45
|
+
EM.threadpool_size.should == 20
|
46
|
+
EM.run_test do
|
47
|
+
count = 30
|
48
|
+
blocks[count ] = lambda{|a| buffer << [count, a]; EM.stop }
|
49
|
+
blocks[count - 1] = lambda{ buffer << (count - 1); count - 1 }
|
50
|
+
(count/ 2 - 1).times do |idx|
|
51
|
+
m = idx * 2 + 1
|
52
|
+
n = idx * 2 + 2
|
53
|
+
blocks[n] = lambda{|a| buffer << [n, a]; EM.defer(blocks[n + 1], blocks[n + 2])}
|
54
|
+
blocks[m] = lambda{ buffer << m; m }
|
55
|
+
end
|
56
|
+
blocks[0] = lambda{ buffer << 0; EM.defer(blocks[1], blocks[2])}
|
57
|
+
blocks[0].call
|
58
|
+
end
|
59
|
+
buffer.should == [
|
60
|
+
0, 1, [2, 1], 3, [4, 3], 5, [6, 5], 7, [8, 7], 9, [10, 9],
|
61
|
+
11, [12, 11], 13, [14, 13], 15, [16, 15], 17, [18, 17], 19, [20, 19],
|
62
|
+
21, [22, 21], 23, [24, 23], 25, [26, 25], 27, [28, 27], 29, [30, 29]
|
63
|
+
]
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'tengine_event'
|
5
|
+
require 'timeout'
|
6
|
+
|
7
|
+
require 'simplecov'
|
8
|
+
SimpleCov.start if ENV["COVERAGE"]
|
9
|
+
|
10
|
+
# Requires supporting files with custom matchers and macros, etc,
|
11
|
+
# in ./support/ and its subdirectories.
|
12
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
|
16
|
+
unless ENV['MANUAL'] == 'true'
|
17
|
+
config.filter_run_excluding manual: true
|
18
|
+
end
|
19
|
+
|
20
|
+
if ENV['TRAVIS'] == 'true'
|
21
|
+
config.filter_run_excluding skip_travis: true
|
22
|
+
end
|
23
|
+
|
24
|
+
if ENV['TEST_RABBITMQ_DISABLED'] =~ /^true$|^on$/i
|
25
|
+
config.filter_run_excluding test_rabbitmq_required: true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
require 'eventmachine'
|
5
|
+
|
6
|
+
module EventMachine
|
7
|
+
|
8
|
+
DEFAULT_TIMEOUT = 10 # seconds
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# call run with timeout
|
13
|
+
# @option options [Numeric] :timeout timeout for EventMachine running.
|
14
|
+
#
|
15
|
+
# other arguments and block are passed to run method.
|
16
|
+
def run_test(*args, &block)
|
17
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
18
|
+
t = (options[:timeout] || ENV['DEFAULT_TIMEOUT'] || DEFAULT_TIMEOUT).to_i
|
19
|
+
timeout(t) do
|
20
|
+
return run(*args, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tmpdir'
|
4
|
+
|
5
|
+
class TestRabbitmq
|
6
|
+
class << self
|
7
|
+
def launched_pids
|
8
|
+
@launched_pids ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def kill_launched_processes
|
12
|
+
launched_pids.uniq!
|
13
|
+
puts "no pid found " if launched_pids.empty?
|
14
|
+
kill_processes(launched_pids.dup)
|
15
|
+
end
|
16
|
+
|
17
|
+
def kill_remain_processes
|
18
|
+
ps_lines = `ps aux`.split(/\n/).select{|line| line =~ /^.+?\s+\d+\s+.+\-sname rspec/}
|
19
|
+
pids = ps_lines.map do |line|
|
20
|
+
line.scan(/^.+?\s+(\d+)\s+.+\-sname rspec/).flatten.first.to_i
|
21
|
+
end
|
22
|
+
puts "Now rabbitmq-server processes remain: #{pids.inspect}"
|
23
|
+
kill_processes(pids.compact)
|
24
|
+
end
|
25
|
+
|
26
|
+
def kill_processes(pids)
|
27
|
+
pids.each do |pid|
|
28
|
+
begin
|
29
|
+
puts "kill INT #{pid}"
|
30
|
+
Process.kill "INT", pid
|
31
|
+
Process.waitpid pid
|
32
|
+
launched_pids.delete(pid)
|
33
|
+
rescue Errno::ECHILD => e
|
34
|
+
puts "Warning: failed to kill process #{pid}. ignore [#{e.class}] #{e.message}\n " << e.backtrace.join("\n ")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def run(*args)
|
40
|
+
unless system(*args)
|
41
|
+
fail("command failed:\n#{args.inspect}\n#{$?.inspect}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def backups
|
46
|
+
@backups ||= []
|
47
|
+
end
|
48
|
+
|
49
|
+
# % rabbitmq-plugins list
|
50
|
+
# [e] amqp_client 2.8.7
|
51
|
+
# [ ] eldap 2.8.7-gite309de4
|
52
|
+
# [ ] erlando 2.8.7
|
53
|
+
# [e] mochiweb 2.3.1-rmq2.8.7-gitd541e9a
|
54
|
+
# [ ] rabbitmq_auth_backend_ldap 2.8.7
|
55
|
+
# [ ] rabbitmq_auth_mechanism_ssl 2.8.7
|
56
|
+
# [ ] rabbitmq_consistent_hash_exchange 2.8.7
|
57
|
+
# [ ] rabbitmq_federation 2.8.7
|
58
|
+
# [ ] rabbitmq_federation_management 2.8.7
|
59
|
+
# [ ] rabbitmq_jsonrpc 2.8.7
|
60
|
+
# [ ] rabbitmq_jsonrpc_channel 2.8.7
|
61
|
+
# [ ] rabbitmq_jsonrpc_channel_examples 2.8.7
|
62
|
+
# [E] rabbitmq_management 2.8.7
|
63
|
+
# [e] rabbitmq_management_agent 2.8.7
|
64
|
+
# [E] rabbitmq_management_visualiser 2.8.7
|
65
|
+
# [e] rabbitmq_mochiweb 2.8.7
|
66
|
+
# [ ] rabbitmq_shovel 2.8.7
|
67
|
+
# [ ] rabbitmq_shovel_management 2.8.7
|
68
|
+
# [ ] rabbitmq_stomp 2.8.7
|
69
|
+
# [ ] rabbitmq_tracing 2.8.7
|
70
|
+
# [ ] rfc4627_jsonrpc 2.8.7-gita5e7ad7
|
71
|
+
# [e] webmachine 1.9.1-rmq2.8.7-git52e62bc
|
72
|
+
#
|
73
|
+
# http://www.rabbitmq.com/man/rabbitmq-plugins.1.man.html
|
74
|
+
|
75
|
+
def backup_plugins
|
76
|
+
backups << `rabbitmq-plugins list`.scan(/^\[[E]\]\s*([^\s]+)\s*.+?\s*$/).flatten
|
77
|
+
end
|
78
|
+
|
79
|
+
def restore_plugins
|
80
|
+
enable_plugins(*backups.pop)
|
81
|
+
end
|
82
|
+
|
83
|
+
def enable_plugins(*plugins)
|
84
|
+
run("rabbitmq-plugins enable " << plugins.join(" "))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
attr_reader :pid
|
90
|
+
attr_accessor :port, :keep_port
|
91
|
+
attr_accessor :base_dir, :nodename, :rabbitmq_server_path
|
92
|
+
attr_accessor :max_attempts, :max_wait_limit, :wait_interval
|
93
|
+
attr_accessor :disabled
|
94
|
+
|
95
|
+
DEFAULT_PORT = 5672
|
96
|
+
|
97
|
+
def initialize(options = {})
|
98
|
+
@pid = nil
|
99
|
+
@port = DEFAULT_PORT
|
100
|
+
# @base_dir ||= File.expand_path("../../../tmp/rabbitmq", __FILE__)
|
101
|
+
@base_dir ||= Dir.mktmpdir
|
102
|
+
FileUtils.mkdir_p(@base_dir)
|
103
|
+
@rabbitmq_server_path = find_rabbitmq_server
|
104
|
+
@keep_port = false
|
105
|
+
@max_attempts = 10
|
106
|
+
@max_wait_limit = 16
|
107
|
+
@wait_interval = 0.5
|
108
|
+
@disabled = (ENV['TRAVIS'] == 'true') || (ENV['TEST_RABBITMQ_DISABLED'].to_s =~ /^true$|^on$/i)
|
109
|
+
(options || {}).each{|key, value| send("#{key}=", value) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def find_rabbitmq_server
|
113
|
+
ENV["PATH"].split(/:/).find do |dir|
|
114
|
+
Dir.glob("#{dir}/rabbitmq-server") do |path|
|
115
|
+
return path if File.executable?(path)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def launch
|
121
|
+
return self if disabled
|
122
|
+
raise "Something wrong! launched process is still living." unless self.class.launched_pids.empty?
|
123
|
+
ps_line = `ps aux`.split(/\n/).select{|line| line =~ /^#{ENV['USER']}\s+\d+\s+.+\-sname rspec/}
|
124
|
+
raise "process is still remain\n#{ps_line}" unless ps_line.empty?
|
125
|
+
raise "rabbitmq-server not found" unless @rabbitmq_server_path
|
126
|
+
return self if try_launch
|
127
|
+
raise "failed to invoke rabbitmq-server."
|
128
|
+
end
|
129
|
+
|
130
|
+
# see http://ja.wikipedia.org/wiki/ポート番号
|
131
|
+
UNRESERVED_PORT_MIN = 1024
|
132
|
+
|
133
|
+
def try_launch
|
134
|
+
# puts "#{__FILE__}##{__LINE__}\n " << caller.join("\n ")
|
135
|
+
|
136
|
+
unless @keep_port
|
137
|
+
@port = rand(32768 - UNRESERVED_PORT_MIN) + UNRESERVED_PORT_MIN
|
138
|
+
end
|
139
|
+
|
140
|
+
envp = {
|
141
|
+
"RABBITMQ_NODENAME" => "rspec",
|
142
|
+
"RABBITMQ_NODE_PORT" => @port.to_s,
|
143
|
+
"RABBITMQ_NODE_IP_ADDRESS" => "auto",
|
144
|
+
"RABBITMQ_MNESIA_BASE" => @base_dir.to_s,
|
145
|
+
"RABBITMQ_LOG_BASE" => @base_dir.to_s,
|
146
|
+
}
|
147
|
+
args = [envp, rabbitmq_server_path, {pgroup: true, chdir: @base_dir, in: :close}]
|
148
|
+
Process.spawn(*args)
|
149
|
+
|
150
|
+
x = Time.now
|
151
|
+
limit = x + max_wait_limit
|
152
|
+
|
153
|
+
while Time.now < limit do
|
154
|
+
sleep wait_interval
|
155
|
+
line = `ps aux`.split(/\n/).select{|line| line =~ /^#{ENV['USER']}\s+\d+\s+.+\-sname\ rspec.+tcp_listeners \[\{\"auto\",#{@port}\}\]/}.flatten.sort.first
|
156
|
+
next unless line
|
157
|
+
pid = line.scan(/^#{ENV['USER']}\s+(\d+)\s+/).flatten.first
|
158
|
+
next unless pid
|
159
|
+
@pid = pid.to_i
|
160
|
+
self.class.launched_pids << @pid
|
161
|
+
|
162
|
+
Process.waitpid2(@pid, Process::WNOHANG) # 起動されているはず
|
163
|
+
Process.kill 0, @pid # プロセスの存在確認。プロセスが起動してたらスルー、いなかったら Errno::ESRCH がraiseされる。
|
164
|
+
break
|
165
|
+
end
|
166
|
+
x = Time.now
|
167
|
+
limit = x + max_wait_limit
|
168
|
+
while Time.now < limit do
|
169
|
+
sleep wait_interval
|
170
|
+
|
171
|
+
# netstat -an は Linux / BSD ともに有効
|
172
|
+
# どちらかに限ればもう少し効率的な探し方はある。たとえば Linux 限定でよければ netstat -lnt ...
|
173
|
+
cmd = "netstat -an | fgrep LISTEN | fgrep #{@port}"
|
174
|
+
y = `#{cmd}`
|
175
|
+
return true if y.lines.to_a.size > 0
|
176
|
+
end
|
177
|
+
|
178
|
+
puts "launch timed out"
|
179
|
+
return false
|
180
|
+
rescue Errno::ECHILD, Errno::ESRCH => e
|
181
|
+
puts "[#{e.class}] #{e.message}\n " << e.backtrace.join("\n ")
|
182
|
+
false
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
3
|
+
|
4
|
+
describe "Tengine::Event::ModelNotifiable" do
|
5
|
+
|
6
|
+
module TengineTest
|
7
|
+
class MockModel
|
8
|
+
attr_accessor :attributes, :changes
|
9
|
+
def initialize(attributes)
|
10
|
+
@attributes = attributes
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class TestModelNotifier
|
16
|
+
include Tengine::Event::ModelNotifiable
|
17
|
+
|
18
|
+
def initialize(sender)
|
19
|
+
@sender= sender
|
20
|
+
end
|
21
|
+
|
22
|
+
def event_sender
|
23
|
+
@sender
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "ActiveModelなどのObserverでそれぞれメソッドが呼び出されます" do
|
28
|
+
before do
|
29
|
+
@mock_sender = mock(:sender)
|
30
|
+
@notifier = TestModelNotifier.new(@mock_sender)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "after_create" do
|
34
|
+
@mock_sender.should_receive(:fire).with("TengineTest::MockModel.created.TestModelNotifier", {
|
35
|
+
:level_key => :info,
|
36
|
+
:properties => {
|
37
|
+
:class_name => "TengineTest::MockModel",
|
38
|
+
:attributes => {
|
39
|
+
:name => "GariGariKun",
|
40
|
+
:price => 50
|
41
|
+
}
|
42
|
+
}
|
43
|
+
})
|
44
|
+
@notifier.after_create(TengineTest::MockModel.new(:name => "GariGariKun", :price => 50))
|
45
|
+
end
|
46
|
+
|
47
|
+
it "after_update" do
|
48
|
+
@mock_sender.should_receive(:fire).with("TengineTest::MockModel.updated.TestModelNotifier", {
|
49
|
+
:level_key => :info,
|
50
|
+
:properties => {
|
51
|
+
:class_name => "TengineTest::MockModel",
|
52
|
+
:attributes => {
|
53
|
+
:name => "GariGariKun",
|
54
|
+
:price => 60
|
55
|
+
},
|
56
|
+
:changes => {"price" => [50, 60]},
|
57
|
+
}
|
58
|
+
})
|
59
|
+
model = TengineTest::MockModel.new(:name => "GariGariKun", :price => 60)
|
60
|
+
model.changes = {"price" => [50, 60]}
|
61
|
+
@notifier.after_update(model)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "after_destroy" do
|
65
|
+
@mock_sender.should_receive(:fire).with("TengineTest::MockModel.destroyed.TestModelNotifier", {
|
66
|
+
:level_key => :info,
|
67
|
+
:properties => {
|
68
|
+
:class_name => "TengineTest::MockModel",
|
69
|
+
:attributes => {
|
70
|
+
:name => "GariGariKun",
|
71
|
+
:price => 60
|
72
|
+
}
|
73
|
+
}
|
74
|
+
})
|
75
|
+
@notifier.after_destroy(TengineTest::MockModel.new(:name => "GariGariKun", :price => 60))
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
3
|
+
|
4
|
+
# fire の機能面(何を送信するか等)に関してはmq/suiteに記載済み
|
5
|
+
describe "Tengine::Event::Sender" do
|
6
|
+
describe "#initialize" do
|
7
|
+
context "no args" do
|
8
|
+
subject{ Tengine::Event::Sender.new.mq_suite }
|
9
|
+
it { should_not be_nil }
|
10
|
+
it { should be_kind_of Tengine::Mq::Suite }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "with options" do
|
14
|
+
subject{ Tengine::Event::Sender.new(:exchange => {:name => "another_exhange"}).mq_suite.config[:exchange][:name] }
|
15
|
+
it { should == "another_exhange" }
|
16
|
+
end
|
17
|
+
|
18
|
+
context "with mq_suite" do
|
19
|
+
before{ @mq_suite = Tengine::Mq::Suite.new }
|
20
|
+
subject{ Tengine::Event::Sender.new(@mq_suite).mq_suite }
|
21
|
+
it { should == @mq_suite }
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with mq_suite and options" do
|
25
|
+
before do
|
26
|
+
@mq_suite = Tengine::Mq::Suite.new
|
27
|
+
@logger = mock(:logger)
|
28
|
+
end
|
29
|
+
subject { Tengine::Event::Sender.new(@mq_suite, :logger => @logger) }
|
30
|
+
its (:mq_suite) { should == @mq_suite }
|
31
|
+
its (:logger) { should == @logger }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#stop" do
|
36
|
+
before { @mq_suite = Tengine::Mq::Suite.new }
|
37
|
+
subject { Tengine::Event::Sender.new(@mq_suite) }
|
38
|
+
|
39
|
+
it "stops suite" do
|
40
|
+
@mq_suite.should_receive :stop
|
41
|
+
subject.stop
|
42
|
+
end
|
43
|
+
|
44
|
+
it "calls the given block (if any) afterwards" do
|
45
|
+
@mq_suite.should_receive(:stop).and_yield
|
46
|
+
block_called = false
|
47
|
+
subject.stop { block_called = true }
|
48
|
+
block_called.should == true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#pending_events" do
|
53
|
+
before do
|
54
|
+
@mq_suite = Tengine::Mq::Suite.new
|
55
|
+
@event = Tengine::Event.new
|
56
|
+
@mq_suite.stub(:pending_events_for).with(an_instance_of(Tengine::Event::Sender)).and_return([@event])
|
57
|
+
end
|
58
|
+
subject { Tengine::Event::Sender.new(@mq_suite).pending_events }
|
59
|
+
|
60
|
+
it { should be_kind_of Array }
|
61
|
+
it { should have(1).events }
|
62
|
+
it { should include(@event) }
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#wait_for_connection" do
|
66
|
+
it "does nothing" do
|
67
|
+
expect {
|
68
|
+
Tengine::Event::Sender.new.wait_for_connection { }
|
69
|
+
}.to_not raise_error
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#fire" do
|
74
|
+
before do
|
75
|
+
@event = Tengine::Event.new
|
76
|
+
@mq_suite = Tengine::Mq::Suite.new
|
77
|
+
@mq_suite.stub(:fire).
|
78
|
+
with(an_instance_of(Tengine::Event::Sender),
|
79
|
+
an_instance_of(Tengine::Event),
|
80
|
+
an_instance_of(Hash),
|
81
|
+
an_instance_of(Proc)) {
|
82
|
+
|q, w, e, r|
|
83
|
+
r.yield
|
84
|
+
}
|
85
|
+
@mq_suite.stub(:fire).
|
86
|
+
with(an_instance_of(Tengine::Event::Sender),
|
87
|
+
an_instance_of(Tengine::Event),
|
88
|
+
an_instance_of(Hash),
|
89
|
+
an_instance_of(NilClass))
|
90
|
+
end
|
91
|
+
|
92
|
+
context "mandatory one arg" do
|
93
|
+
it { expect { Tengine::Event::Sender.new(@mq_suite).fire }.to raise_exception(ArgumentError) }
|
94
|
+
end
|
95
|
+
|
96
|
+
context "one, string arg" do
|
97
|
+
subject { Tengine::Event::Sender.new(@mq_suite).fire("foo") }
|
98
|
+
it { should be_kind_of(Tengine::Event) }
|
99
|
+
its (:event_type_name) { should == "foo" }
|
100
|
+
end
|
101
|
+
|
102
|
+
context "one, event arg" do
|
103
|
+
subject { Tengine::Event::Sender.new(@mq_suite).fire(@event) }
|
104
|
+
it { should be_kind_of(Tengine::Event) }
|
105
|
+
it { should == @event }
|
106
|
+
end
|
107
|
+
|
108
|
+
context "event arg + option" do
|
109
|
+
subject { Tengine::Event::Sender.new(@mq_suite).fire(@event, :keep_connection => true) }
|
110
|
+
it { should == @event }
|
111
|
+
end
|
112
|
+
|
113
|
+
context "block argument" do
|
114
|
+
before { @event = Tengine::Event.new }
|
115
|
+
it "is called" do
|
116
|
+
block_called = false
|
117
|
+
Tengine::Event::Sender.new(@mq_suite).fire(@event) do
|
118
|
+
block_called = true
|
119
|
+
end
|
120
|
+
block_called.should == true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|