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,157 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
5
|
+
|
6
|
+
describe RiCal::Component::Event do
|
7
|
+
|
8
|
+
describe ".entity_name" do
|
9
|
+
it "should be VEVENT" do
|
10
|
+
RiCal::Component::Event.entity_name.should == "VEVENT"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "with an rrule" do
|
15
|
+
before(:each) do
|
16
|
+
@it = RiCal::Component::Event.parse_string("BEGIN:VEVENT\nRRULE:FREQ=DAILY\nEND:VEVENT").first
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have an array of rrules" do
|
20
|
+
@it.rrule.should be_kind_of(Array)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "description property" do
|
25
|
+
before(:each) do
|
26
|
+
@ical_desc = "posted by Joyce per Zan\\nASheville\\, Rayan's Restauratn\\, Biltm\n ore Square"
|
27
|
+
@ruby_desc = "posted by Joyce per Zan\nASheville, Rayan's Restauratn, Biltmore Square"
|
28
|
+
@it = RiCal::Component::Event.parse_string("BEGIN:VEVENT\nDESCRIPTION:#{@ical_desc}\nEND:VEVENT").first
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should product the converted ruby value" do
|
32
|
+
@it.description.should == @ruby_desc
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should produce escaped text for ical" do
|
36
|
+
@it.description = "This is a\nnew description, yes; it is"
|
37
|
+
@it.description_property.value.should == 'This is a\nnew description\, yes\; it is'
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with both dtend and duration specified" do
|
43
|
+
before(:each) do
|
44
|
+
@it = RiCal::Component::Event.parse_string("BEGIN:VEVENT\nDTEND:19970903T190000Z\nDURATION:H1\nEND:VEVENT").first
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be invalid" do
|
48
|
+
@it.should_not be_valid
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with a duration property" do
|
53
|
+
before(:each) do
|
54
|
+
@it = RiCal::Component::Event.parse_string("BEGIN:VEVENT\nDURATION:H1\nEND:VEVENT").first
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should have a duration property" do
|
58
|
+
@it.duration_property.should be
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should have a duration of 1 Hour" do
|
62
|
+
@it.duration_property.value.should == "H1"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should reset the duration property if the dtend property is set" do
|
66
|
+
@it.dtend_property = "19970101".to_ri_cal_date_time_value
|
67
|
+
@it.duration_property.should be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should reset the duration property if the dtend ruby value is set" do
|
71
|
+
@it.dtend = "19970101"
|
72
|
+
@it.duration_property.should == nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "with a dtend property" do
|
77
|
+
before(:each) do
|
78
|
+
@it = RiCal::Component::Event.parse_string("BEGIN:VEVENT\nDTEND:19970903T190000Z\nEND:VEVENT").first
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have a duration property" do
|
82
|
+
@it.dtend_property.should be
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should reset the dtend property if the duration property is set" do
|
86
|
+
@it.duration_property = "H1".to_ri_cal_duration_value
|
87
|
+
@it.dtend_property.should be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should reset the dtend property if the duration ruby value is set" do
|
91
|
+
@it.duration = "H1".to_ri_cal_duration_value
|
92
|
+
@it.dtend_property.should be_nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "with a nested alarm component" do
|
97
|
+
before(:each) do
|
98
|
+
@it = RiCal::Component::Event.parse_string("BEGIN:VEVENT\nDTEND:19970903T190000Z\n\nBEGIN:VALARM\nEND:VALARM\nEND:VEVENT").first
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should have one alarm" do
|
102
|
+
@it.alarms.length.should == 1
|
103
|
+
end
|
104
|
+
|
105
|
+
it "which should be an Alarm component" do
|
106
|
+
@it.alarms.first.should be_kind_of(RiCal::Component::Alarm)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context ".export" do
|
111
|
+
require 'rubygems'
|
112
|
+
require 'tzinfo'
|
113
|
+
|
114
|
+
def date_time_with_tzinfo_zone(date_time, timezone="America/New_York")
|
115
|
+
result = date_time.dup
|
116
|
+
result.stub!(:acts_like_time?).and_return(true)
|
117
|
+
time_zone = TZInfo::Timezone.get(timezone)
|
118
|
+
result.stub!(:time_zone).and_return(time_zone)
|
119
|
+
result
|
120
|
+
end
|
121
|
+
|
122
|
+
# Undo the effects of RFC2445 line folding
|
123
|
+
def unfold(string)
|
124
|
+
string.gsub("\n ", "")
|
125
|
+
end
|
126
|
+
|
127
|
+
before(:each) do
|
128
|
+
cal = RiCal.Calendar
|
129
|
+
@it = RiCal::Component::Event.new(cal)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should cause a VTIMEZONE to be included for a dtstart with a local timezone" do
|
133
|
+
@it.dtstart = date_time_with_tzinfo_zone(DateTime.parse("April 22, 2009 17:55"), "America/New_York")
|
134
|
+
unfold(@it.export).should match(/BEGIN:VTIMEZONE\nTZID;X-RICAL-TZSOURCE=TZINFO:America\/New_York\n/)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should properly format dtstart with a UTC date-time" do
|
138
|
+
@it.dtstart = DateTime.parse("April 22, 2009 1:23:45")
|
139
|
+
unfold(@it.export).should match(/^DTSTART;VALUE=DATE-TIME:20090422T012345Z$/)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should properly format dtstart with a floating date-time" do
|
143
|
+
@it.dtstart = DateTime.parse("April 22, 2009 1:23:45").with_floating_timezone
|
144
|
+
unfold(@it.export).should match(/^DTSTART;VALUE=DATE-TIME:20090422T012345$/)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should properly format dtstart with a local time zone" do
|
148
|
+
@it.dtstart = date_time_with_tzinfo_zone(DateTime.parse("April 22, 2009 17:55"), "America/New_York")
|
149
|
+
unfold(@it.export).should match(/^DTSTART;TZID=America\/New_York;VALUE=DATE-TIME:20090422T175500$/)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should properly format dtstart with a date" do
|
153
|
+
@it.dtstart = Date.parse("April 22, 2009")
|
154
|
+
unfold(@it.export).should match(/^DTSTART;VALUE=DATE:20090422$/)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
5
|
+
|
6
|
+
describe RiCal::Component::Freebusy do
|
7
|
+
|
8
|
+
describe ".entity_name" do
|
9
|
+
it "should be VFREEBUSY" do
|
10
|
+
RiCal::Component::Freebusy.entity_name.should == "VFREEBUSY"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
5
|
+
|
6
|
+
describe RiCal::Component::Journal do
|
7
|
+
|
8
|
+
describe ".entity_name" do
|
9
|
+
it "should be VJOURNAL" do
|
10
|
+
RiCal::Component::Journal.entity_name.should == "VJOURNAL"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
5
|
+
require 'rubygems'
|
6
|
+
require 'tzinfo'
|
7
|
+
|
8
|
+
describe RiCal::Component::TZInfoTimezone do
|
9
|
+
|
10
|
+
it "should produce an rfc representation" do
|
11
|
+
tz = RiCal::Component::TZInfoTimezone.new(TZInfo::Timezone.get("America/New_York"))
|
12
|
+
local_first = DateTime.parse("Apr 10, 2007")
|
13
|
+
local_last = DateTime.parse("Apr 6, 2008")
|
14
|
+
utc_first = tz.local_to_utc(local_first)
|
15
|
+
utc_last = tz.local_to_utc(local_last)
|
16
|
+
rez = tz.to_rfc2445_string(utc_first, utc_last)
|
17
|
+
rez.should == <<-ENDDATA
|
18
|
+
BEGIN:VTIMEZONE
|
19
|
+
TZID;X-RICAL-TZSOURCE=TZINFO:America/New_York
|
20
|
+
BEGIN:DAYLIGHT
|
21
|
+
DTSTART:20070311T030000
|
22
|
+
RDATE:20070311T030000,20080309T030000
|
23
|
+
TZOFFSETFROM:-0500
|
24
|
+
TZOFFSETTO:-0400
|
25
|
+
TZNAME:EDT
|
26
|
+
END:DAYLIGHT
|
27
|
+
BEGIN:STANDARD
|
28
|
+
DTSTART:20071104T010000
|
29
|
+
RDATE:20071104T010000
|
30
|
+
TZOFFSETFROM:-0400
|
31
|
+
TZOFFSETTO:-0500
|
32
|
+
TZNAME:EST
|
33
|
+
END:STANDARD
|
34
|
+
END:VTIMEZONE
|
35
|
+
ENDDATA
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
5
|
+
require 'tzinfo'
|
6
|
+
|
7
|
+
describe RiCal::Component::Timezone do
|
8
|
+
|
9
|
+
context ".entity_name" do
|
10
|
+
it "should be VTIMEZONE" do
|
11
|
+
RiCal::Component::Timezone.entity_name.should == "VTIMEZONE"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "from an iCal.app calendar for America/New_York starting March 11 2007" do
|
16
|
+
before(:each) do
|
17
|
+
@it = RiCal.parse_string <<TZEND
|
18
|
+
BEGIN:VTIMEZONE
|
19
|
+
TZID:US/Eastern
|
20
|
+
BEGIN:DAYLIGHT
|
21
|
+
TZOFFSETFROM:-0500
|
22
|
+
TZOFFSETTO:-0400
|
23
|
+
DTSTART:20070311T020000
|
24
|
+
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
25
|
+
TZNAME:EDT
|
26
|
+
END:DAYLIGHT
|
27
|
+
BEGIN:STANDARD
|
28
|
+
TZOFFSETFROM:-0400
|
29
|
+
TZOFFSETTO:-0500
|
30
|
+
DTSTART:20071104T020000
|
31
|
+
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
32
|
+
TZNAME:EST
|
33
|
+
END:STANDARD
|
34
|
+
END:VTIMEZONE
|
35
|
+
TZEND
|
36
|
+
@it = @it.first
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be a Timezone" do
|
40
|
+
@it.should be_kind_of(RiCal::Component::Timezone)
|
41
|
+
end
|
42
|
+
|
43
|
+
context ".local_to_utc" do
|
44
|
+
it "should produce 2/27/2009 18:00 UTC for 2/27/2009 13:00" do
|
45
|
+
expected = RiCal::PropertyValue::DateTime.new(nil, :value => "20090227T1800Z" )
|
46
|
+
@it.local_to_utc(DateTime.parse("Feb 27, 2009 13:00")).should == expected
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context ".utc_to_local" do
|
51
|
+
it "should produce 2/27/2009 13:00 EST for 2/27/2009 18:00 UTC" do
|
52
|
+
expected = RiCal::PropertyValue::DateTime.new(nil, :params => {'TZID' => 'US/Eastern'}, :value => "20090227T1300" )
|
53
|
+
@it.utc_to_local(DateTime.parse("Feb 27, 2009 18:00")).should == expected
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context ".period_for_local" do
|
58
|
+
it "should raise TZInfo::PeriodNotFound for an invalid local time, e.g. Mar 8, 2009 2:30" do
|
59
|
+
lambda {@it.period_for_local(DateTime.parse("Mar 8, 2009 2:30"))}.should raise_error(TZInfo::PeriodNotFound)
|
60
|
+
end
|
61
|
+
|
62
|
+
context "for an ambiguous local time , e.g. Nov 1, 2009 2:00" do
|
63
|
+
context "lacking a dst parameter or block" do
|
64
|
+
it "should raise TZInfo::AmbiguousTime" do
|
65
|
+
lambda {@it.period_for_local(DateTime.parse("Nov 1, 2009 2:00"))}.should raise_error(TZInfo::AmbiguousTime)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with a dst parameter" do
|
70
|
+
it "should return a dst period if the dst parameter is true" do
|
71
|
+
@it.period_for_local(DateTime.parse("Nov 1, 2009 2:00"), true).should be_dst
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return a std period if the dst parameter is false" do
|
75
|
+
@it.period_for_local(DateTime.parse("Nov 1, 2009 2:00"), false).should_not be_dst
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "with a block" do
|
80
|
+
it "should return a period if the block returns a TimezonePeriod" do
|
81
|
+
mock_period = ::RiCal::Component::Timezone::TimezonePeriod.new(nil)
|
82
|
+
@it.period_for_local(DateTime.parse("Nov 1, 2009 2:00")) { |results|
|
83
|
+
mock_period
|
84
|
+
}.should == mock_period
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return a period if the block returns a single element array" do
|
88
|
+
mock_period = :foo
|
89
|
+
@it.period_for_local(DateTime.parse("Nov 1, 2009 2:00")) { |results|
|
90
|
+
[ mock_period]
|
91
|
+
}.should == mock_period
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should raise TZInfo::PeriodNotFound if the block returns a multi-element array" do
|
95
|
+
lambda {
|
96
|
+
@it.period_for_local(DateTime.parse("Mar 8, 2009 2:30")) {|results| [1,2]}
|
97
|
+
}.should raise_error(TZInfo::PeriodNotFound)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context ".periods_for_local" do
|
105
|
+
context "for the date on which DST begins springing ahead e.g. Mar 8, 2009" do
|
106
|
+
it "should return a 1 element array for 1 second before the transition time" do
|
107
|
+
@it.periods_for_local(DateTime.parse("Mar 8, 2009 1:59:59")).length.should == 1
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should return an empty array for the transition time" do
|
111
|
+
@it.periods_for_local(DateTime.parse("Mar 8, 2009 2:00:00")).should == []
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should return an empty array for 1 second after the transition time" do
|
115
|
+
@it.periods_for_local(DateTime.parse("Mar 8, 2009 2:00:01")).should == []
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return an empty array for 1 second before the spring ahead time" do
|
119
|
+
@it.periods_for_local(DateTime.parse("Mar 8, 2009 2:59:59")).should == []
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return a 1 element array for the spring ahead time" do
|
123
|
+
@it.periods_for_local(DateTime.parse("Mar 8, 2009 3:00:00")).length.should == 1
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "for the date on which DST ends falling back e.g. Nov 11, 2009" do
|
128
|
+
it "should return a 1 element array for 1 second before the transition time" do
|
129
|
+
@it.periods_for_local(DateTime.parse("Nov 1, 2009 1:59:59")).length.should == 1
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should return a 2 element array for the transition time" do
|
133
|
+
@it.periods_for_local(DateTime.parse("Nov 1, 2009 2:00:00")).length.should == 2
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return a 2 element array for 1 second after the transition time" do
|
137
|
+
@it.periods_for_local(DateTime.parse("Nov 1, 2009 2:00:01")).length.should == 2
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return a 2 element array for 59 minutes and 59 seconds after the transition time" do
|
141
|
+
@it.periods_for_local(DateTime.parse("Nov 1, 2009 2:59:59")).length.should == 2
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should return a 2 element array for 1 hour after the transition time" do
|
145
|
+
@it.periods_for_local(DateTime.parse("Nov 1, 2009 3:00:00")).length.should == 2
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should return a 2 element array for 1 hour and 1 second after the transition time" do
|
149
|
+
@it.periods_for_local(DateTime.parse("Nov 1, 2009 3:00:01")).length.should == 2
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
5
|
+
|
6
|
+
describe RiCal::Component::Todo do
|
7
|
+
|
8
|
+
describe "with both due and duration specified" do
|
9
|
+
before(:each) do
|
10
|
+
@it = RiCal::Component::Todo.parse_string("BEGIN:VTODO\nDUE:19970903T190000Z\nDURATION:H1\nEND:VTODO").first
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be invalid" do
|
14
|
+
@it.should_not be_valid
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "with a duration property" do
|
19
|
+
before(:each) do
|
20
|
+
@it = RiCal::Component::Todo.parse_string("BEGIN:VTODO\nDURATION:H1\nEND:VTODO").first
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have a duration property" do
|
24
|
+
@it.duration_property.should be
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have a duration of 1 Hour" do
|
28
|
+
@it.duration_property.value.should == "H1"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should reset the duration property if the due property is set" do
|
32
|
+
@it.due_property = "19970101".to_ri_cal_date_time_value
|
33
|
+
@it.duration_property.should be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should reset the duration property if the dtend ruby value is set" do
|
37
|
+
@it.due = "19970101"
|
38
|
+
@it.duration_property.should == nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "with a due property" do
|
43
|
+
before(:each) do
|
44
|
+
@it = RiCal::Component::Todo.parse_string("BEGIN:VTODO\nDUE:19970903T190000Z\nEND:VTODO").first
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have a due property" do
|
48
|
+
@it.due_property.should be
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should reset the due property if the duration property is set" do
|
52
|
+
@it.duration_property = "H1".to_ri_cal_duration_value
|
53
|
+
@it.due_property.should be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should reset the duration property if the dtend ruby value is set" do
|
57
|
+
@it.duration = "19970101"
|
58
|
+
@it.due_property.should == nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
#- ©2009 Rick DeNatale
|
2
|
+
#- All rights reserved
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
5
|
+
|
6
|
+
describe RiCal::Component do
|
7
|
+
|
8
|
+
context "building blocks" do
|
9
|
+
|
10
|
+
context "building an empty calendar" do
|
11
|
+
before(:each) do
|
12
|
+
@it = RiCal.Calendar.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have the default prodid" do
|
16
|
+
@it.should match(%r{^PRODID;X-RICAL-TZSOURCE=TZINFO:-//com.denhaven2/NONSGML ri_cal gem//EN$})
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have the default calscale" do
|
20
|
+
@it.should match(%r{^CALSCALE:GREGORIAN$})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have the default icalendar version" do
|
24
|
+
@it.should match(%r{^VERSION:2\.0$})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "building a calendar with time zones" do
|
29
|
+
it 'should allow specifying the time zone identifier' do
|
30
|
+
event = RiCal.Event do
|
31
|
+
dtstart [DateTime.parse("Feb 20, 1962 14:47:39"), 'US/Pacific']
|
32
|
+
end
|
33
|
+
event.dtstart_property.should == dt_prop(DateTime.parse("Feb 20, 1962 14:47:39"), tzid = 'US/Pacific')
|
34
|
+
end
|
35
|
+
|
36
|
+
context "adding an exception date" do
|
37
|
+
|
38
|
+
it "should test stuff"
|
39
|
+
# before(:each) do
|
40
|
+
# @event = RiCal.Event do
|
41
|
+
# add_exdate [DateTime.parse("Feb 20, 1962 14:47:39"), 'US/Pacific']
|
42
|
+
# end
|
43
|
+
# @prop = @event.exdate_property.first
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# it "should produce an OccurrenceList for the property" do
|
47
|
+
# @prop.should be_instance_of(RiCal::PropertyValue::OccurrenceList)
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# it "should have the right exdate value" do
|
51
|
+
# @event.exdate.should == ""
|
52
|
+
# end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with a block with 1 parameter" do
|
57
|
+
before(:each) do
|
58
|
+
@it = RiCal.Event do |event|
|
59
|
+
event.description = "MA-6 First US Manned Spaceflight"
|
60
|
+
event.dtstart = DateTime.parse("Feb 20, 1962 14:47:39")
|
61
|
+
event.dtend = DateTime.parse("Feb 20, 1962 19:43:02")
|
62
|
+
event.location = "Cape Canaveral"
|
63
|
+
event.add_attendee "john.glenn@nasa.gov"
|
64
|
+
event.alarm do
|
65
|
+
description "Segment 51"
|
66
|
+
end
|
67
|
+
event.alarm do |alarm|
|
68
|
+
alarm.description = "Second alarm"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have the right description" do
|
74
|
+
@it.description.should == "MA-6 First US Manned Spaceflight"
|
75
|
+
end
|
76
|
+
it "should have the right dtstart" do
|
77
|
+
@it.dtstart.should == DateTime.parse("Feb 20, 1962 14:47:39")
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should have a zulu time dtstart property" do
|
81
|
+
@it.dtstart_property.tzid.should == "UTC"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should have the right dtend" do
|
85
|
+
@it.dtend.should == DateTime.parse("Feb 20, 1962 19:43:02")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should have a zulu time dtend property" do
|
89
|
+
@it.dtend_property.tzid.should == "UTC"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should have the right location" do
|
93
|
+
@it.location.should == "Cape Canaveral"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have the right attendee" do
|
97
|
+
@it.attendee.should include("john.glenn@nasa.gov")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should have 2 alarms" do
|
101
|
+
@it.alarms.length.should == 2
|
102
|
+
end
|
103
|
+
|
104
|
+
it ".the alarms should have the right description" do
|
105
|
+
@it.alarms.first.description.should == "Segment 51"
|
106
|
+
@it.alarms.last.description.should == "Second alarm"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "building an event for MA-6" do
|
111
|
+
before(:each) do
|
112
|
+
@it = RiCal.Event do
|
113
|
+
description "MA-6 First US Manned Spaceflight"
|
114
|
+
dtstart DateTime.parse("Feb 20, 1962 14:47:39")
|
115
|
+
dtend DateTime.parse("Feb 20, 1962 19:43:02")
|
116
|
+
location "Cape Canaveral"
|
117
|
+
add_attendee "john.glenn@nasa.gov"
|
118
|
+
alarm do
|
119
|
+
description "Segment 51"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should have the right description" do
|
125
|
+
@it.description.should == "MA-6 First US Manned Spaceflight"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should have the right dtstart" do
|
129
|
+
@it.dtstart.should == DateTime.parse("Feb 20, 1962 14:47:39")
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should have a zulu time dtstart property" do
|
133
|
+
@it.dtstart_property.tzid.should == "UTC"
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should have the right dtend" do
|
137
|
+
@it.dtend.should == DateTime.parse("Feb 20, 1962 19:43:02")
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should have a zulu time dtend property" do
|
141
|
+
@it.dtend_property.tzid.should == "UTC"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should have the right location" do
|
145
|
+
@it.location.should == "Cape Canaveral"
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should have the right attendee" do
|
149
|
+
@it.attendee.should include("john.glenn@nasa.gov")
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should have 1 alarm" do
|
153
|
+
@it.alarms.length.should == 1
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should have an alarm with the right description" do
|
157
|
+
@it.alarms.first.description.should == "Segment 51"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "building a complex calendar" do
|
162
|
+
|
163
|
+
before(:each) do
|
164
|
+
@it = RiCal.Calendar do
|
165
|
+
add_x_property 'x_wr_calname', 'My Personal Calendar'
|
166
|
+
event do
|
167
|
+
summary 'A Recurring Event'
|
168
|
+
description "This is some really long note content. It should be appropriately folded in the generated file.\nCarriage returns should work, too."
|
169
|
+
dtstart DateTime.parse('Feb 20, 2009 20:30:00')
|
170
|
+
dtend DateTime.parse('Feb 20, 2009 21:30:00')
|
171
|
+
location 'North Carolina'
|
172
|
+
dtstamp Time.now
|
173
|
+
rrule :freq => 'daily', :interval => 1
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should have an x_wr_calname property with the value "My Personal Calendar"' do
|
179
|
+
@it.x_wr_calname.should == "My Personal Calendar"
|
180
|
+
end
|
181
|
+
|
182
|
+
context "event with a long description and a dsl built recurence rule" do
|
183
|
+
before(:each) do
|
184
|
+
@cal = @it
|
185
|
+
@it = @cal.events.first
|
186
|
+
end
|
187
|
+
|
188
|
+
context "its description" do
|
189
|
+
it "should pass through correctly" do
|
190
|
+
@it.description.should == "This is some really long note content. It should be appropriately folded in the generated file.\nCarriage returns should work, too."
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "its rrule" do
|
195
|
+
|
196
|
+
it "should have a 1 rrule" do
|
197
|
+
@it.rrule.length.should == 1
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should have the right rrule" do
|
201
|
+
@it.rrule.first.should == "FREQ=DAILY"
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should have the right rrule hash" do
|
205
|
+
@it.rrule_property.first.to_options_hash.should == {:freq => 'DAILY', :interval => 1}
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
end
|