signal 0.1.1 → 0.2.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
  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