demingfactor-ri_cal 0.9.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 (167) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +402 -0
  3. data/Manifest.txt +161 -0
  4. data/README.txt +410 -0
  5. data/Rakefile +69 -0
  6. data/VERSION +1 -0
  7. data/bin/ri_cal +8 -0
  8. data/component_attributes/alarm.yml +10 -0
  9. data/component_attributes/calendar.yml +4 -0
  10. data/component_attributes/component_property_defs.yml +180 -0
  11. data/component_attributes/event.yml +45 -0
  12. data/component_attributes/freebusy.yml +16 -0
  13. data/component_attributes/journal.yml +35 -0
  14. data/component_attributes/timezone.yml +3 -0
  15. data/component_attributes/timezone_period.yml +11 -0
  16. data/component_attributes/todo.yml +46 -0
  17. data/copyrights.txt +1 -0
  18. data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
  19. data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
  20. data/docs/incrementers.txt +7 -0
  21. data/docs/rfc2445.pdf +0 -0
  22. data/lib/ri_cal/component/alarm.rb +19 -0
  23. data/lib/ri_cal/component/calendar.rb +257 -0
  24. data/lib/ri_cal/component/event.rb +58 -0
  25. data/lib/ri_cal/component/freebusy.rb +16 -0
  26. data/lib/ri_cal/component/journal.rb +27 -0
  27. data/lib/ri_cal/component/non_standard.rb +33 -0
  28. data/lib/ri_cal/component/t_z_info_timezone.rb +153 -0
  29. data/lib/ri_cal/component/timezone/daylight_period.rb +25 -0
  30. data/lib/ri_cal/component/timezone/standard_period.rb +23 -0
  31. data/lib/ri_cal/component/timezone/timezone_period.rb +76 -0
  32. data/lib/ri_cal/component/timezone.rb +197 -0
  33. data/lib/ri_cal/component/todo.rb +42 -0
  34. data/lib/ri_cal/component.rb +256 -0
  35. data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
  36. data/lib/ri_cal/core_extensions/array.rb +7 -0
  37. data/lib/ri_cal/core_extensions/date/conversions.rb +56 -0
  38. data/lib/ri_cal/core_extensions/date.rb +13 -0
  39. data/lib/ri_cal/core_extensions/date_time/conversions.rb +50 -0
  40. data/lib/ri_cal/core_extensions/date_time.rb +15 -0
  41. data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
  42. data/lib/ri_cal/core_extensions/object.rb +8 -0
  43. data/lib/ri_cal/core_extensions/string/conversions.rb +57 -0
  44. data/lib/ri_cal/core_extensions/string.rb +8 -0
  45. data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
  46. data/lib/ri_cal/core_extensions/time/conversions.rb +42 -0
  47. data/lib/ri_cal/core_extensions/time/tzid_access.rb +50 -0
  48. data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +55 -0
  49. data/lib/ri_cal/core_extensions/time.rb +14 -0
  50. data/lib/ri_cal/core_extensions.rb +11 -0
  51. data/lib/ri_cal/fast_date_time.rb +234 -0
  52. data/lib/ri_cal/floating_timezone.rb +32 -0
  53. data/lib/ri_cal/invalid_property_value.rb +8 -0
  54. data/lib/ri_cal/invalid_timezone_identifier.rb +20 -0
  55. data/lib/ri_cal/occurrence_enumerator.rb +265 -0
  56. data/lib/ri_cal/occurrence_period.rb +17 -0
  57. data/lib/ri_cal/parser.rb +148 -0
  58. data/lib/ri_cal/properties/alarm.rb +390 -0
  59. data/lib/ri_cal/properties/calendar.rb +164 -0
  60. data/lib/ri_cal/properties/event.rb +1523 -0
  61. data/lib/ri_cal/properties/freebusy.rb +593 -0
  62. data/lib/ri_cal/properties/journal.rb +1237 -0
  63. data/lib/ri_cal/properties/timezone.rb +150 -0
  64. data/lib/ri_cal/properties/timezone_period.rb +416 -0
  65. data/lib/ri_cal/properties/todo.rb +1559 -0
  66. data/lib/ri_cal/properties.rb +12 -0
  67. data/lib/ri_cal/property_value/array.rb +27 -0
  68. data/lib/ri_cal/property_value/cal_address.rb +11 -0
  69. data/lib/ri_cal/property_value/date.rb +184 -0
  70. data/lib/ri_cal/property_value/date_time/additive_methods.rb +44 -0
  71. data/lib/ri_cal/property_value/date_time/time_machine.rb +159 -0
  72. data/lib/ri_cal/property_value/date_time/timezone_support.rb +100 -0
  73. data/lib/ri_cal/property_value/date_time.rb +359 -0
  74. data/lib/ri_cal/property_value/duration.rb +110 -0
  75. data/lib/ri_cal/property_value/geo.rb +11 -0
  76. data/lib/ri_cal/property_value/integer.rb +12 -0
  77. data/lib/ri_cal/property_value/occurrence_list.rb +144 -0
  78. data/lib/ri_cal/property_value/period.rb +86 -0
  79. data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +100 -0
  80. data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +79 -0
  81. data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +148 -0
  82. data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +53 -0
  83. data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +31 -0
  84. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb +86 -0
  85. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb +31 -0
  86. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb +32 -0
  87. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb +52 -0
  88. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb +31 -0
  89. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb +38 -0
  90. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb +32 -0
  91. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb +69 -0
  92. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb +31 -0
  93. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb +28 -0
  94. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb +80 -0
  95. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb +23 -0
  96. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb +106 -0
  97. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb +23 -0
  98. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb +33 -0
  99. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb +43 -0
  100. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb +28 -0
  101. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb +37 -0
  102. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb +57 -0
  103. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb +135 -0
  104. data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +131 -0
  105. data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +64 -0
  106. data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +33 -0
  107. data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +53 -0
  108. data/lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb +42 -0
  109. data/lib/ri_cal/property_value/recurrence_rule/validations.rb +125 -0
  110. data/lib/ri_cal/property_value/recurrence_rule.rb +154 -0
  111. data/lib/ri_cal/property_value/text.rb +44 -0
  112. data/lib/ri_cal/property_value/uri.rb +11 -0
  113. data/lib/ri_cal/property_value/utc_offset.rb +33 -0
  114. data/lib/ri_cal/property_value/zulu_date_time.rb +34 -0
  115. data/lib/ri_cal/property_value.rb +159 -0
  116. data/lib/ri_cal/required_timezones.rb +55 -0
  117. data/lib/ri_cal.rb +187 -0
  118. data/parked_specs/ri_cal/claudio_a_bug_spec.rb +100 -0
  119. data/performance/empty_propval/subject.rb +43 -0
  120. data/performance/paris_eastern/subject.rb +90 -0
  121. data/performance/penultimate_weekday/subject.rb +15 -0
  122. data/performance/psm_big_enum/ical.ics +3171 -0
  123. data/performance/psm_big_enum/subject.rb +16 -0
  124. data/performance/utah_cycling/subject.rb +55 -0
  125. data/ri_cal.gemspec +244 -0
  126. data/script/benchmark_subject +23 -0
  127. data/script/console +10 -0
  128. data/script/destroy +14 -0
  129. data/script/generate +14 -0
  130. data/script/profile_subject +29 -0
  131. data/script/txt2html +71 -0
  132. data/spec/ri_cal/bugreports_spec.rb +276 -0
  133. data/spec/ri_cal/component/alarm_spec.rb +12 -0
  134. data/spec/ri_cal/component/calendar_spec.rb +88 -0
  135. data/spec/ri_cal/component/event_spec.rb +735 -0
  136. data/spec/ri_cal/component/freebusy_spec.rb +12 -0
  137. data/spec/ri_cal/component/journal_spec.rb +37 -0
  138. data/spec/ri_cal/component/t_z_info_timezone_spec.rb +60 -0
  139. data/spec/ri_cal/component/timezone_spec.rb +236 -0
  140. data/spec/ri_cal/component/todo_spec.rb +112 -0
  141. data/spec/ri_cal/component_spec.rb +224 -0
  142. data/spec/ri_cal/core_extensions/string/conversions_spec.rb +78 -0
  143. data/spec/ri_cal/core_extensions/time/calculations_spec.rb +188 -0
  144. data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +45 -0
  145. data/spec/ri_cal/fast_date_time_spec.rb +77 -0
  146. data/spec/ri_cal/inf_loop_spec.rb +78 -0
  147. data/spec/ri_cal/occurrence_enumerator_spec.rb +611 -0
  148. data/spec/ri_cal/parser_spec.rb +337 -0
  149. data/spec/ri_cal/property_value/date_spec.rb +53 -0
  150. data/spec/ri_cal/property_value/date_time_spec.rb +383 -0
  151. data/spec/ri_cal/property_value/duration_spec.rb +126 -0
  152. data/spec/ri_cal/property_value/occurrence_list_spec.rb +72 -0
  153. data/spec/ri_cal/property_value/period_spec.rb +63 -0
  154. data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +21 -0
  155. data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1814 -0
  156. data/spec/ri_cal/property_value/text_spec.rb +25 -0
  157. data/spec/ri_cal/property_value/utc_offset_spec.rb +48 -0
  158. data/spec/ri_cal/property_value_spec.rb +125 -0
  159. data/spec/ri_cal/required_timezones_spec.rb +67 -0
  160. data/spec/ri_cal_spec.rb +53 -0
  161. data/spec/spec.opts +4 -0
  162. data/spec/spec_helper.rb +50 -0
  163. data/tasks/gem_loader/load_active_support.rb +3 -0
  164. data/tasks/gem_loader/load_tzinfo_gem.rb +2 -0
  165. data/tasks/ri_cal.rake +412 -0
  166. data/tasks/spec.rake +102 -0
  167. metadata +246 -0
@@ -0,0 +1,337 @@
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::Parser do
6
+
7
+ context ".separate_line" do
8
+ it "should work" do
9
+ RiCal::Parser.new.separate_line("DTSTART;TZID=America/New_York:20090804T120000").should == {
10
+ :name => "DTSTART",
11
+ :params => {"TZID" => "America/New_York"},
12
+ :value => "20090804T120000"
13
+ }
14
+ end
15
+ end
16
+
17
+ context ".params_and_value" do
18
+ it "should separate parameters and values" do
19
+ RiCal::Parser.params_and_value(";TZID=(GMT-05.00) Eastern Time (US & Canada):20090804T120000").should == [{"TZID" => "(GMT-05.00) Eastern Time (US & Canada)"}, "20090804T120000"]
20
+ end
21
+
22
+ it "should strip surrounding quotes" do
23
+ RiCal::Parser.params_and_value(";TZID=\"(GMT-05.00) Eastern Time (US & Canada)\":20090804T120000").should == [{"TZID" => "(GMT-05.00) Eastern Time (US & Canada)"}, "20090804T120000"]
24
+ end
25
+ end
26
+
27
+ def self.describe_property(entity_name, prop_name, params, value, type = RiCal::PropertyValue::Text)
28
+ describe_named_property(entity_name, prop_name, prop_name, params, value, false, type)
29
+ end
30
+
31
+ def self.describe_multi_property(entity_name, prop_name, params, value, type = RiCal::PropertyValue::Text)
32
+ describe_named_property(entity_name, prop_name, prop_name, params, value, true, type)
33
+ end
34
+
35
+ def self.describe_named_property(entity_name, prop_text, prop_name, params, value, multi, type = RiCal::PropertyValue::Text)
36
+ ruby_value_name = prop_name.tr("-", "_").downcase
37
+ ruby_prop_name = "#{prop_text.tr('-', '_').downcase}_property"
38
+ expected_ruby_value = type.convert(nil, value).ruby_value
39
+ expected_params = {}
40
+ params.each do |key, parm_value|
41
+ # strip surrounding quotes from values
42
+ expected_params[key] = parm_value.sub(/^\"(.*)\"$/, '\1')
43
+ end
44
+
45
+ describe "#{prop_name} with value of #{value.inspect}" do
46
+ parse_input = params.inject("BEGIN:#{entity_name.upcase}\n#{prop_text.upcase}") { |pi, assoc| "#{pi};#{assoc[0]}=#{assoc[1]}"}
47
+ parse_input = "#{parse_input}:#{value.to_rfc2445_string}\nEND:#{entity_name.upcase}"
48
+
49
+ it "should parse an event with an #{prop_text.upcase} property" do
50
+ lambda {RiCal::Parser.parse(StringIO.new(parse_input))}.should_not raise_error
51
+ end
52
+
53
+ describe "property characteristics" do
54
+ before(:each) do
55
+ @entity = RiCal::Parser.parse(StringIO.new(parse_input)).first
56
+ @prop = @entity.send(ruby_prop_name.to_sym)
57
+ if multi && Array === @prop
58
+ @prop = @prop.first
59
+ end
60
+ end
61
+
62
+ it "should be a #{type.name}" do
63
+ @prop.class.should == type
64
+ end
65
+
66
+ it "should have the right value" do
67
+ @prop.value.should == value
68
+ end
69
+
70
+ it "should make the value accessible directly" do
71
+ val = @entity.send(ruby_value_name)
72
+ val = val.first if multi && Array === val
73
+ val.should == expected_ruby_value
74
+ end
75
+
76
+ it "should have the right parameters" do
77
+ expected_params.each do | key, value |
78
+ @prop.params[key].should == value
79
+ end
80
+ end
81
+ end
82
+
83
+ end
84
+ end
85
+
86
+ describe ".next_line" do
87
+ it "should return line by line" do
88
+ RiCal::Parser.new(StringIO.new("abc\ndef")).next_line.should == "abc"
89
+ end
90
+
91
+ it "should combine lines" do
92
+ RiCal::Parser.new(StringIO.new("abc\n def\n ghi")).next_line.should == "abcdef ghi"
93
+ end
94
+ end
95
+
96
+ describe ".separate_line" do
97
+
98
+ before(:each) do
99
+ @parser = RiCal::Parser.new
100
+ end
101
+
102
+ it "should return a hash" do
103
+ @parser.separate_line("abc;x=y;z=1,2:value").should be_kind_of(Hash)
104
+ end
105
+
106
+ it "should find the name" do
107
+ @parser.separate_line("abc;x=y;z=1,2:value")[:name].should == "abc"
108
+ end
109
+
110
+ it "should find the parameters" do
111
+ @parser.separate_line("abc;x=y;z=1,2:value")[:params].should == {"x" => "y","z" => "1,2"}
112
+ end
113
+
114
+ it "should find the value" do
115
+ @parser.separate_line("abc;x=y;z=1,2:value")[:value].should == "value"
116
+ end
117
+ end
118
+
119
+ describe ".parse" do
120
+
121
+ it "should reject a file which doesn't start with BEGIN" do
122
+ parser = RiCal::Parser.new(StringIO.new("END:VCALENDAR"))
123
+ lambda {parser.parse}.should raise_error
124
+ end
125
+
126
+ describe "parsing an event" do
127
+ it "should parse an event" do
128
+ parser = RiCal::Parser.new(StringIO.new("BEGIN:VEVENT"))
129
+ RiCal::Component::Event.should_receive(:from_parser).with(parser, nil, "VEVENT")
130
+ parser.parse
131
+ end
132
+
133
+ it "should parse an event and return a Event" do
134
+ cal = RiCal::Parser.parse(StringIO.new("BEGIN:VEVENT\nEND:VEVENT")).first
135
+ cal.should be_kind_of(RiCal::Component::Event)
136
+ end
137
+
138
+ #RFC 2445 section 4.8.1.1 pp 77
139
+ describe_multi_property("VEVENT", "ATTACH", {"FMTTYPE" => "application/postscript"}, "FMTTYPE=application/postscript:ftp//xyzCorp.com/put/reports/r-960812.ps", RiCal::PropertyValue::Uri)
140
+
141
+ #RFC 2445 section 4.8.1.2 pp 78
142
+ describe_multi_property("VEVENT", "CATEGORIES", {"LANGUAGE" => "us-EN"}, "APPOINTMENT,EDUCATION", RiCal::PropertyValue::Array)
143
+
144
+ #RFC 2445 section 4.8.1.3 pp 79
145
+ describe_named_property("VEVENT", "CLASS", "security_class", {"X-FOO" => "BAR"}, "PUBLIC", false)
146
+
147
+ #RFC 2445 section 4.8.1.4 pp 80
148
+ describe_multi_property("VEVENT", "COMMENT", {"X-FOO" => "BAR"}, "Event comment")
149
+
150
+ #RFC 2445 section 4.8.1.5 pp 81
151
+ describe_property("VEVENT", "DESCRIPTION", {"X-FOO" => "BAR"}, "Event description")
152
+
153
+ #RFC 2445 section 4.8.1.6 pp 82
154
+ describe_property("VEVENT", "GEO", {"X-FOO" => "BAR"}, "37.386013;-122.082932", RiCal::PropertyValue::Geo)
155
+
156
+ #RFC 2445 section 4.8.1.7 pp 84
157
+ describe_property("VEVENT", "LOCATION", {"ALTREP" => "\"http://xyzcorp.com/conf-rooms/f123.vcf\""}, "Conference Room - F123, Bldg. 002")
158
+
159
+ #Blank value with properties
160
+ describe_property("VEVENT", "LOCATION", {"LANGUAGE" => "en-US"}, "")
161
+
162
+ #RFC 2445 section 4.8.1.8 PERCENT-COMPLETE does not apply to Events
163
+
164
+ #RFC 2445 section 4.8.1.9 pp 84
165
+ describe_property("VEVENT", "PRIORITY", {"X-FOO" => "BAR"}, 1, RiCal::PropertyValue::Integer)
166
+
167
+ #RFC 2445 section 4.8.1.10 pp 87
168
+ describe_multi_property("VEVENT", "RESOURCES", {"X-FOO" => "BAR"}, "Easel,Projector,VCR", RiCal::PropertyValue::Array)
169
+
170
+ #RFC 2445 section 4.8.1.11 pp 88
171
+ describe_property("VEVENT", "STATUS", {"X-FOO" => "BAR"}, "CONFIRMED")
172
+
173
+ #RFC 2445 section 4.8.1.12 pp 89
174
+ describe_property("VEVENT", "SUMMARY", {"X-FOO" => "BAR"}, "Department Party")
175
+
176
+ #RFC 2445 section 4.8.2.1 COMPLETED does not apply to Events
177
+
178
+ #RFC 2445 section 4.8.2.2 DTEND p91
179
+ describe_property("VEVENT", "DTEND", {"X-FOO" => "BAR"}, "19970714", RiCal::PropertyValue::Date)
180
+ describe_property("VEVENT", "DTEND", {"X-FOO" => "BAR"}, "19970714T235959Z", RiCal::PropertyValue::DateTime)
181
+
182
+ #RFC 2445 section 4.8.2.3 DUE does not apply to Events
183
+
184
+ #RFC 2445 section 4.8.2.4 DTSTART p93
185
+ describe_property("VEVENT", "DTSTART", {"X-FOO" => "BAR"}, "19970714", RiCal::PropertyValue::Date)
186
+ describe_property("VEVENT", "DTSTART", {"X-FOO" => "BAR"}, "19970714T235959Z", RiCal::PropertyValue::DateTime)
187
+
188
+ #RFC 2445 section 4.8.2.5 DURATION p94
189
+ describe_property("VEVENT", "DURATION", {"X-FOO" => "BAR"}, "PT1H", RiCal::PropertyValue::Duration)
190
+
191
+ #RFC 2445 section 4.8.2.6 FREEBUSY does not apply to Events
192
+
193
+ #RFC 2445 section 4.8.2.4 TRANSP p93
194
+ describe_property("VEVENT", "TRANSP", {"X-FOO" => "BAR"}, "OPAQUE")
195
+ #TO-DO need to spec that values are constrained to OPAQUE and TRANSPARENT
196
+ # and that this property can be specified at most once
197
+
198
+ #RFC 2445 section 4.8.4.1 ATTENDEE p102
199
+ describe_multi_property("VEVENT", "ATTENDEE", {"X-FOO" => "BAR"}, "MAILTO:jane_doe@host.com", RiCal::PropertyValue::CalAddress)
200
+ #TO-DO need to handle param values
201
+
202
+ #RFC 2445 section 4.8.4.2 CONTACT p104
203
+ describe_multi_property("VEVENT", "CONTACT", {"X-FOO" => "BAR"}, "Contact info")
204
+
205
+ #RFC 2445 section 4.8.4.3 ORGANIZER p106
206
+ describe_property("VEVENT", "ORGANIZER", {"X-FOO" => "BAR", "CN" => "John Smith"}, "MAILTO:jsmith@host1.com", RiCal::PropertyValue::CalAddress)
207
+ #TO-DO need to handle param values
208
+
209
+ #RFC 2445 section 4.8.4.4 RECURRENCE-ID p107
210
+ describe_property("VEVENT", "RECURRENCE-ID", {"X-FOO" => "BAR", "VALUE" => "DATE"}, "19970714", RiCal::PropertyValue::Date)
211
+ describe_property("VEVENT", "RECURRENCE-ID", {"X-FOO" => "BAR", "VALUE" => "DATE-TIME"}, "19970714T235959Z", RiCal::PropertyValue::DateTime)
212
+ #TO-DO need to handle parameters
213
+
214
+ #RFC 2445 section 4.8.4.5 RELATED-TO p109
215
+ describe_multi_property("VEVENT", "RELATED-TO", {"X-FOO" => "BAR"}, "<jsmith.part7.19960817T083000.xyzMail@host3.com")
216
+
217
+ #RFC 2445 section 4.8.4.6 URL p110
218
+ describe_property("VEVENT", "URL", {"X-FOO" => "BAR"}, "http://abc.com/pub/calendars/jsmith/mytime.ics", RiCal::PropertyValue::Uri)
219
+
220
+ #RFC 2445 section 4.8.4.7 UID p111
221
+ describe_property("VEVENT", "UID", {"X-FOO" => "BAR"}, "19960401T080045Z-4000F192713-0052@host1.com")
222
+
223
+ #RFC 2445 section 4.8.5.1 EXDATE p112
224
+ describe_multi_property("VEVENT", "EXDATE", {"X-FOO" => "BAR"}, "19960402T010000,19960403T010000,19960404T010000", RiCal::PropertyValue::OccurrenceList)
225
+
226
+ #RFC 2445 section 4.8.5.2 EXRULE p114
227
+ describe_multi_property("VEVENT", "EXRULE", {"X-FOO" => "BAR"}, "FREQ=DAILY;COUNT=10", RiCal::PropertyValue::RecurrenceRule)
228
+
229
+ #RFC 2445 section 4.8.5.3 RDATE p115
230
+ describe_multi_property("VEVENT", "RDATE", {"X-FOO" => "BAR"}, "19960402T010000,19960403T010000,19960404T010000", RiCal::PropertyValue::OccurrenceList)
231
+
232
+ #RFC 2445 section 4.8.5.2 RRULE p117
233
+ describe_multi_property("VEVENT", "RRULE", {"X-FOO" => "BAR"}, "FREQ=DAILY;COUNT=10", RiCal::PropertyValue::RecurrenceRule)
234
+
235
+ #RFC 2445 section 4.8.7.1 CREATED p129
236
+ describe_property("VEVENT", "CREATED", {"X-FOO" => "BAR"}, "19960329T133000Z", RiCal::PropertyValue::ZuluDateTime)
237
+
238
+ #RFC 2445 section 4.8.7.2 DTSTAMP p129
239
+ describe_property("VEVENT", "DTSTAMP", {"X-FOO" => "BAR"}, "19971210T080000Z", RiCal::PropertyValue::ZuluDateTime)
240
+
241
+ #RFC 2445 section 4.8.7.3 LAST-MODIFIED p131
242
+ describe_property("VEVENT", "LAST-MODIFIED", {"X-FOO" => "BAR"}, "19960817T133000Z", RiCal::PropertyValue::ZuluDateTime)
243
+
244
+ #RFC 2445 section 4.8.7.3 SEQUENCE p131
245
+ describe_property("VEVENT", "SEQUENCE", {"X-FOO" => "BAR"}, 2, RiCal::PropertyValue::Integer)
246
+
247
+ #RFC 2445 section 4.8.8.2 REQUEST-STATUS p131
248
+ describe_multi_property("VEVENT", "REQUEST-STATUS", {"X-FOO" => "BAR"}, "2.0;Success")
249
+ end
250
+
251
+ describe "parsing a calendar" do
252
+
253
+ it "should parse a calendar" do
254
+ parser = RiCal::Parser.new(StringIO.new("BEGIN:VCALENDAR"))
255
+ RiCal::Component::Calendar.should_receive(:from_parser).with(parser, nil, "VCALENDAR")
256
+ parser.parse
257
+ end
258
+
259
+ it "should parse a calendar and return an array of 1 Calendar" do
260
+ cal = RiCal::Parser.parse(StringIO.new("BEGIN:VCALENDAR\nEND:VCALENDAR")).first
261
+ cal.should be_kind_of(RiCal::Component::Calendar)
262
+ end
263
+
264
+ # RFC 2445, section 4.6 section 4.7.1, pp 73-74
265
+ describe_property("VCALENDAR", "CALSCALE", {"X-FOO" => "Y"}, "GREGORIAN")
266
+
267
+ # RFC 2445, section 4.6 section 4.7.2, pp 74-75
268
+ describe_named_property("VCALENDAR", "METHOD", 'icalendar_method', {"X-FOO" => "Y"}, "REQUEST", false)
269
+
270
+ # RFC 2445, section 4.6, pp 51-52, section 4.7.3, p 75-76
271
+ describe_property("VCALENDAR", "PRODID", {"X-FOO" => "Y"}, "-//ABC CORPORATION//NONSGML/ My Product//EN")
272
+
273
+ # RFC 2445, section 4.6, pp 51-52, section 4.7.3, p 75-76
274
+ describe_property("VCALENDAR", "VERSION", {"X-FOO" => "Y"}, "2.0")
275
+
276
+
277
+ # RFC2445 p 51
278
+ it "should parse a calendar with an X property" do
279
+ lambda {RiCal::Parser.parse(StringIO.new("BEGIN:VCALENDAR\nX-PROP;X-FOO=Y:BAR\nEND:VCALENDAR"))}.should_not raise_error
280
+ end
281
+
282
+ describe 'the X property' do
283
+ before(:each) do
284
+ @x_props = RiCal::Parser.parse(StringIO.new("BEGIN:VCALENDAR\nX-PROP;X-FOO=Y:BAR\nEND:VCALENDAR")).first.x_properties
285
+ @x_prop = @x_props["X-PROP"]
286
+ end
287
+
288
+ it "should be an array of length 1" do
289
+ @x_prop.should be_kind_of(Array)
290
+ @x_prop.length.should == 1
291
+ end
292
+
293
+ it "should have a PropertyValue::Text element" do
294
+ @x_prop.first.should be_kind_of(RiCal::PropertyValue::Text)
295
+ end
296
+
297
+ it "should have the right value" do
298
+ @x_prop.first.value.should == "BAR"
299
+ end
300
+
301
+ it "should have the right parameters" do
302
+ @x_prop.first.params.should == {"X-FOO" => "Y"}
303
+ end
304
+ end
305
+ end
306
+
307
+ it "should parse a to-do" do
308
+ parser = RiCal::Parser.new(StringIO.new("BEGIN:VTODO"))
309
+ RiCal::Component::Todo.should_receive(:from_parser).with(parser, nil, "VTODO")
310
+ parser.parse
311
+ end
312
+
313
+ it "should parse a journal entry" do
314
+ parser = RiCal::Parser.new(StringIO.new("BEGIN:VJOURNAL"))
315
+ RiCal::Component::Journal.should_receive(:from_parser).with(parser, nil, "VJOURNAL")
316
+ parser.parse
317
+ end
318
+
319
+ it "should parse a free/busy component" do
320
+ parser = RiCal::Parser.new(StringIO.new("BEGIN:VFREEBUSY"))
321
+ RiCal::Component::Freebusy.should_receive(:from_parser).with(parser, nil, "VFREEBUSY")
322
+ parser.parse
323
+ end
324
+
325
+ it "should parse a timezone component" do
326
+ parser = RiCal::Parser.new(StringIO.new("BEGIN:VTIMEZONE"))
327
+ RiCal::Component::Timezone.should_receive(:from_parser).with(parser, nil, "VTIMEZONE")
328
+ parser.parse
329
+ end
330
+
331
+ it "should parse an alarm component" do
332
+ parser = RiCal::Parser.new(StringIO.new("BEGIN:VALARM"))
333
+ RiCal::Component::Alarm.should_receive(:from_parser).with(parser, nil, "VALARM")
334
+ parser.parse
335
+ end
336
+ end
337
+ end
@@ -0,0 +1,53 @@
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::Date do
6
+ context ".advance" do
7
+ it "should advance by one week if passed :days => 7" do
8
+ dt1 = RiCal::PropertyValue::Date.new(nil, :value => "20050131")
9
+ dt2 = RiCal::PropertyValue::Date.new(nil, :value => "20050207")
10
+ dt1.advance(:days => 7).should == dt2
11
+ end
12
+
13
+ context ".==" do
14
+ it "should return true for two instances representing the same date" do
15
+ dt1 = RiCal::PropertyValue::Date.new(nil, :value => DateTime.parse("20050131T010000"))
16
+ dt2 = RiCal::PropertyValue::Date.new(nil, :value => DateTime.parse("20050131T010001"))
17
+ dt1.should == dt2
18
+ end
19
+ end
20
+ end
21
+
22
+ context ".-" do
23
+
24
+ it "should return a Duration property when the argument is also a Date property" do
25
+ dt1 = RiCal::PropertyValue::Date.new(nil, :value => DateTime.parse("20090519"))
26
+ dt2 = RiCal::PropertyValue::Date.new(nil, :value => DateTime.parse("20090518"))
27
+ (dt1 - dt2).should == RiCal::PropertyValue::Duration.new(nil, :value => "+P1D")
28
+ end
29
+
30
+ it "should return a Duration property when the argument is a DateTime property" do
31
+ dt1 = RiCal::PropertyValue::Date.new(nil, :value => DateTime.parse("20090519"))
32
+ dt2 = RiCal::PropertyValue::DateTime.new(nil, :value => DateTime.parse("20090518T120000"))
33
+ (dt1 - dt2).should == RiCal::PropertyValue::Duration.new(nil, :value => "+PT12H")
34
+ end
35
+
36
+ it "should return a DateTime property when the argument is a Duration Property" do
37
+ dt1 = RiCal::PropertyValue::Date.new(nil, :value => "19980119")
38
+ duration = RiCal::PropertyValue::Duration.new(nil, :value => "+PT2H")
39
+ @it = dt1 - duration
40
+ @it.should == RiCal::PropertyValue::DateTime.new(nil, :value => "19980118T220000")
41
+ end
42
+ end
43
+
44
+ context ".+" do
45
+
46
+ it "should return a DateTime property when the argument is a Duration Property" do
47
+ dt1 = RiCal::PropertyValue::Date.new(nil, :value => "19980119")
48
+ duration = RiCal::PropertyValue::Duration.new(nil, :value => "+PT2H")
49
+ @it = dt1 + duration
50
+ @it.should == RiCal::PropertyValue::DateTime.new(nil, :value => "19980119T020000")
51
+ end
52
+ end
53
+ end