protocolist 0.9.0.beta → 1.0.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.
- data/.gitignore +1 -0
- data/Guardfile +1 -1
- data/README.md +13 -15
- data/Rakefile +1 -1
- data/lib/generators/protocolist/install/install_generator.rb +65 -10
- data/lib/generators/protocolist/install/templates/migration.rb +5 -4
- data/lib/protocolist.rb +11 -20
- data/lib/protocolist/controller_additions.rb +32 -37
- data/lib/protocolist/controller_additions/initializer.rb +16 -0
- data/lib/protocolist/model_additions.rb +30 -28
- data/lib/protocolist/railtie.rb +9 -2
- data/lib/protocolist/util/data_proc.rb +23 -0
- data/lib/protocolist/version.rb +1 -1
- data/protocolist.gemspec +6 -3
- data/spec/protocolist/controller_additions_spec.rb +42 -45
- data/spec/protocolist/model_additions_spec.rb +66 -67
- data/spec/protocolist_spec.rb +29 -24
- data/spec/spec_helper.rb +4 -1
- metadata +90 -21
data/.gitignore
CHANGED
data/Guardfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'guard/guard'
|
2
2
|
|
3
|
-
guard :rspec, :
|
3
|
+
guard :rspec, all_on_start: false, all_after_pass: false, cli: '--fail-fast --format doc' do
|
4
4
|
watch(%r{^spec/.+_spec\.rb$})
|
5
5
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
6
6
|
watch('spec/spec_helper.rb') { "spec" }
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#Protocolist
|
1
|
+
#Protocolist
|
2
|
+
[](http://travis-ci.org/welldan97/protocolist) [](https://gemnasium.com/welldan97/protocolist) [](https://codeclimate.com/github/welldan97/protocolist)
|
2
3
|
|
3
4
|
Simple activity feeds solution for Rails applications. Gives a flexible way to build activity feeds infrastructure over it.
|
4
5
|
|
@@ -27,7 +28,7 @@ Getting started
|
|
27
28
|
---------------
|
28
29
|
|
29
30
|
Activity model has four attributes: actor("who did it"), activity_type("what
|
30
|
-
they did"), target("what they did it to") and data(additional information).
|
31
|
+
they did"), target("what they did it to") and data(additional information). Actor will be
|
31
32
|
set as current user by default.
|
32
33
|
|
33
34
|
Protocolist expects you to have `current_user` method in a
|
@@ -51,12 +52,12 @@ Activity with current user set as actor, `:create` as type,
|
|
51
52
|
The more convenient usage:
|
52
53
|
|
53
54
|
```ruby
|
54
|
-
fires :edit,
|
55
|
-
:
|
56
|
-
:
|
55
|
+
fires :edit, on: :update,
|
56
|
+
data: :changes,
|
57
|
+
if: 'changes.any?'
|
57
58
|
```
|
58
59
|
|
59
|
-
The event type will be `edit`. A proc, symbol
|
60
|
+
The event type will be `edit`. A proc, symbol and a string for data
|
60
61
|
option represent a method, else types will be stored as is.
|
61
62
|
|
62
63
|
The `unless` option also can be passed.
|
@@ -64,7 +65,7 @@ The `unless` option also can be passed.
|
|
64
65
|
The `on` option can be an array:
|
65
66
|
|
66
67
|
```ruby
|
67
|
-
fires :comment_activity, :
|
68
|
+
fires :comment_activity, on: [:create, :update, :destroy]
|
68
69
|
```
|
69
70
|
|
70
71
|
The most flexible way is to use `fire` method:
|
@@ -72,7 +73,7 @@ The most flexible way is to use `fire` method:
|
|
72
73
|
```ruby
|
73
74
|
def destroy_projects
|
74
75
|
self.projects.destroy_all
|
75
|
-
fire :destroy_all, :
|
76
|
+
fire :destroy_all, target: false, data: { company_id: company_id }
|
76
77
|
end
|
77
78
|
```
|
78
79
|
|
@@ -92,9 +93,9 @@ which will strike after download action.
|
|
92
93
|
The customized one:
|
93
94
|
|
94
95
|
```ruby
|
95
|
-
fires :download, :
|
96
|
-
:
|
97
|
-
:
|
96
|
+
fires :download, only: [:download_report, :download_file, :download_map],
|
97
|
+
data: ->(c) { c.params[:city] },
|
98
|
+
if: ->(c) { c.response.status == 200 }
|
98
99
|
```
|
99
100
|
|
100
101
|
The `fire` method can be used same way as in models, but also if type is not
|
@@ -111,7 +112,7 @@ is the same as
|
|
111
112
|
```ruby
|
112
113
|
def show
|
113
114
|
@article = Article.find(params[:id])
|
114
|
-
fire :show, :
|
115
|
+
fire :show, target: @article
|
115
116
|
end
|
116
117
|
```
|
117
118
|
|
@@ -130,6 +131,3 @@ Protocolist was inspired by
|
|
130
131
|
[timeline_fu](https://github.com/jamesgolick/timeline_fu). I used it,
|
131
132
|
but its functionality wasn't enough for me, so I made my own with
|
132
133
|
blackjack and stewardesses.
|
133
|
-
|
134
|
-
|
135
|
-
|
data/Rakefile
CHANGED
@@ -7,23 +7,78 @@ module Protocolist
|
|
7
7
|
|
8
8
|
source_root File.expand_path("../templates", __FILE__)
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
model_content = <<CONTENT
|
14
|
-
attr_accessible :activity_type, :target, :actor, :data
|
15
|
-
belongs_to :target, :polymorphic => true
|
16
|
-
belongs_to :actor, :polymorphic => true
|
17
|
-
serialize :data
|
18
|
-
CONTENT
|
19
|
-
inject_into_class('app/models/activity.rb', 'Activity', model_content) if File.exists?(File.join(destination_root, 'app/models/activity.rb'))
|
10
|
+
class_option 'model-orm', type: :string, default: 'active_record', aliases: '-o', desc: 'Model ORM (ActiveRecord or MongoId)'
|
11
|
+
class_option 'model-classname', type: :string, default: 'Activity', aliases: '-c'
|
12
|
+
class_option 'model-filename', type: :string, default: 'app/models/activity.rb', aliases: '-f'
|
20
13
|
|
21
14
|
|
15
|
+
def generate_activity_model
|
16
|
+
if model_orm == 'mongoid' && defined?(Mongoid)
|
17
|
+
generate_mongoid_activity_model
|
18
|
+
elsif model_orm == 'active_record' && defined?(ActiveRecord)
|
19
|
+
generate_active_record_activity_model
|
20
|
+
end
|
22
21
|
end
|
23
22
|
|
24
23
|
def self.next_migration_number(dirname) #:nodoc:
|
25
24
|
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
26
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def generate_mongoid_activity_model
|
30
|
+
content = <<-CONTENT.gsub(/^ +/, ' ')
|
31
|
+
|
32
|
+
belongs_to :actor, polymorphic: true
|
33
|
+
belongs_to :target, polymorphic: true
|
34
|
+
|
35
|
+
field :activity_type, type: String
|
36
|
+
field :data, type: Hash
|
37
|
+
CONTENT
|
38
|
+
|
39
|
+
|
40
|
+
invoke "mongoid:model", [model_classname]
|
41
|
+
|
42
|
+
if model_exists?
|
43
|
+
inject_into_file(model_filename, content, after: "include Mongoid::Document\n")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_active_record_activity_model
|
48
|
+
content = <<-CONTENT.gsub(/^ +/, ' ')
|
49
|
+
attr_accessible :activity_type, :target, :actor, :data
|
50
|
+
|
51
|
+
belongs_to :target, polymorphic: true
|
52
|
+
belongs_to :actor, polymorphic: true
|
53
|
+
|
54
|
+
serialize :data
|
55
|
+
CONTENT
|
56
|
+
|
57
|
+
|
58
|
+
migration_template "migration.rb", "db/migrate/create_activities"
|
59
|
+
invoke "active_record:model", [model_classname], migration: false
|
60
|
+
|
61
|
+
if model_exists?
|
62
|
+
gsub_file model_filename, / +# attr_accessible :title, :body\n/, ''
|
63
|
+
inject_into_class(model_filename, model_classname, content)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def model_exists?
|
68
|
+
File.exists?(File.join(destination_root, model_filename))
|
69
|
+
end
|
70
|
+
|
71
|
+
def model_filename
|
72
|
+
options['model-filename']
|
73
|
+
end
|
74
|
+
|
75
|
+
def model_classname
|
76
|
+
options['model-classname']
|
77
|
+
end
|
78
|
+
|
79
|
+
def model_orm
|
80
|
+
options['model-orm']
|
81
|
+
end
|
27
82
|
end
|
28
83
|
end
|
29
84
|
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
class CreateActivities < ActiveRecord::Migration
|
2
2
|
def change
|
3
3
|
create_table :activities do |t|
|
4
|
-
t.references :actor,
|
5
|
-
t.references :target, :
|
4
|
+
t.references :actor, polymorphic: true
|
5
|
+
t.references :target, polymorphic: true
|
6
|
+
|
6
7
|
t.string :activity_type
|
7
8
|
t.text :data
|
8
9
|
|
9
10
|
t.timestamps
|
10
11
|
end
|
11
|
-
add_index :activities, :actor_id
|
12
|
-
add_index :activities, :target_id
|
12
|
+
add_index :activities, [:actor_id, :actor_type]
|
13
|
+
add_index :activities, [:target_id, :target_type]
|
13
14
|
end
|
14
15
|
end
|
data/lib/protocolist.rb
CHANGED
@@ -1,29 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require "protocolist/model_additions"
|
3
|
-
require "protocolist/controller_additions"
|
4
|
-
require "protocolist/railtie" if defined? Rails
|
1
|
+
require 'active_support'
|
5
2
|
|
3
|
+
require 'protocolist/version'
|
4
|
+
require 'protocolist/model_additions'
|
5
|
+
require 'protocolist/controller_additions'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
def self.fire activity_type, options={}
|
10
|
-
options = {:actor => @actor, :activity_type => activity_type}.merge options
|
11
|
-
@activity_class.create options if options[:actor] && @activity_class
|
12
|
-
end
|
7
|
+
require 'protocolist/railtie' if defined? Rails
|
13
8
|
|
14
|
-
def self.actor
|
15
|
-
@actor
|
16
|
-
end
|
17
9
|
|
18
|
-
|
19
|
-
@actor = actor
|
20
|
-
end
|
10
|
+
module Protocolist
|
21
11
|
|
22
|
-
def self.
|
23
|
-
|
12
|
+
def self.fire(activity_type, options = {})
|
13
|
+
options = options.reverse_merge(actor:@actor, activity_type: activity_type)
|
14
|
+
@activity_class.try(:create, options) if options[:actor]
|
24
15
|
end
|
25
16
|
|
26
|
-
|
27
|
-
|
17
|
+
class << self
|
18
|
+
attr_accessor :actor, :activity_class
|
28
19
|
end
|
29
20
|
end
|
@@ -1,50 +1,45 @@
|
|
1
|
+
require 'protocolist/controller_additions/initializer'
|
2
|
+
require 'protocolist/util/data_proc'
|
3
|
+
|
1
4
|
module Protocolist
|
2
5
|
module ControllerAdditions
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
options_for_callback = options.select{|k,v| [:if, :unless, :only, :except].include? k }
|
17
|
-
|
18
|
-
options_for_fire = options.reject{|k,v| [:if, :unless, :only, :except].include? k }
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
include Initializer
|
8
|
+
include Util::DataProc
|
9
|
+
|
10
|
+
def fire(activity_type = nil, options = {})
|
11
|
+
target = case options[:target]
|
12
|
+
when nil
|
13
|
+
instance_variable_get("@#{controller_name.singularize}")
|
14
|
+
when false
|
15
|
+
nil
|
16
|
+
else
|
17
|
+
options[:target]
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
}
|
20
|
+
activity_type ||= action_name.to_sym
|
21
|
+
options = options.merge(target: target)
|
23
22
|
|
24
|
-
|
25
|
-
|
23
|
+
Protocolist.fire(activity_type, options)
|
24
|
+
end
|
26
25
|
|
26
|
+
module ClassMethods
|
27
|
+
def fires(activity_type, options = {})
|
28
|
+
options = options.merge(only: activity_type) unless options[:only] || options[:except]
|
27
29
|
|
28
|
-
|
29
|
-
base.send(:before_filter, :initilize_protocolist)
|
30
|
-
end
|
31
|
-
end
|
30
|
+
data_proc = extract_data_proc(options[:data])
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
end
|
32
|
+
options_for_callback = options.slice(:if, :unless, :only, :except)
|
33
|
+
options_for_fire = options.except(:if, :unless, :only, :except)
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
options[:target] = nil if options[:target] == false
|
40
|
-
activity_type ||= action_name.to_sym
|
35
|
+
callback_proc = ->(controller; options) do
|
36
|
+
options = options_for_fire.merge(data: data_proc.call(controller))
|
41
37
|
|
42
|
-
|
43
|
-
|
38
|
+
controller.fire(activity_type, options)
|
39
|
+
end
|
44
40
|
|
45
|
-
|
46
|
-
|
47
|
-
Protocolist.activity_class = Activity
|
41
|
+
send(:after_filter, callback_proc, options_for_callback)
|
42
|
+
end
|
48
43
|
end
|
49
44
|
end
|
50
45
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Protocolist
|
2
|
+
module ControllerAdditions
|
3
|
+
module Initializer
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_filter :initialize_protocolist
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize_protocolist
|
11
|
+
Protocolist.actor = current_user
|
12
|
+
Protocolist.activity_class = Activity
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,41 +1,43 @@
|
|
1
|
+
require 'protocolist/util/data_proc'
|
2
|
+
|
1
3
|
module Protocolist
|
2
4
|
module ModelAdditions
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include Util::DataProc
|
7
|
+
|
8
|
+
def fire(activity_type, options = {})
|
9
|
+
target = case options[:target]
|
10
|
+
when nil
|
11
|
+
self
|
12
|
+
when false
|
13
|
+
nil
|
14
|
+
else
|
15
|
+
options[:target]
|
16
|
+
end
|
17
|
+
|
18
|
+
options = options.merge(target: target)
|
19
|
+
|
20
|
+
Protocolist.fire(activity_type, options)
|
21
|
+
end
|
7
22
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
else
|
13
|
-
lambda{|record| options[:data] }
|
14
|
-
end
|
23
|
+
module ClassMethods
|
24
|
+
def fires(activity_type, options = {})
|
25
|
+
fires_on = [*options[:on] || activity_type]
|
26
|
+
data_proc = extract_data_proc(options[:data])
|
15
27
|
|
16
|
-
options_for_callback = options.
|
28
|
+
options_for_callback = options.slice(:if, :unless)
|
29
|
+
options_for_fire = options.except(:if, :unless, :on)
|
17
30
|
|
18
|
-
|
31
|
+
callback_proc = ->(record; options) do
|
32
|
+
options = options_for_fire.merge(data: data_proc.call(record))
|
19
33
|
|
20
|
-
|
21
|
-
|
22
|
-
}
|
34
|
+
record.fire(activity_type, options)
|
35
|
+
end
|
23
36
|
|
24
37
|
fires_on.each do |on|
|
25
|
-
send("after_#{on
|
38
|
+
send("after_#{on}", callback_proc, options_for_callback)
|
26
39
|
end
|
27
40
|
end
|
28
41
|
end
|
29
|
-
|
30
|
-
def self.included base
|
31
|
-
base.extend ClassMethods
|
32
|
-
end
|
33
|
-
|
34
|
-
def fire activity_type, options={}
|
35
|
-
options[:target] = self if options[:target] == nil
|
36
|
-
options[:target] = nil if options[:target] == false
|
37
|
-
|
38
|
-
Protocolist.fire activity_type, options
|
39
|
-
end
|
40
42
|
end
|
41
43
|
end
|
data/lib/protocolist/railtie.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
module Protocolist
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
initializer 'protocolist.model_additions' do
|
4
|
-
ActiveSupport.on_load
|
4
|
+
ActiveSupport.on_load(:active_record) do
|
5
5
|
include ModelAdditions
|
6
6
|
end
|
7
|
+
if defined?(Mongoid)
|
8
|
+
Mongoid::Document.module_eval do
|
9
|
+
included do
|
10
|
+
include ModelAdditions
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
7
14
|
end
|
8
15
|
initializer 'protocolist.controller_additions' do
|
9
|
-
ActiveSupport.on_load
|
16
|
+
ActiveSupport.on_load(:action_controller) do
|
10
17
|
include ControllerAdditions
|
11
18
|
end
|
12
19
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Protocolist
|
2
|
+
module Util
|
3
|
+
module DataProc
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
private
|
8
|
+
|
9
|
+
def extract_data_proc(data)
|
10
|
+
if data.respond_to?(:call)
|
11
|
+
->(o) { data.call(o) }
|
12
|
+
elsif data.is_a?(Symbol)
|
13
|
+
->(o) { o.send(data) }
|
14
|
+
elsif data.is_a?(String)
|
15
|
+
->(o) { o.instance_eval "(#{data})" }
|
16
|
+
else
|
17
|
+
->(_) { data }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/protocolist/version.rb
CHANGED
data/protocolist.gemspec
CHANGED
@@ -18,9 +18,12 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
+
s.add_dependency 'activesupport', '~> 3.0'
|
22
|
+
|
21
23
|
s.add_development_dependency 'rake'
|
22
|
-
s.add_development_dependency 'rspec', '~> 2.
|
23
|
-
s.add_development_dependency 'guard-rspec', '~>
|
24
|
-
s.add_development_dependency 'supermodel'
|
24
|
+
s.add_development_dependency 'rspec', '~> 2.12.0'
|
25
|
+
s.add_development_dependency 'guard-rspec', '~> 2.3.0'
|
26
|
+
s.add_development_dependency 'supermodel', '~> 0.1.6'
|
27
|
+
s.add_development_dependency 'psych', '~> 1.3.0' # fixes ' superclass mismatch for class Mark ' error
|
25
28
|
s.add_development_dependency 'railties', '~> 3.0'
|
26
29
|
end
|
@@ -1,59 +1,57 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
class User < SuperModel::Base
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
class Activity < SuperModel::Base
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
3
|
class FirestartersController
|
12
4
|
#stub before filter
|
13
5
|
def self.before_filter *args
|
14
6
|
end
|
15
7
|
|
16
8
|
include Protocolist::ControllerAdditions
|
17
|
-
|
18
|
-
|
9
|
+
|
10
|
+
def explicit_use(target, data)
|
11
|
+
fire :gogogo, target: target, data: data
|
19
12
|
end
|
20
13
|
|
21
|
-
def implicit_use
|
22
|
-
@firestarter =
|
14
|
+
def implicit_use(target)
|
15
|
+
@firestarter = target
|
23
16
|
fire
|
24
17
|
end
|
25
18
|
end
|
26
19
|
|
27
20
|
describe Protocolist::ControllerAdditions do
|
21
|
+
let(:controller) { FirestartersController.new }
|
22
|
+
let(:actor) { User.new(name: 'Bill') }
|
23
|
+
let(:lisa) { User.new(name: 'Lisa') }
|
24
|
+
let(:mary) { User.new(name: 'Mary') }
|
25
|
+
|
28
26
|
before :each do
|
29
27
|
Activity.destroy_all
|
30
|
-
user = User.new(:name => 'Bill')
|
31
|
-
@controller = FirestartersController.new
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
controller.stub(:current_user).and_return(actor)
|
30
|
+
controller.stub(:controller_name).and_return('firestarters')
|
31
|
+
controller.stub(:action_name).and_return('quick_and_dirty_action_stub')
|
32
|
+
controller.stub(:params).and_return('les params')
|
37
33
|
|
38
|
-
|
34
|
+
controller.initialize_protocolist
|
39
35
|
end
|
40
36
|
|
41
37
|
describe 'direct fire method call' do
|
42
38
|
it 'saves record with target and data when called explicitly' do
|
43
|
-
|
39
|
+
controller.explicit_use(lisa, '<3 <3 <3')
|
44
40
|
|
45
|
-
Activity.last
|
46
|
-
|
47
|
-
|
48
|
-
|
41
|
+
activity = Activity.last
|
42
|
+
activity.actor.should == actor
|
43
|
+
activity.activity_type.should == :gogogo
|
44
|
+
activity.target.should == lisa
|
45
|
+
activity.data.should == '<3 <3 <3'
|
49
46
|
end
|
50
47
|
|
51
48
|
it 'saves record with target and data when called implicitly' do
|
52
|
-
|
49
|
+
controller.implicit_use(mary)
|
53
50
|
|
54
|
-
Activity.last
|
55
|
-
|
56
|
-
|
51
|
+
activity = Activity.last
|
52
|
+
activity.actor.should == actor
|
53
|
+
activity.activity_type.should == :quick_and_dirty_action_stub
|
54
|
+
activity.target.should == mary
|
57
55
|
end
|
58
56
|
end
|
59
57
|
|
@@ -61,36 +59,35 @@ describe Protocolist::ControllerAdditions do
|
|
61
59
|
it 'saves record when called with minimal options' do
|
62
60
|
FirestartersController.should_receive(:after_filter) do |callback_proc, options|
|
63
61
|
options[:only].should == :download
|
62
|
+
expect { callback_proc.call(controller) }.to change { Activity.count }.by(1)
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
Activity.last.activity_type.should == :download
|
70
|
-
Activity.last.target.should_not be
|
64
|
+
activity = Activity.last
|
65
|
+
activity.actor.should == actor
|
66
|
+
activity.activity_type.should == :download
|
67
|
+
activity.target.should_not be
|
71
68
|
end
|
69
|
+
|
72
70
|
FirestartersController.send(:fires, :download)
|
73
71
|
end
|
74
72
|
|
75
73
|
it 'saves record when called with complex options' do
|
76
74
|
FirestartersController.should_receive(:after_filter) do |callback_proc, options|
|
77
75
|
options[:only].should == [:download_report, :download_file, :download_map]
|
78
|
-
options[:if].should
|
76
|
+
options[:if].should == 'if condition'
|
79
77
|
|
80
|
-
expect {
|
81
|
-
callback_proc.call(@controller)
|
82
|
-
}.to change{Activity.count}.by 1
|
78
|
+
expect { callback_proc.call(controller) }.to change { Activity.count }.by(1)
|
83
79
|
|
84
|
-
Activity.last
|
85
|
-
|
86
|
-
|
87
|
-
|
80
|
+
activity = Activity.last
|
81
|
+
activity.actor.should == actor
|
82
|
+
activity.activity_type.should == :download
|
83
|
+
activity.data.should == 'les params'
|
84
|
+
activity.target.should_not be
|
88
85
|
end
|
89
86
|
|
90
87
|
FirestartersController.send(:fires, :download,
|
91
|
-
|
92
|
-
|
93
|
-
|
88
|
+
only: [:download_report, :download_file, :download_map],
|
89
|
+
data: ->(c) { c.params }, if: 'if condition'
|
90
|
+
)
|
94
91
|
end
|
95
92
|
end
|
96
93
|
end
|
@@ -1,41 +1,31 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
class User < SuperModel::Base
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
class Activity < SuperModel::Base
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
3
|
class Firestarter < SuperModel::Base
|
12
4
|
include Protocolist::ModelAdditions
|
13
5
|
|
14
6
|
def delete
|
15
|
-
fire :delete, :
|
7
|
+
fire :delete, target: false
|
16
8
|
end
|
17
9
|
|
18
10
|
def myself
|
19
11
|
fire :myself
|
20
12
|
end
|
21
13
|
|
22
|
-
def love_letter_for_mary
|
23
|
-
|
24
|
-
fire :love_letter, :target => user, :data => '<3 <3 <3'
|
14
|
+
def love_letter_for_mary(target, data)
|
15
|
+
fire :love_letter, target: target, data: data
|
25
16
|
end
|
26
17
|
end
|
27
18
|
|
28
19
|
class SimpleFirestarter < SuperModel::Base
|
29
20
|
include Protocolist::ModelAdditions
|
30
|
-
|
31
21
|
fires :create
|
32
22
|
end
|
33
23
|
|
34
24
|
class ConditionalFirestarter < SuperModel::Base
|
35
25
|
include Protocolist::ModelAdditions
|
36
26
|
|
37
|
-
fires :i_will_be_saved, :
|
38
|
-
fires :and_i_won_t,
|
27
|
+
fires :i_will_be_saved, on: :create, if: :return_true_please
|
28
|
+
fires :and_i_won_t, on: :create, if: :return_false_please
|
39
29
|
|
40
30
|
def return_false_please
|
41
31
|
false
|
@@ -49,7 +39,8 @@ end
|
|
49
39
|
class ComplexFirestarter < SuperModel::Base
|
50
40
|
include Protocolist::ModelAdditions
|
51
41
|
|
52
|
-
fires :yohoho, :
|
42
|
+
fires :yohoho, on: [:create, :destroy], target: false, data: :hi
|
43
|
+
fires :yohoho, on: :update, data: 'name * 2'
|
53
44
|
|
54
45
|
def hi
|
55
46
|
'Hi!'
|
@@ -57,87 +48,95 @@ class ComplexFirestarter < SuperModel::Base
|
|
57
48
|
end
|
58
49
|
|
59
50
|
describe Protocolist::ModelAdditions do
|
60
|
-
|
51
|
+
let(:actor) { User.new(name: 'Bill') }
|
52
|
+
let(:mary) { User.new(name: 'Mary') }
|
53
|
+
|
54
|
+
before do
|
61
55
|
Activity.destroy_all
|
62
|
-
|
63
|
-
Protocolist.actor =
|
56
|
+
|
57
|
+
Protocolist.actor = actor
|
64
58
|
Protocolist.activity_class = Activity
|
65
59
|
end
|
66
60
|
|
67
61
|
describe 'direct fire method call' do
|
68
|
-
|
69
|
-
@firestarter = Firestarter.new
|
70
|
-
end
|
62
|
+
let(:firestarter) { Firestarter.new }
|
71
63
|
|
72
64
|
it 'saves record with target and data' do
|
73
|
-
expect {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
65
|
+
expect { firestarter.love_letter_for_mary(mary, '<3 <3 <3') }.to change { Activity.count }.by(1)
|
66
|
+
|
67
|
+
activity = Activity.last
|
68
|
+
activity.actor.should == actor
|
69
|
+
activity.activity_type.should == :love_letter
|
70
|
+
activity.target.should == mary
|
71
|
+
activity.data.should == '<3 <3 <3'
|
80
72
|
end
|
81
73
|
|
82
74
|
it 'saves record with self as target if target is not set' do
|
83
|
-
expect {
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
75
|
+
expect { firestarter.myself }.to change { Activity.count }.by(1)
|
76
|
+
|
77
|
+
activity = Activity.last
|
78
|
+
activity.actor.should == actor
|
79
|
+
activity.activity_type.should == :myself
|
80
|
+
activity.target.should == firestarter
|
89
81
|
end
|
90
82
|
|
91
83
|
it 'saves record without target if target set to false' do
|
92
|
-
expect {
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
84
|
+
expect { firestarter.delete }.to change { Activity.count }.by(1)
|
85
|
+
|
86
|
+
activity = Activity.last
|
87
|
+
activity.actor.should == actor
|
88
|
+
activity.activity_type.should == :delete
|
89
|
+
activity.target.should be_false
|
98
90
|
end
|
99
91
|
end
|
100
92
|
|
101
93
|
describe 'fires callback' do
|
102
94
|
it 'saves record when called with minimal options' do
|
103
|
-
expect {
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
95
|
+
expect { SimpleFirestarter.create(name: 'Ted') }.to change { Activity.count }.by(1)
|
96
|
+
|
97
|
+
activity = Activity.last
|
98
|
+
activity.actor.should == actor
|
99
|
+
activity.activity_type.should == :create
|
100
|
+
activity.target.name.should == 'Ted'
|
109
101
|
end
|
110
102
|
|
111
103
|
it 'saves record when called with complex options' do
|
112
104
|
|
113
105
|
#first create record
|
114
106
|
|
115
|
-
expect {
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
107
|
+
expect { ComplexFirestarter.create(name: 'Ted') }.to change { Activity.count }.by(1)
|
108
|
+
|
109
|
+
activity = Activity.last
|
110
|
+
activity.actor.should == actor
|
111
|
+
activity.activity_type.should == :yohoho
|
112
|
+
activity.target.should_not be
|
113
|
+
activity.data.should == 'Hi!'
|
122
114
|
|
123
115
|
#then destroy record
|
124
116
|
|
125
|
-
expect {
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
117
|
+
expect { ComplexFirestarter.last.destroy }.to change { Activity.count }.by(1)
|
118
|
+
|
119
|
+
activity = Activity.last
|
120
|
+
activity.actor.should == actor
|
121
|
+
activity.activity_type.should == :yohoho
|
122
|
+
activity.target.should_not be
|
123
|
+
activity.data.should == 'Hi!'
|
132
124
|
end
|
133
125
|
|
134
|
-
it 'saves
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
Activity.last
|
126
|
+
it 'saves record with string data attribute parsed' do
|
127
|
+
ComplexFirestarter.create(name: 'Ted')
|
128
|
+
ComplexFirestarter.last.update_attributes name: 'Bob'
|
129
|
+
|
130
|
+
activity = Activity.last
|
131
|
+
activity.data.should == 'BobBob'
|
139
132
|
end
|
140
|
-
end
|
141
133
|
|
134
|
+
it 'saves checks conditions' do
|
135
|
+
expect { ConditionalFirestarter.create(name: 'Ted') }.to change { Activity.count }.by(1)
|
142
136
|
|
137
|
+
activity = Activity.last
|
138
|
+
activity.actor.should == actor
|
139
|
+
activity.activity_type.should == :i_will_be_saved
|
140
|
+
end
|
141
|
+
end
|
143
142
|
end
|
data/spec/protocolist_spec.rb
CHANGED
@@ -9,46 +9,51 @@ class Activity < SuperModel::Base
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe Protocolist do
|
12
|
-
|
12
|
+
let(:actor) { User.new(name: 'Bill') }
|
13
|
+
let(:another_actor) { User.new(name: 'Bob') }
|
14
|
+
let(:target) { User.new(name: 'Mary') }
|
15
|
+
|
16
|
+
before do
|
13
17
|
Activity.destroy_all
|
14
|
-
|
15
|
-
Protocolist.actor =
|
18
|
+
|
19
|
+
Protocolist.actor = actor
|
16
20
|
Protocolist.activity_class = Activity
|
17
21
|
end
|
18
22
|
|
19
23
|
it 'should silently skip saving if actor is falsy' do
|
20
24
|
Protocolist.actor = nil
|
21
|
-
|
22
|
-
expect {Protocolist.fire
|
25
|
+
|
26
|
+
expect { Protocolist.fire(:alarm) }.not_to change { Activity.count }
|
27
|
+
expect { Protocolist.fire(:alarm) }.not_to raise_error
|
23
28
|
end
|
24
29
|
|
25
30
|
it 'should silently skip saving if activity_class is falsy' do
|
26
31
|
Protocolist.activity_class = nil
|
27
|
-
|
28
|
-
expect {Protocolist.fire
|
32
|
+
|
33
|
+
expect { Protocolist.fire(:alarm) }.not_to change { Activity.count }
|
34
|
+
expect { Protocolist.fire(:alarm) }.not_to raise_error
|
29
35
|
end
|
30
36
|
|
31
37
|
it 'should save a simple record' do
|
32
|
-
expect {Protocolist.fire
|
38
|
+
expect { Protocolist.fire(:alarm) }.to change { Activity.count }.by(1)
|
33
39
|
|
34
|
-
Activity.last
|
35
|
-
|
40
|
+
activity = Activity.last
|
41
|
+
activity.actor.should == actor
|
42
|
+
activity.activity_type.should == :alarm
|
36
43
|
end
|
37
44
|
|
38
45
|
it 'should save a complex record' do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
Activity.last.target.name.should == 'Mary'
|
52
|
-
Activity.last.data[:some_attr].should == :some_data
|
46
|
+
expect do
|
47
|
+
Protocolist.fire(:alarm,
|
48
|
+
actor: another_actor,
|
49
|
+
target: target,
|
50
|
+
data: { foo: :bar })
|
51
|
+
end.to change { Activity.count }.by(1)
|
52
|
+
|
53
|
+
activity = Activity.last
|
54
|
+
activity.actor.should == another_actor
|
55
|
+
activity.activity_type.should == :alarm
|
56
|
+
activity.target.should == target
|
57
|
+
activity.data[:foo].should == :bar
|
53
58
|
end
|
54
59
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,8 +2,11 @@ require 'protocolist'
|
|
2
2
|
require 'supermodel'
|
3
3
|
Bundler.require(:default)
|
4
4
|
|
5
|
+
User = Class.new(SuperModel::Base)
|
6
|
+
Activity = Class.new(SuperModel::Base)
|
7
|
+
|
5
8
|
RSpec.configure do |config|
|
6
9
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
7
|
-
config.filter_run
|
10
|
+
config.filter_run(focus: true)
|
8
11
|
config.run_all_when_everything_filtered = true
|
9
12
|
end
|
metadata
CHANGED
@@ -1,19 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protocolist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Dmitry Yakimov
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
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'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: rake
|
16
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
17
33
|
none: false
|
18
34
|
requirements:
|
19
35
|
- - ! '>='
|
@@ -21,43 +37,79 @@ dependencies:
|
|
21
37
|
version: '0'
|
22
38
|
type: :development
|
23
39
|
prerelease: false
|
24
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
25
46
|
- !ruby/object:Gem::Dependency
|
26
47
|
name: rspec
|
27
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
51
|
- - ~>
|
31
52
|
- !ruby/object:Gem::Version
|
32
|
-
version: 2.
|
53
|
+
version: 2.12.0
|
33
54
|
type: :development
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.12.0
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
63
|
name: guard-rspec
|
38
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ~>
|
42
68
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
69
|
+
version: 2.3.0
|
44
70
|
type: :development
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.3.0
|
47
78
|
- !ruby/object:Gem::Dependency
|
48
79
|
name: supermodel
|
49
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
50
81
|
none: false
|
51
82
|
requirements:
|
52
|
-
- -
|
83
|
+
- - ~>
|
53
84
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
85
|
+
version: 0.1.6
|
55
86
|
type: :development
|
56
87
|
prerelease: false
|
57
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.1.6
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: psych
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.3.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: 1.3.0
|
58
110
|
- !ruby/object:Gem::Dependency
|
59
111
|
name: railties
|
60
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
61
113
|
none: false
|
62
114
|
requirements:
|
63
115
|
- - ~>
|
@@ -65,7 +117,12 @@ dependencies:
|
|
65
117
|
version: '3.0'
|
66
118
|
type: :development
|
67
119
|
prerelease: false
|
68
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '3.0'
|
69
126
|
description: ! 'Simple activity feeds solution for Rails applications. Gives a flexible
|
70
127
|
way to build activity feeds infrastructure over it. '
|
71
128
|
email:
|
@@ -87,8 +144,10 @@ files:
|
|
87
144
|
- lib/generators/protocolist/install/templates/migration.rb
|
88
145
|
- lib/protocolist.rb
|
89
146
|
- lib/protocolist/controller_additions.rb
|
147
|
+
- lib/protocolist/controller_additions/initializer.rb
|
90
148
|
- lib/protocolist/model_additions.rb
|
91
149
|
- lib/protocolist/railtie.rb
|
150
|
+
- lib/protocolist/util/data_proc.rb
|
92
151
|
- lib/protocolist/version.rb
|
93
152
|
- protocolist.gemspec
|
94
153
|
- spec/protocolist/controller_additions_spec.rb
|
@@ -107,16 +166,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
166
|
- - ! '>='
|
108
167
|
- !ruby/object:Gem::Version
|
109
168
|
version: '0'
|
169
|
+
segments:
|
170
|
+
- 0
|
171
|
+
hash: 1046353843920226917
|
110
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
173
|
none: false
|
112
174
|
requirements:
|
113
|
-
- - ! '
|
175
|
+
- - ! '>='
|
114
176
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
177
|
+
version: '0'
|
178
|
+
segments:
|
179
|
+
- 0
|
180
|
+
hash: 1046353843920226917
|
116
181
|
requirements: []
|
117
182
|
rubyforge_project: protocolist
|
118
|
-
rubygems_version: 1.8.
|
183
|
+
rubygems_version: 1.8.24
|
119
184
|
signing_key:
|
120
185
|
specification_version: 3
|
121
186
|
summary: Activity feeds solution for Rails.
|
122
|
-
test_files:
|
187
|
+
test_files:
|
188
|
+
- spec/protocolist/controller_additions_spec.rb
|
189
|
+
- spec/protocolist/model_additions_spec.rb
|
190
|
+
- spec/protocolist_spec.rb
|
191
|
+
- spec/spec_helper.rb
|