u-attributes 0.14.0 → 1.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/.travis.yml +21 -11
- data/Gemfile +4 -5
- data/Gemfile.lock +1 -1
- data/README.md +126 -29
- data/lib/micro/attributes/features/strict_initialize.rb +43 -0
- data/lib/micro/attributes/features.rb +13 -2
- data/lib/micro/attributes/version.rb +1 -1
- data/lib/micro/attributes/with.rb +33 -0
- data/lib/micro/attributes.rb +15 -11
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3daaa2daf1f8ce4a90b6053e8a5a35d5f066197a15b4353f8f5e09717639bba
|
4
|
+
data.tar.gz: '0499ade9185a2406a06acbc9d33b2e3de808ee23e5625af436253f0d654c7762'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a8ca5c7ee283753e8cbc1a6bf43580d71d98578bb0462464753da03df03c4c2a967629ae54be767a35b5d25720d38b07b85b992546eead410fcbd2180b547f1
|
7
|
+
data.tar.gz: b1cf4055d9e3cc08c87d4fefe2a6b91797fcab85904f0697299cfd22525a0615a3e0d947339bac23ae3fd8b3113c11b05cd8c1609f38adaaaabb1b3781513e1a
|
data/.travis.yml
CHANGED
@@ -1,18 +1,28 @@
|
|
1
|
-
---
|
2
|
-
sudo: false
|
3
1
|
language: ruby
|
4
|
-
|
2
|
+
|
3
|
+
sudo: false
|
4
|
+
|
5
5
|
rvm:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
- 2.2.2
|
7
|
+
- 2.3.0
|
8
|
+
- 2.4.0
|
9
|
+
- 2.5.0
|
10
|
+
- 2.6.0
|
11
|
+
|
12
|
+
cache: bundler
|
13
|
+
|
11
14
|
before_install:
|
12
15
|
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
13
16
|
- gem install bundler -v '< 2'
|
17
|
+
|
14
18
|
install: bundle install --jobs=3 --retry=3
|
15
|
-
env:
|
16
|
-
- DISABLE_SIMPLECOV=true
|
17
|
-
script: ./.travis.sh
|
18
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"
|
data/Gemfile
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'simplecov', require: false, group: :test
|
4
|
-
|
5
3
|
activemodel_version = ENV.fetch('ACTIVEMODEL_VERSION', '6.1')
|
6
4
|
|
7
5
|
activemodel = case activemodel_version
|
@@ -20,9 +18,10 @@ if activemodel_version < '6.1'
|
|
20
18
|
gem 'activesupport', activemodel, require: false
|
21
19
|
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
gem '
|
21
|
+
group :test do
|
22
|
+
gem 'minitest', activemodel_version < '4.1' ? '~> 4.2' : '~> 5.0'
|
23
|
+
gem 'simplecov', require: false
|
24
|
+
end
|
26
25
|
|
27
26
|
# Specify your gem's dependencies in u-attributes.gemspec
|
28
27
|
gemspec
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
[](https://rubygems.org/gems/u-attributes)
|
2
|
+
[](https://travis-ci.com/serradura/u-attributes)
|
3
|
+
[](https://codeclimate.com/github/serradura/u-attributes/maintainability)
|
4
|
+
[](https://codeclimate.com/github/serradura/u-attributes/test_coverage)
|
2
5
|
|
3
6
|
μ-attributes (Micro::Attributes)
|
4
7
|
================================
|
@@ -6,23 +9,25 @@
|
|
6
9
|
This gem allows defining read-only attributes, that is, your objects will have only getters to access their attributes data.
|
7
10
|
|
8
11
|
## Table of contents
|
9
|
-
- [μ-attributes (Micro::Attributes)](#%
|
10
|
-
- [Table of contents](#
|
11
|
-
- [Installation](#
|
12
|
-
- [Usage](#
|
13
|
-
- [How to require?](#
|
14
|
-
- [How to define attributes?](#
|
15
|
-
- [How to define multiple attributes?](#
|
16
|
-
- [How to define attributes with a constructor to assign them?](#
|
17
|
-
- [How to
|
18
|
-
|
19
|
-
|
20
|
-
- [
|
21
|
-
- [
|
22
|
-
|
23
|
-
|
24
|
-
- [
|
25
|
-
- [
|
12
|
+
- [μ-attributes (Micro::Attributes)](#%ce%bc-attributes-microattributes)
|
13
|
+
- [Table of contents](#table-of-contents)
|
14
|
+
- [Installation](#installation)
|
15
|
+
- [Usage](#usage)
|
16
|
+
- [How to require?](#how-to-require)
|
17
|
+
- [How to define attributes?](#how-to-define-attributes)
|
18
|
+
- [How to define multiple attributes?](#how-to-define-multiple-attributes)
|
19
|
+
- [How to define attributes with a constructor to assign them?](#how-to-define-attributes-with-a-constructor-to-assign-them)
|
20
|
+
- [How to inherit the attributes?](#how-to-inherit-the-attributes)
|
21
|
+
- [How to query the attributes?](#how-to-query-the-attributes)
|
22
|
+
- [Built-in extensions](#built-in-extensions)
|
23
|
+
- [ActiveModel::Validations extension](#activemodelvalidations-extension)
|
24
|
+
- [Diff extension](#diff-extension)
|
25
|
+
- [Initialize extension](#initialize-extension)
|
26
|
+
- [Strict initialize extension](#strict-initialize-extension)
|
27
|
+
- [Development](#development)
|
28
|
+
- [Contributing](#contributing)
|
29
|
+
- [License](#license)
|
30
|
+
- [Code of Conduct](#code-of-conduct)
|
26
31
|
|
27
32
|
## Installation
|
28
33
|
|
@@ -198,9 +203,40 @@ puts other_person.equal?(person) # false
|
|
198
203
|
# Person.new(1)
|
199
204
|
# ArgumentError (argument must be a Hash)
|
200
205
|
|
201
|
-
|
202
|
-
#
|
203
|
-
|
206
|
+
#--------------------#
|
207
|
+
# Strict initializer #
|
208
|
+
#--------------------#
|
209
|
+
|
210
|
+
# Use .to_initialize! to forbids an instantiation without all keywords.
|
211
|
+
|
212
|
+
class StrictPerson
|
213
|
+
include Micro::Attributes.to_initialize!
|
214
|
+
|
215
|
+
attributes :age, name: 'John Doe'
|
216
|
+
end
|
217
|
+
|
218
|
+
StrictPerson.new({})
|
219
|
+
|
220
|
+
# The code above will raise:
|
221
|
+
# ArgumentError (missing keyword: :age)
|
222
|
+
|
223
|
+
person_without_age = StrictPerson.new(age: nil)
|
224
|
+
|
225
|
+
p person_without_age.name # "John Doe"
|
226
|
+
p person_without_age.age # nil
|
227
|
+
|
228
|
+
# Except for this validation when initializing,
|
229
|
+
# the `to_initialize!` method will works in the same ways of `to_initialize`.
|
230
|
+
```
|
231
|
+
|
232
|
+
### How to inherit the attributes?
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
class Person
|
236
|
+
include Micro::Attributes.to_initialize
|
237
|
+
|
238
|
+
attributes :age, name: 'John Doe'
|
239
|
+
end
|
204
240
|
|
205
241
|
class Subclass < Person # Will preserve the parent class attributes
|
206
242
|
attribute :foo
|
@@ -322,11 +358,11 @@ end
|
|
322
358
|
# Note:
|
323
359
|
# If `Micro::Attributes.features()` be invoked without arguments, a module with all features will be returned.
|
324
360
|
|
325
|
-
|
326
|
-
# Using the .with() method alias and adding the initialize extension. #
|
327
|
-
|
361
|
+
#----------------------------------------------------------------------------#
|
362
|
+
# Using the .with() method alias and adding the strict initialize extension. #
|
363
|
+
#----------------------------------------------------------------------------#
|
328
364
|
class Job
|
329
|
-
include Micro::Attributes.with(:
|
365
|
+
include Micro::Attributes.with(:strict_initialize, :diff)
|
330
366
|
|
331
367
|
attributes :id, state: 'sleeping'
|
332
368
|
end
|
@@ -338,14 +374,26 @@ end
|
|
338
374
|
# include Micro::Attributes.with() # ArgumentError (Invalid feature name! Available options: diff, initialize, activemodel_validations)
|
339
375
|
# end
|
340
376
|
|
377
|
+
#===================================#
|
378
|
+
# Alternatives to the methods above #
|
379
|
+
#===================================#
|
380
|
+
|
341
381
|
#---------------------------------------#
|
342
382
|
# Via Micro::Attributes.to_initialize() #
|
343
383
|
#---------------------------------------#
|
344
384
|
class Job
|
345
|
-
include Micro::Attributes.to_initialize(diff:
|
385
|
+
include Micro::Attributes.to_initialize(diff: true, activemodel_validations: true)
|
346
386
|
|
347
|
-
|
348
|
-
|
387
|
+
# Same of `include Micro::Attributes.with(:initialize, :diff, :activemodel_validations)`
|
388
|
+
end
|
389
|
+
|
390
|
+
#----------------------------------------#
|
391
|
+
# Via Micro::Attributes.to_initialize!() #
|
392
|
+
#----------------------------------------#
|
393
|
+
class Job
|
394
|
+
include Micro::Attributes.to_initialize!(diff: false, activemodel_validations: true)
|
395
|
+
|
396
|
+
# Same of `include Micro::Attributes.with(:strict_initialize, :activemodel_validations)`
|
349
397
|
end
|
350
398
|
```
|
351
399
|
|
@@ -428,14 +476,19 @@ p job_changes.differences # {"state"=> {"from" => "sleeping", "to" => "running"}
|
|
428
476
|
|
429
477
|
```ruby
|
430
478
|
class Job
|
431
|
-
# include Micro::Attributes.features(:initialize)
|
432
479
|
# include Micro::Attributes.with(:initialize)
|
433
480
|
# include Micro::Attributes.feature(:initialize)
|
481
|
+
# include Micro::Attributes.features(:initialize)
|
434
482
|
include Micro::Attributes.to_initialize
|
435
483
|
|
436
484
|
attributes :id, :state
|
437
485
|
end
|
438
486
|
|
487
|
+
job_null = Job.new({})
|
488
|
+
|
489
|
+
p job.id # nil
|
490
|
+
p job.state # nil
|
491
|
+
|
439
492
|
job = Job.new(id: 1, state: 'sleeping')
|
440
493
|
|
441
494
|
p job.id # 1
|
@@ -468,6 +521,50 @@ puts other_job.state # killed
|
|
468
521
|
puts other_job.equal?(job) # false
|
469
522
|
```
|
470
523
|
|
524
|
+
### Strict initialize extension
|
525
|
+
|
526
|
+
1. Creates a constructor to assign the attributes.
|
527
|
+
2. Adds methods to build new instances when some data was assigned.
|
528
|
+
3. **Forbids missing keywords**.
|
529
|
+
|
530
|
+
```ruby
|
531
|
+
class Job
|
532
|
+
# include Micro::Attributes.with(:strict_initialize)
|
533
|
+
# include Micro::Attributes.feature(:strict_initialize)
|
534
|
+
# include Micro::Attributes.features(:strict_initialize)
|
535
|
+
include Micro::Attributes.to_initialize!
|
536
|
+
|
537
|
+
attributes :id, :state
|
538
|
+
end
|
539
|
+
#----------------------------------------------------------------------------#
|
540
|
+
# The strict_initialize extension will require all the keys when initialize. #
|
541
|
+
#----------------------------------------------------------------------------#
|
542
|
+
|
543
|
+
Job.new({})
|
544
|
+
|
545
|
+
# The code above will raise:
|
546
|
+
# ArgumentError (missing keywords: :id, :state)
|
547
|
+
|
548
|
+
#---------------------------#
|
549
|
+
# Samples passing some data #
|
550
|
+
#---------------------------#
|
551
|
+
|
552
|
+
job_null = Job.new({})
|
553
|
+
|
554
|
+
p job.id # nil
|
555
|
+
p job.state # nil
|
556
|
+
|
557
|
+
job = Job.new(id: 1, state: 'sleeping')
|
558
|
+
|
559
|
+
p job.id # 1
|
560
|
+
p job.state # "sleeping"
|
561
|
+
|
562
|
+
|
563
|
+
# Note:
|
564
|
+
# This extension works like the `initialize` extension.
|
565
|
+
# So, look at its section to understand all the other features.
|
566
|
+
```
|
567
|
+
|
471
568
|
## Development
|
472
569
|
|
473
570
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,43 @@
|
|
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
|
@@ -5,18 +5,22 @@ require "micro/attributes/with"
|
|
5
5
|
module Micro
|
6
6
|
module Attributes
|
7
7
|
module Features
|
8
|
-
INVALID_FEATURES = 'Invalid feature name! Available options: :initialize, :diff, :activemodel_validations'.freeze
|
8
|
+
INVALID_FEATURES = 'Invalid feature name! Available options: :initialize, :strict_initialize, :diff, :activemodel_validations'.freeze
|
9
9
|
|
10
10
|
OPTIONS = {
|
11
11
|
# Features
|
12
12
|
'diff' => With::Diff,
|
13
13
|
'initialize' => With::Initialize,
|
14
|
+
'strict_initialize' => With::StrictInitialize,
|
14
15
|
'activemodel_validations' => With::ActiveModelValidations,
|
15
16
|
# Combinations
|
16
17
|
'diff:initialize' => With::DiffAndInitialize,
|
18
|
+
'diff:strict_initialize' => With::DiffAndStrictInitialize,
|
17
19
|
'activemodel_validations:diff' => With::ActiveModelValidationsAndDiff,
|
18
20
|
'activemodel_validations:initialize' => With::ActiveModelValidationsAndInitialize,
|
19
|
-
'activemodel_validations:
|
21
|
+
'activemodel_validations:strict_initialize' => With::ActiveModelValidationsAndStrictInitialize,
|
22
|
+
'activemodel_validations:diff:initialize' => With::ActiveModelValidationsAndDiffAndInitialize,
|
23
|
+
'activemodel_validations:diff:strict_initialize' => With::ActiveModelValidationsAndDiffAndStrictInitialize
|
20
24
|
}.freeze
|
21
25
|
|
22
26
|
private_constant :OPTIONS
|
@@ -30,6 +34,13 @@ module Micro
|
|
30
34
|
return option if option
|
31
35
|
raise ArgumentError, INVALID_FEATURES
|
32
36
|
end
|
37
|
+
|
38
|
+
def self.options(init, diff, activemodel_validations)
|
39
|
+
[init].tap do |options|
|
40
|
+
options << :diff if diff
|
41
|
+
options << :activemodel_validations if activemodel_validations
|
42
|
+
end
|
43
|
+
end
|
33
44
|
end
|
34
45
|
end
|
35
46
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'micro/attributes/features/diff'
|
4
4
|
require 'micro/attributes/features/initialize'
|
5
5
|
require 'micro/attributes/features/activemodel_validations'
|
6
|
+
require 'micro/attributes/features/strict_initialize'
|
6
7
|
|
7
8
|
module Micro
|
8
9
|
module Attributes
|
@@ -31,6 +32,13 @@ module Micro
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
35
|
+
module StrictInitialize
|
36
|
+
def self.included(base)
|
37
|
+
base.send(:include, ::Micro::Attributes)
|
38
|
+
base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
34
42
|
#
|
35
43
|
# Combinations
|
36
44
|
#
|
@@ -42,6 +50,14 @@ module Micro
|
|
42
50
|
end
|
43
51
|
end
|
44
52
|
|
53
|
+
module DiffAndStrictInitialize
|
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)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
45
61
|
module ActiveModelValidationsAndDiff
|
46
62
|
def self.included(base)
|
47
63
|
base.send(:include, ::Micro::Attributes)
|
@@ -58,6 +74,14 @@ module Micro
|
|
58
74
|
end
|
59
75
|
end
|
60
76
|
|
77
|
+
module ActiveModelValidationsAndStrictInitialize
|
78
|
+
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)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
61
85
|
module ActiveModelValidationsAndDiffAndInitialize
|
62
86
|
def self.included(base)
|
63
87
|
base.send(:include, ::Micro::Attributes)
|
@@ -66,6 +90,15 @@ module Micro
|
|
66
90
|
base.send(:include, ::Micro::Attributes::Features::Diff)
|
67
91
|
end
|
68
92
|
end
|
93
|
+
|
94
|
+
module ActiveModelValidationsAndDiffAndStrictInitialize
|
95
|
+
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)
|
100
|
+
end
|
101
|
+
end
|
69
102
|
end
|
70
103
|
end
|
71
104
|
end
|
data/lib/micro/attributes.rb
CHANGED
@@ -23,10 +23,11 @@ module Micro
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.to_initialize(diff: false, activemodel_validations: false)
|
26
|
-
options
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
features(*Features.options(:initialize, diff, activemodel_validations))
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.to_initialize!(diff: false, activemodel_validations: false)
|
30
|
+
features(*Features.options(:strict_initialize, diff, activemodel_validations))
|
30
31
|
end
|
31
32
|
|
32
33
|
def self.with(*names)
|
@@ -41,18 +42,21 @@ module Micro
|
|
41
42
|
names.empty? ? Features.all : Features.with(names)
|
42
43
|
end
|
43
44
|
|
44
|
-
def attributes=(arg)
|
45
|
-
self.class
|
46
|
-
|
47
|
-
|
45
|
+
protected def attributes=(arg)
|
46
|
+
self.class
|
47
|
+
.attributes_data(AttributesUtils.hash_argument!(arg))
|
48
|
+
.each { |name, value| __attribute_set(name, value) }
|
49
|
+
|
48
50
|
__attributes.freeze
|
49
51
|
end
|
50
|
-
protected :attributes=
|
51
52
|
|
52
|
-
def __attributes
|
53
|
+
private def __attributes
|
53
54
|
@__attributes ||= {}
|
54
55
|
end
|
55
|
-
|
56
|
+
|
57
|
+
private def __attribute_set(name, value)
|
58
|
+
__attributes[name] = instance_variable_set("@#{name}", value) if attribute?(name)
|
59
|
+
end
|
56
60
|
|
57
61
|
def attributes
|
58
62
|
__attributes
|
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: 0.
|
4
|
+
version: 1.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-
|
11
|
+
date: 2019-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- lib/micro/attributes/features/activemodel_validations.rb
|
50
50
|
- lib/micro/attributes/features/diff.rb
|
51
51
|
- lib/micro/attributes/features/initialize.rb
|
52
|
+
- lib/micro/attributes/features/strict_initialize.rb
|
52
53
|
- lib/micro/attributes/macros.rb
|
53
54
|
- lib/micro/attributes/version.rb
|
54
55
|
- lib/micro/attributes/with.rb
|