signal 0.1.1 → 0.2.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
  SHA1:
3
- metadata.gz: cbd0a814de4e6237f0b61910db55ee771bd2ed84
4
- data.tar.gz: ac8b02d08b219eaac0850e4ae57fa054ec4d0053
3
+ metadata.gz: 203af304645a2f533a88161c89f11d777dfbdad5
4
+ data.tar.gz: 825a4bf9ac000f1f9625b1fcbac09bacb1ac8399
5
5
  SHA512:
6
- metadata.gz: 18d186c33d95751a355b9d16ff120bc9f88c2c0e9003897fee839b2643f68c9de61448729cceab114db489495cbfa9da28618038bd5c9b1693bfc759e5a4c0ec
7
- data.tar.gz: cb6c62d5f1fb096e09b76ecbb36d3ef0eaf9140ed57ca662f65a65f8203a547497cd438995b042abad83957b37cffcc743fc11a03938cc7c32e88d238b87f836
6
+ metadata.gz: 3192bbb4d53667ae7c9acc5af81f34942f9a3ae23ec91f3913d86ce9c6739020446c84ad1f694192e981ec58e4c1a94763ba7b47df65c14824863e56d9772a39
7
+ data.tar.gz: 39d8e3725e312e8760684f3d4f93c3963b1caf3a1a81ac663f02855d16ded90eeb4797baf578a96eff9bdd23a4cc15c3aaa80ed86a422c6d44462e286464f9c7
data/.gitignore CHANGED
@@ -14,3 +14,4 @@ spec/reports
14
14
  test/tmp
15
15
  test/version_tmp
16
16
  tmp
17
+ *.lock
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+ script: bundle exec rspec
5
+ rvm:
6
+ - '2.2'
7
+ - '2.1'
8
+ - '2.0'
9
+ addons:
10
+ code_climate:
11
+ repo_token:
12
+ secure: "ASogQTLS/xYYczRtFwuo8DIkNdOl16mez4GHOw4RtdfTQ4BMROxE/CUemdPulMW1b/p7jsp5ghOtH2EJ4jN203s83HN4QjGC2wXhigkk6LzvxqjkmHxIWxJi2JS2sLq8nzOCcD0geO1pcbBFyuAzAdlwWa2g1WDP7O0L0fNjCtM="
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
  gemspec
data/README.md CHANGED
@@ -1,12 +1,18 @@
1
1
  # Signal
2
2
 
3
+ [![Build Status](https://travis-ci.org/fnando/signal.svg?branch=master)](https://travis-ci.org/fnando/signal)
4
+ [![Code Climate](https://codeclimate.com/github/fnando/signal/badges/gpa.svg)](https://codeclimate.com/github/fnando/signal)
5
+ [![Test Coverage](https://codeclimate.com/github/fnando/signal/badges/coverage.svg)](https://codeclimate.com/github/fnando/signal)
6
+
3
7
  A simple observer implementation on POROs (Plain Old Ruby Object) and ActiveRecord objects.
4
8
 
5
9
  ## Installation
6
10
 
7
11
  Add this line to your application's Gemfile:
8
12
 
9
- gem "signal"
13
+ ```ruby
14
+ gem 'signal'
15
+ ```
10
16
 
11
17
  And then execute:
12
18
 
@@ -60,15 +66,15 @@ class MyListener
60
66
  end
61
67
  end
62
68
 
63
- status = Status.new
64
- status.listeners << MyListener.new
65
- status.ready!
69
+ Status.new
70
+ .add_listener(MyListener.new)
71
+ .ready!
66
72
  #=> Before the ready event!
67
73
  #=> I'm ready!
68
74
  #=> After the ready event!
69
75
  ```
70
76
 
71
- Blocks are executed in the context of the observable object.
77
+ Executed blocks don't switch context. You always have to emit the object you're interested in. The follow example uses `emit(:output, self)` to send the `Contact` instance to all listeners.
72
78
 
73
79
  ```ruby
74
80
  class Contact
@@ -81,12 +87,12 @@ class Contact
81
87
  end
82
88
 
83
89
  def output!
84
- emit(:output)
90
+ emit(:output, self)
85
91
  end
86
92
  end
87
93
 
88
- contact = Contact.new("John Doe", "john@example.org")
89
- contact.on(:output) { puts name, email }
94
+ contact = Contact.new('John Doe', 'john@example.org')
95
+ contact.on(:output) {|contact| puts contact.name, contact.email }
90
96
  contact.output!
91
97
  #=> John Doe
92
98
  #=> john@example.org
@@ -105,10 +111,10 @@ class MyListener
105
111
  end
106
112
  end
107
113
 
108
- args = Arguments.new
109
- args.on(:args) {|a, b| puts a, b }
110
- args.listeners << MyListener.new
111
- args.emit(:args, 1, 2)
114
+ Arguments.new
115
+ .on(:args) {|a, b| puts a, b }
116
+ .add_listener(MyListener.new)
117
+ .emit(:args, 1, 2)
112
118
  ```
113
119
 
114
120
  ### ActiveRecord
@@ -158,6 +164,21 @@ These are the available events:
158
164
  * `on(:validation)`: triggered when record is invalid.
159
165
  * `after(:validation)`: triggered after validating record.
160
166
 
167
+ ### Inside Rails
168
+
169
+ Although there's no special code for Rails, here's just an example of how you can use it:
170
+
171
+ ```ruby
172
+ class UsersController < ApplicationController
173
+ def create
174
+ @user = User.new(user_params)
175
+ Signup.new(@user)
176
+ .on(:success) { redirect_to login_path, notice: 'Welcome to MyApp!' }
177
+ .on(:failure) { render :new }
178
+ end
179
+ end
180
+ ```
181
+
161
182
  ## Contributing
162
183
 
163
184
  1. Fork it
@@ -165,3 +186,28 @@ These are the available events:
165
186
  3. Commit your changes (`git commit -am 'Add some feature'`)
166
187
  4. Push to the branch (`git push origin my-new-feature`)
167
188
  5. Create new Pull Request
189
+
190
+ ## License
191
+
192
+ Copyright (c) 2013-2015 Nando Vieira
193
+
194
+ MIT License
195
+
196
+ Permission is hereby granted, free of charge, to any person obtaining
197
+ a copy of this software and associated documentation files (the
198
+ "Software"), to deal in the Software without restriction, including
199
+ without limitation the rights to use, copy, modify, merge, publish,
200
+ distribute, sublicense, and/or sell copies of the Software, and to
201
+ permit persons to whom the Software is furnished to do so, subject to
202
+ the following conditions:
203
+
204
+ The above copyright notice and this permission notice shall be
205
+ included in all copies or substantial portions of the Software.
206
+
207
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
208
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
209
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
210
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
211
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
212
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
213
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1 +1 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
@@ -1,16 +1,16 @@
1
- $:.unshift File.expand_path("../../lib", __FILE__)
2
- require "signal"
3
- require "active_record"
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'signal'
3
+ require 'active_record'
4
4
 
5
5
  ActiveRecord::Base.establish_connection({
6
- :adapter => "sqlite3",
7
- :database => ":memory:"
6
+ :adapter => 'sqlite3',
7
+ :database => ':memory:'
8
8
  })
9
9
 
10
10
  ActiveRecord::Schema.define(:version => 0) do
11
11
  create_table :things do |t|
12
12
  t.string :name
13
- t.timestamps
13
+ t.timestamps null: false
14
14
  end
15
15
  end
16
16
 
@@ -20,22 +20,22 @@ class Thing < ActiveRecord::Base
20
20
  validates_presence_of :name
21
21
  end
22
22
 
23
- thing = Thing.new(:name => "Stuff")
24
- thing.on(:create) { puts updated_at, name }
25
- thing.on(:update) { puts updated_at, name }
26
- thing.on(:remove) { puts destroyed? }
27
- thing.on(:validation) { p errors.full_messages }
23
+ thing = Thing.new(:name => 'Stuff')
24
+ thing.on(:create) {|model| puts model.updated_at, model.name }
25
+ thing.on(:update) {|model| puts model.updated_at, model.name }
26
+ thing.on(:remove) {|model| puts model.destroyed? }
27
+ thing.on(:validation) {|model| p model.errors.full_messages }
28
28
 
29
29
  thing.save!
30
30
  #=> 2013-01-26 10:32:39 -0200
31
31
  #=> Stuff
32
32
 
33
- thing.update_attributes(:name => "Updated stuff")
33
+ thing.update_attributes(:name => 'Updated stuff')
34
34
  #=> 2013-01-26 10:33:11 -0200
35
35
  #=> Updated stuff
36
36
 
37
37
  thing.update_attributes(:name => nil)
38
- #=> ["Name can't be blank"]
38
+ #=> ['Name can't be blank']
39
39
 
40
40
  thing.destroy
41
41
  #=> true
@@ -1,5 +1,5 @@
1
- $:.unshift File.expand_path("../../lib", __FILE__)
2
- require "signal"
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'signal'
3
3
 
4
4
  class Arguments
5
5
  include Signal
@@ -1,5 +1,5 @@
1
- $:.unshift File.expand_path("../../lib", __FILE__)
2
- require "signal"
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'signal'
3
3
 
4
4
  class Contact
5
5
  include Signal
@@ -11,10 +11,10 @@ class Contact
11
11
  end
12
12
 
13
13
  def output!
14
- emit(:output)
14
+ emit(:output, self)
15
15
  end
16
16
  end
17
17
 
18
- contact = Contact.new("John Doe", "john@example.org")
19
- contact.on(:output) { puts name, email }
18
+ contact = Contact.new('John Doe', 'john@example.org')
19
+ contact.on(:output) {|contact| puts contact.name, contact.email }
20
20
  contact.output!
data/examples/blocks.rb CHANGED
@@ -1,5 +1,5 @@
1
- $:.unshift File.expand_path("../../lib", __FILE__)
2
- require "signal"
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'signal'
3
3
 
4
4
  class Status
5
5
  include Signal
@@ -10,7 +10,7 @@ class Status
10
10
  end
11
11
 
12
12
  status = Status.new
13
- status.before(:ready) { puts "Before the ready event!" }
13
+ status.before(:ready) { puts 'Before the ready event!' }
14
14
  status.on(:ready) { puts "I'm ready!" }
15
- status.after(:ready) { puts "After the ready event!" }
15
+ status.after(:ready) { puts 'After the ready event!' }
16
16
  status.ready!
data/examples/chain.rb CHANGED
@@ -1,16 +1,16 @@
1
- $:.unshift File.expand_path("../../lib", __FILE__)
2
- require "signal"
3
- require "active_record"
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'signal'
3
+ require 'active_record'
4
4
 
5
5
  ActiveRecord::Base.establish_connection({
6
- :adapter => "sqlite3",
7
- :database => ":memory:"
6
+ :adapter => 'sqlite3',
7
+ :database => ':memory:'
8
8
  })
9
9
 
10
10
  ActiveRecord::Schema.define(:version => 0) do
11
11
  create_table :things do |t|
12
12
  t.string :name
13
- t.timestamps
13
+ t.timestamps null: false
14
14
  end
15
15
  end
16
16
 
@@ -23,15 +23,15 @@ end
23
23
  class MyListener
24
24
  [:validation, :update, :create, :remove].each do |type|
25
25
  class_eval <<-RUBY
26
- def before_#{type}; puts __method__; end
27
- def on_#{type}; puts __method__; end
28
- def after_#{type}; puts __method__; end
26
+ def before_#{type}(thing); puts __method__; end
27
+ def on_#{type}(thing); puts __method__; end
28
+ def after_#{type}(thing); puts __method__; end
29
29
  RUBY
30
30
  end
31
31
  end
32
32
 
33
33
  puts "\n=== Creating valid record"
34
- thing = Thing.new(:name => "Stuff")
34
+ thing = Thing.new(:name => 'Stuff')
35
35
  thing.listeners << MyListener.new
36
36
  thing.save
37
37
 
@@ -41,16 +41,16 @@ thing.listeners << MyListener.new
41
41
  thing.save
42
42
 
43
43
  puts "\n=== Updating valid record"
44
- thing = Thing.create(:name => "Stuff")
44
+ thing = Thing.create(:name => 'Stuff')
45
45
  thing.listeners << MyListener.new
46
- thing.update_attributes(:name => "Updated stuff")
46
+ thing.update_attributes(:name => 'Updated stuff')
47
47
 
48
48
  puts "\n=== Updating invalid record"
49
- thing = Thing.create!(:name => "Stuff")
49
+ thing = Thing.create!(:name => 'Stuff')
50
50
  thing.listeners << MyListener.new
51
51
  thing.update_attributes(:name => nil)
52
52
 
53
53
  puts "\n=== Removing record"
54
- thing = Thing.create(:name => "Stuff")
54
+ thing = Thing.create(:name => 'Stuff')
55
55
  thing.listeners << MyListener.new
56
56
  thing.destroy
data/examples/listener.rb CHANGED
@@ -1,5 +1,5 @@
1
- $:.unshift File.expand_path("../../lib", __FILE__)
2
- require "signal"
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'signal'
3
3
 
4
4
  class Status
5
5
  include Signal
@@ -11,7 +11,7 @@ end
11
11
 
12
12
  class MyListener
13
13
  def before_ready
14
- puts "Before the ready event!"
14
+ puts 'Before the ready event!'
15
15
  end
16
16
 
17
17
  def on_ready
@@ -19,7 +19,7 @@ class MyListener
19
19
  end
20
20
 
21
21
  def after_ready
22
- puts "After the ready event!"
22
+ puts 'After the ready event!'
23
23
  end
24
24
  end
25
25
 
@@ -10,7 +10,6 @@ module Signal
10
10
 
11
11
  def method_missing(method_name, *args)
12
12
  return super unless respond_to_missing?(method_name, false)
13
- # @context.instance_exec(*args, &@block)
14
13
  @block.call(*args)
15
14
  end
16
15
 
@@ -1,3 +1,3 @@
1
1
  module Signal
2
- VERSION = "0.1.1"
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/signal.rb CHANGED
@@ -1,6 +1,6 @@
1
- require "signal/active_record"
2
- require "signal/listener"
3
- require "signal/version"
1
+ require 'signal/active_record'
2
+ require 'signal/listener'
3
+ require 'signal/version'
4
4
 
5
5
  module Signal
6
6
  def on(event, &block)
@@ -18,6 +18,11 @@ module Signal
18
18
  self
19
19
  end
20
20
 
21
+ def add_listener(listener)
22
+ listeners << listener
23
+ self
24
+ end
25
+
21
26
  def emit(event, *args)
22
27
  emit_signal(:before, event, *args)
23
28
  emit_signal(:on, event, *args)
data/signal.gemspec CHANGED
@@ -1,21 +1,21 @@
1
- # -*- encoding: utf-8 -*-
2
- require "./lib/signal/version"
1
+ require './lib/signal/version'
3
2
 
4
3
  Gem::Specification.new do |gem|
5
- gem.name = "signal"
4
+ gem.name = 'signal'
6
5
  gem.version = Signal::VERSION
7
- gem.authors = ["Nando Vieira"]
8
- gem.email = ["fnando.vieira@gmail.com"]
9
- gem.description = "A simple observer implementation for POROs (Plain Old Ruby Object) and ActiveRecord objects."
6
+ gem.authors = ['Nando Vieira']
7
+ gem.email = ['fnando.vieira@gmail.com']
8
+ gem.description = 'A simple observer implementation for POROs (Plain Old Ruby Object) and ActiveRecord objects.'
10
9
  gem.summary = gem.description
11
- gem.homepage = "http://github.com/fnando/signal"
10
+ gem.homepage = 'http://github.com/fnando/signal'
12
11
 
13
12
  gem.files = `git ls-files`.split($/)
14
13
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
14
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
- gem.require_paths = ["lib"]
15
+ gem.require_paths = ['lib']
17
16
 
18
- gem.add_development_dependency "activerecord"
19
- gem.add_development_dependency "sqlite3"
20
- gem.add_development_dependency "rspec"
17
+ gem.add_development_dependency 'activerecord'
18
+ gem.add_development_dependency 'sqlite3'
19
+ gem.add_development_dependency 'rspec'
20
+ gem.add_development_dependency 'codeclimate-test-reporter'
21
21
  end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe Signal::ActiveRecord do
4
+ let(:callable) { Callable.new }
5
+ let(:user) { User.new(:username => 'johndoe') }
6
+
7
+ context 'create event' do
8
+ it 'triggers before event' do
9
+ user.before(:create, &callable)
10
+ expect(callable).to receive(:called).with(user)
11
+ user.save!
12
+ end
13
+
14
+ it 'triggers event' do
15
+ user.on(:create, &callable)
16
+ expect(callable).to receive(:called).with(user)
17
+ user.save!
18
+ end
19
+
20
+ it 'triggers after event' do
21
+ user.after(:create, &callable)
22
+ expect(callable).to receive(:called).with(user)
23
+ user.save!
24
+ end
25
+
26
+ it 'does not trigger on/after events when record is invalid' do
27
+ user = User.new
28
+
29
+ on_callable = Callable.new
30
+ after_callable = Callable.new
31
+
32
+ user
33
+ .on(:create, &on_callable)
34
+ .after(:create, &after_callable)
35
+
36
+ expect(on_callable).not_to receive(:called)
37
+ expect(after_callable).not_to receive(:called)
38
+
39
+ user.save
40
+ end
41
+ end
42
+
43
+ context 'validation event' do
44
+ it 'triggers before event' do
45
+ user.before(:validation, &callable)
46
+ expect(callable).to receive(:called).with(user)
47
+ user.save!
48
+ end
49
+
50
+ it 'triggers after event' do
51
+ user.after(:validation, &callable)
52
+ expect(callable).to receive(:called).with(user)
53
+ user.save!
54
+ end
55
+
56
+ it 'triggers validation event when record is invalid' do
57
+ user.username = nil
58
+ user.on(:validation, &callable)
59
+ expect(callable).to receive(:called).with(user)
60
+ user.save
61
+ end
62
+
63
+ it 'skips validation event when record is valid' do
64
+ user.on(:validation, &callable)
65
+ expect(callable).not_to receive(:called)
66
+ user.save!
67
+ end
68
+ end
69
+
70
+ context 'update event' do
71
+ let(:user) { User.create!(:username => 'johndoe') }
72
+
73
+ it 'triggers before event' do
74
+ user.before(:update, &callable)
75
+ expect(callable).to receive(:called).with(user)
76
+ user.update_attributes!(:username => 'johnd')
77
+ end
78
+
79
+ it 'triggers on event' do
80
+ user.on(:update, &callable)
81
+ expect(callable).to receive(:called).with(user)
82
+ user.update_attributes!(:username => 'johnd')
83
+ end
84
+
85
+ it 'triggers after event' do
86
+ user.after(:update, &callable)
87
+ expect(callable).to receive(:called).with(user)
88
+ user.update_attributes!(:username => 'johnd')
89
+ end
90
+
91
+ it 'does not trigger on/after events when record is invalid' do
92
+ user.username = nil
93
+
94
+ on_callable = Callable.new
95
+ after_callable = Callable.new
96
+
97
+ user
98
+ .on(:update, &on_callable)
99
+ .after(:update, &after_callable)
100
+
101
+ expect(on_callable).not_to receive(:called)
102
+ expect(after_callable).not_to receive(:called)
103
+
104
+ user.save
105
+ end
106
+ end
107
+
108
+ context 'remove event' do
109
+ let(:user) { User.create!(:username => 'johndoe') }
110
+
111
+ it 'triggers before event' do
112
+ user.before(:remove, &callable)
113
+ expect(callable).to receive(:called).with(user)
114
+
115
+ user.destroy
116
+ end
117
+
118
+ it 'triggers on event' do
119
+ user.on(:remove, &callable)
120
+ expect(callable).to receive(:called).with(user)
121
+
122
+ user.destroy
123
+ end
124
+
125
+ it 'triggers after event' do
126
+ user.after(:remove, &callable)
127
+ expect(callable).to receive(:called).with(user)
128
+
129
+ user.destroy
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Signal::Listener do
4
+ it 'sets string representation' do
5
+ listener = Signal::Listener.new(self, :on, :ready, &->{})
6
+ expect(listener.to_s).to eq('<Signal::Listener event: on_ready>')
7
+ end
8
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe Signal do
4
+ let(:observable) { Observable.new }
5
+ let(:callable) { Callable.new }
6
+
7
+ context 'add listener' do
8
+ it 'runs listener' do
9
+ callable.respond_to(:on_ready)
10
+ observable.add_listener(callable)
11
+ expect(callable).to receive(:called).with(no_args)
12
+
13
+ observable.emit(:ready)
14
+ end
15
+
16
+ it 'returns itself' do
17
+ expect(observable.add_listener(callable)).to eq(observable)
18
+ end
19
+ end
20
+
21
+ context 'using blocks' do
22
+ it 'triggers event' do
23
+ observable.on(:ready, &callable)
24
+ expect(callable).to receive(:called).with(no_args)
25
+
26
+ observable.emit(:ready)
27
+ end
28
+
29
+ it 'triggers event with arguments' do
30
+ observable.on(:ready, &callable)
31
+ expect(callable).to receive(:called).with(1, 2, 3)
32
+
33
+ observable.emit(:ready, 1, 2, 3)
34
+ end
35
+
36
+ it 'triggers before event' do
37
+ observable.before(:ready, &callable)
38
+ expect(callable).to receive(:called).with(no_args)
39
+
40
+ observable.emit(:ready)
41
+ end
42
+
43
+ it 'triggers before event with arguments' do
44
+ observable.before(:ready, &callable)
45
+ expect(callable).to receive(:called).with(1, 2, 3)
46
+
47
+ observable.emit(:ready, 1, 2, 3)
48
+ end
49
+
50
+ it 'triggers after event' do
51
+ observable.after(:ready, &callable)
52
+ expect(callable).to receive(:called).with(no_args)
53
+
54
+ observable.emit(:ready)
55
+ end
56
+
57
+ it 'triggers after event with arguments' do
58
+ observable.after(:ready, &callable)
59
+ expect(callable).to receive(:called).with(1, 2, 3)
60
+
61
+ observable.emit(:ready, 1, 2, 3)
62
+ end
63
+
64
+ it 'chains events' do
65
+ before_callable = Callable.new
66
+ on_callable = Callable.new
67
+ after_callable = Callable.new
68
+
69
+ observable
70
+ .before(:ready, &before_callable)
71
+ .on(:ready, &on_callable)
72
+ .after(:ready, &after_callable)
73
+
74
+ expect(before_callable).to receive(:called).with(no_args).ordered
75
+ expect(on_callable).to receive(:called).with(no_args).ordered
76
+ expect(after_callable).to receive(:called).with(no_args).ordered
77
+
78
+ observable.emit(:ready)
79
+ end
80
+
81
+ it 'keeps context' do
82
+ context = nil
83
+ callable = -> { context = self }
84
+ observable.on(:ready, &callable)
85
+ observable.emit(:ready)
86
+
87
+ expect(context).to eql(self)
88
+ end
89
+ end
90
+
91
+ context 'using listeners' do
92
+ it 'triggers event for listener' do
93
+ callable.respond_to(:on_ready)
94
+ observable.listeners << callable
95
+ expect(callable).to receive(:called).with(no_args)
96
+
97
+ observable.emit(:ready)
98
+ end
99
+
100
+ it 'triggers event for listener with arguments' do
101
+ callable.respond_to(:on_ready)
102
+ observable.listeners << callable
103
+ expect(callable).to receive(:called).with(1, 2, 3)
104
+
105
+ observable.emit(:ready, 1, 2, 3)
106
+ end
107
+ end
108
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,19 @@
1
- require "bundler"
2
- Bundler.setup
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
3
 
4
- require "active_record"
4
+ require 'bundler/setup'
5
+ require 'active_record'
5
6
 
6
- require "signal"
7
- require "support/observable"
8
- require "support/callable"
9
- require "support/user"
7
+ I18n.enforce_available_locales = false
8
+
9
+ require 'signal'
10
+ require 'support/observable'
11
+ require 'support/callable'
12
+ require 'support/user'
10
13
 
11
14
  ActiveRecord::Base.establish_connection({
12
- :adapter => "sqlite3",
13
- :database => ":memory:"
15
+ :adapter => 'sqlite3',
16
+ :database => ':memory:'
14
17
  })
15
18
 
16
19
  ActiveRecord::Schema.define(:version => 0) do
metadata CHANGED
@@ -1,55 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: signal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-17 00:00:00.000000000 Z
11
+ date: 2015-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codeclimate-test-reporter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  description: A simple observer implementation for POROs (Plain Old Ruby Object) and
@@ -60,10 +74,10 @@ executables: []
60
74
  extensions: []
61
75
  extra_rdoc_files: []
62
76
  files:
63
- - .gitignore
64
- - .rspec
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - ".travis.yml"
65
80
  - Gemfile
66
- - Gemfile.lock
67
81
  - LICENSE.txt
68
82
  - README.md
69
83
  - Rakefile
@@ -78,8 +92,9 @@ files:
78
92
  - lib/signal/listener.rb
79
93
  - lib/signal/version.rb
80
94
  - signal.gemspec
81
- - spec/activerecord_spec.rb
82
- - spec/signal_spec.rb
95
+ - spec/signal/activerecord_spec.rb
96
+ - spec/signal/listener_spec.rb
97
+ - spec/signal/signal_spec.rb
83
98
  - spec/spec_helper.rb
84
99
  - spec/support/callable.rb
85
100
  - spec/support/observable.rb
@@ -93,25 +108,27 @@ require_paths:
93
108
  - lib
94
109
  required_ruby_version: !ruby/object:Gem::Requirement
95
110
  requirements:
96
- - - '>='
111
+ - - ">="
97
112
  - !ruby/object:Gem::Version
98
113
  version: '0'
99
114
  required_rubygems_version: !ruby/object:Gem::Requirement
100
115
  requirements:
101
- - - '>='
116
+ - - ">="
102
117
  - !ruby/object:Gem::Version
103
118
  version: '0'
104
119
  requirements: []
105
120
  rubyforge_project:
106
- rubygems_version: 2.0.3
121
+ rubygems_version: 2.4.5.1
107
122
  signing_key:
108
123
  specification_version: 4
109
124
  summary: A simple observer implementation for POROs (Plain Old Ruby Object) and ActiveRecord
110
125
  objects.
111
126
  test_files:
112
- - spec/activerecord_spec.rb
113
- - spec/signal_spec.rb
127
+ - spec/signal/activerecord_spec.rb
128
+ - spec/signal/listener_spec.rb
129
+ - spec/signal/signal_spec.rb
114
130
  - spec/spec_helper.rb
115
131
  - spec/support/callable.rb
116
132
  - spec/support/observable.rb
117
133
  - spec/support/user.rb
134
+ has_rdoc:
data/Gemfile.lock DELETED
@@ -1,51 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- signal (0.1.1)
5
-
6
- GEM
7
- remote: http://rubygems.org/
8
- specs:
9
- activemodel (4.0.0)
10
- activesupport (= 4.0.0)
11
- builder (~> 3.1.0)
12
- activerecord (4.0.0)
13
- activemodel (= 4.0.0)
14
- activerecord-deprecated_finders (~> 1.0.2)
15
- activesupport (= 4.0.0)
16
- arel (~> 4.0.0)
17
- activerecord-deprecated_finders (1.0.3)
18
- activesupport (4.0.0)
19
- i18n (~> 0.6, >= 0.6.4)
20
- minitest (~> 4.2)
21
- multi_json (~> 1.3)
22
- thread_safe (~> 0.1)
23
- tzinfo (~> 0.3.37)
24
- arel (4.0.0)
25
- atomic (1.1.10)
26
- builder (3.1.4)
27
- diff-lcs (1.2.4)
28
- i18n (0.6.4)
29
- minitest (4.7.5)
30
- multi_json (1.7.7)
31
- rspec (2.14.1)
32
- rspec-core (~> 2.14.0)
33
- rspec-expectations (~> 2.14.0)
34
- rspec-mocks (~> 2.14.0)
35
- rspec-core (2.14.3)
36
- rspec-expectations (2.14.0)
37
- diff-lcs (>= 1.1.3, < 2.0)
38
- rspec-mocks (2.14.1)
39
- sqlite3 (1.3.7)
40
- thread_safe (0.1.0)
41
- atomic
42
- tzinfo (0.3.37)
43
-
44
- PLATFORMS
45
- ruby
46
-
47
- DEPENDENCIES
48
- activerecord
49
- rspec
50
- signal!
51
- sqlite3
@@ -1,132 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Signal::ActiveRecord do
4
- let(:callable) { Callable.new }
5
- let(:user) { User.new(:username => "johndoe") }
6
-
7
- context "create event" do
8
- it "triggers before event" do
9
- user.before(:create, &callable)
10
- callable.should_receive(:called).with(user)
11
- user.save!
12
- end
13
-
14
- it "triggers event" do
15
- user.on(:create, &callable)
16
- callable.should_receive(:called).with(user)
17
- user.save!
18
- end
19
-
20
- it "triggers after event" do
21
- user.after(:create, &callable)
22
- callable.should_receive(:called).with(user)
23
- user.save!
24
- end
25
-
26
- it "doesn't trigger on/after events when record is invalid" do
27
- user = User.new
28
-
29
- on_callable = Callable.new
30
- after_callable = Callable.new
31
-
32
- user
33
- .on(:create, &on_callable)
34
- .after(:create, &after_callable)
35
-
36
- on_callable.should_not_receive(:called)
37
- after_callable.should_not_receive(:called)
38
-
39
- user.save
40
- end
41
- end
42
-
43
- context "validation event" do
44
- it "triggers before event" do
45
- user.before(:validation, &callable)
46
- callable.should_receive(:called).with(user)
47
- user.save!
48
- end
49
-
50
- it "triggers after event" do
51
- user.after(:validation, &callable)
52
- callable.should_receive(:called).with(user)
53
- user.save!
54
- end
55
-
56
- it "triggers validation event when record is invalid" do
57
- user.username = nil
58
- user.on(:validation, &callable)
59
- callable.should_receive(:called).with(user)
60
- user.save
61
- end
62
-
63
- it "skips validation event when record is valid" do
64
- user.on(:validation, &callable)
65
- callable.should_not_receive(:called)
66
- user.save!
67
- end
68
- end
69
-
70
- context "update event" do
71
- let(:user) { User.create!(:username => "johndoe") }
72
-
73
- it "triggers before event" do
74
- user.before(:update, &callable)
75
- callable.should_receive(:called).with(user)
76
- user.update_attributes!(:username => "johnd")
77
- end
78
-
79
- it "triggers on event" do
80
- user.on(:update, &callable)
81
- callable.should_receive(:called).with(user)
82
- user.update_attributes!(:username => "johnd")
83
- end
84
-
85
- it "triggers after event" do
86
- user.after(:update, &callable)
87
- callable.should_receive(:called).with(user)
88
- user.update_attributes!(:username => "johnd")
89
- end
90
-
91
- it "doesn't trigger on/after events when record is invalid" do
92
- user.username = nil
93
-
94
- on_callable = Callable.new
95
- after_callable = Callable.new
96
-
97
- user
98
- .on(:update, &on_callable)
99
- .after(:update, &after_callable)
100
-
101
- on_callable.should_not_receive(:called)
102
- after_callable.should_not_receive(:called)
103
-
104
- user.save
105
- end
106
- end
107
-
108
- context "remove event" do
109
- let(:user) { User.create!(:username => "johndoe") }
110
-
111
- it "triggers before event" do
112
- user.before(:remove, &callable)
113
- callable.should_receive(:called).with(user)
114
-
115
- user.destroy
116
- end
117
-
118
- it "triggers on event" do
119
- user.on(:remove, &callable)
120
- callable.should_receive(:called).with(user)
121
-
122
- user.destroy
123
- end
124
-
125
- it "triggers after event" do
126
- user.after(:remove, &callable)
127
- callable.should_receive(:called).with(user)
128
-
129
- user.destroy
130
- end
131
- end
132
- end
data/spec/signal_spec.rb DELETED
@@ -1,105 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Signal do
4
- let(:observable) { Observable.new }
5
- let(:callable) { Callable.new }
6
-
7
- context "using blocks" do
8
- it "triggers event" do
9
- observable.on(:ready, &callable)
10
- callable.should_receive(:called).with(no_args)
11
-
12
- observable.emit(:ready)
13
- end
14
-
15
- it "triggers event with arguments" do
16
- observable.on(:ready, &callable)
17
- callable.should_receive(:called).with(1, 2, 3)
18
-
19
- observable.emit(:ready, 1, 2, 3)
20
- end
21
-
22
- it "triggers before event" do
23
- observable.before(:ready, &callable)
24
- callable.should_receive(:called).with(no_args)
25
-
26
- observable.emit(:ready)
27
- end
28
-
29
- it "triggers before event with arguments" do
30
- observable.before(:ready, &callable)
31
- callable.should_receive(:called).with(1, 2, 3)
32
-
33
- observable.emit(:ready, 1, 2, 3)
34
- end
35
-
36
- it "triggers after event" do
37
- observable.after(:ready, &callable)
38
- callable.should_receive(:called).with(no_args)
39
-
40
- observable.emit(:ready)
41
- end
42
-
43
- it "triggers after event with arguments" do
44
- observable.after(:ready, &callable)
45
- callable.should_receive(:called).with(1, 2, 3)
46
-
47
- observable.emit(:ready, 1, 2, 3)
48
- end
49
-
50
- it "chains events" do
51
- before_callable = Callable.new
52
- on_callable = Callable.new
53
- after_callable = Callable.new
54
-
55
- observable
56
- .before(:ready, &before_callable)
57
- .on(:ready, &on_callable)
58
- .after(:ready, &after_callable)
59
-
60
- before_callable
61
- .should_receive(:called)
62
- .with(no_args)
63
- .ordered
64
-
65
- on_callable
66
- .should_receive(:called)
67
- .with(no_args)
68
- .ordered
69
-
70
- after_callable
71
- .should_receive(:called)
72
- .with(no_args)
73
- .ordered
74
-
75
- observable.emit(:ready)
76
- end
77
-
78
- it "keeps context" do
79
- context = nil
80
- callable = -> { context = self }
81
- observable.on(:ready, &callable)
82
- observable.emit(:ready)
83
-
84
- expect(context).to eql(self)
85
- end
86
- end
87
-
88
- context "using listeners" do
89
- it "triggers event for listener" do
90
- callable.respond_to(:on_ready)
91
- observable.listeners << callable
92
- callable.should_receive(:called).with(no_args)
93
-
94
- observable.emit(:ready)
95
- end
96
-
97
- it "triggers event for listener with arguments" do
98
- callable.respond_to(:on_ready)
99
- observable.listeners << callable
100
- callable.should_receive(:called).with(1, 2, 3)
101
-
102
- observable.emit(:ready, 1, 2, 3)
103
- end
104
- end
105
- end