u-attributes 2.4.0 → 2.8.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.
@@ -1,58 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Micro::Attributes
4
- module Utils
5
- module Hashes
6
- def self.kind(hash)
7
- Kind::Of.(::Hash, hash)
8
- end
3
+ module Micro::Attributes::Utils
9
4
 
10
- def self.stringify_keys(arg)
11
- hash = kind(arg)
5
+ module Hashes
6
+ extend self
12
7
 
13
- return hash if hash.empty?
14
- return hash.transform_keys(&:to_s) if hash.respond_to?(:transform_keys)
8
+ def stringify_keys(arg)
9
+ hash = Kind::Hash[arg]
15
10
 
16
- hash.each_with_object({}) { |(key, val), memo| memo[key.to_s] = val }
17
- end
11
+ return hash if hash.empty?
12
+ return hash.transform_keys(&:to_s) if hash.respond_to?(:transform_keys)
18
13
 
19
- def self.symbolize_keys(arg)
20
- hash = kind(arg)
14
+ hash.each_with_object({}) { |(key, val), memo| memo[key.to_s] = val }
15
+ end
21
16
 
22
- return hash if hash.empty?
23
- return hash.transform_keys(&:to_sym) if hash.respond_to?(:transform_keys)
17
+ def symbolize_keys(arg)
18
+ hash = Kind::Hash[arg]
24
19
 
25
- hash.each_with_object({}) { |(key, val), memo| memo[key.to_sym] = val }
26
- end
20
+ return hash if hash.empty?
21
+ return hash.transform_keys(&:to_sym) if hash.respond_to?(:transform_keys)
27
22
 
28
- def self.keys_as(type, hash)
29
- return kind(hash) unless type
23
+ hash.each_with_object({}) { |(key, val), memo| memo[key.to_sym] = val }
24
+ end
30
25
 
31
- return symbolize_keys(hash) if type == Symbol || type == :symbol
32
- return stringify_keys(hash) if type == String || type == :string
26
+ def keys_as(type, hash)
27
+ return Kind::Hash[hash] unless type
33
28
 
34
- raise ArgumentError, 'argument must be one of these values: :symbol, :string, Symbol, String'.freeze
35
- end
29
+ return symbolize_keys(hash) if type == Symbol || type == :symbol
30
+ return stringify_keys(hash) if type == String || type == :string
36
31
 
37
- def self.assoc(hash, key)
38
- value = hash[key.to_s]
32
+ raise ArgumentError, 'argument must be one of these values: :symbol, :string, Symbol, String'.freeze
33
+ end
39
34
 
40
- value.nil? ? hash[key.to_sym] : value
41
- end
35
+ def assoc(hash, key)
36
+ value = hash[key.to_s]
37
+
38
+ value.nil? ? hash[key.to_sym] : value
42
39
  end
40
+ end
43
41
 
44
- module ExtractAttribute
45
- def self.call(object, key:)
46
- return object.public_send(key) if object.respond_to?(key)
42
+ module ExtractAttribute
43
+ def self.call(object, key:)
44
+ return object.public_send(key) if object.respond_to?(key)
47
45
 
48
- Hashes.assoc(object, key) if object.respond_to?(:[])
49
- end
46
+ Hashes.assoc(object, key) if object.respond_to?(:[])
47
+ end
50
48
 
51
- def self.from(object, keys:)
52
- Kind::Of.(::Array, keys).each_with_object({}) do |key, memo|
53
- memo[key] = call(object, key: key)
54
- end
49
+ def self.from(object, keys:)
50
+ Kind::Array[keys].each_with_object({}) do |key, memo|
51
+ memo[key] = call(object, key: key)
55
52
  end
56
53
  end
57
54
  end
55
+
58
56
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Attributes
5
- VERSION = '2.4.0'.freeze
5
+ VERSION = '2.8.0'.freeze
6
6
  end
7
7
  end
@@ -15,7 +15,8 @@ module Micro
15
15
 
16
16
  base.class_eval do
17
17
  private_class_method :__attributes, :__attribute_reader
18
- private_class_method :__attribute_assign, :__attributes_data_to_assign
18
+ private_class_method :__attribute_assign, :__attributes_groups
19
+ private_class_method :__attributes_required_add, :__attributes_data_to_assign
19
20
  end
20
21
 
21
22
  def base.inherited(subclass)
@@ -37,8 +38,8 @@ module Micro
37
38
  Features.all
38
39
  end
39
40
 
40
- def attribute?(name)
41
- self.class.attribute?(name)
41
+ def attribute?(name, include_all = false)
42
+ self.class.attribute?(name, include_all)
42
43
  end
43
44
 
44
45
  def attribute(name)
@@ -52,10 +53,12 @@ module Micro
52
53
  def attribute!(name, &block)
53
54
  attribute(name) { |name| return block ? block[name] : name }
54
55
 
55
- raise NameError, "undefined attribute `#{name}"
56
+ raise NameError, __attribute_access_error_message(name)
56
57
  end
57
58
 
58
- def defined_attributes
59
+ def defined_attributes(option = nil)
60
+ return self.class.attributes_by_visibility if option == :by_visibility
61
+
59
62
  @defined_attributes ||= self.class.attributes
60
63
  end
61
64
 
@@ -86,45 +89,76 @@ module Micro
86
89
  protected
87
90
 
88
91
  def attributes=(arg)
89
- hash = self.class.__attributes_keys__(arg)
92
+ hash = self.class.__attributes_keys_transform__(arg)
90
93
 
91
94
  __attributes_missing!(hash)
92
95
 
96
+ __call_before_attributes_assign
93
97
  __attributes_assign(hash)
98
+ __call_after_attributes_assign
99
+
100
+ __attributes
94
101
  end
95
102
 
96
103
  private
97
104
 
105
+ def __call_before_attributes_assign; end
106
+ def __call_after_attributes_assign; end
107
+
98
108
  def extract_attributes_from(other)
99
109
  Utils::ExtractAttribute.from(other, keys: defined_attributes)
100
110
  end
101
111
 
112
+ def __attribute_access_error_message(name)
113
+ return "tried to access a private attribute `#{name}" if attribute?(name, true)
114
+
115
+ "undefined attribute `#{name}"
116
+ end
117
+
102
118
  def __attribute_key(value)
103
- self.class.__attribute_key__(value)
119
+ self.class.__attribute_key_transform__(value)
104
120
  end
105
121
 
106
122
  def __attributes
107
123
  @__attributes ||= {}
108
124
  end
109
125
 
110
- FetchValueToAssign = -> (value, default) do
111
- if default.is_a?(Proc)
112
- default.arity > 0 ? default.call(value) : default.call
113
- else
114
- value.nil? ? default : value
115
- end
126
+ FetchValueToAssign = -> (init_hash, value, attribute_data, keep_proc = false) do
127
+ default = attribute_data[0]
128
+
129
+ value_to_assign =
130
+ if default.is_a?(Proc) && !keep_proc
131
+ case default.arity
132
+ when 0 then default.call
133
+ when 2 then default.call(value, init_hash)
134
+ else default.call(value)
135
+ end
136
+ else
137
+ value.nil? ? default : value
138
+ end
139
+
140
+ return value_to_assign unless to_freeze = attribute_data[2]
141
+ return value_to_assign.freeze if to_freeze == true
142
+ return value_to_assign.dup.freeze if to_freeze == :after_dup
143
+ return value_to_assign.clone.freeze if to_freeze == :after_clone
144
+
145
+ raise NotImplementedError
116
146
  end
117
147
 
118
148
  def __attributes_assign(hash)
119
- self.class.__attributes_data__.each do |name, default|
120
- __attribute_assign(name, FetchValueToAssign.(hash[name], default)) if attribute?(name)
149
+ self.class.__attributes_data__.each do |name, attribute_data|
150
+ __attribute_assign(name, hash, attribute_data) if attribute?(name, true)
121
151
  end
122
152
 
123
153
  __attributes.freeze
124
154
  end
125
155
 
126
- def __attribute_assign(name, value)
127
- __attributes[name] = instance_variable_set("@#{name}", value)
156
+ def __attribute_assign(name, init_hash, attribute_data)
157
+ value_to_assign = FetchValueToAssign.(init_hash, init_hash[name], attribute_data)
158
+
159
+ ivar_value = instance_variable_set("@#{name}", value_to_assign)
160
+
161
+ __attributes[name] = ivar_value if attribute_data[3] == :public
128
162
  end
129
163
 
130
164
  MISSING_KEYWORD = 'missing keyword'.freeze
data/u-attributes.gemspec CHANGED
@@ -9,11 +9,10 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Rodrigo Serradura']
10
10
  spec.email = ['rodrigo.serradura@gmail.com']
11
11
 
12
- spec.summary = %q{Create "immutable" objects. No setters, just getters!}
12
+ spec.summary = %q{Create "immutable" objects with no setters, just getters.}
13
13
  spec.description =
14
- "This gem allows you to define \"immutable\" objects, and your objects will have only getters and no setters. "\
15
- "So, if you change some object attribute, you will have a new object instance. " \
16
- "That is, you transform the object instead of modifying it."
14
+ 'This gem allows you to define "immutable" objects, when using it your objects will only have getters and no setters.' \
15
+ 'So, if you change an attribute of the object, you’ll have a new object instance.'
17
16
  spec.homepage = 'https://github.com/serradura/u-attributes'
18
17
  spec.license = 'MIT'
19
18
 
@@ -28,7 +27,7 @@ Gem::Specification.new do |spec|
28
27
 
29
28
  spec.required_ruby_version = '>= 2.2.0'
30
29
 
31
- spec.add_runtime_dependency 'kind', '>= 3.0', '< 5.0'
30
+ spec.add_runtime_dependency 'kind', '>= 4.0', '< 6.0'
32
31
 
33
32
  spec.add_development_dependency 'bundler'
34
33
  spec.add_development_dependency 'rake', '~> 13.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-12 00:00:00.000000000 Z
11
+ date: 2021-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kind
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '4.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5.0'
22
+ version: '6.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '3.0'
29
+ version: '4.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5.0'
32
+ version: '6.0'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: bundler
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -58,29 +58,32 @@ dependencies:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '13.0'
61
- description: This gem allows you to define "immutable" objects, and your objects will
62
- have only getters and no setters. So, if you change some object attribute, you will
63
- have a new object instance. That is, you transform the object instead of modifying
64
- it.
61
+ description: This gem allows you to define "immutable" objects, when using it your
62
+ objects will only have getters and no setters.So, if you change an attribute of
63
+ the object, you’ll have a new object instance.
65
64
  email:
66
65
  - rodrigo.serradura@gmail.com
67
66
  executables: []
68
67
  extensions: []
69
68
  extra_rdoc_files: []
70
69
  files:
70
+ - ".github/workflows/ci.yml"
71
71
  - ".gitignore"
72
- - ".travis.sh"
73
- - ".travis.yml"
72
+ - ".vscode/settings.json"
74
73
  - CODE_OF_CONDUCT.md
75
74
  - Gemfile
76
75
  - LICENSE.txt
77
76
  - README.md
78
77
  - Rakefile
79
78
  - bin/console
79
+ - bin/prepare_coverage
80
80
  - bin/setup
81
+ - bin/test
81
82
  - lib/micro/attributes.rb
82
83
  - lib/micro/attributes/diff.rb
83
84
  - lib/micro/attributes/features.rb
85
+ - lib/micro/attributes/features/accept.rb
86
+ - lib/micro/attributes/features/accept/strict.rb
84
87
  - lib/micro/attributes/features/activemodel_validations.rb
85
88
  - lib/micro/attributes/features/diff.rb
86
89
  - lib/micro/attributes/features/initialize.rb
@@ -89,15 +92,13 @@ files:
89
92
  - lib/micro/attributes/macros.rb
90
93
  - lib/micro/attributes/utils.rb
91
94
  - lib/micro/attributes/version.rb
92
- - lib/micro/attributes/with.rb
93
95
  - lib/u-attributes.rb
94
- - test.sh
95
96
  - u-attributes.gemspec
96
97
  homepage: https://github.com/serradura/u-attributes
97
98
  licenses:
98
99
  - MIT
99
100
  metadata: {}
100
- post_install_message:
101
+ post_install_message:
101
102
  rdoc_options: []
102
103
  require_paths:
103
104
  - lib
@@ -112,8 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  - !ruby/object:Gem::Version
113
114
  version: '0'
114
115
  requirements: []
115
- rubygems_version: 3.0.6
116
- signing_key:
116
+ rubygems_version: 3.2.17
117
+ signing_key:
117
118
  specification_version: 4
118
- summary: Create "immutable" objects. No setters, just getters!
119
+ summary: Create "immutable" objects with no setters, just getters.
119
120
  test_files: []
data/.travis.sh DELETED
@@ -1,31 +0,0 @@
1
- #!/bin/bash
2
-
3
- bundle exec rake test
4
-
5
- ACTIVEMODEL_VERSION='3.2' bundle update
6
- ACTIVEMODEL_VERSION='3.2' bundle exec rake test
7
-
8
- ACTIVEMODEL_VERSION='4.0' bundle update
9
- ACTIVEMODEL_VERSION='4.0' bundle exec rake test
10
-
11
- ACTIVEMODEL_VERSION='4.1' bundle update
12
- ACTIVEMODEL_VERSION='4.1' bundle exec rake test
13
-
14
- ACTIVEMODEL_VERSION='4.2' bundle update
15
- ACTIVEMODEL_VERSION='4.2' bundle exec rake test
16
-
17
- ACTIVEMODEL_VERSION='5.0' bundle update
18
- ACTIVEMODEL_VERSION='5.0' bundle exec rake test
19
-
20
- ACTIVEMODEL_VERSION='5.1' bundle update
21
- ACTIVEMODEL_VERSION='5.1' bundle exec rake test
22
-
23
- if [[ ! $ruby_v =~ '2.2.0' ]]; then
24
- ACTIVEMODEL_VERSION='5.2' bundle update
25
- ACTIVEMODEL_VERSION='5.2' bundle exec rake test
26
- fi
27
-
28
- if [[ $ruby_v =~ '2.5.' ]] || [[ $ruby_v =~ '2.6.' ]] || [[ $ruby_v =~ '2.7.' ]]; then
29
- ACTIVEMODEL_VERSION='6.0' bundle update
30
- ACTIVEMODEL_VERSION='6.0' bundle exec rake test
31
- fi
data/.travis.yml DELETED
@@ -1,28 +0,0 @@
1
- language: ruby
2
-
3
- rvm:
4
- - 2.2.2
5
- - 2.3.0
6
- - 2.4.0
7
- - 2.5.0
8
- - 2.6.0
9
- - 2.7.0
10
- - truffleruby-head
11
-
12
- cache: bundler
13
-
14
- before_install:
15
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
16
- - gem install bundler -v '< 2'
17
-
18
- install: bundle install --jobs=3 --retry=3
19
-
20
- before_script:
21
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
22
- - chmod +x ./cc-test-reporter
23
- - './cc-test-reporter before-build'
24
-
25
- script: './.travis.sh'
26
-
27
- after_success:
28
- - './cc-test-reporter after-build -t simplecov'
@@ -1,182 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'micro/attributes/features/diff'
4
- require 'micro/attributes/features/initialize'
5
- require 'micro/attributes/features/initialize/strict'
6
- require 'micro/attributes/features/keys_as_symbol'
7
- require 'micro/attributes/features/activemodel_validations'
8
-
9
-
10
- module Micro
11
- module Attributes
12
- module With
13
- #
14
- # Features
15
- #
16
- module Diff
17
- def self.included(base)
18
- base.send(:include, ::Micro::Attributes)
19
- base.send(:include, ::Micro::Attributes::Features::Diff)
20
- end
21
- end
22
-
23
- module Initialize
24
- def self.included(base)
25
- base.send(:include, ::Micro::Attributes)
26
- base.send(:include, ::Micro::Attributes::Features::Initialize)
27
- end
28
- end
29
-
30
- module StrictInitialize
31
- def self.included(base)
32
- base.send(:include, Initialize)
33
- base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
34
- end
35
- end
36
-
37
- module KeysAsSymbol
38
- def self.included(base)
39
- base.send(:include, ::Micro::Attributes)
40
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
41
- end
42
- end
43
-
44
- module ActiveModelValidations
45
- def self.included(base)
46
- base.send(:include, Initialize)
47
- base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
48
- end
49
- end
50
-
51
- #
52
- # Combinations
53
- #
54
- module AMValidations_Diff
55
- def self.included(base)
56
- base.send(:include, ActiveModelValidations)
57
- base.send(:include, ::Micro::Attributes::Features::Diff)
58
- end
59
- end
60
-
61
- module AMValidations_Diff_Init
62
- def self.included(base)
63
- base.send(:include, ActiveModelValidations)
64
- base.send(:include, ::Micro::Attributes::Features::Diff)
65
- end
66
- end
67
-
68
- module AMValidations_Diff_Init_KeysAsSymbol
69
- def self.included(base)
70
- base.send(:include, ActiveModelValidations)
71
- base.send(:include, ::Micro::Attributes::Features::Diff)
72
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
73
- end
74
- end
75
-
76
- module AMValidations_Diff_InitStrict
77
- def self.included(base)
78
- base.send(:include, AMValidations_Diff_Init)
79
- base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
80
- end
81
- end
82
-
83
- module AMValidations_Diff_InitStrict_KeysAsSymbol
84
- def self.included(base)
85
- base.send(:include, AMValidations_Diff_Init)
86
- base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
87
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
88
- end
89
- end
90
-
91
- module AMValidations_Diff_KeysAsSymbol
92
- def self.included(base)
93
- base.send(:include, AMValidations_Diff)
94
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
95
- end
96
- end
97
-
98
- module AMValidations_Init
99
- def self.included(base)
100
- base.send(:include, ActiveModelValidations)
101
- end
102
- end
103
-
104
- module AMValidations_Init_KeysAsSymbol
105
- def self.included(base)
106
- base.send(:include, AMValidations_Init)
107
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
108
- end
109
- end
110
-
111
- module AMValidations_InitStrict
112
- def self.included(base)
113
- base.send(:include, ActiveModelValidations)
114
- base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
115
- end
116
- end
117
-
118
- module AMValidations_InitStrict_KeysAsSymbol
119
- def self.included(base)
120
- base.send(:include, AMValidations_InitStrict)
121
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
122
- end
123
- end
124
-
125
- module AMValidations_KeysAsSymbol
126
- def self.included(base)
127
- base.send(:include, ActiveModelValidations)
128
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
129
- end
130
- end
131
-
132
- module Diff_Init
133
- def self.included(base)
134
- base.send(:include, Initialize)
135
- base.send(:include, ::Micro::Attributes::Features::Diff)
136
- end
137
- end
138
-
139
- module Diff_Init_KeysAsSymbol
140
- def self.included(base)
141
- base.send(:include, Diff_Init)
142
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
143
- end
144
- end
145
-
146
- module Diff_InitStrict
147
- def self.included(base)
148
- base.send(:include, Diff_Init)
149
- base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
150
- end
151
- end
152
-
153
- module Diff_InitStrict_KeysAsSymbol
154
- def self.included(base)
155
- base.send(:include, Diff_InitStrict)
156
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
157
- end
158
- end
159
-
160
- module Diff_KeysAsSymbol
161
- def self.included(base)
162
- base.send(:include, Diff)
163
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
164
- end
165
- end
166
-
167
- module Init_KeysAsSymbol
168
- def self.included(base)
169
- base.send(:include, Initialize)
170
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
171
- end
172
- end
173
-
174
- module InitStrict_KeysAsSymbol
175
- def self.included(base)
176
- base.send(:include, StrictInitialize)
177
- base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
178
- end
179
- end
180
- end
181
- end
182
- end