dry-initializer 2.5.0 → 3.0.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 +5 -5
- data/.rubocop.yml +7 -7
- data/.travis.yml +8 -4
- data/CHANGELOG.md +99 -11
- data/Gemfile +1 -1
- data/README.md +0 -1
- data/dry-initializer.gemspec +2 -2
- data/lib/dry/initializer.rb +9 -7
- data/lib/dry/initializer/config.rb +19 -7
- data/lib/dry/initializer/definition.rb +11 -62
- data/lib/dry/initializer/dispatchers.rb +101 -33
- data/lib/dry/initializer/dispatchers/build_nested_type.rb +58 -0
- data/lib/dry/initializer/dispatchers/check_type.rb +43 -0
- data/lib/dry/initializer/dispatchers/prepare_default.rb +40 -0
- data/lib/dry/initializer/dispatchers/prepare_ivar.rb +12 -0
- data/lib/dry/initializer/dispatchers/prepare_optional.rb +13 -0
- data/lib/dry/initializer/dispatchers/prepare_reader.rb +30 -0
- data/lib/dry/initializer/dispatchers/prepare_source.rb +28 -0
- data/lib/dry/initializer/dispatchers/prepare_target.rb +44 -0
- data/lib/dry/initializer/dispatchers/unwrap_type.rb +22 -0
- data/lib/dry/initializer/dispatchers/wrap_type.rb +27 -0
- data/lib/dry/initializer/struct.rb +40 -0
- data/lib/dry/initializer/undefined.rb +2 -0
- data/spec/definition_spec.rb +6 -2
- data/spec/list_type_spec.rb +32 -0
- data/spec/nested_type_spec.rb +44 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/type_constraint_spec.rb +3 -3
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d65124ac530b85023e9152387677a694f2cab063b484ba48133ed8006fc79c2a
|
4
|
+
data.tar.gz: e35526cc7df9ad5271485742f75991e397c06c04af8029003ebdd567974f763c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad262ac79a0191fdaee557a4d1f1b48fbb3c3dc57af0cd639077277dffe52fcecb979db69af0b5f00c803006ceab893d7a057ae085006fc343ef742e2b6f0a2a
|
7
|
+
data.tar.gz: 7b79bd6d05a8a9a7bb239b35cd12629dbd8eda35721916d06b7d04dac7639d361f04958e3a3ace67f5267163c27ae983ad4cb63bbf003efc96cdcf25d9028099
|
data/.rubocop.yml
CHANGED
@@ -10,13 +10,17 @@ AllCops:
|
|
10
10
|
Bundler/DuplicatedGem:
|
11
11
|
Enabled: false
|
12
12
|
|
13
|
+
Naming/FileName:
|
14
|
+
Exclude:
|
15
|
+
- lib/dry-initializer.rb
|
16
|
+
|
13
17
|
Style/CaseEquality:
|
14
18
|
Enabled: false
|
15
19
|
|
16
|
-
Style/
|
20
|
+
Style/ClassAndModuleChildren:
|
17
21
|
Enabled: false
|
18
22
|
|
19
|
-
Style/
|
23
|
+
Style/ClassVars:
|
20
24
|
Enabled: false
|
21
25
|
|
22
26
|
Style/Documentation:
|
@@ -25,10 +29,6 @@ Style/Documentation:
|
|
25
29
|
Style/DoubleNegation:
|
26
30
|
Enabled: false
|
27
31
|
|
28
|
-
Style/FileName:
|
29
|
-
Exclude:
|
30
|
-
- lib/dry-initializer.rb
|
31
|
-
|
32
32
|
Style/Lambda:
|
33
33
|
Exclude:
|
34
34
|
- spec/**/*.rb
|
@@ -36,7 +36,7 @@ Style/Lambda:
|
|
36
36
|
Style/LambdaCall:
|
37
37
|
Enabled: false
|
38
38
|
|
39
|
-
Style/
|
39
|
+
Style/RescueModifier:
|
40
40
|
Exclude:
|
41
41
|
- spec/**/*.rb
|
42
42
|
|
data/.travis.yml
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
---
|
2
2
|
language: ruby
|
3
|
-
sudo: false
|
4
3
|
cache: bundler
|
5
4
|
bundler_args: --without benchmarks tools
|
6
5
|
script:
|
7
6
|
- bundle exec rake spec
|
8
7
|
rvm:
|
9
|
-
- 2.3.
|
10
|
-
- 2.4.
|
8
|
+
- 2.3.8
|
9
|
+
- 2.4.6
|
10
|
+
- 2.5.5
|
11
|
+
- 2.6.2
|
12
|
+
- jruby-9.2.7.0
|
11
13
|
- jruby-9000
|
12
14
|
- rbx-3
|
13
15
|
- ruby-head
|
16
|
+
- truffleruby
|
14
17
|
env:
|
15
18
|
global:
|
16
19
|
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
@@ -19,6 +22,7 @@ matrix:
|
|
19
22
|
- rvm: rbx-3
|
20
23
|
- rvm: ruby-head
|
21
24
|
- rvm: jruby-head
|
25
|
+
- rvm: truffleruby
|
22
26
|
include:
|
23
27
|
- rvm: jruby-head
|
24
|
-
before_install: gem install bundler --no-
|
28
|
+
before_install: gem install bundler --no-document
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,89 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
7
7
|
|
8
|
+
## [3.0.0] [2019-04-14]
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Support of wrapped types/coercers (nepalez)
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
class Test
|
16
|
+
# Wrap type to the array
|
17
|
+
param :foo, [proc(&:to_s)]
|
18
|
+
end
|
19
|
+
|
20
|
+
# And the value will be wrapped as well
|
21
|
+
test = Test.new(42)
|
22
|
+
test.foo # => ["42"]
|
23
|
+
```
|
24
|
+
|
25
|
+
- It works with several layers of nesting (nepalez)
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
class Test
|
29
|
+
# Wrap type to the array
|
30
|
+
param :foo, [[proc(&:to_s)]]
|
31
|
+
end
|
32
|
+
|
33
|
+
# And the value will be wrapped as well
|
34
|
+
test = Test.new(42)
|
35
|
+
test.foo # => [["42"]]
|
36
|
+
```
|
37
|
+
|
38
|
+
- Support of nested types/coercers (nepalez)
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
class Test
|
42
|
+
param :foo do
|
43
|
+
option :bar do
|
44
|
+
option :baz, proc(&:to_s)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
test = Test.new(bar: { "baz" => 42 })
|
50
|
+
test.foo.bar.baz # => "42"
|
51
|
+
```
|
52
|
+
|
53
|
+
- Wrapped/nested combinations are supported as well (nepalez)
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
class Test
|
57
|
+
param :foo, [] do
|
58
|
+
option :bar, proc(&:to_s)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
test = Test.new(bar: 42)
|
63
|
+
test.foo.first.bar # => "42"
|
64
|
+
```
|
65
|
+
|
66
|
+
## [2.7.0] Unreleazed
|
67
|
+
|
68
|
+
### Fixed
|
69
|
+
|
70
|
+
- Roll back master to the state of [2.5.0].
|
71
|
+
|
72
|
+
Somehow distinction between `@default_null` and `@null` variables
|
73
|
+
in the `Dry::Initializer::Builders` broken the `rom` library.
|
74
|
+
|
75
|
+
The version [2.6.0] has been yanked on rubygems, so the master
|
76
|
+
was rolled back to the previous state until the reason for
|
77
|
+
the incompatibility become clear (bjeanes, nepalez)
|
78
|
+
|
79
|
+
## [2.6.0] [2018-09-09] (YANKED)
|
80
|
+
|
81
|
+
## [2.5.0] [2018-08-17]
|
82
|
+
|
83
|
+
### Fixed
|
84
|
+
|
85
|
+
- `nil` coercion (belousovAV)
|
86
|
+
|
87
|
+
When default value is `nil` instead of `Dry::Initializer::UNDEFINED`,
|
88
|
+
the coercion should be applied to any value, including `nil`, because
|
89
|
+
we cannot distinct "undefined" `nil` from the "assigned" `nil` value.
|
90
|
+
|
8
91
|
## [2.4.0] [2018-02-01]
|
9
92
|
|
10
93
|
### Added
|
@@ -367,18 +450,20 @@ and to @gzigzigzeo for persuading me to do this refactoring.
|
|
367
450
|
### Added
|
368
451
|
- enhancement via `Dry::Initializer::Attribute.dispatchers` registry (nepalez)
|
369
452
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
453
|
+
```ruby
|
454
|
+
# Register dispatcher for `:string` option
|
455
|
+
Dry::Initializer::Attribute.dispatchers << ->(string: nil, **op) do
|
456
|
+
string ? op.merge(type: proc(&:to_s)) : op
|
457
|
+
end
|
374
458
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
459
|
+
# Now you can use the `:string` key for `param` and `option`
|
460
|
+
class User
|
461
|
+
extend Dry::Initializer
|
462
|
+
param :name, string: true
|
463
|
+
end
|
380
464
|
|
381
|
-
|
465
|
+
User.new(:Andy).name # => "Andy"
|
466
|
+
```
|
382
467
|
|
383
468
|
### Changed
|
384
469
|
- optimize assignments for performance (nepalez)
|
@@ -757,4 +842,7 @@ First public release
|
|
757
842
|
[2.1.0]: https://github.com/dry-rb/dry-initializer/compare/v2.0.0...v2.1.0
|
758
843
|
[2.2.0]: https://github.com/dry-rb/dry-initializer/compare/v2.1.0...v2.2.0
|
759
844
|
[2.3.0]: https://github.com/dry-rb/dry-initializer/compare/v2.2.0...v2.3.0
|
760
|
-
[2.4.0]: https://github.com/dry-rb/dry-initializer/compare/v2.3.0...v2.4.0
|
845
|
+
[2.4.0]: https://github.com/dry-rb/dry-initializer/compare/v2.3.0...v2.4.0
|
846
|
+
[2.6.0]: https://github.com/dry-rb/dry-initializer/compare/v2.4.0...v2.5.0
|
847
|
+
[2.6.0]: https://github.com/dry-rb/dry-initializer/compare/v2.5.0...v2.6.0
|
848
|
+
[3.0.0]: https://github.com/dry-rb/dry-initializer/compare/v2.5.0...v3.0.0
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
[][gem]
|
4
4
|
[][travis]
|
5
|
-
[][gemnasium]
|
6
5
|
[][codeclimate]
|
7
6
|
[][coveralls]
|
8
7
|
[][inchpages]
|
data/dry-initializer.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = "dry-initializer"
|
3
|
-
gem.version = "
|
3
|
+
gem.version = "3.0.0"
|
4
4
|
gem.author = ["Vladimir Kochnev (marshall-lee)", "Andrew Kozin (nepalez)"]
|
5
5
|
gem.email = "andrew.kozin@gmail.com"
|
6
|
-
gem.homepage = "https://github.com/
|
6
|
+
gem.homepage = "https://github.com/dry-rb/dry-initializer"
|
7
7
|
gem.summary = "DSL for declaring params and options of the initializer"
|
8
8
|
gem.license = "MIT"
|
9
9
|
|
data/lib/dry/initializer.rb
CHANGED
@@ -6,9 +6,7 @@ module Dry
|
|
6
6
|
# DSL for declaring params and options of class initializers
|
7
7
|
#
|
8
8
|
module Initializer
|
9
|
-
|
10
|
-
UNDEFINED = Object.new.freeze
|
11
|
-
|
9
|
+
require_relative "initializer/undefined"
|
12
10
|
require_relative "initializer/dsl"
|
13
11
|
require_relative "initializer/definition"
|
14
12
|
require_relative "initializer/builders"
|
@@ -32,18 +30,20 @@ module Dry
|
|
32
30
|
# @option opts [Boolean] :optional
|
33
31
|
# @option opts [Symbol] :as
|
34
32
|
# @option opts [true, false, :protected, :public, :private] :reader
|
33
|
+
# @yield block with nested definition
|
35
34
|
# @return [self] itself
|
36
|
-
def param(name, type = nil, **opts)
|
37
|
-
dry_initializer.param(name, type,
|
35
|
+
def param(name, type = nil, **opts, &block)
|
36
|
+
dry_initializer.param(name, type, **opts, &block)
|
38
37
|
self
|
39
38
|
end
|
40
39
|
|
41
40
|
# Adds or redefines an option of [#dry_initializer]
|
42
41
|
# @param (see #param)
|
43
42
|
# @option (see #param)
|
43
|
+
# @yield (see #param)
|
44
44
|
# @return (see #param)
|
45
|
-
def option(name, type = nil, **opts)
|
46
|
-
dry_initializer.option(name, type,
|
45
|
+
def option(name, type = nil, **opts, &block)
|
46
|
+
dry_initializer.option(name, type, **opts, &block)
|
47
47
|
self
|
48
48
|
end
|
49
49
|
|
@@ -55,5 +55,7 @@ module Dry
|
|
55
55
|
klass.send(:instance_variable_set, :@dry_initializer, config)
|
56
56
|
dry_initializer.children << config
|
57
57
|
end
|
58
|
+
|
59
|
+
require_relative "initializer/struct"
|
58
60
|
end
|
59
61
|
end
|
@@ -57,8 +57,8 @@ module Dry::Initializer
|
|
57
57
|
# @option opts [Symbol] :as
|
58
58
|
# @option opts [true, false, :protected, :public, :private] :reader
|
59
59
|
# @return [self] itself
|
60
|
-
def param(name, type = nil, **opts)
|
61
|
-
add_definition(false, name, type, opts)
|
60
|
+
def param(name, type = nil, **opts, &block)
|
61
|
+
add_definition(false, name, type, block, opts)
|
62
62
|
end
|
63
63
|
|
64
64
|
# Adds or redefines an option of [#dry_initializer]
|
@@ -67,8 +67,8 @@ module Dry::Initializer
|
|
67
67
|
# @option (see #param)
|
68
68
|
# @return (see #param)
|
69
69
|
#
|
70
|
-
def option(name, type = nil, **opts)
|
71
|
-
add_definition(true, name, type, opts)
|
70
|
+
def option(name, type = nil, **opts, &block)
|
71
|
+
add_definition(true, name, type, block, opts)
|
72
72
|
end
|
73
73
|
|
74
74
|
# The hash of public attributes for an instance of the [#extended_class]
|
@@ -133,13 +133,25 @@ module Dry::Initializer
|
|
133
133
|
finalize
|
134
134
|
end
|
135
135
|
|
136
|
-
|
137
|
-
|
136
|
+
# rubocop: disable Metrics/MethodLength
|
137
|
+
def add_definition(option, name, type, block, **opts)
|
138
|
+
opts = {
|
139
|
+
parent: extended_class,
|
140
|
+
option: option,
|
141
|
+
null: null,
|
142
|
+
source: name,
|
143
|
+
type: type,
|
144
|
+
block: block,
|
145
|
+
**opts,
|
146
|
+
}
|
147
|
+
|
148
|
+
options = Dispatchers.call(opts)
|
149
|
+
definition = Definition.new(options)
|
138
150
|
definitions[definition.source] = definition
|
139
151
|
finalize
|
140
|
-
|
141
152
|
mixin.class_eval definition.code
|
142
153
|
end
|
154
|
+
# rubocop: enable Metrics/MethodLength
|
143
155
|
|
144
156
|
def final_definitions
|
145
157
|
parent_definitions = Hash(parent&.definitions&.dup)
|
@@ -49,68 +49,17 @@ module Dry::Initializer
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
-
def initialize(
|
53
|
-
@option =
|
54
|
-
@null = null
|
55
|
-
@source = source
|
56
|
-
@target =
|
57
|
-
@ivar =
|
58
|
-
@type =
|
59
|
-
@reader =
|
60
|
-
@default =
|
61
|
-
@optional = options
|
62
|
-
@desc = options[:desc]
|
52
|
+
def initialize(**options)
|
53
|
+
@option = options[:option]
|
54
|
+
@null = options[:null]
|
55
|
+
@source = options[:source]
|
56
|
+
@target = options[:target]
|
57
|
+
@ivar = "@#{@target}"
|
58
|
+
@type = options[:type]
|
59
|
+
@reader = options[:reader]
|
60
|
+
@default = options[:default]
|
61
|
+
@optional = options[:optional]
|
62
|
+
@desc = options[:desc]
|
63
63
|
end
|
64
|
-
|
65
|
-
def check_source(value)
|
66
|
-
if RESERVED.include? value
|
67
|
-
raise ArgumentError, "Name #{value} is reserved by dry-initializer gem"
|
68
|
-
end
|
69
|
-
|
70
|
-
unless option || value[ATTRIBUTE]
|
71
|
-
raise ArgumentError, "Invalid parameter name :'#{value}'"
|
72
|
-
end
|
73
|
-
|
74
|
-
value
|
75
|
-
end
|
76
|
-
|
77
|
-
def check_target(value)
|
78
|
-
return value if value[ATTRIBUTE]
|
79
|
-
raise ArgumentError, "Invalid variable name :'#{value}'"
|
80
|
-
end
|
81
|
-
|
82
|
-
def check_type(value)
|
83
|
-
return if value.nil?
|
84
|
-
arity = value.arity if value.is_a? Proc
|
85
|
-
arity ||= value.method(:call).arity if value.respond_to? :call
|
86
|
-
return value if [1, 2].include? arity.to_i.abs
|
87
|
-
raise TypeError,
|
88
|
-
"type of #{inspect} should respond to #call with 1..2 arguments"
|
89
|
-
end
|
90
|
-
|
91
|
-
def check_default(value)
|
92
|
-
return if value.nil?
|
93
|
-
return value if value.is_a?(Proc) && value.arity < 1
|
94
|
-
raise TypeError,
|
95
|
-
"default value of #{inspect} should be a proc without params"
|
96
|
-
end
|
97
|
-
|
98
|
-
def prepare_reader(value)
|
99
|
-
case value.to_s
|
100
|
-
when "", "false" then false
|
101
|
-
when "private" then :private
|
102
|
-
when "protected" then :protected
|
103
|
-
else :public
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
ATTRIBUTE = /\A\w+\z/
|
108
|
-
RESERVED = %i[
|
109
|
-
__dry_initializer_options__
|
110
|
-
__dry_initializer_config__
|
111
|
-
__dry_initializer_value__
|
112
|
-
__dry_initializer_definition__
|
113
|
-
__dry_initializer_initializer__
|
114
|
-
].freeze
|
115
64
|
end
|
116
65
|
end
|
@@ -1,44 +1,112 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
#
|
2
|
+
# The module is responsible for __normalizing__ arguments
|
3
|
+
# of `.param` and `.option`.
|
4
|
+
#
|
5
|
+
# What the module does is convert the source list of arguments
|
6
|
+
# into the standard set of options:
|
7
|
+
# - `:option` -- whether an argument is an option (or param)
|
8
|
+
# - `:source` -- the name of source option
|
9
|
+
# - `:target` -- the target name of the reader
|
10
|
+
# - `:reader` -- if the reader's privacy (:public, :protected, :private, nil)
|
11
|
+
# - `:ivar` -- the target nane of the variable
|
12
|
+
# - `:type` -- the callable coercer of the source value
|
13
|
+
# - `:optional` -- if the argument is optional
|
14
|
+
# - `:default` -- the proc returning the default value of the source value
|
15
|
+
# - `:null` -- the value to be set to unassigned optional argument
|
16
|
+
#
|
17
|
+
# It is this set is used to build [Dry::Initializer::Definition].
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# # from `option :foo, [], as: :bar, optional: :true
|
21
|
+
# input = { name: :foo, as: :bar, type: [], optional: true }
|
22
|
+
#
|
23
|
+
# Dry::Initializer::Dispatcher.call(input)
|
24
|
+
# # => {
|
25
|
+
# # source: "foo",
|
26
|
+
# # target: "bar",
|
27
|
+
# # reader: :public,
|
28
|
+
# # ivar: "@bar",
|
29
|
+
# # type: ->(v) { Array(v) } }, # simplified for brevity
|
30
|
+
# # optional: true,
|
31
|
+
# # default: -> { Dry::Initializer::UNDEFINED },
|
32
|
+
# # }
|
33
|
+
#
|
34
|
+
# # Settings
|
35
|
+
#
|
36
|
+
# The module uses global setting `null` to define what value
|
37
|
+
# should be set to variables that kept unassigned. By default it
|
38
|
+
# uses `Dry::Initializer::UNDEFINED`
|
39
|
+
#
|
40
|
+
# # Syntax Extensions
|
41
|
+
#
|
42
|
+
# The module supports syntax extensions. You can add any number
|
43
|
+
# of custom dispatchers __on top__ of the stack of default dispatchers.
|
44
|
+
# Every dispatcher should be a callable object that takes
|
45
|
+
# the source set of options and converts it to another set of options.
|
46
|
+
#
|
47
|
+
# @example Add special dispatcher
|
48
|
+
#
|
49
|
+
# # Define a dispatcher for key :integer
|
50
|
+
# dispatcher = proc do |integer: false, **opts|
|
51
|
+
# opts.merge(type: proc(&:to_i)) if integer
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# # Register a dispatcher
|
55
|
+
# Dry::Initializer::Dispatchers << dispatcher
|
56
|
+
#
|
57
|
+
# # Now you can use option `integer: true` instead of `type: proc(&:to_i)`
|
58
|
+
# class Foo
|
59
|
+
# extend Dry::Initializer
|
60
|
+
# param :id, integer: true
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
module Dry::Initializer::Dispatchers
|
64
|
+
extend self
|
65
|
+
|
66
|
+
# @!attribute [rw] null Defines a value to be set to unassigned attributes
|
67
|
+
# @return [Object]
|
68
|
+
attr_accessor :null
|
69
|
+
|
6
70
|
#
|
7
|
-
#
|
8
|
-
# the resulting hash so that you can send additional keys to the helpers.
|
71
|
+
# Registers a new dispatcher
|
9
72
|
#
|
10
|
-
# @
|
73
|
+
# @param [#call] dispatcher
|
74
|
+
# @return [self] itself
|
11
75
|
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
76
|
+
def <<(dispatcher)
|
77
|
+
@pipeline = [dispatcher] + pipeline
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
16
81
|
#
|
17
|
-
#
|
18
|
-
# Dry::Initializer::Dispatchers << dispatcher
|
82
|
+
# Normalizes the source set of options
|
19
83
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# extend Dry::Initializer
|
23
|
-
# param :id, integer: true
|
24
|
-
# end
|
84
|
+
# @param [Hash<Symbol, Object>] options
|
85
|
+
# @return [Hash<Symbol, Objct>] normalized set of options
|
25
86
|
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
self
|
31
|
-
end
|
87
|
+
def call(**options)
|
88
|
+
options = { null: null }.merge(options)
|
89
|
+
pipeline.reduce(options) { |opts, dispatcher| dispatcher.call(opts) }
|
90
|
+
end
|
32
91
|
|
33
|
-
|
34
|
-
list.inject(options) { |opts, item| item.call(opts) }
|
35
|
-
end
|
92
|
+
private
|
36
93
|
|
37
|
-
|
94
|
+
require_relative "dispatchers/build_nested_type"
|
95
|
+
require_relative "dispatchers/check_type"
|
96
|
+
require_relative "dispatchers/prepare_default"
|
97
|
+
require_relative "dispatchers/prepare_ivar"
|
98
|
+
require_relative "dispatchers/prepare_optional"
|
99
|
+
require_relative "dispatchers/prepare_reader"
|
100
|
+
require_relative "dispatchers/prepare_source"
|
101
|
+
require_relative "dispatchers/prepare_target"
|
102
|
+
require_relative "dispatchers/unwrap_type"
|
103
|
+
require_relative "dispatchers/wrap_type"
|
38
104
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
105
|
+
def pipeline
|
106
|
+
@pipeline ||= [
|
107
|
+
PrepareSource, PrepareTarget, PrepareIvar, PrepareReader,
|
108
|
+
PrepareDefault, PrepareOptional,
|
109
|
+
UnwrapType, CheckType, BuildNestedType, WrapType
|
110
|
+
]
|
43
111
|
end
|
44
112
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# Prepare nested data type from a block
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# option :foo do
|
6
|
+
# option :bar
|
7
|
+
# option :qux
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
module Dry::Initializer::Dispatchers::BuildNestedType
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# rubocop: disable Metrics/ParameterLists
|
14
|
+
def call(parent:, source:, target:, type: nil, block: nil, **options)
|
15
|
+
check_certainty!(source, type, block)
|
16
|
+
check_name!(target)
|
17
|
+
type ||= build_nested_type(parent, target, block)
|
18
|
+
{ parent: parent, source: source, target: target, type: type, **options }
|
19
|
+
end
|
20
|
+
# rubocop: enable Metrics/ParameterLists
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def check_certainty!(source, type, block)
|
25
|
+
return unless type
|
26
|
+
return unless block
|
27
|
+
|
28
|
+
raise ArgumentError, <<~MESSAGE
|
29
|
+
You should define coercer of values of argument '#{source}'
|
30
|
+
either though the parameter/option, or via nested block, but not the both.
|
31
|
+
MESSAGE
|
32
|
+
end
|
33
|
+
|
34
|
+
def check_name!(name)
|
35
|
+
return unless name[/^_|__|_$/]
|
36
|
+
|
37
|
+
raise ArgumentError, <<~MESSAGE
|
38
|
+
The name of the argument '#{name}' cannot be used for nested struct.
|
39
|
+
A proper name can use underscores _ to divide alphanumeric parts only.
|
40
|
+
MESSAGE
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_nested_type(parent, name, block)
|
44
|
+
return unless block
|
45
|
+
|
46
|
+
klass_name = full_name(parent, name)
|
47
|
+
build_struct(klass_name, block)
|
48
|
+
end
|
49
|
+
|
50
|
+
def full_name(parent, name)
|
51
|
+
"::#{parent.name}::#{name.to_s.split("_").compact.map(&:capitalize).join}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_struct(klass_name, block)
|
55
|
+
eval "class #{klass_name} < Dry::Initializer::Struct; end"
|
56
|
+
const_get(klass_name).tap { |klass| klass.class_eval(&block) }
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Checks whether an unwrapped type is valid
|
3
|
+
#
|
4
|
+
module Dry::Initializer::Dispatchers::CheckType
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def call(source:, type: nil, wrap: 0, **options)
|
8
|
+
check_if_callable! source, type
|
9
|
+
check_arity! source, type, wrap
|
10
|
+
|
11
|
+
{ source: source, type: type, wrap: wrap, **options }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def check_if_callable!(source, type)
|
17
|
+
return if type.nil?
|
18
|
+
return if type.respond_to?(:call)
|
19
|
+
|
20
|
+
raise ArgumentError,
|
21
|
+
"The type of the argument '#{source}' should be callable"
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_arity!(_source, type, wrap)
|
25
|
+
return if type.nil?
|
26
|
+
return if wrap.zero?
|
27
|
+
return if type.method(:call).arity.abs == 1
|
28
|
+
|
29
|
+
raise ArgumentError, <<~MESSAGE
|
30
|
+
The dry_intitializer supports wrapped types with one argument only.
|
31
|
+
You cannot use array types with element coercers having several arguments.
|
32
|
+
|
33
|
+
For example, this definitions are correct:
|
34
|
+
option :foo, [proc(&:to_s)]
|
35
|
+
option :bar, type: [[]]
|
36
|
+
option :baz, ->(a, b) { [a, b] }
|
37
|
+
|
38
|
+
While this is not:
|
39
|
+
option :foo, [->(a, b) { [a, b] }]
|
40
|
+
MESSAGE
|
41
|
+
end
|
42
|
+
# rubocop: enable Metrics/MethodLength
|
43
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#
|
2
|
+
# Prepares the `:default` option
|
3
|
+
#
|
4
|
+
# It must respond to `.call` without arguments
|
5
|
+
#
|
6
|
+
module Dry::Initializer::Dispatchers::PrepareDefault
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def call(default: nil, optional: nil, **options)
|
10
|
+
default = callable! default
|
11
|
+
check_arity! default
|
12
|
+
|
13
|
+
{ default: default, optional: (optional | default), **options }
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def callable!(default)
|
19
|
+
return unless default
|
20
|
+
return default if default.respond_to?(:call)
|
21
|
+
return callable(default.to_proc) if default.respond_to?(:to_proc)
|
22
|
+
|
23
|
+
invalid!(default)
|
24
|
+
end
|
25
|
+
|
26
|
+
def check_arity!(default)
|
27
|
+
return unless default
|
28
|
+
|
29
|
+
arity = default.method(:call).arity.to_i
|
30
|
+
return unless arity.positive?
|
31
|
+
|
32
|
+
invalid!(default)
|
33
|
+
end
|
34
|
+
|
35
|
+
def invalid!(default)
|
36
|
+
raise TypeError, "The #{default.inspect} should be" \
|
37
|
+
" either convertable to proc with no arguments," \
|
38
|
+
" or respond to #call without arguments."
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#
|
2
|
+
# Prepares the variable name of a parameter or an option.
|
3
|
+
#
|
4
|
+
module Dry::Initializer::Dispatchers::PrepareIvar
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def call(target:, **options)
|
8
|
+
ivar = "@#{target}".delete("?").to_sym
|
9
|
+
|
10
|
+
{ target: target, ivar: ivar, **options }
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#
|
2
|
+
# Defines whether an argument is optional
|
3
|
+
#
|
4
|
+
module Dry::Initializer::Dispatchers::PrepareOptional
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def call(optional: nil, default: nil, required: nil, **options)
|
8
|
+
optional ||= default
|
9
|
+
optional &&= !required
|
10
|
+
|
11
|
+
{ optional: !!optional, default: default, **options }
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#
|
2
|
+
# Checks the reader privacy
|
3
|
+
#
|
4
|
+
module Dry::Initializer::Dispatchers::PrepareReader
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def call(target: nil, reader: :public, **options)
|
8
|
+
reader = case reader.to_s
|
9
|
+
when "false", "" then nil
|
10
|
+
when "true" then :public
|
11
|
+
when "public", "private", "protected" then reader.to_sym
|
12
|
+
else invalid_reader!(target, reader)
|
13
|
+
end
|
14
|
+
|
15
|
+
{ target: target, reader: reader, **options }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def invalid_reader!(target, _reader)
|
21
|
+
raise ArgumentError, <<~MESSAGE
|
22
|
+
Invalid setting for the ##{target} reader's privacy.
|
23
|
+
Use the one of the following values for the `:reader` option:
|
24
|
+
- 'public' (true) for the public reader (default)
|
25
|
+
- 'private' for the private reader
|
26
|
+
- 'protected' for the protected reader
|
27
|
+
- nil (false) if no reader should be defined
|
28
|
+
MESSAGE
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#
|
2
|
+
# The dispatcher verifies a correctness of the source name
|
3
|
+
# of param or option, taken as a `:source` option.
|
4
|
+
#
|
5
|
+
# We allow any stringified name for the source.
|
6
|
+
# For example, this syntax is correct because we accept any key
|
7
|
+
# in the original hash of arguments, but give them proper names:
|
8
|
+
#
|
9
|
+
# ```ruby
|
10
|
+
# class Foo
|
11
|
+
# extend Dry::Initializer
|
12
|
+
#
|
13
|
+
# option "", as: :first
|
14
|
+
# option 1, as: :second
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# foo = Foo.new("": 42, 1: 666)
|
18
|
+
# foo.first # => 42
|
19
|
+
# foo.second # => 666
|
20
|
+
# ```
|
21
|
+
#
|
22
|
+
module Dry::Initializer::Dispatchers::PrepareSource
|
23
|
+
module_function
|
24
|
+
|
25
|
+
def call(source:, **options)
|
26
|
+
{ source: source.to_s.to_sym, **options }
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#
|
2
|
+
# Prepares the target name of a parameter or an option.
|
3
|
+
#
|
4
|
+
# Unlike source, the target must satisfy requirements for Ruby variable names.
|
5
|
+
# It also shouldn't be in conflict with names used by the gem.
|
6
|
+
#
|
7
|
+
module Dry::Initializer::Dispatchers::PrepareTarget
|
8
|
+
extend self
|
9
|
+
|
10
|
+
# List of variable names reserved by the gem
|
11
|
+
RESERVED = %i[
|
12
|
+
__dry_initializer_options__
|
13
|
+
__dry_initializer_config__
|
14
|
+
__dry_initializer_value__
|
15
|
+
__dry_initializer_definition__
|
16
|
+
__dry_initializer_initializer__
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
def call(source:, target: nil, as: nil, **options)
|
20
|
+
target ||= as || source
|
21
|
+
target = target.to_s.to_sym.downcase
|
22
|
+
|
23
|
+
check_ruby_name!(target)
|
24
|
+
check_reserved_names!(target)
|
25
|
+
|
26
|
+
{ source: source, target: target, **options }
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def check_ruby_name!(target)
|
32
|
+
return if target[/\A[[:alpha:]_][[:alnum:]_]*\??\z/u]
|
33
|
+
|
34
|
+
raise ArgumentError,
|
35
|
+
"The name `#{target}` is not allowed for Ruby methods"
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_reserved_names!(target)
|
39
|
+
return unless RESERVED.include?(target)
|
40
|
+
|
41
|
+
raise ArgumentError,
|
42
|
+
"The method name `#{target}` is reserved by the dry-initializer gem"
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# Looks at the `:type` option and counts how many nested arrays
|
3
|
+
# it contains around either nil or a callable value.
|
4
|
+
#
|
5
|
+
# The counted number is preserved in the `:wrap` virtual option
|
6
|
+
# used by the [WrapType] dispatcher.
|
7
|
+
#
|
8
|
+
module Dry::Initializer::Dispatchers::UnwrapType
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def call(type: nil, wrap: 0, **options)
|
12
|
+
type, wrap = unwrap(type, 0)
|
13
|
+
|
14
|
+
{ type: type, wrap: wrap, **options }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def unwrap(type, count)
|
20
|
+
type.is_a?(Array) ? unwrap(type.first, count + 1) : [type, count]
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#
|
2
|
+
# Takes `:type` and `:wrap` to construct the final value coercer
|
3
|
+
#
|
4
|
+
module Dry::Initializer::Dispatchers::WrapType
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def call(type: nil, wrap: 0, **options)
|
8
|
+
{ type: wrapped_type(type, wrap), **options }
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def wrapped_type(type, count)
|
14
|
+
return type if count.zero?
|
15
|
+
|
16
|
+
->(value) { wrap_value(value, count, type) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def wrap_value(value, count, type)
|
20
|
+
if count.zero?
|
21
|
+
type ? type.call(value) : value
|
22
|
+
else
|
23
|
+
return [wrap_value(value, count - 1, type)] unless value.is_a?(Array)
|
24
|
+
value.map { |item| wrap_value(item, count - 1, type) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#
|
2
|
+
# The nested structure that takes nested hashes with indifferent access
|
3
|
+
#
|
4
|
+
class Dry::Initializer::Struct
|
5
|
+
extend Dry::Initializer
|
6
|
+
|
7
|
+
class << self
|
8
|
+
undef_method :param
|
9
|
+
|
10
|
+
def new(options)
|
11
|
+
super Hash(options).transform_keys(&:to_sym)
|
12
|
+
end
|
13
|
+
alias call new
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents event data as a nested hash with deeply stringified keys
|
18
|
+
# @return [Hash<String, ...>]
|
19
|
+
#
|
20
|
+
def to_h
|
21
|
+
self
|
22
|
+
.class
|
23
|
+
.dry_initializer
|
24
|
+
.attributes(self)
|
25
|
+
.transform_values { |v| __hashify(v) }
|
26
|
+
.stringify_keys
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def __hashify(value)
|
32
|
+
case value
|
33
|
+
when Hash
|
34
|
+
value.each_with_object({}) { |(k, v), obj| obj[k.to_s] = __hashify(v) }
|
35
|
+
when Array then value.map { |v| __hashify(v) }
|
36
|
+
when Dry::Initializer::Struct then value.to_h
|
37
|
+
else value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/definition_spec.rb
CHANGED
@@ -22,7 +22,9 @@ describe "definition" do
|
|
22
22
|
[definition.source, definition.options]
|
23
23
|
end
|
24
24
|
|
25
|
-
expect(params).to eq [
|
25
|
+
expect(params).to eq [
|
26
|
+
[:foo, { as: :foo, reader: :public, optional: false }]
|
27
|
+
]
|
26
28
|
end
|
27
29
|
|
28
30
|
it "preservers definition options" do
|
@@ -30,7 +32,9 @@ describe "definition" do
|
|
30
32
|
[definition.source, definition.options]
|
31
33
|
end
|
32
34
|
|
33
|
-
expect(options).to eq [
|
35
|
+
expect(options).to eq [
|
36
|
+
[:bar, { as: :bar, reader: :public, optional: false }]
|
37
|
+
]
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "dry-types"
|
2
|
+
|
3
|
+
describe "list type argument" do
|
4
|
+
before do
|
5
|
+
class Test::Foo
|
6
|
+
extend Dry::Initializer
|
7
|
+
param :foo, [proc(&:to_s)]
|
8
|
+
option :bar, [Dry::Types["strict.string"]]
|
9
|
+
option :baz, []
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "with single items" do
|
14
|
+
subject { Test::Foo.new(1, bar: "2", baz: { qux: :QUX }) }
|
15
|
+
|
16
|
+
it "coerces and wraps them to arrays" do
|
17
|
+
expect(subject.foo).to eq %w[1]
|
18
|
+
expect(subject.bar).to eq %w[2]
|
19
|
+
expect(subject.baz).to eq [{ qux: :QUX }]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with arrays" do
|
24
|
+
subject { Test::Foo.new([1], bar: %w[2], baz: [{ qux: :QUX }]) }
|
25
|
+
|
26
|
+
it "coerces elements" do
|
27
|
+
expect(subject.foo).to eq %w[1]
|
28
|
+
expect(subject.bar).to eq %w[2]
|
29
|
+
expect(subject.baz).to eq [{ qux: :QUX }]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe "nested type argument" do
|
2
|
+
subject { Test::Xyz.new("bar" => { "baz" => 42 }) }
|
3
|
+
|
4
|
+
context "with nested definition only" do
|
5
|
+
before do
|
6
|
+
class Test::Xyz
|
7
|
+
extend Dry::Initializer
|
8
|
+
|
9
|
+
param :foo, as: :x do
|
10
|
+
option :bar, as: :y do
|
11
|
+
option :baz, proc(&:to_s), as: :z
|
12
|
+
option :qux, as: :w, optional: true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "builds the type" do
|
19
|
+
expect(subject.x.y.z).to eq "42"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with nested and wrapped definitions" do
|
24
|
+
before do
|
25
|
+
class Test::Xyz
|
26
|
+
extend Dry::Initializer
|
27
|
+
|
28
|
+
param :foo, [], as: :x do
|
29
|
+
option :bar, as: :y do
|
30
|
+
option :baz, proc(&:to_s), as: :z
|
31
|
+
option :qux, as: :w, optional: true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "builds the type" do
|
38
|
+
x = subject.x
|
39
|
+
expect(x).to be_instance_of Array
|
40
|
+
|
41
|
+
expect(x.first.y.z).to eq "42"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -42,7 +42,7 @@ describe "type constraint" do
|
|
42
42
|
context "in case of mismatch" do
|
43
43
|
subject { Test::Foo.new 1 }
|
44
44
|
|
45
|
-
it "raises
|
45
|
+
it "raises ArgumentError" do
|
46
46
|
expect { subject }.to raise_error TypeError, /1/
|
47
47
|
end
|
48
48
|
end
|
@@ -66,13 +66,13 @@ describe "type constraint" do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
context "by invalid constraint" do
|
69
|
-
it "raises
|
69
|
+
it "raises ArgumentError" do
|
70
70
|
expect do
|
71
71
|
class Test::Foo
|
72
72
|
extend Dry::Initializer
|
73
73
|
param :foo, type: String
|
74
74
|
end
|
75
|
-
end.to raise_error(
|
75
|
+
end.to raise_error(ArgumentError)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-initializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Kochnev (marshall-lee)
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-04-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -103,10 +103,22 @@ files:
|
|
103
103
|
- lib/dry/initializer/config.rb
|
104
104
|
- lib/dry/initializer/definition.rb
|
105
105
|
- lib/dry/initializer/dispatchers.rb
|
106
|
+
- lib/dry/initializer/dispatchers/build_nested_type.rb
|
107
|
+
- lib/dry/initializer/dispatchers/check_type.rb
|
108
|
+
- lib/dry/initializer/dispatchers/prepare_default.rb
|
109
|
+
- lib/dry/initializer/dispatchers/prepare_ivar.rb
|
110
|
+
- lib/dry/initializer/dispatchers/prepare_optional.rb
|
111
|
+
- lib/dry/initializer/dispatchers/prepare_reader.rb
|
112
|
+
- lib/dry/initializer/dispatchers/prepare_source.rb
|
113
|
+
- lib/dry/initializer/dispatchers/prepare_target.rb
|
114
|
+
- lib/dry/initializer/dispatchers/unwrap_type.rb
|
115
|
+
- lib/dry/initializer/dispatchers/wrap_type.rb
|
106
116
|
- lib/dry/initializer/dsl.rb
|
107
117
|
- lib/dry/initializer/mixin.rb
|
108
118
|
- lib/dry/initializer/mixin/local.rb
|
109
119
|
- lib/dry/initializer/mixin/root.rb
|
120
|
+
- lib/dry/initializer/struct.rb
|
121
|
+
- lib/dry/initializer/undefined.rb
|
110
122
|
- lib/tasks/benchmark.rake
|
111
123
|
- lib/tasks/profile.rake
|
112
124
|
- spec/attributes_spec.rb
|
@@ -116,7 +128,9 @@ files:
|
|
116
128
|
- spec/default_values_spec.rb
|
117
129
|
- spec/definition_spec.rb
|
118
130
|
- spec/invalid_default_spec.rb
|
131
|
+
- spec/list_type_spec.rb
|
119
132
|
- spec/missed_default_spec.rb
|
133
|
+
- spec/nested_type_spec.rb
|
120
134
|
- spec/optional_spec.rb
|
121
135
|
- spec/options_tolerance_spec.rb
|
122
136
|
- spec/public_attributes_utility_spec.rb
|
@@ -128,7 +142,7 @@ files:
|
|
128
142
|
- spec/type_argument_spec.rb
|
129
143
|
- spec/type_constraint_spec.rb
|
130
144
|
- spec/value_coercion_via_dry_types_spec.rb
|
131
|
-
homepage: https://github.com/
|
145
|
+
homepage: https://github.com/dry-rb/dry-initializer
|
132
146
|
licenses:
|
133
147
|
- MIT
|
134
148
|
metadata: {}
|
@@ -147,8 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
161
|
- !ruby/object:Gem::Version
|
148
162
|
version: '0'
|
149
163
|
requirements: []
|
150
|
-
|
151
|
-
rubygems_version: 2.6.14
|
164
|
+
rubygems_version: 3.0.3
|
152
165
|
signing_key:
|
153
166
|
specification_version: 4
|
154
167
|
summary: DSL for declaring params and options of the initializer
|
@@ -160,7 +173,9 @@ test_files:
|
|
160
173
|
- spec/default_values_spec.rb
|
161
174
|
- spec/definition_spec.rb
|
162
175
|
- spec/invalid_default_spec.rb
|
176
|
+
- spec/list_type_spec.rb
|
163
177
|
- spec/missed_default_spec.rb
|
178
|
+
- spec/nested_type_spec.rb
|
164
179
|
- spec/optional_spec.rb
|
165
180
|
- spec/options_tolerance_spec.rb
|
166
181
|
- spec/public_attributes_utility_spec.rb
|