sub_pub 0.0.3 → 0.0.6

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.
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