dgp-schedule_attributes 0.4.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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +28 -0
  5. data/Appraisals +21 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +63 -0
  8. data/README.markdown +78 -0
  9. data/Rakefile +7 -0
  10. data/gemfiles/rails_3.2.gemfile +8 -0
  11. data/gemfiles/rails_3.2.gemfile.lock +112 -0
  12. data/gemfiles/rails_4.0.gemfile +7 -0
  13. data/gemfiles/rails_4.0.gemfile.lock +76 -0
  14. data/gemfiles/rails_4.1.gemfile +7 -0
  15. data/gemfiles/rails_4.1.gemfile.lock +75 -0
  16. data/gemfiles/rails_4.2.gemfile +7 -0
  17. data/gemfiles/rails_4.2.gemfile.lock +75 -0
  18. data/gemfiles/rails_edge.gemfile +8 -0
  19. data/gemfiles/rails_edge.gemfile.lock +83 -0
  20. data/lib/schedule_attributes.rb +18 -0
  21. data/lib/schedule_attributes/active_record.rb +50 -0
  22. data/lib/schedule_attributes/configuration.rb +22 -0
  23. data/lib/schedule_attributes/core.rb +146 -0
  24. data/lib/schedule_attributes/extensions/ice_cube.rb +11 -0
  25. data/lib/schedule_attributes/form_builder.rb +42 -0
  26. data/lib/schedule_attributes/input.rb +159 -0
  27. data/lib/schedule_attributes/model.rb +24 -0
  28. data/lib/schedule_attributes/railtie.rb +13 -0
  29. data/lib/schedule_attributes/rule_parser.rb +25 -0
  30. data/lib/schedule_attributes/rule_parser/base.rb +96 -0
  31. data/lib/schedule_attributes/rule_parser/day.rb +13 -0
  32. data/lib/schedule_attributes/rule_parser/month.rb +40 -0
  33. data/lib/schedule_attributes/rule_parser/week.rb +18 -0
  34. data/lib/schedule_attributes/rule_parser/year.rb +21 -0
  35. data/lib/schedule_attributes/serializer.rb +30 -0
  36. data/lib/schedule_attributes/time_helpers.rb +36 -0
  37. data/lib/schedule_attributes/version.rb +3 -0
  38. data/schedule_attributes.gemspec +32 -0
  39. data/spec/active_record_integration_spec.rb +57 -0
  40. data/spec/schedule_attributes/configuration_spec.rb +29 -0
  41. data/spec/schedule_attributes/input_spec.rb +182 -0
  42. data/spec/schedule_attributes/rule_parser/day_spec.rb +113 -0
  43. data/spec/schedule_attributes/rule_parser/month_spec.rb +47 -0
  44. data/spec/schedule_attributes/rule_parser/week_spec.rb +36 -0
  45. data/spec/schedule_attributes/rule_parser/year_spec.rb +53 -0
  46. data/spec/schedule_attributes/rule_parser_spec.rb +18 -0
  47. data/spec/schedule_attributes/time_helpers_spec.rb +39 -0
  48. data/spec/schedule_attributes_spec.rb +226 -0
  49. data/spec/spec_helper.rb +11 -0
  50. data/spec/support/parser_macros.rb +31 -0
  51. data/spec/support/scheduled_active_record_model.rb +39 -0
  52. data/spec/support/scheduled_model.rb +16 -0
  53. metadata +234 -0
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'ice_cube'
3
+ require 'schedule_attributes/rule_parser'
4
+ require 'schedule_attributes/input'
5
+
6
+ describe ScheduleAttributes::RuleParser::Month do
7
+
8
+ describe "#rule" do
9
+ let(:input) { ScheduleAttributes::Input.new(RSpec.current_example.metadata[:args]) }
10
+ let(:parser) { described_class.new(input) }
11
+ subject { parser.rule }
12
+
13
+ let(:t) { Date.current }
14
+ let(:n) { (t-14 >> 1).change(day: 14) }
15
+
16
+ let(:monthly) { [t, t >> 1, t >> 2, t >> 3].map(&:to_time) }
17
+ let(:bimonthly) { [t, t >> 2, t >> 4, t >> 6].map(&:to_time) }
18
+ let(:every_14th) { [n, n >> 1, n >> 2, n >> 3].map(&:to_time) }
19
+
20
+ context 'no arguments', args: {} do
21
+ it { should == IceCube::Rule.monthly }
22
+ its_occurrences_until(3.months.from_now) { should == monthly }
23
+ end
24
+
25
+ context 'start_date and interval arguments', args: {"start_date" => "2000-03-14", "interval" => "2"} do
26
+ it { should == IceCube::Rule.monthly(2) }
27
+ its_occurrences_until(6.months.from_now) { should == bimonthly }
28
+ end
29
+
30
+ context 'ordinal_unit and ordinal_day arguments', args: {"ordinal_unit" => "day", "ordinal_day" => "14"} do
31
+ it { should == IceCube::Rule.monthly.day_of_month(14) }
32
+ its_occurrences_until(4.months.from_now) { should == every_14th }
33
+ end
34
+
35
+ context 'ordinal_unit, ordinal_week and tuesday arguments', args: {"ordinal_unit" => "week", "ordinal_week" => "2", "tuesday" => "1"} do
36
+ it { should == IceCube::Rule.monthly.day_of_week(:tuesday => [2]) }
37
+ end
38
+
39
+ context 'ordinal_unit and ordinal_week arguments', args: {"ordinal_unit" => "week", "ordinal_week" => "2"} do
40
+ it { should == IceCube::Rule.monthly.day_of_week(0=>(w=[2]), 1=>w, 2=>w, 3=>w, 4=>w, 5=>w, 6=>w) }
41
+ end
42
+
43
+ context 'start_date and end_date arguments', args: {"start_date" => "2000-03-14", "end_date" => "2000-06-14"} do
44
+ it { should == IceCube::Rule.monthly.until(Time.new(2000,6,14)) }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'ice_cube'
3
+ require 'schedule_attributes/rule_parser'
4
+ require 'schedule_attributes/input'
5
+
6
+ describe ScheduleAttributes::RuleParser::Week do
7
+ let(:t) { Date.current.to_time }
8
+ let(:sun) { (Date.current - Date.current.cwday.days).to_time + 1.week }
9
+ let(:mon) { sun + 1.day }
10
+ let(:sat) { sun - 1.day }
11
+
12
+ let(:weekly) { [t, t+1.week, t+2.weeks, t+3.weeks, t+4.weeks, t+5.weeks] }
13
+ let(:every_2_weeks) { [t, t+2.week, t+4.weeks]}
14
+ let(:weekends) { [sat, sun, sat+1.week, sun+1.week, sat+2.weeks, sun+2.weeks] }
15
+
16
+ describe "#rule" do
17
+ let(:input) { ScheduleAttributes::Input.new(RSpec.current_example.metadata[:args]) }
18
+ let(:parser) { described_class.new(input) }
19
+ subject { parser.rule }
20
+
21
+ context 'no arguments', args: {} do
22
+ it { should == IceCube::Rule.weekly }
23
+ its_occurrences_until(5.weeks.from_now) { should == weekly }
24
+ end
25
+
26
+ context 'interval argument', args: {"interval" => "2"} do
27
+ it { should == IceCube::Rule.weekly(2) }
28
+ its_occurrences_until(5.weeks.from_now) { should == every_2_weeks }
29
+ end
30
+
31
+ context 'several day name arguments', args: {"monday" => "0", "saturday" => "1", "sunday" => "1"} do
32
+ it { should == IceCube::Rule.weekly.day(0,6) }
33
+ its_occurrences_until(Date.today.beginning_of_week+3.weeks) { subject[-4..-1].should == weekends[-4..-1] }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'ice_cube'
3
+ require 'schedule_attributes/rule_parser'
4
+ require 'schedule_attributes/input'
5
+
6
+ describe ScheduleAttributes::RuleParser::Year do
7
+ let(:t) { Date.today }
8
+ let(:n) { Date.new(Date.current.year,3,14) }
9
+
10
+ let(:every_year) { [t, t>>12, t>>24, t>>36, t>>48].map(&:to_time) }
11
+ let(:every_2nd_year) { [t, t>>24, t>>48].map(&:to_time) }
12
+ let(:every_pi_day) { [n, n>>12, n>>24, n>>36, n>>48].tap{ |a| a.shift if t.yday > n.yday }.map(&:to_time) }
13
+
14
+ describe "#rule" do
15
+ let(:input) { ScheduleAttributes::Input.new(RSpec.current_example.metadata[:args]) }
16
+ let(:parser) { described_class.new(input) }
17
+ subject { parser.rule }
18
+
19
+ context 'no arguments', args: {} do
20
+ it { should == IceCube::Rule.yearly }
21
+ its_occurrences_until(4.years.from_now) { should == every_year }
22
+ end
23
+
24
+ context 'interval argument', args: {"interval" => "2"} do
25
+ it { should == IceCube::Rule.yearly(2) }
26
+ its_occurrences_until(4.years.from_now) { should == every_2nd_year }
27
+ end
28
+
29
+ context 'start_date argument', args: {"start_date" => "2000-03-14"} do
30
+ it { should == IceCube::Rule.yearly.month_of_year(3).day_of_month(14) }
31
+ end
32
+
33
+ context 'start_date argument alt', args: {"start_date" => "2000-01-30"} do
34
+ it { should == IceCube::Rule.yearly.month_of_year(1).day_of_month(30) }
35
+ end
36
+
37
+ context 'start_date and end_date arguments', args: {"start_date" => "2000-03-14", "end_date" => "#{Date.current.year+4}-03-14"} do
38
+ it { should == IceCube::Rule.yearly.month_of_year(3).day_of_month(14).until(Date.new(Date.current.year+4,3,14).to_time) }
39
+ its_occurrences_until(10.years.from_now) { should == every_pi_day }
40
+ end
41
+
42
+ context "ignoring yearly_start and end limits", args: {
43
+ "start_date" => "2000-03-14",
44
+ "yearly_start_month" => "4",
45
+ "yearly_start_month_day" => "15",
46
+ "yearly_end_month" => "5",
47
+ "yearly_end_month_day" => "20"
48
+ } do
49
+ it { should == IceCube::Rule.yearly.month_of_year(3).day_of_month(14) }
50
+ its_occurrences_until(Date.new(Date.current.year+4,12,31)) { should == every_pi_day }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'schedule_attributes/rule_parser'
3
+
4
+ describe ScheduleAttributes::RuleParser do
5
+ describe "class methods" do
6
+ {
7
+ "day" => ScheduleAttributes::RuleParser::Day,
8
+ "week" => ScheduleAttributes::RuleParser::Week,
9
+ "month" => ScheduleAttributes::RuleParser::Month,
10
+ "year" => ScheduleAttributes::RuleParser::Year
11
+ }. each do |key,parser_class|
12
+
13
+ it "returns parser for #{key} interval units" do
14
+ ScheduleAttributes::RuleParser[key].should == parser_class
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'schedule_attributes/time_helpers'
3
+ require 'active_support/time_with_zone'
4
+
5
+ describe ScheduleAttributes::TimeHelpers do
6
+ describe '.parse_in_zone' do
7
+
8
+ context "with time zone" do
9
+ before { Time.zone = 'UTC' }
10
+
11
+ it "returns a time from a date string" do
12
+ subject.parse_in_zone("2000-12-31").should == Time.zone.parse("2000-12-31")
13
+ end
14
+
15
+ it "returns a time from a time" do
16
+ local_offset = "-08:00"
17
+ local_time = Time.new(2000,12,31,0,0,0,local_offset)
18
+ subject.parse_in_zone(local_time).should == Time.zone.parse("2000-12-31 08:00:00")
19
+ end
20
+
21
+ it "returns a time from a date" do
22
+ subject.parse_in_zone(Date.new(2000,12,31)).should == Time.zone.parse("2000-12-31")
23
+ end
24
+ end
25
+
26
+ context "without ActiveSupport" do
27
+ before { Time.zone = nil }
28
+
29
+ it "returns a time from a date string" do
30
+ subject.parse_in_zone("2000-12-31").should == Time.parse("2000-12-31")
31
+ end
32
+
33
+ it "returns a time from a time" do
34
+ subject.parse_in_zone(Time.new(2000,12,31)).should == Time.parse("2000-12-31")
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,226 @@
1
+ require 'spec_helper'
2
+ require 'support/scheduled_model'
3
+
4
+ describe ScheduledModel do
5
+
6
+ describe "#schedule" do
7
+ subject(:schedule) { ScheduledModel.new.schedule }
8
+
9
+ it "should default to a daily schedule" do
10
+ schedule.should be_a(IceCube::Schedule)
11
+ schedule.rtimes.should == []
12
+ schedule.start_time.should == Date.today.to_time
13
+ schedule.end_time.should be nil
14
+ schedule.rrules.should == [IceCube::Rule.daily]
15
+ end
16
+ end
17
+
18
+ describe "#schedule_attributes=" do
19
+ describe "setting the correct schedule" do
20
+ let(:scheduled_model) { ScheduledModel.new.tap { |m| m.schedule_attributes = RSpec.current_example.metadata[:args] } }
21
+ subject(:schedule) { scheduled_model.schedule }
22
+
23
+ context args: {repeat: '0', date: '1-1-1985', interval: '5 (ignore this)'} do
24
+ it { subject.start_time.should == Time.new(1985,1,1) }
25
+ it { subject.all_occurrences.should == [Time.new(1985,1,1)] }
26
+ it { subject.rrules.should be_blank }
27
+ end
28
+
29
+ context args: {repeat: '0', dates: ['1-1-1985', '31-12-1985'], interval: '5 (ignore this)'} do
30
+ it { subject.start_time.should == Time.new(1985,1,1) }
31
+ it { subject.all_occurrences.should == [Time.new(1985,1,1), Time.new(1985,12,31)] }
32
+ it { subject.rrules.should be_blank }
33
+ end
34
+
35
+ context args: {repeat: '0', dates: ['1-1-1985', '31-12-1985'], start_time: '12:00', end_time: '14:00', interval: '5 (ignore this)'} do
36
+ it { subject.start_time.should == Time.new(1985,1,1,12,0) }
37
+ it { subject.duration.should == 7200 }
38
+ it { subject.all_occurrences.should == [Time.new(1985,1,1,12,0), Time.new(1985,12,31,12,0)] }
39
+ it { subject.rrules.should be_blank }
40
+ specify { schedule.occurring_between?(helpers.parse_in_zone('1985-1-1 12:00'), helpers.parse_in_zone('1985-6-25 14:00')).should be_truthy }
41
+ specify { schedule.occurs_at?(helpers.parse_in_zone('1985-1-1 12:00')).should be_truthy }
42
+ specify { schedule.occurs_at?(helpers.parse_in_zone('1985-6-6 15:00')).should be_falsey }
43
+ end
44
+
45
+ context args: {repeat: '1'} do
46
+ it { subject.start_time.should == Date.today.to_time }
47
+ it { subject.rrules.should == [IceCube::Rule.daily] }
48
+ end
49
+
50
+ context args: {repeat: '1', start_date: '1-1-1985', interval_unit: 'day', interval: '3'} do
51
+ it { subject.start_time.should == Date.new(1985,1,1).to_time }
52
+ it { subject.rrules.should == [IceCube::Rule.daily(3)] }
53
+ specify { schedule.first(3).should == [Date.civil(1985,1,1), Date.civil(1985,1,4), Date.civil(1985,1,7)].map(&:to_time) }
54
+ end
55
+
56
+ context args: {repeat: "1", start_date: "1-1-1985", interval_unit: "day", interval: "3", end_date: "29-12-1985", ends: "eventually"} do
57
+ it { subject.start_time.should == Date.new(1985,1,1).to_time }
58
+ # Rails 4.1 removes Date.current.to_time_in_current_zone in favour of Date.in_time_zone
59
+ it do
60
+ if Date.current.respond_to?(:in_time_zone)
61
+ subject.rrules.should == [ IceCube::Rule.daily(3).until(Date.new(1985,12,29).in_time_zone) ]
62
+ else
63
+ subject.rrules.should == [ IceCube::Rule.daily(3).until(Date.new(1985,12,29).to_time_in_current_zone) ]
64
+ end
65
+ end
66
+ specify { schedule.first(3).should == [Date.civil(1985,1,1), Date.civil(1985,1,4), Date.civil(1985,1,7)].map(&:to_time) }
67
+ end
68
+
69
+ context args: {repeat: '1', start_date: '1-1-1985', interval_unit: 'day', interval: '3', until_date: '29-12-1985', ends: 'never'} do
70
+ it { subject.start_time.should == Date.new(1985,1,1).to_time }
71
+ it { subject.rrules.should == [IceCube::Rule.daily(3)] }
72
+ specify { schedule.first(3).should == [Date.civil(1985,1,1), Date.civil(1985,1,4), Date.civil(1985,1,7)].map(&:to_time) }
73
+ end
74
+
75
+ context args: {repeat: '1', start_date: '1-1-1985', interval_unit: 'week', interval: '3', monday: '1', wednesday: '1', friday: '1'} do
76
+ it { subject.start_time.should == Date.new(1985,1,1).to_time }
77
+ it { subject.rrules.should == [IceCube::Rule.weekly(3).day(:monday, :wednesday, :friday)] }
78
+ specify { schedule.occurs_at?(helpers.parse_in_zone('1985-1-2')).should be_truthy }
79
+ specify { schedule.occurs_at?(helpers.parse_in_zone('1985-1-4')).should be_truthy }
80
+ specify { schedule.occurs_at?(helpers.parse_in_zone('1985-1-7')).should be_falsey }
81
+ specify { schedule.occurs_at?(helpers.parse_in_zone('1985-1-21')).should be_truthy }
82
+ end
83
+
84
+ context args: {repeat: '1', start_date: '1-1-1985', interval_unit: 'day'} do
85
+ it { subject.rrules.should == [IceCube::Rule.daily(1)] }
86
+ end
87
+
88
+ context args: {repeat: '1', start_date: '1-1-1985', interval_unit: 'year'} do
89
+ it { subject.start_time.should == Date.new(1985,1,1).to_time }
90
+ it { subject.rrules.should == [IceCube::Rule.yearly.day_of_month(1).month_of_year(1)] }
91
+ specify { schedule.first(3).should == [Date.civil(1985,1,1), Date.civil(1986,1,1), Date.civil(1987,1,1)].map(&:to_time) }
92
+ end
93
+
94
+ context args: {repeat: '1', interval_unit: 'day', start_date: '2012-09-27', yearly_start_month: '12', yearly_start_month_day: '1', yearly_end_month: '4', yearly_end_month_day: '21'} do
95
+ it { subject.start_time.should == Time.new(2012,9,27) }
96
+ it { subject.rrules.should == [IceCube::Rule.daily.month_of_year(12,1,2,3,4)] }
97
+ it { subject.exrules.should == [IceCube::Rule.daily.month_of_year(4).day_of_month(*22..31)] }
98
+ end
99
+
100
+ context "all_day", pending: "Work in progress"
101
+ end
102
+
103
+ describe "setting the schedule field", args: {repeat: '1', start_date: '1-1-1985', interval_unit: 'day', interval: '3'} do
104
+ let(:scheduled_model) { ScheduledModel.new.tap { |m| m.schedule_attributes = RSpec.current_example.metadata[:args] } }
105
+ subject { scheduled_model }
106
+
107
+ it { subject.schedule.should == IceCube::Schedule.new(Date.new(1985,1,1).to_time).tap { |s| s.add_recurrence_rule IceCube::Rule.daily(3) } }
108
+ end
109
+
110
+ end
111
+
112
+ describe "schedule_attributes" do
113
+ let(:scheduled_model) { ScheduledModel.new }
114
+ let(:schedule) { IceCube::Schedule.new(Date.tomorrow.to_time) }
115
+ subject { scheduled_model.schedule_attributes }
116
+ before { scheduled_model.stub(schedule: schedule) }
117
+
118
+ context "for a single date" do
119
+ before { schedule.add_recurrence_time(Date.tomorrow.to_time) }
120
+ it { should == OpenStruct.new(repeat: 0, interval: 1, date: Date.tomorrow, dates: [Date.tomorrow], start_date: Date.today, all_day: true) }
121
+ it { subject.date.should be_a(Date) }
122
+ end
123
+
124
+ context "when it repeats daily" do
125
+ before do
126
+ schedule.add_recurrence_rule(IceCube::Rule.daily(4))
127
+ end
128
+ it { should == OpenStruct.new(repeat: 1, start_date: Date.tomorrow, interval_unit: 'day', interval: 4, ends: 'never', date: Date.today, all_day: true) }
129
+ it { subject.start_date.should be_a(Date) }
130
+ end
131
+
132
+ context "when it repeats with an end date" do
133
+ before do
134
+ schedule.add_recurrence_rule(IceCube::Rule.daily(4).until((Date.today+10).to_time))
135
+ end
136
+ it { should == OpenStruct.new(repeat: 1, start_date: Date.tomorrow, interval_unit: 'day', interval: 4, ends: 'eventually', end_date: Date.today+10, date: Date.today, all_day: true) }
137
+ it { subject.start_date.should be_a(Date) }
138
+ it { subject.end_date.should be_a(Date) }
139
+ end
140
+
141
+ context "when it repeats weekly" do
142
+ before do
143
+ schedule.add_recurrence_time(Date.tomorrow)
144
+ schedule.add_recurrence_rule(IceCube::Rule.weekly(4).day(:monday, :wednesday, :friday))
145
+ end
146
+ it do
147
+ should == OpenStruct.new(
148
+ :repeat => 1,
149
+ :start_date => Date.tomorrow,
150
+ :interval_unit => 'week',
151
+ :interval => 4,
152
+ :ends => 'never',
153
+ :monday => 1,
154
+ :wednesday => 1,
155
+ :friday => 1,
156
+ :all_day => true,
157
+
158
+ :date => Date.today #for the form
159
+ )
160
+ end
161
+ end
162
+
163
+ context "when it repeats yearly" do
164
+ before do
165
+ schedule.add_recurrence_time(Date.tomorrow)
166
+ schedule.add_recurrence_rule(IceCube::Rule.yearly)
167
+ end
168
+ it do
169
+ should == OpenStruct.new(
170
+ :repeat => 1,
171
+ :start_date => Date.tomorrow,
172
+ :interval_unit => 'year',
173
+ :interval => 1,
174
+ :ends => 'never',
175
+ :all_day => true,
176
+
177
+ :date => Date.today #for the form
178
+ )
179
+ end
180
+ end
181
+
182
+ context "when it has yearly date range" do
183
+ it "should have yearly start and end months" do
184
+ schedule.add_recurrence_rule(IceCube::Rule.daily.month_of_year(12,1,2))
185
+
186
+ subject.yearly_start_month.should == 12
187
+ subject.yearly_end_month.should == 2
188
+ end
189
+
190
+ it "should have a yearly start date" do
191
+ schedule.add_recurrence_rule(IceCube::Rule.daily.month_of_year(11,12,1,2))
192
+ schedule.add_exception_rule(IceCube::Rule.daily.month_of_year(11).day_of_month(*1..6))
193
+
194
+ subject.yearly_start_month.should == 11
195
+ subject.yearly_start_month_day.should == 7
196
+ end
197
+
198
+ it "should have a yearly end date" do
199
+ schedule.add_recurrence_rule(IceCube::Rule.daily.month_of_year(1,2,3))
200
+ schedule.add_exception_rule(IceCube::Rule.daily.month_of_year(3).day_of_month(*26..31))
201
+
202
+ subject.yearly_end_month.should == 3
203
+ subject.yearly_end_month_day.should == 25
204
+ end
205
+
206
+ it "should have no yearly start day for months only" do
207
+ schedule.add_recurrence_rule(IceCube::Rule.daily.month_of_year(1,2,3))
208
+
209
+ subject.yearly_start_month_day.should be_nil
210
+ end
211
+
212
+ it "should have a yearly start day on the first when end day is set" do
213
+ schedule.add_recurrence_rule(IceCube::Rule.daily.month_of_year(1,2,3))
214
+ schedule.add_exception_rule(IceCube::Rule.daily.month_of_year(3).day_of_month(*26..31))
215
+
216
+ subject.yearly_start_month_day.should == 1
217
+ end
218
+ end
219
+
220
+ context "all_day", pending: "Work in progress"
221
+ end
222
+
223
+ def helpers
224
+ ScheduleAttributes::TimeHelpers
225
+ end
226
+ end
@@ -0,0 +1,11 @@
1
+ require 'active_support'
2
+ require 'ostruct'
3
+ require 'pry'
4
+ require 'support/parser_macros'
5
+
6
+ $: << File.expand_path('../lib')
7
+
8
+ RSpec.configure do |config|
9
+ config.include SpecHelpers::ParserMacros
10
+ config.expect_with :rspec
11
+ end
@@ -0,0 +1,31 @@
1
+ module SpecHelpers
2
+ def input_for(klass, args = nil)
3
+ klass.new(args)
4
+ end
5
+
6
+ module ParserMacros
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def its_occurrences_until(date, &block)
11
+ describe "occurrences" do
12
+ shared_examples 'occurrences' do
13
+
14
+ orig_subject = subject
15
+
16
+ self.class.class_eval do
17
+ define_method(:subject) do
18
+ schedule = IceCube::Schedule.new(Date.today.to_time)
19
+ schedule.add_recurrence_rule(orig_subject)
20
+ @_subject = schedule.occurrences(date)
21
+ end
22
+ end
23
+
24
+ yield
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+ end