chalk_dust 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ spec/db.sqlite3
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - '1.9.2'
4
+ - '1.9.3'
5
+ - jruby-19mode
6
+ - rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chalk_dust.gemspec
4
+ gemspec
5
+
6
+ # These are development dependencies
7
+
8
+ platforms :jruby do
9
+ gem "activerecord-jdbcsqlite3-adapter"
10
+ end
11
+
12
+ platforms :ruby do
13
+ gem "sqlite3-ruby"
14
+ end
data/Guardfile ADDED
@@ -0,0 +1,7 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
6
+ end
7
+
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # ChalkDust
2
+
3
+ ChalkDust can be used to build activty feeds such as followings and friendships
4
+ by allowing models to subscribe to activity feeds published by other models.
5
+
6
+ Every time an activity occurs it is copied to all subscribers of the target of
7
+ that activity. This creates an activty feed per subscriber (more data) which
8
+ scales better and allows additional features such as feed to delete/hide
9
+ activity items.
10
+
11
+ [![Code Climate](https://codeclimate.com/github/krisleech/chalk-dust.png)](https://codeclimate.com/github/krisleech/chalk-dust)
12
+ [![Build Status](https://travis-ci.org/krisleech/chalk-dust.png)](https://travis-ci.org/krisleech/chalk-dust)
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'chalk_dust'
19
+
20
+ ## Usage
21
+
22
+ ### Subscribing
23
+
24
+ A subscription connects two objects, e.g "Sam" follows "My first blog post"
25
+
26
+ ```ruby
27
+ ChalkDust.subscribe(user, :to => post)
28
+ ```
29
+
30
+ ```ruby
31
+ ChalkDust.subscribers_of(post) # => [user, post]
32
+ ```
33
+
34
+ #### Self-subscribing
35
+
36
+ Typically you will want to self-subscribe models on creation to themseleves so
37
+ an activity feed is built for the model itself.
38
+
39
+ ```ruby
40
+ ChalkDust.self_subscribe(user)
41
+ # or
42
+ ChalkDust.subscribe(user, :to => user)
43
+ ```
44
+
45
+ #### Undirected subscriptions
46
+
47
+ All subscriptions are directed. You can create a two way subscription, e.g a
48
+ friendship, as follows:
49
+
50
+ ```ruby
51
+ ChalkDust.subscribe(bob, :to => alice, :undirected => true)
52
+ # or
53
+ ChalkDust.subscribe(bob, :to => alice)
54
+ ChalkDust.subscribe(alice, :to => bob)
55
+ ```
56
+
57
+ ### Publishing activity
58
+
59
+ Describes an event where X (performer) did Y (activity) to Z (target).
60
+
61
+ ```ruby
62
+ ChalkDust.publish_event(user, 'added', comment)
63
+ ```
64
+
65
+ If the activity should be published to the feed of an object other
66
+ than the target then it can be either be passed as an additional argument or
67
+ provided as a method called `activity_root`.
68
+
69
+ ```ruby
70
+ ChalkDust.publish_event(user, 'added', comment, :root => comment.post)
71
+ ```
72
+
73
+ or
74
+
75
+ (TODO)
76
+ ```ruby
77
+ class Comment < ActiveRecord::Base
78
+ belongs_to :post
79
+
80
+ def activity_root
81
+ post
82
+ end
83
+ end
84
+ ```
85
+
86
+ ### Activity Feeds
87
+
88
+ ```ruby
89
+ ChalkDust.activity_feed_for(user, :since => 2.weeks.ago)
90
+ ChalkDust.activity_feed_for(post, :since => 2.weeks.ago)
91
+ ```
92
+
93
+ ## Contributing
94
+
95
+ Contributions welcome, please fork and send a pull request.
96
+
97
+ ## Thanks
98
+
99
+ Thanks to Igor @ Lifetrip Limited for allowing this code to be open sourced.
100
+
101
+ ## License
102
+
103
+ Copyright (c) 2013 Lifetrip Limited
104
+
105
+ MIT License
106
+
107
+ Permission is hereby granted, free of charge, to any person obtaining
108
+ a copy of this software and associated documentation files (the
109
+ "Software"), to deal in the Software without restriction, including
110
+ without limitation the rights to use, copy, modify, merge, publish,
111
+ distribute, sublicense, and/or sell copies of the Software, and to
112
+ permit persons to whom the Software is furnished to do so, subject to
113
+ the following conditions:
114
+
115
+ The above copyright notice and this permission notice shall be
116
+ included in all copies or substantial portions of the Software.
117
+
118
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
119
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
120
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
121
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
122
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
123
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
124
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new
7
+
8
+ task :default => :spec
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/chalk_dust/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Kris Leech"]
6
+ gem.email = ["kris.leech@gmail.com"]
7
+ gem.description = %q{Subscribe to and build activity feeds for your models, for example followings and friendships}
8
+ gem.summary = %q{Subscribe to and build activity feeds for your models, for example followings and friendships}
9
+ gem.homepage = "https://github.com/krisleech/chalk-dust"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "chalk_dust"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = ChalkDust::VERSION
17
+
18
+ gem.add_dependency "activerecord", "~> 3.0"
19
+
20
+ gem.add_development_dependency "bundler"
21
+ gem.add_development_dependency "rspec", "~> 2.3"
22
+ gem.add_development_dependency 'rake'
23
+ gem.add_development_dependency 'simplecov'
24
+ gem.add_development_dependency 'guard-rspec'
25
+ end
data/lib/chalk_dust.rb ADDED
@@ -0,0 +1,63 @@
1
+ require "chalk_dust/version"
2
+
3
+ module ChalkDust
4
+ class Connection < ActiveRecord::Base
5
+ belongs_to :publisher, :polymorphic => true
6
+ belongs_to :subscriber, :polymorphic => true
7
+
8
+ def self.subscribers_of(publisher)
9
+ where(:publisher_id => publisher.id,
10
+ :publisher_type => publisher.class.to_s).map(&:subscriber)
11
+ end
12
+ end
13
+
14
+ class ActivityItem < ActiveRecord::Base
15
+ belongs_to :performer, :polymorphic => true
16
+ belongs_to :target, :polymorphic => true
17
+ belongs_to :owner, :polymorphic => true
18
+
19
+ validates :event, :presence => true
20
+
21
+ def self.for_owner(owner)
22
+ where(:owner_id => owner.id,
23
+ :owner_type => owner.class.to_s)
24
+ end
25
+
26
+ def self.since(time)
27
+ where("created_at >= ?", time)
28
+ end
29
+ end
30
+
31
+ def self.subscribe(subscriber, options)
32
+ publisher = options.fetch(:to)
33
+ undirected = options.fetch(:undirected, false)
34
+ Connection.create(:subscriber => subscriber, :publisher => publisher)
35
+ Connection.create(:subscriber => publisher, :publisher => subscriber) if undirected
36
+ end
37
+
38
+ def self.subscribers_of(publisher)
39
+ Connection.subscribers_of(publisher)
40
+ end
41
+
42
+ def self.self_subscribe(publisher_subscriber)
43
+ subscribe(publisher_subscriber, :to => publisher_subscriber)
44
+ end
45
+
46
+ # publishes an event where X (performer) did Y (event) to Z (target) to every
47
+ # subscriber of the target
48
+ def self.publish_event(performer, event, target, options = {})
49
+ root_publisher = options.fetch(:root, target)
50
+ subscribers_of(root_publisher).map do |subscriber|
51
+ ActivityItem.create(:performer => performer,
52
+ :event => event,
53
+ :target => target,
54
+ :owner => subscriber)
55
+ end
56
+ end
57
+
58
+ def self.activity_feed_for(subscriber, options = {})
59
+ activity_items = ActivityItem.for_owner(subscriber)
60
+ activity_items = activity_items.since(options[:since]) if options[:since].present?
61
+ activity_items
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module ChalkDust
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'activity feeds' do
4
+ before(:each) do
5
+ ChalkDust::ActivityItem.delete_all
6
+ end
7
+
8
+ describe '.activity_feed_for' do
9
+ it 'returns activity feed for given object' do
10
+ kris = User.create!
11
+ lindsey = User.create!
12
+ hallie = User.create!
13
+ post = Post.create!
14
+ comment = Comment.create!
15
+
16
+ activity_item_1 = ChalkDust::ActivityItem.create(:performer => kris,
17
+ :event => 'editted',
18
+ :target => post,
19
+ :owner => hallie)
20
+
21
+ activity_item_2 = ChalkDust::ActivityItem.create(:performer => lindsey,
22
+ :event => 'added',
23
+ :target => comment,
24
+ :owner => hallie)
25
+
26
+ activity_items = ChalkDust.activity_feed_for(hallie)
27
+ activity_items.should == [activity_item_1, activity_item_2]
28
+ end
29
+
30
+ describe 'options' do
31
+ it ':since limits to activities created since the given date' do
32
+ kris = User.create!
33
+ lindsey = User.create!
34
+ hallie = User.create!
35
+ post = Post.create!
36
+ comment = Comment.create!
37
+
38
+ activity_item_1 = ChalkDust::ActivityItem.create(:performer => kris,
39
+ :event => 'editted',
40
+ :target => post,
41
+ :owner => hallie,
42
+ :created_at => 2.months.ago)
43
+
44
+ activity_item_2 = ChalkDust::ActivityItem.create(:performer => lindsey,
45
+ :event => 'added',
46
+ :target => comment,
47
+ :owner => hallie)
48
+
49
+ activity_items = ChalkDust.activity_feed_for(hallie, :since => Time.now - 1.week)
50
+ activity_items.should == [activity_item_2]
51
+ end
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'publishing' do
4
+ before(:each) do
5
+ ChalkDust::Connection.delete_all
6
+ ChalkDust::ActivityItem.delete_all
7
+ end
8
+
9
+ describe '.publish_event' do
10
+ it 'creates an event for every subscriber' do
11
+ kris = User.create!
12
+ lindsey = User.create!
13
+ hallie = User.create!
14
+ post = Post.create!
15
+
16
+ ChalkDust::Connection.create(:subscriber => kris, :publisher => post)
17
+ ChalkDust::Connection.create(:subscriber => lindsey, :publisher => post)
18
+
19
+ activity_items = ChalkDust.publish_event(kris, 'editted', post)
20
+
21
+ activity_items.size.should == 2
22
+
23
+ activity_item = activity_items.first
24
+ activity_item.performer.should == kris
25
+ activity_item.event.should == 'editted'
26
+ activity_item.target.should == post
27
+ activity_item.owner.should == kris
28
+
29
+ activity_item = activity_items.last
30
+ activity_item.performer.should == kris
31
+ activity_item.event.should == 'editted'
32
+ activity_item.target.should == post
33
+ activity_item.owner.should == lindsey
34
+ end
35
+
36
+ describe 'options' do
37
+ describe ':root' do
38
+ it 'sets the root object of the target' do
39
+ kris = User.create!
40
+ lindsey = User.create!
41
+ post = Post.create!
42
+ comment = Comment.create!(:post => post)
43
+
44
+ ChalkDust::Connection.create(:subscriber => lindsey, :publisher => post)
45
+
46
+ activity_items = ChalkDust.publish_event(kris, 'added', comment, :root => comment.post)
47
+
48
+ activity_items.size.should == 1
49
+
50
+ activity_item = activity_items.first
51
+ activity_item.performer.should == kris
52
+ activity_item.event.should == 'added'
53
+ activity_item.target.should == comment
54
+ activity_item.owner.should == lindsey
55
+ end
56
+ end
57
+ end
58
+
59
+ # pending 'target root can be set by the `activity_root` method on the target'
60
+ end
61
+ end
62
+
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe ChalkDust do
4
+ before(:each) { ChalkDust::Connection.delete_all }
5
+
6
+ describe 'subscribing' do
7
+ it '.subscribe connects two objects' do
8
+ user = User.create!
9
+ post = Post.create!
10
+
11
+ ChalkDust.subscribe(user, :to => post)
12
+
13
+ connection = ChalkDust::Connection.first
14
+ connection.subscriber.should == user
15
+ connection.publisher.should == post
16
+ end
17
+
18
+ it '.self_subscribe connects object to itself' do
19
+ user = User.create!
20
+
21
+ ChalkDust.self_subscribe(user)
22
+
23
+ connection = ChalkDust::Connection.first
24
+ connection.subscriber.should == user
25
+ connection.publisher.should == user
26
+ end
27
+
28
+ describe 'options' do
29
+ it ':undirected subscribes in both directions' do
30
+ bob = User.create!
31
+ alice = User.create!
32
+
33
+ ChalkDust.subscribe(bob, :to => alice, :undirected => true)
34
+
35
+ ChalkDust::Connection.count.should == 2
36
+
37
+ connection_1 = ChalkDust::Connection.first
38
+ connection_1.subscriber.should == bob
39
+ connection_1.publisher.should == alice
40
+
41
+ connection_2 = ChalkDust::Connection.last
42
+ connection_2.subscriber.should == alice
43
+ connection_2.publisher.should == bob
44
+ end
45
+ end
46
+ end
47
+
48
+ describe 'fetching subscriptions' do
49
+ it '.subscriptions_of returns subscribers to given object' do
50
+ user = User.create!
51
+ post = Post.create!
52
+
53
+ ChalkDust::Connection.create!(:subscriber => user, :publisher => post)
54
+
55
+ ChalkDust.subscribers_of(post).should == [user]
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,21 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'active_record'
5
+ require 'chalk_dust'
6
+
7
+ adapter = RUBY_PLATFORM == "java" ? 'jdbcsqlite3' : 'sqlite3'
8
+
9
+ ActiveRecord::Base.establish_connection(:adapter => adapter,
10
+ :database => File.dirname(__FILE__) + "/db.sqlite3")
11
+
12
+ load File.dirname(__FILE__) + '/support/schema.rb'
13
+
14
+ require 'support/models'
15
+
16
+ RSpec.configure do |config|
17
+ config.treat_symbols_as_metadata_keys_with_true_values = true
18
+ config.run_all_when_everything_filtered = true
19
+ config.filter_run :focus
20
+ config.order = 'random'
21
+ end
@@ -0,0 +1,12 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :comments
3
+ end
4
+
5
+ class Post < ActiveRecord::Base
6
+ has_many :comments
7
+ end
8
+
9
+ class Comment < ActiveRecord::Base
10
+ belongs_to :post
11
+ belongs_to :user
12
+ end
@@ -0,0 +1,48 @@
1
+ ActiveRecord::Schema.define do
2
+ self.verbose = false
3
+
4
+ create_table :users, :force => true do |t|
5
+ t.integer :id
6
+ t.string :name
7
+ t.string :email
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :posts, :force => true do |t|
12
+ t.integer :id
13
+ t.string :title
14
+ t.string :body
15
+ t.timestamps
16
+ end
17
+
18
+ create_table :comments, :force => true do |t|
19
+ t.integer :id
20
+ t.integer :user_id
21
+ t.integer :post_id
22
+ t.string :body
23
+ t.timestamps
24
+ end
25
+
26
+ create_table :connections, :force => true do |t|
27
+ t.integer :subscriber_id
28
+ t.string :subscriber_type
29
+ t.integer :publisher_id
30
+ t.string :publisher_type
31
+ t.timestamps
32
+ end
33
+
34
+ create_table :activity_items, :force => true do |t|
35
+ t.integer :performer_id
36
+ t.string :performer_type
37
+
38
+ t.string :event
39
+
40
+ t.integer :target_id
41
+ t.string :target_type
42
+
43
+ t.integer :owner_id
44
+ t.string :owner_type
45
+
46
+ t.timestamps
47
+ end
48
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chalk_dust
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kris Leech
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '2.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: simplecov
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Subscribe to and build activity feeds for your models, for example followings
111
+ and friendships
112
+ email:
113
+ - kris.leech@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - .travis.yml
121
+ - Gemfile
122
+ - Guardfile
123
+ - README.md
124
+ - Rakefile
125
+ - chalk_dust.gemspec
126
+ - lib/chalk_dust.rb
127
+ - lib/chalk_dust/version.rb
128
+ - spec/lib/chalk_dust/activity_feeds_spec.rb
129
+ - spec/lib/chalk_dust/publishing_spec.rb
130
+ - spec/lib/chalk_dust/subscribing_spec.rb
131
+ - spec/spec_helper.rb
132
+ - spec/support/models.rb
133
+ - spec/support/schema.rb
134
+ homepage: https://github.com/krisleech/chalk-dust
135
+ licenses: []
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ segments:
147
+ - 0
148
+ hash: -4022978035697313999
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ segments:
156
+ - 0
157
+ hash: -4022978035697313999
158
+ requirements: []
159
+ rubyforge_project:
160
+ rubygems_version: 1.8.23
161
+ signing_key:
162
+ specification_version: 3
163
+ summary: Subscribe to and build activity feeds for your models, for example followings
164
+ and friendships
165
+ test_files:
166
+ - spec/lib/chalk_dust/activity_feeds_spec.rb
167
+ - spec/lib/chalk_dust/publishing_spec.rb
168
+ - spec/lib/chalk_dust/subscribing_spec.rb
169
+ - spec/spec_helper.rb
170
+ - spec/support/models.rb
171
+ - spec/support/schema.rb