shivam 0.0.0-java

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.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/test.yml +57 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +1 -0
  5. data/.yardopts +5 -0
  6. data/CHANGELOG.md +899 -0
  7. data/Gemfile +35 -0
  8. data/Guardfile +14 -0
  9. data/LICENSE +23 -0
  10. data/README.md +679 -0
  11. data/Rakefile +21 -0
  12. data/bin/ci/before_build.sh +20 -0
  13. data/bin/ci/before_build_docker.sh +20 -0
  14. data/bin/ci/install_on_debian.sh +46 -0
  15. data/bin/hutch +8 -0
  16. data/examples/consumer.rb +13 -0
  17. data/examples/producer.rb +10 -0
  18. data/hutch.gemspec +27 -0
  19. data/lib/hutch/acknowledgements/base.rb +16 -0
  20. data/lib/hutch/acknowledgements/nack_on_all_failures.rb +19 -0
  21. data/lib/hutch/adapter.rb +11 -0
  22. data/lib/hutch/adapters/bunny.rb +37 -0
  23. data/lib/hutch/adapters/march_hare.rb +41 -0
  24. data/lib/hutch/broker.rb +384 -0
  25. data/lib/hutch/cli.rb +246 -0
  26. data/lib/hutch/config.rb +305 -0
  27. data/lib/hutch/consumer.rb +125 -0
  28. data/lib/hutch/error_handlers/airbrake.rb +54 -0
  29. data/lib/hutch/error_handlers/base.rb +15 -0
  30. data/lib/hutch/error_handlers/bugsnag.rb +30 -0
  31. data/lib/hutch/error_handlers/honeybadger.rb +43 -0
  32. data/lib/hutch/error_handlers/logger.rb +22 -0
  33. data/lib/hutch/error_handlers/rollbar.rb +28 -0
  34. data/lib/hutch/error_handlers/sentry.rb +26 -0
  35. data/lib/hutch/error_handlers/sentry_raven.rb +31 -0
  36. data/lib/hutch/error_handlers.rb +11 -0
  37. data/lib/hutch/exceptions.rb +14 -0
  38. data/lib/hutch/logging.rb +32 -0
  39. data/lib/hutch/message.rb +31 -0
  40. data/lib/hutch/publisher.rb +75 -0
  41. data/lib/hutch/serializers/identity.rb +19 -0
  42. data/lib/hutch/serializers/json.rb +22 -0
  43. data/lib/hutch/tracers/datadog.rb +18 -0
  44. data/lib/hutch/tracers/newrelic.rb +19 -0
  45. data/lib/hutch/tracers/null_tracer.rb +15 -0
  46. data/lib/hutch/tracers.rb +7 -0
  47. data/lib/hutch/version.rb +3 -0
  48. data/lib/hutch/waiter.rb +104 -0
  49. data/lib/hutch/worker.rb +145 -0
  50. data/lib/hutch.rb +69 -0
  51. data/lib/yard-settings/handler.rb +38 -0
  52. data/lib/yard-settings/yard-settings.rb +2 -0
  53. data/spec/hutch/broker_spec.rb +462 -0
  54. data/spec/hutch/cli_spec.rb +93 -0
  55. data/spec/hutch/config_spec.rb +259 -0
  56. data/spec/hutch/consumer_spec.rb +208 -0
  57. data/spec/hutch/error_handlers/airbrake_spec.rb +49 -0
  58. data/spec/hutch/error_handlers/bugsnag_spec.rb +55 -0
  59. data/spec/hutch/error_handlers/honeybadger_spec.rb +58 -0
  60. data/spec/hutch/error_handlers/logger_spec.rb +28 -0
  61. data/spec/hutch/error_handlers/rollbar_spec.rb +45 -0
  62. data/spec/hutch/error_handlers/sentry_raven_spec.rb +37 -0
  63. data/spec/hutch/error_handlers/sentry_spec.rb +47 -0
  64. data/spec/hutch/logger_spec.rb +34 -0
  65. data/spec/hutch/message_spec.rb +38 -0
  66. data/spec/hutch/serializers/json_spec.rb +17 -0
  67. data/spec/hutch/tracers/datadog_spec.rb +44 -0
  68. data/spec/hutch/waiter_spec.rb +51 -0
  69. data/spec/hutch/worker_spec.rb +184 -0
  70. data/spec/hutch_spec.rb +87 -0
  71. data/spec/spec_helper.rb +42 -0
  72. data/templates/default/class/html/settings.erb +0 -0
  73. data/templates/default/class/setup.rb +4 -0
  74. data/templates/default/fulldoc/html/css/hutch.css +13 -0
  75. data/templates/default/layout/html/setup.rb +7 -0
  76. data/templates/default/method_details/html/settings.erb +5 -0
  77. data/templates/default/method_details/setup.rb +4 -0
  78. data/templates/default/method_details/text/settings.erb +0 -0
  79. data/templates/default/module/html/settings.erb +40 -0
  80. data/templates/default/module/setup.rb +4 -0
  81. metadata +205 -0
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hutch::ErrorHandlers::SentryRaven do
4
+ let(:error_handler) { Hutch::ErrorHandlers::SentryRaven.new }
5
+
6
+ describe '#handle' do
7
+ let(:properties) { OpenStruct.new(message_id: "1") }
8
+ let(:payload) { "{}" }
9
+ let(:error) do
10
+ begin
11
+ raise "Stuff went wrong"
12
+ rescue RuntimeError => err
13
+ err
14
+ end
15
+ end
16
+
17
+ it "logs the error to Sentry" do
18
+ expect(Raven).to receive(:capture_exception).with(error, {extra: { payload: payload }})
19
+ error_handler.handle(properties, payload, double, error)
20
+ end
21
+ end
22
+
23
+ describe '#handle_setup_exception' do
24
+ let(:error) do
25
+ begin
26
+ raise "Stuff went wrong during setup"
27
+ rescue RuntimeError => err
28
+ err
29
+ end
30
+ end
31
+
32
+ it "logs the error to Sentry" do
33
+ expect(Raven).to receive(:capture_exception).with(error)
34
+ error_handler.handle_setup_exception(error)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hutch::ErrorHandlers::Sentry do
4
+ let(:error_handler) { Hutch::ErrorHandlers::Sentry.new }
5
+
6
+ before do
7
+ Sentry.init do
8
+ # initialize Sentry so that the integration acutally works
9
+ # otherwise, all its methods are going to return early
10
+ # so it will be impossible to check if it actually works
11
+ end
12
+ end
13
+
14
+ describe '#handle' do
15
+ let(:properties) { OpenStruct.new(message_id: "1") }
16
+ let(:payload) { "{}" }
17
+ let(:error) do
18
+ begin
19
+ raise "Stuff went wrong"
20
+ rescue RuntimeError => err
21
+ err
22
+ end
23
+ end
24
+
25
+ it "logs the error to Sentry" do
26
+ expect(::Sentry).to receive(:capture_exception).with(error).and_call_original
27
+
28
+ error_handler.handle(properties, payload, double, error)
29
+ end
30
+ end
31
+
32
+ describe '#handle_setup_exception' do
33
+ let(:error) do
34
+ begin
35
+ raise "Stuff went wrong during setup"
36
+ rescue RuntimeError => err
37
+ err
38
+ end
39
+ end
40
+
41
+ it "logs the error to Sentry" do
42
+ expect(::Sentry).to receive(:capture_exception).with(error).and_call_original
43
+
44
+ error_handler.handle_setup_exception(error)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hutch::Logging do
4
+ let(:dummy_object) do
5
+ class DummyObject
6
+ include described_class
7
+ end
8
+ end
9
+
10
+ describe '#logger' do
11
+ around do |example|
12
+ old_logger = described_class.logger
13
+ described_class.setup_logger
14
+ example.run
15
+ described_class.logger = old_logger
16
+ end
17
+
18
+ context 'with the default logger' do
19
+ subject { described_class.logger }
20
+
21
+ it { is_expected.to be_instance_of(Logger) }
22
+ end
23
+
24
+ context 'with a custom logger' do
25
+ let(:dummy_logger) { double("Dummy logger") }
26
+
27
+ it "users the custom logger" do
28
+ described_class.logger = dummy_logger
29
+ expect(described_class.logger).to eq(dummy_logger)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,38 @@
1
+ require 'hutch/message'
2
+
3
+ describe Hutch::Message do
4
+ let(:delivery_info) { double('Delivery Info') }
5
+ let(:props) { double('Properties', content_type: "application/json") }
6
+ let(:body) {{ foo: 'bar' }.with_indifferent_access}
7
+ let(:json_body) { MultiJson.dump(body) }
8
+ subject(:message) { Hutch::Message.new(delivery_info, props, json_body, Hutch::Config[:serializer]) }
9
+
10
+ describe '#body' do
11
+ subject { super().body }
12
+ it { is_expected.to eq(body) }
13
+ end
14
+
15
+ describe '[]' do
16
+ subject { message[:foo] }
17
+ it { is_expected.to eq('bar') }
18
+ end
19
+
20
+ [:message_id, :timestamp].each do |method|
21
+ describe method.to_s do
22
+ it 'delegates to @properties' do
23
+ expect(props).to receive(method)
24
+ message.send(method)
25
+ end
26
+ end
27
+ end
28
+
29
+ [:routing_key, :exchange].each do |method|
30
+ describe method.to_s do
31
+ it 'delegates to @delivery_info' do
32
+ expect(delivery_info).to receive(method)
33
+ message.send(method)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hutch::Serializers::JSON do
4
+ let(:subject) { described_class }
5
+
6
+ it "encode/decode" do
7
+ payload = { a: 1, b: 2 }
8
+ encoded = subject.encode(payload)
9
+ decoded = subject.decode(encoded)
10
+
11
+ expect(encoded).to eq "{\"a\":1,\"b\":2}"
12
+ expect(decoded).to eq("a" => 1, "b" => 2)
13
+ expect(decoded[:a]).to eq 1
14
+ expect(decoded[:b]).to eq 2
15
+ end
16
+
17
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Hutch::Tracers::Datadog do
4
+ describe "#handle" do
5
+ subject(:handle) { tracer.handle(message) }
6
+
7
+ let(:tracer) { described_class.new(klass) }
8
+ let(:klass) do
9
+ Class.new do
10
+ attr_reader :message
11
+
12
+ def initialize
13
+ @message = nil
14
+ end
15
+
16
+ def class
17
+ OpenStruct.new(name: 'ClassName')
18
+ end
19
+
20
+ def process(message)
21
+ @message = message
22
+ end
23
+ end.new
24
+ end
25
+ let(:message) { double(:message) }
26
+
27
+ before do
28
+ allow(::Datadog::Tracing).to receive(:trace).and_call_original
29
+ end
30
+
31
+ it 'uses Datadog tracer' do
32
+ handle
33
+
34
+ expect(::Datadog::Tracing).to have_received(:trace).with('ClassName',
35
+ hash_including(service: 'hutch', type: 'rabbitmq'))
36
+ end
37
+
38
+ it 'processes the message' do
39
+ expect {
40
+ handle
41
+ }.to change { klass.message }.from(nil).to(message)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,51 @@
1
+ require 'hutch/waiter'
2
+
3
+ RSpec.describe Hutch::Waiter do
4
+ describe '.wait_until_signaled' do
5
+ let(:pid) { Process.pid }
6
+ def start_kill_thread(signal)
7
+ Thread.new do
8
+ # sleep allows the worker time to set up the signal handling
9
+ # before the kill signal is sent.
10
+ sleep 0.001
11
+ Process.kill signal, pid
12
+ end
13
+ end
14
+
15
+ context 'a QUIT signal is received', if: RSpec::Support::Ruby.mri? do
16
+ it 'logs that hutch is stopping' do
17
+ expect(Hutch::Logging.logger).to receive(:info)
18
+ .with('caught SIGQUIT, stopping hutch...')
19
+
20
+ start_kill_thread('QUIT')
21
+ described_class.wait_until_signaled
22
+ end
23
+ end
24
+
25
+ context 'a TERM signal is received', if: !defined?(JRUBY_VERSION) do
26
+ it 'logs that hutch is stopping' do
27
+ expect(Hutch::Logging.logger).to receive(:info)
28
+ .with('caught SIGTERM, stopping hutch...')
29
+
30
+ start_kill_thread('TERM')
31
+ described_class.wait_until_signaled
32
+ end
33
+ end
34
+
35
+ context 'a INT signal is received', if: !defined?(JRUBY_VERSION) do
36
+ it 'logs that hutch is stopping' do
37
+ expect(Hutch::Logging.logger).to receive(:info)
38
+ .with('caught SIGINT, stopping hutch...')
39
+
40
+ start_kill_thread('INT')
41
+ described_class.wait_until_signaled
42
+ end
43
+ end
44
+ end
45
+
46
+ describe described_class::SHUTDOWN_SIGNALS do
47
+ it 'includes only things in Signal.list.keys' do
48
+ expect(described_class).to eq(described_class & Signal.list.keys)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+ require 'hutch/worker'
3
+
4
+ describe Hutch::Worker do
5
+ let(:consumer) { double('Consumer', routing_keys: %w( a b c ),
6
+ get_queue_name: 'consumer', get_arguments: {},
7
+ get_options: {}, get_serializer: nil) }
8
+ let(:consumers) { [consumer, double('Consumer')] }
9
+ let(:broker) { Hutch::Broker.new }
10
+ let(:setup_procs) { Array.new(2) { Proc.new {} } }
11
+ subject(:worker) { Hutch::Worker.new(broker, consumers, setup_procs) }
12
+
13
+ describe ".#run" do
14
+ it "calls each setup proc" do
15
+ setup_procs.each { |prc| expect(prc).to receive(:call) }
16
+ allow(worker).to receive(:setup_queues)
17
+ allow(Hutch::Waiter).to receive(:wait_until_signaled)
18
+ allow(broker).to receive(:stop)
19
+
20
+ worker.run
21
+ end
22
+ end
23
+
24
+ describe '#setup_queues' do
25
+ it 'sets up queues for each of the consumers' do
26
+ consumers.each do |consumer|
27
+ expect(worker).to receive(:setup_queue).with(consumer)
28
+ end
29
+ worker.setup_queues
30
+ end
31
+ end
32
+
33
+ describe '#setup_queue' do
34
+ let(:queue) { double('Queue', bind: nil, subscribe: nil) }
35
+ before { allow(broker).to receive_messages(queue: queue, bind_queue: nil) }
36
+
37
+ it 'creates a queue' do
38
+ expect(broker).to receive(:queue).with(consumer.get_queue_name, consumer.get_options).and_return(queue)
39
+ worker.setup_queue(consumer)
40
+ end
41
+
42
+ it 'binds the queue to each of the routing keys' do
43
+ expect(broker).to receive(:bind_queue).with(queue, %w( a b c ))
44
+ worker.setup_queue(consumer)
45
+ end
46
+
47
+ it 'sets up a subscription' do
48
+ expect(queue).to receive(:subscribe).with(consumer_tag: %r(^hutch\-.{36}$), manual_ack: true)
49
+ worker.setup_queue(consumer)
50
+ end
51
+
52
+ context 'with a configured consumer tag prefix' do
53
+ before { Hutch::Config.set(:consumer_tag_prefix, 'appname') }
54
+
55
+ it 'sets up a subscription with the configured tag prefix' do
56
+ expect(queue).to receive(:subscribe).with(consumer_tag: %r(^appname\-.{36}$), manual_ack: true)
57
+ worker.setup_queue(consumer)
58
+ end
59
+ end
60
+
61
+ context 'with a configured consumer tag prefix that is too long' do
62
+ let(:maximum_size) { 255 - SecureRandom.uuid.size - 1 }
63
+ before { Hutch::Config.set(:consumer_tag_prefix, 'a'.*(maximum_size + 1)) }
64
+
65
+ it 'raises an error' do
66
+ expect { worker.setup_queue(consumer) }.to raise_error(/Tag must be 255 bytes long at most/)
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#handle_message' do
72
+ let(:payload) { '{}' }
73
+ let(:consumer_instance) { double('Consumer instance') }
74
+ let(:delivery_info) { double('Delivery Info', routing_key: '',
75
+ delivery_tag: 'dt') }
76
+ let(:properties) { double('Properties', message_id: nil, content_type: "application/json") }
77
+ before { allow(consumer).to receive_messages(new: consumer_instance) }
78
+ before { allow(broker).to receive(:ack) }
79
+ before { allow(broker).to receive(:nack) }
80
+ before { allow(consumer_instance).to receive(:broker=) }
81
+ before { allow(consumer_instance).to receive(:delivery_info=) }
82
+
83
+ it 'passes the message to the consumer' do
84
+ expect(consumer_instance).to receive(:process).
85
+ with(an_instance_of(Hutch::Message))
86
+ expect(consumer_instance).to receive(:message_rejected?).and_return(false)
87
+ worker.handle_message(consumer, delivery_info, properties, payload)
88
+ end
89
+
90
+ it 'acknowledges the message' do
91
+ allow(consumer_instance).to receive(:process)
92
+ expect(broker).to receive(:ack).with(delivery_info.delivery_tag)
93
+ expect(consumer_instance).to receive(:message_rejected?).and_return(false)
94
+ worker.handle_message(consumer, delivery_info, properties, payload)
95
+ end
96
+
97
+ context 'when the consumer fails and a requeue is configured' do
98
+
99
+ it 'requeues the message' do
100
+ allow(consumer_instance).to receive(:process).and_raise('failed')
101
+ requeuer = double
102
+ allow(requeuer).to receive(:handle) { |delivery_info, properties, broker, e|
103
+ broker.requeue delivery_info.delivery_tag
104
+ true
105
+ }
106
+ allow(worker).to receive(:error_acknowledgements).and_return([requeuer])
107
+ expect(broker).to_not receive(:ack)
108
+ expect(broker).to_not receive(:nack)
109
+ expect(broker).to receive(:requeue)
110
+
111
+ worker.handle_message(consumer, delivery_info, properties, payload)
112
+ end
113
+ end
114
+
115
+
116
+ context 'when the consumer raises an exception' do
117
+ before { allow(consumer_instance).to receive(:process).and_raise('a consumer error') }
118
+
119
+ it 'logs the error' do
120
+ Hutch::Config[:error_handlers].each do |backend|
121
+ expect(backend).to receive(:handle)
122
+ end
123
+ worker.handle_message(consumer, delivery_info, properties, payload)
124
+ end
125
+
126
+ it 'rejects the message' do
127
+ expect(broker).to receive(:nack).with(delivery_info.delivery_tag)
128
+ worker.handle_message(consumer, delivery_info, properties, payload)
129
+ end
130
+ end
131
+
132
+ context "when the payload is not valid json" do
133
+ let(:payload) { "Not Valid JSON" }
134
+
135
+ it 'logs the error' do
136
+ Hutch::Config[:error_handlers].each do |backend|
137
+ expect(backend).to receive(:handle)
138
+ end
139
+ worker.handle_message(consumer, delivery_info, properties, payload)
140
+ end
141
+
142
+ it 'rejects the message' do
143
+ expect(broker).to receive(:nack).with(delivery_info.delivery_tag)
144
+ worker.handle_message(consumer, delivery_info, properties, payload)
145
+ end
146
+ end
147
+ end
148
+
149
+
150
+ describe '#acknowledge_error' do
151
+ let(:delivery_info) { double('Delivery Info', routing_key: '',
152
+ delivery_tag: 'dt') }
153
+ let(:properties) { double('Properties', message_id: 'abc123') }
154
+
155
+ subject { worker.acknowledge_error delivery_info, properties, broker, StandardError.new }
156
+
157
+ it 'stops when it runs a successful acknowledgement' do
158
+ skip_ack = double handle: false
159
+ always_ack = double handle: true
160
+ never_used = double handle: true
161
+
162
+ allow(worker).
163
+ to receive(:error_acknowledgements).
164
+ and_return([skip_ack, always_ack, never_used])
165
+
166
+ expect(never_used).to_not receive(:handle)
167
+
168
+ subject
169
+ end
170
+
171
+ it 'defaults to nacking' do
172
+ skip_ack = double handle: false
173
+
174
+ allow(worker).
175
+ to receive(:error_acknowledgements).
176
+ and_return([skip_ack, skip_ack])
177
+
178
+ expect(broker).to receive(:nack)
179
+
180
+ subject
181
+ end
182
+ end
183
+ end
184
+
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hutch do
4
+ describe '.register_consumer' do
5
+ let(:consumer_a) { double('Consumer') }
6
+ let(:consumer_b) { double('Consumer') }
7
+
8
+ it 'saves the consumers in the global consumer list' do
9
+ Hutch.register_consumer(consumer_a)
10
+ Hutch.register_consumer(consumer_b)
11
+ expect(Hutch.consumers).to include consumer_a
12
+ expect(Hutch.consumers).to include consumer_b
13
+ end
14
+ end
15
+
16
+ describe '.connect' do
17
+ context 'not connected' do
18
+ let(:options) { double 'options' }
19
+ let(:config) { double 'config' }
20
+ let(:broker) { double 'broker' }
21
+ let(:action) { Hutch.connect(options, config) }
22
+
23
+ it 'passes options and config' do
24
+ expect(Hutch::Broker).to receive(:new).with(config).and_return broker
25
+ expect(broker).to receive(:connect).with options
26
+
27
+ action
28
+ end
29
+
30
+ end
31
+
32
+ context 'connected' do
33
+ before { allow(Hutch).to receive(:connected?).and_return true }
34
+
35
+ it 'does not reconnect' do
36
+ expect(Hutch::Broker).not_to receive :new
37
+ Hutch.connect
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '.connected?' do
43
+ subject(:connected?) { Hutch.connected? }
44
+
45
+ before { allow(Hutch).to receive(:broker).and_return(broker) }
46
+
47
+ context 'without a broker' do
48
+ let(:broker) { nil }
49
+
50
+ it { expect(connected?).to be_falsey }
51
+ end
52
+
53
+ context 'without a connection' do
54
+ let(:connection) { nil }
55
+ let(:broker) { double(:broker, connection: connection) }
56
+
57
+ it { expect(connected?).to be_falsey }
58
+ end
59
+
60
+ context 'with a closed connection' do
61
+ let(:connection) { double(:connection, open?: false) }
62
+ let(:broker) { double(:broker, connection: connection) }
63
+
64
+ it { expect(connected?).to be_falsey }
65
+ end
66
+
67
+ context 'with an opened connection' do
68
+ let(:connection) { double(:connection, open?: true) }
69
+ let(:broker) { double(:broker, connection: connection) }
70
+
71
+ it { expect(connected?).to be_truthy }
72
+ end
73
+ end
74
+
75
+ describe '#publish' do
76
+ let(:broker) { double(Hutch::Broker) }
77
+ let(:args) { ['test.key', 'message', { headers: { foo: 'bar' } }] }
78
+
79
+ before { allow(Hutch).to receive(:broker).and_return(broker) }
80
+
81
+ it 'delegates to Hutch::Broker#publish' do
82
+ expect(broker).to receive(:publish).with(*args)
83
+ Hutch.publish(*args)
84
+ end
85
+ end
86
+ end
87
+
@@ -0,0 +1,42 @@
1
+ require 'simplecov'
2
+ if ENV['TRAVIS']
3
+ require 'coveralls'
4
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
5
+ end
6
+
7
+ SimpleCov.start do
8
+ add_filter '/spec/'
9
+ add_filter '/.bundle/'
10
+ end
11
+
12
+ require 'raven'
13
+ require 'hutch'
14
+ require 'logger'
15
+
16
+ # set logger to be a null logger
17
+ Hutch::Logging.logger = Logger.new(File::NULL)
18
+
19
+ RSpec.configure do |config|
20
+ config.raise_errors_for_deprecations!
21
+
22
+ if defined?(JRUBY_VERSION)
23
+ config.filter_run_excluding adapter: :bunny
24
+ else
25
+ config.filter_run_excluding adapter: :march_hare
26
+ end
27
+
28
+ config.mock_with :rspec do |mocks|
29
+ mocks.verify_partial_doubles = true
30
+ end
31
+ end
32
+
33
+ # Constants (classes, etc) defined within a block passed to this method
34
+ # will be removed from the global namespace after the block as run.
35
+ def isolate_constants
36
+ existing_constants = Object.constants
37
+ yield
38
+ ensure
39
+ (Object.constants - existing_constants).each do |constant|
40
+ Object.send(:remove_const, constant)
41
+ end
42
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ def init
2
+ super
3
+ sections.push :settings
4
+ end
@@ -0,0 +1,13 @@
1
+ .settings {
2
+ border-spacing: 2.5rem;
3
+ border-collapse: collapse;
4
+ }
5
+
6
+ .settings thead th {
7
+ text-align: left;
8
+ }
9
+
10
+ .settings thead th,
11
+ .settings tbody td {
12
+ padding: .5em 1em;
13
+ }
@@ -0,0 +1,7 @@
1
+ def init
2
+ super
3
+ end
4
+
5
+ def stylesheets
6
+ super + %w(css/hutch.css)
7
+ end
@@ -0,0 +1,5 @@
1
+ <% if object['custom_field'] %>
2
+ <p>
3
+ <%= object['custom_field'] %>
4
+ </p>
5
+ <% end %>
@@ -0,0 +1,4 @@
1
+ def init
2
+ super
3
+ sections.last.place(:settings).after(:source)
4
+ end
@@ -0,0 +1,40 @@
1
+ <% if object['setting_rows'] %>
2
+ <h2>
3
+ Configuration
4
+ </h2>
5
+
6
+ <div class="tags">
7
+ <table border="1" class="settings">
8
+ <thead>
9
+ <tr>
10
+ <th>
11
+ Setting name
12
+ </th>
13
+ <th>
14
+ Default value
15
+ </th>
16
+ <th>
17
+ Type
18
+ </th>
19
+ <th>
20
+ ENV variable
21
+ </th>
22
+ <th>
23
+ Description
24
+ </th>
25
+ </tr>
26
+ </thead>
27
+ <tbody>
28
+ <% for setting in object['setting_rows'] %>
29
+ <tr>
30
+ <td><tt><%= resolve_links "{Hutch::Config##{setting[:name]} #{setting[:name]}}" %></tt></td>
31
+ <td><%= setting[:default_value] %></td>
32
+ <td><%= setting[:type] %></td>
33
+ <td><tt>HUTCH_<%= setting[:name].upcase %></tt></td>
34
+ <td><%= html_markup_markdown setting[:first_line_of_description] %></td>
35
+ </tr>
36
+ <% end %>
37
+ </tbody>
38
+ </table>
39
+ </div>
40
+ <% end %>
@@ -0,0 +1,4 @@
1
+ def init
2
+ super
3
+ sections.place(:settings).before(:children)
4
+ end