nxt_init 0.1.4 → 0.1.5
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 +52 -0
- data/.ruby-version +1 -1
- data/Gemfile +4 -0
- data/Gemfile.lock +13 -10
- data/README.md +61 -26
- data/lib/nxt_init.rb +20 -48
- data/lib/nxt_init/not_provided_option.rb +4 -0
- data/lib/nxt_init/option.rb +56 -0
- data/lib/nxt_init/version.rb +1 -1
- data/nxt_init.gemspec +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e476a1496d78ec53eff95f0d9c1ac56938adbd21ff3773ead35cd75142f9e80b
|
4
|
+
data.tar.gz: e4c28f04b5f4bae9b18e63207af4769c312431ec622bbbdf3a3d8c0df9a68a47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53b5060fe7b794a93c28a0cbee74b5192d4355d1d140330990cd3d88e4574da795dc44d7018cbd0f3095c6970f5a7e231348f19bad48c4c25465492162921cec
|
7
|
+
data.tar.gz: 7f8a523bda1983ace6c0920c41e4f5bbfff06efee3225320c86c9a232c6d404034e91fab98d1d05ff5c4de16a70a31374b47ebb7f044454f4f1bda353999790d
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Ruby CircleCI 2.0 configuration file
|
2
|
+
#
|
3
|
+
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
|
4
|
+
#
|
5
|
+
version: 2
|
6
|
+
jobs:
|
7
|
+
build:
|
8
|
+
docker:
|
9
|
+
# specify the version you desire here
|
10
|
+
- image: circleci/ruby:2.6.1-node
|
11
|
+
|
12
|
+
working_directory: ~/repo
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- checkout
|
16
|
+
|
17
|
+
# Download and cache dependencies
|
18
|
+
- restore_cache:
|
19
|
+
keys:
|
20
|
+
- v1-dependencies-{{ checksum "Gemfile.lock" }}
|
21
|
+
|
22
|
+
- run:
|
23
|
+
name: install dependencies
|
24
|
+
command: |
|
25
|
+
bundle install --jobs=4 --retry=3 --path vendor/bundle
|
26
|
+
|
27
|
+
- save_cache:
|
28
|
+
paths:
|
29
|
+
- ./vendor/bundle
|
30
|
+
key: v1-dependencies-{{ checksum "Gemfile.lock" }}
|
31
|
+
|
32
|
+
# run tests!
|
33
|
+
- run:
|
34
|
+
name: run tests
|
35
|
+
command: |
|
36
|
+
mkdir /tmp/test-results
|
37
|
+
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
|
38
|
+
circleci tests split --split-by=timings)"
|
39
|
+
|
40
|
+
bundle exec rspec \
|
41
|
+
--format progress \
|
42
|
+
--format RspecJunitFormatter \
|
43
|
+
--out /tmp/test-results/rspec.xml \
|
44
|
+
--format progress \
|
45
|
+
$TEST_FILES
|
46
|
+
|
47
|
+
# collect reports
|
48
|
+
- store_test_results:
|
49
|
+
path: /tmp/test-results
|
50
|
+
- store_artifacts:
|
51
|
+
path: /tmp/test-results
|
52
|
+
destination: test-results
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.6.
|
1
|
+
2.6.3
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,41 +1,43 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nxt_init (0.1.
|
4
|
+
nxt_init (0.1.5)
|
5
5
|
activesupport
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activesupport (5.2.
|
10
|
+
activesupport (5.2.3)
|
11
11
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
12
12
|
i18n (>= 0.7, < 2)
|
13
13
|
minitest (~> 5.1)
|
14
14
|
tzinfo (~> 1.1)
|
15
15
|
coderay (1.1.2)
|
16
|
-
concurrent-ruby (1.1.
|
16
|
+
concurrent-ruby (1.1.5)
|
17
17
|
diff-lcs (1.3)
|
18
|
-
i18n (1.
|
18
|
+
i18n (1.6.0)
|
19
19
|
concurrent-ruby (~> 1.0)
|
20
20
|
method_source (0.9.2)
|
21
21
|
minitest (5.11.3)
|
22
22
|
pry (0.12.2)
|
23
23
|
coderay (~> 1.1.0)
|
24
24
|
method_source (~> 0.9.0)
|
25
|
-
rake (
|
25
|
+
rake (12.3.2)
|
26
26
|
rspec (3.8.0)
|
27
27
|
rspec-core (~> 3.8.0)
|
28
28
|
rspec-expectations (~> 3.8.0)
|
29
29
|
rspec-mocks (~> 3.8.0)
|
30
|
-
rspec-core (3.8.
|
30
|
+
rspec-core (3.8.2)
|
31
31
|
rspec-support (~> 3.8.0)
|
32
|
-
rspec-expectations (3.8.
|
32
|
+
rspec-expectations (3.8.4)
|
33
33
|
diff-lcs (>= 1.2.0, < 2.0)
|
34
34
|
rspec-support (~> 3.8.0)
|
35
|
-
rspec-mocks (3.8.
|
35
|
+
rspec-mocks (3.8.1)
|
36
36
|
diff-lcs (>= 1.2.0, < 2.0)
|
37
37
|
rspec-support (~> 3.8.0)
|
38
|
-
rspec-support (3.8.
|
38
|
+
rspec-support (3.8.2)
|
39
|
+
rspec_junit_formatter (0.4.1)
|
40
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
39
41
|
thread_safe (0.3.6)
|
40
42
|
tzinfo (1.2.5)
|
41
43
|
thread_safe (~> 0.1)
|
@@ -47,8 +49,9 @@ DEPENDENCIES
|
|
47
49
|
bundler (~> 1.17)
|
48
50
|
nxt_init!
|
49
51
|
pry
|
50
|
-
rake (~>
|
52
|
+
rake (~> 12.3)
|
51
53
|
rspec (~> 3.0)
|
54
|
+
rspec_junit_formatter
|
52
55
|
|
53
56
|
BUNDLED WITH
|
54
57
|
1.17.2
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://circleci.com/gh/nxt-insurance/nxt_init)
|
2
|
+
|
1
3
|
# NxtInit
|
2
4
|
|
3
5
|
Create an initializer that accepts option arguments and define private readers for your
|
@@ -21,39 +23,72 @@ Or install it yourself as:
|
|
21
23
|
|
22
24
|
## Usage
|
23
25
|
|
26
|
+
NxtInit removes some boilerplate. Instead of writing your initializer and (private) attribute readers each and every time like so:
|
27
|
+
|
24
28
|
```ruby
|
25
|
-
class
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
one: one,
|
35
|
-
two: two,
|
36
|
-
three: three,
|
37
|
-
four: four
|
38
|
-
}
|
39
|
-
end
|
29
|
+
class GetSafe
|
30
|
+
def initialize(frontend:, backend:)
|
31
|
+
@frontend = frontend
|
32
|
+
@backend = backend
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :frontend, :backend
|
40
38
|
end
|
39
|
+
```
|
41
40
|
|
42
|
-
|
43
|
-
my_service.call
|
41
|
+
You can instead do the following:
|
44
42
|
|
45
|
-
|
46
|
-
|
43
|
+
```ruby
|
44
|
+
class GetSafe
|
45
|
+
include NxtInit
|
46
|
+
attr_init :frontend, :backend
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
three: nil,
|
51
|
-
four: "This is evaluated on initialize: 2019-02-04 18:10:56 +0100 - means it will not be evaluated multiple times"
|
52
|
-
}
|
49
|
+
GetSafe.new # KeyError (NxtInit attr_init key :frontend was missing at initialization!
|
50
|
+
GetSafe.new(frontend: 'React', backend: 'Ruby on Rails') #<GetSafe:0x00007f81fb8506b8 @frontend="React", @backend="Ruby on Rails">
|
53
51
|
```
|
54
52
|
|
55
|
-
|
56
|
-
|
53
|
+
### Optional arguments and defaults
|
54
|
+
|
55
|
+
In order to provide default values you can simply use the hash syntax to define your defaults.
|
56
|
+
If you want to make an attribute optional, just pass nil as the default argument.
|
57
|
+
If there is no default value and you did not provide one when initializing your class, you will get a KeyError.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class GetSafe
|
61
|
+
include NxtInit
|
62
|
+
attr_init frontend: 'React',
|
63
|
+
backend: -> { 'Ruby on Rails' },
|
64
|
+
middleware: nil
|
65
|
+
end
|
66
|
+
|
67
|
+
GetSafe.new #<GetSafe:0x00007fab608e1918 @frontend="React", @backend="Ruby on Rails", @middleware=nil>
|
68
|
+
```
|
69
|
+
|
70
|
+
### Preprocessors
|
71
|
+
|
72
|
+
If you want to preprocess your attribute somehow, you can define a preprocessor block to which the original attribute will be yielded.
|
73
|
+
Note that you can also call methods in your block if you have some heavier lifting to do.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
class GetSafe
|
77
|
+
include NxtInit
|
78
|
+
attr_init date: -> (date) { date && (date.is_a?(Date) ? date : Date.parse(date)) }
|
79
|
+
end
|
80
|
+
|
81
|
+
GetSafe.new(date: '2020/12/12').send(:date) # will give you the date
|
82
|
+
GetSafe.new(date: nil).send(:date) # would give you nil
|
83
|
+
GetSafe.new # would raise KeyError (NxtInit attr_init key :date was missing at initialization!)
|
84
|
+
```
|
85
|
+
|
86
|
+
Also you can still pass in nil if your block can handle it. If the attribute is not provided on initialization again a KeyError will be raised.
|
87
|
+
|
88
|
+
### Inheritance
|
89
|
+
|
90
|
+
When you inherit from a class that already includes NxtInit you can add further attributes to your subclass and overwrite existing options
|
91
|
+
simply by using attr_init for the same attributes. Check out the specs for more examples.
|
57
92
|
|
58
93
|
## Development
|
59
94
|
|
data/lib/nxt_init.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
require "nxt_init/version"
|
2
|
-
require
|
2
|
+
require "nxt_init/option"
|
3
|
+
require "nxt_init/not_provided_option"
|
4
|
+
require 'active_support/all'
|
3
5
|
|
4
6
|
module NxtInit
|
5
|
-
InvalidOptionError = Class.new(ArgumentError)
|
6
|
-
|
7
7
|
module ClassMethods
|
8
8
|
def attr_init(*args)
|
9
|
-
|
10
|
-
|
11
|
-
self.attr_init_opts
|
12
|
-
|
9
|
+
options_map = build_options_map(*args)
|
10
|
+
|
11
|
+
self.attr_init_opts ||= {}
|
12
|
+
self.attr_init_opts.merge!(options_map)
|
13
|
+
|
14
|
+
define_private_readers(*options_map.keys)
|
13
15
|
end
|
14
16
|
|
15
17
|
attr_accessor :attr_init_opts
|
@@ -17,31 +19,29 @@ module NxtInit
|
|
17
19
|
private
|
18
20
|
|
19
21
|
def inherited(subclass)
|
20
|
-
subclass.attr_init_opts = attr_init_opts.
|
22
|
+
subclass.attr_init_opts = attr_init_opts.deep_dup
|
21
23
|
end
|
22
24
|
|
23
|
-
def define_private_readers(*
|
24
|
-
keys = args.map { |attr| attr.is_a?(Hash) ? attr.keys.first : attr }
|
25
|
+
def define_private_readers(*keys)
|
25
26
|
attr_reader *keys
|
26
27
|
private *keys
|
27
28
|
end
|
28
29
|
|
29
|
-
def
|
30
|
+
def build_options_map(*args)
|
30
31
|
options_hash = *args.extract_options!
|
31
|
-
|
32
|
-
|
32
|
+
options_from_args = args.each_with_object({}) { |key, acc| acc[key] = Option.new(key) }
|
33
|
+
options_from_options = options_hash.each_with_object({}) { |(key, value), acc| acc[key] = Option.new(key, default_value: value) }
|
34
|
+
options_from_args.merge(options_from_options)
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
38
|
module InstanceMethods
|
37
39
|
def initialize(*args, **attrs)
|
38
|
-
option_keys = self.class.send(:attr_init_opts).
|
39
|
-
option.is_a?(Hash) ? option.keys.first : option
|
40
|
-
end
|
40
|
+
option_keys = self.class.send(:attr_init_opts).keys
|
41
41
|
|
42
42
|
attr_init_opts = attrs.slice(*option_keys)
|
43
43
|
other_options = attrs.slice!(*option_keys)
|
44
|
-
# passing **{} is like calling super({}) which does not work when super does not except arguments
|
44
|
+
# passing **{} is like calling super({}) which does not work when super does not except arguments#
|
45
45
|
initialize_attrs_from_options(**attr_init_opts)
|
46
46
|
other_options.empty? ? super(*args) : super(*args, **other_options)
|
47
47
|
end
|
@@ -49,39 +49,11 @@ module NxtInit
|
|
49
49
|
private
|
50
50
|
|
51
51
|
def initialize_attrs_from_options(**attrs)
|
52
|
-
self.class.send(:attr_init_opts).each do |opt|
|
53
|
-
|
54
|
-
|
55
|
-
default_value = opt.values.first
|
56
|
-
given_value = attrs[key]
|
57
|
-
key_missing = !attrs.key?(key)
|
58
|
-
|
59
|
-
if default_value_is_preprocessor?(default_value)
|
60
|
-
value = key_missing ? raise_key_error(key) : instance_exec(given_value, &default_value)
|
61
|
-
else
|
62
|
-
value = given_value || (default_value.respond_to?(:call) ? instance_exec(&default_value) : default_value)
|
63
|
-
end
|
64
|
-
elsif opt.is_a?(Symbol)
|
65
|
-
key = opt
|
66
|
-
value = attrs.fetch(opt) { |k| raise_key_error(k) }
|
67
|
-
else
|
68
|
-
raise InvalidOptionError, "Don't know how to deal with #{opt}"
|
69
|
-
end
|
70
|
-
instance_variable_set("@#{key}", value)
|
52
|
+
self.class.send(:attr_init_opts).each do |_, opt|
|
53
|
+
value = opt.resolve(attrs, target: self)
|
54
|
+
instance_variable_set("@#{opt.key}", value)
|
71
55
|
end
|
72
56
|
end
|
73
|
-
|
74
|
-
def default_value_is_block?(default_value)
|
75
|
-
default_value.respond_to?(:call)
|
76
|
-
end
|
77
|
-
|
78
|
-
def default_value_is_preprocessor?(default_value)
|
79
|
-
default_value_is_block?(default_value) && default_value.arity == 1
|
80
|
-
end
|
81
|
-
|
82
|
-
def raise_key_error(key)
|
83
|
-
raise KeyError, "NxtInit attr_init key :#{key} was missing at initialization!"
|
84
|
-
end
|
85
57
|
end
|
86
58
|
|
87
59
|
def self.included(base)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module NxtInit
|
2
|
+
class Option
|
3
|
+
InvalidOptionError = Class.new(ArgumentError)
|
4
|
+
|
5
|
+
def initialize(key, default_value: NotProvidedOption.new)
|
6
|
+
@key = key
|
7
|
+
@default_value = default_value
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :key, :default_value
|
11
|
+
|
12
|
+
def resolve(attrs, target:)
|
13
|
+
if default_value_was_given?
|
14
|
+
key_missing = !attrs.key?(key)
|
15
|
+
given_value = attrs[key]
|
16
|
+
|
17
|
+
if default_value_is_preprocessor?
|
18
|
+
key_missing ? raise_key_error : target.instance_exec(given_value, &default_value)
|
19
|
+
else
|
20
|
+
# only when the given value was nil we will evaluate the fallback --> false is a valid value
|
21
|
+
if given_value.nil?
|
22
|
+
default_value_is_block? ? target.instance_exec(&default_value) : default_value
|
23
|
+
else
|
24
|
+
given_value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
elsif requires_value?
|
28
|
+
attrs.fetch(key) { |_| raise_key_error }
|
29
|
+
else
|
30
|
+
raise InvalidOptionError, "Don't know how to deal with #{self}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def requires_value?
|
35
|
+
!default_value_was_given?
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_value_is_block?
|
39
|
+
default_value && default_value.respond_to?(:call)
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_value_is_preprocessor?
|
43
|
+
default_value_is_block? && default_value.arity == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_value_was_given?
|
47
|
+
!default_value.is_a?(NotProvidedOption)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def raise_key_error
|
53
|
+
raise KeyError, "NxtInit attr_init key :#{key} was missing at initialization!"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/nxt_init/version.rb
CHANGED
data/nxt_init.gemspec
CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
|
37
37
|
spec.add_dependency "activesupport"
|
38
38
|
spec.add_development_dependency "bundler", "~> 1.17"
|
39
|
-
spec.add_development_dependency "rake", "~>
|
39
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
40
40
|
spec.add_development_dependency "pry"
|
41
41
|
spec.add_development_dependency "rspec", "~> 3.0"
|
42
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nxt_init
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Robecke
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-07-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -46,14 +46,14 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '12.3'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '12.3'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: pry
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,6 +89,7 @@ executables: []
|
|
89
89
|
extensions: []
|
90
90
|
extra_rdoc_files: []
|
91
91
|
files:
|
92
|
+
- ".circleci/config.yml"
|
92
93
|
- ".gitignore"
|
93
94
|
- ".rspec"
|
94
95
|
- ".ruby-version"
|
@@ -101,6 +102,8 @@ files:
|
|
101
102
|
- bin/console
|
102
103
|
- bin/setup
|
103
104
|
- lib/nxt_init.rb
|
105
|
+
- lib/nxt_init/not_provided_option.rb
|
106
|
+
- lib/nxt_init/option.rb
|
104
107
|
- lib/nxt_init/version.rb
|
105
108
|
- nxt_init.gemspec
|
106
109
|
homepage: https://github.com/nxt-insurance
|
@@ -125,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
128
|
- !ruby/object:Gem::Version
|
126
129
|
version: '0'
|
127
130
|
requirements: []
|
128
|
-
rubygems_version: 3.0.
|
131
|
+
rubygems_version: 3.0.3
|
129
132
|
signing_key:
|
130
133
|
specification_version: 4
|
131
134
|
summary: nxt_init allows you to define an initializer that takes option arguments
|