riaction 1.1.0 → 1.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG #
2
2
 
3
+ ## 1.2.0 ##
4
+
5
+ * Added rspec matchers
6
+ * rake task to list all defined events also shows default params
7
+
3
8
  ## 1.1.0 ##
4
9
 
5
10
  * Entire re-spec and re-factor of gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- riaction (1.0.0)
4
+ riaction (1.2.0)
5
5
  activerecord (>= 3.0.0)
6
6
  activesupport (>= 3.0.0)
7
7
  rake
data/README.md CHANGED
@@ -107,7 +107,14 @@ Models in your application may declare any number of events that they wish to lo
107
107
  # stars :integer(4)
108
108
  # text :string(255)
109
109
 
110
- In the above example, `:write_a_review` is the name of the event and should match the key used on IActionable. The value for `:trigger` determines the action that will cause the event to fire, and can also be `:update` or `:destroy`, and will automatically fire when a record is created, updated, or destroyed, respectively. The value given to `:profile` should return the riaction profile object that this event will be logged under.
110
+ In the above example:
111
+
112
+ * `:write_a_review` is the name of the event and should match the key used on IActionable.
113
+ * The value for `:trigger` determines the action that will cause the event to fire, and can also be `:update` or `:destroy`, and will automatically fire when a record is created, updated, or destroyed, respectively.
114
+ * **If the value for `:trigger` is not given, `:create` will be assumed.**
115
+ * The value given to `:profile` should return the riaction profile object that this event will be logged under.
116
+
117
+ <!-- end list -->
111
118
 
112
119
  #### Event Parameters ####
113
120
 
@@ -123,7 +130,7 @@ Part of the power in the way IActionable may be configured to process your event
123
130
 
124
131
  riaction :event, :name => :write_a_review, :trigger => :create, :profile => :user, :params => Proc.new{|record| {:length => record.text.length}}
125
132
 
126
- ...or the name of an instance method (which ought to return a hash)
133
+ ...or the name of an instance method (which ought to return a hash):
127
134
 
128
135
  riaction :event, :name => :write_a_review, :trigger => :create, :profile => :user, :params => :stats
129
136
 
@@ -155,12 +162,20 @@ If the object given as the riaction profile for an event defines more than one p
155
162
 
156
163
  #### Profiles With Their Own Events ####
157
164
 
158
- A class the declares itself as a profile may also declare events which rely on that same class as the profile object:
165
+ A class that declares itself as a profile may also declare events, and for those events it may point to itself as the profile to use:
159
166
 
160
167
  riaction :profile, :type => :player, :custom => :id
161
168
  riaction :event, :name => :join_the_game, :trigger => :create, :profile => :self
162
169
 
163
- In the above example of a declaration on the User class, the user will fire a `:join_the_game` event using itself as the profile upon its creation. The profile declaration should come before the event declaration.
170
+ In the above example of a declaration on the User class, the user will fire a `:join_the_game` event using itself as the profile upon its creation. _The profile declaration must come before the event declaration._
171
+
172
+ #### Turning Riaction Off ####
173
+
174
+ If you want to avoid the automatic creation of a profile, or the automatic logging of an event, classes that declare themselves as riaction profiles or event drivers provide a method to disable those automatic events:
175
+
176
+ User.riactionless{ User.create(:nickname => 'zortnac') } # won't create the profile for the newly created user
177
+ Review.riactionless{ @user_instance.reviews.create(:text => "loved it!") } # won't fire the 'write_a_review' event
178
+ Review.riactionless{ @review_instance.trigger_thumbs_up! } # won't fire the 'receive_thumbs_up' event
164
179
 
165
180
  ### Rails Rake Tasks ###
166
181
 
data/db/riaction.db CHANGED
Binary file
data/lib/riaction.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'ruby-iactionable'
2
2
  require "riaction/version"
3
3
  require "riaction/riaction"
4
- require "riaction/railtie" if defined?(Rails)
4
+ require "riaction/railtie" if defined?(Rails)
5
+ require "rspec/matchers/riaction" if defined?(RSpec)
@@ -1,3 +1,3 @@
1
1
  module Riaction
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -0,0 +1,113 @@
1
+ RSpec::Matchers.define :define_riaction_profile do |expected_type|
2
+ chain :identified_by do |identifiers|
3
+ @identifiers = identifiers
4
+ end
5
+
6
+ match do |actual|
7
+ if actual.riactionary? && actual.riaction_profile? && actual.riaction_profile_keys.has_key?(expected_type)
8
+ if @identifiers.present?
9
+ if @identifiers.select{|id_type, id| actual.riaction_profile_keys[expected_type][:identifiers].has_key?(id_type) &&
10
+ actual.riaction_profile_keys[expected_type][:identifiers][id_type] == id}.size == @identifiers.size
11
+ true
12
+ else
13
+ false
14
+ end
15
+ else
16
+ true
17
+ end
18
+ else
19
+ false
20
+ end
21
+ end
22
+
23
+ failure_message_for_should do |actual|
24
+ if @identifiers.present?
25
+ "expected that #{actual} would define a riaction profile of type #{expected_type} with identifiers #{@identifiers.keys.join(", ")}"
26
+ else
27
+ "expected that #{actual} would define a riaction profile of type #{expected_type}"
28
+ end
29
+ end
30
+ end
31
+
32
+ RSpec::Matchers.define :identify_with_riaction_as do |expected_type, expected_ids|
33
+ match do |actual|
34
+ if actual.class.riactionary? &&
35
+ actual.class.riaction_profile? &&
36
+ actual.riaction_profile_keys.has_key?(expected_type) &&
37
+ expected_ids.select{|id_type, id| actual.riaction_profile_keys[expected_type].fetch(id_type, nil) == id}.size == expected_ids.size
38
+ true
39
+ else
40
+ false
41
+ end
42
+ end
43
+
44
+ failure_message_for_should do |actual|
45
+ "expected that instance of #{actual.class} would use the value(s) #{expected_ids} to identify to IActionable"
46
+ end
47
+ end
48
+
49
+ RSpec::Matchers.define :define_riaction_event do |expected_event|
50
+ chain :triggered_on do |expected_trigger|
51
+ @expected_trigger = expected_trigger
52
+ end
53
+
54
+ match do |actual|
55
+ if actual.riactionary? && actual.riaction_events? && actual.riaction_events.has_key?(expected_event)
56
+ if @expected_trigger.present?
57
+ if actual.riaction_events[expected_event][:trigger] == @expected_trigger
58
+ true
59
+ else
60
+ false
61
+ end
62
+ else
63
+ true
64
+ end
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ failure_message_for_should do |actual|
71
+ if @expected_trigger.present?
72
+ "expected that #{actual} would define a riaction event named #{expected_event} triggered on #{@expected_trigger}"
73
+ else
74
+ "expected that #{actual} would define a riaction event named #{expected_event}"
75
+ end
76
+ end
77
+ end
78
+
79
+ RSpec::Matchers.define :log_riaction_event_with_profile do |expected_event, expected_profile_type, expected_profile_id_type, expected_profile_id|
80
+ match do |actual|
81
+ if actual.class.riactionary? &&
82
+ actual.class.riaction_events? &&
83
+ actual.riaction_event_params.has_key?(expected_event) &&
84
+ actual.riaction_event_params[expected_event][:profile][:type] == expected_profile_type &&
85
+ actual.riaction_event_params[expected_event][:profile][:id_type] == expected_profile_id_type &&
86
+ actual.riaction_event_params[expected_event][:profile][:id] == expected_profile_id
87
+ true
88
+ else
89
+ false
90
+ end
91
+ end
92
+
93
+ failure_message_for_should do |actual|
94
+ "expected that instance of #{actual.class} would log event #{expected_event} with the profile keys: #{expected_profile_type}, #{expected_profile_id_type}, #{expected_profile_id}"
95
+ end
96
+ end
97
+
98
+ RSpec::Matchers.define :log_riaction_event_with_params do |expected_event, expected_params|
99
+ match do |actual|
100
+ if actual.class.riactionary? &&
101
+ actual.class.riaction_events? &&
102
+ actual.riaction_event_params.has_key?(expected_event) &&
103
+ actual.riaction_event_params[expected_event][:params] == expected_params
104
+ true
105
+ else
106
+ false
107
+ end
108
+ end
109
+
110
+ failure_message_for_should do |actual|
111
+ "expected that instance of #{actual.class} would log event #{expected_event} with params #{expected_params}"
112
+ end
113
+ end
@@ -10,6 +10,7 @@ namespace 'riaction' do
10
10
  Riaction::Riaction::EVENT_CLASSES.each do |class_name|
11
11
  klass = class_name.constantize
12
12
  puts "#{klass} defines the following events:"
13
+ opts = klass.riaction_options
13
14
  klass.riaction_events.each_pair do |name, deets|
14
15
  puts " :#{name}:"
15
16
  if Riaction::Constants.crud_actions.include? deets[:trigger]
@@ -47,6 +48,17 @@ namespace 'riaction' do
47
48
  puts " Event Params: #{deets[:params]}"
48
49
  end
49
50
 
51
+ if opts[:default_event_params].present?
52
+ case opts[:default_event_params]
53
+ when Symbol
54
+ puts " Params included by default: Hash returned by :#{opts[:default_event_params]}"
55
+ when Proc
56
+ puts " Params included by default: Hash returned via Proc"
57
+ when Hash
58
+ puts " Params included by default: #{opts[:default_event_params]}"
59
+ end
60
+ end
61
+
50
62
  case deets[:guard]
51
63
  when NilClass
52
64
  puts " Guard: None"
@@ -0,0 +1,134 @@
1
+ require 'spec_helper.rb'
2
+
3
+ ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'users'")
4
+ ActiveRecord::Base.connection.create_table(:users) do |t|
5
+ t.string :name
6
+ t.string :email
7
+ t.timestamps
8
+ end
9
+
10
+ class User < ActiveRecord::Base
11
+ extend Riaction::Riaction::ClassMethods
12
+
13
+ has_many :comments, :dependent => :destroy
14
+ end
15
+
16
+ ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'comments'")
17
+ ActiveRecord::Base.connection.create_table(:comments) do |t|
18
+ t.belongs_to :user
19
+ t.string :content
20
+ end
21
+
22
+ class Comment < ActiveRecord::Base
23
+ extend Riaction::Riaction::ClassMethods
24
+
25
+ belongs_to :user
26
+ end
27
+
28
+
29
+ describe "Custom matchers for riaction" do
30
+ before do
31
+ User.reset_riaction if User.riactionary?
32
+ Comment.reset_riaction if Comment.riactionary?
33
+
34
+ # multiple test runs are building up the callbacks
35
+ Comment.class_eval do
36
+ reset_callbacks :create
37
+ reset_callbacks :update
38
+ reset_callbacks :destroy
39
+ end
40
+ end
41
+
42
+ describe "profile objects" do
43
+ before do
44
+ User.class_eval do
45
+ riaction :profile, :type => :player, :custom => :id
46
+ end
47
+ end
48
+
49
+ describe "at the class level" do
50
+ it "should raise an ExpectationNotMetError when asserting that the class defines a profile type that isn't actually defined" do
51
+ lambda {User.should define_riaction_profile(:bogus)}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
52
+ end
53
+
54
+ it "should not raise an ExpectationNotMetError when asserting that the class defines a profile type that is actually defined" do
55
+ lambda {User.should define_riaction_profile(:player)}.should_not raise_error(RSpec::Expectations::ExpectationNotMetError)
56
+ end
57
+
58
+ it "should raise an ExpectationNotMetError when asserting that the class uses an identifier that it doesn't define" do
59
+ lambda {User.should define_riaction_profile(:player).identified_by(:bogus => :bogus)}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
60
+ end
61
+
62
+ it "should not raise an ExpectationNotMetError when asserting that the class uses an identifier that is correctlty defined" do
63
+ lambda {User.should define_riaction_profile(:player).identified_by(:custom => :id)}.should_not raise_error(RSpec::Expectations::ExpectationNotMetError)
64
+ end
65
+ end
66
+
67
+ describe "at the instance level" do
68
+ before do
69
+ @user = User.riactionless{ User.create(:name => 'zortnac') }
70
+ end
71
+
72
+ it "should raise an ExpectationNotMetError when asserting that the instance should deliver the correct identifiers and it does not" do
73
+ lambda {@user.should identify_with_riaction_as(:player, :custom => 'bogus')}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
74
+ end
75
+
76
+ it "should not raise an ExpectationNotMetError when asserting that the instance should deliver the correct identifiers and it does" do
77
+ lambda {@user.should identify_with_riaction_as(:player, :custom => @user.id)}.should_not raise_error(RSpec::Expectations::ExpectationNotMetError)
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "event objects" do
83
+ before do
84
+ User.class_eval do
85
+ riaction :profile, :type => :player, :custom => :id
86
+ end
87
+
88
+ Comment.class_eval do
89
+ riaction :event, :name => :make_a_comment, :trigger => :create, :profile => :user, :params => {:comment => :content}
90
+ end
91
+ end
92
+
93
+ describe "at the class level" do
94
+ it "should raise an ExpectationNotMetError when incorrectly asserting that the class defines an event" do
95
+ lambda {Comment.should define_riaction_event(:bogus)}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
96
+ end
97
+
98
+ it "should not raise an ExpectationNotMetError when correctly asserting that the class defines an event" do
99
+ lambda {Comment.should define_riaction_event(:make_a_comment)}.should_not raise_error(RSpec::Expectations::ExpectationNotMetError)
100
+ end
101
+
102
+ it "should raise an ExpectationNotMetError when incorrectly asserting that the class defines the event on a specific action" do
103
+ lambda {Comment.should define_riaction_event(:make_a_comment).triggered_on(:bogus)}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
104
+ end
105
+
106
+ it "should not raise an ExpectationNotMetError when correctly asserting that the class defines the event on a specific action" do
107
+ lambda {Comment.should define_riaction_event(:make_a_comment).triggered_on(:create)}.should_not raise_error(RSpec::Expectations::ExpectationNotMetError)
108
+ end
109
+ end
110
+
111
+ describe "at the instance level" do
112
+ before do
113
+ @user = User.riactionless{ User.create(:name => 'zortnac') }
114
+ @comment = Comment.riactionless{ Comment.create(:user => @user, :content => "this is a comment") }
115
+ end
116
+
117
+ it "should raise an ExpectationNotMetError when incorrectly asserting that the instance uses the desired riaction profile" do
118
+ lambda {@comment.should log_riaction_event_with_profile(:make_a_comment, :player, :custom, -1)}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
119
+ end
120
+
121
+ it "should raise an ExpectationNotMetError when correctly asserting that the instance uses the desired riaction profile" do
122
+ lambda {@comment.should log_riaction_event_with_profile(:make_a_comment, :player, :custom, @user.id)}.should_not raise_error(RSpec::Expectations::ExpectationNotMetError)
123
+ end
124
+
125
+ it "should raise an ExpectationNotMetError when incorrectly asserting that the instance uses the desired params" do
126
+ lambda {@comment.should log_riaction_event_with_params(:make_a_comment, {:comment => "bogus"})}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
127
+ end
128
+
129
+ it "should raise an ExpectationNotMetError when correctly asserting that the instance uses the desired params" do
130
+ lambda {@comment.should log_riaction_event_with_params(:make_a_comment, {:comment => @comment.content})}.should_not raise_error(RSpec::Expectations::ExpectationNotMetError)
131
+ end
132
+ end
133
+ end
134
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riaction
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-10 00:00:00.000000000Z
12
+ date: 2012-02-21 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2161139200 !ruby/object:Gem::Requirement
16
+ requirement: &2160644000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '2.6'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2161139200
24
+ version_requirements: *2160644000
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sqlite3
27
- requirement: &2161138580 !ruby/object:Gem::Requirement
27
+ requirement: &2160643540 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2161138580
35
+ version_requirements: *2160643540
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: ruby-debug19
38
- requirement: &2161138020 !ruby/object:Gem::Requirement
38
+ requirement: &2160637060 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2161138020
46
+ version_requirements: *2160637060
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &2161137440 !ruby/object:Gem::Requirement
49
+ requirement: &2160636500 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2161137440
57
+ version_requirements: *2160636500
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: activerecord
60
- requirement: &2161136640 !ruby/object:Gem::Requirement
60
+ requirement: &2160635460 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 3.0.0
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *2161136640
68
+ version_requirements: *2160635460
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activesupport
71
- requirement: &2161136140 !ruby/object:Gem::Requirement
71
+ requirement: &2160634940 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 3.0.0
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *2161136140
79
+ version_requirements: *2160634940
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: resque
82
- requirement: &2161135740 !ruby/object:Gem::Requirement
82
+ requirement: &2160634560 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *2161135740
90
+ version_requirements: *2160634560
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: ruby-iactionable
93
- requirement: &2161134860 !ruby/object:Gem::Requirement
93
+ requirement: &2160633900 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: 0.0.2
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *2161134860
101
+ version_requirements: *2160633900
102
102
  description: Wrapper for IActionable's restful API and an "acts-as" style interface
103
103
  for models to behave as profiles and drive game events.
104
104
  email:
@@ -126,8 +126,10 @@ files:
126
126
  - lib/riaction/railtie.rb
127
127
  - lib/riaction/riaction.rb
128
128
  - lib/riaction/version.rb
129
+ - lib/rspec/matchers/riaction.rb
129
130
  - lib/tasks/riaction.rake
130
131
  - riaction.gemspec
132
+ - spec/custom_matchers_spec.rb
131
133
  - spec/event_performer_spec.rb
132
134
  - spec/profile_creation_spec.rb
133
135
  - spec/riaction_spec.rb
@@ -159,6 +161,7 @@ specification_version: 3
159
161
  summary: Wrapper for IActionable's restful API and an "acts-as" style interface for
160
162
  models to behave as profiles and drive game events.
161
163
  test_files:
164
+ - spec/custom_matchers_spec.rb
162
165
  - spec/event_performer_spec.rb
163
166
  - spec/profile_creation_spec.rb
164
167
  - spec/riaction_spec.rb