u-observers 0.4.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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