safai 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/generators/safai/safai_generator.rb +9 -0
- data/generators/safai/templates/migration.rb +10 -0
- data/generators/safai/templates/model.rb +38 -0
- data/lib/safai/fires.rb +39 -0
- data/lib/safai/macros.rb +20 -0
- data/lib/safai/matchers.rb +58 -0
- data/lib/safai.rb +2 -0
- metadata +7 -1
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreateTimelineEvents < ActiveRecord::Migration
|
2
|
+
def self.change
|
3
|
+
create_table :timeline_events do |t|
|
4
|
+
t.string :event_type, :subject_type, :actor_type, :secondary_subject_type, :link
|
5
|
+
t.integer :subject_id, :actor_id, :secondary_subject_id
|
6
|
+
t.text :message
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class TimelineEvent < ActiveRecord::Base
|
2
|
+
|
3
|
+
#GEMS USED
|
4
|
+
#ACCESSORS
|
5
|
+
attr_accessible :event_type, :actor, :subject, :secondary_subject, :link, :message
|
6
|
+
|
7
|
+
#ASSOCIATIONS
|
8
|
+
belongs_to :actor, :polymorphic => true
|
9
|
+
belongs_to :subject, :polymorphic => true
|
10
|
+
belongs_to :secondary_subject, :polymorphic => true
|
11
|
+
|
12
|
+
#CALLBACKS
|
13
|
+
#VALIDATIONS
|
14
|
+
#QUERY SCOPES
|
15
|
+
#CUSTOM SCOPES
|
16
|
+
#SORTING SCOPES
|
17
|
+
default_scope :order => "created_at desc"
|
18
|
+
|
19
|
+
#OTHER STUFF
|
20
|
+
|
21
|
+
def tag
|
22
|
+
if alertable_type == "Campaign"
|
23
|
+
return "<span class='tag1'>Campaign</span>".html_safe
|
24
|
+
elsif alertable_type == "Impact" or alertable_type == "Project"
|
25
|
+
return "<span class='tag2'>Project</span>".html_safe
|
26
|
+
elsif alertable_type == "Bank"
|
27
|
+
return "<span class='tag3'>Bank Account</span>".html_safe
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#PRIVATE STUFF
|
32
|
+
private
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
data/lib/safai/fires.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Safai
|
2
|
+
module Fires
|
3
|
+
def self.included(klass)
|
4
|
+
klass.send(:extend, ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def fires(event_type, opts)
|
9
|
+
raise ArgumentError, "Argument :on is mandatory" unless opts.has_key?(:on)
|
10
|
+
|
11
|
+
# Array provided, set multiple callbacks
|
12
|
+
if opts[:on].kind_of?(Array)
|
13
|
+
opts[:on].each { |on| fires(event_type, opts.merge({:on => on})) }
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
opts[:subject] = :self unless opts.has_key?(:subject)
|
18
|
+
|
19
|
+
send(:"after_#{opts[:on]}", :if => opts[:if]) do
|
20
|
+
create_options = [:actor, :subject, :secondary_subject].inject({}) do |memo, sym|
|
21
|
+
if opts[sym]
|
22
|
+
if opts[sym].respond_to?(:call)
|
23
|
+
memo[sym] = opts[sym].call(self)
|
24
|
+
elsif opts[sym] == :self
|
25
|
+
memo[sym] = self
|
26
|
+
else
|
27
|
+
memo[sym] = send(opts[sym])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
memo
|
31
|
+
end
|
32
|
+
create_options[:event_type] = event_type.to_s
|
33
|
+
|
34
|
+
TimelineEvent.create!(create_options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/safai/macros.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Safai
|
2
|
+
module Macros
|
3
|
+
def should_fire_event(event_type, opts = {})
|
4
|
+
should "fire #{event_type} on #{opts[:on]}" do
|
5
|
+
matcher = fire_event(event_type, opts)
|
6
|
+
|
7
|
+
assert_accepts matcher, self.class.name.gsub(/Test$/, '').constantize
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_not_fire_event(event_type, opts = {})
|
12
|
+
should "fire #{event_type} on #{opts[:on]}" do
|
13
|
+
matcher = fire_event(event_type, opts)
|
14
|
+
|
15
|
+
assert_rejects matcher, self.class.name.gsub(/Test$/, '').constantize
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Safai
|
2
|
+
module Matchers
|
3
|
+
class FireEvent
|
4
|
+
def initialize(event_type, opts = {})
|
5
|
+
@event_type = event_type
|
6
|
+
@opts = opts
|
7
|
+
@method = :"fire_#{@event_type}_after_#{@opts[:on]}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches?(subject)
|
11
|
+
@subject = subject
|
12
|
+
|
13
|
+
defines_callback_method? && setups_up_callback?
|
14
|
+
end
|
15
|
+
|
16
|
+
def defines_callback_method?
|
17
|
+
if @subject.instance_methods.include?(@method.to_s)
|
18
|
+
true
|
19
|
+
else
|
20
|
+
@missing = "#{@subject.name} does not respond to #{@method}"
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def setups_up_callback?
|
26
|
+
callback_chain_name = "after_#{@opts[:on]}_callback_chain"
|
27
|
+
callback_chain = @subject.send(callback_chain_name)
|
28
|
+
if callback_chain.any? {|chain| chain.method == @method }
|
29
|
+
true
|
30
|
+
else
|
31
|
+
@missing = "does setup after #{@opts[:on]} callback for #{@method}"
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def description
|
37
|
+
"fire a #{@event_type} event"
|
38
|
+
end
|
39
|
+
|
40
|
+
def expectation
|
41
|
+
expected = "#{@subject.name} to #{description}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def failure_message
|
45
|
+
"Expected #{expectation} (#{@missing})"
|
46
|
+
end
|
47
|
+
|
48
|
+
def negative_failure_message
|
49
|
+
"Did not expect #{expectation}"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def fire_event(event_type, opts)
|
55
|
+
FireEvent.new(event_type, opts)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/safai.rb
CHANGED
@@ -123,5 +123,7 @@ require 'safai/clean'
|
|
123
123
|
require 'safai/gravatar'
|
124
124
|
require 'safai/money'
|
125
125
|
require 'safai/date'
|
126
|
+
require 'timeline_fu/fires'
|
127
|
+
ActiveRecord::Base.send :include, Safai::Fires
|
126
128
|
ActionView::Base.send :include, Safai::Helpers
|
127
129
|
ActionView::Base.send :include, Safai::DeviseHelpers
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -57,6 +57,12 @@ files:
|
|
57
57
|
- lib/safai/gravatar.rb
|
58
58
|
- lib/safai/money.rb
|
59
59
|
- lib/safai/date.rb
|
60
|
+
- generators/safai/templates/migration.rb
|
61
|
+
- generators/safai/templates/model.rb
|
62
|
+
- generators/safai/safai_generator.rb
|
63
|
+
- lib/safai/fires.rb
|
64
|
+
- lib/safai/macros.rb
|
65
|
+
- lib/safai/matchers.rb
|
60
66
|
homepage: http://rubygems.org/gems/safai
|
61
67
|
licenses: []
|
62
68
|
post_install_message:
|