hutch 0.9.0 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db5d3539145e0b5196542b4157d4262045f4e414
4
- data.tar.gz: 072daf962f5ff1cd2c63278b97bd2d11efcd37e0
3
+ metadata.gz: 803369cb7619eae888379612cf278d49133a3f68
4
+ data.tar.gz: 4eb4a16d6b7a12441b9e56d972ebcc413b5fec82
5
5
  SHA512:
6
- metadata.gz: fd18ffdbf03f1bbc8f18e9bbb71a3e92937392873c482ed1a2ba2bf7ccb6fc1b8e03ad1ed6dee2e1b09e03dfee6c15e59b4f8311c882a9b95e19c5cdb88d90c8
7
- data.tar.gz: 241814297de25974719b07d728fb236df4b3de062997c033d50e79223bbb0609bb331f45d563efc8206ded3b0d2722583bb87e1b160a0e8a5a8744b0838a57ca
6
+ metadata.gz: 3f557376e9db220197b6f6f99cd28621593ed3a5f0bc96e26c471fb40b7b54e3f79564cad661873b223c7688713112bbf5536b705efdb0d3aa4b86d88725cd6b
7
+ data.tar.gz: d497420735d0567a167290a9de4130d66635f4ef36d5b1f674ca77e0320956518014cbc91054d72b10dc16ef3c2edc5498e47dd7a1b6ddce4edb013a757158ff
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "2.1.0"
4
- - "2.0.0"
5
- - "1.9.3"
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
6
  services:
7
7
  - rabbitmq
@@ -1,4 +1,16 @@
1
- ## 0.9.0 — unreleased
1
+ ## 0.10.0 — unreleased
2
+
3
+ ### Bunny Update
4
+
5
+ Bunny is updated to `1.4.x`.
6
+
7
+ ### Exceptions in Error Handlers Don't Prevent Nacks
8
+
9
+ Exceptions in error handlers no longer prevent messages from being
10
+ `basic.nack`-ed.
11
+
12
+
13
+ ## 0.9.0 — May 13, 2014
2
14
 
3
15
  ### Platform-aware Signal Registration
4
16
 
@@ -1,10 +1,10 @@
1
1
  require File.expand_path('../lib/hutch/version', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |gem|
4
- gem.add_runtime_dependency 'bunny', '~> 1.2.1'
4
+ gem.add_runtime_dependency 'bunny', '>= 1.5.1'
5
5
  gem.add_runtime_dependency 'carrot-top', '~> 0.0.7'
6
6
  gem.add_runtime_dependency 'multi_json', '~> 1.5'
7
- gem.add_development_dependency 'rspec', '~> 2.12.0'
7
+ gem.add_development_dependency 'rspec', '~> 3.0'
8
8
  gem.add_development_dependency 'simplecov', '~> 0.7.1'
9
9
 
10
10
  gem.name = 'hutch'
@@ -19,8 +19,11 @@ module Hutch
19
19
  set_up_api_connection if options.fetch(:enable_http_api_use, true)
20
20
 
21
21
  if block_given?
22
- yield
23
- disconnect
22
+ begin
23
+ yield
24
+ ensure
25
+ disconnect
26
+ end
24
27
  end
25
28
  end
26
29
 
@@ -46,6 +49,16 @@ module Hutch
46
49
  end
47
50
 
48
51
  def open_connection!
52
+ if @config[:uri] && !@config[:uri].empty?
53
+ u = URI.parse(@config[:uri])
54
+
55
+ @config[:mq_host] = u.host
56
+ @config[:mq_port] = u.port
57
+ @config[:mq_vhost] = u.path.sub(/^\//, "")
58
+ @config[:mq_username] = u.user
59
+ @config[:mq_password] = u.password
60
+ end
61
+
49
62
  host = @config[:mq_host]
50
63
  port = @config[:mq_port]
51
64
  vhost = @config[:mq_vhost]
@@ -57,7 +70,6 @@ module Hutch
57
70
  protocol = tls ? "amqps://" : "amqp://"
58
71
  sanitized_uri = "#{protocol}#{username}@#{host}:#{port}/#{vhost.sub(/^\//, '')}"
59
72
  logger.info "connecting to rabbitmq (#{sanitized_uri})"
60
-
61
73
  @connection = Bunny.new(host: host, port: port, vhost: vhost,
62
74
  tls: tls, tls_key: tls_key, tls_cert: tls_cert,
63
75
  username: username, password: password,
@@ -68,6 +80,7 @@ module Hutch
68
80
  @connection.start
69
81
  end
70
82
 
83
+ logger.info "connected to RabbitMQ at #{host} as #{username}"
71
84
  @connection
72
85
  end
73
86
 
@@ -148,6 +161,14 @@ module Hutch
148
161
  @channel.work_pool.kill
149
162
  end
150
163
 
164
+ def requeue(delivery_tag)
165
+ @channel.reject(delivery_tag, true)
166
+ end
167
+
168
+ def reject(delivery_tag, requeue=false)
169
+ @channel.reject(delivery_tag, requeue)
170
+ end
171
+
151
172
  def ack(delivery_tag)
152
173
  @channel.ack(delivery_tag, false)
153
174
  end
@@ -12,7 +12,11 @@ module Hutch
12
12
  def run(argv = ARGV)
13
13
  parse_options(argv)
14
14
 
15
- Hutch.logger.info "hutch booted with pid #{Process.pid}"
15
+ ::Process.daemon(true) if Hutch::Config.daemonise
16
+
17
+ write_pid if Hutch::Config.pidfile
18
+
19
+ Hutch.logger.info "hutch booted with pid #{::Process.pid}"
16
20
 
17
21
  if load_app && start_work_loop == :success
18
22
  # If we got here, the worker was shut down nicely
@@ -170,6 +174,14 @@ module Hutch
170
174
  Hutch::Config.namespace = namespace
171
175
  end
172
176
 
177
+ opts.on('-d', '--daemonise', 'Daemonise') do |daemonise|
178
+ Hutch::Config.daemonise = daemonise
179
+ end
180
+
181
+ opts.on('--pidfile PIDFILE', 'Pidfile') do |pidfile|
182
+ Hutch::Config.pidfile = pidfile
183
+ end
184
+
173
185
  opts.on('--version', 'Print the version and exit') do
174
186
  puts "hutch v#{VERSION}"
175
187
  exit 0
@@ -181,5 +193,12 @@ module Hutch
181
193
  end
182
194
  end.parse!(args)
183
195
  end
196
+
197
+ def write_pid
198
+ pidfile = File.expand_path(Hutch::Config.pidfile)
199
+ Hutch.logger.info "writing pid in #{pidfile}"
200
+ File.open(pidfile, 'w') { |f| f.puts ::Process.pid }
201
+ end
202
+
184
203
  end
185
204
  end
@@ -7,7 +7,7 @@ module Hutch
7
7
  module Config
8
8
  require 'yaml'
9
9
 
10
- def self.initialize
10
+ def self.initialize(params={})
11
11
  @config = {
12
12
  mq_host: 'localhost',
13
13
  mq_port: 5672,
@@ -21,13 +21,18 @@ module Hutch
21
21
  mq_api_host: 'localhost',
22
22
  mq_api_port: 15672,
23
23
  mq_api_ssl: false,
24
+ # placeholder, allows specifying connection parameters
25
+ # as a URI.
26
+ uri: nil,
24
27
  log_level: Logger::INFO,
25
28
  require_paths: [],
26
29
  autoload_rails: true,
27
30
  error_handlers: [Hutch::ErrorHandlers::Logger.new],
28
31
  namespace: nil,
32
+ daemonise: false,
33
+ pidfile: nil,
29
34
  channel_prefetch: 0
30
- }
35
+ }.merge(params)
31
36
  end
32
37
 
33
38
  def self.get(attr)
@@ -5,11 +5,21 @@ module Hutch
5
5
  # gain a class method called `consume`, which should be used to register
6
6
  # the routing keys a consumer is interested in.
7
7
  module Consumer
8
+ attr_accessor :broker, :delivery_info
9
+
8
10
  def self.included(base)
9
11
  base.extend(ClassMethods)
10
12
  Hutch.register_consumer(base)
11
13
  end
12
14
 
15
+ def reject!
16
+ broker.reject(delivery_info.delivery_tag)
17
+ end
18
+
19
+ def requeue!
20
+ broker.requeue(delivery_info.delivery_tag)
21
+ end
22
+
13
23
  module ClassMethods
14
24
  # Add one or more routing keys to the set of routing keys the consumer
15
25
  # wants to subscribe to.
@@ -5,7 +5,7 @@ module Hutch
5
5
  class Logger
6
6
  include Logging
7
7
 
8
- def handle(message_id, consumer, ex)
8
+ def handle(message_id, payload, consumer, ex)
9
9
  prefix = "message(#{message_id || '-'}): "
10
10
  logger.error prefix + "error in consumer '#{consumer}'"
11
11
  logger.error prefix + "#{ex.class} - #{ex.message}"
@@ -12,7 +12,7 @@ module Hutch
12
12
  end
13
13
  end
14
14
 
15
- def handle(message_id, consumer, ex)
15
+ def handle(message_id, payload, consumer, ex)
16
16
  prefix = "message(#{message_id || '-'}): "
17
17
  logger.error prefix + "Logging event to Sentry"
18
18
  logger.error prefix + "#{ex.class} - #{ex.message}"
@@ -5,6 +5,8 @@ module Hutch
5
5
  class Message
6
6
  extend Forwardable
7
7
 
8
+ attr_reader :delivery_info, :properties, :payload
9
+
8
10
  def initialize(delivery_info, properties, payload)
9
11
  @delivery_info = delivery_info
10
12
  @properties = properties
@@ -1,4 +1,4 @@
1
1
  module Hutch
2
- VERSION = '0.9.0'.freeze
2
+ VERSION = '0.10.0'.freeze
3
3
  end
4
4
 
@@ -81,17 +81,17 @@ module Hutch
81
81
  broker = @broker
82
82
  begin
83
83
  message = Message.new(delivery_info, properties, payload)
84
- consumer.new.process(message)
84
+ consumer.new.tap { |c| c.broker, c.delivery_info = @broker, delivery_info }.process(message)
85
85
  broker.ack(delivery_info.delivery_tag)
86
86
  rescue StandardError => ex
87
- handle_error(properties.message_id, consumer, ex)
88
87
  broker.nack(delivery_info.delivery_tag)
88
+ handle_error(properties.message_id, payload, consumer, ex)
89
89
  end
90
90
  end
91
91
 
92
- def handle_error(message_id, consumer, ex)
92
+ def handle_error(message_id, payload, consumer, ex)
93
93
  Hutch::Config[:error_handlers].each do |backend|
94
- backend.handle(message_id, consumer, ex)
94
+ backend.handle(message_id, payload, consumer, ex)
95
95
  end
96
96
  end
97
97
 
@@ -6,37 +6,48 @@ describe Hutch::Broker do
6
6
  subject(:broker) { Hutch::Broker.new(config) }
7
7
 
8
8
  describe '#connect' do
9
- before { broker.stub(:set_up_amqp_connection) }
10
- before { broker.stub(:set_up_api_connection) }
11
- before { broker.stub(:disconnect) }
9
+ before { allow(broker).to receive(:set_up_amqp_connection) }
10
+ before { allow(broker).to receive(:set_up_api_connection) }
11
+ before { allow(broker).to receive(:disconnect) }
12
12
 
13
13
  it 'sets up the amqp connection' do
14
- broker.should_receive(:set_up_amqp_connection)
14
+ expect(broker).to receive(:set_up_amqp_connection)
15
15
  broker.connect
16
16
  end
17
17
 
18
18
  it 'sets up the api connection' do
19
- broker.should_receive(:set_up_api_connection)
19
+ expect(broker).to receive(:set_up_api_connection)
20
20
  broker.connect
21
21
  end
22
22
 
23
23
  it 'does not disconnect' do
24
- broker.should_not_receive(:disconnect)
24
+ expect(broker).not_to receive(:disconnect)
25
25
  broker.connect
26
26
  end
27
27
 
28
28
  context 'when given a block' do
29
29
  it 'disconnects' do
30
- broker.should_receive(:disconnect).once
30
+ expect(broker).to receive(:disconnect).once
31
31
  broker.connect { }
32
32
  end
33
33
  end
34
34
 
35
+ context 'when given a block that fails' do
36
+ let(:exception) { Class.new(StandardError) }
37
+
38
+ it 'disconnects' do
39
+ expect(broker).to receive(:disconnect).once
40
+ expect do
41
+ broker.connect { fail exception }
42
+ end.to raise_error(exception)
43
+ end
44
+ end
45
+
35
46
  context "with options" do
36
47
  let(:options) { { enable_http_api_use: false } }
37
48
 
38
49
  it "doesnt set up api" do
39
- broker.should_not_receive(:set_up_api_connection)
50
+ expect(broker).not_to receive(:set_up_api_connection)
40
51
  broker.connect options
41
52
  end
42
53
  end
@@ -47,16 +58,27 @@ describe Hutch::Broker do
47
58
  before { broker.set_up_amqp_connection }
48
59
  after { broker.disconnect }
49
60
 
50
- its(:connection) { should be_a Bunny::Session }
51
- its(:channel) { should be_a Bunny::Channel }
52
- its(:exchange) { should be_a Bunny::Exchange }
61
+ describe '#connection' do
62
+ subject { super().connection }
63
+ it { is_expected.to be_a Bunny::Session }
64
+ end
65
+
66
+ describe '#channel' do
67
+ subject { super().channel }
68
+ it { is_expected.to be_a Bunny::Channel }
69
+ end
70
+
71
+ describe '#exchange' do
72
+ subject { super().exchange }
73
+ it { is_expected.to be_a Bunny::Exchange }
74
+ end
53
75
  end
54
76
 
55
77
  context 'when given invalid details' do
56
78
  before { config[:mq_host] = 'notarealhost' }
57
79
  let(:set_up_amqp_connection) { ->{ broker.set_up_amqp_connection } }
58
80
 
59
- specify { set_up_amqp_connection.should raise_error }
81
+ specify { expect(set_up_amqp_connection).to raise_error }
60
82
  end
61
83
 
62
84
  context 'with channel_prefetch set' do
@@ -65,7 +87,8 @@ describe Hutch::Broker do
65
87
  after { broker.disconnect }
66
88
 
67
89
  it "set's channel's prefetch" do
68
- Bunny::Channel.any_instance.should_receive(:prefetch).with(prefetch_value)
90
+ expect_any_instance_of(Bunny::Channel).
91
+ to receive(:prefetch).with(prefetch_value)
69
92
  broker.set_up_amqp_connection
70
93
  end
71
94
  end
@@ -76,7 +99,10 @@ describe Hutch::Broker do
76
99
  before { broker.set_up_api_connection }
77
100
  after { broker.disconnect }
78
101
 
79
- its(:api_client) { should be_a CarrotTop }
102
+ describe '#api_client' do
103
+ subject { super().api_client }
104
+ it { is_expected.to be_a CarrotTop }
105
+ end
80
106
  end
81
107
 
82
108
  context 'when given invalid details' do
@@ -84,17 +110,19 @@ describe Hutch::Broker do
84
110
  after { broker.disconnect }
85
111
  let(:set_up_api_connection) { ->{ broker.set_up_api_connection } }
86
112
 
87
- specify { set_up_api_connection.should raise_error }
113
+ specify { expect(set_up_api_connection).to raise_error }
88
114
  end
89
115
  end
90
116
 
91
117
  describe '#queue' do
92
118
  let(:channel) { double('Channel') }
93
- before { broker.stub(:channel) { channel } }
119
+ before { allow(broker).to receive(:channel) { channel } }
94
120
 
95
121
  it 'applies a global namespace' do
96
122
  config[:namespace] = 'mirror-all.service'
97
- broker.channel.should_receive(:queue).with { |*args| args.first == 'mirror-all.service:test' }
123
+ expect(broker.channel).to receive(:queue) do |*args|
124
+ args.first == 'mirror-all.service:test'
125
+ end
98
126
  broker.queue('test')
99
127
  end
100
128
  end
@@ -104,7 +132,10 @@ describe Hutch::Broker do
104
132
  subject { broker.bindings }
105
133
 
106
134
  context 'with no bindings' do
107
- its(:keys) { should_not include 'test' }
135
+ describe '#keys' do
136
+ subject { super().keys }
137
+ it { is_expected.not_to include 'test' }
138
+ end
108
139
  end
109
140
 
110
141
  context 'with a binding' do
@@ -114,7 +145,7 @@ describe Hutch::Broker do
114
145
  queue.unbind(broker.exchange, routing_key: 'key').delete
115
146
  end
116
147
 
117
- it { should include({ 'test' => ['key'] }) }
148
+ it { is_expected.to include({ 'test' => ['key'] }) }
118
149
  end
119
150
  end
120
151
 
@@ -124,17 +155,17 @@ describe Hutch::Broker do
124
155
 
125
156
  let(:routing_keys) { %w( a b c ) }
126
157
  let(:queue) { double('Queue', bind: nil, unbind: nil, name: 'consumer') }
127
- before { broker.stub(bindings: { 'consumer' => ['d'] }) }
158
+ before { allow(broker).to receive(:bindings).and_return('consumer' => ['d']) }
128
159
 
129
160
  it 'calls bind for each routing key' do
130
161
  routing_keys.each do |key|
131
- queue.should_receive(:bind).with(broker.exchange, routing_key: key)
162
+ expect(queue).to receive(:bind).with(broker.exchange, routing_key: key)
132
163
  end
133
164
  broker.bind_queue(queue, routing_keys)
134
165
  end
135
166
 
136
167
  it 'calls unbind for each redundant existing binding' do
137
- queue.should_receive(:unbind).with(broker.exchange, routing_key: 'd')
168
+ expect(queue).to receive(:unbind).with(broker.exchange, routing_key: 'd')
138
169
  broker.bind_queue(queue, routing_keys)
139
170
  end
140
171
 
@@ -142,29 +173,29 @@ describe Hutch::Broker do
142
173
  let(:queue) { broker.queue('consumer') }
143
174
  let(:routing_key) { 'key' }
144
175
 
145
- before { broker.unstub(:bindings) }
176
+ before { allow(broker).to receive(:bindings).and_call_original }
146
177
  before { queue.bind(broker.exchange, routing_key: 'redundant-key') }
147
178
  after { queue.unbind(broker.exchange, routing_key: routing_key).delete }
148
179
 
149
180
  it 'results in the correct bindings' do
150
181
  broker.bind_queue(queue, [routing_key])
151
- broker.bindings.should include({ queue.name => [routing_key] })
182
+ expect(broker.bindings).to include({ queue.name => [routing_key] })
152
183
  end
153
184
  end
154
185
  end
155
186
 
156
187
  describe '#wait_on_threads' do
157
188
  let(:thread) { double('Thread') }
158
- before { broker.stub(work_pool_threads: threads) }
189
+ before { allow(broker).to receive(:work_pool_threads).and_return(threads) }
159
190
 
160
191
  context 'when all threads finish within the timeout' do
161
192
  let(:threads) { [double(join: thread), double(join: thread)] }
162
- specify { expect(broker.wait_on_threads(1)).to be_true }
193
+ specify { expect(broker.wait_on_threads(1)).to be_truthy }
163
194
  end
164
195
 
165
196
  context 'when timeout expires for one thread' do
166
197
  let(:threads) { [double(join: thread), double(join: nil)] }
167
- specify { expect(broker.wait_on_threads(1)).to be_false }
198
+ specify { expect(broker.wait_on_threads(1)).to be_falsey }
168
199
  end
169
200
  end
170
201
 
@@ -174,12 +205,12 @@ describe Hutch::Broker do
174
205
  after { broker.disconnect }
175
206
 
176
207
  it 'publishes to the exchange' do
177
- broker.exchange.should_receive(:publish).once
208
+ expect(broker.exchange).to receive(:publish).once
178
209
  broker.publish('test.key', 'message')
179
210
  end
180
211
 
181
212
  it 'sets default properties' do
182
- broker.exchange.should_receive(:publish).with(
213
+ expect(broker.exchange).to receive(:publish).with(
183
214
  JSON.dump("message"),
184
215
  hash_including(
185
216
  persistent: true,
@@ -192,29 +223,31 @@ describe Hutch::Broker do
192
223
  end
193
224
 
194
225
  it 'allows passing message properties' do
195
- broker.exchange.should_receive(:publish).once
226
+ expect(broker.exchange).to receive(:publish).once
196
227
  broker.publish('test.key', 'message', {expiration: "2000", persistent: false})
197
228
  end
198
229
 
199
230
  context 'when there are global properties' do
200
231
  context 'as a hash' do
201
232
  before do
202
- Hutch.stub global_properties: { app_id: 'app' }
233
+ allow(Hutch).to receive(:global_properties).and_return(app_id: 'app')
203
234
  end
204
235
 
205
236
  it 'merges the properties' do
206
- broker.exchange.should_receive(:publish).with('"message"', hash_including(app_id: 'app'))
237
+ expect(broker.exchange).
238
+ to receive(:publish).with('"message"', hash_including(app_id: 'app'))
207
239
  broker.publish('test.key', 'message')
208
240
  end
209
241
  end
210
242
 
211
243
  context 'as a callable object' do
212
244
  before do
213
- Hutch.stub global_properties: proc { { app_id: 'app' } }
245
+ allow(Hutch).to receive(:global_properties).and_return(proc { { app_id: 'app' } })
214
246
  end
215
247
 
216
248
  it 'calls the proc and merges the properties' do
217
- broker.exchange.should_receive(:publish).with('"message"', hash_including(app_id: 'app'))
249
+ expect(broker.exchange).
250
+ to receive(:publish).with('"message"', hash_including(app_id: 'app'))
218
251
  broker.publish('test.key', 'message')
219
252
  end
220
253
  end
@@ -228,7 +261,7 @@ describe Hutch::Broker do
228
261
  end
229
262
 
230
263
  it 'logs an error' do
231
- broker.logger.should_receive(:error)
264
+ expect(broker.logger).to receive(:error)
232
265
  broker.publish('test.key', 'message') rescue nil
233
266
  end
234
267
  end
@@ -8,7 +8,7 @@ describe Hutch::CLI do
8
8
  context "--config" do
9
9
  context "when the config file does not exist" do
10
10
  let(:file) { "/path/to/nonexistant/file" }
11
- before { STDERR.stub(:write) }
11
+ before { allow(STDERR).to receive(:write) }
12
12
 
13
13
  it "bails" do
14
14
  expect {
@@ -23,7 +23,7 @@ describe Hutch::CLI do
23
23
  end
24
24
 
25
25
  it "parses the config" do
26
- Hutch::Config.should_receive(:load_from_file)
26
+ expect(Hutch::Config).to receive(:load_from_file)
27
27
  cli.parse_options(["--config=#{file}"])
28
28
  end
29
29
  end
@@ -32,7 +32,7 @@ describe Hutch::CLI do
32
32
  context "--mq-tls-key" do
33
33
  context "when the keyfile file does not exist" do
34
34
  let(:file) { "/path/to/nonexistant/file" }
35
- before { STDERR.stub(:write) }
35
+ before { allow(STDERR).to receive(:write) }
36
36
 
37
37
  it "bails" do
38
38
  expect {
@@ -47,7 +47,7 @@ describe Hutch::CLI do
47
47
  end
48
48
 
49
49
  it "sets mq_tls_key to the file" do
50
- Hutch::Config.should_receive(:mq_tls_key=)
50
+ expect(Hutch::Config).to receive(:mq_tls_key=)
51
51
  cli.parse_options(["--mq-tls-key=#{file}"])
52
52
  end
53
53
  end
@@ -56,7 +56,7 @@ describe Hutch::CLI do
56
56
  context "--mq-tls-cert" do
57
57
  context "when the certfile file does not exist" do
58
58
  let(:file) { "/path/to/nonexistant/file" }
59
- before { STDERR.stub(:write) }
59
+ before { allow(STDERR).to receive(:write) }
60
60
 
61
61
  it "bails" do
62
62
  expect {
@@ -71,7 +71,7 @@ describe Hutch::CLI do
71
71
  end
72
72
 
73
73
  it "sets mq_tls_cert to the file" do
74
- Hutch::Config.should_receive(:mq_tls_cert=)
74
+ expect(Hutch::Config).to receive(:mq_tls_cert=)
75
75
  cli.parse_options(["--mq-tls-cert=#{file}"])
76
76
  end
77
77
  end
@@ -9,18 +9,18 @@ describe Hutch::Config do
9
9
  subject { Hutch::Config.get(:mq_host) }
10
10
 
11
11
  context 'with no overridden value' do
12
- it { should == 'localhost' }
12
+ it { is_expected.to eq('localhost') }
13
13
  end
14
14
 
15
15
  context 'with an overridden value' do
16
- before { Hutch::Config.stub(user_config: { mq_host: new_value }) }
17
- it { should == new_value }
16
+ before { allow(Hutch::Config).to receive_messages(user_config: { mq_host: new_value }) }
17
+ it { is_expected.to eq(new_value) }
18
18
  end
19
19
  end
20
20
 
21
21
  context 'for invalid attributes' do
22
22
  let(:invalid_get) { ->{ Hutch::Config.get(:invalid_attr) } }
23
- specify { invalid_get.should raise_error Hutch::UnknownAttributeError }
23
+ specify { expect(invalid_get).to raise_error Hutch::UnknownAttributeError }
24
24
  end
25
25
  end
26
26
 
@@ -30,41 +30,41 @@ describe Hutch::Config do
30
30
  subject { Hutch::Config.user_config[:mq_host] }
31
31
 
32
32
  context 'sets value in user config hash' do
33
- it { should == new_value }
33
+ it { is_expected.to eq(new_value) }
34
34
  end
35
35
  end
36
36
 
37
37
  context 'for invalid attributes' do
38
38
  let(:invalid_set) { ->{ Hutch::Config.set(:invalid_attr, new_value) } }
39
- specify { invalid_set.should raise_error Hutch::UnknownAttributeError }
39
+ specify { expect(invalid_set).to raise_error Hutch::UnknownAttributeError }
40
40
  end
41
41
  end
42
42
 
43
43
  describe 'a magic getter' do
44
44
  context 'for a valid attribute' do
45
45
  it 'calls get' do
46
- Hutch::Config.should_receive(:get).with(:mq_host)
46
+ expect(Hutch::Config).to receive(:get).with(:mq_host)
47
47
  Hutch::Config.mq_host
48
48
  end
49
49
  end
50
50
 
51
51
  context 'for an invalid attribute' do
52
52
  let(:invalid_getter) { ->{ Hutch::Config.invalid_attr } }
53
- specify { invalid_getter.should raise_error NoMethodError }
53
+ specify { expect(invalid_getter).to raise_error NoMethodError }
54
54
  end
55
55
  end
56
56
 
57
57
  describe 'a magic setter' do
58
58
  context 'for a valid attribute' do
59
59
  it 'calls set' do
60
- Hutch::Config.should_receive(:set).with(:mq_host, new_value)
60
+ expect(Hutch::Config).to receive(:set).with(:mq_host, new_value)
61
61
  Hutch::Config.mq_host = new_value
62
62
  end
63
63
  end
64
64
 
65
65
  context 'for an invalid attribute' do
66
66
  let(:invalid_setter) { ->{ Hutch::Config.invalid_attr = new_value } }
67
- specify { invalid_setter.should raise_error NoMethodError }
67
+ specify { expect(invalid_setter).to raise_error NoMethodError }
68
68
  end
69
69
  end
70
70
 
@@ -92,8 +92,8 @@ describe Hutch::Config do
92
92
 
93
93
  it 'loads in the config data' do
94
94
  Hutch::Config.load_from_file(file)
95
- Hutch::Config.mq_host.should eq host
96
- Hutch::Config.mq_username.should eq username
95
+ expect(Hutch::Config.mq_host).to eq host
96
+ expect(Hutch::Config.mq_username).to eq username
97
97
  end
98
98
  end
99
99
  end
@@ -29,8 +29,8 @@ describe Hutch::Consumer do
29
29
 
30
30
  describe 'module inclusion' do
31
31
  it 'registers the class as a consumer' do
32
- Hutch.should_receive(:register_consumer) do |klass|
33
- klass.should == simple_consumer
32
+ expect(Hutch).to receive(:register_consumer) do |klass|
33
+ expect(klass).to eq(simple_consumer)
34
34
  end
35
35
 
36
36
  simple_consumer
@@ -40,20 +40,24 @@ describe Hutch::Consumer do
40
40
 
41
41
  describe '.consume' do
42
42
  it 'saves the routing key to the consumer' do
43
- simple_consumer.routing_keys.should include 'hutch.test1'
43
+ expect(simple_consumer.routing_keys).to include 'hutch.test1'
44
44
  end
45
45
 
46
46
  context 'with multiple routing keys' do
47
47
  it 'registers the class once for each routing key' do
48
- complex_consumer.routing_keys.should include 'hutch.test1'
49
- complex_consumer.routing_keys.should include 'hutch.test2'
48
+ expect(complex_consumer.routing_keys).to include 'hutch.test1'
49
+ expect(complex_consumer.routing_keys).to include 'hutch.test2'
50
50
  end
51
51
  end
52
52
 
53
53
  context 'when given the same routing key multiple times' do
54
54
  subject { simple_consumer.routing_keys }
55
55
  before { simple_consumer.consume 'hutch.test1' }
56
- its(:length) { should == 1}
56
+
57
+ describe '#length' do
58
+ subject { super().length }
59
+ it { is_expected.to eq(1)}
60
+ end
57
61
  end
58
62
  end
59
63
 
@@ -72,7 +76,7 @@ describe Hutch::Consumer do
72
76
  queue_name "bar"
73
77
  end
74
78
 
75
- Foo.get_queue_name.should == "bar"
79
+ expect(Foo.get_queue_name).to eq("bar")
76
80
  end
77
81
  end
78
82
 
@@ -84,7 +88,7 @@ describe Hutch::Consumer do
84
88
  end
85
89
  end
86
90
 
87
- Foo::Bar.get_queue_name.should == 'foo:bar'
91
+ expect(Foo::Bar.get_queue_name).to eq('foo:bar')
88
92
  end
89
93
 
90
94
  it 'converts camelcase class names to snake case' do
@@ -92,7 +96,7 @@ describe Hutch::Consumer do
92
96
  include Hutch::Consumer
93
97
  end
94
98
 
95
- FooBarBAZ.get_queue_name.should == 'foo_bar_baz'
99
+ expect(FooBarBAZ.get_queue_name).to eq('foo_bar_baz')
96
100
  end
97
101
  end
98
102
  end
@@ -4,12 +4,12 @@ describe Hutch::ErrorHandlers::Logger do
4
4
  let(:error_handler) { Hutch::ErrorHandlers::Logger.new }
5
5
 
6
6
  describe '#handle' do
7
- let(:error) { stub(message: "Stuff went wrong", class: "RuntimeError",
7
+ let(:error) { double(message: "Stuff went wrong", class: "RuntimeError",
8
8
  backtrace: ["line 1", "line 2"]) }
9
9
 
10
10
  it "logs three separate lines" do
11
- Hutch::Logging.logger.should_receive(:error).exactly(3).times
12
- error_handler.handle("1", stub, error)
11
+ expect(Hutch::Logging.logger).to receive(:error).exactly(3).times
12
+ error_handler.handle("1", "{}", double, error)
13
13
  end
14
14
  end
15
15
  end
@@ -13,8 +13,8 @@ describe Hutch::ErrorHandlers::Sentry do
13
13
  end
14
14
 
15
15
  it "logs the error to Sentry" do
16
- Raven.should_receive(:capture_exception).with(error)
17
- error_handler.handle("1", stub, error)
16
+ expect(Raven).to receive(:capture_exception).with(error)
17
+ error_handler.handle("1", "{}", double, error)
18
18
  end
19
19
  end
20
20
  end
@@ -11,16 +11,16 @@ describe Hutch::Logging do
11
11
  context 'with the default logger' do
12
12
  subject { Hutch::Logging.logger }
13
13
 
14
- it { should be_instance_of(Logger) }
14
+ it { is_expected.to be_instance_of(Logger) }
15
15
  end
16
16
 
17
17
  context 'with a custom logger' do
18
- let(:dummy_logger) { mock("Dummy logger", warn: true, info: true) }
18
+ let(:dummy_logger) { double("Dummy logger", warn: true, info: true) }
19
19
  after { Hutch::Logging.setup_logger }
20
20
 
21
21
  it "users the custom logger" do
22
22
  Hutch::Logging.logger = dummy_logger
23
- Hutch::Logging.logger.should == dummy_logger
23
+ expect(Hutch::Logging.logger).to eq(dummy_logger)
24
24
  end
25
25
  end
26
26
  end
@@ -7,17 +7,20 @@ describe Hutch::Message do
7
7
  let(:json_body) { MultiJson.dump(body) }
8
8
  subject(:message) { Hutch::Message.new(delivery_info, props, json_body) }
9
9
 
10
- its(:body) { should == body }
10
+ describe '#body' do
11
+ subject { super().body }
12
+ it { is_expected.to eq(body) }
13
+ end
11
14
 
12
15
  describe '[]' do
13
16
  subject { message[:foo] }
14
- it { should == 'bar' }
17
+ it { is_expected.to eq('bar') }
15
18
  end
16
19
 
17
20
  [:message_id, :timestamp].each do |method|
18
21
  describe method.to_s do
19
22
  it 'delegates to @properties' do
20
- props.should_receive(method)
23
+ expect(props).to receive(method)
21
24
  message.send(method)
22
25
  end
23
26
  end
@@ -26,7 +29,7 @@ describe Hutch::Message do
26
29
  [:routing_key, :exchange].each do |method|
27
30
  describe method.to_s do
28
31
  it 'delegates to @delivery_info' do
29
- delivery_info.should_receive(method)
32
+ expect(delivery_info).to receive(method)
30
33
  message.send(method)
31
34
  end
32
35
  end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
  require 'hutch/worker'
3
3
 
4
4
  describe Hutch::Worker do
5
- before { Raven.as_null_object }
6
5
  let(:consumer) { double('Consumer', routing_keys: %w( a b c ),
7
6
  get_queue_name: 'consumer') }
8
7
  let(:consumers) { [consumer, double('Consumer')] }
@@ -12,7 +11,7 @@ describe Hutch::Worker do
12
11
  describe '#setup_queues' do
13
12
  it 'sets up queues for each of the consumers' do
14
13
  consumers.each do |consumer|
15
- worker.should_receive(:setup_queue).with(consumer)
14
+ expect(worker).to receive(:setup_queue).with(consumer)
16
15
  end
17
16
  worker.setup_queues
18
17
  end
@@ -20,21 +19,21 @@ describe Hutch::Worker do
20
19
 
21
20
  describe '#setup_queue' do
22
21
  let(:queue) { double('Queue', bind: nil, subscribe: nil) }
23
- before { worker.stub(consumer_queue: queue) }
24
- before { broker.stub(queue: queue, bind_queue: nil) }
22
+ before { allow(worker).to receive_messages(consumer_queue: queue) }
23
+ before { allow(broker).to receive_messages(queue: queue, bind_queue: nil) }
25
24
 
26
25
  it 'creates a queue' do
27
- broker.should_receive(:queue).with(consumer.get_queue_name).and_return(queue)
26
+ expect(broker).to receive(:queue).with(consumer.get_queue_name).and_return(queue)
28
27
  worker.setup_queue(consumer)
29
28
  end
30
29
 
31
30
  it 'binds the queue to each of the routing keys' do
32
- broker.should_receive(:bind_queue).with(queue, %w( a b c ))
31
+ expect(broker).to receive(:bind_queue).with(queue, %w( a b c ))
33
32
  worker.setup_queue(consumer)
34
33
  end
35
34
 
36
35
  it 'sets up a subscription' do
37
- queue.should_receive(:subscribe).with(ack: true)
36
+ expect(queue).to receive(:subscribe).with(ack: true)
38
37
  worker.setup_queue(consumer)
39
38
  end
40
39
  end
@@ -45,34 +44,36 @@ describe Hutch::Worker do
45
44
  let(:delivery_info) { double('Delivery Info', routing_key: '',
46
45
  delivery_tag: 'dt') }
47
46
  let(:properties) { double('Properties', message_id: nil) }
48
- before { consumer.stub(new: consumer_instance) }
49
- before { broker.stub(:ack) }
50
- before { broker.stub(:nack) }
47
+ before { allow(consumer).to receive_messages(new: consumer_instance) }
48
+ before { allow(broker).to receive(:ack) }
49
+ before { allow(broker).to receive(:nack) }
50
+ before { allow(consumer_instance).to receive(:broker=) }
51
+ before { allow(consumer_instance).to receive(:delivery_info=) }
51
52
 
52
53
  it 'passes the message to the consumer' do
53
- consumer_instance.should_receive(:process).
54
+ expect(consumer_instance).to receive(:process).
54
55
  with(an_instance_of(Hutch::Message))
55
56
  worker.handle_message(consumer, delivery_info, properties, payload)
56
57
  end
57
58
 
58
59
  it 'acknowledges the message' do
59
- consumer_instance.stub(:process)
60
- broker.should_receive(:ack).with(delivery_info.delivery_tag)
60
+ allow(consumer_instance).to receive(:process)
61
+ expect(broker).to receive(:ack).with(delivery_info.delivery_tag)
61
62
  worker.handle_message(consumer, delivery_info, properties, payload)
62
63
  end
63
64
 
64
65
  context 'when the consumer raises an exception' do
65
- before { consumer_instance.stub(:process).and_raise('a consumer error') }
66
+ before { allow(consumer_instance).to receive(:process).and_raise('a consumer error') }
66
67
 
67
68
  it 'logs the error' do
68
69
  Hutch::Config[:error_handlers].each do |backend|
69
- backend.should_receive(:handle)
70
+ expect(backend).to receive(:handle)
70
71
  end
71
72
  worker.handle_message(consumer, delivery_info, properties, payload)
72
73
  end
73
74
 
74
75
  it 'rejects the message' do
75
- broker.should_receive(:nack).with(delivery_info.delivery_tag)
76
+ expect(broker).to receive(:nack).with(delivery_info.delivery_tag)
76
77
  worker.handle_message(consumer, delivery_info, properties, payload)
77
78
  end
78
79
  end
@@ -82,13 +83,13 @@ describe Hutch::Worker do
82
83
 
83
84
  it 'logs the error' do
84
85
  Hutch::Config[:error_handlers].each do |backend|
85
- backend.should_receive(:handle)
86
+ expect(backend).to receive(:handle)
86
87
  end
87
88
  worker.handle_message(consumer, delivery_info, properties, payload)
88
89
  end
89
90
 
90
91
  it 'rejects the message' do
91
- broker.should_receive(:nack).with(delivery_info.delivery_tag)
92
+ expect(broker).to receive(:nack).with(delivery_info.delivery_tag)
92
93
  worker.handle_message(consumer, delivery_info, properties, payload)
93
94
  end
94
95
  end
@@ -8,8 +8,8 @@ describe Hutch do
8
8
  it 'saves the consumers in the global consumer list' do
9
9
  Hutch.register_consumer(consumer_a)
10
10
  Hutch.register_consumer(consumer_b)
11
- Hutch.consumers.should include consumer_a
12
- Hutch.consumers.should include consumer_b
11
+ expect(Hutch.consumers).to include consumer_a
12
+ expect(Hutch.consumers).to include consumer_b
13
13
  end
14
14
  end
15
15
 
@@ -21,8 +21,8 @@ describe Hutch do
21
21
  let(:action) { Hutch.connect(options, config) }
22
22
 
23
23
  it 'passes options and config' do
24
- Hutch::Broker.should_receive(:new).with(config).and_return broker
25
- broker.should_receive(:connect).with options
24
+ expect(Hutch::Broker).to receive(:new).with(config).and_return broker
25
+ expect(broker).to receive(:connect).with options
26
26
 
27
27
  action
28
28
  end
@@ -30,15 +30,15 @@ describe Hutch do
30
30
  it 'sets @connect' do
31
31
  action
32
32
 
33
- expect(Hutch.connected?).to be_true
33
+ expect(Hutch.connected?).to be_truthy
34
34
  end
35
35
  end
36
36
 
37
37
  context 'connected' do
38
- before { Hutch.stub(:connected?).and_return true }
38
+ before { allow(Hutch).to receive(:connected?).and_return true }
39
39
 
40
40
  it 'does not reconnect' do
41
- Hutch::Broker.should_not_receive :new
41
+ expect(Hutch::Broker).not_to receive :new
42
42
  Hutch.connect
43
43
  end
44
44
  end
@@ -48,12 +48,10 @@ describe Hutch do
48
48
  let(:broker) { double(Hutch::Broker) }
49
49
  let(:args) { ['test.key', 'message', { headers: { foo: 'bar' } }] }
50
50
 
51
- before do
52
- Hutch.stub broker: broker
53
- end
51
+ before { allow(Hutch).to receive(:broker).and_return(broker) }
54
52
 
55
53
  it 'delegates to Hutch::Broker#publish' do
56
- broker.should_receive(:publish).with(*args)
54
+ expect(broker).to receive(:publish).with(*args)
57
55
  Hutch.publish(*args)
58
56
  end
59
57
  end
@@ -15,6 +15,7 @@ require 'logger'
15
15
 
16
16
  RSpec.configure do |config|
17
17
  config.before(:all) { Hutch::Config.log_level = Logger::FATAL }
18
+ config.raise_errors_for_deprecations!
18
19
  end
19
20
 
20
21
  # Constants (classes, etc) defined within a block passed to this method
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hutch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harry Marr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-13 00:00:00.000000000 Z
11
+ date: 2014-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: 1.2.1
19
+ version: 1.5.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
- version: 1.2.1
26
+ version: 1.5.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: carrot-top
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 2.12.0
61
+ version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
- version: 2.12.0
68
+ version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement