acts_as_event_owner 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/.gitignore +7 -0
  2. data/LICENSE +24 -0
  3. data/README.textile +205 -0
  4. data/Rakefile +28 -0
  5. data/acts_as_event_owner.gemspec +76 -0
  6. data/generators/acts_as_event_owner_migration/USAGE +6 -0
  7. data/generators/acts_as_event_owner_migration/acts_as_event_owner_migration_generator.rb +7 -0
  8. data/generators/acts_as_event_owner_migration/templates/acts_as_event_owner_migration.rb +38 -0
  9. data/lib/acts_as_event_owner/core.rb +38 -0
  10. data/lib/acts_as_event_owner/event_occurrence.rb +6 -0
  11. data/lib/acts_as_event_owner/event_specification.rb +152 -0
  12. data/lib/acts_as_event_owner/exception.rb +4 -0
  13. data/lib/acts_as_event_owner/railtie.rb +13 -0
  14. data/lib/acts_as_event_owner/version.rb +3 -0
  15. data/lib/acts_as_event_owner.rb +17 -0
  16. data/lib/generators/acts_as_event_owner/migration/migration_generator.rb +31 -0
  17. data/lib/generators/acts_as_event_owner/migration/templates/active_record/acts_as_event_owner_migration.rb +38 -0
  18. data/lib/generators/acts_as_event_owner_migration/USAGE +6 -0
  19. data/lib/generators/acts_as_event_owner_migration/acts_as_event_owner_migration_generator.rb +7 -0
  20. data/lib/generators/acts_as_event_owner_migration/templates/acts_as_event_owner_migration.rb +38 -0
  21. data/lib/tasks/acts_as_event_owner_tasks.rake +14 -0
  22. data/rails/init.rb +1 -0
  23. data/spec/acts_as_event_owner/core_spec.rb +62 -0
  24. data/spec/acts_as_event_owner/event_specification_spec.rb +365 -0
  25. data/spec/schema.rb +43 -0
  26. data/spec/spec_helper.rb +26 -0
  27. data/spec/support/model_builders.rb +13 -0
  28. data/spec/support/user.rb +3 -0
  29. metadata +106 -0
@@ -0,0 +1,38 @@
1
+ class ActsAsEventOwnerMigration < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :event_specifications do |t|
4
+ t.integer :owner_id
5
+ t.string :owner_type
6
+ t.string :description
7
+ t.datetime :start_at
8
+ t.datetime :end_at
9
+ t.string :repeat # daily, weekly, monthly, yearly
10
+ t.integer :frequency, :default => 1 # every 'n' days, weeks, months, or years
11
+ t.string :on # su, mo, tu, we, th, fr, sa, 1-31, jan-dec
12
+ t.string :on_the # first, second, third, fourth, last
13
+ t.string :target # su, mo, tu, we, th, fr, sa, day, wkday, wkend
14
+ t.datetime :until
15
+ t.timestamps
16
+ end
17
+
18
+ add_index :event_specifications, [:owner_id, :owner_type]
19
+
20
+ create_table :event_occurrences do |t|
21
+ t.integer :owner_id
22
+ t.string :owner_type
23
+ t.integer :event_specification_id
24
+ t.datetime :start_at
25
+ t.datetime :end_at
26
+ t.string :description
27
+ t.timestamps
28
+ end
29
+
30
+ add_index :event_occurrences, [:owner_id, :owner_type]
31
+ add_index :event_occurrences, :event_specification_id
32
+ end
33
+
34
+ def self.down
35
+ drop_table :event_specifications
36
+ drop_table :event_occurrences
37
+ end
38
+ end
@@ -0,0 +1,6 @@
1
+ Usage:
2
+
3
+ script/generate acts_as_event_owner_migration
4
+
5
+ This will create a migration that will add the acts_as_event_owner tables to your database
6
+
@@ -0,0 +1,7 @@
1
+ class ActsAsEventOwnerMigrationGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template 'acts_as_event_owner_migration.rb', File.join('db', 'migrate'), :migration_file_name => "acts_as_event_owner_migration"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,38 @@
1
+ class ActsAsEventOwnerMigration < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :event_specifications do |t|
4
+ t.integer :owner_id
5
+ t.string :owner_type
6
+ t.string :description
7
+ t.datetime :start_at
8
+ t.datetime :end_at
9
+ t.string :repeat # daily, weekly, monthly, yearly
10
+ t.integer :frequency, :default => 1 # every 'n' days, weeks, months, or years
11
+ t.string :on # su, mo, tu, we, th, fr, sa, 1-31, jan-dec
12
+ t.string :on_the # first, second, third, fourth, last
13
+ t.string :target # su, mo, tu, we, th, fr, sa, day, wkday, wkend
14
+ t.datetime :until
15
+ t.timestamps
16
+ end
17
+
18
+ add_index :event_specifications, [:owner_id, :owner_type]
19
+
20
+ create_table :event_occurrences do |t|
21
+ t.integer :owner_id
22
+ t.string :owner_type
23
+ t.integer :event_specification_id
24
+ t.datetime :start_at
25
+ t.datetime :end_at
26
+ t.string :description
27
+ t.timestamps
28
+ end
29
+
30
+ add_index :event_occurrences, [:owner_id, :owner_type]
31
+ add_index :event_occurrences, :event_specification_id
32
+ end
33
+
34
+ def self.down
35
+ drop_table :event_specifications
36
+ drop_table :event_occurrences
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ namespace :acts_as_event_owner do
2
+ task :require_from do
3
+ raise "Set FROM to something understandable by Time.parse" if !ENV['FROM']
4
+ end
5
+
6
+ task :require_to do
7
+ raise "Set TO to something understandable by Time.parse" if !ENV['TO']
8
+ end
9
+
10
+ desc "Generate all events within a certain time window"
11
+ task :generate_events => [:environment, :require_from, :require_to] do
12
+ ActsAsEventOwner::EventSpecification.all(:conditions => "until IS NULL OR until >= '#{Time.now.utc.to_s(:db)}'").each {|spec| spec.generate_events(options)}
13
+ end
14
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'acts_as_event_owner'
@@ -0,0 +1,62 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe ActsAsEventOwner::Core do
4
+ before(:each) do
5
+ clean_database!
6
+ @user = User.create :name => 'dude'
7
+ @now = Time.now.utc
8
+ @bod = Date.today.to_time.utc
9
+ end
10
+
11
+ it "adds associations to the host object" do
12
+ lambda {
13
+ @user.events
14
+ @user.event_specifications
15
+ }.should_not raise_error
16
+ end
17
+
18
+ it "adds event specifications to the host object" do
19
+ lambda {
20
+ @user.event_specifications.create :description => 'walk the dog', :start_at => @now, :repeat => :daily, :frequency => 1
21
+ }.should change(EventSpecification, :count).by(1)
22
+
23
+ specs = @user.reload.event_specifications
24
+ specs.size.should == 1
25
+ end
26
+
27
+ it "adds events to the host object" do
28
+ @user.event_specifications.create :description => 'walk the dog', :start_at => @now, :repeat => :daily, :frequency => 1, :generate => false
29
+ @user.event_specifications.create :description => 'go to the gym', :start_at => @now, :repeat => :daily, :frequency => 2, :generate => false
30
+
31
+ lambda {
32
+ @user.events.generate :from => @bod, :to => @bod + 1.week
33
+ }.should change(EventOccurrence, :count).by(11)
34
+ end
35
+
36
+ it "injects events into the association immediately" do
37
+ @user.event_specifications.create :description => 'walk the dog', :start_at => @now, :repeat => :daily, :frequency => 1, :generate => false
38
+ @user.events.should be_empty
39
+ @user.events.generate :from => @bod, :to => @bod + 1.week
40
+ @user.events.should be_present
41
+ @user.events.size.should == 7
42
+ end
43
+
44
+ describe "events association" do
45
+ before(:each) do
46
+ @new_event = EventOccurrence.new
47
+ @new_event.should be_valid
48
+ end
49
+
50
+ it "raises an exception if #<< is called" do
51
+ lambda { @user.events << @new_event }.should raise_error(ActsAsEventOwner::Exception)
52
+ end
53
+
54
+ it "raises an exception is #build is called" do
55
+ lambda { @user.events.build @new_event.attributes }.should raise_error(ActsAsEventOwner::Exception)
56
+ end
57
+
58
+ it "raises an exception if #create is called" do
59
+ lambda { @user.events.create @new_event.attributes }.should raise_error(ActsAsEventOwner::Exception)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,365 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe ActsAsEventOwner::EventSpecification do
4
+ before(:each) do
5
+ clean_database!
6
+ end
7
+
8
+ describe "defaults" do
9
+ it "defaults start_at to now" do
10
+ now = Time.now
11
+ Time.stub!(:now).and_return(now)
12
+ spec = new_event_specification
13
+ spec.should be_valid
14
+ spec.start_at.should == now
15
+ end
16
+
17
+ it "defaults duration to one hour" do
18
+ spec = new_event_specification
19
+ spec.should be_valid
20
+ spec.end_at.should == spec.start_at + 1.hour
21
+ end
22
+
23
+ it "defaults repeat until forever" do
24
+ spec = new_event_specification(:repeat => :daily)
25
+ spec.should be_valid
26
+ spec.until.should be_nil
27
+ end
28
+ end
29
+
30
+ describe "validations" do
31
+ it "requires a valid repeat interval" do
32
+ spec = new_event_specification(:repeat => :bogus)
33
+ spec.should_not be_valid
34
+ spec.errors[:repeat].should be_present
35
+ end
36
+
37
+ it "requires a description" do
38
+ spec = new_event_specification(:description => nil)
39
+ spec.should_not be_valid
40
+ spec.errors[:description].should be_present
41
+ end
42
+ end
43
+
44
+ describe "non-recurring events" do
45
+ it "passes validations" do
46
+ new_event_specification.should be_valid
47
+ end
48
+
49
+ it "does not generate an RRULE" do
50
+ new_event_specification.to_rrule.should be_nil
51
+ end
52
+ end
53
+
54
+ describe "events recurring daily" do
55
+ it "passes validations" do
56
+ new_event_specification(:repeat => :daily).should be_valid
57
+ new_event_specification(:repeat => :daily, :frequency => 4).should be_valid
58
+ end
59
+
60
+ it "does not support invalid recurrence specifications" do
61
+ spec = new_event_specification(:repeat => :daily, :frequency => 'foo')
62
+ spec.should_not be_valid
63
+ spec.errors[:frequency].should be_present
64
+
65
+ spec = new_event_specification(:repeat => :daily, :on => [1, 2])
66
+ spec.should_not be_valid
67
+ spec.errors[:on].should be_present
68
+
69
+ spec = new_event_specification(:repeat => :daily, :on_the => :first)
70
+ spec.should_not be_valid
71
+ spec.errors[:on_the].should be_present
72
+
73
+ spec = new_event_specification(:repeat => :daily, :on_the => :first, :target => :wkday)
74
+ spec.should_not be_valid
75
+ spec.errors[:target].should be_present
76
+ end
77
+
78
+ it "defaults frequency to 1" do
79
+ new_event_specification(:repeat => :daily).frequency.should == 1
80
+ end
81
+
82
+ it "generates an RRULE" do
83
+ # every day
84
+ new_event_specification(:repeat => :daily).to_rrule.should == "FREQ=DAILY;INTERVAL=1"
85
+ # every four days
86
+ new_event_specification(:repeat => :daily, :frequency => 4).to_rrule.should == "FREQ=DAILY;INTERVAL=4"
87
+ end
88
+ end
89
+
90
+ describe "events recurring weekly" do
91
+ it "passes validations" do
92
+ new_event_specification(:repeat => :weekly).should be_valid
93
+ new_event_specification(:repeat => :weekly, :frequency => 2).should be_valid
94
+ new_event_specification(:repeat => :weekly, :on => [:mo, :we, :fr]).should be_valid
95
+ new_event_specification(:repeat => :weekly, :frequency => 2, :on => [:mo, :we, :fr]).should be_valid
96
+ new_event_specification(:repeat => :weekly, :frequency => 2, :on => [:mo, :we, :fr], :until => Time.parse("12/31/2010")).should be_valid
97
+ end
98
+
99
+ it "does not support invalid recurrence specifications" do
100
+ spec = new_event_specification(:repeat => :weekly, :frequency => 'foo')
101
+ spec.should_not be_valid
102
+ spec.errors[:frequency].should be_present
103
+
104
+ spec = new_event_specification(:repeat => :weekly, :on_the => :first, :target => :wkend)
105
+ spec.should_not be_valid
106
+ spec.errors[:on_the].should be_present
107
+ spec.errors[:target].should be_present
108
+
109
+ spec = new_event_specification(:repeat => :weekly, :on => '2')
110
+ spec.should_not be_valid
111
+ spec.errors[:on].should be_present
112
+ end
113
+
114
+ it "generates an RRULE" do
115
+ # every week
116
+ new_event_specification(:repeat => :weekly).to_rrule.should == "FREQ=WEEKLY;INTERVAL=1"
117
+ # every two weeks
118
+ new_event_specification(:repeat => :weekly, :frequency => 2).to_rrule.should == "FREQ=WEEKLY;INTERVAL=2"
119
+ # every monday, wednesday, and friday
120
+ new_event_specification(:repeat => :weekly, :on => [:mo, :we, :fr]).to_rrule.should == "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR"
121
+ # every other monday, wednesday, and friday
122
+ new_event_specification(:repeat => :weekly, :frequency => 2, :on => [:mo, :we, :fr]).to_rrule.should == "FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR"
123
+ # every other monday, wednesday, and friday, until 12/31/2010
124
+ new_event_specification(:repeat => :weekly, :frequency => 2, :on => [:mo, :we, :fr], :until => Time.parse("12/31/2010")).to_rrule.should == "FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR;UNTIL=20101231T000000Z"
125
+ end
126
+ end
127
+
128
+ describe "events recurring monthly" do
129
+ it "passes validations" do
130
+ new_event_specification(:repeat => :monthly).should be_valid
131
+ new_event_specification(:repeat => :monthly, :frequency => 2).should be_valid
132
+ new_event_specification(:repeat => :monthly, :frequency => 2, :on => [1, 15, 20]).should be_valid
133
+ new_event_specification(:repeat => :monthly, :frequency => 2, :on_the => :third, :target => :wkday).should be_valid
134
+ new_event_specification(:repeat => :monthly, :frequency => 2, :on_the => :third, :target => [:mo, :we], :until => Time.parse("12/31/2010")).should be_valid
135
+ end
136
+
137
+ it "does not support invalid recurrence specification" do
138
+ spec = new_event_specification(:repeat => :monthly, :frequency => 'foo')
139
+ spec.should_not be_valid
140
+ spec.errors[:frequency].should be_present
141
+
142
+ spec = new_event_specification(:repeat => :monthly, :on => 2)
143
+ spec.should_not be_valid
144
+ spec.errors[:on].should be_present
145
+
146
+ spec = new_event_specification(:repeat => :monthly, :on => [2], :on_the => :first, :target => :wkday)
147
+ spec.should_not be_valid
148
+ spec.errors[:on].should be_present
149
+
150
+ spec = new_event_specification(:repeat => :monthly, :on_the => 2)
151
+ spec.should_not be_valid
152
+ spec.errors[:on_the].should be_present
153
+
154
+ spec = new_event_specification(:repeat => :monthly, :on_the => :first, :target => :we)
155
+ spec.should_not be_valid
156
+ spec.errors[:target].should be_present
157
+
158
+ spec = new_event_specification(:repeat => :monthly, :on_the => :first, :on => [2])
159
+ spec.should_not be_valid
160
+ spec.errors[:on].should be_present
161
+ end
162
+
163
+ it "generates an RRULE" do
164
+ # every month
165
+ new_event_specification(:repeat => :monthly).to_rrule.should == "FREQ=MONTHLY;INTERVAL=1"
166
+ # every two months
167
+ new_event_specification(:repeat => :monthly, :frequency => 2).to_rrule.should == "FREQ=MONTHLY;INTERVAL=2"
168
+ # every other month, on the 1st, 15th, and 20th
169
+ new_event_specification(:repeat => :monthly, :frequency => 2, :on => [1, 15, 20]).to_rrule.should == "FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=1,15,20"
170
+ # every other month, on the third weekday of the month
171
+ new_event_specification(:repeat => :monthly, :frequency => 2, :on_the => :third, :target => :wkday).to_rrule.should == "FREQ=MONTHLY;INTERVAL=2;BYSETPOS=3;BYDAY=MO,TU,WE,TH,FR"
172
+ # every other month, on the third monday and third wednesday, until 12/31/2010
173
+ new_event_specification(:repeat => :monthly, :frequency => 2, :on_the => :third, :target => [:mo, :we], :until => Time.parse("12/31/2010")).to_rrule.should == "FREQ=MONTHLY;INTERVAL=2;BYSETPOS=3;BYDAY=MO,WE;UNTIL=20101231T000000Z"
174
+ end
175
+ end
176
+
177
+ describe "events recurring yearly" do
178
+ it "passes validations" do
179
+ new_event_specification(:repeat => :yearly, :on => [1,7]).should be_valid
180
+ new_event_specification(:repeat => :yearly, :frequency => 2, :on => [1,7]).should be_valid
181
+ new_event_specification(:repeat => :yearly, :on => [1,7], :on_the => :first, :target => :wkend).should be_valid
182
+ new_event_specification(:repeat => :yearly, :frequency => 2, :on => [1,7], :on_the => :first, :target => :wkday, :until => Time.parse("12/31/2010")).should be_valid
183
+ end
184
+
185
+ it "does not support invalid recurrence rules" do
186
+ spec = new_event_specification(:repeat => :yearly)
187
+ spec.should_not be_valid
188
+ spec.errors[:on].should be_present
189
+
190
+ spec = new_event_specification(:repeat => :yearly, :frequency => 3)
191
+ spec.should_not be_valid
192
+ spec.errors[:on].should be_present
193
+
194
+ spec = new_event_specification(:repeat => :yearly, :frequency => 'foo')
195
+ spec.should_not be_valid
196
+ spec.errors[:frequency].should be_present
197
+
198
+ spec = new_event_specification(:repeat => :yearly, :on => 2)
199
+ spec.should_not be_valid
200
+ spec.errors[:on].should be_present
201
+
202
+ spec = new_event_specification(:repeat => :yearly, :on => [2], :on_the => 'first')
203
+ spec.should_not be_valid
204
+ spec.errors[:on_the].should be_present
205
+
206
+ spec = new_event_specification(:repeat => :yearly, :on => [2], :on_the => :first, :target => 2)
207
+ spec.should_not be_valid
208
+ spec.errors[:target].should be_present
209
+ end
210
+
211
+ it "generates an RRULE" do
212
+ # every year in january and july
213
+ new_event_specification(:repeat => :yearly, :on => [1,7]).to_rrule.should == "FREQ=YEARLY;INTERVAL=1;BYMONTH=1,7"
214
+ # every other year, in january and july
215
+ new_event_specification(:repeat => :yearly, :frequency => 2, :on => [1,7]).to_rrule.should == "FREQ=YEARLY;INTERVAL=2;BYMONTH=1,7"
216
+ # every year, on the first weekend day in january and july
217
+ new_event_specification(:repeat => :yearly, :on => [1,7], :on_the => :first, :target => :wkend).to_rrule.should == "FREQ=YEARLY;INTERVAL=1;BYMONTH=1,7;BYSETPOS=1;BYDAY=SU,SA"
218
+ # every other year, on the first weekday in january and july, until 12/31/2010
219
+ new_event_specification(:repeat => :yearly, :frequency => 2, :on => [1,7], :on_the => :first, :target => :wkday, :until => Time.parse("12/31/2010")).to_rrule.should == "FREQ=YEARLY;INTERVAL=2;BYMONTH=1,7;BYSETPOS=1;BYDAY=MO,TU,WE,TH,FR;UNTIL=20101231T000000Z"
220
+ end
221
+ end
222
+
223
+ describe "#generate_events" do
224
+ before(:each) do
225
+ @now = Time.now.utc
226
+ @bod = Date.today.to_time.utc
227
+ end
228
+
229
+ describe "non-recurring events" do
230
+ before(:each) do
231
+ @spec = create_event_specification :start_at => @now, :added_string => 'foo', :added_boolean => true, :added_datetime => Date.yesterday.to_time, :generate => false
232
+ end
233
+
234
+ it "generates a single event" do
235
+ lambda {
236
+ @spec.generate_events
237
+ }.should change(EventOccurrence, :count).by(1)
238
+ end
239
+
240
+ it "copies added columns from event_specifications to event_occurrences" do
241
+ @spec.generate_events
242
+ @spec.event_occurrences.first.added_string.should == @spec.added_string
243
+ @spec.event_occurrences.first.added_boolean.should == @spec.added_boolean
244
+ @spec.event_occurrences.first.added_datetime.should == @spec.added_datetime
245
+ end
246
+
247
+ it "allows attribute overrides" do
248
+ @spec.generate_events :attributes => { :description => 'something new', :added_string => 'something else new'}
249
+ @spec.event_occurrences.first.description.should == 'something new'
250
+ @spec.event_occurrences.first.added_string.should == 'something else new'
251
+ end
252
+ end
253
+
254
+ describe "recurring events" do
255
+ before(:each) do
256
+ @spec = create_event_specification :description => 'walk the dog', :start_at => @now, :repeat => :daily, :frequency => 1, :generate => false
257
+ end
258
+
259
+ it "generates recurring events according to the rrule" do
260
+ lambda {
261
+ @spec.generate_events :from => @bod, :to => @bod + 1.week
262
+ }.should change(EventOccurrence, :count).by(7)
263
+ end
264
+
265
+ it "does not generate events before the specified :from" do
266
+ lambda {
267
+ @spec.generate_events :from => @bod + 1.day, :to => @bod + 1.week
268
+ }.should change(EventOccurrence, :count).by(6)
269
+ end
270
+
271
+ it "does not generate events after the specified :to" do
272
+ lambda {
273
+ @spec.generate_events :from => @bod + 1.day, :to => @bod + 6.days
274
+ }.should change(EventOccurrence, :count).by(5)
275
+ end
276
+
277
+ it "does not generate more events than the specified :count" do
278
+ lambda {
279
+ @spec.generate_events :from => @bod, :to => @bod + 1.week, :count => 3
280
+ }.should change(EventOccurrence, :count).by(3)
281
+ end
282
+
283
+ it "returns the new events" do
284
+ events = @spec.generate_events :from => @bod, :to => @bod + 1.week
285
+ events.should be_present
286
+ events.first.class.should == EventOccurrence
287
+ end
288
+
289
+ it "returns but does not persist duplicate events" do
290
+ lambda {
291
+ @spec.generate_events :from => @bod, :to => @bod + 1.week
292
+ }.should change(EventOccurrence, :count).by(7)
293
+
294
+ lambda {
295
+ events = @spec.generate_events :from => @bod, :to => @bod + 1.week
296
+ events.should be_present
297
+ events.size.should == 7
298
+ }.should_not change(EventOccurrence, :count)
299
+ end
300
+
301
+ it "raises an exception if the event specification is invalid" do
302
+ spec = new_event_specification(:description => nil)
303
+ spec.should_not be_valid
304
+ lambda {
305
+ spec.generate_events :from => @bod
306
+ }.should raise_error(ActsAsEventOwner::Exception)
307
+ end
308
+
309
+ it "does not generate events for specifications that are past their end_at" do
310
+ @spec.update_attributes! :start_at => @now - 1.week, :until => @now - 2.days
311
+ lambda {
312
+ @spec.generate_events :from => @bod, :to => @bod + 1.week
313
+ }.should_not change(EventOccurrence, :count)
314
+ end
315
+ end
316
+ end
317
+
318
+ describe "autogeneration" do
319
+ before(:each) do
320
+ @now = Time.now.utc
321
+ @bod = Date.today.to_time.utc
322
+ end
323
+
324
+ def create_daily_event(generate=nil)
325
+ create_event_specification :description => 'walk the dog', :start_at => @now, :repeat => :daily, :frequency => 2, :generate => generate
326
+ end
327
+
328
+ it "generates 30 days worth of events by default" do
329
+ lambda {
330
+ create_daily_event
331
+ }.should change(EventOccurrence, :count).by(15)
332
+ end
333
+
334
+ it "does not generate any events if the :generate attribute is set to false" do
335
+ lambda {
336
+ create_daily_event(false)
337
+ }.should_not change(EventOccurrence, :count)
338
+ end
339
+
340
+ it "generates events according the :generate attribute" do
341
+ lambda {
342
+ create_daily_event(:to => @now + 15.days)
343
+ }.should change(EventOccurrence, :count).by(8)
344
+
345
+ lambda {
346
+ create_daily_event(:count => 5)
347
+ }.should change(EventOccurrence, :count).by(5)
348
+ end
349
+ end
350
+
351
+ describe "self.generate_events" do
352
+ before(:each) do
353
+ @now = Time.now.utc
354
+ @bod = Date.today.to_time.utc
355
+ @walking_the_dog = create_event_specification :description => 'walk the dog', :start_at => @now, :repeat => :daily, :frequency => 1, :generate => false
356
+ @taking_out_the_trash = create_event_specification :description => 'take out the trash', :start_at => @now, :repeat => :daily, :frequency => 3, :generate => false
357
+ end
358
+
359
+ it "generates events for all event specifications" do
360
+ lambda {
361
+ ActsAsEventOwner::EventSpecification.generate_events :from => @bod, :to => @bod + 1.week
362
+ }.should change(EventOccurrence, :count).by(10)
363
+ end
364
+ end
365
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,43 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+ create_table "event_occurrences", :force => true do |t|
3
+ t.integer "owner_id"
4
+ t.string "owner_type"
5
+ t.integer "event_specification_id"
6
+ t.datetime "start_at"
7
+ t.datetime "end_at"
8
+ t.string "description"
9
+ t.datetime "created_at"
10
+ t.datetime "updated_at"
11
+ t.string "added_string"
12
+ t.boolean "added_boolean"
13
+ t.datetime "added_datetime"
14
+ end
15
+ add_index "event_occurrences", ["event_specification_id"], :name => "index_event_occurrences_on_event_specification_id"
16
+ add_index "event_occurrences", ["owner_id", "owner_type"], :name => "index_event_occurrences_on_owner_id_and_owner_type"
17
+
18
+ create_table "event_specifications", :force => true do |t|
19
+ t.integer "owner_id"
20
+ t.string "owner_type"
21
+ t.string "description"
22
+ t.datetime "start_at"
23
+ t.datetime "end_at"
24
+ t.string "repeat"
25
+ t.integer "frequency", :default => 1
26
+ t.string "on"
27
+ t.string "on_the"
28
+ t.string "target"
29
+ t.datetime "until"
30
+ t.datetime "created_at"
31
+ t.datetime "updated_at"
32
+ t.string "added_string"
33
+ t.boolean "added_boolean"
34
+ t.datetime "added_datetime"
35
+ end
36
+ add_index "event_specifications", ["owner_id", "owner_type"], :name => "index_event_specifications_on_owner_id_and_owner_type"
37
+
38
+ create_table "users", :force => true do |t|
39
+ t.string "name"
40
+ t.datetime "created_at"
41
+ t.datetime "updated_at"
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require 'pp'
4
+
5
+ ActiveRecord::Base.establish_connection({
6
+ :adapter => 'sqlite3',
7
+ :database => ':memory:'
8
+ })
9
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
10
+
11
+ require File.expand_path('../../lib/acts_as_event_owner', __FILE__)
12
+ include ActsAsEventOwner
13
+
14
+ require 'support/model_builders'
15
+ require 'support/user'
16
+
17
+ ActiveRecord::Base.silence do
18
+ ActiveRecord::Migration.verbose = false
19
+ load(File.dirname(__FILE__) + '/schema.rb')
20
+ end
21
+
22
+ def clean_database!
23
+ [ActsAsEventOwner::EventSpecification, ActsAsEventOwner::EventOccurrence, User].each do |model|
24
+ ActiveRecord::Base.connection.execute "DELETE FROM #{model.table_name}"
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ def attributes_for_event_specification(overrides={})
2
+ {
3
+ :description => 'do something'
4
+ }.merge(overrides)
5
+ end
6
+
7
+ def new_event_specification(overrides={})
8
+ ActsAsEventOwner::EventSpecification.new(attributes_for_event_specification(overrides))
9
+ end
10
+
11
+ def create_event_specification(overrides={})
12
+ ActsAsEventOwner::EventSpecification.create(attributes_for_event_specification(overrides))
13
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ acts_as_event_owner
3
+ end