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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.sh +9 -2
- data/.travis.yml +4 -3
- data/Gemfile +1 -1
- data/LICENSE.txt +2 -2
- data/README.md +285 -234
- data/Rakefile +5 -5
- data/bin/console +4 -4
- data/lib/micro/attributes.rb +58 -40
- data/lib/micro/attributes/diff.rb +52 -0
- data/lib/micro/attributes/features.rb +82 -17
- data/lib/micro/attributes/features/activemodel_validations.rb +17 -23
- data/lib/micro/attributes/features/diff.rb +2 -50
- data/lib/micro/attributes/features/initialize.rb +5 -0
- data/lib/micro/attributes/features/initialize/strict.rb +39 -0
- data/lib/micro/attributes/macros.rb +25 -23
- data/lib/micro/attributes/utils.rb +19 -0
- data/lib/micro/attributes/version.rb +1 -1
- data/lib/micro/attributes/with.rb +9 -13
- data/u-attributes.gemspec +14 -10
- metadata +42 -8
- data/Gemfile.lock +0 -29
- data/lib/micro/attributes/attributes_utils.rb +0 -21
- data/lib/micro/attributes/features/strict_initialize.rb +0 -43
@@ -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
|
7
|
-
@
|
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,
|
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
|
-
|
24
|
-
end
|
25
|
+
__attributes_data__[name] = options[:default] if can_overwrite || !has_attribute
|
25
26
|
|
26
|
-
|
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
|
32
|
-
|
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,
|
40
|
-
__attribute_set(name,
|
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
|
-
|
49
|
-
|
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,
|
56
|
-
__attribute_set(name,
|
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,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,
|
38
|
-
base.send(:include, ::Micro::Attributes::Features::
|
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,
|
56
|
-
base.send(:include, ::Micro::Attributes::Features::
|
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,
|
80
|
-
base.send(:include, ::Micro::Attributes::Features::
|
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,
|
97
|
-
base.send(:include, ::Micro::Attributes::Features::
|
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
|
data/u-attributes.gemspec
CHANGED
@@ -1,28 +1,32 @@
|
|
1
1
|
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require 'micro/attributes/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'u-attributes'
|
8
8
|
spec.version = Micro::Attributes::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
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 =
|
15
|
-
spec.license =
|
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 =
|
22
|
+
spec.bindir = 'exe'
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
-
spec.require_paths = [
|
24
|
+
spec.require_paths = ['lib']
|
25
25
|
|
26
26
|
spec.required_ruby_version = '>= 2.2.0'
|
27
|
-
|
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:
|
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:
|
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: '
|
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: '
|
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/
|
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/
|
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.
|
112
|
+
rubygems_version: 3.0.6
|
79
113
|
signing_key:
|
80
114
|
specification_version: 4
|
81
115
|
summary: Define read-only attributes
|
data/Gemfile.lock
DELETED
@@ -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
|