u-attributes 2.4.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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