smart_initializer 0.3.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,100 +1,109 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- smart_initializer (0.2.0)
4
+ smart_initializer (0.5.0)
5
5
  qonfig (~> 0.24)
6
- smart_engine (~> 0.6)
7
- smart_types (~> 0.1.0)
6
+ smart_engine (~> 0.11)
7
+ smart_types (~> 0.4)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (6.0.3.1)
12
+ activesupport (6.1.1)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
- i18n (>= 0.7, < 2)
15
- minitest (~> 5.1)
16
- tzinfo (~> 1.1)
17
- zeitwerk (~> 2.2, >= 2.2.2)
18
- armitage-rubocop (0.85.0)
19
- rubocop (= 0.85.0)
20
- rubocop-performance (= 1.6.1)
21
- rubocop-rails (= 2.5.2)
14
+ i18n (>= 1.6, < 2)
15
+ minitest (>= 5.1)
16
+ tzinfo (~> 2.0)
17
+ zeitwerk (~> 2.3)
18
+ armitage-rubocop (1.7.0.1)
19
+ rubocop (= 1.7.0)
20
+ rubocop-performance (= 1.9.1)
21
+ rubocop-rails (= 2.9.1)
22
22
  rubocop-rake (= 0.5.1)
23
- rubocop-rspec (= 1.39.0)
24
- ast (2.4.0)
25
- concurrent-ruby (1.1.6)
26
- diff-lcs (1.3)
27
- docile (1.3.2)
28
- i18n (1.8.3)
23
+ rubocop-rspec (= 2.1.0)
24
+ ast (2.4.1)
25
+ coderay (1.1.3)
26
+ concurrent-ruby (1.1.7)
27
+ diff-lcs (1.4.4)
28
+ docile (1.3.5)
29
+ i18n (1.8.7)
29
30
  concurrent-ruby (~> 1.0)
30
- minitest (5.14.1)
31
- parallel (1.19.1)
32
- parser (2.7.1.3)
33
- ast (~> 2.4.0)
34
- qonfig (0.24.1)
35
- rack (2.2.2)
31
+ method_source (1.0.0)
32
+ minitest (5.14.3)
33
+ parallel (1.20.1)
34
+ parser (3.0.0.0)
35
+ ast (~> 2.4.1)
36
+ pry (0.13.1)
37
+ coderay (~> 1.1)
38
+ method_source (~> 1.0)
39
+ qonfig (0.25.0)
40
+ rack (2.2.3)
36
41
  rainbow (3.0.0)
37
- rake (13.0.1)
38
- regexp_parser (1.7.1)
42
+ rake (13.0.3)
43
+ regexp_parser (2.0.3)
39
44
  rexml (3.2.4)
40
- rspec (3.9.0)
41
- rspec-core (~> 3.9.0)
42
- rspec-expectations (~> 3.9.0)
43
- rspec-mocks (~> 3.9.0)
44
- rspec-core (3.9.2)
45
- rspec-support (~> 3.9.3)
46
- rspec-expectations (3.9.2)
45
+ rspec (3.10.0)
46
+ rspec-core (~> 3.10.0)
47
+ rspec-expectations (~> 3.10.0)
48
+ rspec-mocks (~> 3.10.0)
49
+ rspec-core (3.10.1)
50
+ rspec-support (~> 3.10.0)
51
+ rspec-expectations (3.10.1)
47
52
  diff-lcs (>= 1.2.0, < 2.0)
48
- rspec-support (~> 3.9.0)
49
- rspec-mocks (3.9.1)
53
+ rspec-support (~> 3.10.0)
54
+ rspec-mocks (3.10.1)
50
55
  diff-lcs (>= 1.2.0, < 2.0)
51
- rspec-support (~> 3.9.0)
52
- rspec-support (3.9.3)
53
- rubocop (0.85.0)
56
+ rspec-support (~> 3.10.0)
57
+ rspec-support (3.10.1)
58
+ rubocop (1.7.0)
54
59
  parallel (~> 1.10)
55
- parser (>= 2.7.0.1)
60
+ parser (>= 2.7.1.5)
56
61
  rainbow (>= 2.2.2, < 4.0)
57
- regexp_parser (>= 1.7)
62
+ regexp_parser (>= 1.8, < 3.0)
58
63
  rexml
59
- rubocop-ast (>= 0.0.3)
64
+ rubocop-ast (>= 1.2.0, < 2.0)
60
65
  ruby-progressbar (~> 1.7)
61
66
  unicode-display_width (>= 1.4.0, < 2.0)
62
- rubocop-ast (0.0.3)
63
- parser (>= 2.7.0.1)
64
- rubocop-performance (1.6.1)
65
- rubocop (>= 0.71.0)
66
- rubocop-rails (2.5.2)
67
- activesupport
67
+ rubocop-ast (1.4.0)
68
+ parser (>= 2.7.1.5)
69
+ rubocop-performance (1.9.1)
70
+ rubocop (>= 0.90.0, < 2.0)
71
+ rubocop-ast (>= 0.4.0)
72
+ rubocop-rails (2.9.1)
73
+ activesupport (>= 4.2.0)
68
74
  rack (>= 1.1)
69
- rubocop (>= 0.72.0)
75
+ rubocop (>= 0.90.0, < 2.0)
70
76
  rubocop-rake (0.5.1)
71
77
  rubocop
72
- rubocop-rspec (1.39.0)
73
- rubocop (>= 0.68.1)
74
- ruby-progressbar (1.10.1)
75
- simplecov (0.18.5)
78
+ rubocop-rspec (2.1.0)
79
+ rubocop (~> 1.0)
80
+ rubocop-ast (>= 1.1.0)
81
+ ruby-progressbar (1.11.0)
82
+ simplecov (0.21.2)
76
83
  docile (~> 1.1)
77
84
  simplecov-html (~> 0.11)
78
- simplecov-html (0.12.2)
79
- smart_engine (0.6.0)
80
- smart_types (0.1.0)
81
- smart_engine (~> 0.6)
82
- thread_safe (0.3.6)
83
- tzinfo (1.2.7)
84
- thread_safe (~> 0.1)
85
+ simplecov_json_formatter (~> 0.1)
86
+ simplecov-html (0.12.3)
87
+ simplecov_json_formatter (0.1.2)
88
+ smart_engine (0.11.0)
89
+ smart_types (0.4.0)
90
+ smart_engine (~> 0.11)
91
+ tzinfo (2.0.4)
92
+ concurrent-ruby (~> 1.0)
85
93
  unicode-display_width (1.7.0)
86
- zeitwerk (2.3.0)
94
+ zeitwerk (2.4.2)
87
95
 
88
96
  PLATFORMS
89
- ruby
97
+ x86_64-darwin-20
90
98
 
91
99
  DEPENDENCIES
92
- armitage-rubocop (~> 0.85)
93
- bundler (~> 2.1)
100
+ armitage-rubocop (~> 1.7)
101
+ bundler (~> 2.2)
102
+ pry (~> 0.13)
94
103
  rake (~> 13.0)
95
- rspec (~> 3.9)
96
- simplecov (~> 0.18)
104
+ rspec (~> 3.10)
105
+ simplecov (~> 0.21)
97
106
  smart_initializer!
98
107
 
99
108
  BUNDLED WITH
100
- 2.1.4
109
+ 2.2.3
@@ -23,9 +23,6 @@ module SmartCore
23
23
  require_relative 'initializer/instance_attribute_accessing'
24
24
  require_relative 'initializer/functionality'
25
25
 
26
- # @since 0.3.0
27
- include SmartCore::Initializer::InstanceAttributeAccessing
28
-
29
26
  class << self
30
27
  # @param base_klass [Class]
31
28
  # @return [void]
@@ -59,27 +59,55 @@ class SmartCore::Initializer::Attribute
59
59
  # @since 0.1.0
60
60
  def_delegator :parameters, :has_default?
61
61
 
62
+ # @return [Boolean]
63
+ #
64
+ # @api private
65
+ # @since 0.4.0
66
+ def_delegator :parameters, :read_only
67
+
68
+ # @return [String, Symbol, NilClass]
69
+ #
70
+ # @api private
71
+ # @since 0.4.0
72
+ def_delegator :parameters, :as
73
+
62
74
  # @param name [Symbol]
63
75
  # @param type [SmartCore::Initializer::TypeSystem::Interop]
64
76
  # @param type_system [Class<SmartCore::Initializer::TypeSystem::Interop>]
65
77
  # @param privacy [Symbol]
66
78
  # @param finalizer [SmartCore::Initializer::Attribute::Finalizer::AnonymousBlock/InstanceMethod]
67
79
  # @param cast [Boolean]
80
+ # @param read_only [Boolean]
81
+ # @param as [String, Symbol, NilClass]
68
82
  # @param dynamic_options [Hash<Symbol,Any>]
69
83
  # @return [void]
70
84
  #
71
85
  # @api private
72
86
  # @since 0.1.0
73
- def initialize(name, type, type_system, privacy, finalizer, cast, dynamic_options)
87
+ def initialize(name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options)
74
88
  @parameters = SmartCore::Initializer::Attribute::Parameters.new(
75
- name, type, type_system, privacy, finalizer, cast, dynamic_options
89
+ name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options
76
90
  )
77
91
  end
78
92
 
93
+ # @param value [Any]
94
+ # @return [void]
95
+ #
96
+ # @api private
97
+ # @since 0.5.1
98
+ def validate!(value)
99
+ type.validate!(value)
100
+ rescue => error
101
+ raise SmartCore::Initializer::IncorrectTypeError,
102
+ "Validation of attribute '#{name}' (#{type.identifier}, got #{value.class}) failed: " \
103
+ "#{error.message}"
104
+ end
105
+
79
106
  # @return [SmartCore::Initializer::Attribute]
80
107
  #
81
108
  # @api private
82
109
  # @since 0.1.0
110
+ # rubocop:disable Metrics/AbcSize
83
111
  def dup
84
112
  self.class.new(
85
113
  parameters.name.dup,
@@ -88,9 +116,12 @@ class SmartCore::Initializer::Attribute
88
116
  parameters.privacy,
89
117
  parameters.finalizer.dup,
90
118
  parameters.cast,
119
+ parameters.read_only,
120
+ parameters.as,
91
121
  parameters.dynamic_options.dup
92
122
  )
93
123
  end
124
+ # rubocop:enable Metrics/AbcSize
94
125
 
95
126
  private
96
127
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
+ # rubocop:disable Metrics/ClassLength
5
6
  class SmartCore::Initializer::Attribute::Factory
6
7
  class << self
7
8
  # @param name [String, Symbol]
@@ -10,18 +11,22 @@ class SmartCore::Initializer::Attribute::Factory
10
11
  # @param privacy [String, Symbol]
11
12
  # @param finalize [String, Symbol, Proc]
12
13
  # @param cast [Boolean]
14
+ # @param read_only [Boolean]
15
+ # @param as [String, Symbol, NilClass]
13
16
  # @param dynamic_options [Hash<Symbol,Any>]
14
17
  # @return [SmartCore::Initializer::Attribute]
15
18
  #
16
19
  # @api private
17
20
  # @since 0.1.0
18
- def create(name, type, type_system, privacy, finalize, cast, dynamic_options)
21
+ def create(name, type, type_system, privacy, finalize, cast, read_only, as, dynamic_options)
19
22
  prepared_name = prepare_name_param(name)
20
23
  prepared_privacy = prepare_privacy_param(privacy)
21
24
  prepared_finalize = prepare_finalize_param(finalize)
22
25
  prepared_cast = prepare_cast_param(cast)
23
26
  prepared_type_system = prepare_type_system_param(type_system)
24
27
  prepared_type = prepare_type_param(type, prepared_type_system)
28
+ prepared_read_only = prepare_read_only_param(read_only)
29
+ prepared_as = preapre_as_param(as)
25
30
  prepared_dynamic_options = prepare_dynamic_options_param(dynamic_options)
26
31
 
27
32
  create_attribute(
@@ -31,6 +36,8 @@ class SmartCore::Initializer::Attribute::Factory
31
36
  prepared_privacy,
32
37
  prepared_finalize,
33
38
  prepared_cast,
39
+ prepared_read_only,
40
+ prepared_as,
34
41
  prepared_dynamic_options
35
42
  )
36
43
  end
@@ -118,6 +125,36 @@ class SmartCore::Initializer::Attribute::Factory
118
125
  SmartCore::Initializer::Attribute::Finalizer.create(finalize)
119
126
  end
120
127
 
128
+ # @param read_only [Boolean]
129
+ # @return [Boolean]
130
+ #
131
+ # @api private
132
+ # @since 0.4.0
133
+ def prepare_read_only_param(read_only)
134
+ unless read_only.is_a?(FalseClass) || read_only.is_a?(TrueClass)
135
+ raise(SmartCore::Initializer::ArgumentError, <<~ERROR_MESSAGE)
136
+ :read_only attribute should be a type of boolean
137
+ ERROR_MESSAGE
138
+ end
139
+
140
+ read_only
141
+ end
142
+
143
+ # @param [String, Symbol, NilClass]
144
+ # @return [String, Symbol, NilClass]
145
+ #
146
+ # @api private
147
+ # @since 0.4.0
148
+ def preapre_as_param(as)
149
+ unless as.is_a?(NilClass) || as.is_a?(String) || as.is_a?(Symbol)
150
+ raise(SmartCore::Initializer::ArgumentError, <<~ERROR_MESSAGE)
151
+ Attribute alias should be a type of String or Symbol
152
+ ERROR_MESSAGE
153
+ end
154
+
155
+ as
156
+ end
157
+
121
158
  # @param dynamic_options [Hash<Symbol,Any>]
122
159
  # @return [Hash<Symbol,Any>]
123
160
  #
@@ -155,10 +192,13 @@ class SmartCore::Initializer::Attribute::Factory
155
192
  #
156
193
  # @api private
157
194
  # @since 0.1.0
158
- def create_attribute(name, type, type_system, privacy, finalize, cast, dynamic_options)
195
+ # rubocop:disable Layout/LineLength
196
+ def create_attribute(name, type, type_system, privacy, finalize, cast, read_only, as, dynamic_options)
159
197
  SmartCore::Initializer::Attribute.new(
160
- name, type, type_system, privacy, finalize, cast, dynamic_options
198
+ name, type, type_system, privacy, finalize, cast, read_only, as, dynamic_options
161
199
  )
162
200
  end
201
+ # rubocop:enable Layout/LineLength
163
202
  end
164
203
  end
204
+ # rubocop:enable Metrics/ClassLength
@@ -37,6 +37,18 @@ class SmartCore::Initializer::Attribute::Parameters
37
37
  # @since 0.1.0
38
38
  DEFAULT_DYNAMIC_OPTIONS = {}.freeze
39
39
 
40
+ # @return [Boolean]
41
+ #
42
+ # @api private
43
+ # @since 0.4.0
44
+ DEFAULT_READ_ONLY = true
45
+
46
+ # @return [NilClass]
47
+ #
48
+ # @api private
49
+ # @since 0.4.0
50
+ DEFAULT_AS = nil
51
+
40
52
  # @return [Symbol]
41
53
  #
42
54
  # @api private
@@ -81,25 +93,42 @@ class SmartCore::Initializer::Attribute::Parameters
81
93
  # @since 0.1.0
82
94
  attr_reader :dynamic_options
83
95
 
96
+ # @return [Boolean]
97
+ #
98
+ # @api private
99
+ # @since 0.4.0
100
+ attr_reader :read_only
101
+
102
+ # @return [String, Symbol, NilClass]
103
+ #
104
+ # @api private
105
+ # @since 0.4.0
106
+ attr_reader :as
107
+
84
108
  # @param name [Symbol]
85
109
  # @param type [SmartCore::Initializer::TypeSystem::Interop]
86
110
  # @param type_system [Class<SmartCore::Initializer::TypeSystem::Interop>]
87
111
  # @param privacy [Symbol]
88
112
  # @param finalizer [SmartCore::Initializer::Attribute::AnonymousBlock/InstanceMethod]
89
113
  # @param cast [Boolean]
114
+ # @param read_only [Boolean]
115
+ # @param as [NilClass, Symbol, String]
90
116
  # @param dynamic_options [Hash<Symbol,Any>]
91
117
  # - :default - default value (Proc value will be called)
92
118
  # @return [void]
93
119
  #
94
120
  # @api private
95
121
  # @since 0.1.0
96
- def initialize(name, type, type_system, privacy, finalizer, cast, dynamic_options)
122
+ # @version 0.4.0
123
+ def initialize(name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options)
97
124
  @name = name
98
125
  @type = type
99
126
  @type_system = type_system
100
127
  @privacy = privacy
101
128
  @finalizer = finalizer
102
129
  @cast = cast
130
+ @read_only = read_only
131
+ @as = as
103
132
  @dynamic_options = dynamic_options
104
133
  end
105
134
 
@@ -29,5 +29,10 @@ module SmartCore::Initializer::Configuration
29
29
  validate :default_type_system do |value|
30
30
  SmartCore::Initializer::TypeSystem.resolve(value) rescue false
31
31
  end
32
+
33
+ setting :strict_options, true
34
+ validate :strict_options do |value|
35
+ !!value == value # check if it's a boolean value
36
+ end
32
37
  end
33
38
  end
@@ -72,6 +72,7 @@ class SmartCore::Initializer::Constructor
72
72
  #
73
73
  # @api private
74
74
  # @since 0.1.0
75
+ # @version 0.7.0
75
76
  # rubocop:disable Metrics/AbcSize
76
77
  def prevent_attribute_insufficiency
77
78
  required_parameter_count = klass.__params__.size
@@ -96,7 +97,7 @@ class SmartCore::Initializer::Constructor
96
97
  raise(
97
98
  SmartCore::Initializer::OptionArgumentError,
98
99
  "Unknown options: #{unknown_options.join(', ')}"
99
- ) if unknown_options.any?
100
+ ) if unknown_options.any? && SmartCore::Initializer::Configuration[:strict_options]
100
101
  end
101
102
  # rubocop:enable Metrics/AbcSize
102
103
 
@@ -113,15 +114,16 @@ class SmartCore::Initializer::Constructor
113
114
  #
114
115
  # @api private
115
116
  # @since 0.1.0
117
+ # @version 0.5.1
116
118
  def initialize_parameters(instance)
117
- parameter_definitions = Hash[klass.__params__.zip(parameters)]
119
+ parameter_definitions = klass.__params__.zip(parameters).to_h
118
120
 
119
121
  parameter_definitions.each_pair do |attribute, parameter_value|
120
122
  if !attribute.type.valid?(parameter_value) && attribute.cast?
121
123
  parameter_value = attribute.type.cast(parameter_value)
122
124
  end
123
125
 
124
- attribute.type.validate!(parameter_value)
126
+ attribute.validate!(parameter_value)
125
127
 
126
128
  final_value = attribute.finalizer.call(parameter_value, instance)
127
129
  instance.instance_variable_set("@#{attribute.name}", final_value)
@@ -133,7 +135,7 @@ class SmartCore::Initializer::Constructor
133
135
  #
134
136
  # @api private
135
137
  # @since 0.1.0
136
- # rubocop:disable Metrics/AbcSize
138
+ # @version 0.5.1
137
139
  def initialize_options(instance)
138
140
  klass.__options__.each do |attribute|
139
141
  option_value = options.fetch(attribute.name) { attribute.default }
@@ -142,13 +144,12 @@ class SmartCore::Initializer::Constructor
142
144
  option_value = attribute.type.cast(option_value)
143
145
  end
144
146
 
145
- attribute.type.validate!(option_value)
147
+ attribute.validate!(option_value)
146
148
 
147
149
  final_value = attribute.finalizer.call(option_value, instance)
148
150
  instance.instance_variable_set("@#{attribute.name}", final_value)
149
151
  end
150
152
  end
151
- # rubocop:enable Metrics/AbcSize
152
153
 
153
154
  # @param instance [Any]
154
155
  # @return [void]