sinclair 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c574eec3a6df9fca413808866c33a03da39ac3aea5a55ad588ea0532fdcb8058
4
- data.tar.gz: ccdf5e26711abfeb0c9a2eee9f59cabc8a4ae912b624b976720b228b7be7adbd
3
+ metadata.gz: 5a99344876ea7ff46dc785f5d9a9daddedce4fa84fb1d33c1387f333ef2611f8
4
+ data.tar.gz: 2687f7ebd7816a13275d9aede938dff46731edde1dba1b2e0a272f9e0967af18
5
5
  SHA512:
6
- metadata.gz: 807968f16b1be5c991e7377aa888fc70548c8058945e7f137a6cfa53ef4a6359c5be19305a5184f8d2b1d7ed8343d815a8595b9deef8b1f266c7e5fbca4bc94f
7
- data.tar.gz: 2dc1e2cbf9e95829d488e49ee6835775d99cc9743313b0b58ea50fc2ac739a471ecd98da35c9193dc631bcbfdfabe6cb665fa190a97afacf4b4d4ecfec9dde95
6
+ metadata.gz: 8b6278abe2c8f3b0ec4f20cc9856508cf7f5726643229d532c075e5a142cca02141f5e3e8b8d99bea25859dd2a4b072b2fb457aa0b682f4a25949f132c2715e4
7
+ data.tar.gz: d0e6cae7c4e3d1f87c99f737066292cdee42ee6b14c00ce7b1a6cb1eb20f05dd73a776e5cd75c3ac2d6ffb7ab1a91a67f57d5d0d00385238aa57ab84dbc6d7bb
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.3.1
17
+ https://www.rubydoc.info/gems/sinclair/1.3.2
18
18
 
19
19
  Installation
20
20
  ---------------
@@ -314,7 +314,8 @@ the `configurable#configure` method
314
314
  class MyConfigurable
315
315
  extend Sinclair::Configurable
316
316
 
317
- configurable_with :host, :port
317
+ # port is defaulted to 80
318
+ configurable_with :host, port: 80
318
319
  end
319
320
 
320
321
  MyConfigurable.configure do |config|
@@ -328,7 +329,7 @@ the `configurable#configure` method
328
329
  MyConfigurable.reset_config
329
330
 
330
331
  MyConfigurable.config.host # returns nil
331
- MyConfigurable.config.port # returns nil
332
+ MyConfigurable.config.port # returns 80
332
333
  ```
333
334
 
334
335
  RSspec matcher
data/config/yardstick.yml CHANGED
@@ -18,6 +18,9 @@ rules:
18
18
  exclude:
19
19
  - Sinclair::OptionsParser#options
20
20
  - Sinclair::OptionsParser#options_object
21
+ - Sinclair::Configurable#config
22
+ - Sinclair::Configurable#reset_config
23
+ - Sinclair::Configurable#configure
21
24
  ReturnTag:
22
25
  enabled: true
23
26
  exclude:
@@ -34,6 +37,11 @@ rules:
34
37
  - Sinclair::ConfigFactory#initialize
35
38
  - Sinclair::ConfigFactory#config_class
36
39
  - Sinclair::ConfigFactory#config_attributes
40
+ - Sinclair::ConfigFactory::MethodsBuilder#names
41
+ - Sinclair::ConfigFactory::MethodsBuilder#defaults
42
+ - Sinclair::Configurable#config
43
+ - Sinclair::Configurable#reset_config
44
+ - Sinclair::Configurable#configure
37
45
  Summary::Presence:
38
46
  enabled: true
39
47
  exclude:
@@ -52,6 +60,9 @@ rules:
52
60
  - Sinclair::ConfigFactory#initialize
53
61
  - Sinclair::ConfigFactory#config_class
54
62
  - Sinclair::ConfigFactory#config_attributes
63
+ - Sinclair::ConfigFactory::MethodsBuilder#initialize
64
+ - Sinclair::ConfigFactory::MethodsBuilder#names
65
+ - Sinclair::ConfigFactory::MethodsBuilder#defaults
55
66
  Summary::Length:
56
67
  enabled: true
57
68
  exclude: []
@@ -16,6 +16,8 @@ class Sinclair
16
16
  # factory.config.equal?(config) # returns true
17
17
  # config.name # returns 'John'
18
18
  class ConfigFactory
19
+ autoload :MethodsBuilder, 'sinclair/config_factory/methods_builder'
20
+
19
21
  # @param config_class [Class] configuration class to be used
20
22
  # @param config_attributes [Array<Symbol,String>] list of possible configurations
21
23
  def initialize(config_class: Class.new(Config), config_attributes: [])
@@ -77,9 +79,12 @@ class Sinclair
77
79
  #
78
80
  # config.respond_to? :active
79
81
  # # returns true
80
- def add_configs(*attributes)
81
- config_class.attr_reader(*attributes)
82
- config_attributes.concat(attributes.map(&:to_sym))
82
+ def add_configs(*args)
83
+ builder = MethodsBuilder.new(config_class, *args)
84
+
85
+ builder.build
86
+
87
+ config_attributes.concat(builder.config_names.map(&:to_sym))
83
88
  end
84
89
 
85
90
  # Set the values in the config
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class ConfigFactory
5
+ # @api private
6
+ #
7
+ # Class responsible for adding method to configuration
8
+ # classes
9
+ class MethodsBuilder < Sinclair
10
+ # @param klass [Class] class inheriting from {Sinclair::Config}
11
+ # that will receive the methods
12
+ # @overload initialize(klass, *names, default)
13
+ # @param names [Array<Symbol,String>] List of configuration names
14
+ # to be added
15
+ # @param default [Hash] Configurations that will receive a default
16
+ # value when not configured
17
+ def initialize(klass, *names)
18
+ super(klass)
19
+
20
+ @names = names
21
+ @defaults = names.find { |arg| arg.is_a?(Hash) } || {}
22
+ names.delete(defaults)
23
+ end
24
+
25
+ # Build the methods in config class
26
+ #
27
+ # Methods will be attribute readers that, when an attribute
28
+ # (instance variable) has never been defined, a default value
29
+ # is returned
30
+ #
31
+ # Setting an instance variable to nil will not return default
32
+ # value.
33
+ #
34
+ # If default value is required, {Sinclair::Configurable#reset_config}
35
+ # should be called
36
+ #
37
+ # @return (see Sinclair#build)
38
+ #
39
+ # @see Sinclair#build
40
+ def build
41
+ config_hash.each do |method, value|
42
+ add_method(method, cached: :full) { value }
43
+ end
44
+
45
+ super
46
+ end
47
+
48
+ # Returns the name of all configs defined by {MethodsBuilder}
49
+ #
50
+ # @return [Array<String,Symbol>]
51
+ def config_names
52
+ config_hash.keys
53
+ end
54
+
55
+ private
56
+
57
+ attr_reader :names, :defaults
58
+
59
+ # @private
60
+ #
61
+ # Builds the final config hash
62
+ #
63
+ # Config hash merges defauls config hashs
64
+ # with {#name_as_hash}
65
+ #
66
+ # @return [Hash]
67
+ def config_hash
68
+ @config_hash ||= names_as_hash.merge!(defaults)
69
+ end
70
+
71
+ # @private
72
+ #
73
+ # Builds a hash with nil values from config names
74
+ #
75
+ # @return [Hash]
76
+ def names_as_hash
77
+ Hash[names.map { |*name| name }]
78
+ end
79
+ end
80
+ end
81
+ end
@@ -17,7 +17,8 @@ class Sinclair
17
17
  # class MyConfigurable
18
18
  # extend Sinclair::Configurable
19
19
  #
20
- # configurable_with :host, :port
20
+ # # port is defaulted to 80
21
+ # configurable_with :host, port: 80
21
22
  # end
22
23
  #
23
24
  # MyConfigurable.configure do
@@ -31,12 +32,31 @@ class Sinclair
31
32
  # MyConfigurable.config.port
32
33
  # # returns 5555
33
34
  #
34
- # MyConfigurable.reset
35
+ # MyConfigurable.reset_config
35
36
  #
36
37
  # MyConfigurable.config.host
37
38
  # # returns nil
39
+ #
40
+ # MyConfigurable.config.port
41
+ # # returns 80
38
42
  module Configurable
39
- delegate :config, :reset_config, :configure, to: :config_factory
43
+ # (see ConfigFactory#config)
44
+ # @see ConfigFactory#config
45
+ def config
46
+ config_factory.config
47
+ end
48
+
49
+ # (see ConfigFactory#reset_config)
50
+ # @see ConfigFactory#reset_config
51
+ def reset_config
52
+ config_factory.reset_config
53
+ end
54
+
55
+ # (see ConfigFactory#configure)
56
+ # @see ConfigFactory#configure
57
+ def configure(&block)
58
+ config_factory.configure(&block)
59
+ end
40
60
 
41
61
  protected
42
62
 
@@ -64,7 +84,7 @@ class Sinclair
64
84
 
65
85
  private
66
86
 
67
- # @visibility public
87
+ # @!visibility public
68
88
  #
69
89
  # Adds a configuration option to config class
70
90
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.3.1'
4
+ VERSION = '1.3.2'
5
5
  end
@@ -36,8 +36,7 @@ describe Sinclair::Configurable do
36
36
  end
37
37
 
38
38
  it 'resets configuration port' do
39
- expect(MyConfigurable.config.port)
40
- .to be_nil
39
+ expect(MyConfigurable.config.port).to eq(80)
41
40
  end
42
41
  end
43
42
  end
@@ -27,8 +27,11 @@ describe Sinclair::Configurable do
27
27
  before { MyConfigurable.reset_config }
28
28
 
29
29
  it 'returns initial value for host' do
30
- expect(MyConfigurable.config.host)
31
- .to be_nil
30
+ expect(MyConfigurable.config.host).to be_nil
31
+ end
32
+
33
+ it 'returns initial value for port' do
34
+ expect(MyConfigurable.config.port).to eq(80)
32
35
  end
33
36
  end
34
37
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::ConfigFactory::MethodsBuilder do
6
+ describe '#build' do
7
+ let(:config_class) { Class.new(Sinclair::Config) }
8
+ let(:config) { config_class.new }
9
+ let(:code_block) { proc { builder.build } }
10
+
11
+ let(:setter_block) do
12
+ proc do |value|
13
+ config.instance_variable_set(:@name, value)
14
+ end
15
+ end
16
+
17
+ context 'when not initializing defaults' do
18
+ subject(:builder) { described_class.new(config_class, :name, 'password') }
19
+
20
+ it_behaves_like 'a config methods builder adding config'
21
+
22
+ it 'does not set a default value' do
23
+ code_block.call
24
+
25
+ expect(config.name).to be_nil
26
+ end
27
+ end
28
+
29
+ context 'when initializing defaults' do
30
+ subject(:builder) do
31
+ described_class.new(
32
+ config_class, name: 'Bobby', 'password' => 'abcdef'
33
+ )
34
+ end
35
+
36
+ it_behaves_like 'a config methods builder adding config'
37
+
38
+ it 'sets a default value' do
39
+ code_block.call
40
+
41
+ expect(config.name).to eq('Bobby')
42
+ end
43
+ end
44
+
45
+ context 'when mixing names and hash' do
46
+ subject(:builder) do
47
+ described_class.new(
48
+ config_class, :name, 'password' => 'abcdef'
49
+ )
50
+ end
51
+
52
+ it_behaves_like 'a config methods builder adding config'
53
+
54
+ it 'does not set a default value' do
55
+ code_block.call
56
+
57
+ expect(config.name).to be_nil
58
+ end
59
+
60
+ context 'when name and hash define same config' do
61
+ subject(:builder) do
62
+ described_class.new(
63
+ config_class, :name, name: 'Bobby'
64
+ )
65
+ end
66
+
67
+ it_behaves_like 'a config methods builder adding config'
68
+
69
+ it 'sets a default value' do
70
+ code_block.call
71
+
72
+ expect(config.name).to eq('Bobby')
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -81,46 +81,23 @@ describe Sinclair::ConfigFactory do
81
81
  end
82
82
 
83
83
  describe '#add_configs' do
84
- it 'adds reader to config' do
85
- expect { factory.add_configs(:name) }
86
- .to add_method(:name).to(factory.config)
87
- end
88
-
89
- it 'does not add setter to config' do
90
- expect { factory.add_configs(:name) }
91
- .not_to add_method(:name=).to(factory.config)
92
- end
93
-
94
- it 'does not change Sinclair::Config class' do
95
- expect { factory.add_configs(:name) }
96
- .not_to add_method(:name).to(Sinclair::Config.new)
97
- end
84
+ let(:config) { factory.config }
98
85
 
99
- it 'allows config_builder to handle method missing' do
100
- factory.add_configs(:name)
101
- expect { factory.configure { name 'John' } }.not_to raise_error
86
+ let(:code_block) do
87
+ proc { factory.instance_eval(&method_call) }
102
88
  end
103
89
 
104
- it 'changes subclasses of config' do
105
- expect { factory.add_configs(:name) }
106
- .to add_method(:name).to(factory.child.config)
90
+ let(:setter_block) do
91
+ proc { |value| factory.configure { name value } }
107
92
  end
108
93
 
109
- it 'does not mess with parent config_builder' do
110
- factory.child.add_configs(:name)
111
- expect { factory.configure { name 'John' } }
112
- .to raise_error(NoMethodError)
113
- end
94
+ it_behaves_like 'a config factory adding config' do
95
+ let(:method_call) { proc { add_configs(:name) } }
114
96
 
115
- context 'when initializing with custom config class' do
116
- it do
117
- expect { factory.add_configs(:name) }
118
- .to add_method(:name).to(factory.config)
119
- end
97
+ it 'does not set a default value' do
98
+ code_block.call
120
99
 
121
- it 'does not change other config classes' do
122
- expect { factory.add_configs(:name) }
123
- .not_to add_method(:name).to(other_factory.config)
100
+ expect(factory.config.name).to be_nil
124
101
  end
125
102
  end
126
103
 
@@ -130,30 +107,33 @@ describe Sinclair::ConfigFactory do
130
107
  factory.reset_config
131
108
  expect(factory.config).to be_a(Sinclair::Config)
132
109
  end
110
+
111
+ context 'when passing a hash' do
112
+ it_behaves_like 'a config factory adding config' do
113
+ let(:method_call) { proc { add_configs(name: 'Bobby') } }
114
+
115
+ it 'sets a default value' do
116
+ code_block.call
117
+
118
+ expect(factory.config.name).to eq('Bobby')
119
+ end
120
+ end
121
+ end
133
122
  end
134
123
 
135
124
  describe '#configure' do
136
- before { factory.add_configs(:user, 'password') }
125
+ context 'when factory was not initialized with defaults' do
126
+ before { factory.add_configs(:user, 'password') }
137
127
 
138
- it do
139
- expect { factory.configure { |c| c.user 'Bob' } }
140
- .to change(config, :user)
141
- .from(nil).to('Bob')
128
+ it_behaves_like 'configure a config'
142
129
  end
143
130
 
144
- context 'when it was defined using string' do
145
- it do
146
- expect { factory.configure { |c| c.password '123456' } }
147
- .to change(config, :password)
148
- .from(nil).to('123456')
131
+ context 'when factory initialized with defaults' do
132
+ before do
133
+ factory.add_configs(user: 'Jack', 'password' => 'abcdef')
149
134
  end
150
- end
151
135
 
152
- context 'when calling a method that was not defined' do
153
- it do
154
- expect { factory.configure { |c| c.nope '123456' } }
155
- .to raise_error(NoMethodError)
156
- end
136
+ it_behaves_like 'configure a config'
157
137
  end
158
138
  end
159
139
 
@@ -3,5 +3,6 @@
3
3
  class MyConfigurable
4
4
  extend Sinclair::Configurable
5
5
 
6
- configurable_with :host, :port
6
+ # port is defaulted to 80
7
+ configurable_with :host, port: 80
7
8
  end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples 'a config methods builder adding config' do
4
+ it 'adds reader to config' do
5
+ expect(&code_block).to add_method(:name).to(config)
6
+ end
7
+
8
+ it 'does not add setter to config' do
9
+ expect(&code_block)
10
+ .not_to add_method(:name=).to(config)
11
+ end
12
+
13
+ it 'does not change Sinclair::Config class' do
14
+ expect(&code_block)
15
+ .not_to add_method(:name).to(Sinclair::Config)
16
+ end
17
+
18
+ it 'allows config_builder to handle method missing' do
19
+ code_block.call
20
+
21
+ expect { setter_block.call('John') }
22
+ .not_to raise_error
23
+ end
24
+
25
+ it 'adds reader for configuration' do
26
+ code_block.call
27
+ setter_block.call('John')
28
+
29
+ expect(config.name).to eq('John')
30
+ end
31
+
32
+ it 'adds reader for configuration accepting nil values' do
33
+ code_block.call
34
+ setter_block.call('John')
35
+ setter_block.call(nil)
36
+
37
+ expect(config.name).to be_nil
38
+ end
39
+ end
40
+
41
+ shared_examples 'a config factory adding config' do
42
+ it_behaves_like 'a config methods builder adding config'
43
+
44
+ it 'changes subclasses of config' do
45
+ expect(&code_block)
46
+ .to add_method(:name).to(factory.child.config)
47
+ end
48
+
49
+ it 'does not mess with parent config_builder' do
50
+ factory.child.instance_eval(&method_call)
51
+ expect { factory.configure { name 'John' } }
52
+ .to raise_error(NoMethodError)
53
+ end
54
+
55
+ context 'when initializing with custom config class' do
56
+ it do
57
+ expect(&code_block)
58
+ .to add_method(:name).to(factory.config)
59
+ end
60
+
61
+ it 'does not change other config classes' do
62
+ expect(&code_block)
63
+ .not_to add_method(:name).to(other_factory.config)
64
+ end
65
+ end
66
+ end
67
+
68
+ shared_examples 'configure a config' do
69
+ it 'sets value on config' do
70
+ expect { factory.configure { |c| c.user 'Bob' } }
71
+ .to change(config, :user).to('Bob')
72
+ end
73
+
74
+ context 'when re-seting the value to nil' do
75
+ before { factory.configure { |c| c.user 'Bob' } }
76
+
77
+ it 'sets nil value on config' do
78
+ expect { factory.configure { |c| c.user nil } }
79
+ .to change(config, :user).to(nil)
80
+ end
81
+ end
82
+
83
+ context 'when calling a method that was not defined' do
84
+ it do
85
+ expect { factory.configure { |c| c.nope '123456' } }
86
+ .to raise_error(NoMethodError)
87
+ end
88
+ end
89
+
90
+ context 'when it was defined using string' do
91
+ it do
92
+ expect { factory.configure { |c| c.password '123456' } }
93
+ .to change(config, :password)
94
+ .to('123456')
95
+ end
96
+ end
97
+ 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.3.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - DarthJee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-17 00:00:00.000000000 Z
11
+ date: 2019-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -189,6 +189,7 @@ files:
189
189
  - lib/sinclair/config.rb
190
190
  - lib/sinclair/config_builder.rb
191
191
  - lib/sinclair/config_factory.rb
192
+ - lib/sinclair/config_factory/methods_builder.rb
192
193
  - lib/sinclair/configurable.rb
193
194
  - lib/sinclair/matchers.rb
194
195
  - lib/sinclair/matchers/add_method.rb
@@ -220,6 +221,7 @@ files:
220
221
  - spec/integration/yard/sinclair/options_parser_spec.rb
221
222
  - spec/integration/yard/sinclair_spec.rb
222
223
  - spec/lib/sinclair/config_builder_spec.rb
224
+ - spec/lib/sinclair/config_factory/methods_builder_spec.rb
223
225
  - spec/lib/sinclair/config_factory_spec.rb
224
226
  - spec/lib/sinclair/configurable_spec.rb
225
227
  - spec/lib/sinclair/matchers/add_method_spec.rb
@@ -252,6 +254,7 @@ files:
252
254
  - spec/support/models/purchase.rb
253
255
  - spec/support/models/server.rb
254
256
  - spec/support/models/validator_builder.rb
257
+ - spec/support/shared_examples/config_factory.rb
255
258
  - spec/support/shared_examples/method_definition.rb
256
259
  homepage: https://github.com/darthjee/sinclair
257
260
  licenses: []