sinclair 1.2.1 → 1.3.0
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 +4 -4
- data/.circleci/config.yml +4 -1
- data/.gitignore +1 -0
- data/Dockerfile +23 -3
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/config/rubycritc.rb +12 -0
- data/config/yardstick.yml +6 -0
- data/lib/sinclair/config.rb +11 -0
- data/lib/sinclair/config_builder.rb +66 -0
- data/lib/sinclair/config_factory.rb +151 -0
- data/lib/sinclair/configurable.rb +81 -0
- data/lib/sinclair/version.rb +1 -1
- data/lib/sinclair.rb +4 -0
- data/scripts/rubycritic.sh +10 -0
- data/sinclair.gemspec +1 -0
- data/spec/integration/yard/sinclair/config_builder_spec.rb +19 -0
- data/spec/integration/yard/sinclair/config_factory_spec.rb +78 -0
- data/spec/integration/yard/sinclair/configurable_spec.rb +31 -0
- data/spec/lib/sinclair/config_builder_spec.rb +51 -0
- data/spec/lib/sinclair/config_factory_spec.rb +171 -0
- data/spec/lib/sinclair/configurable_spec.rb +97 -0
- data/spec/spec_helper.rb +2 -3
- data/spec/support/models/dummy_config.rb +4 -0
- data/spec/support/models/dummy_configurable.rb +7 -0
- data/spec/support/models/my_config.rb +5 -0
- data/spec/support/models/my_configurable.rb +7 -0
- metadata +32 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8078be623117ced163bf463e484e1e2553781dc3ebf379e48a98dc5c3e710079
|
4
|
+
data.tar.gz: 5edfd7356786a04ee94f5bfff56fd954e26b52b5fa4ef7eb3372ddd33ddb6c80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03b32dcf796be1331442a673040264bc2cb215f1ad2eb657aaf416f76bea0e6aaca71ccb8bd356e5c9ab094dc31f4d2a0c3cc4dc607ccb39db429b864b5e785c
|
7
|
+
data.tar.gz: 28bd3ed7dea51f96d82bdbbdb64588762cc017ab92d8847045dbf33beb8aa83abc71869ff5e55f4f8dc72f4f29f4f9907596702acb7ab5f456c43bc0b92e902b
|
data/.circleci/config.yml
CHANGED
@@ -2,7 +2,7 @@ version: 2
|
|
2
2
|
jobs:
|
3
3
|
build:
|
4
4
|
docker:
|
5
|
-
- image: darthjee/circleci_ruby_gems:0.0
|
5
|
+
- image: darthjee/circleci_ruby_gems:0.1.0
|
6
6
|
steps:
|
7
7
|
- checkout
|
8
8
|
- run:
|
@@ -26,3 +26,6 @@ jobs:
|
|
26
26
|
- run:
|
27
27
|
name: Check version documentation
|
28
28
|
command: scripts/check_readme.sh
|
29
|
+
- run:
|
30
|
+
name: Rubycritcs check
|
31
|
+
command: scripts/rubycritic.sh
|
data/.gitignore
CHANGED
data/Dockerfile
CHANGED
@@ -1,6 +1,26 @@
|
|
1
|
-
FROM darthjee/ruby_gems:0.0.1
|
1
|
+
FROM darthjee/ruby_gems:0.0.1 as base
|
2
|
+
FROM darthjee/scripts:0.0.2 as scripts
|
3
|
+
|
4
|
+
######################################
|
5
|
+
|
6
|
+
FROM base as builder
|
2
7
|
|
3
|
-
USER app
|
4
8
|
COPY --chown=app ./ /home/app/app/
|
9
|
+
COPY --chown=app:app --from=scripts /home/scripts/ ./
|
10
|
+
|
11
|
+
ENV HOME_DIR /home/app
|
12
|
+
RUN /bin/bash bundle_builder.sh
|
5
13
|
|
6
|
-
|
14
|
+
#######################
|
15
|
+
#FINAL IMAGE
|
16
|
+
FROM base
|
17
|
+
|
18
|
+
USER root
|
19
|
+
|
20
|
+
COPY --chown=app:app --from=builder /home/app/bundle/gems /usr/local/bundle/gems
|
21
|
+
COPY --chown=app:app --from=builder /home/app/bundle/cache /usr/local/bundle/cache
|
22
|
+
COPY --chown=app:app --from=builder /home/app/bundle/specifications /usr/local/bundle/specifications
|
23
|
+
COPY --chown=app:app --from=builder /home/app/bundle/bin /usr/local/bundle/bin
|
24
|
+
COPY --chown=app:app --from=builder /home/app/bundle/extensions /usr/local/bundle/extensions
|
25
|
+
|
26
|
+
USER app
|
data/README.md
CHANGED
data/Rakefile
CHANGED
data/config/rubycritc.rb
ADDED
data/config/yardstick.yml
CHANGED
@@ -31,6 +31,9 @@ rules:
|
|
31
31
|
- Sinclair::OptionsParser#options
|
32
32
|
- Sinclair::OptionsParser#options_object
|
33
33
|
- Sinclair::Matchers::AddMethodTo#raise_block_syntax_error
|
34
|
+
- Sinclair::ConfigFactory#initialize
|
35
|
+
- Sinclair::ConfigFactory#config_class
|
36
|
+
- Sinclair::ConfigFactory#config_attributes
|
34
37
|
Summary::Presence:
|
35
38
|
enabled: true
|
36
39
|
exclude:
|
@@ -43,6 +46,9 @@ rules:
|
|
43
46
|
- Sinclair::MethodDefinition#block
|
44
47
|
- Sinclair::OptionsParser#options
|
45
48
|
- Sinclair::OptionsParser#options_object
|
49
|
+
- Sinclair::ConfigFactory#initialize
|
50
|
+
- Sinclair::ConfigFactory#config_class
|
51
|
+
- Sinclair::ConfigFactory#config_attributes
|
46
52
|
Summary::Length:
|
47
53
|
enabled: true
|
48
54
|
exclude: []
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
# @api private
|
5
|
+
#
|
6
|
+
# Class responsible for setting the values on configuration
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class MyConfig
|
10
|
+
# attr_reader :name, :config
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# config = MyConfig.new
|
14
|
+
#
|
15
|
+
# builder = Sinclair::ConfigBuilder.new(config, :name)
|
16
|
+
#
|
17
|
+
# builder.instance_eval { |c| c.name 'John' }
|
18
|
+
#
|
19
|
+
# config.name # returns 'John'
|
20
|
+
class ConfigBuilder
|
21
|
+
# A new instance of ConfigBuilder
|
22
|
+
#
|
23
|
+
# @param config [Sinclair::Config] config object to be build
|
24
|
+
# config object has no attribute setters (only readers)
|
25
|
+
# so all attributes are set as instance variable
|
26
|
+
#
|
27
|
+
# @param config_attributes [Array<Symbol>] list of attributes
|
28
|
+
# that can be set on config (expecting that config has
|
29
|
+
# the right attribute readers)
|
30
|
+
def initialize(config, *config_attributes)
|
31
|
+
@config = config
|
32
|
+
@config_attributes = config_attributes
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @private
|
38
|
+
#
|
39
|
+
# Method called for methods missing
|
40
|
+
#
|
41
|
+
# When a method is missing, it is expected that it is the
|
42
|
+
# name of a variable to be set on config (as long as it was
|
43
|
+
# defined in the config_attributes_array)
|
44
|
+
#
|
45
|
+
# @param method_name [Symbol] name of the method called
|
46
|
+
# @param args [Array<Object>] arguments of the call
|
47
|
+
#
|
48
|
+
# @return [Object]
|
49
|
+
def method_missing(method_name, *args)
|
50
|
+
return super unless @config_attributes.include?(method_name)
|
51
|
+
|
52
|
+
@config.instance_variable_set("@#{method_name}", *args)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @private
|
56
|
+
#
|
57
|
+
# Checks if method missing will catch the method called
|
58
|
+
#
|
59
|
+
# @return [TrueClass,FalseClass]
|
60
|
+
#
|
61
|
+
# @see #method_missing
|
62
|
+
def respond_to_missing?(method_name, include_private)
|
63
|
+
@config_attributes.include?(method_name) || super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
# @api private
|
5
|
+
#
|
6
|
+
# Class responsible for configuring the configuration class
|
7
|
+
#
|
8
|
+
# @example General usage
|
9
|
+
# factory = Sinclair::ConfigFactory.new
|
10
|
+
# factory.add_configs(:name)
|
11
|
+
# factory.configure { |c| c.name 'John' }
|
12
|
+
#
|
13
|
+
# config = factory.config
|
14
|
+
#
|
15
|
+
# config.class.superclass # returns Sinclair::Config
|
16
|
+
# factory.config.equal?(config) # returns true
|
17
|
+
# config.name # returns 'John'
|
18
|
+
class ConfigFactory
|
19
|
+
# @param config_class [Class] configuration class to be used
|
20
|
+
# @param config_attributes [Array<Symbol,String>] list of possible configurations
|
21
|
+
def initialize(config_class: Class.new(Config), config_attributes: [])
|
22
|
+
@config_class = config_class
|
23
|
+
@config_attributes = config_attributes.dup
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns current instance of config
|
27
|
+
#
|
28
|
+
# the method returns the same instance until +reset_config+
|
29
|
+
# is called
|
30
|
+
#
|
31
|
+
# @return [Config,Object] the instance of given
|
32
|
+
# config_class. by default, this returns
|
33
|
+
# +Class.new(Config).new+
|
34
|
+
#
|
35
|
+
# @see #reset_config
|
36
|
+
#
|
37
|
+
# @example (see ConfigFactory)
|
38
|
+
def config
|
39
|
+
@config ||= config_class.new
|
40
|
+
end
|
41
|
+
|
42
|
+
# Cleans the current config instance
|
43
|
+
#
|
44
|
+
# After cleaning it, {#config} will generate a new
|
45
|
+
# instance
|
46
|
+
#
|
47
|
+
# @return [NilClass]
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# factory = Sinclair::ConfigFactory.new
|
51
|
+
#
|
52
|
+
# config = factory.config
|
53
|
+
#
|
54
|
+
# factory.reset_config
|
55
|
+
#
|
56
|
+
# factory.config == config # returns false
|
57
|
+
def reset_config
|
58
|
+
@config = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# Adds possible configurations
|
62
|
+
#
|
63
|
+
# It change the configuration class adding methods
|
64
|
+
# and keeps track of those configurations so that
|
65
|
+
# {ConfigBuilder} is able to set those values when invoked
|
66
|
+
#
|
67
|
+
# @return [Array<Symbol>] all known config attributes
|
68
|
+
#
|
69
|
+
# @example Adding configuration name
|
70
|
+
# factory = Sinclair::ConfigFactory.new
|
71
|
+
# config = factory.config
|
72
|
+
#
|
73
|
+
# config.respond_to? :active
|
74
|
+
# # returns false
|
75
|
+
#
|
76
|
+
# factory.add_configs(:active)
|
77
|
+
#
|
78
|
+
# config.respond_to? :active
|
79
|
+
# # returns true
|
80
|
+
def add_configs(*attributes)
|
81
|
+
config_class.attr_reader(*attributes)
|
82
|
+
config_attributes.concat(attributes.map(&:to_sym))
|
83
|
+
end
|
84
|
+
|
85
|
+
# Set the values in the config
|
86
|
+
#
|
87
|
+
# The block given is evaluated by the {ConfigBuilder}
|
88
|
+
# where each method missed will be used to set a variable
|
89
|
+
# in the config
|
90
|
+
#
|
91
|
+
# @yield [ConfigBuilder] methods called in the block
|
92
|
+
# that are not present in {ConfigBuilder} are
|
93
|
+
# then set as instance variables of the config
|
94
|
+
#
|
95
|
+
# @return [Object] the result of the block
|
96
|
+
#
|
97
|
+
# @example Setting name on config
|
98
|
+
# class MyConfig
|
99
|
+
# attr_reader :name
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# factory = Sinclair::ConfigFactory.new(
|
103
|
+
# config_class: MyConfig,
|
104
|
+
# config_attributes: [:name]
|
105
|
+
# )
|
106
|
+
#
|
107
|
+
# config = factory.config
|
108
|
+
#
|
109
|
+
# factory.configure { name 'John' }
|
110
|
+
#
|
111
|
+
# config.name # returns 'John'
|
112
|
+
def configure(&block)
|
113
|
+
config_builder.instance_eval(&block)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns a new instance of ConfigFactory
|
117
|
+
#
|
118
|
+
# the new instance will have the same
|
119
|
+
# config_attributes and for config_class a child
|
120
|
+
# of the current config_class
|
121
|
+
#
|
122
|
+
# This method is called when initializing {Configurable}
|
123
|
+
# config_factory and the superclass is also configurable
|
124
|
+
#
|
125
|
+
# This way, child classes from other {Configurable} classes
|
126
|
+
# will have a config_class that is a child from the original
|
127
|
+
# config_class
|
128
|
+
#
|
129
|
+
# @return [ConfigFactory]
|
130
|
+
def child
|
131
|
+
self.class.new(
|
132
|
+
config_class: Class.new(config_class),
|
133
|
+
config_attributes: config_attributes
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
# @private
|
140
|
+
attr_reader :config_class, :config_attributes
|
141
|
+
|
142
|
+
# @private
|
143
|
+
#
|
144
|
+
# Returns a builder capable of injecting variables into config
|
145
|
+
#
|
146
|
+
# @return [ConfigBuilder]
|
147
|
+
def config_builder
|
148
|
+
ConfigBuilder.new(config, *config_attributes)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
# @api public
|
5
|
+
#
|
6
|
+
# Module capable of giving configuration capability
|
7
|
+
#
|
8
|
+
# By extending Configurable, class receives the methods public
|
9
|
+
# {ConfigFactory#config .config}, {ConfigFactory#reset_config .reset_config}
|
10
|
+
# and {ConfigFactory#configure .configure}
|
11
|
+
# and the private {#configurable_with .configurable_with}
|
12
|
+
#
|
13
|
+
# @see ConfigFactory
|
14
|
+
# @see ConfigBuilder
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# class MyConfigurable
|
18
|
+
# extend Sinclair::Configurable
|
19
|
+
#
|
20
|
+
# configurable_with :host, :port
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# MyConfigurable.configure do
|
24
|
+
# host 'interstella.com'
|
25
|
+
# port 5555
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# MyConfigurable.config.host
|
29
|
+
# # returns 'interstella.com'
|
30
|
+
#
|
31
|
+
# MyConfigurable.config.port
|
32
|
+
# # returns 5555
|
33
|
+
#
|
34
|
+
# MyConfigurable.reset
|
35
|
+
#
|
36
|
+
# MyConfigurable.config.host
|
37
|
+
# # returns nil
|
38
|
+
module Configurable
|
39
|
+
delegate :config, :reset_config, :configure, to: :config_factory
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
# @api private
|
44
|
+
#
|
45
|
+
# @private
|
46
|
+
#
|
47
|
+
# Generates a config factory
|
48
|
+
#
|
49
|
+
# When the current class is a child of a class extending
|
50
|
+
# {Configurable}, config_factory will be initialized with
|
51
|
+
# parameters to generate a configuration child from the
|
52
|
+
# original factory config
|
53
|
+
#
|
54
|
+
# @see ConfigFactory#child
|
55
|
+
#
|
56
|
+
# @return [ConfigFactory]
|
57
|
+
def config_factory
|
58
|
+
@config_factory ||= if superclass.is_a?(Configurable)
|
59
|
+
superclass.config_factory.child
|
60
|
+
else
|
61
|
+
ConfigFactory.new
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# @visibility public
|
68
|
+
#
|
69
|
+
# Adds a configuration option to config class
|
70
|
+
#
|
71
|
+
# @return [Array<Symbol>] list of possible
|
72
|
+
# configurations
|
73
|
+
#
|
74
|
+
# @see ConfigFactory#add_configs
|
75
|
+
#
|
76
|
+
# @example (see Configurable)
|
77
|
+
def configurable_with(*attributes)
|
78
|
+
config_factory.add_configs(*attributes)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/sinclair/version.rb
CHANGED
data/lib/sinclair.rb
CHANGED
@@ -29,6 +29,10 @@ class Sinclair
|
|
29
29
|
|
30
30
|
autoload :VERSION, 'sinclair/version'
|
31
31
|
autoload :MethodDefinition, 'sinclair/method_definition'
|
32
|
+
autoload :Config, 'sinclair/config'
|
33
|
+
autoload :ConfigBuilder, 'sinclair/config_builder'
|
34
|
+
autoload :ConfigFactory, 'sinclair/config_factory'
|
35
|
+
autoload :Configurable, 'sinclair/configurable'
|
32
36
|
|
33
37
|
include OptionsParser
|
34
38
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
DIFF_LIST=$(git diff --name-only $CIRCLE_SHA1 $(git merge-base $CIRCLE_SHA1 origin/master) | grep "^lib/")
|
4
|
+
|
5
|
+
if [ ! -z "$DIFF_LIST" ]; then
|
6
|
+
mkdir -p tmp/rubycritic/compare
|
7
|
+
bundle exec rubycritic --format console --branch origin/master -t 0 $DIFF_LIST
|
8
|
+
else
|
9
|
+
echo "No changes detected. Skipping rubycritic..."
|
10
|
+
fi
|
data/sinclair.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_development_dependency 'rspec', '>= 3.8'
|
28
28
|
gem.add_development_dependency 'rubocop', '0.58.1'
|
29
29
|
gem.add_development_dependency 'rubocop-rspec', '1.30.0'
|
30
|
+
gem.add_development_dependency 'rubycritic', '>= 4.0.2'
|
30
31
|
gem.add_development_dependency 'simplecov', '~> 0.16.x'
|
31
32
|
gem.add_development_dependency 'yard', '>= 0.9.18'
|
32
33
|
gem.add_development_dependency 'yardstick', '>= 0.9.9'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Sinclair::ConfigBuilder do
|
4
|
+
describe 'yard' do
|
5
|
+
describe '#instance_eval' do
|
6
|
+
subject(:builder) do
|
7
|
+
described_class.new(config, :name)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:config) { MyConfig.new }
|
11
|
+
|
12
|
+
it 'sets variable from config' do
|
13
|
+
expect { builder.instance_eval { |c| c.name 'John' } }
|
14
|
+
.to change(config, :name)
|
15
|
+
.from(nil).to('John')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Sinclair::ConfigFactory do
|
4
|
+
describe '#yard' do
|
5
|
+
subject(:factory) do
|
6
|
+
described_class.new(
|
7
|
+
config_class: config_class,
|
8
|
+
config_attributes: config_attributes
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:config_class) { Class.new(Sinclair::Config) }
|
13
|
+
let(:config_attributes) { [:name] }
|
14
|
+
let(:config) { factory.config }
|
15
|
+
|
16
|
+
describe 'general usage' do
|
17
|
+
context 'when not passing any argument' do
|
18
|
+
subject(:factory) { described_class.new }
|
19
|
+
|
20
|
+
before do
|
21
|
+
factory.add_configs(:name)
|
22
|
+
factory.configure { |c| c.name 'John' }
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns an instance of Config child class' do
|
26
|
+
expect(config.class.superclass)
|
27
|
+
.to eq(Sinclair::Config)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'configures name to be John' do
|
31
|
+
expect(config.name).to eq('John')
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns always the same instance' do
|
35
|
+
expect(factory.config).to be_equal(config)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#reset_config' do
|
41
|
+
it 'changes config instance' do
|
42
|
+
expect { factory.reset_config }
|
43
|
+
.to change(factory, :config)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#add_configs' do
|
48
|
+
let(:config) { factory.config }
|
49
|
+
|
50
|
+
context 'when it already have config_attributes' do
|
51
|
+
it 'returns current possible configurations' do
|
52
|
+
expect(factory.add_configs('active'))
|
53
|
+
.to eq(%i[name active])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when initializing with no parameters' do
|
58
|
+
subject(:factory) { described_class.new }
|
59
|
+
|
60
|
+
it 'adds method to config' do
|
61
|
+
expect { factory.add_configs(:active) }
|
62
|
+
.to change { config.respond_to?(:active) }
|
63
|
+
.from(false).to(true)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#configure' do
|
69
|
+
let(:config_class) { MyConfig }
|
70
|
+
|
71
|
+
it 'sets variable on config' do
|
72
|
+
expect { factory.configure { name 'John' } }
|
73
|
+
.to change(config, :name)
|
74
|
+
.from(nil).to('John')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Sinclair::Configurable do
|
4
|
+
describe '#yard' do
|
5
|
+
before do
|
6
|
+
MyConfigurable.configure do
|
7
|
+
host 'interstella.com'
|
8
|
+
port 5555
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'sets right value for config host' do
|
13
|
+
expect(MyConfigurable.config.host)
|
14
|
+
.to eq('interstella.com')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets right value for config port' do
|
18
|
+
expect(MyConfigurable.config.port)
|
19
|
+
.to eq(5555)
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when reset_config is called' do
|
23
|
+
before { MyConfigurable.reset_config }
|
24
|
+
|
25
|
+
it 'returns initial value for host' do
|
26
|
+
expect(MyConfigurable.config.host)
|
27
|
+
.to be_nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Sinclair::ConfigBuilder do
|
4
|
+
subject(:builder) { described_class.new(config, *config_attributes) }
|
5
|
+
|
6
|
+
let(:config) { MyConfig.new }
|
7
|
+
let(:config_attributes) { [:name] }
|
8
|
+
|
9
|
+
it 'changes responds to given config' do
|
10
|
+
expect(builder).to respond_to(:name)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'does not respond to othr configs' do
|
14
|
+
expect(builder).not_to respond_to(:other_method)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'responds to other parent methods' do
|
18
|
+
expect(builder).to respond_to(:to_s)
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when builder was configuratd with the method called' do
|
22
|
+
let(:config_attributes) { [:name] }
|
23
|
+
|
24
|
+
it 'sets the instance variable' do
|
25
|
+
expect { builder.name 'John' }
|
26
|
+
.to change(config, :name)
|
27
|
+
.from(nil).to('John')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when builder was configuratd without the method called' do
|
32
|
+
let(:config_attributes) { [] }
|
33
|
+
|
34
|
+
it 'does not set the instance variable and raises error' do
|
35
|
+
expect { builder.name 'John' }
|
36
|
+
.to raise_error(NoMethodError)
|
37
|
+
.and not_change(config, :name)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when using a variable name from builder variables' do
|
42
|
+
let(:config_attributes) { [:config] }
|
43
|
+
|
44
|
+
it 'sets the instance variable without changing builder instance variable' do
|
45
|
+
expect { builder.config(key: 'value') }
|
46
|
+
.to not_change { builder.instance_variable_get(:@config) }
|
47
|
+
.and change(config, :config)
|
48
|
+
.from(nil).to(key: 'value')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::ConfigFactory do
|
6
|
+
subject(:factory) { described_class.new }
|
7
|
+
|
8
|
+
let(:config) { factory.config }
|
9
|
+
let(:other_factory) { described_class.new }
|
10
|
+
|
11
|
+
describe '#config' do
|
12
|
+
it do
|
13
|
+
expect(factory.config).to be_a(Sinclair::Config)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when calling twice' do
|
17
|
+
it 'returns the same instance' do
|
18
|
+
expect(factory.config)
|
19
|
+
.to be(factory.config)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when calling after reset_config' do
|
24
|
+
before { factory.reset_config }
|
25
|
+
|
26
|
+
it do
|
27
|
+
expect(factory.config).to be_a(Sinclair::Config)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when initializing with custom config class' do
|
32
|
+
subject(:factory) { described_class.new(config_class: DummyConfig) }
|
33
|
+
|
34
|
+
it do
|
35
|
+
expect(factory.config).to be_a(DummyConfig)
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when calling after reset_config' do
|
39
|
+
before { factory.reset_config }
|
40
|
+
|
41
|
+
it do
|
42
|
+
expect(factory.config).to be_a(DummyConfig)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#reset_config' do
|
49
|
+
let(:old_instance) { factory.config }
|
50
|
+
|
51
|
+
it 'reset_configs instance' do
|
52
|
+
expect { factory.reset_config }
|
53
|
+
.to change { factory.config.eql?(old_instance) }
|
54
|
+
.from(true).to(false)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'forces regeneration of instance' do
|
58
|
+
expect { factory.reset_config }
|
59
|
+
.not_to change { factory.config.class }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when initializing with custom config class' do
|
63
|
+
subject(:factory) { described_class.new(config_class: DummyConfig) }
|
64
|
+
|
65
|
+
it 'reset_configs instance' do
|
66
|
+
expect { factory.reset_config }
|
67
|
+
.to change { factory.config.eql?(old_instance) }
|
68
|
+
.from(true).to(false)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'forces regeneration of instance' do
|
72
|
+
expect { factory.reset_config }
|
73
|
+
.not_to change { factory.config.class }
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'does not affect other factories' do
|
77
|
+
expect { factory.reset_config }
|
78
|
+
.not_to change(other_factory, :config)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
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
|
98
|
+
|
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
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'changes subclasses of config' do
|
105
|
+
expect { factory.add_configs(:name) }
|
106
|
+
.to add_method(:name).to(factory.child.config)
|
107
|
+
end
|
108
|
+
|
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
|
114
|
+
|
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
|
120
|
+
|
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)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'does not mess with configurable methods' do
|
128
|
+
factory.add_configs(:reset_config)
|
129
|
+
factory.configure { |c| c.reset_config true }
|
130
|
+
factory.reset_config
|
131
|
+
expect(factory.config).to be_a(Sinclair::Config)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#configure' do
|
136
|
+
before { factory.add_configs(:user, 'password') }
|
137
|
+
|
138
|
+
it do
|
139
|
+
expect { factory.configure { |c| c.user 'Bob' } }
|
140
|
+
.to change(config, :user)
|
141
|
+
.from(nil).to('Bob')
|
142
|
+
end
|
143
|
+
|
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')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
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
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe '#child' do
|
161
|
+
it { expect(factory.child).to be_a(described_class) }
|
162
|
+
|
163
|
+
it 'generates factory capable of generating config subclasses' do
|
164
|
+
expect(factory.child.config).to be_a(factory.config.class)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'generates factory that does not generate same config class' do
|
168
|
+
expect(factory.child.config.class).not_to eq(factory.config.class)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Configurable do
|
6
|
+
subject(:configurable) { Class.new(DummyConfigurable) }
|
7
|
+
|
8
|
+
describe '.config' do
|
9
|
+
it do
|
10
|
+
expect(configurable.config).to be_a(Sinclair::Config)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when calling twice' do
|
14
|
+
it 'returns the same instance' do
|
15
|
+
expect(configurable.config)
|
16
|
+
.to be(configurable.config)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when calling after reset_config' do
|
21
|
+
before { configurable.reset_config }
|
22
|
+
|
23
|
+
it do
|
24
|
+
expect(configurable.config).to be_a(Sinclair::Config)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.reset_config' do
|
30
|
+
let(:old_instance) { configurable.config }
|
31
|
+
|
32
|
+
it 'reset_configs instance' do
|
33
|
+
expect { configurable.reset_config }
|
34
|
+
.to change { configurable.config.eql?(old_instance) }
|
35
|
+
.from(true).to(false)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'forces regeneration of instance' do
|
39
|
+
expect { configurable.reset_config }
|
40
|
+
.not_to change { configurable.config.class }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.configurable_with' do
|
45
|
+
it 'adds reader to config' do
|
46
|
+
expect { configurable.send(:configurable_with, :name) }
|
47
|
+
.to add_method(:name).to(configurable.config)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'does not add setter to config' do
|
51
|
+
expect { configurable.send(:configurable_with, :name) }
|
52
|
+
.not_to add_method(:name=).to(configurable.config)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'does not change parent class configuration' do
|
56
|
+
expect { configurable.send(:configurable_with, :name) }
|
57
|
+
.not_to add_method(:name).to(DummyConfigurable.config)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not change Sinclair::Config' do
|
61
|
+
expect { configurable.send(:configurable_with, :name) }
|
62
|
+
.not_to add_method(:name).to(Sinclair::Config.new)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'does not mess with configurable methods' do
|
66
|
+
configurable.send(:configurable_with, :reset_config)
|
67
|
+
configurable.configure { |c| c.reset_config true }
|
68
|
+
configurable.reset_config
|
69
|
+
expect(configurable.config).to be_a(Sinclair::Config)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '.configure' do
|
74
|
+
let(:config) { configurable.config }
|
75
|
+
|
76
|
+
it do
|
77
|
+
expect { configurable.configure { |c| c.user 'Bob' } }
|
78
|
+
.to change(config, :user)
|
79
|
+
.from(nil).to('Bob')
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when it was defined using string' do
|
83
|
+
it do
|
84
|
+
expect { configurable.configure { |c| c.password '123456' } }
|
85
|
+
.to change(config, :password)
|
86
|
+
.from(nil).to('123456')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when calling a method that was not defined' do
|
91
|
+
it do
|
92
|
+
expect { configurable.configure { |c| c.nope '123456' } }
|
93
|
+
.to raise_error(NoMethodError)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/spec/spec_helper.rb
CHANGED
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.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DarthJee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - '='
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 1.30.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubycritic
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 4.0.2
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 4.0.2
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: simplecov
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,10 +181,15 @@ files:
|
|
167
181
|
- LICENSE
|
168
182
|
- README.md
|
169
183
|
- Rakefile
|
184
|
+
- config/rubycritc.rb
|
170
185
|
- config/yardstick.rb
|
171
186
|
- config/yardstick.yml
|
172
187
|
- docker-compose.yml
|
173
188
|
- lib/sinclair.rb
|
189
|
+
- lib/sinclair/config.rb
|
190
|
+
- lib/sinclair/config_builder.rb
|
191
|
+
- lib/sinclair/config_factory.rb
|
192
|
+
- lib/sinclair/configurable.rb
|
174
193
|
- lib/sinclair/matchers.rb
|
175
194
|
- lib/sinclair/matchers/add_method.rb
|
176
195
|
- lib/sinclair/matchers/add_method_to.rb
|
@@ -178,6 +197,7 @@ files:
|
|
178
197
|
- lib/sinclair/options_parser.rb
|
179
198
|
- lib/sinclair/version.rb
|
180
199
|
- scripts/check_readme.sh
|
200
|
+
- scripts/rubycritic.sh
|
181
201
|
- sinclair.gemspec
|
182
202
|
- sinclair.jpg
|
183
203
|
- spec/integration/readme/my_class_spec.rb
|
@@ -186,11 +206,17 @@ files:
|
|
186
206
|
- spec/integration/readme/sinclair_spec.rb
|
187
207
|
- spec/integration/sinclair/matchers_spec.rb
|
188
208
|
- spec/integration/yard/my_builder_spec.rb
|
209
|
+
- spec/integration/yard/sinclair/config_builder_spec.rb
|
210
|
+
- spec/integration/yard/sinclair/config_factory_spec.rb
|
211
|
+
- spec/integration/yard/sinclair/configurable_spec.rb
|
189
212
|
- spec/integration/yard/sinclair/matchers/add_method_spec.rb
|
190
213
|
- spec/integration/yard/sinclair/matchers/add_method_to_spec.rb
|
191
214
|
- spec/integration/yard/sinclair/method_definition_spec.rb
|
192
215
|
- spec/integration/yard/sinclair/options_parser_spec.rb
|
193
216
|
- spec/integration/yard/sinclair_spec.rb
|
217
|
+
- spec/lib/sinclair/config_builder_spec.rb
|
218
|
+
- spec/lib/sinclair/config_factory_spec.rb
|
219
|
+
- spec/lib/sinclair/configurable_spec.rb
|
194
220
|
- spec/lib/sinclair/matchers/add_method_spec.rb
|
195
221
|
- spec/lib/sinclair/matchers/add_method_to_spec.rb
|
196
222
|
- spec/lib/sinclair/matchers_spec.rb
|
@@ -201,11 +227,15 @@ files:
|
|
201
227
|
- spec/support/fixture_helpers.rb
|
202
228
|
- spec/support/models/default_value.rb
|
203
229
|
- spec/support/models/dummy_builder.rb
|
230
|
+
- spec/support/models/dummy_config.rb
|
231
|
+
- spec/support/models/dummy_configurable.rb
|
204
232
|
- spec/support/models/dummy_options_parser.rb
|
205
233
|
- spec/support/models/initial_valuer.rb
|
206
234
|
- spec/support/models/my_builder.rb
|
207
235
|
- spec/support/models/my_class.rb
|
208
236
|
- spec/support/models/my_concern.rb
|
237
|
+
- spec/support/models/my_config.rb
|
238
|
+
- spec/support/models/my_configurable.rb
|
209
239
|
- spec/support/models/my_model.rb
|
210
240
|
- spec/support/models/person.rb
|
211
241
|
- spec/support/models/purchase.rb
|