u-observers 0.4.0 → 0.9.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: d9c81561b00ca412faa80abc349e8a87251f4d84ce81da5fcd95ca1117e2bd2e
4
- data.tar.gz: da923ace22c60cac08f710dccac65367b0bb568d9b4a99fbbe8bc164c8824b12
3
+ metadata.gz: bfa6d5600e86dd6086b2d6ebd4cd1b015ebe3331bd4cd61be90f2d96a1abf601
4
+ data.tar.gz: b483b0721def3d41085260343edf1041905b376264354b6ffbd07cbb5386725f
5
5
  SHA512:
6
- metadata.gz: 69eedf04951d55a0889412d50e62e226fdfe2561a3a3a52df087f0091ec15ec696fe002fe906a00fdf15119455c4c7f7f1a54a464c83e56c3ec5d6ff143ed1f4
7
- data.tar.gz: 805003dac964746271f6b7789527e608fbd2caf77dd8f9eb735b8d30f42159e9d577f0a8bb0b3b60199fc764b40c0ae7a1edd005deb2d01f7e9567d49e18c4fd
6
+ metadata.gz: '06318ee21d6b9e842fa7ad752f9ccb137286667211fc43bed267d5593506d239fe946f03159236e00e0549c45e71d5de1f36cb1213ce698c3ad3b8edaf4c5abf'
7
+ data.tar.gz: 91aac7ae90a990f5575838bf13ddfd174066257a2b82620e82fc8af963519d9c85526aa742005b3d7c1cc78c1dba67d557f62ab233d34b30b70b8c69a945a929
@@ -0,0 +1 @@
1
+ ruby 2.6.5
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+
3
+ ruby_v=$(ruby -v)
4
+
5
+ ACTIVERECORD_VERSION='3.2' bundle update
6
+ ACTIVERECORD_VERSION='3.2' bundle exec rake test
7
+
8
+ ACTIVERECORD_VERSION='4.0' bundle update
9
+ ACTIVERECORD_VERSION='4.0' bundle exec rake test
10
+
11
+ ACTIVERECORD_VERSION='4.1' bundle update
12
+ ACTIVERECORD_VERSION='4.1' bundle exec rake test
13
+
14
+ ACTIVERECORD_VERSION='4.2' bundle update
15
+ ACTIVERECORD_VERSION='4.2' bundle exec rake test
16
+
17
+ ACTIVERECORD_VERSION='5.0' bundle update
18
+ ACTIVERECORD_VERSION='5.0' bundle exec rake test
19
+
20
+ ACTIVERECORD_VERSION='5.1' bundle update
21
+ ACTIVERECORD_VERSION='5.1' bundle exec rake test
22
+
23
+ if [[ ! $ruby_v =~ '2.2.0' ]]; then
24
+ ACTIVERECORD_VERSION='5.2' bundle update
25
+ ACTIVERECORD_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
+ ACTIVERECORD_VERSION='6.0' bundle update
30
+ ACTIVERECORD_VERSION='6.0' bundle exec rake test
31
+ fi
@@ -1,6 +1,30 @@
1
1
  ---
2
2
  language: ruby
3
- cache: bundler
3
+
4
+ sudo: false
5
+
4
6
  rvm:
5
- - 2.6.5
6
- before_install: gem install bundler -v 2.1.4
7
+ - 2.2.0
8
+ - 2.3.0
9
+ - 2.4.0
10
+ - 2.5.0
11
+ - 2.6.0
12
+ - 2.7.0
13
+
14
+ cache: bundler
15
+
16
+ before_install:
17
+ - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
18
+ - gem install bundler -v '< 2'
19
+
20
+ install: bundle install --jobs=3 --retry=3
21
+
22
+ before_script:
23
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
24
+ - chmod +x ./cc-test-reporter
25
+ - "./cc-test-reporter before-build"
26
+
27
+ script: "./.travis.sh"
28
+
29
+ after_success:
30
+ - "./cc-test-reporter after-build -t simplecov"
data/Gemfile CHANGED
@@ -3,12 +3,36 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in u-observers.gemspec
4
4
  gemspec
5
5
 
6
- gem 'rake', '~> 12.0'
7
- gem 'minitest', '~> 5.0'
6
+ activerecord_version = ENV.fetch('ACTIVERECORD_VERSION', '6.1')
7
+
8
+ activerecord = case activerecord_version
9
+ when '3.2' then '3.2.22'
10
+ when '4.0' then '4.0.13'
11
+ when '4.1' then '4.1.16'
12
+ when '4.2' then '4.2.11'
13
+ when '5.0' then '5.0.7'
14
+ when '5.1' then '5.1.7'
15
+ when '5.2' then '5.2.3'
16
+ when '6.0' then '6.0.3'
17
+ end
18
+
19
+ simplecov_version =
20
+ case RUBY_VERSION
21
+ when /\A2.[23]/ then '~> 0.17.1'
22
+ when /\A2.4/ then '~> 0.18.5'
23
+ else '~> 0.19'
24
+ end
25
+
26
+ sqlite3 =
27
+ case activerecord
28
+ when /\A6\.0/, nil then '~> 1.4.0'
29
+ else '~> 1.3.0'
30
+ end
8
31
 
9
32
  group :test do
10
- gem 'activerecord', require: 'active_record'
11
- gem 'sqlite3'
33
+ gem 'minitest', activerecord_version < '4.1' ? '~> 4.2' : '~> 5.0'
34
+ gem 'simplecov', simplecov_version, require: false
12
35
 
13
- gem 'simplecov', '~> 0.19', require: false
36
+ gem 'sqlite3', sqlite3
37
+ gem 'activerecord', activerecord, require: 'active_record'
14
38
  end
@@ -3,20 +3,19 @@ require 'micro/observers/version'
3
3
  module Micro
4
4
  module Observers
5
5
  require 'micro/observers/utils'
6
- require 'micro/observers/events_or_actions'
6
+ require 'micro/observers/events'
7
7
  require 'micro/observers/manager'
8
8
 
9
9
  module ClassMethods
10
- def notify_observers!(with:)
11
- proc { |object| with.each { |evt_or_act| object.observers.call(evt_or_act) } }
10
+ def notify_observers!(events)
11
+ proc do |object|
12
+ object.observers.subject_changed!
13
+ object.observers.send(:notify!, events)
14
+ end
12
15
  end
13
16
 
14
17
  def notify_observers(*events)
15
- notify_observers!(with: EventsOrActions[events])
16
- end
17
-
18
- def call_observers(action: :call)
19
- notify_observers!(with: EventsOrActions[action])
18
+ notify_observers!(Events[events])
20
19
  end
21
20
  end
22
21
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Observers
5
+
6
+ module Events
7
+ DEFAULTS = [:call]
8
+
9
+ def self.[](value)
10
+ values = Utils.compact_array(value)
11
+
12
+ values.empty? ? DEFAULTS : values
13
+ end
14
+
15
+ private_constant :DEFAULTS
16
+ end
17
+
18
+ end
19
+ end
@@ -4,83 +4,151 @@ module Micro
4
4
  module Observers
5
5
 
6
6
  class Manager
7
- EMPTY_HASH = {}.freeze
7
+ MapObserver = -> (observer, options) { [:observer, observer, options[:context]] }
8
+
9
+ MapSubscribers = -> (value) do
10
+ array = Utils.compact_array(value.kind_of?(Array) ? value : [])
11
+ array.map { |observer| MapObserver[observer, Utils::EMPTY_HASH] }
12
+ end
8
13
 
9
14
  EqualTo = -> (observer) do
10
- -> item { item[0] == :observer && item[1] == observer }
15
+ -> subscriber do
16
+ handler = subscriber[0] == :observer ? subscriber[1] : subscriber[2][0]
17
+ handler == observer
18
+ end
11
19
  end
12
20
 
13
21
  def self.for(subject)
14
22
  new(subject)
15
23
  end
16
24
 
17
- def initialize(subject, list = nil)
25
+ def initialize(subject, subscribers: nil)
18
26
  @subject = subject
19
27
 
20
- @list = Utils.compact_array(list.kind_of?(Array) ? list : [])
28
+ @subject_changed = false
29
+
30
+ @subscribers = MapSubscribers.call(subscribers)
21
31
  end
22
32
 
23
- def included?(observer)
24
- @list.any?(&EqualTo[observer])
33
+ def count
34
+ @subscribers.size
35
+ end
36
+
37
+ def none?
38
+ @subscribers.empty?
39
+ end
40
+
41
+ def some?
42
+ !none?
43
+ end
44
+
45
+ def subject_changed?
46
+ @subject_changed
25
47
  end
26
48
 
27
- def attach(observer, options = EMPTY_HASH)
28
- if options[:allow_duplication] || !included?(observer)
29
- @list << [:observer, observer, options[:data]]
49
+ INVALID_BOOLEAN_ERROR = 'expected a boolean (true, false)'.freeze
50
+
51
+ def subject_changed(state)
52
+ if state == true || state == false
53
+ @subject_changed = state
54
+
55
+ return self
30
56
  end
31
57
 
32
- self
58
+ raise ArgumentError, INVALID_BOOLEAN_ERROR
33
59
  end
34
60
 
35
- def on(options=EMPTY_HASH)
36
- event, callable, with = options[:event], options[:call], options[:with]
61
+ def subject_changed!
62
+ subject_changed(true)
63
+ end
37
64
 
38
- return self unless event.is_a?(Symbol) && callable.respond_to?(:call)
65
+ def included?(observer)
66
+ @subscribers.any?(&EqualTo[observer])
67
+ end
39
68
 
40
- arg = with.is_a?(Proc) ? with.call(@subject) : (arg || subject)
69
+ def attach(*args)
70
+ options = args.last.is_a?(Hash) ? args.pop : Utils::EMPTY_HASH
41
71
 
42
- @list << [:callable, event, [callable, arg]]
72
+ Utils.compact_array(args).each do |observer|
73
+ @subscribers << MapObserver[observer, options] unless included?(observer)
74
+ end
75
+
76
+ self
43
77
  end
44
78
 
45
- def detach(observer)
46
- @list.delete_if(&EqualTo[observer])
79
+ def detach(*args)
80
+ Utils.compact_array(args).each do |observer|
81
+ @subscribers.delete_if(&EqualTo[observer])
82
+ end
47
83
 
48
84
  self
49
85
  end
50
86
 
51
- def notify(event)
52
- notify!(event)
87
+ def on(options = Utils::EMPTY_HASH)
88
+ event, callable, with = options[:event], options[:call], options[:with]
89
+
90
+ return self unless event.is_a?(Symbol) && callable.respond_to?(:call)
91
+
92
+ @subscribers << [:callable, event, [callable, with]] unless included?(callable)
53
93
 
54
94
  self
55
95
  end
56
96
 
57
- def call(*actions)
58
- EventsOrActions[actions].each { |act| notify!(act) }
97
+ def notify(*events)
98
+ notify!(Events[events])
99
+ end
100
+
101
+ def call(*events)
102
+ broadcast(Events[events])
59
103
 
60
104
  self
61
105
  end
62
106
 
107
+ protected
108
+
109
+ def notify!(events)
110
+ return self unless subject_changed?
111
+
112
+ broadcast(events)
113
+
114
+ subject_changed(false)
115
+
116
+ self
117
+ end
118
+
63
119
  private
64
120
 
65
- def notify!(evt_or_act)
66
- @list.each do |strategy, observer, data|
67
- call!(observer, strategy, data, with: evt_or_act)
121
+ def broadcast(events)
122
+ events.each do |event|
123
+ @subscribers.each { |subscriber| call!(subscriber, event) }
68
124
  end
69
125
  end
70
126
 
71
- def call!(observer, strategy, data, with:)
72
- return data[0].call(data[1]) if strategy == :callable && observer == with
127
+ def call!(subscriber, event)
128
+ strategy, observer, context = subscriber
73
129
 
74
- if strategy == :observer && observer.respond_to?(with)
75
- handler = observer.method(with)
130
+ return call_observer(observer, event, context) if strategy == :observer
76
131
 
77
- return handler.call(@subject) if handler.arity == 1
132
+ return call_callable(context) if strategy == :callable && observer == event
133
+ end
78
134
 
79
- handler.call(@subject, data)
80
- end
135
+ def call_callable(context)
136
+ callable, with = context[0], context[1]
137
+
138
+ arg = with.is_a?(Proc) ? with.call(@subject) : (with || @subject)
139
+
140
+ callable.call(arg)
141
+ end
142
+
143
+ def call_observer(observer, method_name, context)
144
+ return unless observer.respond_to?(method_name)
145
+
146
+ handler = observer.is_a?(Proc) ? observer : observer.method(method_name)
147
+
148
+ handler.arity == 1 ? handler.call(@subject) : handler.call(@subject, context)
81
149
  end
82
150
 
83
- private_constant :EMPTY_HASH, :EqualTo
151
+ private_constant :MapObserver, :MapSubscribers, :EqualTo, :INVALID_BOOLEAN_ERROR
84
152
  end
85
153
 
86
154
  end
@@ -4,6 +4,8 @@ module Micro
4
4
  module Observers
5
5
 
6
6
  module Utils
7
+ EMPTY_HASH = {}.freeze
8
+
7
9
  def self.compact_array(value)
8
10
  Array(value).flatten.tap(&:compact!)
9
11
  end
@@ -1,5 +1,5 @@
1
1
  module Micro
2
2
  module Observers
3
- VERSION = '0.4.0'
3
+ VERSION = '0.9.0'
4
4
  end
5
5
  end
data/test.sh ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+
3
+ bundle
4
+
5
+ rm Gemfile.lock
6
+
7
+ source $(dirname $0)/.travis.sh
8
+
9
+ rm Gemfile.lock
10
+
11
+ bundle
@@ -10,7 +10,6 @@ Gem::Specification.new do |spec|
10
10
  spec.description = %q{Simple and powerful implementation of the observer pattern.}
11
11
  spec.homepage = 'https://github.com/serradura/u-observers'
12
12
  spec.license = 'MIT'
13
- spec.required_ruby_version = Gem::Requirement.new('>= 2.2.0')
14
13
 
15
14
  spec.metadata['homepage_uri'] = spec.homepage
16
15
  spec.metadata['source_code_uri'] = 'https://github.com/serradura/u-observers'
@@ -24,4 +23,9 @@ Gem::Specification.new do |spec|
24
23
  spec.bindir = 'exe'
25
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
25
  spec.require_paths = ['lib']
26
+
27
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.2.0')
28
+
29
+ spec.add_development_dependency 'bundler'
30
+ spec.add_development_dependency 'rake', '~> 13.0'
27
31
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-observers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.9.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: 2020-09-26 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2020-09-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '13.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '13.0'
13
41
  description: Simple and powerful implementation of the observer pattern.
14
42
  email:
15
43
  - rodrigo.serradura@gmail.com
@@ -18,6 +46,8 @@ extensions: []
18
46
  extra_rdoc_files: []
19
47
  files:
20
48
  - ".gitignore"
49
+ - ".tool-versions"
50
+ - ".travis.sh"
21
51
  - ".travis.yml"
22
52
  - CODE_OF_CONDUCT.md
23
53
  - Gemfile
@@ -27,11 +57,12 @@ files:
27
57
  - bin/console
28
58
  - bin/setup
29
59
  - lib/micro/observers.rb
30
- - lib/micro/observers/events_or_actions.rb
60
+ - lib/micro/observers/events.rb
31
61
  - lib/micro/observers/manager.rb
32
62
  - lib/micro/observers/utils.rb
33
63
  - lib/micro/observers/version.rb
34
64
  - lib/u-observers.rb
65
+ - test.sh
35
66
  - u-observers.gemspec
36
67
  homepage: https://github.com/serradura/u-observers
37
68
  licenses:
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Micro
4
- module Observers
5
-
6
- module EventsOrActions
7
- DEFAULT = [:call]
8
-
9
- def self.[](values)
10
- vals = Utils.compact_array(values)
11
-
12
- vals.empty? ? DEFAULT : vals
13
- end
14
-
15
- private_constant :DEFAULT
16
- end
17
-
18
- end
19
- end