sinclair 1.6.0 → 1.6.1

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: 6f1f053534fe80318f1a84b287fc624a243f70d5b5c48d6a8b36c256fcd37268
4
- data.tar.gz: 2ecaef88cfe979d42ab08000c416cad6554983c57305b74603cb349d24bada41
3
+ metadata.gz: a9873a31c5a1ab56553a834bb0acdae13abeb3189b19a79789911d914c72f52c
4
+ data.tar.gz: cb209f36a4bd60319e6133e6526a4145a58649bc78a2fd68632e63ef0c157255
5
5
  SHA512:
6
- metadata.gz: 8bd3befeca69e2c7bd4f2edf93adc6688f810d5691c7c25fa574ee26337f8ad9a52a16abe194382f961774db53babc5859699c4178e9f54fb428cbaf168a5f30
7
- data.tar.gz: 2ab928115bb31bc0214b2238accdb76033bb2a4baf974e19cbcdb60929aa0baab42dc6d1ae583e3975688443142c4c0ed705915f44c12051ab0516d05fa408ac
6
+ metadata.gz: 8cb67cbeb1032f090809daaebb92f57e9f3bb5db023e413f3101aa79415f319089ef22080a9086772c37ba03870553825be651c6ed1568cb21d9f39db398e47b
7
+ data.tar.gz: 2852f036aec1df4ecdd7be65497c83389fd481aecf0e9783f55258646fbb8e18d064e1cfa23b0b8f901e4bfa8a1e4b33ac9b114a2ebb5e8f268b945e9d37ba24
data/.rubocop.yml CHANGED
@@ -20,35 +20,20 @@ Lint/AmbiguousBlockAssociation:
20
20
  RSpec/AlignLeftLetBrace:
21
21
  Enabled: true
22
22
 
23
- RSpec/InstanceVariable:
23
+
24
+ RSpec/DescribedClass:
24
25
  Exclude:
25
- - spec/integration/yard/sinclair/method_definition_spec.rb
26
- - spec/integration/yard/sinclair/method_definition/instance_block_definition_spec.rb
27
- - spec/integration/yard/sinclair/method_definition/instance_method_definition_spec.rb
28
- - spec/integration/yard/sinclair/method_definition/class_block_definition_spec.rb
29
- - spec/integration/yard/sinclair/method_definition/class_method_definition_spec.rb
30
- - spec/lib/sinclair/method_definition/instance_block_definition_spec.rb
31
- - spec/lib/sinclair/method_definition/instance_method_definition_spec.rb
32
- - spec/lib/sinclair/method_definition/class_block_definition_spec.rb
33
- - spec/lib/sinclair/method_definition/class_method_definition_spec.rb
34
- - spec/lib/sinclair/method_definition_spec.rb
35
- - spec/lib/sinclair/method_definition/block_definition_spec.rb
36
- - spec/integration/yard/sinclair/method_definition/block_definition_spec.rb
26
+ - 'spec/integration/yard/**/*_spec.rb'
37
27
 
28
+ RSpec/ExampleLength:
29
+ Exclude:
30
+ - 'spec/integration/yard/**/*_spec.rb'
38
31
 
39
32
  RSpec/MultipleExpectations:
40
33
  Exclude:
41
- - spec/integration/yard/sinclair/method_definition_spec.rb
42
- - spec/integration/yard/sinclair/method_definition/instance_block_definition_spec.rb
43
- - spec/integration/yard/sinclair/method_definition/instance_string_definition_spec.rb
44
- - spec/integration/yard/sinclair/method_definition/instance_method_definition_spec.rb
45
- - spec/integration/yard/sinclair/method_definition/class_block_definition_spec.rb
46
- - spec/integration/yard/sinclair/method_definition/class_string_definition_spec.rb
47
- - spec/integration/yard/sinclair/method_definition/class_method_definition_spec.rb
34
+ - 'spec/integration/yard/**/*_spec.rb'
35
+ - 'spec/integration/readme/**/*_spec.rb'
48
36
  - spec/lib/sinclair_spec.rb
49
- - spec/integration/readme/my_model_spec.rb
50
- - spec/integration/yard/sinclair/method_definition/block_definition_spec.rb
51
- - spec/integration/yard/sinclair/method_definition/string_definition_spec.rb
52
37
 
53
38
  RSpec/NestedGroups:
54
39
  Max: 4
data/README.md CHANGED
@@ -15,7 +15,7 @@ methods
15
15
 
16
16
  Yard Documentation
17
17
  -------------------
18
- [https://www.rubydoc.info/gems/sinclair/1.6.0](https://www.rubydoc.info/gems/sinclair/1.6.0)
18
+ [https://www.rubydoc.info/gems/sinclair/1.6.1](https://www.rubydoc.info/gems/sinclair/1.6.1)
19
19
 
20
20
  Installation
21
21
  ---------------
@@ -3,3 +3,4 @@ ignore:
3
3
  - lib/sinclair/matchers/add_method.rb
4
4
  - lib/sinclair/version.rb
5
5
  - lib/sinclair/method_builder/base.rb
6
+ - lib/sinclair/exception.rb
data/config/yardstick.yml CHANGED
@@ -33,6 +33,8 @@ rules:
33
33
  - Sinclair::Config::MethodsBuilder#initialize
34
34
  - Sinclair::ConfigFactory#initialize
35
35
  - Sinclair::EnvSettable::Builder#initialize
36
+ - Sinclair::Exception::InvalidOptions#initialize
37
+ - Sinclair::InputHash#initialize
36
38
  - Sinclair::Matchers::AddClassMethodTo#initialize
37
39
  - Sinclair::Matchers::AddInstanceMethodTo#instance
38
40
  - Sinclair::Matchers::AddMethod#initialize
@@ -42,6 +44,8 @@ rules:
42
44
  - Sinclair::MethodDefinition#initialize
43
45
  - Sinclair::MethodDefinition::BlockDefinition#initialize
44
46
  - Sinclair::MethodDefinition::StringDefinition#initialize
47
+ - Sinclair::Options#initialize
48
+ - Sinclair::Options::Builder#initialize
45
49
  Summary::Length:
46
50
  enabled: true
47
51
  exclude: []
@@ -33,9 +33,7 @@ class Sinclair
33
33
  def initialize(klass, *names)
34
34
  super(klass)
35
35
 
36
- @names = names
37
- @defaults = names.find { |arg| arg.is_a?(Hash) } || {}
38
- names.delete(defaults)
36
+ @config_hash = Sinclair::InputHash.input_hash(*names)
39
37
  end
40
38
 
41
39
  # Build the methods in config class
@@ -70,43 +68,14 @@ class Sinclair
70
68
 
71
69
  private
72
70
 
73
- attr_reader :names, :defaults
74
- # @method names
71
+ attr_reader :config_hash
72
+ # @method config_hash
75
73
  # @private
76
74
  # @api private
77
75
  #
78
- # List of configuration names
79
- #
80
- # @return [Array<Symbol,String>]
81
-
82
- # @method defaults
83
- # @private
84
- # @api private
85
- #
86
- # Configurations that will receive a default value
87
- #
88
- # @return [Hash]
89
-
90
- # @private
91
- #
92
- # Builds the final config hash
93
- #
94
- # Config hash merges defauls config hashs
95
- # with {#name_as_hash}
76
+ # Configuration hash
96
77
  #
97
78
  # @return [Hash]
98
- def config_hash
99
- @config_hash ||= names_as_hash.merge!(defaults)
100
- end
101
-
102
- # @private
103
- #
104
- # Builds a hash with nil values from config names
105
- #
106
- # @return [Hash]
107
- def names_as_hash
108
- Hash[names.map { |*name| name }]
109
- end
110
79
  end
111
80
  end
112
81
  end
@@ -16,9 +16,7 @@ class Sinclair
16
16
  def initialize(klass, prefix, *settings_name, **defaults)
17
17
  super(klass, prefix: prefix)
18
18
 
19
- @settings = Hash[settings_name.map { |name| [name] }]
20
-
21
- @settings.merge!(defaults)
19
+ @settings = Sinclair::InputHash.input_hash(*settings_name, **defaults)
22
20
 
23
21
  add_all_methods
24
22
  end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ # @api public
5
+ # @author Darthjee
6
+ #
7
+ # Class responsible to convert inputs into
8
+ # hash of default values
9
+ class InputHash
10
+ # @api public
11
+ #
12
+ # Converts args into Hash
13
+ #
14
+ # @overload input_hash(*args)
15
+ # @param args [Array] Names attributes
16
+ # @overload input_hash(*args, **hash))
17
+ # @param args [Array] Names attributes
18
+ # @param hash [Hash] already converted
19
+ # hahs
20
+ #
21
+ # @return [Hash]
22
+ #
23
+ # @example
24
+ # Sinclair::InputHash.input_hash(
25
+ # :key1, 'key2',
26
+ # key3: 10,
27
+ # 'key4' => 20
28
+ # )
29
+ #
30
+ # # returns
31
+ # # {
32
+ # # key1: nil,
33
+ # # 'key2' => nil,
34
+ # # key3: 10,
35
+ # # 'key4' => 20
36
+ # # }
37
+ def self.input_hash(*args)
38
+ new(*args).to_h
39
+ end
40
+
41
+ # @api private
42
+ # @private
43
+ #
44
+ # Returns hash from initialization arguments
45
+ #
46
+ # @return [Hahs]
47
+ def to_h
48
+ hash_from_attributes.merge!(hash)
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :attributes, :hash
54
+ # @method attributes
55
+ # @api private
56
+ # @private
57
+ #
58
+ # Attribute list for creation of hash
59
+ #
60
+ # @return [Array<String,Symbol>]
61
+
62
+ # @method hash
63
+ # @api private
64
+ # @private
65
+ #
66
+ # Hash already in hash format
67
+ #
68
+ # @return [Hash]
69
+
70
+ # @api private
71
+ # @private
72
+ #
73
+ # @overload initialize(*arguments)
74
+ # @param arguments [String,Symbol] attributes to generate
75
+ # hash keys
76
+ # @overload initialize(*arguments, **hash)
77
+ # @param arguments [String,Symbol] attributes to generate
78
+ # hash keys
79
+ # @param hash [Hash] hash to be merged with final hash
80
+ # from attributes
81
+ def initialize(*arguments)
82
+ block = proc { |value| value.is_a?(Hash) }
83
+
84
+ @attributes = arguments.reject(&block)
85
+ @hash = arguments.find(&block) || {}
86
+ end
87
+
88
+ # @api private
89
+ # @private
90
+ #
91
+ # Creates a hash of nil values using attributes as keys
92
+ #
93
+ # @return [Hash]
94
+ def hash_from_attributes
95
+ Hash[attributes.map { |*attribute| attribute }]
96
+ end
97
+ end
98
+ end
@@ -2,12 +2,29 @@
2
2
 
3
3
  class Sinclair
4
4
  class Options
5
+ # @api private
6
+ # @author Darthjee
7
+ #
8
+ # Option Class Builder
9
+ #
10
+ # This class builds methods for options objects
5
11
  class Builder < Sinclair
6
- def initialize(klass, *options, **defaults)
12
+ # @overload initialize(klass, *options)
13
+ # @param klass [Class] options class to receive
14
+ # methods
15
+ # @param options [Array<Symbol>] list of accepted
16
+ # options
17
+ # @overload initialize(klass, *options, **defaults)
18
+ # @param klass [Class] options class to receive
19
+ # methods
20
+ # @param options [Array<Symbol>] list of accepted
21
+ # options
22
+ # @param defaults [Hash<Symbol,Object>] default options
23
+ # hash
24
+ def initialize(klass, *options)
7
25
  super(klass)
8
26
 
9
- @attributes = Hash[options.map { |name| [name] }]
10
- @attributes.merge!(defaults)
27
+ @attributes = Sinclair::InputHash.input_hash(*options)
11
28
 
12
29
  add_all_methods
13
30
  end
@@ -15,11 +32,21 @@ class Sinclair
15
32
  private
16
33
 
17
34
  attr_reader :attributes
35
+ # @method attributes
36
+ # @api private
37
+ # @private
38
+ #
39
+ # Options attributes
40
+ #
41
+ # @return [Hash<Symbol.Object>]
18
42
 
43
+ # Add all methods for options
44
+ #
45
+ # @return [Array<MethodDefinition>]
19
46
  def add_all_methods
20
47
  attributes.each do |option, value|
21
48
  add_method(option, cached: true) { value }
22
- klass.options.push(option)
49
+ klass.allowed_options.push(option.to_sym)
23
50
  end
24
51
  end
25
52
  end
@@ -1,22 +1,72 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
+ # @api public
5
+ # @author Darthjee
6
+ #
7
+ # Base options class
8
+ #
9
+ # @example Options usage
10
+ # class ConnectionOptions < Sinclair::Options
11
+ # with_options :timeout, :retries, port: 443, protocol: 'https'
12
+ # end
13
+ #
14
+ # options = ConnectionOptions.new(retries: 10, port: 8080)
15
+ #
16
+ # options.timeout # returns nil
17
+ # options.retries # returns 10
18
+ # options.port # returns 8080
19
+ # options.protocol # returns 'https'
4
20
  class Options
5
21
  autoload :Builder, 'sinclair/options/builder'
6
22
 
7
23
  class << self
8
- def options
9
- @options ||= []
24
+ # @api private
25
+ # @private
26
+ #
27
+ # Options allowed when initializing options
28
+ #
29
+ # @return [Array<Symbol>]
30
+ def allowed_options
31
+ @allowed_options ||= (superclass.try(:allowed_options).dup || [])
32
+ end
33
+
34
+ # @api private
35
+ # @private
36
+ #
37
+ # returns invalid options
38
+ #
39
+ # @return [Array<Symbol>]
40
+ def invalid_options_in(names)
41
+ names.map(&:to_sym) - allowed_options
10
42
  end
11
43
 
12
44
  private
13
45
 
46
+ # @api public
47
+ # @!visibility public
48
+ #
49
+ # Add available options
50
+ #
51
+ # @example (see Options)
52
+ #
53
+ # @return (see Sinclair#build)
54
+ #
55
+ # @overload with_options(*options)
56
+ # @param options [Array<Symbol>] list of accepted
57
+ # options
58
+ # @overload with_options(*options, **defaults)
59
+ # @param options [Array<Symbol>] list of accepted
60
+ # options
61
+ # @param defaults [Hash<Symbol,Object>] default options
62
+ # hash
14
63
  def with_options(*options)
15
64
  Builder.new(self, *options).build
16
65
  end
17
66
  end
18
67
 
19
68
  # @param options [Hash] hash with options (see {.options}, {.with_options})
69
+ # @example (see Options)
20
70
  def initialize(options = {})
21
71
  check_options(options)
22
72
 
@@ -28,6 +78,7 @@ class Sinclair
28
78
  private
29
79
 
30
80
  # @private
81
+ # @api private
31
82
  #
32
83
  # check if given options are allowed
33
84
  #
@@ -35,7 +86,7 @@ class Sinclair
35
86
  #
36
87
  # @return [NilClass]
37
88
  def check_options(options)
38
- invalid_keys = options.keys - self.class.options
89
+ invalid_keys = self.class.invalid_options_in(options.keys)
39
90
 
40
91
  return if invalid_keys.empty?
41
92
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.6.0'
4
+ VERSION = '1.6.1'
5
5
  end
data/lib/sinclair.rb CHANGED
@@ -90,6 +90,7 @@ class Sinclair
90
90
  autoload :Configurable, 'sinclair/configurable'
91
91
  autoload :EnvSettable, 'sinclair/env_settable'
92
92
  autoload :Exception, 'sinclair/exception'
93
+ autoload :InputHash, 'sinclair/input_hash'
93
94
  autoload :MethodBuilder, 'sinclair/method_builder'
94
95
  autoload :MethodDefinition, 'sinclair/method_definition'
95
96
  autoload :MethodDefinitions, 'sinclair/method_definitions'
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Sinclair::InputHash do
4
+ describe 'yard' do
5
+ describe 'Regular usage' do
6
+ it do
7
+ expect(
8
+ Sinclair::InputHash.input_hash(
9
+ :key1, 'key2',
10
+ key3: 10,
11
+ 'key4' => 20
12
+ )
13
+ ).to eq(
14
+ key1: nil,
15
+ 'key2' => nil,
16
+ key3: 10,
17
+ 'key4' => 20
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::Options do
6
+ describe 'yard' do
7
+ it 'creates options object' do
8
+ options = ConnectionOptions.new(retries: 10, port: 8080)
9
+
10
+ expect(options.timeout).to be_nil
11
+ expect(options.retries).to eq(10)
12
+ expect(options.port).to eq(8080)
13
+ expect(options.protocol).to eq('https')
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::InputHash do
6
+ describe '.input_hash' do
7
+ context 'when arguments are strings and symbols' do
8
+ let(:hash) do
9
+ described_class.input_hash(
10
+ :attribute1,
11
+ 'attribute2'
12
+ )
13
+ end
14
+
15
+ let(:expected_hash) do
16
+ {
17
+ attribute1: nil,
18
+ 'attribute2' => nil
19
+ }
20
+ end
21
+
22
+ it 'uses attributes as keys for the hash' do
23
+ expect(hash).to eq(expected_hash)
24
+ end
25
+ end
26
+
27
+ context 'when arguments is a hash' do
28
+ let(:hash) do
29
+ described_class.input_hash(expected_hash)
30
+ end
31
+
32
+ let(:expected_hash) do
33
+ {
34
+ attribute1: 10,
35
+ 'attribute2' => 20
36
+ }
37
+ end
38
+
39
+ it 'returns same hash' do
40
+ expect(hash).to eq(expected_hash)
41
+ end
42
+ end
43
+
44
+ context 'when arguments is a mix of names and hashes' do
45
+ let(:hash) do
46
+ described_class.input_hash(
47
+ :attribute1, 'attribute2',
48
+ attribute3: 10,
49
+ 'attribute4' => 20
50
+ )
51
+ end
52
+
53
+ let(:expected_hash) do
54
+ {
55
+ attribute1: nil,
56
+ 'attribute2' => nil,
57
+ attribute3: 10,
58
+ 'attribute4' => 20
59
+ }
60
+ end
61
+
62
+ it 'returns same hash' do
63
+ expect(hash).to eq(expected_hash)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::Options::Builder do
6
+ describe '#build' do
7
+ subject(:builder) do
8
+ described_class.new(klass, *args)
9
+ end
10
+
11
+ let(:klass) { Class.new(Sinclair::Options) }
12
+ let(:options) { klass.new }
13
+
14
+ context 'when calling with keys' do
15
+ let(:args) { [:timeout, 'retries'] }
16
+
17
+ it 'add first method' do
18
+ expect { builder.build }
19
+ .to add_method(:timeout).to(klass)
20
+ end
21
+
22
+ it 'add second method' do
23
+ expect { builder.build }
24
+ .to add_method(:retries).to(klass)
25
+ end
26
+
27
+ it do
28
+ expect { builder.build }
29
+ .to change(klass, :allowed_options)
30
+ .from([])
31
+ .to(%i[timeout retries])
32
+ end
33
+
34
+ it do
35
+ expect { builder.build }
36
+ .not_to change(Sinclair::Options, :allowed_options)
37
+ end
38
+
39
+ context 'when when calling method after building' do
40
+ before { builder.build }
41
+
42
+ it { expect(options.timeout).to be_nil }
43
+ end
44
+ end
45
+
46
+ context 'when calling with a hash' do
47
+ let(:args) { [{ timeout_sec: 10, 'retries' => 20 }] }
48
+
49
+ it 'adds method' do
50
+ expect { builder.build }
51
+ .to add_method(:timeout_sec).to(klass)
52
+ end
53
+
54
+ context 'when when calling method after building' do
55
+ before { builder.build }
56
+
57
+ it 'returns default value' do
58
+ expect(options.retries).to eq(20)
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'when calling on subclass' do
64
+ let(:super_class) { Class.new(Sinclair::Options) }
65
+ let(:klass) { Class.new(super_class) }
66
+ let(:args) do
67
+ [:protocol, { 'port' => 443 }]
68
+ end
69
+
70
+ let(:super_builder) do
71
+ described_class.new(super_class, :timeout, 'retries')
72
+ end
73
+
74
+ before { super_builder.build }
75
+
76
+ it 'add first method' do
77
+ expect { builder.build }
78
+ .to add_method(:protocol).to(klass)
79
+ end
80
+
81
+ it 'add second method' do
82
+ expect { builder.build }
83
+ .to add_method(:port).to(klass)
84
+ end
85
+
86
+ it do
87
+ expect { builder.build }
88
+ .to change(klass, :allowed_options)
89
+ .from(%i[timeout retries])
90
+ .to(%i[timeout retries protocol port])
91
+ end
92
+
93
+ it do
94
+ expect { builder.build }
95
+ .not_to change(super_class, :allowed_options)
96
+ end
97
+ end
98
+ end
99
+ end
@@ -5,22 +5,34 @@ require 'spec_helper'
5
5
  describe Sinclair::Options do
6
6
  subject(:options) { klass.new }
7
7
 
8
- let(:klass) { Class.new(described_class) }
9
-
10
8
  describe '.with_options' do
9
+ let(:klass) { Class.new(described_class) }
10
+
11
11
  context 'when calling with keys' do
12
12
  it 'add first method' do
13
- expect { klass.send(:with_options, :timeout, :retries) }
13
+ expect { klass.send(:with_options, :timeout, 'retries') }
14
14
  .to add_method(:timeout).to(klass)
15
15
  end
16
16
 
17
17
  it 'add second method' do
18
- expect { klass.send(:with_options, :timeout, :retries) }
18
+ expect { klass.send(:with_options, :timeout, 'retries') }
19
19
  .to add_method(:retries).to(klass)
20
20
  end
21
21
 
22
+ it do
23
+ expect { klass.send(:with_options, :timeout, 'retries') }
24
+ .to change(klass, :allowed_options)
25
+ .from([])
26
+ .to(%i[timeout retries])
27
+ end
28
+
29
+ it do
30
+ expect { klass.send(:with_options, :timeout, 'retries') }
31
+ .not_to change(described_class, :allowed_options)
32
+ end
33
+
22
34
  context 'when when calling method after building' do
23
- before { klass.send(:with_options, :timeout, :retries) }
35
+ before { klass.send(:with_options, :timeout, 'retries') }
24
36
 
25
37
  it { expect(options.timeout).to be_nil }
26
38
  end
@@ -28,14 +40,45 @@ describe Sinclair::Options do
28
40
 
29
41
  context 'when calling with a hash' do
30
42
  it 'adds method' do
31
- expect { klass.send(:with_options, timeout: 10) }
32
- .to add_method(:timeout).to(klass)
43
+ expect { klass.send(:with_options, timeout_sec: 10, 'retries' => 20) }
44
+ .to add_method(:timeout_sec).to(klass)
33
45
  end
34
46
 
35
47
  context 'when when calling method after building' do
36
- before { klass.send(:with_options, timeout: 10) }
48
+ before { klass.send(:with_options, timeout_sec: 10, 'retries' => 20) }
37
49
 
38
- it { expect(options.timeout).not_to be_nil }
50
+ it 'returns default value' do
51
+ expect(options.retries).to eq(20)
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'when calling on subclass' do
57
+ let(:super_class) { Class.new(described_class) }
58
+ let(:klass) { Class.new(super_class) }
59
+
60
+ before { super_class.send(:with_options, :timeout, 'retries') }
61
+
62
+ it 'add first method' do
63
+ expect { klass.send(:with_options, :protocol, 'port' => 443) }
64
+ .to add_method(:protocol).to(klass)
65
+ end
66
+
67
+ it 'add second method' do
68
+ expect { klass.send(:with_options, :protocol, 'port' => 443) }
69
+ .to add_method(:port).to(klass)
70
+ end
71
+
72
+ it do
73
+ expect { klass.send(:with_options, 'protocol', port: 443) }
74
+ .to change(klass, :allowed_options)
75
+ .from(%i[timeout retries])
76
+ .to(%i[timeout retries protocol port])
77
+ end
78
+
79
+ it do
80
+ expect { klass.send(:with_options, 'protocol', port: 443) }
81
+ .not_to change(super_class, :allowed_options)
39
82
  end
40
83
  end
41
84
  end
@@ -77,11 +120,55 @@ describe Sinclair::Options do
77
120
  end
78
121
  end
79
122
 
123
+ context 'when initializing subclass with valid args' do
124
+ subject(:options) do
125
+ klass.new(timeout: timeout, protocol: 'http')
126
+ end
127
+
128
+ let(:klass) { Class.new(ConnectionOptions) }
129
+ let(:timeout) { Random.rand(10..19) }
130
+
131
+ before do
132
+ klass.send(:with_options, :access_token, identifier: 'my client')
133
+ end
134
+
135
+ it 'sets value of options attribute' do
136
+ expect(options.timeout).to eq(timeout)
137
+ end
138
+
139
+ it 'sets value of options attribute that has default' do
140
+ expect(options.protocol).to eq('http')
141
+ end
142
+
143
+ it 'does not mess with non initialized attributes' do
144
+ expect(options.retries).to be_nil
145
+ end
146
+
147
+ it 'does not mess with non initialized attributes with defaults' do
148
+ expect(options.port).to eq(443)
149
+ end
150
+
151
+ it 'returns nil for new added option without default' do
152
+ expect(options.access_token).to be_nil
153
+ end
154
+
155
+ it 'returns value for new added option with default' do
156
+ expect(options.identifier).to eq('my client')
157
+ end
158
+ end
159
+
80
160
  context 'when initializing with invalid args' do
81
161
  it do
82
162
  expect { klass.new(invalid: 10) }
83
163
  .to raise_error(Sinclair::Exception::InvalidOptions)
84
164
  end
85
165
  end
166
+
167
+ context 'when initializing with string or symbol keys' do
168
+ it do
169
+ expect { klass.new('timeout' => 20, retries: 30) }
170
+ .not_to raise_error
171
+ end
172
+ end
86
173
  end
87
174
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinclair
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DarthJee
@@ -281,6 +281,7 @@ files:
281
281
  - lib/sinclair/env_settable.rb
282
282
  - lib/sinclair/env_settable/builder.rb
283
283
  - lib/sinclair/exception.rb
284
+ - lib/sinclair/input_hash.rb
284
285
  - lib/sinclair/matchers.rb
285
286
  - lib/sinclair/matchers/add_class_method.rb
286
287
  - lib/sinclair/matchers/add_class_method_to.rb
@@ -316,11 +317,13 @@ files:
316
317
  - spec/integration/yard/sinclair/config_spec.rb
317
318
  - spec/integration/yard/sinclair/configurable_spec.rb
318
319
  - spec/integration/yard/sinclair/env_settable_spec.rb
320
+ - spec/integration/yard/sinclair/input_hash_spec.rb
319
321
  - spec/integration/yard/sinclair/matchers/add_class_method_spec.rb
320
322
  - spec/integration/yard/sinclair/matchers/add_class_method_to_spec.rb
321
323
  - spec/integration/yard/sinclair/matchers/add_instance_method_spec.rb
322
324
  - spec/integration/yard/sinclair/matchers/add_instance_method_to_spec.rb
323
325
  - spec/integration/yard/sinclair/options_parser_spec.rb
326
+ - spec/integration/yard/sinclair/options_spec.rb
324
327
  - spec/integration/yard/sinclair_spec.rb
325
328
  - spec/lib/sinclair/config/methods_builder_spec.rb
326
329
  - spec/lib/sinclair/config_builder_spec.rb
@@ -331,6 +334,7 @@ files:
331
334
  - spec/lib/sinclair/env_settable/builder_spec.rb
332
335
  - spec/lib/sinclair/env_settable_spec.rb
333
336
  - spec/lib/sinclair/exception/invalid_options_spec.rb
337
+ - spec/lib/sinclair/input_hash_spec.rb
334
338
  - spec/lib/sinclair/matchers/add_class_method_spec.rb
335
339
  - spec/lib/sinclair/matchers/add_class_method_to_spec.rb
336
340
  - spec/lib/sinclair/matchers/add_instance_method_spec.rb
@@ -344,6 +348,7 @@ files:
344
348
  - spec/lib/sinclair/method_definition/string_definition_spec.rb
345
349
  - spec/lib/sinclair/method_definition_spec.rb
346
350
  - spec/lib/sinclair/method_definitions_spec.rb
351
+ - spec/lib/sinclair/options/builder_spec.rb
347
352
  - spec/lib/sinclair/options_parser_spec.rb
348
353
  - spec/lib/sinclair/options_spec.rb
349
354
  - spec/lib/sinclair_spec.rb