dry-initializer 3.0.2 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/---bug-report.md +1 -5
  3. data/.github/workflows/custom_ci.yml +31 -47
  4. data/.github/workflows/sync_configs.yml +29 -7
  5. data/.rspec +1 -1
  6. data/.rubocop.yml +19 -6
  7. data/CHANGELOG.md +6 -0
  8. data/Gemfile +27 -29
  9. data/Gemfile.devtools +16 -0
  10. data/Guardfile +3 -3
  11. data/LICENSE +1 -1
  12. data/README.md +17 -77
  13. data/Rakefile +4 -4
  14. data/benchmarks/compare_several_defaults.rb +27 -27
  15. data/benchmarks/plain_options.rb +14 -14
  16. data/benchmarks/plain_params.rb +22 -22
  17. data/benchmarks/with_coercion.rb +14 -14
  18. data/benchmarks/with_defaults.rb +17 -17
  19. data/benchmarks/with_defaults_and_coercion.rb +14 -14
  20. data/bin/.gitkeep +0 -0
  21. data/dry-initializer.gemspec +13 -13
  22. data/lib/dry-initializer.rb +1 -1
  23. data/lib/dry/initializer.rb +9 -9
  24. data/lib/dry/initializer/builders.rb +2 -2
  25. data/lib/dry/initializer/builders/attribute.rb +12 -7
  26. data/lib/dry/initializer/builders/initializer.rb +9 -13
  27. data/lib/dry/initializer/builders/reader.rb +3 -1
  28. data/lib/dry/initializer/builders/signature.rb +3 -3
  29. data/lib/dry/initializer/config.rb +6 -4
  30. data/lib/dry/initializer/definition.rb +9 -9
  31. data/lib/dry/initializer/dispatchers.rb +10 -10
  32. data/lib/dry/initializer/dispatchers/prepare_default.rb +2 -2
  33. data/lib/dry/initializer/dispatchers/prepare_ivar.rb +1 -1
  34. data/lib/dry/initializer/dispatchers/prepare_reader.rb +3 -3
  35. data/lib/dry/initializer/dispatchers/wrap_type.rb +1 -0
  36. data/lib/dry/initializer/mixin.rb +4 -4
  37. data/lib/dry/initializer/version.rb +5 -0
  38. data/lib/tasks/benchmark.rake +13 -13
  39. data/lib/tasks/profile.rake +16 -16
  40. data/project.yml +2 -0
  41. data/spec/attributes_spec.rb +7 -7
  42. data/spec/coercion_of_nil_spec.rb +3 -3
  43. data/spec/custom_dispatchers_spec.rb +6 -6
  44. data/spec/custom_initializer_spec.rb +2 -2
  45. data/spec/default_values_spec.rb +9 -9
  46. data/spec/definition_spec.rb +10 -10
  47. data/spec/invalid_default_spec.rb +2 -2
  48. data/spec/list_type_spec.rb +8 -8
  49. data/spec/missed_default_spec.rb +2 -2
  50. data/spec/nested_type_spec.rb +10 -10
  51. data/spec/optional_spec.rb +16 -16
  52. data/spec/options_tolerance_spec.rb +2 -2
  53. data/spec/public_attributes_utility_spec.rb +5 -5
  54. data/spec/reader_spec.rb +13 -13
  55. data/spec/repetitive_definitions_spec.rb +9 -9
  56. data/spec/several_assignments_spec.rb +9 -9
  57. data/spec/spec_helper.rb +3 -8
  58. data/spec/subclassing_spec.rb +5 -5
  59. data/spec/support/coverage.rb +7 -0
  60. data/spec/support/warnings.rb +7 -0
  61. data/spec/type_argument_spec.rb +13 -13
  62. data/spec/type_constraint_spec.rb +44 -26
  63. data/spec/value_coercion_via_dry_types_spec.rb +7 -7
  64. metadata +11 -31
File without changes
@@ -1,20 +1,20 @@
1
+ require File.expand_path('lib/dry/initializer/version', __dir__)
2
+
1
3
  Gem::Specification.new do |gem|
2
- gem.name = "dry-initializer"
3
- gem.version = "3.0.2"
4
- gem.author = ["Vladimir Kochnev (marshall-lee)", "Andrew Kozin (nepalez)"]
5
- gem.email = "andrew.kozin@gmail.com"
6
- gem.homepage = "https://github.com/dry-rb/dry-initializer"
7
- gem.summary = "DSL for declaring params and options of the initializer"
8
- gem.license = "MIT"
4
+ gem.name = 'dry-initializer'
5
+ gem.version = Dry::Initializer::VERSION
6
+ gem.author = ['Vladimir Kochnev (marshall-lee)', 'Andrew Kozin (nepalez)']
7
+ gem.email = 'andrew.kozin@gmail.com'
8
+ gem.homepage = 'https://github.com/dry-rb/dry-initializer'
9
+ gem.summary = 'DSL for declaring params and options of the initializer'
10
+ gem.license = 'MIT'
9
11
 
10
12
  gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
11
13
  gem.test_files = gem.files.grep(/^spec/)
12
- gem.extra_rdoc_files = Dir["README.md", "LICENSE", "CHANGELOG.md"]
14
+ gem.extra_rdoc_files = Dir['README.md', 'LICENSE', 'CHANGELOG.md']
13
15
 
14
- gem.required_ruby_version = ">= 2.3"
16
+ gem.required_ruby_version = '>= 2.3'
15
17
 
16
- gem.add_development_dependency "rspec", "~> 3.0"
17
- gem.add_development_dependency "rake", "> 10"
18
- gem.add_development_dependency "dry-types", "> 0.5.1"
19
- gem.add_development_dependency "rubocop", "~> 0.49.0"
18
+ gem.add_development_dependency 'rspec', '~> 3.0'
19
+ gem.add_development_dependency 'rake', '> 10'
20
20
  end
@@ -1 +1 @@
1
- require_relative "dry/initializer"
1
+ require_relative 'dry/initializer'
@@ -1,4 +1,4 @@
1
- require "set"
1
+ require 'set'
2
2
 
3
3
  # Namespace for gems in a dry-rb community
4
4
  module Dry
@@ -6,13 +6,13 @@ module Dry
6
6
  # DSL for declaring params and options of class initializers
7
7
  #
8
8
  module Initializer
9
- require_relative "initializer/undefined"
10
- require_relative "initializer/dsl"
11
- require_relative "initializer/definition"
12
- require_relative "initializer/builders"
13
- require_relative "initializer/config"
14
- require_relative "initializer/mixin"
15
- require_relative "initializer/dispatchers"
9
+ require_relative 'initializer/undefined'
10
+ require_relative 'initializer/dsl'
11
+ require_relative 'initializer/definition'
12
+ require_relative 'initializer/builders'
13
+ require_relative 'initializer/config'
14
+ require_relative 'initializer/mixin'
15
+ require_relative 'initializer/dispatchers'
16
16
 
17
17
  # Adds methods [.[]] and [.define]
18
18
  extend DSL
@@ -56,6 +56,6 @@ module Dry
56
56
  dry_initializer.children << config
57
57
  end
58
58
 
59
- require_relative "initializer/struct"
59
+ require_relative 'initializer/struct'
60
60
  end
61
61
  end
@@ -1,7 +1,7 @@
1
1
  module Dry::Initializer
2
2
  # @private
3
3
  module Builders
4
- require_relative "builders/reader"
5
- require_relative "builders/initializer"
4
+ require_relative 'builders/reader'
5
+ require_relative 'builders/initializer'
6
6
  end
7
7
  end
@@ -20,17 +20,17 @@ module Dry::Initializer::Builders
20
20
  @default = definition.default
21
21
  @source = definition.source
22
22
  @ivar = definition.ivar
23
- @null = definition.null ? "Dry::Initializer::UNDEFINED" : "nil"
24
- @opts = "__dry_initializer_options__"
25
- @congif = "__dry_initializer_config__"
26
- @item = "__dry_initializer_definition__"
27
- @val = @option ? "__dry_initializer_value__" : @source
23
+ @null = definition.null ? 'Dry::Initializer::UNDEFINED' : 'nil'
24
+ @opts = '__dry_initializer_options__'
25
+ @congif = '__dry_initializer_config__'
26
+ @item = '__dry_initializer_definition__'
27
+ @val = @option ? '__dry_initializer_value__' : @source
28
28
  end
29
29
  # rubocop: enable Metrics/MethodLength
30
30
 
31
31
  def lines
32
32
  [
33
- "",
33
+ '',
34
34
  definition_line,
35
35
  reader_line,
36
36
  default_line,
@@ -41,6 +41,7 @@ module Dry::Initializer::Builders
41
41
 
42
42
  def reader_line
43
43
  return unless @option
44
+
44
45
  @optional ? optional_reader : required_reader
45
46
  end
46
47
 
@@ -55,18 +56,22 @@ module Dry::Initializer::Builders
55
56
 
56
57
  def definition_line
57
58
  return unless @type || @default
59
+
58
60
  "#{@item} = __dry_initializer_config__.definitions[:'#{@source}']"
59
61
  end
60
62
 
61
63
  def default_line
62
64
  return unless @default
65
+
63
66
  "#{@val} = instance_exec(&#{@item}.default) if #{@null} == #{@val}"
64
67
  end
65
68
 
66
69
  def coercion_line
67
70
  return unless @type
71
+
68
72
  arity = @type.is_a?(Proc) ? @type.arity : @type.method(:call).arity
69
- if arity.abs == 1
73
+
74
+ if arity.abs == 1 || Dry::Types::Type.equal?(@type)
70
75
  "#{@val} = #{@item}.type.call(#{@val}) unless #{@null} == #{@val}"
71
76
  else
72
77
  "#{@val} = #{@item}.type.call(#{@val}, self) unless #{@null} == #{@val}"
@@ -1,8 +1,8 @@
1
1
  module Dry::Initializer::Builders
2
2
  # @private
3
3
  class Initializer
4
- require_relative "signature"
5
- require_relative "attribute"
4
+ require_relative 'signature'
5
+ require_relative 'attribute'
6
6
 
7
7
  def self.[](config)
8
8
  new(config).call
@@ -30,8 +30,8 @@ module Dry::Initializer::Builders
30
30
  end
31
31
 
32
32
  def undef_line
33
- "undef :__dry_initializer_initialize__" \
34
- " if private_method_defined? :__dry_initializer_initialize__"
33
+ 'undef :__dry_initializer_initialize__' \
34
+ ' if private_method_defined? :__dry_initializer_initialize__'
35
35
  end
36
36
 
37
37
  def define_line
@@ -40,22 +40,18 @@ module Dry::Initializer::Builders
40
40
 
41
41
  def params_lines
42
42
  @definitions.reject(&:option)
43
- .flat_map { |item| Attribute[item] }
44
- .map { |line| " " << line }
43
+ .flat_map { |item| Attribute[item] }
44
+ .map { |line| ' ' << line }
45
45
  end
46
46
 
47
47
  def options_lines
48
48
  @definitions.select(&:option)
49
- .flat_map { |item| Attribute[item] }
50
- .map { |line| " " << line }
49
+ .flat_map { |item| Attribute[item] }
50
+ .map { |line| ' ' << line }
51
51
  end
52
52
 
53
53
  def end_line
54
- "end"
55
- end
56
-
57
- def private_line
58
- "private :__dry_initializer_initialize__"
54
+ 'end'
59
55
  end
60
56
  end
61
57
  end
@@ -30,16 +30,18 @@ module Dry::Initializer::Builders
30
30
 
31
31
  def attribute_line
32
32
  return unless @reader
33
+
33
34
  "attr_reader :#{@target}" unless @null
34
35
  end
35
36
 
36
37
  def method_lines
37
38
  return unless @reader
38
39
  return unless @null
40
+
39
41
  [
40
42
  "def #{@target}",
41
43
  " #{@ivar} unless Dry::Initializer::UNDEFINED == #{@ivar}",
42
- "end"
44
+ 'end'
43
45
  ]
44
46
  end
45
47
 
@@ -6,7 +6,7 @@ module Dry::Initializer::Builders
6
6
  end
7
7
 
8
8
  def call
9
- [*required_params, *optional_params, "*", options].compact.join(", ")
9
+ [*required_params, *optional_params, '*', options].compact.join(', ')
10
10
  end
11
11
 
12
12
  private
@@ -14,7 +14,7 @@ module Dry::Initializer::Builders
14
14
  def initialize(config)
15
15
  @config = config
16
16
  @options = config.options.any?
17
- @null = config.null ? "Dry::Initializer::UNDEFINED" : "nil"
17
+ @null = config.null ? 'Dry::Initializer::UNDEFINED' : 'nil'
18
18
  end
19
19
 
20
20
  def required_params
@@ -26,7 +26,7 @@ module Dry::Initializer::Builders
26
26
  end
27
27
 
28
28
  def options
29
- "**__dry_initializer_options__" if @options
29
+ '**__dry_initializer_options__' if @options
30
30
  end
31
31
  end
32
32
  end
@@ -78,6 +78,7 @@ module Dry::Initializer
78
78
  definitions.values.each_with_object({}) do |item, obj|
79
79
  key = item.target
80
80
  next unless instance.respond_to? key
81
+
81
82
  val = instance.send(key)
82
83
  obj[key] = val unless null == val
83
84
  end
@@ -114,7 +115,7 @@ module Dry::Initializer
114
115
  # @return [String]
115
116
  def inch
116
117
  line = Builders::Signature[self]
117
- line = line.gsub("__dry_initializer_options__", "options")
118
+ line = line.gsub('__dry_initializer_options__', 'options')
118
119
  lines = ["@!method initialize(#{line})"]
119
120
  lines += ["Initializes an instance of #{extended_class}"]
120
121
  lines += definitions.values.map(&:inch)
@@ -138,10 +139,10 @@ module Dry::Initializer
138
139
  opts = {
139
140
  parent: extended_class,
140
141
  option: option,
141
- null: null,
142
+ null: null,
142
143
  source: name,
143
- type: type,
144
- block: block,
144
+ type: type,
145
+ block: block,
145
146
  **opts
146
147
  }
147
148
 
@@ -163,6 +164,7 @@ module Dry::Initializer
163
164
  def check_type(previous, current)
164
165
  return current unless previous
165
166
  return current if previous.option == current.option
167
+
166
168
  raise SyntaxError,
167
169
  "cannot reload #{previous} of #{extended_class.superclass}" \
168
170
  " by #{current} of its subclass #{extended_class}"
@@ -14,17 +14,17 @@ module Dry::Initializer
14
14
 
15
15
  def options
16
16
  {
17
- as: target,
18
- type: type,
17
+ as: target,
18
+ type: type,
19
19
  optional: optional,
20
- default: default,
21
- reader: reader,
22
- desc: desc
20
+ default: default,
21
+ reader: reader,
22
+ desc: desc
23
23
  }.reject { |_, value| value.nil? }
24
24
  end
25
25
 
26
26
  def name
27
- @name ||= (option ? "option" : "parameter") << " '#{source}'"
27
+ @name ||= (option ? 'option' : 'parameter') << " '#{source}'"
28
28
  end
29
29
  alias to_s name
30
30
  alias to_str name
@@ -39,10 +39,10 @@ module Dry::Initializer
39
39
  end
40
40
 
41
41
  def inch
42
- @inch ||= (option ? "@option" : "@param ").tap do |text|
43
- text << " [Object]"
42
+ @inch ||= (option ? '@option' : '@param ').tap do |text|
43
+ text << ' [Object]'
44
44
  text << (option ? " :#{source}" : " #{source}")
45
- text << (optional ? " (optional)" : " (required)")
45
+ text << (optional ? ' (optional)' : ' (required)')
46
46
  text << " #{desc}" if desc
47
47
  end
48
48
  end
@@ -91,16 +91,16 @@ module Dry::Initializer::Dispatchers
91
91
 
92
92
  private
93
93
 
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"
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'
104
104
 
105
105
  def pipeline
106
106
  @pipeline ||= [
@@ -34,7 +34,7 @@ module Dry::Initializer::Dispatchers::PrepareDefault
34
34
 
35
35
  def invalid!(default)
36
36
  raise TypeError, "The #{default.inspect} should be" \
37
- " either convertable to proc with no arguments," \
38
- " or respond to #call without arguments."
37
+ ' either convertable to proc with no arguments,' \
38
+ ' or respond to #call without arguments.'
39
39
  end
40
40
  end
@@ -5,7 +5,7 @@ module Dry::Initializer::Dispatchers::PrepareIvar
5
5
  module_function
6
6
 
7
7
  def call(target:, **options)
8
- ivar = "@#{target}".delete("?").to_sym
8
+ ivar = "@#{target}".delete('?').to_sym
9
9
 
10
10
  { target: target, ivar: ivar, **options }
11
11
  end
@@ -6,9 +6,9 @@ module Dry::Initializer::Dispatchers::PrepareReader
6
6
 
7
7
  def call(target: nil, reader: :public, **options)
8
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
9
+ when 'false', '' then nil
10
+ when 'true' then :public
11
+ when 'public', 'private', 'protected' then reader.to_sym
12
12
  else invalid_reader!(target, reader)
13
13
  end
14
14
 
@@ -21,6 +21,7 @@ module Dry::Initializer::Dispatchers::WrapType
21
21
  type ? type.call(value) : value
22
22
  else
23
23
  return [wrap_value(value, count - 1, type)] unless value.is_a?(Array)
24
+
24
25
  value.map { |item| wrap_value(item, count - 1, type) }
25
26
  end
26
27
  end
@@ -4,12 +4,12 @@ module Dry::Initializer
4
4
  extend DSL # @deprecated
5
5
  include Dry::Initializer # @deprecated
6
6
  def self.extended(klass) # @deprecated
7
- warn "[DEPRECATED] Use Dry::Initializer instead of its alias" \
8
- " Dry::Initializer::Mixin. The later will be removed in v2.1.0"
7
+ warn '[DEPRECATED] Use Dry::Initializer instead of its alias' \
8
+ ' Dry::Initializer::Mixin. The later will be removed in v2.1.0'
9
9
  super
10
10
  end
11
11
 
12
- require_relative "mixin/root"
13
- require_relative "mixin/local"
12
+ require_relative 'mixin/root'
13
+ require_relative 'mixin/local'
14
14
  end
15
15
  end
@@ -0,0 +1,5 @@
1
+ module Dry
2
+ module Initializer
3
+ VERSION = '3.0.3'.freeze
4
+ end
5
+ end
@@ -1,36 +1,36 @@
1
1
  namespace :benchmark do
2
- desc "Runs benchmarks for plain params"
2
+ desc 'Runs benchmarks for plain params'
3
3
  task :plain_params do
4
- system "ruby benchmarks/plain_params.rb"
4
+ system 'ruby benchmarks/plain_params.rb'
5
5
  end
6
6
 
7
- desc "Runs benchmarks for plain options"
7
+ desc 'Runs benchmarks for plain options'
8
8
  task :plain_options do
9
- system "ruby benchmarks/plain_options.rb"
9
+ system 'ruby benchmarks/plain_options.rb'
10
10
  end
11
11
 
12
- desc "Runs benchmarks for value coercion"
12
+ desc 'Runs benchmarks for value coercion'
13
13
  task :with_coercion do
14
- system "ruby benchmarks/with_coercion.rb"
14
+ system 'ruby benchmarks/with_coercion.rb'
15
15
  end
16
16
 
17
- desc "Runs benchmarks with defaults"
17
+ desc 'Runs benchmarks with defaults'
18
18
  task :with_defaults do
19
- system "ruby benchmarks/with_defaults.rb"
19
+ system 'ruby benchmarks/with_defaults.rb'
20
20
  end
21
21
 
22
- desc "Runs benchmarks with defaults and coercion"
22
+ desc 'Runs benchmarks with defaults and coercion'
23
23
  task :with_defaults_and_coercion do
24
- system "ruby benchmarks/with_defaults_and_coercion.rb"
24
+ system 'ruby benchmarks/with_defaults_and_coercion.rb'
25
25
  end
26
26
 
27
- desc "Runs benchmarks for several defaults"
27
+ desc 'Runs benchmarks for several defaults'
28
28
  task :compare_several_defaults do
29
- system "ruby benchmarks/with_several_defaults.rb"
29
+ system 'ruby benchmarks/with_several_defaults.rb'
30
30
  end
31
31
  end
32
32
 
33
- desc "Runs all benchmarks"
33
+ desc 'Runs all benchmarks'
34
34
  task benchmark: %i[
35
35
  benchmark:plain_params
36
36
  benchmark:plain_options