u-attributes 0.9.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 63911d6718fe30f139ee9acfb5b4a4577a71c3e01222087a17a4d0f349b31935
4
- data.tar.gz: 8a3a4266c67d1e8eade0d742cf2d057c0bafb2f2e25c26c768f73cea4d40aa97
3
+ metadata.gz: e37bcd7fa7880973930c3a455850708bf22962266c5d2b09f69885dc0c7b9a8d
4
+ data.tar.gz: ed08290e3bca0a590a88a7720deb3c6e94eae93d64a12884eb108806ce2a13ce
5
5
  SHA512:
6
- metadata.gz: 927eb73d0b9cfce21e9d8abe11ab899296a6f45721d7821ea175e0bc58d144015ba22e488f1bdb6be563821a8b4e25a1082eba4c103ceedbed556ded654ab721
7
- data.tar.gz: 85bf3683290458bfb863b215fe5eca4e57e041bb2dd167e1908a629c9081d9c8417584b847b9a775d46658f8069c5d960484a9c7a2be7ffb462eac1104f4b4ca
6
+ metadata.gz: 031f5deb4ece3c5be0004290675a4bbd72e90a8b1436068054dc1acf8d949e7b4957e6b20d4f53112136cd35d15ede29d648576e7b3fe52fe0216e73012afad7
7
+ data.tar.gz: 6191e30d97bdf5cdeb06a5ece5db65877ca14304af432dc8f69077cb691fc0458a4adb1124ebf1acdbdeae4eae2682944770cb1268708680ebafd0062165a38c
@@ -3,5 +3,13 @@ sudo: false
3
3
  language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
- - 2.6.3
7
- before_install: gem install bundler -v 2.0.1
6
+ - 2.2.0
7
+ - 2.3.0
8
+ - 2.4.0
9
+ - 2.5.0
10
+ - 2.6.0
11
+ before_install:
12
+ - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
13
+ - gem install bundler -v '< 2'
14
+ env:
15
+ - DISABLE_SIMPLECOV=true
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- u-attributes (0.9.0)
4
+ u-attributes (0.10.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # μ-attributes (Micro::Attributes)
1
+ # μ-attributes (Micro::Attributes) [![Build Status](https://travis-ci.com/serradura/u-attributes.svg?branch=master)](https://travis-ci.com/serradura/u-attributes)
2
2
 
3
3
  This gem allows defining read-only attributes, that is, your objects will have only getters to access their attributes data.
4
4
 
@@ -98,9 +98,9 @@ person.attribute(:name) { |value| puts value } # John Doe
98
98
  person.attribute('age') { |value| puts value } # 20
99
99
  person.attribute('foo') { |value| puts value } # !! Nothing happened, because of the attribute not exists.
100
100
 
101
- #--------------#
102
- # #attribute() #
103
- #--------------#
101
+ #---------------#
102
+ # #attribute!() #
103
+ #---------------#
104
104
  #
105
105
  # Works like the #attribute() method, but will raise an exception when the attribute not exist.
106
106
 
@@ -264,6 +264,99 @@ p person.attributes # {"age"=>20, "name"=>"John Doe"}
264
264
  p Person.new(name: 'John').attributes # {"age"=>nil, "name"=>"John"}
265
265
  ```
266
266
 
267
+ ## Built-in extensions
268
+
269
+ You can use the method `Micro::Attributes.features()` to combine and require only the features that better fit your needs.
270
+
271
+ Note: The method `Micro::Attributes.with()` is an alias for `Micro::Attributes.features()`.
272
+
273
+ ### Diff extension
274
+
275
+ Provides a way to track changes in your object attributes.
276
+
277
+ #### How to enable?
278
+
279
+ ```ruby
280
+ #----------------------------------#
281
+ # Via Micro::Attributes.features() #
282
+ #----------------------------------#
283
+ class Job
284
+ include Micro::Attributes.features(:diff)
285
+
286
+ attributes :id, state: 'sleeping'
287
+
288
+ def initialize(options)
289
+ self.options = options
290
+ end
291
+ end
292
+
293
+ # --------------------------------------------------------------------#
294
+ # Using the .with() method alias and adding the initialize extension. #
295
+ # --------------------------------------------------------------------#
296
+
297
+ class Job
298
+ include Micro::Attributes.with(:initialize, :diff)
299
+
300
+ attributes :id, state: 'sleeping'
301
+ end
302
+
303
+ #---------------------------------------#
304
+ # Via Micro::Attributes.to_initialize() #
305
+ #---------------------------------------#
306
+ class Job
307
+ include Micro::Attributes.to_initialize(diff: true)
308
+
309
+ attribute :id
310
+ attribute :state, 'sleeping'
311
+ end
312
+ ```
313
+
314
+ #### Usage
315
+
316
+ ```ruby
317
+ require 'securerandom'
318
+
319
+ class Job
320
+ include Micro::Attributes.features(:initialize, :diff)
321
+
322
+ attributes :id, state: 'sleeping'
323
+ end
324
+
325
+ job = Job.new(id: SecureRandom.uuid())
326
+
327
+ p job.id # A random UUID generated from SecureRandom.uuid(). e.g: "e68bcc74-b91c-45c2-a904-12f1298cc60e"
328
+ p job.state # "sleeping"
329
+
330
+ job_running = job.with_attribute(:state, 'running')
331
+
332
+ p job_running.state # "running"
333
+
334
+ job_changes = job.diff_attributes(job_running)
335
+
336
+ #-----------------------------#
337
+ # #present?, #blank?, #empty? #
338
+ #-----------------------------#
339
+
340
+ p job_changes.present? # true
341
+ p job_changes.blank? # false
342
+ p job_changes.empty? # false
343
+
344
+ #-----------#
345
+ # #changed? #
346
+ #-----------#
347
+ p job_changes.changed? # true
348
+
349
+ p job_changes.changed?(:id) # false
350
+
351
+ p job_changes.changed?(:state) # true
352
+ p job_changes.changed?(:state, from: 'sleeping', to: 'running') # true
353
+
354
+ #----------------#
355
+ # #differences() #
356
+ #----------------#
357
+ p job_changes.differences # {"state"=>"running"}
358
+ ```
359
+
267
360
  ## Development
268
361
 
269
362
  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.
@@ -3,7 +3,7 @@
3
3
  require "micro/attributes/version"
4
4
  require "micro/attributes/attributes_utils"
5
5
  require "micro/attributes/macros"
6
- require "micro/attributes/to_initialize"
6
+ require "micro/attributes/features"
7
7
 
8
8
  module Micro
9
9
  module Attributes
@@ -22,23 +22,32 @@ module Micro
22
22
  end
23
23
  end
24
24
 
25
- def self.to_initialize
26
- @to_initialize ||= ::Micro::Attributes.const_get(:ToInitialize)
25
+ def self.to_initialize(diff: false)
26
+ options = [:initialize]
27
+ options << :diff if diff
28
+ features(*options)
27
29
  end
28
30
 
31
+ def self.features(*names)
32
+ Features.fetch(names)
33
+ end
34
+ singleton_class.send(:alias_method, :with, :features)
35
+
29
36
  def attributes=(arg)
30
37
  self.class.attributes_data(AttributesUtils.hash_argument!(arg)).each do |name, value|
31
- instance_variable_set("@#{name}", value) if attribute?(name)
38
+ __attributes[name] = instance_variable_set("@#{name}", value) if attribute?(name)
32
39
  end
40
+ __attributes.freeze
33
41
  end
34
42
  protected :attributes=
35
43
 
36
- def attributes
37
- state = self.class.attributes.each_with_object({}) do |name, memo|
38
- memo[name] = public_send(name) if respond_to?(name)
39
- end
44
+ def __attributes
45
+ @__attributes ||= {}
46
+ end
47
+ private :__attributes
40
48
 
41
- self.class.attributes_data(state)
49
+ def attributes
50
+ __attributes
42
51
  end
43
52
 
44
53
  def attribute?(name)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "micro/attributes/features/diff"
4
+ require "micro/attributes/features/initialize"
5
+
6
+ module Micro
7
+ module Attributes
8
+ module Features
9
+ module InitializeAndDiff
10
+ def self.included(base)
11
+ base.send(:include, ::Micro::Attributes::Features::Initialize)
12
+ base.send(:include, ::Micro::Attributes::Features::Diff)
13
+ end
14
+ end
15
+
16
+ OPTIONS = {
17
+ 'diff' => Diff,
18
+ 'initialize' => Initialize,
19
+ 'diff:initialize' => InitializeAndDiff
20
+ }.freeze
21
+
22
+ private_constant :OPTIONS
23
+
24
+ def self.fetch(names)
25
+ option = OPTIONS[names.map { |name| name.to_s.downcase }.sort.join(':')]
26
+ return option if option
27
+ raise ArgumentError, 'Invalid feature name! Available options: diff, initialize'
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro::Attributes
4
+ module Features
5
+ module Diff
6
+ class Changes
7
+ attr_reader :from, :to, :differences
8
+
9
+ def initialize(from:, to:)
10
+ raise ArgumentError, "expected an instance of #{from.class}" unless to.is_a?(from.class)
11
+ @from, @to = from, to
12
+ @differences = diff(from.attributes, to.attributes).freeze
13
+ end
14
+
15
+ def empty?
16
+ @differences.empty?
17
+ end
18
+ alias_method :blank?, :empty?
19
+
20
+ def present?
21
+ !empty?
22
+ end
23
+
24
+ def changed?(name = nil, from: nil, to: nil)
25
+ if name.nil?
26
+ return present? if from.nil? && to.nil?
27
+ raise ArgumentError, 'pass the attribute name with the :from and :to values'
28
+ elsif from.nil? && to.nil?
29
+ differences.has_key?(name.to_s)
30
+ else
31
+ key = name.to_s
32
+ @from_attributes[key] == from && @to_attributes[key] == to
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def diff(from_attributes, to_attributes)
39
+ @to_attributes = to_attributes
40
+ @from_attributes = from_attributes
41
+ @from_attributes.each_with_object({}) do |(from_key, from_val), acc|
42
+ to_value = @to_attributes[from_key]
43
+ acc[from_key] = to_value if from_val != to_value
44
+ end
45
+ end
46
+ end
47
+ private_constant :Changes
48
+
49
+ def diff_attributes(to)
50
+ return Changes.new(from: self, to: to) if to.is_a?(::Micro::Attributes)
51
+ raise ArgumentError, "#{to.inspect} must implement Micro::Attributes"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Micro
4
- module Attributes
5
- module ToInitialize
3
+ module Micro::Attributes
4
+ module Features
5
+ module Initialize
6
6
  def self.included(base)
7
7
  base.send(:include, ::Micro::Attributes)
8
8
  end
@@ -19,7 +19,5 @@ module Micro
19
19
  self.class.new(attributes.merge(arg))
20
20
  end
21
21
  end
22
-
23
- private_constant :ToInitialize
24
22
  end
25
23
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Attributes
5
- VERSION = "0.9.0"
5
+ VERSION = "0.10.0"
6
6
  end
7
7
  end
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.9.0
4
+ version: 0.10.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-08 00:00:00.000000000 Z
11
+ date: 2019-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -58,8 +58,10 @@ files:
58
58
  - bin/setup
59
59
  - lib/micro/attributes.rb
60
60
  - lib/micro/attributes/attributes_utils.rb
61
+ - lib/micro/attributes/features.rb
62
+ - lib/micro/attributes/features/diff.rb
63
+ - lib/micro/attributes/features/initialize.rb
61
64
  - lib/micro/attributes/macros.rb
62
- - lib/micro/attributes/to_initialize.rb
63
65
  - lib/micro/attributes/version.rb
64
66
  - lib/u-attributes.rb
65
67
  - u-attributes.gemspec