justinsoong-ri_cal 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/History.txt +402 -0
  2. data/Manifest.txt +161 -0
  3. data/README.txt +410 -0
  4. data/Rakefile +69 -0
  5. data/VERSION +1 -0
  6. data/bin/ri_cal +8 -0
  7. data/component_attributes/alarm.yml +10 -0
  8. data/component_attributes/calendar.yml +4 -0
  9. data/component_attributes/component_property_defs.yml +180 -0
  10. data/component_attributes/event.yml +45 -0
  11. data/component_attributes/freebusy.yml +16 -0
  12. data/component_attributes/journal.yml +35 -0
  13. data/component_attributes/timezone.yml +3 -0
  14. data/component_attributes/timezone_period.yml +11 -0
  15. data/component_attributes/todo.yml +46 -0
  16. data/copyrights.txt +1 -0
  17. data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
  18. data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
  19. data/docs/incrementers.txt +7 -0
  20. data/docs/rfc2445.pdf +0 -0
  21. data/lib/ri_cal/component/alarm.rb +19 -0
  22. data/lib/ri_cal/component/calendar.rb +258 -0
  23. data/lib/ri_cal/component/event.rb +58 -0
  24. data/lib/ri_cal/component/freebusy.rb +16 -0
  25. data/lib/ri_cal/component/journal.rb +27 -0
  26. data/lib/ri_cal/component/non_standard.rb +33 -0
  27. data/lib/ri_cal/component/t_z_info_timezone.rb +153 -0
  28. data/lib/ri_cal/component/timezone/daylight_period.rb +25 -0
  29. data/lib/ri_cal/component/timezone/standard_period.rb +23 -0
  30. data/lib/ri_cal/component/timezone/timezone_period.rb +76 -0
  31. data/lib/ri_cal/component/timezone.rb +197 -0
  32. data/lib/ri_cal/component/todo.rb +42 -0
  33. data/lib/ri_cal/component.rb +256 -0
  34. data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
  35. data/lib/ri_cal/core_extensions/array.rb +7 -0
  36. data/lib/ri_cal/core_extensions/date/conversions.rb +56 -0
  37. data/lib/ri_cal/core_extensions/date.rb +13 -0
  38. data/lib/ri_cal/core_extensions/date_time/conversions.rb +50 -0
  39. data/lib/ri_cal/core_extensions/date_time.rb +15 -0
  40. data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
  41. data/lib/ri_cal/core_extensions/object.rb +8 -0
  42. data/lib/ri_cal/core_extensions/string/conversions.rb +57 -0
  43. data/lib/ri_cal/core_extensions/string.rb +8 -0
  44. data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
  45. data/lib/ri_cal/core_extensions/time/conversions.rb +42 -0
  46. data/lib/ri_cal/core_extensions/time/tzid_access.rb +50 -0
  47. data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +55 -0
  48. data/lib/ri_cal/core_extensions/time.rb +14 -0
  49. data/lib/ri_cal/core_extensions.rb +11 -0
  50. data/lib/ri_cal/fast_date_time.rb +234 -0
  51. data/lib/ri_cal/floating_timezone.rb +32 -0
  52. data/lib/ri_cal/invalid_property_value.rb +8 -0
  53. data/lib/ri_cal/invalid_timezone_identifier.rb +20 -0
  54. data/lib/ri_cal/occurrence_enumerator.rb +265 -0
  55. data/lib/ri_cal/occurrence_period.rb +17 -0
  56. data/lib/ri_cal/parser.rb +145 -0
  57. data/lib/ri_cal/properties/alarm.rb +390 -0
  58. data/lib/ri_cal/properties/calendar.rb +164 -0
  59. data/lib/ri_cal/properties/event.rb +1523 -0
  60. data/lib/ri_cal/properties/freebusy.rb +593 -0
  61. data/lib/ri_cal/properties/journal.rb +1237 -0
  62. data/lib/ri_cal/properties/timezone.rb +150 -0
  63. data/lib/ri_cal/properties/timezone_period.rb +416 -0
  64. data/lib/ri_cal/properties/todo.rb +1559 -0
  65. data/lib/ri_cal/properties.rb +12 -0
  66. data/lib/ri_cal/property_value/array.rb +27 -0
  67. data/lib/ri_cal/property_value/cal_address.rb +11 -0
  68. data/lib/ri_cal/property_value/date.rb +184 -0
  69. data/lib/ri_cal/property_value/date_time/additive_methods.rb +44 -0
  70. data/lib/ri_cal/property_value/date_time/time_machine.rb +159 -0
  71. data/lib/ri_cal/property_value/date_time/timezone_support.rb +100 -0
  72. data/lib/ri_cal/property_value/date_time.rb +359 -0
  73. data/lib/ri_cal/property_value/duration.rb +110 -0
  74. data/lib/ri_cal/property_value/geo.rb +11 -0
  75. data/lib/ri_cal/property_value/integer.rb +12 -0
  76. data/lib/ri_cal/property_value/occurrence_list.rb +144 -0
  77. data/lib/ri_cal/property_value/period.rb +86 -0
  78. data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +100 -0
  79. data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +79 -0
  80. data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +148 -0
  81. data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +53 -0
  82. data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +31 -0
  83. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb +86 -0
  84. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb +31 -0
  85. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb +32 -0
  86. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb +52 -0
  87. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb +31 -0
  88. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb +38 -0
  89. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb +32 -0
  90. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb +69 -0
  91. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb +31 -0
  92. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb +28 -0
  93. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb +80 -0
  94. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb +23 -0
  95. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb +106 -0
  96. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb +23 -0
  97. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb +33 -0
  98. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb +43 -0
  99. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb +28 -0
  100. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb +37 -0
  101. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb +57 -0
  102. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb +135 -0
  103. data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +131 -0
  104. data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +64 -0
  105. data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +33 -0
  106. data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +53 -0
  107. data/lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb +42 -0
  108. data/lib/ri_cal/property_value/recurrence_rule/validations.rb +125 -0
  109. data/lib/ri_cal/property_value/recurrence_rule.rb +154 -0
  110. data/lib/ri_cal/property_value/text.rb +44 -0
  111. data/lib/ri_cal/property_value/uri.rb +11 -0
  112. data/lib/ri_cal/property_value/utc_offset.rb +33 -0
  113. data/lib/ri_cal/property_value/zulu_date_time.rb +34 -0
  114. data/lib/ri_cal/property_value.rb +159 -0
  115. data/lib/ri_cal/required_timezones.rb +55 -0
  116. data/lib/ri_cal.rb +187 -0
  117. data/parked_specs/ri_cal/claudio_a_bug_spec.rb +100 -0
  118. data/performance/empty_propval/subject.rb +43 -0
  119. data/performance/paris_eastern/subject.rb +90 -0
  120. data/performance/penultimate_weekday/subject.rb +15 -0
  121. data/performance/psm_big_enum/ical.ics +3171 -0
  122. data/performance/psm_big_enum/subject.rb +16 -0
  123. data/performance/utah_cycling/subject.rb +55 -0
  124. data/ri_cal.gemspec +244 -0
  125. data/script/benchmark_subject +23 -0
  126. data/script/console +10 -0
  127. data/script/destroy +14 -0
  128. data/script/generate +14 -0
  129. data/script/profile_subject +29 -0
  130. data/script/txt2html +71 -0
  131. data/spec/ri_cal/bugreports_spec.rb +276 -0
  132. data/spec/ri_cal/component/alarm_spec.rb +12 -0
  133. data/spec/ri_cal/component/calendar_spec.rb +88 -0
  134. data/spec/ri_cal/component/event_spec.rb +735 -0
  135. data/spec/ri_cal/component/freebusy_spec.rb +12 -0
  136. data/spec/ri_cal/component/journal_spec.rb +37 -0
  137. data/spec/ri_cal/component/t_z_info_timezone_spec.rb +60 -0
  138. data/spec/ri_cal/component/timezone_spec.rb +236 -0
  139. data/spec/ri_cal/component/todo_spec.rb +112 -0
  140. data/spec/ri_cal/component_spec.rb +224 -0
  141. data/spec/ri_cal/core_extensions/string/conversions_spec.rb +78 -0
  142. data/spec/ri_cal/core_extensions/time/calculations_spec.rb +188 -0
  143. data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +45 -0
  144. data/spec/ri_cal/fast_date_time_spec.rb +77 -0
  145. data/spec/ri_cal/inf_loop_spec.rb +78 -0
  146. data/spec/ri_cal/occurrence_enumerator_spec.rb +611 -0
  147. data/spec/ri_cal/parser_spec.rb +337 -0
  148. data/spec/ri_cal/property_value/date_spec.rb +53 -0
  149. data/spec/ri_cal/property_value/date_time_spec.rb +383 -0
  150. data/spec/ri_cal/property_value/duration_spec.rb +126 -0
  151. data/spec/ri_cal/property_value/occurrence_list_spec.rb +72 -0
  152. data/spec/ri_cal/property_value/period_spec.rb +63 -0
  153. data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +21 -0
  154. data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1814 -0
  155. data/spec/ri_cal/property_value/text_spec.rb +25 -0
  156. data/spec/ri_cal/property_value/utc_offset_spec.rb +48 -0
  157. data/spec/ri_cal/property_value_spec.rb +125 -0
  158. data/spec/ri_cal/required_timezones_spec.rb +67 -0
  159. data/spec/ri_cal_spec.rb +53 -0
  160. data/spec/spec.opts +4 -0
  161. data/spec/spec_helper.rb +50 -0
  162. data/tasks/gem_loader/load_active_support.rb +3 -0
  163. data/tasks/gem_loader/load_tzinfo_gem.rb +2 -0
  164. data/tasks/ri_cal.rake +412 -0
  165. data/tasks/spec.rake +102 -0
  166. metadata +264 -0
@@ -0,0 +1,383 @@
1
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
4
+ require 'tzinfo'
5
+
6
+ describe RiCal::PropertyValue::DateTime do
7
+ before(:each) do
8
+ @cal = RiCal.Calendar
9
+ end
10
+
11
+ def utc_datetime(string)
12
+ RiCal::PropertyValue::DateTime.new(@cal, :value => "#{string}Z")
13
+ end
14
+
15
+ def local_datetime(string, tzid = "America/New_York")
16
+ RiCal::PropertyValue::DateTime.new(@cal, :value => string, :params => {'TZID' => tzid})
17
+ end
18
+
19
+ context "time_with_zone_methods" do
20
+ context ".utc" do
21
+ context "for a datetime already in zulu time" do
22
+ before(:each) do
23
+ @it = utc_datetime("19970101T012300").utc
24
+ end
25
+
26
+ it "should return the same datetime" do
27
+ @it.should == utc_datetime("19970101T012300")
28
+ end
29
+
30
+ it "should return a result with a tzid of UTC" do
31
+ @it.utc.tzid.should == "UTC"
32
+ end
33
+ end
34
+
35
+ it "should raise an invalid timezone exception if the timezone of the receiver is unknown" do
36
+ lambda {local_datetime("19970101T012300", 'America/Caspian').utc}.should raise_error(RiCal::InvalidTimezoneIdentifier)
37
+ end
38
+
39
+ context "for a datetime with a tzid of America/New_York" do
40
+ before(:each) do
41
+ @it = local_datetime("19970101T012300")
42
+ @it = @it.utc
43
+ end
44
+
45
+ it "should return the equivalent utc time" do
46
+ @it.should == utc_datetime("19970101T062300")
47
+ end
48
+
49
+ it "should return a result with a tzid of UTC" do
50
+ @it.tzid.should == "UTC"
51
+ end
52
+ end
53
+
54
+ context ".in_timezone('America/New_York')" do
55
+
56
+ it "should raise an invalid timezone exception if the timezone of the receiver is unknown" do
57
+ lambda {local_datetime("19970101T012300", 'America/Caspian').in_time_zone('America/New_York')}.should raise_error(RiCal::InvalidTimezoneIdentifier)
58
+ end
59
+
60
+ context "for a datetime 19970101T012300 in zulu time" do
61
+ before(:each) do
62
+ @it = utc_datetime("19970101T012300").in_time_zone('America/New_York')
63
+ end
64
+
65
+ it "should return the 8:23 p. Dec 31, 1996" do
66
+ @it.should == local_datetime("19961231T202300")
67
+ end
68
+
69
+ it "should return a result with a tzid of UTC" do
70
+ @it.tzid.should == "America/New_York"
71
+ end
72
+ end
73
+
74
+ context "for a datetime 19970101T012300 with a tzid of America/New_York" do
75
+ before(:each) do
76
+ @it = local_datetime("19970101T012300").in_time_zone('America/New_York')
77
+ end
78
+
79
+ it "should return the same time" do
80
+ @it.should == local_datetime("19970101T012300")
81
+ end
82
+
83
+ it "should return a result with a tzid of UTC" do
84
+ @it.tzid.should == "America/New_York"
85
+ end
86
+ end
87
+
88
+ context "for a datetime 19970101T012300 with a tzid of America/Chicago" do
89
+ before(:each) do
90
+ @it = local_datetime("19970101T012300", "America/Chicago").in_time_zone('America/New_York')
91
+ end
92
+
93
+ it "should return Jan 1, 1997 02:23 a.m." do
94
+ @it.should == local_datetime("19970101T022300")
95
+ end
96
+
97
+ it "should return a result with a tzid of America/New_York" do
98
+ @it.tzid.should == "America/New_York"
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ context "for a datetime from an imported calendar" do
105
+
106
+ before(:each) do
107
+ cals = RiCal.parse_string <<-END_OF_DATA
108
+ BEGIN:VCALENDAR
109
+ METHOD:PUBLISH
110
+ X-WR-TIMEZONE:America/New_York
111
+ PRODID:-//Apple Inc.//iCal 3.0//EN
112
+ CALSCALE:GREGORIAN
113
+ X-WR-CALNAME:Test
114
+ VERSION:2.0
115
+ X-WR-RELCALID:58DB0663-196B-4B6B-A05A-A53049661280
116
+ X-APPLE-CALENDAR-COLOR:#0252D4
117
+ BEGIN:VTIMEZONE
118
+ TZID:Europe/Paris
119
+ BEGIN:DAYLIGHT
120
+ TZOFFSETFROM:+0100
121
+ TZOFFSETTO:+0200
122
+ DTSTART:19810329T020000
123
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
124
+ TZNAME:CEST
125
+ END:DAYLIGHT
126
+ BEGIN:STANDARD
127
+ TZOFFSETFROM:+0200
128
+ TZOFFSETTO:+0100
129
+ DTSTART:19961027T030000
130
+ RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
131
+ TZNAME:CET
132
+ END:STANDARD
133
+ END:VTIMEZONE
134
+ BEGIN:VTIMEZONE
135
+ TZID:US/Eastern
136
+ BEGIN:DAYLIGHT
137
+ TZOFFSETFROM:-0500
138
+ TZOFFSETTO:-0400
139
+ DTSTART:20070311T020000
140
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
141
+ TZNAME:EDT
142
+ END:DAYLIGHT
143
+ BEGIN:STANDARD
144
+ TZOFFSETFROM:-0400
145
+ TZOFFSETTO:-0500
146
+ DTSTART:20071104T020000
147
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
148
+ TZNAME:EST
149
+ END:STANDARD
150
+ END:VTIMEZONE
151
+ BEGIN:VEVENT
152
+ SEQUENCE:3
153
+ TRANSP:OPAQUE
154
+ UID:AC2EFB19-A8A8-49EF-929F-CA0975374ED6
155
+ DTSTART:20090501T000000Z
156
+ DTSTAMP:20090501T174405Z
157
+ SUMMARY:UTC Event
158
+ CREATED:20090501T174347Z
159
+ DTEND:20090501T010000Z
160
+ END:VEVENT
161
+ BEGIN:VEVENT
162
+ SEQUENCE:2
163
+ TRANSP:OPAQUE
164
+ UID:A5517A09-C53E-4E1F-A642-EA47680BF2B6
165
+ DTSTART;TZID=US/Eastern:20090430T140000
166
+ DTSTAMP:20090501T174428Z
167
+ SUMMARY:Eastern Event
168
+ CREATED:20090501T174415Z
169
+ DTEND;TZID=US/Eastern:20090430T150000
170
+ END:VEVENT
171
+ BEGIN:VEVENT
172
+ SEQUENCE:3
173
+ TRANSP:OPAQUE
174
+ UID:B5024763-9197-4A60-A96E-D8D59D578BB2
175
+ DTSTART;TZID=Europe/Paris:20090430T140000
176
+ DTSTAMP:20090501T174509Z
177
+ SUMMARY:Paris Event
178
+ CREATED:20090501T174439Z
179
+ DTEND;TZID=Europe/Paris:20090430T150000
180
+ END:VEVENT
181
+ END:VCALENDAR
182
+ END_OF_DATA
183
+ @cal = cals.first
184
+ end
185
+
186
+ def find_event(summary)
187
+ @cal.events.find {|event| event.summary == summary}
188
+ end
189
+
190
+ context ".utc" do
191
+
192
+ it "should raise an invalid timezone exception if the timezone of the receiver is not in the calendar" do
193
+ lambda {local_datetime("19970101T012300", 'America/New_York').utc}.should raise_error(RiCal::InvalidTimezoneIdentifier)
194
+ end
195
+
196
+ context "for the DTSTART of the UTC Event" do
197
+ before(:each) do
198
+ @it = find_event("UTC Event").dtstart_property.utc
199
+ end
200
+
201
+ it "should return the same datetime" do
202
+ @it.should == utc_datetime("20090501T000000")
203
+ end
204
+
205
+ it "should return a result with a tzid of UTC" do
206
+ @it.utc.tzid.should == "UTC"
207
+ end
208
+ end
209
+
210
+ context "for the DTSTART of the Eastern Event" do
211
+ before(:each) do
212
+ @it = find_event("Eastern Event").dtstart_property.utc
213
+ end
214
+
215
+ it "should return the equivalent utc time" do
216
+ @it.should == utc_datetime("20090430T180000")
217
+ end
218
+
219
+ it "should return a result with a tzid of UTC" do
220
+ @it.tzid.should == "UTC"
221
+ end
222
+ end
223
+ end
224
+
225
+ context ".in_timezone('US/Eastern')" do
226
+
227
+ it "should raise an invalid timezone exception if the timezone of the receiver is not in the calendar" do
228
+ lambda {local_datetime("19970101T012300", 'America/New_York').in_time_zone("US/Eastern")}.should raise_error(RiCal::InvalidTimezoneIdentifier)
229
+ end
230
+
231
+ context "for the DTSTART of the UTC Event" do
232
+ before(:each) do
233
+ @it = find_event("UTC Event").dtstart_property.in_time_zone("US/Eastern")
234
+ end
235
+
236
+ it "should return 8:00 p.m. Apr 30, 2009" do
237
+ @it.should == local_datetime("20090430T2000000", "US/Eastern")
238
+ end
239
+
240
+ it "should return a result with a tzid of US/Eastern" do
241
+ @it.tzid.should == "US/Eastern"
242
+ end
243
+ end
244
+
245
+ context "for the DTSTART of the Eastern Event" do
246
+ before(:each) do
247
+ @it = find_event("Eastern Event").dtstart_property.in_time_zone("US/Eastern")
248
+ end
249
+
250
+ it "should return the same time" do
251
+ @it.should == local_datetime("20090430T140000", "US/Eastern")
252
+ end
253
+
254
+ it "should return a result with a tzid of UTC" do
255
+ @it.tzid.should == "US/Eastern"
256
+ end
257
+ end
258
+
259
+ context "for the DTSTART of the Paris Event" do
260
+ before(:each) do
261
+ @it = find_event("Paris Event").dtstart_property.in_time_zone("US/Eastern")
262
+ end
263
+
264
+ it "should return 8:00 a.m. on Apr 30, 2009" do
265
+ @it.should == local_datetime("20090430T080000", "US/Eastern")
266
+ end
267
+
268
+ it "should return a result with a tzid of US/Eastern" do
269
+ @it.tzid.should == "US/Eastern"
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
275
+
276
+ context ".from_separated_line" do
277
+ it "should return a RiCal::PropertyValue::Date if the value doesn't contain a time specification" do
278
+ RiCal::PropertyValue::DateTime.or_date(nil, :value => "19970714").should be_kind_of(RiCal::PropertyValue::Date)
279
+ end
280
+
281
+ it "should return a RiCal::PropertyValue::DateTime if the value does contain a time specification" do
282
+ RiCal::PropertyValue::DateTime.or_date(nil, :value => "19980118T230000").should be_kind_of(RiCal::PropertyValue::DateTime)
283
+ end
284
+ end
285
+
286
+ context ".advance" do
287
+ it "should advance by one week if passed :days => 7" do
288
+ dt1 = RiCal::PropertyValue::DateTime.new(nil, :value => "20050131T230000")
289
+ dt2 = RiCal::PropertyValue::DateTime.new(nil, :value => "20050207T230000")
290
+ dt1.advance(:days => 7).should == dt2
291
+ end
292
+ end
293
+
294
+ context "subtracting one date-time from another" do
295
+
296
+ it "should produce the right RiCal::PropertyValue::Duration" do
297
+ dt1 = RiCal::PropertyValue::DateTime.new(nil, :value => "19980118T230000")
298
+ dt2 = RiCal::PropertyValue::DateTime.new(nil, :value => "19980119T010000")
299
+ @it = dt2 - dt1
300
+ @it.should == RiCal::PropertyValue::Duration.new(nil, :value => "+PT2H")
301
+ end
302
+ end
303
+
304
+ context "adding a RiCal::PropertyValue::Duration to a RiCal::PropertyValue::DateTime" do
305
+
306
+ it "should produce the right RiCal::PropertyValue::DateTime" do
307
+ dt1 = RiCal::PropertyValue::DateTime.new(nil, :value => "19980118T230000")
308
+ duration = RiCal::PropertyValue::Duration.new(nil, :value => "+PT2H")
309
+ @it = dt1 + duration
310
+ @it.should == RiCal::PropertyValue::DateTime.new(nil, :value => "19980119T010000")
311
+ end
312
+ end
313
+
314
+ context "subtracting a RiCal::PropertyValue::Duration from a RiCal::PropertyValue::DateTime" do
315
+
316
+ it "should produce the right RiCal::PropertyValue::DateTime" do
317
+ dt1 = RiCal::PropertyValue::DateTime.new(nil, :value => "19980119T010000")
318
+ duration = RiCal::PropertyValue::Duration.new(nil, :value => "+PT2H")
319
+ @it = dt1 - duration
320
+ @it.should == RiCal::PropertyValue::DateTime.new(nil, :value => "19980118T230000")
321
+ end
322
+ end
323
+ context "when setting the default timezone identifier" do
324
+
325
+ before(:each) do
326
+ RiCal::PropertyValue::DateTime.default_tzid = "America/Chicago"
327
+ @time = Time.mktime(2009,2,5,19,17,11)
328
+ @it = RiCal::PropertyValue::DateTime.convert(nil, @time)
329
+ end
330
+
331
+ after(:each) do
332
+ RiCal::PropertyValue::DateTime.default_tzid = "UTC"
333
+ end
334
+
335
+ it "should update the default timezone to America/Chicago" do
336
+ @it.params.should == {'TZID' => 'America/Chicago'}
337
+ end
338
+
339
+ it "should not have a tzid when default_tzid is :floating" do
340
+ RiCal::PropertyValue::DateTime.default_tzid = :floating
341
+ dt = RiCal::PropertyValue::DateTime.convert(nil, @time)
342
+ dt.params.should == {}
343
+ end
344
+ end
345
+
346
+ context ".convert(rubyobject)" do
347
+ describe "for a Time instance of Feb 05 19:17:11"
348
+ before(:each) do
349
+ @time = Time.mktime(2009,2,5,19,17,11)
350
+ end
351
+
352
+ context "with a normal a normal time instance" do
353
+ describe "when the default timezone identifier is UTC" do
354
+ before(:each) do
355
+ @it = RiCal::PropertyValue::DateTime.convert(nil, @time)
356
+ end
357
+
358
+ it "should have a TZID of UTC" do
359
+ @it.tzid.should == 'UTC'
360
+ end
361
+
362
+ it "should have the right value" do
363
+ @it.value.should == "20090205T191711Z"
364
+ end
365
+ end
366
+
367
+ context "when the default timezone has been set to 'America/Chicago" do
368
+ before(:each) do
369
+ RiCal::PropertyValue::DateTime.stub!(:default_tzid).and_return("America/Chicago")
370
+ @it = RiCal::PropertyValue::DateTime.convert(nil, @time)
371
+ end
372
+
373
+ it "should have a TZID of America/Chicago" do
374
+ @it.tzid.should == 'America/Chicago'
375
+ end
376
+
377
+ it "should have the right value" do
378
+ @it.value.should == "20090205T191711"
379
+ end
380
+ end
381
+ end
382
+ end
383
+ end
@@ -0,0 +1,126 @@
1
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
4
+ require 'date'
5
+
6
+ describe RiCal::PropertyValue::Duration do
7
+
8
+ context "with various values" do
9
+ def value_expectations(dv, values = {})
10
+ values = {:weeks => 0, :days => 0, :hours => 0, :minutes => 0, :seconds => 0}.merge(values)
11
+ dv.weeks.should == values[:weeks]
12
+ dv.days.should == values[:days]
13
+ dv.hours.should == values[:hours]
14
+ dv.minutes.should == values[:minutes]
15
+ dv.seconds.should == values[:seconds]
16
+ end
17
+
18
+ it ".+P7W should have represent 7 weeks" do
19
+ value_expectations(RiCal::PropertyValue::Duration.new(nil, :value => "+P7W"), :weeks => 7)
20
+ end
21
+
22
+ it ".P15DT5H0M20S should have represent 15 days, 5 hours and 20 seconds" do
23
+ value_expectations(RiCal::PropertyValue::Duration.new(nil, :value => "P15DT5H0M20S"), :days => 15, :hours => 5, :seconds => 20)
24
+ end
25
+
26
+ it ".+P2D should have represent 2 days" do
27
+ value_expectations(RiCal::PropertyValue::Duration.new(nil, :value => "+P2D"), :days => 2)
28
+ end
29
+
30
+ it ".+PT3H should have represent 3 hours" do
31
+ value_expectations(RiCal::PropertyValue::Duration.new(nil, :value => "+PT3H"), :hours => 3)
32
+ end
33
+
34
+ it ".+PT15M should have represent 15 minutes" do
35
+ value_expectations(RiCal::PropertyValue::Duration.new(nil, :value => "+PT15M"), :minutes => 15)
36
+ end
37
+
38
+ it ".+PT45S should have represent 45 seconds" do
39
+ value_expectations(RiCal::PropertyValue::Duration.new(nil, :value => "+PT45S"), :seconds => 45)
40
+ end
41
+ end
42
+
43
+ context ".==" do
44
+ it "should return true for two durations of one day" do
45
+ RiCal::PropertyValue.new(nil, :value => "+P1D").should == RiCal::PropertyValue.new(nil, :value => "+P1D")
46
+ end
47
+ end
48
+
49
+ context ".from_datetimes" do
50
+
51
+ context "starting at 11:00 pm, and ending at 1:01:02 am the next day" do
52
+ before(:each) do
53
+ @it = RiCal::PropertyValue::Duration.from_datetimes(nil,
54
+ DateTime.parse("Sep 1, 2008 23:00"),
55
+ DateTime.parse("Sep 2, 2008 1:01:02")
56
+ )
57
+ end
58
+
59
+ it "should produce a duration" do
60
+ @it.class.should == RiCal::PropertyValue::Duration
61
+ end
62
+
63
+ it "should have a value of '+P2H1M2S'" do
64
+ @it.value.should == '+PT2H1M2S'
65
+ end
66
+
67
+ it "should contain zero days" do
68
+ @it.days.should == 0
69
+ end
70
+
71
+ it "should contain two hours" do
72
+ @it.hours.should == 2
73
+ end
74
+
75
+ it "should contain one minute" do
76
+ @it.minutes.should == 1
77
+ end
78
+
79
+ it "should contain one minute" do
80
+ @it.minutes.should == 1
81
+ end
82
+ end
83
+
84
+ context "starting at 00:00, and ending at 00:00 the next day" do
85
+ before(:each) do
86
+ @it = RiCal::PropertyValue::Duration.from_datetimes(nil,
87
+ DateTime.parse("Sep 1, 2008 00:00"),
88
+ DateTime.parse("Sep 2, 2008 00:00")
89
+ )
90
+ end
91
+
92
+ it "should produce a duration" do
93
+ @it.class.should == RiCal::PropertyValue::Duration
94
+ end
95
+
96
+ it "should have a value of '+P1D'" do
97
+ @it.value.should == '+P1D'
98
+ end
99
+
100
+ it "should contain zero days" do
101
+ @it.days.should == 1
102
+ end
103
+
104
+ it "should contain zero hours" do
105
+ @it.hours.should == 0
106
+ end
107
+
108
+ it "should contain zero minutes" do
109
+ @it.minutes.should == 0
110
+ end
111
+
112
+ it "should contain zero minutes" do
113
+ @it.minutes.should == 0
114
+ end
115
+ end
116
+
117
+ it "should work when start > finish" do
118
+ lambda {
119
+ RiCal::PropertyValue::Duration.from_datetimes(nil,
120
+ DateTime.parse("Sep 2, 2008 1:01:02"),
121
+ DateTime.parse("Sep 1, 2008 23:00")
122
+ )
123
+ }.should_not raise_error(ArgumentError)
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,72 @@
1
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
4
+
5
+ describe RiCal::PropertyValue::OccurrenceList do
6
+
7
+ context ".convert method" do
8
+ context "with a single datetime" do
9
+ before(:each) do
10
+ @it = RiCal::PropertyValue::OccurrenceList.convert(nil, DateTime.parse("5 May 2009, 9:32 am"))
11
+ end
12
+
13
+ it "should produce the right ical representation" do
14
+ @it.to_s.should == ":20090505T093200Z"
15
+ end
16
+
17
+ it "should have the right ruby value" do
18
+ @it.ruby_value.should == [DateTime.parse("5 May 2009, 9:32 am")]
19
+ end
20
+
21
+ it "should have the right elements" do
22
+ @it.send(:elements).should == [RiCal::PropertyValue::DateTime.new(nil, :value => "20090505T093200Z" )]
23
+ end
24
+ end
25
+
26
+ context "with conflicting timezones" do
27
+ before(:each) do
28
+ @event = RiCal.Event
29
+ end
30
+
31
+ it "should raise an InvalidPropertyValue if an argument does not match an explicit time zone" do
32
+ lambda {RiCal::PropertyValue::OccurrenceList.convert(@event, "America/New_York", Time.now.set_tzid("America/Chicago"))}.should raise_error(RiCal::InvalidPropertyValue)
33
+ end
34
+
35
+ it "should raise an InvalidPropertyValue if the arguments have mixed time zones" do
36
+ lambda {RiCal::PropertyValue::OccurrenceList.convert(@event, Time.now.set_tzid("America/New_York"), Time.now.set_tzid("America/Chicago"))}.should raise_error(RiCal::InvalidPropertyValue)
37
+ end
38
+ end
39
+
40
+ context "with a tzid and a single datetime" do
41
+ before(:each) do
42
+ timezone = mock("Timezone",
43
+ :rational_utc_offset => Rational(-5, 24),
44
+ :local_to_utc => RiCal::PropertyValue.date_or_date_time(nil, :value => "19620220T194739"),
45
+ :name => 'America/New_York'
46
+ )
47
+
48
+ timezone_finder = mock("tz_finder", :find_timezone => timezone, :default_tzid => "UTC", :tz_info_source? => true)
49
+ @it = RiCal::PropertyValue::OccurrenceList.convert(timezone_finder, 'America/New_York', "19620220T144739")
50
+ end
51
+
52
+ it "should produce the right ical representation" do
53
+ @it.to_s.should == ";TZID=America/New_York:19620220T144739"
54
+ end
55
+
56
+ context "its ruby value" do
57
+
58
+ it "should be the right DateTime" do
59
+ @it.ruby_value.should == [result_time_in_zone(1962, 2, 20, 14, 47, 39, 'America/New_York')]
60
+ end
61
+
62
+ it "should have the right tzid" do
63
+ @it.ruby_value.first.tzid.should == "America/New_York"
64
+ end
65
+ end
66
+
67
+ it "should have the right elements" do
68
+ @it.send(:elements).should == [RiCal::PropertyValue::DateTime.new(nil, :params=> {'TZID' => 'America/New_York'}, :value => "19620220T144739" )]
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,63 @@
1
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
4
+
5
+ # RFC 2445 Section 4.3.9 pp 39-40
6
+ describe RiCal::PropertyValue::Period do
7
+
8
+ before(:each) do
9
+ @start_dt = RiCal::PropertyValue::DateTime.new(nil, :value => "19970101T180000Z")
10
+ @end_dt = RiCal::PropertyValue::DateTime.new(nil, :value => "19970102T070000Z")
11
+ @duration = RiCal::PropertyValue::Duration.from_datetimes(nil, @start_dt.to_datetime, @end_dt.to_datetime)
12
+ end
13
+
14
+ describe "with an explicit period" do
15
+ before(:each) do
16
+ @value_string = "#{@start_dt.value}/#{@end_dt.value}"
17
+ @it = RiCal::PropertyValue::Period.new(nil, :value => @value_string)
18
+ end
19
+
20
+ it "should have the correct dtstart value" do
21
+ @it.dtstart.should == @start_dt
22
+ end
23
+
24
+ it "should have the correct dtend value" do
25
+ @it.dtend.should == @end_dt
26
+ end
27
+
28
+ it "should have the correct duration value" do
29
+ @it.duration.should == @duration
30
+ end
31
+
32
+ it "should have the correct string value" do
33
+ @it.to_s.should == ":#{@value_string}"
34
+ end
35
+
36
+ it "should be its own ruby_value" do
37
+ @it.ruby_value.should == @it
38
+ end
39
+ end
40
+
41
+ describe "with a start time and period" do
42
+ before(:each) do
43
+ @value_string = "#{@start_dt.value}/#{@duration.value}"
44
+ @it = RiCal::PropertyValue::Period.new(nil, :value => @value_string)
45
+ end
46
+
47
+ it "should have the correct dtstart value" do
48
+ @it.dtstart.should == @start_dt
49
+ end
50
+
51
+ it "should have the correct dtend value" do
52
+ @it.dtend.should == @end_dt
53
+ end
54
+
55
+ it "should have the correct duration value" do
56
+ @it.duration.should == @duration
57
+ end
58
+
59
+ it "should have the correct string value" do
60
+ @it.to_s.should == ":#{@value_string}"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. .. .. spec_helper])
4
+
5
+ describe RiCal::PropertyValue::RecurrenceRule::RecurringYearDay do
6
+
7
+ def set_it(which, rule=nil)
8
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(which, rule)
9
+ end
10
+
11
+ def time_property(str)
12
+ RiCal::PropertyValue.date_or_date_time(nil, :value => str)
13
+ end
14
+
15
+ describe ".matches_for(time)" do
16
+
17
+ it "should return an array containing January 1, in the times year for the the 1st day" do
18
+ set_it(1).matches_for(time_property("19970603T090000")).should == [time_property("19970101T090000")]
19
+ end
20
+ end
21
+ end