rubyredrick-ri_cal 0.0.2
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/History.txt +3 -0
- data/Manifest.txt +122 -0
- data/README.txt +271 -0
- data/Rakefile +31 -0
- data/bin/ri_cal +8 -0
- data/component_attributes/alarm.yml +10 -0
- data/component_attributes/calendar.yml +4 -0
- data/component_attributes/component_property_defs.yml +180 -0
- data/component_attributes/event.yml +45 -0
- data/component_attributes/freebusy.yml +16 -0
- data/component_attributes/journal.yml +35 -0
- data/component_attributes/timezone.yml +3 -0
- data/component_attributes/timezone_period.yml +11 -0
- data/component_attributes/todo.yml +46 -0
- data/copyrights.txt +2 -0
- data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
- data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
- data/docs/incrementers.txt +7 -0
- data/docs/rfc2445.pdf +0 -0
- data/lib/ri_cal/component/alarm.rb +22 -0
- data/lib/ri_cal/component/calendar.rb +199 -0
- data/lib/ri_cal/component/event.rb +30 -0
- data/lib/ri_cal/component/freebusy.rb +19 -0
- data/lib/ri_cal/component/journal.rb +22 -0
- data/lib/ri_cal/component/t_z_info_timezone.rb +124 -0
- data/lib/ri_cal/component/timezone/daylight_period.rb +26 -0
- data/lib/ri_cal/component/timezone/standard_period.rb +24 -0
- data/lib/ri_cal/component/timezone/timezone_period.rb +54 -0
- data/lib/ri_cal/component/timezone.rb +193 -0
- data/lib/ri_cal/component/todo.rb +26 -0
- data/lib/ri_cal/component.rb +224 -0
- data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
- data/lib/ri_cal/core_extensions/array.rb +7 -0
- data/lib/ri_cal/core_extensions/date/conversions.rb +27 -0
- data/lib/ri_cal/core_extensions/date.rb +13 -0
- data/lib/ri_cal/core_extensions/date_time/conversions.rb +27 -0
- data/lib/ri_cal/core_extensions/date_time.rb +13 -0
- data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
- data/lib/ri_cal/core_extensions/object.rb +8 -0
- data/lib/ri_cal/core_extensions/string/conversions.rb +32 -0
- data/lib/ri_cal/core_extensions/string.rb +8 -0
- data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
- data/lib/ri_cal/core_extensions/time/conversions.rb +27 -0
- data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +88 -0
- data/lib/ri_cal/core_extensions/time.rb +11 -0
- data/lib/ri_cal/core_extensions.rb +6 -0
- data/lib/ri_cal/invalid_timezone_identifer.rb +20 -0
- data/lib/ri_cal/occurrence_enumerator.rb +172 -0
- data/lib/ri_cal/parser.rb +138 -0
- data/lib/ri_cal/properties/alarm.rb +390 -0
- data/lib/ri_cal/properties/calendar.rb +164 -0
- data/lib/ri_cal/properties/event.rb +1526 -0
- data/lib/ri_cal/properties/freebusy.rb +594 -0
- data/lib/ri_cal/properties/journal.rb +1240 -0
- data/lib/ri_cal/properties/timezone.rb +151 -0
- data/lib/ri_cal/properties/timezone_period.rb +416 -0
- data/lib/ri_cal/properties/todo.rb +1562 -0
- data/lib/ri_cal/property_value/array.rb +19 -0
- data/lib/ri_cal/property_value/cal_address.rb +12 -0
- data/lib/ri_cal/property_value/date.rb +119 -0
- data/lib/ri_cal/property_value/date_time/additive_methods.rb +43 -0
- data/lib/ri_cal/property_value/date_time/time_machine.rb +180 -0
- data/lib/ri_cal/property_value/date_time/timezone_support.rb +65 -0
- data/lib/ri_cal/property_value/date_time.rb +324 -0
- data/lib/ri_cal/property_value/duration.rb +106 -0
- data/lib/ri_cal/property_value/geo.rb +12 -0
- data/lib/ri_cal/property_value/integer.rb +13 -0
- data/lib/ri_cal/property_value/occurrence_list.rb +82 -0
- data/lib/ri_cal/property_value/period.rb +63 -0
- data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +98 -0
- data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +77 -0
- data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +149 -0
- data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +54 -0
- data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +32 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb +794 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +132 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +61 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +34 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +50 -0
- data/lib/ri_cal/property_value/recurrence_rule/validations.rb +126 -0
- data/lib/ri_cal/property_value/recurrence_rule.rb +146 -0
- data/lib/ri_cal/property_value/text.rb +41 -0
- data/lib/ri_cal/property_value/uri.rb +12 -0
- data/lib/ri_cal/property_value/utc_offset.rb +34 -0
- data/lib/ri_cal/property_value.rb +110 -0
- data/lib/ri_cal/required_timezones.rb +56 -0
- data/lib/ri_cal/time_with_floating_timezone.rb +59 -0
- data/lib/ri_cal.rb +134 -0
- data/ri_cal.gemspec +47 -0
- data/sample_ical_files/from_ical_dot_app/test1.ics +38 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/spec/ri_cal/component/alarm_spec.rb +13 -0
- data/spec/ri_cal/component/calendar_spec.rb +55 -0
- data/spec/ri_cal/component/event_spec.rb +157 -0
- data/spec/ri_cal/component/freebusy_spec.rb +13 -0
- data/spec/ri_cal/component/journal_spec.rb +13 -0
- data/spec/ri_cal/component/t_z_info_timezone_spec.rb +37 -0
- data/spec/ri_cal/component/timezone_spec.rb +155 -0
- data/spec/ri_cal/component/todo_spec.rb +61 -0
- data/spec/ri_cal/component_spec.rb +212 -0
- data/spec/ri_cal/core_extensions/time/calculations_spec.rb +189 -0
- data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +46 -0
- data/spec/ri_cal/occurrence_enumerator_spec.rb +218 -0
- data/spec/ri_cal/parser_spec.rb +304 -0
- data/spec/ri_cal/property_value/date_spec.rb +22 -0
- data/spec/ri_cal/property_value/date_time_spec.rb +448 -0
- data/spec/ri_cal/property_value/duration_spec.rb +80 -0
- data/spec/ri_cal/property_value/period_spec.rb +50 -0
- data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +22 -0
- data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1815 -0
- data/spec/ri_cal/property_value/text_spec.rb +14 -0
- data/spec/ri_cal/property_value/utc_offset_spec.rb +49 -0
- data/spec/ri_cal/property_value_spec.rb +111 -0
- data/spec/ri_cal/required_timezones_spec.rb +68 -0
- data/spec/ri_cal_spec.rb +54 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +24 -0
- data/tasks/ri_cal.rake +403 -0
- data/tasks/spec.rake +35 -0
- metadata +201 -0
@@ -0,0 +1,189 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. .. spec_helper])
|
5
|
+
|
6
|
+
describe RiCal::CoreExtensions::Time::Calculations do
|
7
|
+
|
8
|
+
describe ".iso_week_num" do
|
9
|
+
|
10
|
+
it "should calculate week 1 for January 1, 2001 for a wkst of 1 (Monday)" do
|
11
|
+
Date.new(2001, 1,1).iso_week_num(1).should == 1
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should calculate week 1 for January 7, 2001 for a wkst of 1 (Monday)" do
|
15
|
+
Date.new(2001, 1,7).iso_week_num(1).should == 1
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should calculate week 2 for January 8, 2001 for a wkst of 1 (Monday)" do
|
19
|
+
Date.new(2001, 1,8).iso_week_num(1).should == 2
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should calculate week 52 for December 31, 2000 for a wkst of 1 (Monday)" do
|
23
|
+
Date.new(2000, 12,31).iso_week_num(1).should == 52
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should calculate week 52 for January 1, 2001 for a wkst of 2 (Tuesday)" do
|
27
|
+
Date.new(2001, 1, 1).iso_week_num(2).should == 52
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should calculate week 1 for Dec 31, 2003 for a wkst of 1 (Monday)" do
|
31
|
+
Date.new(2003, 12, 31).iso_week_num(1).should == 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".iso_year" do
|
36
|
+
it "should be 1999 for January 2 2000" do
|
37
|
+
Date.new(2000, 1, 2).iso_year(1).should == 1999
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be 1998 for December 29, 1997" do
|
41
|
+
Date.new(1997, 12, 29).iso_year(1).should == 1998
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe ".iso_year_start" do
|
46
|
+
|
47
|
+
it "should calculate January 4 1999 for January 2 2000 for a wkst of 1 (Monday)" do
|
48
|
+
Date.new(2000, 1, 2).iso_year_start(1).to_s.should == Date.new(1999, 1, 4).to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should calculate January 3 2000 for January 3 2000 for a wkst of 1 (Monday)" do
|
52
|
+
Date.new(2000, 1, 3).iso_year_start(1).to_s.should == Date.new(2000, 1, 3).to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should calculate January 3 2000 for January 4 2000 for a wkst of 1 (Monday)" do
|
56
|
+
Date.new(2000, 1, 4).iso_year_start(1).to_s.should == Date.new(2000, 1, 3).to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should calculate January 3 2000 for December 31 2000 for a wkst of 1 (Monday)" do
|
60
|
+
Date.new(2000, 12, 31).iso_year_start(1).to_s.should == Date.new(2000, 1, 3).to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should calculate week January 1, 2001 for January 1, 2001 for a wkst of 1 (Monday)" do
|
64
|
+
Date.new(2001, 1,1).iso_year_start(1).should == Date.new(2001, 1, 1)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should calculate week January 1, 2001 for July 4, 2001 for a wkst of 1 (Monday)" do
|
68
|
+
Date.new(2001, 7,4).iso_year_start(1).should == Date.new(2001, 1, 1)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should calculate January 3 2000 for January 3 2000" do
|
72
|
+
Date.new(2000, 1, 3).iso_year_start(1).to_s.should == Date.new(2000, 1, 3).to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should calculate January 3 2000 for January 4 2000" do
|
76
|
+
Date.new(2000, 1, 4).iso_year_start(1).to_s.should == Date.new(2000, 1, 3).to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
# it "should calculate week 1 for January 7, 2001 for a wkst of 1 (Monday)" do
|
80
|
+
# Date.new(2001, 1,7).iso_week_num(1).should == 1
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# it "should calculate week 2 for January 8, 2001 for a wkst of 1 (Monday)" do
|
84
|
+
# Date.new(2001, 1,8).iso_week_num(1).should == 2
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# it "should calculate week 52 for December 31, 2000 for a wkst of 1 (Monday)" do
|
88
|
+
# Date.new(2000, 12,31).iso_week_num(1).should == 52
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# it "should calculate week 52 for January 1, 2001 for a wkst of 2 (Tuesday)" do
|
92
|
+
# Date.new(2001, 1, 1).iso_week_num(2).should == 52
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# it "should calculate week 1 for Dec 31, 2003 for a wkst of 1 (Monday)" do
|
96
|
+
# Date.new(2003, 12, 31).iso_week_num(1).should == 1
|
97
|
+
# end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#iso_week_one" do
|
101
|
+
|
102
|
+
before(:each) do
|
103
|
+
@it = RiCal::CoreExtensions::Time::Calculations
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "with a monday week start" do
|
107
|
+
it "should return Jan 3, 2000 for 2000" do
|
108
|
+
@it.iso_week_one(2000, 1).should == Date.new(2000, 1, 3)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return Jan 1, 2001 for 2001" do
|
112
|
+
@it.iso_week_one(2001, 1).should == Date.new(2001, 1,1)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should return Dec 31, 2001 for 2002" do
|
116
|
+
@it.iso_week_one(2002, 1).should == Date.new(2001, 12, 31)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should return Dec 30, 2002 for 2003" do
|
120
|
+
@it.iso_week_one(2003, 1).should == Date.new(2002, 12, 30)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should return Dec 29, 2003 for 2004" do
|
124
|
+
@it.iso_week_one(2004, 1).should == Date.new(2003, 12, 29)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return Jan 2, 2001 for 2001 with a Tuesday week start" do
|
129
|
+
@it.iso_week_one(2001, 2).should == Date.new(2001, 1, 2)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should return Jan 3, 2001 for 2001 with a Wednesday week start" do
|
133
|
+
@it.iso_week_one(2001, 3).should == Date.new(2001, 1, 3)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return Jan 4, 2001 for 2001 with a Thursday week start" do
|
137
|
+
@it.iso_week_one(2001, 4).should == Date.new(2001, 1, 4)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return Dec 29, 2000 for 2001 with a Friday week start" do
|
141
|
+
@it.iso_week_one(2001, 5).should == Date.new(2000, 12, 29)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should return Dec 30, 2000 for 2001 with a Saturday week start" do
|
145
|
+
@it.iso_week_one(2001, 6).should == Date.new(2000, 12, 30)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should return Dec 31, 2000 for 2001 with a Sunday week start" do
|
149
|
+
@it.iso_week_one(2001, 0).should == Date.new(2000, 12, 31)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe ".leap_year?" do
|
154
|
+
it "should return true for 2000" do
|
155
|
+
Date.parse("1/3/2000").should be_leap_year
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should return false for 2007" do
|
159
|
+
Date.parse("1/3/2007").should_not be_leap_year
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should return true for 2008" do
|
163
|
+
Date.parse("1/3/2008").should be_leap_year
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should return false for 2100" do
|
167
|
+
Date.parse("1/3/2100").should_not be_leap_year
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe ".days_in_month" do
|
172
|
+
|
173
|
+
it "should return 29 for February in a leap year" do
|
174
|
+
Date.new(2008, 2, 1).days_in_month.should == 29
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should return 28 for February in a non-leap year" do
|
178
|
+
Date.new(2009, 2, 1).days_in_month.should == 28
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should return 31 for January in a leap year" do
|
182
|
+
Date.new(2008, 1, 1).days_in_month.should == 31
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should return 31 for January in a non-leap year" do
|
186
|
+
Date.new(2009, 1, 1).days_in_month.should == 31
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. .. spec_helper])
|
5
|
+
|
6
|
+
describe RiCal::CoreExtensions::Time::WeekDayPredicates do
|
7
|
+
|
8
|
+
describe ".nth_wday_in_month" do
|
9
|
+
it "should return Feb 28, 2005 for the 4th Monday for a date in February 2005" do
|
10
|
+
expected = RiCal::PropertyValue::Date.new(nil, :value => "20050228")
|
11
|
+
it =Date.parse("Feb 7, 2005").nth_wday_in_month(4, 1)
|
12
|
+
it.should == expected
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe ".nth_wday_in_month?" do
|
17
|
+
it "should return true for Feb 28, 2005 for the 4th Monday" do
|
18
|
+
Date.parse("Feb 28, 2005").nth_wday_in_month?(4, 1).should be
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".start_of_week_with_wkst" do
|
23
|
+
describe "for Wednesday Sept 10 1997" do
|
24
|
+
before(:each) do
|
25
|
+
@date = Date.parse("Sept 10, 1997")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return a Date of Sept 7, 1997 00:00 for a wkst of 0 - Sunday" do
|
29
|
+
@date.start_of_week_with_wkst(0).should == Date.parse("Sept 7, 1997")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return a Date of Sept 8, 1997 00:00 for a wkst of 1 - Monday" do
|
33
|
+
@date.start_of_week_with_wkst(1).should == Date.parse("Sept 8, 1997")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return a Date of Sept 10, 1997 00:00 for a wkst of 3 - Wednesday" do
|
37
|
+
@date.start_of_week_with_wkst(3).should == Date.parse("Sept 10, 1997")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return a Date of Sept 4, 1997 00:00 for a wkst of 4 - Thursday" do
|
41
|
+
@date.start_of_week_with_wkst(4).should == Date.parse("Sept 4, 1997")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper.rb])
|
5
|
+
|
6
|
+
# Note that this is more of a functional spec
|
7
|
+
describe RiCal::OccurrenceEnumerator do
|
8
|
+
|
9
|
+
Fr13Unbounded_Zulu = <<-TEXT
|
10
|
+
BEGIN:VEVENT
|
11
|
+
DTSTART:19970902T090000Z
|
12
|
+
EXDATE:19970902T090000Z
|
13
|
+
RRULE:FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13
|
14
|
+
END:VEVENT
|
15
|
+
TEXT
|
16
|
+
|
17
|
+
Fr13Unbounded_Eastern = <<-TEXT
|
18
|
+
BEGIN:VEVENT
|
19
|
+
DTSTART;TZID=US-Eastern:19970902T090000
|
20
|
+
EXDATE;TZID=US-Eastern:19970902T090000
|
21
|
+
RRULE:FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13
|
22
|
+
END:VEVENT
|
23
|
+
TEXT
|
24
|
+
|
25
|
+
Fr13UnboundedZuluExpectedFive = [
|
26
|
+
"19980213T090000Z",
|
27
|
+
"19980313T090000Z",
|
28
|
+
"19981113T090000Z",
|
29
|
+
"19990813T090000Z",
|
30
|
+
"20001013T090000Z"
|
31
|
+
].map {|start| src = <<-TEXT
|
32
|
+
BEGIN:VEVENT
|
33
|
+
DTSTART:#{start}
|
34
|
+
RECURRENCE-ID:#{start}
|
35
|
+
END:VEVENT
|
36
|
+
TEXT
|
37
|
+
RiCal.parse_string(src).first
|
38
|
+
}
|
39
|
+
|
40
|
+
describe ".occurrences" do
|
41
|
+
describe "with an unbounded component" do
|
42
|
+
before(:each) do
|
43
|
+
@it = RiCal.parse_string(Fr13Unbounded_Zulu).first
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise an ArgumentError with no options to limit result" do
|
47
|
+
lambda {@it.occurrences}.should raise_error(ArgumentError)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have the right five occurrences when :count => 5 option is used" do
|
51
|
+
result = @it.occurrences(:count => 5)
|
52
|
+
result.should == Fr13UnboundedZuluExpectedFive
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
describe ".each" do
|
60
|
+
describe " for Every Friday the 13th, forever" do
|
61
|
+
before(:each) do
|
62
|
+
event = RiCal.parse_string(Fr13Unbounded_Zulu).first
|
63
|
+
@result = []
|
64
|
+
event.each do |occurrence|
|
65
|
+
break if @result.length >= 5
|
66
|
+
@result << occurrence
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have the right first six occurrences" do
|
71
|
+
# TODO - Need to properly deal with timezones
|
72
|
+
@result.should == Fr13UnboundedZuluExpectedFive
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe RiCal::OccurrenceEnumerator::OccurrenceMerger do
|
80
|
+
before(:each) do
|
81
|
+
@merger = RiCal::OccurrenceEnumerator::OccurrenceMerger
|
82
|
+
end
|
83
|
+
|
84
|
+
describe ".for" do
|
85
|
+
it "should return an EmptyEnumerator if the rules parameter is nil" do
|
86
|
+
@merger.for(nil, nil).should == RiCal::OccurrenceEnumerator::EmptyRulesEnumerator
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return an EmptyEnumerator if the rules parameter is empty" do
|
90
|
+
@merger.for(nil, []).should == RiCal::OccurrenceEnumerator::EmptyRulesEnumerator
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "with a single rrule" do
|
94
|
+
before(:each) do
|
95
|
+
@component = mock("component", :dtstart => :dtstart_value)
|
96
|
+
@rrule = mock("rrule", :enumerator => :rrule_enumerator)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should return the enumerator the rrule" do
|
100
|
+
@merger.for(@component, [@rrule]).should == :rrule_enumerator
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should pass the component to the enumerator instantiation" do
|
104
|
+
@rrule.should_receive(:enumerator).with(@component)
|
105
|
+
@merger.for(@component, [@rrule])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "with multiple rrules" do
|
110
|
+
before(:each) do
|
111
|
+
@component = mock("component", :dtstart => :dtstart_value)
|
112
|
+
@enum1 = mock("rrule_enumerator1", :next_occurrence => :occ1, :bounded? => true)
|
113
|
+
@enum2 = mock("rrule_enumerator2", :next_occurrence => :occ2, :bounded? => true)
|
114
|
+
@rrule1 = mock("rrule", :enumerator => @enum1)
|
115
|
+
@rrule2 = mock("rrule", :enumerator => @enum2)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return an instance of RiCal::OccurrenceEnumerator::OccurrenceMerger" do
|
119
|
+
@merger.for(@component, [@rrule1, @rrule2]).should be_kind_of(RiCal::OccurrenceEnumerator::OccurrenceMerger)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should pass the component to the enumerator instantiation" do
|
123
|
+
@rrule1.should_receive(:enumerator).with(@component).and_return(@enum1)
|
124
|
+
@rrule2.should_receive(:enumerator).with(@component).and_return(@enum2)
|
125
|
+
@merger.for(@component, [@rrule1, @rrule2])
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should preload the next occurrences" do
|
129
|
+
@enum1.should_receive(:next_occurrence).and_return(:occ1)
|
130
|
+
@enum2.should_receive(:next_occurrence).and_return(:occ2)
|
131
|
+
@merger.for(@component, [@rrule1, @rrule2])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "#next_occurence" do
|
137
|
+
|
138
|
+
describe "with unique nexts" do
|
139
|
+
before(:each) do
|
140
|
+
@enum1 = mock("rrule_enumerator1", :next_occurrence => 3, :bounded? => true)
|
141
|
+
@enum2 = mock("rrule_enumerator2", :next_occurrence => 2, :bounded? => true)
|
142
|
+
@rrule1 = mock("rrule", :enumerator => @enum1)
|
143
|
+
@rrule2 = mock("rrule", :enumerator => @enum2)
|
144
|
+
@it = @merger.new(0, [@rrule1, @rrule2])
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should return the earliest occurrence" do
|
148
|
+
@it.next_occurrence.should == 2
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should advance the enumerator which returned the result" do
|
152
|
+
@enum2.should_receive(:next_occurrence).and_return(4)
|
153
|
+
@it.next_occurrence
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should not advance the other enumerator" do
|
157
|
+
@enum1.should_not_receive(:next_occurrence)
|
158
|
+
@it.next_occurrence
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should properly update the next array" do
|
162
|
+
@enum2.stub!(:next_occurrence).and_return(4)
|
163
|
+
@it.next_occurrence
|
164
|
+
@it.nexts.should == [3, 4]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "with duplicated nexts" do
|
169
|
+
before(:each) do
|
170
|
+
@enum1 = mock("rrule_enumerator1", :next_occurrence => 2, :bounded? => true)
|
171
|
+
@enum2 = mock("rrule_enumerator2", :next_occurrence => 2, :bounded? => true)
|
172
|
+
@rrule1 = mock("rrule", :enumerator => @enum1)
|
173
|
+
@rrule2 = mock("rrule", :enumerator => @enum2)
|
174
|
+
@it = @merger.new(0, [@rrule1, @rrule2])
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should return the earliest occurrence" do
|
178
|
+
@it.next_occurrence.should == 2
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should advance both enumerators" do
|
182
|
+
@enum1.should_receive(:next_occurrence).and_return(5)
|
183
|
+
@enum2.should_receive(:next_occurrence).and_return(4)
|
184
|
+
@it.next_occurrence
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should properly update the next array" do
|
188
|
+
@enum1.stub!(:next_occurrence).and_return(5)
|
189
|
+
@enum2.stub!(:next_occurrence).and_return(4)
|
190
|
+
@it.next_occurrence
|
191
|
+
@it.nexts.should == [5, 4]
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "with all enumerators at end" do
|
197
|
+
before(:each) do
|
198
|
+
@enum1 = mock("rrule_enumerator1", :next_occurrence => nil, :bounded? => true)
|
199
|
+
@enum2 = mock("rrule_enumerator2", :next_occurrence => nil, :bounded? => true)
|
200
|
+
@rrule1 = mock("rrule", :enumerator => @enum1)
|
201
|
+
@rrule2 = mock("rrule", :enumerator => @enum2)
|
202
|
+
@it = @merger.new(0, [@rrule1, @rrule2])
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should return nil" do
|
206
|
+
@it.next_occurrence.should == nil
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should not advance the enumerators which returned the result" do
|
210
|
+
@enum1.should_not_receive(:next_occurrence)
|
211
|
+
@enum2.should_not_receive(:next_occurrence)
|
212
|
+
@it.next_occurrence
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|