dry-initializer 0.11.0 → 1.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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +18 -11
- data/CHANGELOG.md +85 -43
- data/benchmarks/options.rb +4 -4
- data/benchmarks/with_types.rb +2 -4
- data/benchmarks/with_types_and_defaults.rb +2 -4
- data/dry-initializer.gemspec +1 -1
- data/lib/dry/initializer.rb +77 -13
- data/lib/dry/initializer/attribute.rb +52 -0
- data/lib/dry/initializer/builder.rb +79 -72
- data/lib/dry/initializer/exceptions/default_value_error.rb +8 -0
- data/lib/dry/initializer/exceptions/params_order_error.rb +8 -0
- data/lib/dry/initializer/exceptions/type_constraint_error.rb +7 -0
- data/lib/dry/initializer/option.rb +55 -0
- data/lib/dry/initializer/param.rb +49 -0
- data/spec/missed_default_spec.rb +2 -2
- data/spec/optional_spec.rb +16 -6
- data/spec/options_var_spec.rb +39 -0
- data/spec/repetitive_definitions_spec.rb +38 -18
- data/spec/type_constraint_spec.rb +3 -3
- metadata +10 -18
- data/lib/dry/initializer/errors.rb +0 -10
- data/lib/dry/initializer/errors/default_value_error.rb +0 -6
- data/lib/dry/initializer/errors/order_error.rb +0 -7
- data/lib/dry/initializer/errors/plugin_error.rb +0 -6
- data/lib/dry/initializer/errors/redefinition_error.rb +0 -5
- data/lib/dry/initializer/errors/type_constraint_error.rb +0 -5
- data/lib/dry/initializer/mixin.rb +0 -77
- data/lib/dry/initializer/plugins.rb +0 -10
- data/lib/dry/initializer/plugins/base.rb +0 -47
- data/lib/dry/initializer/plugins/default_proc.rb +0 -28
- data/lib/dry/initializer/plugins/signature.rb +0 -28
- data/lib/dry/initializer/plugins/type_constraint.rb +0 -21
- data/lib/dry/initializer/plugins/variable_setter.rb +0 -30
- data/lib/dry/initializer/signature.rb +0 -61
- data/spec/plugin_registry_spec.rb +0 -45
data/spec/missed_default_spec.rb
CHANGED
data/spec/optional_spec.rb
CHANGED
@@ -9,22 +9,27 @@ describe "optional value" do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
it "
|
12
|
+
it "quacks like nil" do
|
13
13
|
subject = Test::Foo.new(1)
|
14
14
|
|
15
|
-
expect(subject.
|
16
|
-
|
15
|
+
expect(subject.bar).to eq nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "keeps info about been UNDEFINED" do
|
19
|
+
subject = Test::Foo.new(1)
|
20
|
+
|
21
|
+
expect(subject.instance_variable_get(:@bar))
|
22
|
+
.to eq Dry::Initializer::UNDEFINED
|
17
23
|
end
|
18
24
|
|
19
25
|
it "can be set explicitly" do
|
20
26
|
subject = Test::Foo.new(1, "qux")
|
21
27
|
|
22
|
-
expect(subject.foo).to eq 1
|
23
28
|
expect(subject.bar).to eq "qux"
|
24
29
|
end
|
25
30
|
end
|
26
31
|
|
27
|
-
context "when has default value" do
|
32
|
+
context "when has a default value" do
|
28
33
|
before do
|
29
34
|
class Test::Foo
|
30
35
|
extend Dry::Initializer::Mixin
|
@@ -37,8 +42,13 @@ describe "optional value" do
|
|
37
42
|
it "is takes default value" do
|
38
43
|
subject = Test::Foo.new(1)
|
39
44
|
|
40
|
-
expect(subject.foo).to eq 1
|
41
45
|
expect(subject.bar).to eq "baz"
|
42
46
|
end
|
47
|
+
|
48
|
+
it "can be set explicitly" do
|
49
|
+
subject = Test::Foo.new(1, "qux")
|
50
|
+
|
51
|
+
expect(subject.bar).to eq "qux"
|
52
|
+
end
|
43
53
|
end
|
44
54
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe "@__options__" do
|
2
|
+
context "when class has no options" do
|
3
|
+
before do
|
4
|
+
class Test::Foo
|
5
|
+
extend Dry::Initializer::Mixin
|
6
|
+
param :foo
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "is set to empty hash" do
|
11
|
+
subject = Test::Foo.new(1)
|
12
|
+
|
13
|
+
expect(subject.instance_variable_get(:@__options__)).to eq({})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when class has options" do
|
18
|
+
before do
|
19
|
+
class Test::Foo
|
20
|
+
extend Dry::Initializer::Mixin
|
21
|
+
param :foo
|
22
|
+
option :bar, optional: true
|
23
|
+
option :baz, optional: true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "is set to empty hash if no options assigned" do
|
28
|
+
subject = Test::Foo.new(1)
|
29
|
+
|
30
|
+
expect(subject.instance_variable_get(:@__options__)).to eq({})
|
31
|
+
end
|
32
|
+
|
33
|
+
it "is set to hash of assigned options" do
|
34
|
+
subject = Test::Foo.new(1, baz: :QUX)
|
35
|
+
|
36
|
+
expect(subject.instance_variable_get(:@__options__)).to eq({ baz: :QUX })
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,49 +1,69 @@
|
|
1
1
|
describe "repetitive definitions" do
|
2
|
+
subject { Test::Foo.new }
|
3
|
+
|
2
4
|
context "of params" do
|
3
|
-
|
5
|
+
before do
|
4
6
|
class Test::Foo
|
5
7
|
extend Dry::Initializer::Mixin
|
6
8
|
|
7
|
-
param :foo
|
8
|
-
param :bar
|
9
|
-
param :foo
|
9
|
+
param :foo, default: proc { 0 }
|
10
|
+
param :bar, default: proc { 1 }
|
11
|
+
param :foo, default: proc { 2 }
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
|
-
it "
|
14
|
-
expect
|
15
|
+
it "reloads the attribute" do
|
16
|
+
expect(subject.foo).to eq 2
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
20
|
context "of options" do
|
19
|
-
|
21
|
+
before do
|
20
22
|
class Test::Foo
|
21
23
|
extend Dry::Initializer::Mixin
|
22
24
|
|
23
|
-
option :foo
|
24
|
-
option :bar
|
25
|
-
option :foo
|
25
|
+
option :foo, default: proc { 0 }
|
26
|
+
option :bar, default: proc { 1 }
|
27
|
+
option :foo, default: proc { 2 }
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
it "
|
30
|
-
expect
|
31
|
+
it "reloads the attribute" do
|
32
|
+
expect(subject.foo).to eq 2
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
36
|
context "of param and option" do
|
35
|
-
|
37
|
+
before do
|
38
|
+
class Test::Foo
|
39
|
+
extend Dry::Initializer::Mixin
|
40
|
+
|
41
|
+
param :foo, default: proc { 0 }
|
42
|
+
option :bar, default: proc { 1 }
|
43
|
+
option :foo, default: proc { 2 }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "reloads the attribute" do
|
48
|
+
expect(subject.foo).to eq 2
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "of optional param and option" do
|
53
|
+
before do
|
36
54
|
class Test::Foo
|
37
55
|
extend Dry::Initializer::Mixin
|
38
56
|
|
39
|
-
param :foo
|
40
|
-
option :bar
|
41
|
-
option :foo
|
57
|
+
param :foo, optional: true
|
58
|
+
option :bar, optional: true
|
59
|
+
option :foo, optional: true
|
42
60
|
end
|
43
61
|
end
|
44
62
|
|
45
|
-
it "
|
46
|
-
expect
|
63
|
+
it "allows various assignments" do
|
64
|
+
expect(Test::Foo.new(1).foo).to eq 1
|
65
|
+
expect(Test::Foo.new(foo: 2).foo).to eq 2
|
66
|
+
expect(Test::Foo.new(1, foo: 2).foo).to eq 2
|
47
67
|
end
|
48
68
|
end
|
49
69
|
end
|
@@ -5,7 +5,7 @@ describe "type constraint" do
|
|
5
5
|
before do
|
6
6
|
class Test::Foo
|
7
7
|
extend Dry::Initializer::Mixin
|
8
|
-
param :foo,
|
8
|
+
param :foo, Dry::Types["strict.string"], optional: true
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -28,8 +28,8 @@ describe "type constraint" do
|
|
28
28
|
context "if optional value not set" do
|
29
29
|
subject { Test::Foo.new }
|
30
30
|
|
31
|
-
it "
|
32
|
-
expect { subject }.
|
31
|
+
it "applies type constraint to Dry::Initializer::UNDEFINED" do
|
32
|
+
expect { subject }.to raise_error Dry::Types::ConstraintError
|
33
33
|
end
|
34
34
|
end
|
35
35
|
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: 0.
|
4
|
+
version: 1.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: 2017-01-
|
12
|
+
date: 2017-01-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -99,21 +99,13 @@ files:
|
|
99
99
|
- dry-initializer.gemspec
|
100
100
|
- lib/dry-initializer.rb
|
101
101
|
- lib/dry/initializer.rb
|
102
|
+
- lib/dry/initializer/attribute.rb
|
102
103
|
- lib/dry/initializer/builder.rb
|
103
|
-
- lib/dry/initializer/
|
104
|
-
- lib/dry/initializer/
|
105
|
-
- lib/dry/initializer/
|
106
|
-
- lib/dry/initializer/
|
107
|
-
- lib/dry/initializer/
|
108
|
-
- lib/dry/initializer/errors/type_constraint_error.rb
|
109
|
-
- lib/dry/initializer/mixin.rb
|
110
|
-
- lib/dry/initializer/plugins.rb
|
111
|
-
- lib/dry/initializer/plugins/base.rb
|
112
|
-
- lib/dry/initializer/plugins/default_proc.rb
|
113
|
-
- lib/dry/initializer/plugins/signature.rb
|
114
|
-
- lib/dry/initializer/plugins/type_constraint.rb
|
115
|
-
- lib/dry/initializer/plugins/variable_setter.rb
|
116
|
-
- lib/dry/initializer/signature.rb
|
104
|
+
- lib/dry/initializer/exceptions/default_value_error.rb
|
105
|
+
- lib/dry/initializer/exceptions/params_order_error.rb
|
106
|
+
- lib/dry/initializer/exceptions/type_constraint_error.rb
|
107
|
+
- lib/dry/initializer/option.rb
|
108
|
+
- lib/dry/initializer/param.rb
|
117
109
|
- spec/base_spec.rb
|
118
110
|
- spec/container_spec.rb
|
119
111
|
- spec/custom_initializer_spec.rb
|
@@ -123,7 +115,7 @@ files:
|
|
123
115
|
- spec/missed_default_spec.rb
|
124
116
|
- spec/optional_spec.rb
|
125
117
|
- spec/options_tolerance_spec.rb
|
126
|
-
- spec/
|
118
|
+
- spec/options_var_spec.rb
|
127
119
|
- spec/reader_spec.rb
|
128
120
|
- spec/renaming_options_spec.rb
|
129
121
|
- spec/repetitive_definitions_spec.rb
|
@@ -166,7 +158,7 @@ test_files:
|
|
166
158
|
- spec/missed_default_spec.rb
|
167
159
|
- spec/optional_spec.rb
|
168
160
|
- spec/options_tolerance_spec.rb
|
169
|
-
- spec/
|
161
|
+
- spec/options_var_spec.rb
|
170
162
|
- spec/reader_spec.rb
|
171
163
|
- spec/renaming_options_spec.rb
|
172
164
|
- spec/repetitive_definitions_spec.rb
|
@@ -1,10 +0,0 @@
|
|
1
|
-
module Dry::Initializer
|
2
|
-
# Collection of gem-specific exceptions
|
3
|
-
module Errors
|
4
|
-
require_relative "errors/default_value_error"
|
5
|
-
require_relative "errors/order_error"
|
6
|
-
require_relative "errors/plugin_error"
|
7
|
-
require_relative "errors/redefinition_error"
|
8
|
-
require_relative "errors/type_constraint_error"
|
9
|
-
end
|
10
|
-
end
|
@@ -1,7 +0,0 @@
|
|
1
|
-
class Dry::Initializer::Errors::OrderError < SyntaxError
|
2
|
-
def initialize(name)
|
3
|
-
super "Cannot define the required param '#{name}' after optional ones." \
|
4
|
-
" Either provide a default value for the '#{name}', or declare it" \
|
5
|
-
" before params with default values."
|
6
|
-
end
|
7
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
module Dry::Initializer
|
2
|
-
# Class-level DSL for the initializer
|
3
|
-
module Mixin
|
4
|
-
# Declares a plain argument
|
5
|
-
#
|
6
|
-
# @param [#to_sym] name
|
7
|
-
#
|
8
|
-
# @option options [Object] :default The default value
|
9
|
-
# @option options [#call] :type The type constraings via `dry-types`
|
10
|
-
# @option options [Boolean] :reader (true) Whether to define attr_reader
|
11
|
-
#
|
12
|
-
# @return [self] itself
|
13
|
-
#
|
14
|
-
def param(name, type = nil, **options)
|
15
|
-
options[:type] = type if type
|
16
|
-
options[:option] = false
|
17
|
-
@__initializer_builder__ = __initializer_builder__.define(name, **options)
|
18
|
-
__initializer_builder__.call(__initializer_mixin__)
|
19
|
-
end
|
20
|
-
|
21
|
-
# Declares a named argument
|
22
|
-
#
|
23
|
-
# @param (see #param)
|
24
|
-
# @option (see #param)
|
25
|
-
# @return (see #param)
|
26
|
-
#
|
27
|
-
def option(name, type = nil, **options)
|
28
|
-
options[:type] = type if type
|
29
|
-
options[:option] = true
|
30
|
-
@__initializer_builder__ = __initializer_builder__.define(name, **options)
|
31
|
-
__initializer_builder__.call(__initializer_mixin__)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Adds new plugin to the builder
|
35
|
-
#
|
36
|
-
# @param [Dry::Initializer::Plugins::Base] plugin
|
37
|
-
# @return [self] itself
|
38
|
-
#
|
39
|
-
def register_initializer_plugin(plugin)
|
40
|
-
@__initializer_builder__ = __initializer_builder__.register(plugin)
|
41
|
-
__initializer_builder__.call(__initializer_mixin__)
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def __initializer_mixin__
|
47
|
-
@__initializer_mixin__ ||= Module.new do
|
48
|
-
def initialize(*args)
|
49
|
-
__initialize__(*args)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def __initializer_builder__
|
55
|
-
@__initializer_builder__ ||= Builder.new
|
56
|
-
end
|
57
|
-
|
58
|
-
def inherited(klass)
|
59
|
-
new_builder = __initializer_builder__.dup
|
60
|
-
klass.instance_variable_set :@__initializer_builder__, new_builder
|
61
|
-
|
62
|
-
new_mixin = Module.new
|
63
|
-
new_builder.call(new_mixin)
|
64
|
-
klass.instance_variable_set :@__initializer_mixin__, new_mixin
|
65
|
-
klass.include new_mixin
|
66
|
-
|
67
|
-
super
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.extended(klass)
|
71
|
-
super
|
72
|
-
mixin = klass.send(:__initializer_mixin__)
|
73
|
-
klass.send(:__initializer_builder__).call(mixin)
|
74
|
-
klass.include mixin
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
module Dry::Initializer
|
2
|
-
# Namespace for code plugins builders
|
3
|
-
module Plugins
|
4
|
-
require_relative "plugins/base"
|
5
|
-
require_relative "plugins/default_proc"
|
6
|
-
require_relative "plugins/signature"
|
7
|
-
require_relative "plugins/type_constraint"
|
8
|
-
require_relative "plugins/variable_setter"
|
9
|
-
end
|
10
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
module Dry::Initializer::Plugins
|
2
|
-
# Base class for plugins
|
3
|
-
#
|
4
|
-
# A plugin should has class method [.call] that takes argument name and
|
5
|
-
# settings and return a chunk of code for the #initialize method body.
|
6
|
-
#
|
7
|
-
class Base
|
8
|
-
include Dry::Initializer::Errors
|
9
|
-
|
10
|
-
# Builds the proc for the `__after_initializer__` callback
|
11
|
-
#
|
12
|
-
# @param [#to_s] name
|
13
|
-
# @param [Hash<Symbol, Object>] settings
|
14
|
-
#
|
15
|
-
# @return [String, Proc, nil]
|
16
|
-
#
|
17
|
-
def self.call(name, settings)
|
18
|
-
new(name, settings).call
|
19
|
-
end
|
20
|
-
|
21
|
-
# @private
|
22
|
-
attr_reader :name, :settings
|
23
|
-
|
24
|
-
# Initializes a builder with argument name and settings
|
25
|
-
# @param (see .call)
|
26
|
-
def initialize(name, settings)
|
27
|
-
@name = name
|
28
|
-
@settings = settings
|
29
|
-
end
|
30
|
-
|
31
|
-
# Checks equality to another instance by name
|
32
|
-
# @return [Boolean]
|
33
|
-
def ==(other)
|
34
|
-
other.instance_of?(self.class) && (other.name == name)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Builds a chunk of code
|
38
|
-
# @return (see .call)
|
39
|
-
def call; end
|
40
|
-
|
41
|
-
# Returns the name for the attribute
|
42
|
-
# @return (see .name)
|
43
|
-
def rename
|
44
|
-
@rename ||= settings[:option] ? (settings[:as] || name) : name
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|