deimos-ruby 1.3.0.pre.beta5 → 1.4.0.pre.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -9
- data/Gemfile.lock +2 -88
- data/README.md +18 -135
- data/Rakefile +1 -1
- data/deimos-ruby.gemspec +0 -1
- data/docs/CONFIGURATION.md +200 -0
- data/lib/deimos/avro_data_coder.rb +4 -4
- data/lib/deimos/backends/db.rb +0 -5
- data/lib/deimos/base_consumer.rb +2 -2
- data/lib/deimos/config/configurable.rb +258 -0
- data/lib/deimos/config/configuration.rb +354 -0
- data/lib/deimos/config/phobos_config.rb +134 -0
- data/lib/deimos/kafka_message.rb +6 -0
- data/lib/deimos/producer.rb +5 -5
- data/lib/deimos/test_helpers.rb +2 -10
- data/lib/deimos/utils/db_producer.rb +0 -5
- data/lib/deimos/utils/lag_reporter.rb +4 -4
- data/lib/deimos/version.rb +1 -1
- data/lib/deimos.rb +2 -86
- data/lib/tasks/deimos.rake +1 -1
- data/spec/backends/db_spec.rb +0 -5
- data/spec/batch_consumer_spec.rb +1 -1
- data/spec/config/configurable_spec.rb +121 -0
- data/spec/config/configuration_spec.rb +229 -0
- data/spec/consumer_spec.rb +5 -5
- data/spec/deimos_spec.rb +14 -35
- data/spec/kafka_source_spec.rb +1 -1
- data/spec/producer_spec.rb +5 -5
- data/spec/spec_helper.rb +8 -20
- data/spec/updateable_schema_store_spec.rb +1 -1
- data/spec/utils/db_producer_spec.rb +0 -10
- data/spec/utils/lag_reporter_spec.rb +2 -2
- metadata +10 -19
- data/lib/deimos/configuration.rb +0 -124
- data/spec/rake_spec.rb +0 -19
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/array'
|
4
|
+
|
5
|
+
module Deimos
|
6
|
+
# Module to handle phobos.yml as well as outputting the configuration to save
|
7
|
+
# to Phobos itself.
|
8
|
+
module PhobosConfig
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
# @return [Hash]
|
12
|
+
def to_h
|
13
|
+
(FIELDS + [:handler]).map { |f|
|
14
|
+
val = self.send(f)
|
15
|
+
if f == :backoff && val
|
16
|
+
[:backoff, _backoff(val)]
|
17
|
+
elsif val.present?
|
18
|
+
[f, val]
|
19
|
+
end
|
20
|
+
}.to_h
|
21
|
+
end
|
22
|
+
|
23
|
+
# :nodoc:
|
24
|
+
def reset!
|
25
|
+
super
|
26
|
+
Phobos.configure(self.phobos_config)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Create a hash representing the config that Phobos expects.
|
30
|
+
# @return [Hash]
|
31
|
+
def phobos_config
|
32
|
+
p_config = {
|
33
|
+
logger: Logger.new(STDOUT),
|
34
|
+
custom_logger: self.phobos_logger,
|
35
|
+
custom_kafka_logger: self.kafka.logger,
|
36
|
+
kafka: {
|
37
|
+
client_id: self.kafka.client_id,
|
38
|
+
connect_timeout: self.kafka.connect_timeout,
|
39
|
+
socket_timeout: self.kafka.socket_timeout,
|
40
|
+
ssl_verify_hostname: self.kafka.ssl.verify_hostname,
|
41
|
+
seed_brokers: Array.wrap(self.kafka.seed_brokers)
|
42
|
+
},
|
43
|
+
producer: {
|
44
|
+
ack_timeout: self.producers.ack_timeout,
|
45
|
+
required_acks: self.producers.required_acks,
|
46
|
+
max_retries: self.producers.max_retries,
|
47
|
+
retry_backoff: self.producers.retry_backoff,
|
48
|
+
max_buffer_size: self.producers.max_buffer_size,
|
49
|
+
max_buffer_bytesize: self.producers.max_buffer_bytesize,
|
50
|
+
compression_codec: self.producers.compression_codec,
|
51
|
+
compression_threshold: self.producers.compression_threshold,
|
52
|
+
max_queue_size: self.producers.max_queue_size,
|
53
|
+
delivery_threshold: self.producers.delivery_threshold,
|
54
|
+
delivery_interval: self.producers.delivery_interval
|
55
|
+
},
|
56
|
+
consumer: {
|
57
|
+
session_timeout: self.consumers.session_timeout,
|
58
|
+
offset_commit_interval: self.consumers.offset_commit_interval,
|
59
|
+
offset_commit_threshold: self.consumers.offset_commit_threshold,
|
60
|
+
heartbeat_interval: self.consumers.heartbeat_interval
|
61
|
+
},
|
62
|
+
backoff: _backoff(self.consumers.backoff.to_a)
|
63
|
+
}
|
64
|
+
|
65
|
+
p_config[:listeners] = self.consumer_objects.map do |consumer|
|
66
|
+
hash = consumer.to_h.reject do |k, _|
|
67
|
+
%i(class_name schema namespace key_config backoff).include?(k)
|
68
|
+
end
|
69
|
+
hash = hash.map { |k, v| [k, v.is_a?(Symbol) ? v.to_s : v] }.to_h
|
70
|
+
hash[:handler] = consumer.class_name
|
71
|
+
if consumer.backoff
|
72
|
+
hash[:backoff] = _backoff(consumer.backoff.to_a)
|
73
|
+
end
|
74
|
+
hash
|
75
|
+
end
|
76
|
+
|
77
|
+
if self.kafka.ssl.enabled
|
78
|
+
%w(ca_cert client_cert client_cert_key).each do |key|
|
79
|
+
next if self.kafka.ssl.send(key).blank?
|
80
|
+
|
81
|
+
p_config[:kafka]["ssl_#{key}".to_sym] = ssl_var_contents(self.kafka.ssl.send(key))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
p_config
|
85
|
+
end
|
86
|
+
|
87
|
+
# @param key [String]
|
88
|
+
# @return [String]
|
89
|
+
def ssl_var_contents(key)
|
90
|
+
File.exist?(key) ? File.read(key) : key
|
91
|
+
end
|
92
|
+
|
93
|
+
# Legacy method to parse Phobos config file
|
94
|
+
def phobos_config_file=(file)
|
95
|
+
pconfig = YAML.load(ERB.new(File.read(File.expand_path(file))).result). # rubocop:disable Security/YAMLLoad
|
96
|
+
with_indifferent_access
|
97
|
+
self.logger&.warn('phobos.yml is deprecated - use direct configuration instead.')
|
98
|
+
pconfig[:kafka].each do |k, v|
|
99
|
+
if k.starts_with?('ssl')
|
100
|
+
k = k.sub('ssl_', '')
|
101
|
+
self.kafka.ssl.send("#{k}=", v)
|
102
|
+
else
|
103
|
+
self.kafka.send("#{k}=", v)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
pconfig[:producer].each do |k, v|
|
107
|
+
self.producers.send("#{k}=", v)
|
108
|
+
end
|
109
|
+
pconfig[:consumer].each do |k, v|
|
110
|
+
self.consumers.send("#{k}=", v)
|
111
|
+
end
|
112
|
+
self.consumers.backoff = pconfig[:backoff][:min_ms]..pconfig[:backoff][:max_ms]
|
113
|
+
pconfig[:listeners].each do |listener_hash|
|
114
|
+
self.consumer do
|
115
|
+
listener_hash.each do |k, v|
|
116
|
+
k = 'class_name' if k == 'handler'
|
117
|
+
send(k, v)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# @param values [Array<Integer>]
|
126
|
+
# @return [Hash<Integer>]
|
127
|
+
def _backoff(values)
|
128
|
+
{
|
129
|
+
min_ms: values[0],
|
130
|
+
max_ms: values[-1]
|
131
|
+
}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/deimos/kafka_message.rb
CHANGED
@@ -14,6 +14,12 @@ module Deimos
|
|
14
14
|
write_attribute(:message, mess ? mess.to_s : nil)
|
15
15
|
end
|
16
16
|
|
17
|
+
# Decoded payload for this message.
|
18
|
+
# @return [Hash]
|
19
|
+
def decoded_message
|
20
|
+
self.class.decoded([self]).first
|
21
|
+
end
|
22
|
+
|
17
23
|
# Get a decoder to decode a set of messages on the given topic.
|
18
24
|
# @param topic [String]
|
19
25
|
# @return [Deimos::Consumer]
|
data/lib/deimos/producer.rb
CHANGED
@@ -63,7 +63,7 @@ module Deimos
|
|
63
63
|
def config
|
64
64
|
@config ||= {
|
65
65
|
encode_key: true,
|
66
|
-
namespace: Deimos.config.
|
66
|
+
namespace: Deimos.config.producers.schema_namespace
|
67
67
|
}
|
68
68
|
end
|
69
69
|
|
@@ -76,7 +76,7 @@ module Deimos
|
|
76
76
|
return
|
77
77
|
end
|
78
78
|
# accessor
|
79
|
-
"#{Deimos.config.
|
79
|
+
"#{Deimos.config.producers.topic_prefix}#{config[:topic]}"
|
80
80
|
end
|
81
81
|
|
82
82
|
# Override the default partition key (which is the payload key).
|
@@ -100,8 +100,8 @@ module Deimos
|
|
100
100
|
# @param force_send [Boolean] if true, ignore the configured backend
|
101
101
|
# and send immediately to Kafka.
|
102
102
|
def publish_list(payloads, sync: nil, force_send: false)
|
103
|
-
return if Deimos.config.
|
104
|
-
Deimos.config.
|
103
|
+
return if Deimos.config.kafka.seed_brokers.blank? ||
|
104
|
+
Deimos.config.producers.disabled ||
|
105
105
|
Deimos.producers_disabled?(self)
|
106
106
|
|
107
107
|
backend_class = determine_backend_class(sync, force_send)
|
@@ -126,7 +126,7 @@ module Deimos
|
|
126
126
|
backend = if force_send
|
127
127
|
:kafka
|
128
128
|
else
|
129
|
-
Deimos.config.
|
129
|
+
Deimos.config.producers.backend
|
130
130
|
end
|
131
131
|
if backend == :kafka_async && sync
|
132
132
|
backend = :kafka
|
data/lib/deimos/test_helpers.rb
CHANGED
@@ -61,7 +61,6 @@ module Deimos
|
|
61
61
|
encoder = Deimos::AvroDataEncoder.new(schema: schema,
|
62
62
|
namespace: decoder.namespace)
|
63
63
|
encoder.schema_store = decoder.schema_store
|
64
|
-
payload = payload.respond_to?(:stringify_keys) ? payload.stringify_keys : payload
|
65
64
|
encoder.encode_local(payload)
|
66
65
|
end
|
67
66
|
payload
|
@@ -77,9 +76,8 @@ module Deimos
|
|
77
76
|
config.before(:suite) do
|
78
77
|
Deimos.configure do |fr_config|
|
79
78
|
fr_config.logger = Logger.new(STDOUT)
|
80
|
-
fr_config.
|
81
|
-
fr_config.
|
82
|
-
fr_config.metrics = Deimos::Metrics::Mock.new
|
79
|
+
fr_config.consumers.reraise_errors = true
|
80
|
+
fr_config.kafka.seed_brokers ||= ['test_broker']
|
83
81
|
end
|
84
82
|
end
|
85
83
|
|
@@ -469,12 +467,6 @@ module Deimos
|
|
469
467
|
allow(klass).to receive(:decoder) do
|
470
468
|
create_decoder(klass.config[:schema], klass.config[:namespace])
|
471
469
|
end
|
472
|
-
|
473
|
-
if klass.config[:key_schema] # rubocop:disable Style/GuardClause
|
474
|
-
allow(klass).to receive(:key_decoder) do
|
475
|
-
create_decoder(klass.config[:key_schema], klass.config[:namespace])
|
476
|
-
end
|
477
|
-
end
|
478
470
|
end
|
479
471
|
end
|
480
472
|
end
|
@@ -93,11 +93,6 @@ module Deimos
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
Deimos::KafkaMessage.where(id: messages.map(&:id)).delete_all
|
96
|
-
Deimos.config.metrics&.increment(
|
97
|
-
'db_producer.process',
|
98
|
-
tags: %W(topic:#{@current_topic}),
|
99
|
-
by: messages.size
|
100
|
-
)
|
101
96
|
return false if batch_size < BATCH_SIZE
|
102
97
|
|
103
98
|
KafkaTopicInfo.heartbeat(@current_topic, @id) # keep alive
|
@@ -153,28 +153,28 @@ module Deimos
|
|
153
153
|
end
|
154
154
|
|
155
155
|
ActiveSupport::Notifications.subscribe('start_process_message.consumer.kafka') do |*args|
|
156
|
-
next unless Deimos.config.report_lag
|
156
|
+
next unless Deimos.config.consumers.report_lag
|
157
157
|
|
158
158
|
event = ActiveSupport::Notifications::Event.new(*args)
|
159
159
|
Deimos::Utils::LagReporter.message_processed(event.payload)
|
160
160
|
end
|
161
161
|
|
162
162
|
ActiveSupport::Notifications.subscribe('start_process_batch.consumer.kafka') do |*args|
|
163
|
-
next unless Deimos.config.report_lag
|
163
|
+
next unless Deimos.config.consumers.report_lag
|
164
164
|
|
165
165
|
event = ActiveSupport::Notifications::Event.new(*args)
|
166
166
|
Deimos::Utils::LagReporter.message_processed(event.payload)
|
167
167
|
end
|
168
168
|
|
169
169
|
ActiveSupport::Notifications.subscribe('seek.consumer.kafka') do |*args|
|
170
|
-
next unless Deimos.config.report_lag
|
170
|
+
next unless Deimos.config.consumers.report_lag
|
171
171
|
|
172
172
|
event = ActiveSupport::Notifications::Event.new(*args)
|
173
173
|
Deimos::Utils::LagReporter.offset_seek(event.payload)
|
174
174
|
end
|
175
175
|
|
176
176
|
ActiveSupport::Notifications.subscribe('heartbeat.consumer.kafka') do |*args|
|
177
|
-
next unless Deimos.config.report_lag
|
177
|
+
next unless Deimos.config.consumers.report_lag
|
178
178
|
|
179
179
|
event = ActiveSupport::Notifications::Event.new(*args)
|
180
180
|
Deimos::Utils::LagReporter.heartbeat(event.payload)
|
data/lib/deimos/version.rb
CHANGED
data/lib/deimos.rb
CHANGED
@@ -4,6 +4,7 @@ require 'avro-patches'
|
|
4
4
|
require 'avro_turf'
|
5
5
|
require 'phobos'
|
6
6
|
require 'deimos/version'
|
7
|
+
require 'deimos/config/configuration'
|
7
8
|
require 'deimos/avro_data_encoder'
|
8
9
|
require 'deimos/avro_data_decoder'
|
9
10
|
require 'deimos/producer'
|
@@ -11,7 +12,6 @@ require 'deimos/active_record_producer'
|
|
11
12
|
require 'deimos/active_record_consumer'
|
12
13
|
require 'deimos/consumer'
|
13
14
|
require 'deimos/batch_consumer'
|
14
|
-
require 'deimos/configuration'
|
15
15
|
require 'deimos/instrumentation'
|
16
16
|
require 'deimos/utils/lag_reporter'
|
17
17
|
|
@@ -40,48 +40,10 @@ require 'erb'
|
|
40
40
|
# Parent module.
|
41
41
|
module Deimos
|
42
42
|
class << self
|
43
|
-
attr_accessor :config
|
44
|
-
|
45
|
-
# Configure Deimos.
|
46
|
-
def configure
|
47
|
-
first_time_config = self.config.nil?
|
48
|
-
self.config ||= Configuration.new
|
49
|
-
old_config = self.config.dup
|
50
|
-
yield(config)
|
51
|
-
|
52
|
-
# Don't re-configure Phobos every time
|
53
|
-
if first_time_config || config.phobos_config_changed?(old_config)
|
54
|
-
|
55
|
-
file = config.phobos_config_file
|
56
|
-
phobos_config = YAML.load(ERB.new(File.read(File.expand_path(file))).result)
|
57
|
-
|
58
|
-
configure_kafka_for_phobos(phobos_config)
|
59
|
-
configure_loggers(phobos_config)
|
60
|
-
|
61
|
-
Phobos.configure(phobos_config)
|
62
|
-
|
63
|
-
validate_consumers
|
64
|
-
end
|
65
|
-
|
66
|
-
validate_db_backend if self.config.publish_backend == :db
|
67
|
-
end
|
68
|
-
|
69
|
-
# Ensure everything is set up correctly for the DB backend.
|
70
|
-
def validate_db_backend
|
71
|
-
begin
|
72
|
-
require 'activerecord-import'
|
73
|
-
rescue LoadError
|
74
|
-
raise 'Cannot set publish_backend to :db without activerecord-import! Please add it to your Gemfile.'
|
75
|
-
end
|
76
|
-
if Phobos.config.producer_hash[:required_acks] != :all
|
77
|
-
raise 'Cannot set publish_backend to :db unless required_acks is set to ":all" in phobos.yml!'
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
43
|
# Start the DB producers to send Kafka messages.
|
82
44
|
# @param thread_count [Integer] the number of threads to start.
|
83
45
|
def start_db_backend!(thread_count: 1)
|
84
|
-
if self.config.
|
46
|
+
if self.config.producers.backend != :db
|
85
47
|
raise('Publish backend is not set to :db, exiting')
|
86
48
|
end
|
87
49
|
|
@@ -99,52 +61,6 @@ module Deimos
|
|
99
61
|
signal_handler = Deimos::Utils::SignalHandler.new(executor)
|
100
62
|
signal_handler.run!
|
101
63
|
end
|
102
|
-
|
103
|
-
# @param phobos_config [Hash]
|
104
|
-
def configure_kafka_for_phobos(phobos_config)
|
105
|
-
if config.ssl_enabled
|
106
|
-
%w(ssl_ca_cert ssl_client_cert ssl_client_cert_key).each do |key|
|
107
|
-
next if config.send(key).blank?
|
108
|
-
|
109
|
-
phobos_config['kafka'][key] = ssl_var_contents(config.send(key))
|
110
|
-
end
|
111
|
-
end
|
112
|
-
phobos_config['kafka']['seed_brokers'] = config.seed_broker if config.seed_broker
|
113
|
-
end
|
114
|
-
|
115
|
-
# @param phobos_config [Hash]
|
116
|
-
def configure_loggers(phobos_config)
|
117
|
-
phobos_config['custom_logger'] = config.phobos_logger
|
118
|
-
phobos_config['custom_kafka_logger'] = config.kafka_logger
|
119
|
-
end
|
120
|
-
|
121
|
-
# @param filename [String] a file to read, or the contents of the SSL var
|
122
|
-
# @return [String] the contents of the file
|
123
|
-
def ssl_var_contents(filename)
|
124
|
-
File.exist?(filename) ? File.read(filename) : filename
|
125
|
-
end
|
126
|
-
|
127
|
-
# Validate that consumers are configured correctly, including their
|
128
|
-
# delivery mode.
|
129
|
-
def validate_consumers
|
130
|
-
Phobos.config.listeners.each do |listener|
|
131
|
-
handler_class = listener.handler.constantize
|
132
|
-
delivery = listener.delivery
|
133
|
-
|
134
|
-
# Validate that Deimos consumers use proper delivery configs
|
135
|
-
if handler_class < Deimos::BatchConsumer
|
136
|
-
unless delivery == 'inline_batch'
|
137
|
-
raise "BatchConsumer #{listener.handler} must have delivery set to"\
|
138
|
-
' `inline_batch`'
|
139
|
-
end
|
140
|
-
elsif handler_class < Deimos::Consumer
|
141
|
-
if delivery.present? && !%w(message batch).include?(delivery)
|
142
|
-
raise "Non-batch Consumer #{listener.handler} must have delivery"\
|
143
|
-
' set to `message` or `batch`'
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
64
|
end
|
149
65
|
end
|
150
66
|
|
data/lib/tasks/deimos.rake
CHANGED
@@ -7,7 +7,7 @@ namespace :deimos do
|
|
7
7
|
desc 'Starts Deimos in the rails environment'
|
8
8
|
task start: :environment do
|
9
9
|
Deimos.configure do |config|
|
10
|
-
config.
|
10
|
+
config.producers.backend = :kafka_sync if config.producers.backend == :kafka_async
|
11
11
|
end
|
12
12
|
ENV['DEIMOS_RAKE_TASK'] = 'true'
|
13
13
|
STDOUT.sync = true
|
data/spec/backends/db_spec.rb
CHANGED
@@ -4,11 +4,6 @@ each_db_config(Deimos::Backends::Db) do
|
|
4
4
|
include_context 'with publish_backend'
|
5
5
|
|
6
6
|
it 'should save to the database' do
|
7
|
-
expect(Deimos.config.metrics).to receive(:increment).with(
|
8
|
-
'db_producer.insert',
|
9
|
-
tags: %w(topic:my-topic),
|
10
|
-
by: 3
|
11
|
-
)
|
12
7
|
described_class.publish(producer_class: MyProducer, messages: messages)
|
13
8
|
records = Deimos::KafkaMessage.all
|
14
9
|
expect(records.size).to eq(3)
|
data/spec/batch_consumer_spec.rb
CHANGED
@@ -50,7 +50,7 @@ module ConsumerTest
|
|
50
50
|
|
51
51
|
describe 'when reraising errors is disabled' do
|
52
52
|
before(:each) do
|
53
|
-
Deimos.configure { |config| config.
|
53
|
+
Deimos.configure { |config| config.consumers.reraise_errors = false }
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should not fail when before_consume_batch fails' do
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nodoc:
|
4
|
+
class MyConfig
|
5
|
+
include Deimos::Configurable
|
6
|
+
|
7
|
+
configure do
|
8
|
+
setting :set1
|
9
|
+
setting :set2, 'hi mom'
|
10
|
+
setting :group do
|
11
|
+
setting :set3, default_proc: proc { false }
|
12
|
+
setting :set5, (proc { 5 })
|
13
|
+
end
|
14
|
+
|
15
|
+
setting_object :listy do
|
16
|
+
setting :list1, 10
|
17
|
+
setting :list2, 5
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Deimos::Configurable do
|
23
|
+
it 'should configure correctly with default values' do
|
24
|
+
expect(MyConfig.config.set1).to be_nil
|
25
|
+
expect(MyConfig.config.set2).to eq('hi mom')
|
26
|
+
expect(MyConfig.config.group.set3).to eq(false)
|
27
|
+
expect(MyConfig.config.listy_objects).to be_empty
|
28
|
+
expect { MyConfig.config.blah }.to raise_error(NameError)
|
29
|
+
expect { MyConfig.config.group.set4 }.to raise_error(NameError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should raise error when setting configs that don't exist" do
|
33
|
+
expect { MyConfig.configure { set15 'some_value' } }.to raise_error(NameError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should add values' do
|
37
|
+
MyConfig.configure do |config|
|
38
|
+
config.set1 = 5 # config.x syntax
|
39
|
+
set2 nil # method_missing syntax
|
40
|
+
config.group.set3 = true
|
41
|
+
end
|
42
|
+
|
43
|
+
# second configure should not blow anything away
|
44
|
+
MyConfig.configure do
|
45
|
+
listy do
|
46
|
+
list1 0
|
47
|
+
list2 1
|
48
|
+
end
|
49
|
+
listy do
|
50
|
+
list1 100
|
51
|
+
list2 200
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
expect(MyConfig.config.set1).to eq(5)
|
56
|
+
expect(MyConfig.config.set2).to be_nil
|
57
|
+
expect(MyConfig.config.group.set3).to eq(true)
|
58
|
+
expect(MyConfig.config.listy_objects.map(&:to_h)).
|
59
|
+
to eq([
|
60
|
+
{ list1: 0, list2: 1 },
|
61
|
+
{ list1: 100, list2: 200 }
|
62
|
+
])
|
63
|
+
|
64
|
+
# test reset!
|
65
|
+
MyConfig.config.reset!
|
66
|
+
expect(MyConfig.config.set1).to be_nil
|
67
|
+
expect(MyConfig.config.set2).to eq('hi mom')
|
68
|
+
expect(MyConfig.config.group.set3).to eq(false)
|
69
|
+
expect(MyConfig.config.listy_objects).to be_empty
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should add with block syntax' do
|
73
|
+
MyConfig.configure do
|
74
|
+
group do
|
75
|
+
set5(proc { 10 })
|
76
|
+
end
|
77
|
+
end
|
78
|
+
expect(MyConfig.config.group.set5.call).to eq(10)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should add or redefine settings' do
|
82
|
+
MyConfig.configure do
|
83
|
+
setting :group do
|
84
|
+
setting :set6, 15
|
85
|
+
setting :set5, (proc { 15 })
|
86
|
+
end
|
87
|
+
setting_object :notey do
|
88
|
+
setting :note_title, 'some-title'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
expect(MyConfig.config.group.set6).to eq(15)
|
93
|
+
expect(MyConfig.config.group.set5.call).to eq(15)
|
94
|
+
expect(MyConfig.config.listy_objects).to be_empty
|
95
|
+
expect(MyConfig.config.notey_objects).to be_empty
|
96
|
+
|
97
|
+
MyConfig.configure do
|
98
|
+
notey do
|
99
|
+
note_title 'hi mom'
|
100
|
+
end
|
101
|
+
listy do
|
102
|
+
list1 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
expect(MyConfig.config.notey_objects.size).to eq(1)
|
106
|
+
expect(MyConfig.config.notey_objects.first.note_title).to eq('hi mom')
|
107
|
+
expect(MyConfig.config.listy_objects.size).to eq(1)
|
108
|
+
expect(MyConfig.config.listy_objects.first.list1).to eq(0)
|
109
|
+
|
110
|
+
# This should not remove any keys
|
111
|
+
MyConfig.configure do
|
112
|
+
setting :group do
|
113
|
+
setting :set6, 20
|
114
|
+
end
|
115
|
+
end
|
116
|
+
expect(MyConfig.config.group.set6).to eq(20)
|
117
|
+
expect(MyConfig.config.group.set5.call).to eq(15)
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|