sub_pub 0.0.3 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sub_pub (0.0.3)
4
+ sub_pub (0.0.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -92,6 +92,14 @@ Or install it yourself as:
92
92
  User.create(name: 'John Doe')
93
93
  => SubPub.publish("active_record::user::after_create")
94
94
 
95
+
96
+ ## Supported Active Record Callbacks
97
+
98
+ * before_create
99
+ * after_create
100
+ * after_commit
101
+
102
+
95
103
  ## Backlog / To Do
96
104
 
97
105
  http://www.pivotaltracker.com/projects/705655
data/Rakefile CHANGED
@@ -1 +1,12 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ task :suite do
4
+ if system("rspec spec")
5
+ puts "Test suite passed!!"
6
+ else
7
+ puts "Test suite failed..."
8
+ exit(1)
9
+ end
10
+ end
11
+
12
+ task :default => :suite
@@ -1,38 +1,22 @@
1
1
  module SubPub
2
- class ActiveRecordExtensions < Rails::Railtie
3
- initializer "pub sub configuration of active record extensions" do
4
- class ::ActiveRecord::Base
5
- after_create :notify_of_after_create
2
+ module ActiveRecordExtensions
3
+ extend ActiveSupport::Concern
6
4
 
7
- private
8
-
9
- def notify_of_after_create
10
- notify_pub_sub_of_active_record_callback('after_create')
11
- end
12
-
13
- def notify_pub_sub_of_active_record_callback(callback)
14
- message = "active_record::#{self.class.to_s.underscore}::#{callback}"
15
- SubPub.publish(message, record: self)
16
- end
17
- end
18
-
19
- config.after_initialize do
20
- Dir[
21
- File.expand_path("app/models/pub_sub/*.rb", Rails.root)
22
- ].each { |file| require file }
5
+ included do
6
+ ['before_create', 'after_create', 'after_commit'].each do |callback|
7
+ class_eval "
8
+ #{callback} do
9
+ notify_pub_sub_of_active_record_callback('#{callback}')
10
+ end
11
+ "
23
12
  end
24
13
  end
25
- end
26
14
 
27
- module ActiveRecord
28
- class Subscriber < SubPub::Subscriber
29
- def self.subscribe_to(class_instance, callback)
30
- super("active_record::#{class_instance.to_s.underscore}::#{callback}")
31
- end
15
+ private
32
16
 
33
- def record
34
- options[:record]
35
- end
17
+ def notify_pub_sub_of_active_record_callback(callback)
18
+ message = "active_record::#{self.class.to_s.underscore}::#{callback}"
19
+ SubPub.publish(message, record: self)
36
20
  end
37
21
  end
38
22
  end
@@ -0,0 +1,13 @@
1
+ module SubPub
2
+ module ActiveRecord
3
+ class Subscriber < SubPub::Subscriber
4
+ def self.subscribe_to(class_instance, callback)
5
+ super("active_record::#{class_instance.to_s.underscore}::#{callback}")
6
+ end
7
+
8
+ def record
9
+ options[:record]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module SubPub
2
+ class Railtie < Rails::Railtie
3
+ initializer "pub sub configuration of active record extensions" do
4
+ class ::ActiveRecord::Base
5
+ include SubPub::ActiveRecordExtensions
6
+ end
7
+
8
+ config.after_initialize do
9
+ Dir[
10
+ File.expand_path("app/models/pub_sub/*.rb", Rails.root)
11
+ ].each { |file| require file }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -4,14 +4,28 @@ module SubPub
4
4
  class Register
5
5
  include Singleton
6
6
 
7
- attr_accessor :enabled
7
+ attr_accessor :enabled, :scope, :subscriptions
8
8
 
9
9
  def initialize
10
- @enabled = true
10
+ @enabled = default_enabled_state
11
+ @scope = default_scope
12
+ @subscriptions = []
11
13
  super
12
14
  end
13
15
 
16
+ def default_enabled_state
17
+ true
18
+ end
19
+
20
+ def default_scope
21
+ "sub_pub"
22
+ end
23
+
14
24
  class << self
25
+ def scope=(new_scope)
26
+ instance.scope = new_scope
27
+ end
28
+
15
29
  def enable
16
30
  instance.enabled = true
17
31
  end
@@ -35,11 +49,36 @@ module SubPub
35
49
  def publish(*args, &block)
36
50
  return if disabled?
37
51
 
38
- ActiveSupport::Notifications.publish(*args, &block)
52
+ topic = args.shift
53
+ payload = args.last
54
+ full_topic = scoped(topic).full_topic
55
+
56
+ ActiveSupport::Notifications.publish(full_topic, payload, &block)
57
+ end
58
+
59
+ def scoped(topic)
60
+ ScopedTopic.new(topic, instance.scope)
39
61
  end
40
62
 
41
63
  def subscribe(*args, &block)
42
- ActiveSupport::Notifications.subscribe(*args, &block)
64
+ topic = args.first
65
+
66
+ options = {
67
+ scoped_topic: ScopedTopic.new(topic, instance.scope),
68
+ action: block
69
+ }
70
+
71
+ Subscription.subscribe(options).tap do |subscription|
72
+ instance.subscriptions << subscription
73
+ end
74
+ end
75
+
76
+ def unsubscribe_all
77
+ instance.subscriptions.each do |subscription|
78
+ subscription.unsubscribe
79
+ end
80
+
81
+ instance.subscriptions = []
43
82
  end
44
83
  end
45
84
  end
@@ -0,0 +1,16 @@
1
+ module SubPub
2
+ class ScopedTopic
3
+ def initialize(topic, scope)
4
+ @topic = topic
5
+ @scope = scope
6
+ end
7
+
8
+ def full_topic
9
+ "#{@scope}::#{@topic}"
10
+ end
11
+
12
+ def topic
13
+ @topic
14
+ end
15
+ end
16
+ end
@@ -24,7 +24,7 @@ module SubPub
24
24
  end
25
25
 
26
26
  def self.topic
27
- @subscription.instance_variable_get("@pattern")
27
+ @subscription.topic
28
28
  end
29
29
 
30
30
  def on_publish
@@ -0,0 +1,26 @@
1
+ module SubPub
2
+ class Subscription
3
+ def initialize(options)
4
+ @scoped_topic = options[:scoped_topic]
5
+ @action = options[:action]
6
+ end
7
+
8
+ def self.subscribe(options)
9
+ subscription = new(options)
10
+ subscription.subscribe
11
+ subscription
12
+ end
13
+
14
+ def subscribe
15
+ @subscription = ActiveSupport::Notifications.subscribe(@scoped_topic.full_topic, @action)
16
+ end
17
+
18
+ def unsubscribe
19
+ ActiveSupport::Notifications.unsubscribe(@scoped_topic.full_topic)
20
+ end
21
+
22
+ def topic
23
+ @scoped_topic.topic
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module SubPub
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/sub_pub.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  module SubPub
2
2
  class << self
3
+ def scope=(new_scope)
4
+ Register.scope = new_scope
5
+ end
6
+
3
7
  def enable
4
8
  Register.enable
5
9
  end
@@ -26,14 +30,22 @@ module SubPub
26
30
  def subscribe(*args, &block)
27
31
  Register.subscribe(*args, &block)
28
32
  end
33
+
34
+ def unsubscribe_all
35
+ Register.unsubscribe_all
36
+ end
29
37
  end
30
38
  end
31
39
 
32
40
  require "sub_pub/version"
33
41
  require "sub_pub/subscriber"
34
42
  require "sub_pub/register"
43
+ require "sub_pub/subscription"
44
+ require "sub_pub/scoped_topic"
35
45
 
36
- require 'rails'
37
- require 'active_record'
46
+ require "rails"
47
+ require "active_record"
38
48
 
39
- require_relative "sub_pub/active_record_extensions"
49
+ require "sub_pub/active_record_subscriber"
50
+ require "sub_pub/active_record_extensions"
51
+ require "sub_pub/railtie"
Binary file
@@ -0,0 +1,177 @@
1
+ require 'spec_helper'
2
+
3
+ describe SubPub do
4
+ with_model :FakeActiveRecordUser do
5
+ table do |t|
6
+ t.string :title
7
+ end
8
+
9
+ model do
10
+ has_many :fake_active_record_results
11
+ end
12
+ end
13
+
14
+ with_model :FakeActiveRecordResult do
15
+ table do |t|
16
+ t.string :title
17
+ t.integer :fake_active_record_user_id
18
+ end
19
+ end
20
+
21
+ describe "initial state" do
22
+ it "defaults enabled to true" do
23
+ SubPub::Register.instance.enabled = nil
24
+ SubPub.enabled?.should be_true
25
+ end
26
+ end
27
+
28
+ describe "#enable" do
29
+ it "enables SubPub" do
30
+ SubPub.disable
31
+ SubPub.enable
32
+ SubPub.enabled?.should be_true
33
+ end
34
+ end
35
+
36
+ describe "#disable" do
37
+ it "disables SubPub" do
38
+ SubPub.disable
39
+ SubPub.enabled?.should be_false
40
+ end
41
+ end
42
+
43
+ describe "#publish" do
44
+ context "when disabled" do
45
+ before { SubPub.disable }
46
+
47
+ it "does not publish" do
48
+ ActiveSupport::Notifications.should_receive(:publish).never
49
+ SubPub.publish
50
+ end
51
+ end
52
+
53
+ context "with a set scope" do
54
+ it "uses the configured scope" do
55
+ payload = { :payload => 'here' }
56
+
57
+ SubPub.scope = 'rails'
58
+
59
+ ActiveSupport::Notifications.should_receive(:publish).with(
60
+ "rails::my-message",
61
+ payload
62
+ )
63
+
64
+ SubPub.publish("my-message", payload)
65
+ end
66
+ end
67
+
68
+ context "when using the default scope" do
69
+ it "publishes to active support using the default scope" do
70
+ payload = { :payload => 'here' }
71
+
72
+ ActiveSupport::Notifications.should_receive(:publish).with(
73
+ "sub_pub::my-message",
74
+ payload
75
+ )
76
+
77
+ SubPub.publish("my-message", payload)
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "normal pubsub" do
83
+ before do
84
+ class CreateAccountSubscriber < SubPub::Subscriber
85
+ subscribe_to("new_account_posted")
86
+
87
+ def on_publish
88
+ FakeActiveRecordUser.create(title: options[:title])
89
+ end
90
+ end
91
+ end
92
+
93
+ it "calls the subscriber properly" do
94
+ FakeActiveRecordUser.all.size.should == 0
95
+ SubPub.publish("new_account_posted", {title: 'foo'})
96
+ FakeActiveRecordUser.all.size.should == 1
97
+ FakeActiveRecordUser.all.first.title.should == 'foo'
98
+ end
99
+ end
100
+
101
+ describe "normal pubsub with a configured scope" do
102
+ before do
103
+ SubPub.scope = 'foo-bar'
104
+
105
+ class CreateAccountSubscriber < SubPub::Subscriber
106
+ subscribe_to("new_account_posted")
107
+
108
+ def on_publish
109
+ FakeActiveRecordUser.create(title: options[:title])
110
+ end
111
+ end
112
+ end
113
+
114
+ it "calls the subscriber properly" do
115
+ FakeActiveRecordUser.all.size.should == 0
116
+ SubPub.publish("new_account_posted", {title: 'foo'})
117
+ FakeActiveRecordUser.all.size.should == 1
118
+ FakeActiveRecordUser.all.first.title.should == 'foo'
119
+ end
120
+ end
121
+
122
+ describe "active record configuration" do
123
+ describe "after create" do
124
+ before do
125
+ class FakeActiveRecordUserSubscriber < SubPub::ActiveRecord::Subscriber
126
+ subscribe_to(FakeActiveRecordUser, 'after_create')
127
+
128
+ def on_publish
129
+ FakeActiveRecordResult.create
130
+ end
131
+ end
132
+ end
133
+
134
+ it "successfully calls through to the subscriber" do
135
+ FakeActiveRecordResult.all.size.should == 0
136
+ FakeActiveRecordUser.create
137
+ FakeActiveRecordResult.all.size.should == 1
138
+ end
139
+ end
140
+
141
+ describe "after commit" do
142
+ before do
143
+ class FakeActiveRecordUserSubscriber < SubPub::ActiveRecord::Subscriber
144
+ subscribe_to(FakeActiveRecordUser, 'after_commit')
145
+
146
+ def on_publish
147
+ FakeActiveRecordResult.create
148
+ end
149
+ end
150
+ end
151
+
152
+ it "successfully calls through to the subscriber" do
153
+ FakeActiveRecordResult.all.size.should == 0
154
+ FakeActiveRecordUser.create
155
+ FakeActiveRecordResult.all.size.should == 1
156
+ end
157
+ end
158
+
159
+ describe "before create" do
160
+ before do
161
+ class FakeActiveRecordUserSubscriber < SubPub::ActiveRecord::Subscriber
162
+ subscribe_to(FakeActiveRecordUser, 'before_create')
163
+
164
+ def on_publish
165
+ record.fake_active_record_results.build(title: 'fooz')
166
+ end
167
+ end
168
+ end
169
+
170
+ it "successfully calls through to the subscriber" do
171
+ FakeActiveRecordResult.all.size.should == 0
172
+ FakeActiveRecordUser.create
173
+ FakeActiveRecordResult.all.size.should == 1
174
+ end
175
+ end
176
+ end
177
+ end
data/spec/spec_helper.rb CHANGED
@@ -24,7 +24,7 @@ RSpec.configure do |config|
24
24
  #
25
25
  # Rails loads this during its setup
26
26
  #
27
- SubPub::ActiveRecordExtensions.run_initializers
27
+ SubPub::Railtie.run_initializers
28
28
 
29
29
  #
30
30
  # Test database
@@ -44,7 +44,9 @@ RSpec.configure do |config|
44
44
  #
45
45
  # Ensure pubsub is enabled
46
46
  #
47
- config.before do
47
+ config.before(:each) do
48
48
  SubPub.enable
49
+ SubPub.scope = 'sub_pub'
50
+ SubPub.unsubscribe_all
49
51
  end
50
52
  end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe SubPub::Register do
4
+
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sub_pub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-13 00:00:00.000000000 Z
12
+ date: 2012-12-17 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: In process publish/subscribe for Ruby
15
15
  email:
@@ -28,12 +28,18 @@ files:
28
28
  - db/.gitkeep
29
29
  - lib/sub_pub.rb
30
30
  - lib/sub_pub/active_record_extensions.rb
31
+ - lib/sub_pub/active_record_subscriber.rb
32
+ - lib/sub_pub/railtie.rb
31
33
  - lib/sub_pub/register.rb
34
+ - lib/sub_pub/scoped_topic.rb
32
35
  - lib/sub_pub/subscriber.rb
36
+ - lib/sub_pub/subscription.rb
33
37
  - lib/sub_pub/version.rb
34
38
  - pkg/sub_pub-0.0.3.gem
35
- - spec/integration/pub_sub_spec.rb
39
+ - pkg/sub_pub-0.0.4.gem
40
+ - spec/integration/sub_pub_spec.rb
36
41
  - spec/spec_helper.rb
42
+ - spec/unit/register_spec.rb
37
43
  - spec/unit/subscriber_spec.rb
38
44
  - sub_pub.gemspec
39
45
  homepage: ''
@@ -48,18 +54,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
48
54
  - - ! '>='
49
55
  - !ruby/object:Gem::Version
50
56
  version: '0'
51
- segments:
52
- - 0
53
- hash: -923795167419613194
54
57
  required_rubygems_version: !ruby/object:Gem::Requirement
55
58
  none: false
56
59
  requirements:
57
60
  - - ! '>='
58
61
  - !ruby/object:Gem::Version
59
62
  version: '0'
60
- segments:
61
- - 0
62
- hash: -923795167419613194
63
63
  requirements: []
64
64
  rubyforge_project:
65
65
  rubygems_version: 1.8.24
@@ -68,6 +68,8 @@ specification_version: 3
68
68
  summary: SubPub is a thin wrapper around ActiveSupport::Notifications, which provides
69
69
  an implementation of the Publish/Subscribe pattern.
70
70
  test_files:
71
- - spec/integration/pub_sub_spec.rb
71
+ - spec/integration/sub_pub_spec.rb
72
72
  - spec/spec_helper.rb
73
+ - spec/unit/register_spec.rb
73
74
  - spec/unit/subscriber_spec.rb
75
+ has_rdoc:
@@ -1,66 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SubPub do
4
- describe "initial state" do
5
- it "defaults enabled to true" do
6
- SubPub::Register.instance.enabled = nil
7
- SubPub.enabled?.should be_true
8
- end
9
- end
10
-
11
- describe "#enable" do
12
- it "enables SubPub" do
13
- SubPub.disable
14
- SubPub.enable
15
- SubPub.enabled?.should be_true
16
- end
17
- end
18
-
19
- describe "#disable" do
20
- it "disables SubPub" do
21
- SubPub.disable
22
- SubPub.enabled?.should be_false
23
- end
24
- end
25
-
26
- describe "#publish" do
27
- context "when disabled" do
28
- before { SubPub.disable }
29
-
30
- it "does not publish" do
31
- ActiveSupport::Notifications.should_receive(:publish).never
32
- SubPub.publish
33
- end
34
- end
35
- end
36
-
37
- describe "active record configuration" do
38
- with_model :FakeActiveRecordUser do
39
- table do |t|
40
- t.string :title
41
- end
42
- end
43
-
44
- with_model :FakeActiveRecordResult do
45
- table do |t|
46
- t.string :title
47
- end
48
- end
49
-
50
- before do
51
- class FakeActiveRecordUserSubscriber < SubPub::ActiveRecord::Subscriber
52
- subscribe_to(FakeActiveRecordUser, 'after_create')
53
-
54
- def on_publish
55
- FakeActiveRecordResult.create
56
- end
57
- end
58
- end
59
-
60
- it "successfully calls through to the subscriber" do
61
- FakeActiveRecordResult.all.size.should == 0
62
- FakeActiveRecordUser.create
63
- FakeActiveRecordResult.all.size.should == 1
64
- end
65
- end
66
- end