u-attributes 1.0.0 → 2.0.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.
@@ -7,6 +7,7 @@ module Micro::Attributes
7
7
  base.class_eval(<<-RUBY)
8
8
  def initialize(arg)
9
9
  self.attributes = arg
10
+ __call_after_micro_attribute
10
11
  end
11
12
  RUBY
12
13
  end
@@ -18,6 +19,10 @@ module Micro::Attributes
18
19
  def with_attributes(arg)
19
20
  self.class.new(attributes.merge(arg))
20
21
  end
22
+
23
+ private
24
+
25
+ def __call_after_micro_attribute; end
21
26
  end
22
27
  end
23
28
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro::Attributes
4
+ module Features
5
+ module Initialize
6
+ module Strict
7
+ MISSING_KEYWORD = 'missing keyword'.freeze
8
+ MISSING_KEYWORDS = 'missing keywords'.freeze
9
+
10
+ protected def attributes=(arg)
11
+ arg_hash = Utils.stringify_hash_keys(arg)
12
+ att_data = self.class.__attributes_data__
13
+
14
+ attributes_missing!(ref: att_data, arg: arg_hash)
15
+
16
+ __attributes_set(arg_hash, att_data)
17
+ end
18
+
19
+ private def attributes_missing!(ref:, arg:)
20
+ missing_keys = attributes_missing(ref, arg)
21
+
22
+ return if missing_keys.empty?
23
+
24
+ label = missing_keys.size == 1 ? MISSING_KEYWORD : MISSING_KEYWORDS
25
+
26
+ raise ArgumentError, "#{label}: #{missing_keys.join(', ')}"
27
+ end
28
+
29
+ private def attributes_missing(ref, arg)
30
+ ref.each_with_object([]) do |(key, val), memo|
31
+ memo << ":#{key}" if val.nil? && !arg.has_key?(key)
32
+ end
33
+ end
34
+
35
+ private_constant :MISSING_KEYWORD, :MISSING_KEYWORDS
36
+ end
37
+ end
38
+ end
39
+ end
@@ -3,8 +3,8 @@
3
3
  module Micro
4
4
  module Attributes
5
5
  module Macros
6
- def __attributes_data
7
- @__attributes_data ||= {}
6
+ def __attributes_data__
7
+ @__attributes_data__ ||= {}
8
8
  end
9
9
 
10
10
  def __attributes
@@ -13,58 +13,60 @@ module Micro
13
13
 
14
14
  def __attribute_reader(name)
15
15
  __attributes.add(name)
16
+
16
17
  attr_reader(name)
17
18
  end
18
19
 
19
- def __attribute_set(key, value, can_overwrite)
20
+ def __attribute_set(key, can_overwrite, options)
20
21
  name = key.to_s
21
22
  has_attribute = attribute?(name)
23
+
22
24
  __attribute_reader(name) unless has_attribute
23
- __attributes_data[name] = value if can_overwrite || !has_attribute
24
- end
25
+ __attributes_data__[name] = options[:default] if can_overwrite || !has_attribute
25
26
 
26
- def __attributes_def(arg, can_overwrite)
27
- return __attribute_set(arg, nil, can_overwrite) unless arg.is_a?(::Hash)
28
- arg.each { |key, val| __attribute_set(key, val, can_overwrite) }
27
+ __call_after_attribute_set__(name, options)
29
28
  end
30
29
 
31
- def __attributes_set(args, can_overwrite)
32
- args.flatten.each { |arg| __attributes_def(arg, can_overwrite) }
30
+ def __call_after_attribute_set__(attr_name, options); end
31
+
32
+ def __attributes_set_after_inherit__(arg)
33
+ arg.each { |key, val| __attribute_set(key, true, default: val) }
33
34
  end
34
35
 
35
36
  def attribute?(name)
36
37
  __attributes.member?(name.to_s)
37
38
  end
38
39
 
39
- def attribute(name, value=nil)
40
- __attribute_set(name, value, false)
40
+ def attribute(name, options = Kind::Empty::HASH)
41
+ __attribute_set(name, false, options)
41
42
  end
42
43
 
43
44
  def attributes(*args)
44
45
  return __attributes.to_a if args.empty?
45
- __attributes_set(args, can_overwrite: false)
46
- end
47
46
 
48
- def attributes_data(arg)
49
- __attributes_data.merge(AttributesUtils.stringify_hash_keys!(arg))
47
+ args.flatten!
48
+ args.each do |arg|
49
+ if arg.is_a?(String) || arg.is_a?(Symbol)
50
+ __attribute_set(arg, false, Kind::Empty::HASH)
51
+ else
52
+ raise Kind::Error.new('String/Symbol'.freeze, arg)
53
+ end
54
+ end
50
55
  end
51
56
 
52
57
  module ForSubclasses
53
58
  WRONG_NUMBER_OF_ARGS = 'wrong number of arguments (given 0, expected 1 or more)'.freeze
54
59
 
55
- def attribute!(name, value=nil)
56
- __attribute_set(name, value, true)
57
- end
58
-
59
- def attributes!(*args)
60
- return __attributes_set(args, can_overwrite: true) unless args.empty?
61
- raise ArgumentError, WRONG_NUMBER_OF_ARGS
60
+ def attribute!(name, options = Kind::Empty::HASH)
61
+ __attribute_set(name, true, options)
62
62
  end
63
63
 
64
64
  private_constant :WRONG_NUMBER_OF_ARGS
65
65
  end
66
+
66
67
  private_constant :ForSubclasses
67
68
  end
69
+
68
70
  private_constant :Macros
69
71
  end
70
72
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Attributes
5
+ module Utils
6
+ def self.stringify_hash_keys(arg)
7
+ hash = Kind::Of.(::Hash, arg)
8
+
9
+ return hash if hash.empty?
10
+
11
+ if hash.respond_to?(:transform_keys)
12
+ hash.transform_keys { |key| key.to_s }
13
+ else
14
+ hash.each_with_object({}) { |(key, val), memo| memo[key.to_s] = val }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Attributes
5
- VERSION = '1.0.0'.freeze
5
+ VERSION = '2.0.0'.freeze
6
6
  end
7
7
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'micro/attributes/features/diff'
4
4
  require 'micro/attributes/features/initialize'
5
+ require 'micro/attributes/features/initialize/strict'
5
6
  require 'micro/attributes/features/activemodel_validations'
6
- require 'micro/attributes/features/strict_initialize'
7
7
 
8
8
  module Micro
9
9
  module Attributes
@@ -34,8 +34,8 @@ module Micro
34
34
 
35
35
  module StrictInitialize
36
36
  def self.included(base)
37
- base.send(:include, ::Micro::Attributes)
38
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
37
+ base.send(:include, Initialize)
38
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
39
39
  end
40
40
  end
41
41
 
@@ -52,9 +52,8 @@ module Micro
52
52
 
53
53
  module DiffAndStrictInitialize
54
54
  def self.included(base)
55
- base.send(:include, ::Micro::Attributes)
56
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
57
- base.send(:include, ::Micro::Attributes::Features::Diff)
55
+ base.send(:include, DiffAndInitialize)
56
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
58
57
  end
59
58
  end
60
59
 
@@ -76,9 +75,8 @@ module Micro
76
75
 
77
76
  module ActiveModelValidationsAndStrictInitialize
78
77
  def self.included(base)
79
- base.send(:include, ::Micro::Attributes)
80
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
81
- base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
78
+ base.send(:include, ActiveModelValidationsAndInitialize)
79
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
82
80
  end
83
81
  end
84
82
 
@@ -93,10 +91,8 @@ module Micro
93
91
 
94
92
  module ActiveModelValidationsAndDiffAndStrictInitialize
95
93
  def self.included(base)
96
- base.send(:include, ::Micro::Attributes)
97
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
98
- base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
99
- base.send(:include, ::Micro::Attributes::Features::Diff)
94
+ base.send(:include, ActiveModelValidationsAndDiffAndInitialize)
95
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
100
96
  end
101
97
  end
102
98
  end
@@ -1,28 +1,32 @@
1
1
 
2
- lib = File.expand_path("../lib", __FILE__)
2
+ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "micro/attributes/version"
4
+ require 'micro/attributes/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "u-attributes"
7
+ spec.name = 'u-attributes'
8
8
  spec.version = Micro::Attributes::VERSION
9
- spec.authors = ["Rodrigo Serradura"]
10
- spec.email = ["rodrigo.serradura@gmail.com"]
9
+ spec.authors = ['Rodrigo Serradura']
10
+ spec.email = ['rodrigo.serradura@gmail.com']
11
11
 
12
12
  spec.summary = %q{Define read-only attributes}
13
13
  spec.description = %q{This gem allows defining read-only attributes, that is, your objects will have only getters to access their attributes data.}
14
- spec.homepage = "https://github.com/serradura/u-attributes"
15
- spec.license = "MIT"
14
+ spec.homepage = 'https://github.com/serradura/u-attributes'
15
+ spec.license = 'MIT'
16
16
 
17
17
  # Specify which files should be added to the gem when it is released.
18
18
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
19
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
20
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
21
  end
22
- spec.bindir = "exe"
22
+ spec.bindir = 'exe'
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
- spec.require_paths = ["lib"]
24
+ spec.require_paths = ['lib']
25
25
 
26
26
  spec.required_ruby_version = '>= 2.2.0'
27
- spec.add_development_dependency "rake", "~> 10.0"
27
+
28
+ spec.add_runtime_dependency 'kind', '>= 3.0', '< 5.0'
29
+
30
+ spec.add_development_dependency 'bundler'
31
+ spec.add_development_dependency 'rake', '~> 13.0'
28
32
  end
metadata CHANGED
@@ -1,29 +1,63 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-29 00:00:00.000000000 Z
11
+ date: 2020-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kind
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
13
47
  - !ruby/object:Gem::Dependency
14
48
  name: rake
15
49
  requirement: !ruby/object:Gem::Requirement
16
50
  requirements:
17
51
  - - "~>"
18
52
  - !ruby/object:Gem::Version
19
- version: '10.0'
53
+ version: '13.0'
20
54
  type: :development
21
55
  prerelease: false
22
56
  version_requirements: !ruby/object:Gem::Requirement
23
57
  requirements:
24
58
  - - "~>"
25
59
  - !ruby/object:Gem::Version
26
- version: '10.0'
60
+ version: '13.0'
27
61
  description: This gem allows defining read-only attributes, that is, your objects
28
62
  will have only getters to access their attributes data.
29
63
  email:
@@ -37,20 +71,20 @@ files:
37
71
  - ".travis.yml"
38
72
  - CODE_OF_CONDUCT.md
39
73
  - Gemfile
40
- - Gemfile.lock
41
74
  - LICENSE.txt
42
75
  - README.md
43
76
  - Rakefile
44
77
  - bin/console
45
78
  - bin/setup
46
79
  - lib/micro/attributes.rb
47
- - lib/micro/attributes/attributes_utils.rb
80
+ - lib/micro/attributes/diff.rb
48
81
  - lib/micro/attributes/features.rb
49
82
  - lib/micro/attributes/features/activemodel_validations.rb
50
83
  - lib/micro/attributes/features/diff.rb
51
84
  - lib/micro/attributes/features/initialize.rb
52
- - lib/micro/attributes/features/strict_initialize.rb
85
+ - lib/micro/attributes/features/initialize/strict.rb
53
86
  - lib/micro/attributes/macros.rb
87
+ - lib/micro/attributes/utils.rb
54
88
  - lib/micro/attributes/version.rb
55
89
  - lib/micro/attributes/with.rb
56
90
  - lib/u-attributes.rb
@@ -75,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
109
  - !ruby/object:Gem::Version
76
110
  version: '0'
77
111
  requirements: []
78
- rubygems_version: 3.0.3
112
+ rubygems_version: 3.0.6
79
113
  signing_key:
80
114
  specification_version: 4
81
115
  summary: Define read-only attributes
@@ -1,29 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- u-attributes (1.0.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- docile (1.3.2)
10
- json (2.2.0)
11
- minitest (5.11.3)
12
- rake (10.5.0)
13
- simplecov (0.17.0)
14
- docile (~> 1.1)
15
- json (>= 1.8, < 3)
16
- simplecov-html (~> 0.10.0)
17
- simplecov-html (0.10.2)
18
-
19
- PLATFORMS
20
- ruby
21
-
22
- DEPENDENCIES
23
- minitest (~> 5.0)
24
- rake (~> 10.0)
25
- simplecov
26
- u-attributes!
27
-
28
- BUNDLED WITH
29
- 1.17.3
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Micro
4
- module Attributes
5
- module AttributesUtils
6
- ARGUMENT_ERROR_MSG = 'argument must be a Hash'.freeze
7
-
8
- def self.hash_argument!(arg)
9
- return arg if arg.is_a?(Hash)
10
-
11
- raise ArgumentError, ARGUMENT_ERROR_MSG
12
- end
13
-
14
- def self.stringify_hash_keys!(arg)
15
- hash_argument!(arg).each_with_object({}) do |(key, val), memo|
16
- memo[key.to_s] = val
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Micro::Attributes
4
- module Features
5
- module StrictInitialize
6
- MISSING_KEYWORD = 'missing keyword'.freeze
7
- MISSING_KEYWORDS = 'missing keywords'.freeze
8
-
9
- def self.included(base)
10
- base.send(:include, ::Micro::Attributes::Features::Initialize)
11
- end
12
-
13
- protected def attributes=(arg)
14
- arg_hash = AttributesUtils.stringify_hash_keys!(arg)
15
- att_data = self.class.attributes_data({})
16
-
17
- attributes_missing!(ref: att_data, arg: arg_hash)
18
-
19
- att_data.merge(arg_hash).each { |name, value| __attribute_set(name, value) }
20
-
21
- __attributes.freeze
22
- end
23
-
24
- private def attributes_missing!(ref:, arg:)
25
- missing_keys = attributes_missing(ref, arg)
26
-
27
- return if missing_keys.empty?
28
-
29
- label = missing_keys.size == 1 ? MISSING_KEYWORD : MISSING_KEYWORDS
30
-
31
- raise ArgumentError, "#{label}: #{missing_keys.join(', ')}"
32
- end
33
-
34
- private def attributes_missing(ref, arg)
35
- ref.each_with_object([]) do |(key, val), memo|
36
- memo << ":#{key}" if val.nil? && !arg.has_key?(key)
37
- end
38
- end
39
-
40
- private_constant :MISSING_KEYWORD, :MISSING_KEYWORDS
41
- end
42
- end
43
- end