sinclair 1.5.0 → 1.5.1

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
  SHA256:
3
- metadata.gz: 4e368ae3e5bd4a4fdea678f56442dd2d88fb29c1b59ef31b0bebb668c35eb6f4
4
- data.tar.gz: 2662bab987171ad5199be408d3b88af8076f261ee038265f1d143eeb3a56a6b6
3
+ metadata.gz: 82efd1a6383697b8f2a0bbc803c27f21f87e47dbeca8536c55ebeb7efc097cf9
4
+ data.tar.gz: 301b644a37ca5227dc0f8247bbf46ba1988b71b6d157ed2f21e19e3f6c20a957
5
5
  SHA512:
6
- metadata.gz: f6d067cd6b01d8f1244ab3c32587d377d7b33460b1110f5209df3f0b5fd6b57dab5e5aa34fd7e7bfa1f462178e46ce8e50ce16ebbb8e78463447211753fde260
7
- data.tar.gz: a25a3ad8031fe74fc8861c52e6cdfe1069a54049fd306929e0164f88f77e7f215d5ed816f842b06b80868862523d3e022b27f4dc78448cc39cf0a3f5af1f720d
6
+ metadata.gz: d22f829400b914d4c297eea101bc88f1676ad9febf7f76ca703a090553e0756d97af9889d9a93debd81b820a3aacd4ff969bbfbb9015c43a0eb7a9646ceb345f
7
+ data.tar.gz: 53c0b4d4e8d480577ee93d7e0436f6ee1d35d47208a1e363a3d6672f88894d9c3debc4c11804b226372690f6d5afa69793c08e49d855d135820cd940ec11ed0e
data/README.md CHANGED
@@ -14,7 +14,7 @@ methods
14
14
 
15
15
  Yard Documentation
16
16
  -------------------
17
- https://www.rubydoc.info/gems/sinclair/1.5.0
17
+ https://www.rubydoc.info/gems/sinclair/1.5.1
18
18
 
19
19
  Installation
20
20
  ---------------
@@ -37,7 +37,7 @@ Installation
37
37
  Usage
38
38
  ---------------
39
39
  # Sinclair
40
- Sinclair can actully be used in several ways, as an stand alone object capable of
40
+ Sinclair can actually be used in several ways, as a stand alone object capable of
41
41
  adding methods to your class on the fly, as a builder inside a class method
42
42
  or by extending it for more complex logics
43
43
 
@@ -52,12 +52,17 @@ or by extending it for more complex logics
52
52
 
53
53
  builder.add_method(:twenty, '10 + 10')
54
54
  builder.add_method(:eighty) { 4 * twenty }
55
+ builder.add_class_method(:one_hundred) { 100 }
56
+ builder.add_class_method(:one_hundred_twenty, 'one_hundred + 20')
55
57
  builder.build
56
58
 
57
59
  instance = Clazz.new
58
60
 
59
61
  puts "Twenty => #{instance.twenty}" # Twenty => 20
60
62
  puts "Eighty => #{instance.eighty}" # Eighty => 80
63
+
64
+ puts "One Hundred => #{Clazz.one_hundred}" # One Hundred => 100
65
+ puts "One Hundred => #{Clazz.one_hundred_twenty}" # One Hundred Twenty => 120
61
66
  ```
62
67
 
63
68
  ## Builder in class method:
@@ -120,6 +125,43 @@ or by extending it for more complex logics
120
125
  person.email # returns 'lord@bob.com'
121
126
  ```
122
127
 
128
+ ```ruby
129
+ module EnvSettings
130
+ def env_prefix(new_prefix=nil)
131
+ @env_prefix = new_prefix if new_prefix
132
+ @env_prefix
133
+ end
134
+
135
+ def from_env(*method_names)
136
+ builder = Sinclair.new(self)
137
+
138
+ method_names.each do |method_name|
139
+ env_key = [env_prefix, method_name].compact.join('_').upcase
140
+
141
+ builder.add_class_method(method_name, cached: true) do
142
+ ENV[env_key]
143
+ end
144
+
145
+ builder.build
146
+ end
147
+ end
148
+ end
149
+
150
+ class MyServerConfig
151
+ extend EnvSettings
152
+
153
+ env_prefix :server
154
+
155
+ from_env :host, :port
156
+ end
157
+
158
+ ENV['SERVER_HOST'] = 'myserver.com'
159
+ ENV['SERVER_PORT'] = '9090'
160
+
161
+ MyServerConfig.host # returns 'myserver.com'
162
+ MyServerConfig.port # returns '9090'
163
+ ```
164
+
123
165
  ## Extending the builder
124
166
 
125
167
  ```ruby
@@ -366,57 +408,101 @@ Configurations can also be done through custom classes
366
408
  Client.config.url # returns 'http://interstella.com:8080'
367
409
  ```
368
410
 
411
+ # Sinclair::Settable
412
+
413
+ Settable allows classes to extract configuration from environments through
414
+ a simple meta-programable way
415
+
416
+ ```ruby
417
+ class ServiceClient
418
+ extend Sinclair::EnvSettable
419
+ attr_reader :username, :password, :host, :port
420
+
421
+ settings_prefix 'SERVICE'
422
+
423
+ with_settings :username, :password, port: 80, hostname: 'my-host.com'
424
+
425
+ def self.default
426
+ @default ||= new
427
+ end
428
+
429
+ def initialize(
430
+ username: self.class.username,
431
+ password: self.class.password,
432
+ port: self.class.port,
433
+ hostname: self.class.hostname
434
+ )
435
+ @username = username
436
+ @password = password
437
+ @port = port
438
+ @hostname = hostname
439
+ end
440
+ end
441
+
442
+ ENV['SERVICE_USERNAME'] = 'my-login'
443
+ ENV['SERVICE_HOSTNAME'] = 'host.com'
444
+
445
+ ServiceClient.default # returns #<ServiceClient:0x0000556fa1b366e8 @username="my-login", @password=nil, @port=80, @hostname="host.com">'
446
+ ```
447
+
369
448
  RSspec matcher
370
449
  ---------------
371
450
 
372
451
  You can use the provided matcher to check that your builder is adding a method correctly
373
452
 
374
453
  ```ruby
375
-
376
454
  class DefaultValue
377
455
  delegate :build, to: :builder
378
- attr_reader :klass, :method, :value
456
+ attr_reader :klass, :method, :value, :class_method
379
457
 
380
- def initialize(klass, method, value)
458
+ def initialize(klass, method, value, class_method: false)
381
459
  @klass = klass
382
460
  @method = method
383
461
  @value = value
462
+ @class_method = class_method
384
463
  end
385
464
 
386
465
  private
387
466
 
388
467
  def builder
389
468
  @builder ||= Sinclair.new(klass).tap do |b|
390
- b.add_method(method) { value }
469
+ if class_method
470
+ b.add_class_method(method) { value }
471
+ else
472
+ b.add_method(method) { value }
473
+ end
391
474
  end
392
475
  end
393
476
  end
394
477
 
395
- require 'sinclair/matchers'
396
- RSpec.configure do |config|
397
- config.include Sinclair::Matchers
398
- end
478
+ RSpec.describe Sinclair::Matchers do
479
+ subject(:builder_class) { DefaultValue }
399
480
 
400
- RSpec.describe DefaultValue do
401
- let(:klass) { Class.new }
402
- let(:method) { :the_method }
403
- let(:value) { Random.rand(100) }
404
- let(:builder) { described_class.new(klass, method, value) }
405
- let(:instance) { klass.new }
481
+ let(:klass) { Class.new }
482
+ let(:method) { :the_method }
483
+ let(:value) { Random.rand(100) }
484
+ let(:builder) { builder_class.new(klass, method, value) }
485
+ let(:instance) { klass.new }
406
486
 
407
487
  context 'when the builder runs' do
408
488
  it do
409
- expect do
410
- described_class.new(klass, method, value).build
411
- end.to add_method(method).to(instance)
489
+ expect { builder.build }.to add_method(method).to(instance)
412
490
  end
413
491
  end
414
492
 
415
493
  context 'when the builder runs' do
416
494
  it do
417
- expect do
418
- described_class.new(klass, method, value).build
419
- end.to add_method(method).to(klass)
495
+ expect { builder.build }.to add_method(method).to(klass)
496
+ end
497
+ end
498
+
499
+ context 'when adding class methods' do
500
+ subject(:builder) { builder_class.new(klass, method, value, class_method: true) }
501
+
502
+ context 'when the builder runs' do
503
+ it do
504
+ expect { builder.build }.to add_class_method(method).to(klass)
505
+ end
420
506
  end
421
507
  end
422
508
  end
@@ -428,13 +514,14 @@ You can use the provided matcher to check that your builder is adding a method c
428
514
  ```
429
515
 
430
516
  ```string
431
-
432
- DefaultValue
517
+ Sinclair::Matchers
433
518
  when the builder runs
434
- should add method 'the_method' to #<Class:0x0000000146c160> instances
435
- when the builder runs
436
- should add method 'the_method' to #<Class:0x0000000143a1b0> instances
437
-
519
+ should add method 'the_method' to #<Class:0x000055e5d9b7f150> instances
520
+ when the builder runs
521
+ should add method 'the_method' to #<Class:0x000055e5d9b8c0a8> instances
522
+ when adding class methods
523
+ when the builder runs
524
+ should add method class_method 'the_method' to #<Class:0x000055e5d9b95d88>
438
525
  ```
439
526
 
440
527
  Projects Using
data/config/yardstick.yml CHANGED
@@ -32,6 +32,7 @@ rules:
32
32
  exclude:
33
33
  - Sinclair::Config::MethodsBuilder#initialize
34
34
  - Sinclair::ConfigFactory#initialize
35
+ - Sinclair::EnvSettable::Builder#initialize
35
36
  - Sinclair::Matchers::AddClassMethodTo#initialize
36
37
  - Sinclair::Matchers::AddInstanceMethodTo#instance
37
38
  - Sinclair::Matchers::AddMethod#initialize
data/lib/sinclair.rb CHANGED
@@ -25,7 +25,7 @@ require 'active_support/all'
25
25
  # instance.value = 20
26
26
  # instance.value # returns 20
27
27
  #
28
- # @example Usin cache
28
+ # @example Using cache
29
29
  # module DefaultValueable
30
30
  # def default_reader(*methods, value:, accept_nil: false)
31
31
  # DefaultValueBuilder.new(
@@ -91,6 +91,7 @@ class Sinclair
91
91
  autoload :MethodBuilder, 'sinclair/method_builder'
92
92
  autoload :MethodDefinition, 'sinclair/method_definition'
93
93
  autoload :MethodDefinitions, 'sinclair/method_definitions'
94
+ autoload :EnvSettable, 'sinclair/env_settable'
94
95
 
95
96
  include OptionsParser
96
97
 
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ # @api public
5
+ # @author darthjee
6
+ #
7
+ # Module to be extended allowing configurations from environment
8
+ #
9
+ # @example
10
+ # class MyAppClient
11
+ # extend Sinclair::EnvSettable
12
+ #
13
+ # settings_prefix 'MY_APP'
14
+ #
15
+ # with_settings :username, :password, host: 'my-host.com'
16
+ # end
17
+ #
18
+ # ENV['MY_APP_USERNAME'] = 'my_login'
19
+ #
20
+ # MyAppClient.username # returns 'my_login'
21
+ # MyAppClient.password # returns nil
22
+ # MyAppClient.host # returns 'my-host.com'
23
+ #
24
+ # ENV['MY_APP_HOST'] = 'other-host.com'
25
+ #
26
+ # MyAppClient.host # returns 'other-host.com'
27
+ #
28
+ module EnvSettable
29
+ autoload :Builder, 'sinclair/env_settable/builder'
30
+
31
+ private
32
+
33
+ # @private
34
+ # @api public
35
+ # @visibility public
36
+ #
37
+ # Sets environment keys prefix
38
+ #
39
+ # @param prefix [String] prefix of the env keys
40
+ #
41
+ # @return [String]
42
+ #
43
+ # @example (see EnvSettable)
44
+ def settings_prefix(prefix)
45
+ @settings_prefix = prefix
46
+ end
47
+
48
+ # @private
49
+ # @api public
50
+ # @visibility public
51
+ #
52
+ # Adds settings
53
+ #
54
+ # @param settings_name [Array<Symbol,String>] Name of all settings
55
+ # to be added
56
+ # @param defaults [Hash] Settings with default values
57
+ #
58
+ # @return (see Sinclair#build)
59
+ #
60
+ # @example (see EnvSettable)
61
+ def with_settings(*settings_name, **defaults)
62
+ Builder.new(self, @settings_prefix, *settings_name, **defaults).build
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ module EnvSettable
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Env setting methods builder
9
+ #
10
+ # This builder does the magic of adding methods
11
+ # that will fetch variables from env or a default value
12
+ class Builder < Sinclair
13
+ # @param klass [Class] Class that will receive the methods
14
+ # @param prefix [String] Env keys prefix
15
+ # @param (see EnvSettable#with_settings)
16
+ def initialize(klass, prefix, *settings_name, **defaults)
17
+ super(klass, prefix: prefix)
18
+
19
+ @settings = Hash[settings_name.map { |name| [name] }]
20
+
21
+ @settings.merge!(defaults)
22
+
23
+ add_all_methods
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :settings
29
+ # @method settings
30
+ # @private
31
+ # @api private
32
+ #
33
+ # Settings map with default values
34
+ #
35
+ # @return [Hash<Symbol,Object>]
36
+
37
+ delegate :prefix, to: :options_object
38
+ # @method prefix
39
+ # @private
40
+ # @api private
41
+ #
42
+ # Env keys prefix
43
+ #
44
+ # @return [String]
45
+
46
+ # @private
47
+ # @api private
48
+ #
49
+ # Process all settings adding the methods
50
+ #
51
+ # @return (see settings)
52
+ def add_all_methods
53
+ settings.each do |name, value|
54
+ key = [prefix, name].compact.join('_').to_s.upcase
55
+
56
+ add_class_method(name) do
57
+ ENV[key] || value
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.5.0'
4
+ VERSION = '1.5.1'
5
5
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::EnvSettable do
6
+ describe 'readme' do
7
+ let(:client) { ServiceClient.default }
8
+ let(:query) do
9
+ /#<ServiceClient:[^ ]* @username="my-login", @password=nil, @port=80, @hostname="host.com">/
10
+ end
11
+
12
+ before do
13
+ ENV['SERVICE_USERNAME'] = 'my-login'
14
+ ENV['SERVICE_HOSTNAME'] = 'host.com'
15
+ end
16
+
17
+ it 'sets defaults values' do
18
+ expect(client.inspect.to_s).to match(query)
19
+ end
20
+ end
21
+ end
@@ -3,10 +3,11 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Sinclair::Matchers do
6
+ subject(:builder_class) { DefaultValue }
7
+
6
8
  let(:klass) { Class.new }
7
9
  let(:method) { :the_method }
8
10
  let(:value) { Random.rand(100) }
9
- let(:builder_class) { DefaultValue }
10
11
  let(:builder) { builder_class.new(klass, method, value) }
11
12
  let(:instance) { klass.new }
12
13
 
@@ -21,4 +22,14 @@ RSpec.describe Sinclair::Matchers do
21
22
  expect { builder.build }.to add_method(method).to(klass)
22
23
  end
23
24
  end
25
+
26
+ context 'when adding class methods' do
27
+ subject(:builder) { builder_class.new(klass, method, value, class_method: true) }
28
+
29
+ context 'when the builder runs' do
30
+ it do
31
+ expect { builder.build }.to add_class_method(method).to(klass)
32
+ end
33
+ end
34
+ end
24
35
  end
@@ -11,6 +11,8 @@ describe Sinclair do
11
11
  before do
12
12
  builder.add_method(:twenty, '10 + 10')
13
13
  builder.add_method(:eighty) { 4 * twenty }
14
+ builder.add_class_method(:one_hundred) { 100 }
15
+ builder.add_class_method(:one_hundred_twenty, 'one_hundred + 20')
14
16
  builder.build
15
17
  end
16
18
 
@@ -21,6 +23,15 @@ describe Sinclair do
21
23
  it 'knows how to add block defined methods' do
22
24
  expect("Eighty => #{instance.eighty}").to eq('Eighty => 80')
23
25
  end
26
+
27
+ it 'adds class method from block' do
28
+ expect("One Hundred => #{klass.one_hundred}").to eq('One Hundred => 100')
29
+ end
30
+
31
+ it 'adds class method from string' do
32
+ expect("One Hundred Twenty => #{klass.one_hundred_twenty}")
33
+ .to eq('One Hundred Twenty => 120')
34
+ end
24
35
  end
25
36
 
26
37
  describe 'Stand Alone concern' do
@@ -63,6 +74,29 @@ describe Sinclair do
63
74
  end
64
75
  end
65
76
 
77
+ describe 'Class Stand Alone Concern' do
78
+ let(:host) { 'myserver.com' }
79
+ let(:port) { '9090' }
80
+
81
+ before do
82
+ ENV['SERVER_HOST'] = host
83
+ ENV['SERVER_PORT'] = port
84
+ end
85
+
86
+ after do
87
+ ENV.delete('SERVER_HOST')
88
+ ENV.delete('SERVER_PORT')
89
+ end
90
+
91
+ it 'adds class method for host' do
92
+ expect(HostConfig.host).to eq(host)
93
+ end
94
+
95
+ it 'adds class method for port' do
96
+ expect(HostConfig.port).to eq(port)
97
+ end
98
+ end
99
+
66
100
  describe 'DefaultValuable' do
67
101
  subject(:server) { Server.new }
68
102
 
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::EnvSettable do
6
+ describe '#yard' do
7
+ subject(:settable) { Class.new(MyAppClient) }
8
+
9
+ before do
10
+ ENV['MY_APP_USERNAME'] = 'my_login'
11
+ end
12
+
13
+ after do
14
+ ENV.delete('MY_APP_USERNAME')
15
+ end
16
+
17
+ it 'retrieves username from env' do
18
+ expect(settable.username).to eq('my_login')
19
+ end
20
+
21
+ it 'retrieves password from env' do
22
+ expect(settable.password).to be_nil
23
+ end
24
+
25
+ context 'when defining defaults' do
26
+ it 'returns default value' do
27
+ expect(settable.host).to eq('my-host.com')
28
+ end
29
+
30
+ context 'when setting the env variable' do
31
+ before do
32
+ ENV['MY_APP_HOST'] = 'other-host.com'
33
+ end
34
+
35
+ after do
36
+ ENV.delete('MY_APP_HOST')
37
+ end
38
+
39
+ it 'retrieves host from env' do
40
+ expect(settable.host).to eq('other-host.com')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::EnvSettable::Builder do
6
+ subject(:settable) { Class.new }
7
+
8
+ let(:username) { 'my_login' }
9
+ let(:password) { Random.rand(10_000).to_s }
10
+
11
+ let(:builder) do
12
+ described_class.new(settable, prefix, :username, :password, host: 'my-host.com')
13
+ end
14
+
15
+ before { builder.build }
16
+
17
+ context 'when not using prefix' do
18
+ let(:prefix) { nil }
19
+
20
+ let(:username_key) { 'USERNAME' }
21
+ let(:password_key) { 'PASSWORD' }
22
+ let(:host_key) { 'HOST' }
23
+
24
+ it_behaves_like 'settings reading from env'
25
+ end
26
+
27
+ context 'when defining a prefix' do
28
+ let(:prefix) { 'MY_APP' }
29
+ let(:username_key) { 'MY_APP_USERNAME' }
30
+ let(:password_key) { 'MY_APP_PASSWORD' }
31
+ let(:host_key) { 'MY_APP_HOST' }
32
+
33
+ it_behaves_like 'settings reading from env'
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::EnvSettable do
6
+ subject(:settable) { Class.new(AppClient) }
7
+
8
+ let(:username) { 'my_login' }
9
+ let(:password) { Random.rand(10_000).to_s }
10
+
11
+ let(:username_key) { 'USERNAME' }
12
+ let(:password_key) { 'PASSWORD' }
13
+ let(:host_key) { 'HOST' }
14
+
15
+ it_behaves_like 'settings reading from env'
16
+
17
+ context 'when defining a prefix' do
18
+ subject(:settable) { Class.new(MyAppClient) }
19
+
20
+ let(:username_key) { 'MY_APP_USERNAME' }
21
+ let(:password_key) { 'MY_APP_PASSWORD' }
22
+ let(:host_key) { 'MY_APP_HOST' }
23
+
24
+ it_behaves_like 'settings reading from env'
25
+ end
26
+ end
data/spec/spec_helper.rb CHANGED
@@ -13,7 +13,8 @@ require 'sinclair/matchers'
13
13
  require 'pry-nav'
14
14
 
15
15
  support_files = File.expand_path('spec/support/**/*.rb')
16
- Dir[support_files].each { |file| require file }
16
+
17
+ Dir[support_files].sort.each { |file| require file }
17
18
 
18
19
  RSpec.configure do |config|
19
20
  config.run_all_when_everything_filtered = true
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AppClient
4
+ extend Sinclair::EnvSettable
5
+
6
+ with_settings :username, :password, host: 'my-host.com'
7
+ end
@@ -2,19 +2,24 @@
2
2
 
3
3
  class DefaultValue
4
4
  delegate :build, to: :builder
5
- attr_reader :klass, :method, :value
5
+ attr_reader :klass, :method, :value, :class_method
6
6
 
7
- def initialize(klass, method, value)
7
+ def initialize(klass, method, value, class_method: false)
8
8
  @klass = klass
9
9
  @method = method
10
10
  @value = value
11
+ @class_method = class_method
11
12
  end
12
13
 
13
14
  private
14
15
 
15
16
  def builder
16
17
  @builder ||= Sinclair.new(klass).tap do |b|
17
- b.add_method(method) { value }
18
+ if class_method
19
+ b.add_class_method(method) { value }
20
+ else
21
+ b.add_method(method) { value }
22
+ end
18
23
  end
19
24
  end
20
25
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EnvSettings
4
+ def env_prefix(new_prefix = nil)
5
+ @env_prefix = new_prefix if new_prefix
6
+ @env_prefix
7
+ end
8
+
9
+ def from_env(*method_names)
10
+ builder = Sinclair.new(self)
11
+
12
+ method_names.each do |method_name|
13
+ env_key = [env_prefix, method_name].compact.join('_').upcase
14
+
15
+ builder.add_class_method(method_name, cached: true) do
16
+ ENV[env_key]
17
+ end
18
+
19
+ builder.build
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HostConfig
4
+ extend EnvSettings
5
+
6
+ env_prefix :server
7
+
8
+ from_env :host, :port
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MyAppClient
4
+ extend Sinclair::EnvSettable
5
+
6
+ settings_prefix 'MY_APP'
7
+
8
+ with_settings :username, :password, host: 'my-host.com'
9
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ServiceClient
4
+ extend Sinclair::EnvSettable
5
+ attr_reader :username, :password, :host, :port
6
+
7
+ settings_prefix 'SERVICE'
8
+
9
+ with_settings :username, :password, port: 80, hostname: 'my-host.com'
10
+
11
+ def self.default
12
+ @default ||= new
13
+ end
14
+
15
+ def initialize(
16
+ username: self.class.username,
17
+ password: self.class.password,
18
+ port: self.class.port,
19
+ hostname: self.class.hostname
20
+ )
21
+ @username = username
22
+ @password = password
23
+ @port = port
24
+ @hostname = hostname
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples 'settings reading from env' do
4
+ before do
5
+ ENV[username_key] = username
6
+ ENV[password_key] = password
7
+ end
8
+
9
+ after do
10
+ ENV.delete(username_key)
11
+ ENV.delete(password_key)
12
+ end
13
+
14
+ it 'retrieves username from env' do
15
+ expect(settable.username).to eq(username)
16
+ end
17
+
18
+ it 'retrieves password from env' do
19
+ expect(settable.password).to eq(password)
20
+ end
21
+
22
+ context 'when defining defaults' do
23
+ it 'returns default value' do
24
+ expect(settable.host).to eq('my-host.com')
25
+ end
26
+
27
+ context 'when setting the env variable' do
28
+ let(:other_host) { 'other-host.com' }
29
+
30
+ before do
31
+ ENV[host_key] = other_host
32
+ end
33
+
34
+ after do
35
+ ENV.delete(host_key)
36
+ end
37
+
38
+ it 'retrieves host from env' do
39
+ expect(settable.host).to eq(other_host)
40
+ end
41
+ end
42
+ end
43
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinclair
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DarthJee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-11 00:00:00.000000000 Z
11
+ date: 2019-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -278,6 +278,8 @@ files:
278
278
  - lib/sinclair/config_class.rb
279
279
  - lib/sinclair/config_factory.rb
280
280
  - lib/sinclair/configurable.rb
281
+ - lib/sinclair/env_settable.rb
282
+ - lib/sinclair/env_settable/builder.rb
281
283
  - lib/sinclair/matchers.rb
282
284
  - lib/sinclair/matchers/add_class_method.rb
283
285
  - lib/sinclair/matchers/add_class_method_to.rb
@@ -301,6 +303,7 @@ files:
301
303
  - spec/integration/readme/my_class_spec.rb
302
304
  - spec/integration/readme/my_model_spec.rb
303
305
  - spec/integration/readme/sinclair/configurable_spec.rb
306
+ - spec/integration/readme/sinclair/env_settable_spec.rb
304
307
  - spec/integration/readme/sinclair/matchers_spec.rb
305
308
  - spec/integration/readme/sinclair_spec.rb
306
309
  - spec/integration/yard/my_builder_spec.rb
@@ -309,6 +312,7 @@ files:
309
312
  - spec/integration/yard/sinclair/config_factory_spec.rb
310
313
  - spec/integration/yard/sinclair/config_spec.rb
311
314
  - spec/integration/yard/sinclair/configurable_spec.rb
315
+ - spec/integration/yard/sinclair/env_settable_spec.rb
312
316
  - spec/integration/yard/sinclair/matchers/add_class_method_spec.rb
313
317
  - spec/integration/yard/sinclair/matchers/add_class_method_to_spec.rb
314
318
  - spec/integration/yard/sinclair/matchers/add_instance_method_spec.rb
@@ -321,6 +325,8 @@ files:
321
325
  - spec/lib/sinclair/config_factory_spec.rb
322
326
  - spec/lib/sinclair/config_spec.rb
323
327
  - spec/lib/sinclair/configurable_spec.rb
328
+ - spec/lib/sinclair/env_settable/builder_spec.rb
329
+ - spec/lib/sinclair/env_settable_spec.rb
324
330
  - spec/lib/sinclair/matchers/add_class_method_spec.rb
325
331
  - spec/lib/sinclair/matchers/add_class_method_to_spec.rb
326
332
  - spec/lib/sinclair/matchers/add_instance_method_spec.rb
@@ -338,6 +344,7 @@ files:
338
344
  - spec/lib/sinclair_spec.rb
339
345
  - spec/spec_helper.rb
340
346
  - spec/support/fixture_helpers.rb
347
+ - spec/support/models/app_client.rb
341
348
  - spec/support/models/app_config.rb
342
349
  - spec/support/models/client.rb
343
350
  - spec/support/models/default_value.rb
@@ -348,10 +355,13 @@ files:
348
355
  - spec/support/models/dummy_config.rb
349
356
  - spec/support/models/dummy_configurable.rb
350
357
  - spec/support/models/dummy_options_parser.rb
358
+ - spec/support/models/env_settings.rb
359
+ - spec/support/models/host_config.rb
351
360
  - spec/support/models/http_json_model.rb
352
361
  - spec/support/models/http_person.rb
353
362
  - spec/support/models/initial_valuer.rb
354
363
  - spec/support/models/login_config.rb
364
+ - spec/support/models/my_app_client.rb
355
365
  - spec/support/models/my_builder.rb
356
366
  - spec/support/models/my_class.rb
357
367
  - spec/support/models/my_concern.rb
@@ -364,10 +374,12 @@ files:
364
374
  - spec/support/models/random_generator.rb
365
375
  - spec/support/models/server.rb
366
376
  - spec/support/models/server_config.rb
377
+ - spec/support/models/service_client.rb
367
378
  - spec/support/models/validator_builder.rb
368
379
  - spec/support/shared_examples/class_method_definition.rb
369
380
  - spec/support/shared_examples/config.rb
370
381
  - spec/support/shared_examples/config_factory.rb
382
+ - spec/support/shared_examples/env_settable.rb
371
383
  - spec/support/shared_examples/instance_method_definition.rb
372
384
  homepage: https://github.com/darthjee/sinclair
373
385
  licenses: []