dry-initializer 3.0.2 → 3.1.1
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/CHANGELOG.md +260 -241
- data/LICENSE +1 -1
- data/README.md +18 -77
- data/dry-initializer.gemspec +34 -19
- data/lib/dry/initializer/builders/attribute.rb +78 -69
- data/lib/dry/initializer/builders/initializer.rb +56 -58
- data/lib/dry/initializer/builders/reader.rb +55 -47
- data/lib/dry/initializer/builders/signature.rb +29 -23
- data/lib/dry/initializer/builders.rb +9 -5
- data/lib/dry/initializer/config.rb +162 -158
- data/lib/dry/initializer/definition.rb +58 -54
- data/lib/dry/initializer/dispatchers/build_nested_type.rb +54 -40
- data/lib/dry/initializer/dispatchers/check_type.rb +45 -39
- data/lib/dry/initializer/dispatchers/prepare_default.rb +32 -25
- data/lib/dry/initializer/dispatchers/prepare_ivar.rb +13 -6
- data/lib/dry/initializer/dispatchers/prepare_optional.rb +14 -7
- data/lib/dry/initializer/dispatchers/prepare_reader.rb +29 -22
- data/lib/dry/initializer/dispatchers/prepare_source.rb +12 -5
- data/lib/dry/initializer/dispatchers/prepare_target.rb +44 -37
- data/lib/dry/initializer/dispatchers/unwrap_type.rb +21 -10
- data/lib/dry/initializer/dispatchers/wrap_type.rb +25 -17
- data/lib/dry/initializer/dispatchers.rb +48 -43
- data/lib/dry/initializer/dsl.rb +42 -34
- data/lib/dry/initializer/mixin/local.rb +19 -13
- data/lib/dry/initializer/mixin/root.rb +12 -7
- data/lib/dry/initializer/mixin.rb +17 -12
- data/lib/dry/initializer/struct.rb +34 -29
- data/lib/dry/initializer/undefined.rb +7 -1
- data/lib/dry/initializer/version.rb +7 -0
- data/lib/dry/initializer.rb +2 -0
- data/lib/dry-initializer.rb +2 -0
- data/lib/tasks/benchmark.rake +2 -0
- data/lib/tasks/profile.rake +4 -0
- metadata +25 -125
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -34
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/custom_ci.yml +0 -74
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -34
- data/.gitignore +0 -12
- data/.rspec +0 -4
- data/.rubocop.yml +0 -89
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -38
- data/Guardfile +0 -5
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -8
- data/benchmarks/compare_several_defaults.rb +0 -82
- data/benchmarks/plain_options.rb +0 -63
- data/benchmarks/plain_params.rb +0 -84
- data/benchmarks/with_coercion.rb +0 -71
- data/benchmarks/with_defaults.rb +0 -66
- data/benchmarks/with_defaults_and_coercion.rb +0 -59
- data/docsite/source/attributes.html.md +0 -106
- data/docsite/source/container-version.html.md +0 -39
- data/docsite/source/index.html.md +0 -43
- data/docsite/source/inheritance.html.md +0 -43
- data/docsite/source/optionals-and-defaults.html.md +0 -130
- data/docsite/source/options-tolerance.html.md +0 -27
- data/docsite/source/params-and-options.html.md +0 -74
- data/docsite/source/rails-support.html.md +0 -101
- data/docsite/source/readers.html.md +0 -43
- data/docsite/source/skip-undefined.html.md +0 -59
- data/docsite/source/type-constraints.html.md +0 -160
- data/spec/attributes_spec.rb +0 -38
- data/spec/coercion_of_nil_spec.rb +0 -25
- data/spec/custom_dispatchers_spec.rb +0 -35
- data/spec/custom_initializer_spec.rb +0 -30
- data/spec/default_values_spec.rb +0 -83
- data/spec/definition_spec.rb +0 -111
- data/spec/invalid_default_spec.rb +0 -13
- data/spec/list_type_spec.rb +0 -32
- data/spec/missed_default_spec.rb +0 -14
- data/spec/nested_type_spec.rb +0 -48
- data/spec/optional_spec.rb +0 -71
- data/spec/options_tolerance_spec.rb +0 -11
- data/spec/public_attributes_utility_spec.rb +0 -22
- data/spec/reader_spec.rb +0 -87
- data/spec/repetitive_definitions_spec.rb +0 -69
- data/spec/several_assignments_spec.rb +0 -41
- data/spec/spec_helper.rb +0 -29
- data/spec/subclassing_spec.rb +0 -49
- data/spec/type_argument_spec.rb +0 -35
- data/spec/type_constraint_spec.rb +0 -78
- data/spec/value_coercion_via_dry_types_spec.rb +0 -29
@@ -1,59 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Skip Undefined
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-initializer
|
5
|
-
---
|
6
|
-
|
7
|
-
The initializer uses special constant `Dry::Initializer::UNDEFINED` to distinguish variables that are set to `nil` from those that are not set at all.
|
8
|
-
|
9
|
-
When no value was provided, the constant is assigned to a variable, but hidden in a reader.
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
require 'dry-initializer'
|
13
|
-
|
14
|
-
class User
|
15
|
-
extend Dry::Initializer
|
16
|
-
option :email, optional: true
|
17
|
-
end
|
18
|
-
|
19
|
-
user = User.new
|
20
|
-
|
21
|
-
user.email
|
22
|
-
# => nil
|
23
|
-
|
24
|
-
user.instance_variable_get :@email
|
25
|
-
# => Dry::Initializer::UNDEFINED
|
26
|
-
```
|
27
|
-
|
28
|
-
This gives you full control of the real state of the attributes. However, all that checks cost about >30% of instantiation time, and make attribute readers 2 times slower.
|
29
|
-
|
30
|
-
To avoid the overhead in cases you don't care about the differences between `nil` and undefined, you can use a light version of the module. Add `[undefined: false]` config to either `extend` or `include` line of code:
|
31
|
-
|
32
|
-
```ruby
|
33
|
-
extend Dry::Initializer[undefined: false]
|
34
|
-
```
|
35
|
-
|
36
|
-
```ruby
|
37
|
-
include Dry::Initializer[undefined: false] -> do
|
38
|
-
# ...
|
39
|
-
end
|
40
|
-
```
|
41
|
-
|
42
|
-
This time you should expect `nil` every time no value was given to an optional attribute:
|
43
|
-
|
44
|
-
```ruby
|
45
|
-
require 'dry-initializer'
|
46
|
-
|
47
|
-
class User
|
48
|
-
extend Dry::Initializer[undefined: false]
|
49
|
-
option :email, optional: true
|
50
|
-
end
|
51
|
-
|
52
|
-
user = User.new
|
53
|
-
|
54
|
-
user.email
|
55
|
-
# => nil
|
56
|
-
|
57
|
-
user.instance_variable_get :@email
|
58
|
-
# => nil
|
59
|
-
```
|
@@ -1,160 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Type Constraints
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-initializer
|
5
|
-
---
|
6
|
-
|
7
|
-
## Base Syntax
|
8
|
-
|
9
|
-
Use `:type` key in a `param` or `option` declarations to add type coercer.
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
require 'dry-initializer'
|
13
|
-
|
14
|
-
class User
|
15
|
-
extend Dry::Initializer
|
16
|
-
param :name, type: proc(&:to_s)
|
17
|
-
end
|
18
|
-
|
19
|
-
user = User.new :Andrew
|
20
|
-
user.name # => "Andrew"
|
21
|
-
```
|
22
|
-
|
23
|
-
Any object that responds to `#call` with 1 argument can be used as a type. Common examples are `proc(&:to_s)` for strings, `method(:Array)` (for arrays) or `Array.method(:wrap)` in Rails, `->(v) { !!v }` (for booleans), etc.
|
24
|
-
|
25
|
-
## Dry Types as coercers
|
26
|
-
|
27
|
-
Another important example is the usage of `dry-types` as type constraints:
|
28
|
-
|
29
|
-
```ruby
|
30
|
-
require 'dry-initializer'
|
31
|
-
require 'dry-types'
|
32
|
-
|
33
|
-
class User
|
34
|
-
extend Dry::Initializer
|
35
|
-
param :name, type: Dry::Types['strict.string']
|
36
|
-
end
|
37
|
-
|
38
|
-
user = User.new :Andrew # => #<TypeError ...>
|
39
|
-
```
|
40
|
-
|
41
|
-
## Positional Argument
|
42
|
-
|
43
|
-
Instead of `:type` option you can send a constraint/coercer as the second argument:
|
44
|
-
|
45
|
-
```ruby
|
46
|
-
require 'dry-initializer'
|
47
|
-
require 'dry-types'
|
48
|
-
|
49
|
-
class User
|
50
|
-
extend Dry::Initializer
|
51
|
-
param :name, Dry::Types['coercible.string']
|
52
|
-
param :email, proc(&:to_s)
|
53
|
-
end
|
54
|
-
```
|
55
|
-
|
56
|
-
## Array Types
|
57
|
-
|
58
|
-
As mentioned above, the `:type` option takes a callable object... with one important exception.
|
59
|
-
|
60
|
-
You can use arrays for values that should be wrapped to array:
|
61
|
-
|
62
|
-
```ruby
|
63
|
-
class User
|
64
|
-
extend Dry::Initializer
|
65
|
-
|
66
|
-
option :name, proc(&:to_s)
|
67
|
-
option :emails, [proc(&:to_s)]
|
68
|
-
end
|
69
|
-
|
70
|
-
user = User.new name: "joe", emails: :"joe@example.com"
|
71
|
-
user.emails # => ["joe@example.com"]
|
72
|
-
|
73
|
-
user = User.new name: "jane", emails: [:"jane@example.com", :"jane@example.org"]
|
74
|
-
user.emails # => ["jane@example.com", "jane@example.org"]
|
75
|
-
```
|
76
|
-
|
77
|
-
You can wrap the coercer into several arrays as well:
|
78
|
-
|
79
|
-
```ruby
|
80
|
-
class User
|
81
|
-
extend Dry::Initializer
|
82
|
-
|
83
|
-
option :emails, [[proc(&:to_s)]]
|
84
|
-
end
|
85
|
-
|
86
|
-
user = User.new name: "joe", emails: "joe@example.com"
|
87
|
-
user.emails # => [["joe@example.com"]]
|
88
|
-
```
|
89
|
-
|
90
|
-
Eventually, you can use an empty array as a coercer. In that case we just wrap the source value(s) into array, not modifying the items:
|
91
|
-
|
92
|
-
```ruby
|
93
|
-
class Article
|
94
|
-
extend Dry::Initializer
|
95
|
-
|
96
|
-
option :tags, []
|
97
|
-
end
|
98
|
-
|
99
|
-
article = Article.new(tags: 1)
|
100
|
-
article.tags # => [1]
|
101
|
-
```
|
102
|
-
|
103
|
-
## Nested Options
|
104
|
-
|
105
|
-
Sometimes you need to describe a structure with nested options. In this case you can use a block with `options` inside.
|
106
|
-
|
107
|
-
```ruby
|
108
|
-
class User
|
109
|
-
extend Dry::Initializer
|
110
|
-
|
111
|
-
option :name, proc(&:to_s)
|
112
|
-
|
113
|
-
option :emails, [] do
|
114
|
-
option :address, proc(&:to_s)
|
115
|
-
option :description, proc(&:to_s)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
user = User.new name: "joe",
|
120
|
-
emails: { address: "joe@example.com", description: "Job email" }
|
121
|
-
|
122
|
-
user.emails.class # => Array
|
123
|
-
user.emails.first.class # => User::Emails
|
124
|
-
user.emails.first.address # => "joe@example.com"
|
125
|
-
|
126
|
-
user.emails.to_h # => [{ address: "joe@example.com", description: "Job email" }]
|
127
|
-
```
|
128
|
-
|
129
|
-
Notice how we mixed array wrapper with a nested type.
|
130
|
-
|
131
|
-
The only syntax restriction here is that you cannot use a positional `param` _inside_ the block.
|
132
|
-
|
133
|
-
## Back References
|
134
|
-
|
135
|
-
Sometimes you need to refer back to the initialized instance. In this case use a second argument to explicitly give the instance to a coercer:
|
136
|
-
|
137
|
-
```ruby
|
138
|
-
class Location < String
|
139
|
-
attr_reader :parameter # refers back to its parameter
|
140
|
-
|
141
|
-
def initialize(name, parameter)
|
142
|
-
super(name)
|
143
|
-
@parameter = parameter
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
class Parameter
|
148
|
-
extend Dry::Initializer
|
149
|
-
param :name
|
150
|
-
param :location, ->(value, param) { Location.new(value, param) }
|
151
|
-
end
|
152
|
-
|
153
|
-
offset = Parameter.new "offset", location: "query"
|
154
|
-
offset.name # => "offset"
|
155
|
-
offset.location # => "query"
|
156
|
-
offset.location.parameter == offset # true
|
157
|
-
```
|
158
|
-
|
159
|
-
[dry-types]: https://github.com/dry-rb/dry-types
|
160
|
-
[dry-types-docs]: http://dry-rb.org/gems/dry-types/
|
data/spec/attributes_spec.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
describe Dry::Initializer, "dry_initializer.attributes" do
|
2
|
-
subject { instance.class.dry_initializer.attributes(instance) }
|
3
|
-
|
4
|
-
context "when class has params" do
|
5
|
-
before do
|
6
|
-
class Test::Foo
|
7
|
-
extend Dry::Initializer
|
8
|
-
param :foo, proc(&:to_s)
|
9
|
-
param :bar, default: proc { 1 }
|
10
|
-
param :baz, optional: true
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
let(:instance) { Test::Foo.new(:FOO) }
|
15
|
-
|
16
|
-
it "collects coerced params with default values" do
|
17
|
-
expect(subject).to eq({ foo: "FOO", bar: 1 })
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
context "when class has options" do
|
22
|
-
before do
|
23
|
-
class Test::Foo
|
24
|
-
extend Dry::Initializer
|
25
|
-
option :foo
|
26
|
-
option :bar, default: proc { 1 }
|
27
|
-
option :baz, optional: true
|
28
|
-
option :qux, proc(&:to_s), as: :quxx
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
let(:instance) { Test::Foo.new(foo: :FOO, qux: :QUX) }
|
33
|
-
|
34
|
-
it "collects coerced and renamed options with default values" do
|
35
|
-
expect(subject).to eq({ foo: :FOO, bar: 1, quxx: "QUX" })
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
describe "coercion of nil" do
|
2
|
-
before do
|
3
|
-
class Test::Foo
|
4
|
-
extend Dry::Initializer
|
5
|
-
param :bar, proc(&:to_i)
|
6
|
-
end
|
7
|
-
|
8
|
-
class Test::Baz
|
9
|
-
include Dry::Initializer.define -> do
|
10
|
-
param :qux, proc(&:to_i)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
let(:foo) { Test::Foo.new(nil) }
|
16
|
-
let(:baz) { Test::Baz.new(nil) }
|
17
|
-
|
18
|
-
it "works with extend syntax" do
|
19
|
-
expect(foo.bar).to eq 0
|
20
|
-
end
|
21
|
-
|
22
|
-
it "works with include syntax" do
|
23
|
-
expect(baz.qux).to eq 0
|
24
|
-
end
|
25
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
describe "custom dispatchers" do
|
2
|
-
subject { Test::Foo.new "123" }
|
3
|
-
|
4
|
-
before do
|
5
|
-
dispatcher = ->(op) { op[:integer] ? op.merge(type: proc(&:to_i)) : op }
|
6
|
-
Dry::Initializer::Dispatchers << dispatcher
|
7
|
-
end
|
8
|
-
|
9
|
-
context "with extend syntax" do
|
10
|
-
before do
|
11
|
-
class Test::Foo
|
12
|
-
extend Dry::Initializer
|
13
|
-
param :id, integer: true
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "adds syntax sugar" do
|
18
|
-
expect(subject.id).to eq 123
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context "with include syntax" do
|
23
|
-
before do
|
24
|
-
class Test::Foo
|
25
|
-
include Dry::Initializer.define -> do
|
26
|
-
param :id, integer: true
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
it "adds syntax sugar" do
|
32
|
-
expect(subject.id).to eq 123
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
describe "custom initializer" do
|
2
|
-
before do
|
3
|
-
class Test::Foo
|
4
|
-
extend Dry::Initializer
|
5
|
-
|
6
|
-
param :bar
|
7
|
-
|
8
|
-
def initialize(*args)
|
9
|
-
super
|
10
|
-
@bar *= 3
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class Test::Baz < Test::Foo
|
15
|
-
param :qux
|
16
|
-
|
17
|
-
def initialize(*args)
|
18
|
-
super
|
19
|
-
@qux += 1
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
it "reloads the initializer" do
|
25
|
-
baz = Test::Baz.new(5, 5)
|
26
|
-
|
27
|
-
expect(baz.bar).to eq 15 # 5 * 3
|
28
|
-
expect(baz.qux).to eq 6 # 5 + 1
|
29
|
-
end
|
30
|
-
end
|
data/spec/default_values_spec.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
describe "default values" do
|
2
|
-
before do
|
3
|
-
class Test::Foo
|
4
|
-
extend Dry::Initializer
|
5
|
-
|
6
|
-
param :foo, default: proc { :FOO }
|
7
|
-
param :bar, default: proc { :BAR }
|
8
|
-
option :baz, default: -> { :BAZ }
|
9
|
-
option :qux, default: proc { foo }
|
10
|
-
option :mox, default: -> { default_mox }
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def default_mox
|
15
|
-
:MOX
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
it "instantiate arguments" do
|
21
|
-
subject = Test::Foo.new(1, 2, baz: 3, qux: 4)
|
22
|
-
|
23
|
-
expect(subject.foo).to eql 1
|
24
|
-
expect(subject.bar).to eql 2
|
25
|
-
expect(subject.baz).to eql 3
|
26
|
-
expect(subject.qux).to eql 4
|
27
|
-
end
|
28
|
-
|
29
|
-
it "applies default values" do
|
30
|
-
subject = Test::Foo.new
|
31
|
-
|
32
|
-
expect(subject.foo).to eql :FOO
|
33
|
-
expect(subject.bar).to eql :BAR
|
34
|
-
expect(subject.baz).to eql :BAZ
|
35
|
-
expect(subject.qux).to eql :FOO
|
36
|
-
end
|
37
|
-
|
38
|
-
it "applies default values partially" do
|
39
|
-
subject = Test::Foo.new 1, baz: 3
|
40
|
-
|
41
|
-
expect(subject.foo).to eql 1
|
42
|
-
expect(subject.bar).to eql :BAR
|
43
|
-
expect(subject.baz).to eql 3
|
44
|
-
expect(subject.qux).to eql 1
|
45
|
-
end
|
46
|
-
|
47
|
-
it "applies default values from private methods" do
|
48
|
-
subject = Test::Foo.new
|
49
|
-
expect(subject.mox).to eql :MOX
|
50
|
-
end
|
51
|
-
|
52
|
-
describe "when the last param has a default and there are no options" do
|
53
|
-
before do
|
54
|
-
class Test::Bar
|
55
|
-
extend Dry::Initializer
|
56
|
-
|
57
|
-
param :foo
|
58
|
-
param :bar, default: proc { {} }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
it "instantiates arguments" do
|
63
|
-
subject = Test::Bar.new(1, 2)
|
64
|
-
|
65
|
-
expect(subject.foo).to eql 1
|
66
|
-
expect(subject.bar).to eql 2
|
67
|
-
end
|
68
|
-
|
69
|
-
it "applies default values" do
|
70
|
-
subject = Test::Bar.new(1)
|
71
|
-
|
72
|
-
expect(subject.foo).to eql 1
|
73
|
-
expect(subject.bar).to eql({})
|
74
|
-
end
|
75
|
-
|
76
|
-
it "instantiates arguments also if the last is an hash" do
|
77
|
-
subject = Test::Bar.new(1, { baz: 2, qux: 3 })
|
78
|
-
|
79
|
-
expect(subject.foo).to eql 1
|
80
|
-
expect(subject.bar).to eql({ baz: 2, qux: 3 })
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
data/spec/definition_spec.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
describe "definition" do
|
2
|
-
shared_examples :initializer do |in_context|
|
3
|
-
subject { Test::Foo.new(1, bar: 2) }
|
4
|
-
|
5
|
-
it "sets variables when defined via `#{in_context}`" do
|
6
|
-
expect(subject.instance_variable_get(:@foo)).to eql 1
|
7
|
-
expect(subject.instance_variable_get(:@bar)).to eql 2
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
it_behaves_like :initializer, "extend Dry::Initializer" do
|
12
|
-
before do
|
13
|
-
class Test::Foo
|
14
|
-
extend Dry::Initializer
|
15
|
-
param :foo
|
16
|
-
option :bar
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
it "preservers definition params" do
|
21
|
-
params = Test::Foo.dry_initializer.params.map do |definition|
|
22
|
-
[definition.source, definition.options]
|
23
|
-
end
|
24
|
-
|
25
|
-
expect(params).to eq [
|
26
|
-
[:foo, { as: :foo, reader: :public, optional: false }]
|
27
|
-
]
|
28
|
-
end
|
29
|
-
|
30
|
-
it "preservers definition options" do
|
31
|
-
options = Test::Foo.dry_initializer.options.map do |definition|
|
32
|
-
[definition.source, definition.options]
|
33
|
-
end
|
34
|
-
|
35
|
-
expect(options).to eq [
|
36
|
-
[:bar, { as: :bar, reader: :public, optional: false }]
|
37
|
-
]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it_behaves_like :initializer, "extend Dry::Initializer" do
|
42
|
-
before do
|
43
|
-
class Test::Foo
|
44
|
-
extend Dry::Initializer
|
45
|
-
param :foo
|
46
|
-
option :bar
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
it_behaves_like :initializer, "extend Dry::Initializer[undefined: false]" do
|
52
|
-
before do
|
53
|
-
class Test::Foo
|
54
|
-
extend Dry::Initializer[undefined: false]
|
55
|
-
param :foo
|
56
|
-
option :bar
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
it_behaves_like :initializer, "include Dry::Initializer with block" do
|
62
|
-
before do
|
63
|
-
class Test::Foo
|
64
|
-
include(
|
65
|
-
Dry::Initializer.define do
|
66
|
-
param :foo
|
67
|
-
option :bar
|
68
|
-
end
|
69
|
-
)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
it_behaves_like :initializer, "include Dry::Initializer with lambda" do
|
75
|
-
before do
|
76
|
-
class Test::Foo
|
77
|
-
include Dry::Initializer.define -> do
|
78
|
-
param :foo
|
79
|
-
option :bar
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
it_behaves_like :initializer, "include Dry::Initializer[undefined: false]" do
|
86
|
-
before do
|
87
|
-
class Test::Foo
|
88
|
-
include(
|
89
|
-
Dry::Initializer[undefined: false].define do
|
90
|
-
param :foo
|
91
|
-
option :bar
|
92
|
-
end
|
93
|
-
)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# @deprecated
|
99
|
-
it_behaves_like :initializer, "include Dry::Initializer::Mixin" do
|
100
|
-
before do
|
101
|
-
class Test::Foo
|
102
|
-
include(
|
103
|
-
Dry::Initializer::Mixin.define do
|
104
|
-
param :foo
|
105
|
-
option :bar
|
106
|
-
end
|
107
|
-
)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
data/spec/list_type_spec.rb
DELETED
@@ -1,32 +0,0 @@
|
|
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
|
data/spec/missed_default_spec.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
describe "missed default values" do
|
2
|
-
subject do
|
3
|
-
class Test::Foo
|
4
|
-
extend Dry::Initializer
|
5
|
-
|
6
|
-
param :foo, default: proc { :FOO }
|
7
|
-
param :bar, required: true
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
it "raises SyntaxError" do
|
12
|
-
expect { subject }.to raise_error SyntaxError, /bar/
|
13
|
-
end
|
14
|
-
end
|
data/spec/nested_type_spec.rb
DELETED
@@ -1,48 +0,0 @@
|
|
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
|
-
|
22
|
-
it "converts the nested type to hash" do
|
23
|
-
expect(subject.x.to_h).to eq("y" => { "z" => "42" })
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context "with nested and wrapped definitions" do
|
28
|
-
before do
|
29
|
-
class Test::Xyz
|
30
|
-
extend Dry::Initializer
|
31
|
-
|
32
|
-
param :foo, [], as: :x do
|
33
|
-
option :bar, as: :y do
|
34
|
-
option :baz, proc(&:to_s), as: :z
|
35
|
-
option :qux, as: :w, optional: true
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it "builds the type" do
|
42
|
-
x = subject.x
|
43
|
-
expect(x).to be_instance_of Array
|
44
|
-
|
45
|
-
expect(x.first.y.z).to eq "42"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|