dry-initializer 2.5.0 → 3.0.4

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.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +367 -239
  3. data/LICENSE +20 -0
  4. data/README.md +17 -79
  5. data/dry-initializer.gemspec +29 -16
  6. data/lib/dry-initializer.rb +1 -1
  7. data/lib/dry/initializer.rb +16 -14
  8. data/lib/dry/initializer/builders.rb +2 -2
  9. data/lib/dry/initializer/builders/attribute.rb +12 -7
  10. data/lib/dry/initializer/builders/initializer.rb +9 -13
  11. data/lib/dry/initializer/builders/reader.rb +3 -1
  12. data/lib/dry/initializer/builders/signature.rb +3 -3
  13. data/lib/dry/initializer/config.rb +22 -8
  14. data/lib/dry/initializer/definition.rb +20 -71
  15. data/lib/dry/initializer/dispatchers.rb +101 -33
  16. data/lib/dry/initializer/dispatchers/build_nested_type.rb +59 -0
  17. data/lib/dry/initializer/dispatchers/check_type.rb +43 -0
  18. data/lib/dry/initializer/dispatchers/prepare_default.rb +40 -0
  19. data/lib/dry/initializer/dispatchers/prepare_ivar.rb +12 -0
  20. data/lib/dry/initializer/dispatchers/prepare_optional.rb +13 -0
  21. data/lib/dry/initializer/dispatchers/prepare_reader.rb +30 -0
  22. data/lib/dry/initializer/dispatchers/prepare_source.rb +28 -0
  23. data/lib/dry/initializer/dispatchers/prepare_target.rb +44 -0
  24. data/lib/dry/initializer/dispatchers/unwrap_type.rb +22 -0
  25. data/lib/dry/initializer/dispatchers/wrap_type.rb +28 -0
  26. data/lib/dry/initializer/mixin.rb +4 -4
  27. data/lib/dry/initializer/mixin/root.rb +1 -0
  28. data/lib/dry/initializer/struct.rb +39 -0
  29. data/lib/dry/initializer/undefined.rb +2 -0
  30. data/lib/dry/initializer/version.rb +5 -0
  31. data/lib/tasks/benchmark.rake +13 -13
  32. data/lib/tasks/profile.rake +16 -16
  33. metadata +38 -103
  34. data/.codeclimate.yml +0 -23
  35. data/.gitignore +0 -10
  36. data/.rspec +0 -4
  37. data/.rubocop.yml +0 -51
  38. data/.travis.yml +0 -24
  39. data/Gemfile +0 -29
  40. data/Guardfile +0 -5
  41. data/LICENSE.txt +0 -21
  42. data/Rakefile +0 -8
  43. data/benchmarks/compare_several_defaults.rb +0 -82
  44. data/benchmarks/plain_options.rb +0 -63
  45. data/benchmarks/plain_params.rb +0 -84
  46. data/benchmarks/with_coercion.rb +0 -71
  47. data/benchmarks/with_defaults.rb +0 -66
  48. data/benchmarks/with_defaults_and_coercion.rb +0 -59
  49. data/spec/attributes_spec.rb +0 -38
  50. data/spec/coercion_of_nil_spec.rb +0 -25
  51. data/spec/custom_dispatchers_spec.rb +0 -35
  52. data/spec/custom_initializer_spec.rb +0 -30
  53. data/spec/default_values_spec.rb +0 -83
  54. data/spec/definition_spec.rb +0 -107
  55. data/spec/invalid_default_spec.rb +0 -13
  56. data/spec/missed_default_spec.rb +0 -14
  57. data/spec/optional_spec.rb +0 -71
  58. data/spec/options_tolerance_spec.rb +0 -11
  59. data/spec/public_attributes_utility_spec.rb +0 -22
  60. data/spec/reader_spec.rb +0 -87
  61. data/spec/repetitive_definitions_spec.rb +0 -69
  62. data/spec/several_assignments_spec.rb +0 -41
  63. data/spec/spec_helper.rb +0 -21
  64. data/spec/subclassing_spec.rb +0 -49
  65. data/spec/type_argument_spec.rb +0 -35
  66. data/spec/type_constraint_spec.rb +0 -78
  67. data/spec/value_coercion_via_dry_types_spec.rb +0 -29
@@ -1,66 +0,0 @@
1
- Bundler.require(:benchmarks)
2
-
3
- require "dry-initializer"
4
- class DryTest
5
- extend Dry::Initializer[undefined: false]
6
-
7
- option :foo, default: -> { "FOO" }
8
- option :bar, default: -> { "BAR" }
9
- end
10
-
11
- class DryTestUndefined
12
- extend Dry::Initializer
13
-
14
- option :foo, default: -> { "FOO" }
15
- option :bar, default: -> { "BAR" }
16
- end
17
-
18
- class PlainRubyTest
19
- attr_reader :foo, :bar
20
-
21
- def initialize(foo: "FOO", bar: "BAR")
22
- @foo = foo
23
- @bar = bar
24
- end
25
- end
26
-
27
- require "kwattr"
28
- class KwattrTest
29
- kwattr foo: "FOO", bar: "BAR"
30
- end
31
-
32
- require "active_attr"
33
- class ActiveAttrTest
34
- include ActiveAttr::AttributeDefaults
35
-
36
- attribute :foo, default: "FOO"
37
- attribute :bar, default: "BAR"
38
- end
39
-
40
- puts "Benchmark for instantiation with default values"
41
-
42
- Benchmark.ips do |x|
43
- x.config time: 15, warmup: 10
44
-
45
- x.report("plain Ruby") do
46
- PlainRubyTest.new
47
- end
48
-
49
- x.report("dry-initializer") do
50
- DryTest.new
51
- end
52
-
53
- x.report("dry-initializer (with UNDEFINED)") do
54
- DryTestUndefined.new
55
- end
56
-
57
- x.report("kwattr") do
58
- KwattrTest.new
59
- end
60
-
61
- x.report("active_attr") do
62
- ActiveAttrTest.new
63
- end
64
-
65
- x.compare!
66
- end
@@ -1,59 +0,0 @@
1
- Bundler.require(:benchmarks)
2
-
3
- require "dry-initializer"
4
- class DryTest
5
- extend Dry::Initializer[undefined: false]
6
-
7
- option :foo, proc(&:to_s), default: -> { "FOO" }
8
- option :bar, proc(&:to_s), default: -> { "BAR" }
9
- end
10
-
11
- class DryTestUndefined
12
- extend Dry::Initializer
13
-
14
- option :foo, proc(&:to_s), default: -> { "FOO" }
15
- option :bar, proc(&:to_s), default: -> { "BAR" }
16
- end
17
-
18
- class PlainRubyTest
19
- attr_reader :foo, :bar
20
-
21
- def initialize(foo: "FOO", bar: "BAR")
22
- @foo = foo
23
- @bar = bar
24
- raise TypeError unless String === @foo
25
- raise TypeError unless String === @bar
26
- end
27
- end
28
-
29
- require "virtus"
30
- class VirtusTest
31
- include Virtus.model
32
-
33
- attribute :foo, String, default: "FOO"
34
- attribute :bar, String, default: "BAR"
35
- end
36
-
37
- puts "Benchmark for instantiation with type constraints and default values"
38
-
39
- Benchmark.ips do |x|
40
- x.config time: 15, warmup: 10
41
-
42
- x.report("plain Ruby") do
43
- PlainRubyTest.new
44
- end
45
-
46
- x.report("dry-initializer") do
47
- DryTest.new
48
- end
49
-
50
- x.report("dry-initializer (with UNDEFINED)") do
51
- DryTest.new
52
- end
53
-
54
- x.report("virtus") do
55
- VirtusTest.new
56
- end
57
-
58
- x.compare!
59
- end
@@ -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
@@ -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
@@ -1,107 +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 [[:foo, { as: :foo, reader: :public }]]
26
- end
27
-
28
- it "preservers definition options" do
29
- options = Test::Foo.dry_initializer.options.map do |definition|
30
- [definition.source, definition.options]
31
- end
32
-
33
- expect(options).to eq [[:bar, { as: :bar, reader: :public }]]
34
- end
35
- end
36
-
37
- it_behaves_like :initializer, "extend Dry::Initializer" do
38
- before do
39
- class Test::Foo
40
- extend Dry::Initializer
41
- param :foo
42
- option :bar
43
- end
44
- end
45
- end
46
-
47
- it_behaves_like :initializer, "extend Dry::Initializer[undefined: false]" do
48
- before do
49
- class Test::Foo
50
- extend Dry::Initializer[undefined: false]
51
- param :foo
52
- option :bar
53
- end
54
- end
55
- end
56
-
57
- it_behaves_like :initializer, "include Dry::Initializer with block" do
58
- before do
59
- class Test::Foo
60
- include(
61
- Dry::Initializer.define do
62
- param :foo
63
- option :bar
64
- end
65
- )
66
- end
67
- end
68
- end
69
-
70
- it_behaves_like :initializer, "include Dry::Initializer with lambda" do
71
- before do
72
- class Test::Foo
73
- include Dry::Initializer.define -> do
74
- param :foo
75
- option :bar
76
- end
77
- end
78
- end
79
- end
80
-
81
- it_behaves_like :initializer, "include Dry::Initializer[undefined: false]" do
82
- before do
83
- class Test::Foo
84
- include(
85
- Dry::Initializer[undefined: false].define do
86
- param :foo
87
- option :bar
88
- end
89
- )
90
- end
91
- end
92
- end
93
-
94
- # @deprecated
95
- it_behaves_like :initializer, "include Dry::Initializer::Mixin" do
96
- before do
97
- class Test::Foo
98
- include(
99
- Dry::Initializer::Mixin.define do
100
- param :foo
101
- option :bar
102
- end
103
- )
104
- end
105
- end
106
- end
107
- end