icalendar 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.txt +7 -0
- data/README.md +6 -6
- data/icalendar.gemspec +3 -0
- data/lib/icalendar/parser.rb +12 -3
- data/lib/icalendar/tzinfo.rb +28 -26
- data/lib/icalendar/values/date.rb +9 -1
- data/lib/icalendar/values/date_time.rb +9 -1
- data/lib/icalendar/values/text.rb +7 -11
- data/lib/icalendar/values/utc_offset.rb +1 -3
- data/lib/icalendar/version.rb +1 -1
- data/spec/fixtures/single_event_bad_line.ics +22 -0
- data/spec/fixtures/two_date_time_events.ics +64 -0
- data/spec/fixtures/two_day_events.ics +35 -0
- data/spec/fixtures/two_time_events.ics +64 -0
- data/spec/parser_spec.rb +22 -3
- data/spec/roundtrip_spec.rb +46 -0
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1247afeb6249a4562ed23fdf9a01345f10513d8e
|
4
|
+
data.tar.gz: edb231f0a00055c53bafec1e92a4006b741d14fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c93f4624d028b364b42ed6054df4b7bffe2296bdd392985aff5d929be4fff0ebea3ff15ae93799277935497385d28f0f210ff7928309dac9488b42d1c25bc0c
|
7
|
+
data.tar.gz: 59a6178deb2fc347b0487306aff201d64360ed52aae18fe3e905082988f827f7c6f509fdde39d15461cfb38a1b34b506c6caaa821fe3ede4af0eda7259121570
|
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 2.2.0 2014-09-23
|
2
|
+
* Default to non-strict parsing
|
3
|
+
* Enable sorting events by dtstart - Mark Rickert
|
4
|
+
* Better tolerate malformed lines in parser - Gary Shutler
|
5
|
+
* Deduplicate timezone code - Jan Vlnas
|
6
|
+
* Eliminate warnings - rochefort
|
7
|
+
|
1
8
|
=== 2.1.2 2014-09-10
|
2
9
|
* Fix timezone abbreviation generation - Jan Vlnas
|
3
10
|
* Fix timezone repeat rules for end of month
|
data/README.md
CHANGED
@@ -233,13 +233,13 @@ Parsing iCalendars
|
|
233
233
|
puts "start date-time timezone: #{event.dtstart.ical_params['tzid']}"
|
234
234
|
puts "summary: #{event.summary}"
|
235
235
|
|
236
|
-
You can also create a `Parser` instance directly, this can be used to
|
237
|
-
|
236
|
+
You can also create a `Parser` instance directly, this can be used to enable
|
237
|
+
strict parsing:
|
238
238
|
|
239
|
-
#
|
240
|
-
#
|
241
|
-
|
242
|
-
cal =
|
239
|
+
# Sometimes you want to strongly verify only rfc-approved properties are
|
240
|
+
# used
|
241
|
+
strict_parser = Icalendar::Parser.new(cal_file, true)
|
242
|
+
cal = strict_parser.parse
|
243
243
|
|
244
244
|
Finders
|
245
245
|
---
|
data/icalendar.gemspec
CHANGED
@@ -18,6 +18,9 @@ variety of calendaring applications.
|
|
18
18
|
s.post_install_message = <<-EOM
|
19
19
|
HEADS UP! iCalendar 2.0 is not backwards-compatible with 1.x. Please see the README for the new syntax
|
20
20
|
|
21
|
+
HEADS UP! icalendar 2.2.0 switches to non-strict parsing as default. Please see the README if you
|
22
|
+
rely on strict parsing for information on how to enable it.
|
23
|
+
|
21
24
|
ActiveSupport is required for TimeWithZone support, but not required for general use.
|
22
25
|
EOM
|
23
26
|
|
data/lib/icalendar/parser.rb
CHANGED
@@ -4,7 +4,7 @@ module Icalendar
|
|
4
4
|
|
5
5
|
attr_reader :source, :strict
|
6
6
|
|
7
|
-
def initialize(source, strict =
|
7
|
+
def initialize(source, strict = false)
|
8
8
|
if source.respond_to? :gets
|
9
9
|
@source = source
|
10
10
|
elsif source.respond_to? :to_s
|
@@ -119,9 +119,18 @@ module Icalendar
|
|
119
119
|
PARAM = "(#{NAME})=(#{PVALUE}(?:,#{PVALUE})*)"
|
120
120
|
VALUE = '.*'
|
121
121
|
LINE = "(?<name>#{NAME})(?<params>(?:;#{PARAM})*):(?<value>#{VALUE})"
|
122
|
+
BAD_LINE = "(?<name>#{NAME})(?<params>(?:;#{PARAM})*)"
|
122
123
|
|
123
124
|
def parse_fields(input)
|
124
|
-
parts = %r{#{LINE}}.match(input)
|
125
|
+
if parts = %r{#{LINE}}.match(input)
|
126
|
+
value = parts[:value]
|
127
|
+
else
|
128
|
+
parts = %r{#{BAD_LINE}}.match(input) unless strict?
|
129
|
+
parts or fail "Invalid iCalendar input line: #{input}"
|
130
|
+
# Non-strict and bad line so use a value of empty string
|
131
|
+
value = ''
|
132
|
+
end
|
133
|
+
|
125
134
|
params = {}
|
126
135
|
parts[:params].scan %r{#{PARAM}} do |match|
|
127
136
|
param_name = match[0].downcase
|
@@ -134,7 +143,7 @@ module Icalendar
|
|
134
143
|
{
|
135
144
|
name: parts[:name].downcase.gsub('-', '_'),
|
136
145
|
params: params,
|
137
|
-
value:
|
146
|
+
value: value
|
138
147
|
}
|
139
148
|
end
|
140
149
|
end
|
data/lib/icalendar/tzinfo.rb
CHANGED
@@ -128,38 +128,29 @@ module TZInfo
|
|
128
128
|
end
|
129
129
|
|
130
130
|
class TimezonePeriod
|
131
|
+
|
132
|
+
# For DST, use the start_transition,
|
133
|
+
# for standard TZ, use the following period (starting from the end_transition).
|
131
134
|
def daylight
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
else
|
140
|
-
day.tzname = end_transition.offset_abbreviation
|
141
|
-
day.tzoffsetfrom = end_transition.offset_from
|
142
|
-
day.tzoffsetto = end_transition.offset_to
|
143
|
-
day.dtstart = end_transition.dtstart
|
144
|
-
day.rrule = end_transition.rrule
|
135
|
+
transition = dst? ? start_transition : end_transition
|
136
|
+
day = Icalendar::Timezone::Daylight.new
|
137
|
+
build_timezone(day, transition) do |tz|
|
138
|
+
# rrule should not be set for the current [==DST/daylight] period
|
139
|
+
# if there is no recurrence rule for the end transition
|
140
|
+
if !dst? || !end_transition.nil?
|
141
|
+
tz.rrule = transition.rrule
|
145
142
|
end
|
146
143
|
end
|
147
144
|
end
|
148
145
|
|
146
|
+
# For standard TZ, use the start_transition,
|
147
|
+
# for DST, use the following period, (starting from the end_transition)
|
149
148
|
def standard
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
std.dtstart = end_transition.dtstart
|
156
|
-
std.rrule = end_transition.rrule
|
157
|
-
else
|
158
|
-
std.tzname = abbreviation.to_s
|
159
|
-
std.tzoffsetfrom = start_transition.offset_from
|
160
|
-
std.tzoffsetto = start_transition.offset_to
|
161
|
-
std.dtstart = start_transition.dtstart
|
162
|
-
std.rrule = start_transition.rrule unless end_transition.nil?
|
149
|
+
transition = dst? ? end_transition : start_transition
|
150
|
+
std = Icalendar::Timezone::Standard.new
|
151
|
+
build_timezone(std, transition) do |tz|
|
152
|
+
if dst? || !end_transition.nil?
|
153
|
+
tz.rrule = transition.rrule
|
163
154
|
end
|
164
155
|
end
|
165
156
|
end
|
@@ -172,5 +163,16 @@ module TZInfo
|
|
172
163
|
std.dtstart = DateTime.new(1970).strftime '%Y%m%dT%H%M%S'
|
173
164
|
end
|
174
165
|
end
|
166
|
+
|
167
|
+
private
|
168
|
+
def build_timezone(timezone, transition)
|
169
|
+
timezone.tap do |tz|
|
170
|
+
tz.tzname = transition.offset_abbreviation
|
171
|
+
tz.tzoffsetfrom = transition.offset_from
|
172
|
+
tz.tzoffsetto = transition.offset_to
|
173
|
+
tz.dtstart = transition.dtstart
|
174
|
+
yield tz
|
175
|
+
end
|
176
|
+
end
|
175
177
|
end
|
176
178
|
end
|
@@ -20,7 +20,15 @@ module Icalendar
|
|
20
20
|
value.strftime FORMAT
|
21
21
|
end
|
22
22
|
|
23
|
+
def <=>(other)
|
24
|
+
if other.is_a?(Icalendar::Values::Date) || other.is_a?(Icalendar::Values::DateTime)
|
25
|
+
value_ical <=> other.value_ical
|
26
|
+
else
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
23
31
|
end
|
24
32
|
|
25
33
|
end
|
26
|
-
end
|
34
|
+
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
module Icalendar
|
2
2
|
module Values
|
3
|
-
|
4
3
|
class Text < Value
|
5
|
-
|
6
4
|
def initialize(value, params = {})
|
7
|
-
value = value.gsub
|
8
|
-
value.gsub!
|
9
|
-
value.gsub!
|
5
|
+
value = value.gsub('\n', "\n")
|
6
|
+
value.gsub!('\,', ',')
|
7
|
+
value.gsub!('\;', ';')
|
10
8
|
value.gsub!('\\\\') { '\\' }
|
11
9
|
super value, params
|
12
10
|
end
|
@@ -14,13 +12,11 @@ module Icalendar
|
|
14
12
|
def value_ical
|
15
13
|
value.dup.tap do |v|
|
16
14
|
v.gsub!('\\') { '\\\\' }
|
17
|
-
v.gsub!
|
18
|
-
v.gsub!
|
19
|
-
v.gsub!
|
15
|
+
v.gsub!(';', '\;')
|
16
|
+
v.gsub!(',', '\,')
|
17
|
+
v.gsub!(/\r?\n/, '\n')
|
20
18
|
end
|
21
19
|
end
|
22
|
-
|
23
20
|
end
|
24
|
-
|
25
21
|
end
|
26
|
-
end
|
22
|
+
end
|
@@ -2,9 +2,7 @@ require 'ostruct'
|
|
2
2
|
|
3
3
|
module Icalendar
|
4
4
|
module Values
|
5
|
-
|
6
5
|
class UtcOffset < Value
|
7
|
-
|
8
6
|
def initialize(value, params = {})
|
9
7
|
if value.is_a? Icalendar::Values::UtcOffset
|
10
8
|
value = value.value
|
@@ -30,7 +28,7 @@ module Icalendar
|
|
30
28
|
end
|
31
29
|
|
32
30
|
def parse_fields(value)
|
33
|
-
value.gsub!
|
31
|
+
value.gsub!(/\s+/, '')
|
34
32
|
md = /\A(?<behind>[+-])(?<hours>\d{2})(?<minutes>\d{2})(?<seconds>\d{2})?\z/.match value
|
35
33
|
{
|
36
34
|
behind: (md[:behind] == '-'),
|
data/lib/icalendar/version.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
VERSION:2.0
|
3
|
+
PRODID:bsprodidfortestabc123
|
4
|
+
CALSCALE:GREGORIAN
|
5
|
+
BEGIN:VEVENT
|
6
|
+
DTSTAMP:20050118T211523Z
|
7
|
+
UID:bsuidfortestabc123
|
8
|
+
DTSTART;TZID=US-Mountain:20050120T170000
|
9
|
+
DTEND;TZID=US-Mountain:20050120T184500
|
10
|
+
CLASS:PRIVATE
|
11
|
+
GEO:37.386013;-122.0829322
|
12
|
+
ORGANIZER:mailto:joebob@random.net
|
13
|
+
PRIORITY:2
|
14
|
+
SUMMARY:This is a really long summary to test the method of unfolding lines
|
15
|
+
\, so I'm just going to make it a whole bunch of lines.
|
16
|
+
ATTACH:http://bush.sucks.org/impeach/him.rhtml
|
17
|
+
ATTACH:http://corporations-dominate.existence.net/why.rhtml
|
18
|
+
RDATE;TZID=US-Mountain:20050121T170000,20050122T170000
|
19
|
+
X-TEST-COMPONENT;QTEST="Hello, World":Shouldn't double double quotes
|
20
|
+
X-NO-VALUE
|
21
|
+
END:VEVENT
|
22
|
+
END:VCALENDAR
|
@@ -0,0 +1,64 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
METHOD:PUBLISH
|
3
|
+
VERSION:2.0
|
4
|
+
X-WR-CALNAME:TMP
|
5
|
+
PRODID:-//Apple Inc.//Mac OS X 10.9.4//EN
|
6
|
+
X-APPLE-CALENDAR-COLOR:#0E61B9
|
7
|
+
X-WR-TIMEZONE:America/New_York
|
8
|
+
CALSCALE:GREGORIAN
|
9
|
+
BEGIN:VTIMEZONE
|
10
|
+
TZID:America/New_York
|
11
|
+
BEGIN:DAYLIGHT
|
12
|
+
TZOFFSETFROM:-0500
|
13
|
+
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
14
|
+
DTSTART:20070311T020000
|
15
|
+
TZNAME:EDT
|
16
|
+
TZOFFSETTO:-0400
|
17
|
+
END:DAYLIGHT
|
18
|
+
BEGIN:STANDARD
|
19
|
+
TZOFFSETFROM:-0400
|
20
|
+
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
21
|
+
DTSTART:20071104T020000
|
22
|
+
TZNAME:EST
|
23
|
+
TZOFFSETTO:-0500
|
24
|
+
END:STANDARD
|
25
|
+
END:VTIMEZONE
|
26
|
+
BEGIN:VEVENT
|
27
|
+
STATUS:CONFIRMED
|
28
|
+
CREATED:20140731T162556Z
|
29
|
+
UID:7C4A5440-ABA5-4B32-A69D-AFD243B39FE1
|
30
|
+
DTEND;TZID=America/New_York:20140714T100000
|
31
|
+
TRANSP:OPAQUE
|
32
|
+
SUMMARY:9am
|
33
|
+
LAST-MODIFIED:20140731T162556Z
|
34
|
+
DTSTAMP:20140731T164042Z
|
35
|
+
DTSTART;TZID=America/New_York:20140714T090000
|
36
|
+
LOCATION:
|
37
|
+
SEQUENCE:13
|
38
|
+
BEGIN:VALARM
|
39
|
+
X-WR-ALARMUID:6F54CD66-F2A9-491D-8892-7E3209F6A2E4
|
40
|
+
UID:6F54CD66-F2A9-491D-8892-7E3209F6A2E4
|
41
|
+
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
|
42
|
+
ACTION:NONE
|
43
|
+
END:VALARM
|
44
|
+
END:VEVENT
|
45
|
+
BEGIN:VEVENT
|
46
|
+
STATUS:CONFIRMED
|
47
|
+
CREATED:20140731T162556Z
|
48
|
+
UID:A50FA12F-BCA9-4822-A61D-E86EB7440A16
|
49
|
+
DTEND;VALUE=DATE:20140715
|
50
|
+
TRANSP:TRANSPARENT
|
51
|
+
SUMMARY:All Day
|
52
|
+
LAST-MODIFIED:20140731T162556Z
|
53
|
+
DTSTAMP:20140731T164829Z
|
54
|
+
DTSTART;VALUE=DATE:20140714
|
55
|
+
LOCATION:
|
56
|
+
SEQUENCE:18
|
57
|
+
BEGIN:VALARM
|
58
|
+
X-WR-ALARMUID:295F2CF7-1C48-4E76-A8FC-718A1EBEDB76
|
59
|
+
UID:295F2CF7-1C48-4E76-A8FC-718A1EBEDB76
|
60
|
+
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
|
61
|
+
ACTION:NONE
|
62
|
+
END:VALARM
|
63
|
+
END:VEVENT
|
64
|
+
END:VCALENDAR
|
@@ -0,0 +1,35 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
METHOD:PUBLISH
|
3
|
+
VERSION:2.0
|
4
|
+
X-WR-CALNAME:TMP
|
5
|
+
PRODID:-//Apple Inc.//Mac OS X 10.9.4//EN
|
6
|
+
X-APPLE-CALENDAR-COLOR:#0E61B9
|
7
|
+
X-WR-TIMEZONE:America/New_York
|
8
|
+
CALSCALE:GREGORIAN
|
9
|
+
BEGIN:VEVENT
|
10
|
+
STATUS:CONFIRMED
|
11
|
+
CREATED:20140731T162556Z
|
12
|
+
UID:A50FA12F-BCA9-4822-A61D-E86EB7440A16
|
13
|
+
DTEND;VALUE=DATE:20140715
|
14
|
+
TRANSP:TRANSPARENT
|
15
|
+
SUMMARY:Monday
|
16
|
+
LAST-MODIFIED:20140731T162556Z
|
17
|
+
DTSTAMP:20140731T162628Z
|
18
|
+
DTSTART;VALUE=DATE:20140714
|
19
|
+
LOCATION:
|
20
|
+
SEQUENCE:3
|
21
|
+
END:VEVENT
|
22
|
+
BEGIN:VEVENT
|
23
|
+
STATUS:CONFIRMED
|
24
|
+
CREATED:20140731T162556Z
|
25
|
+
UID:7C4A5440-ABA5-4B32-A69D-AFD243B39FE1
|
26
|
+
DTEND;VALUE=DATE:20140714
|
27
|
+
TRANSP:TRANSPARENT
|
28
|
+
SUMMARY:Sunday
|
29
|
+
LAST-MODIFIED:20140731T162556Z
|
30
|
+
DTSTAMP:20140731T162611Z
|
31
|
+
DTSTART;VALUE=DATE:20140713
|
32
|
+
LOCATION:
|
33
|
+
SEQUENCE:5
|
34
|
+
END:VEVENT
|
35
|
+
END:VCALENDAR
|
@@ -0,0 +1,64 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
METHOD:PUBLISH
|
3
|
+
VERSION:2.0
|
4
|
+
X-WR-CALNAME:TMP
|
5
|
+
PRODID:-//Apple Inc.//Mac OS X 10.9.4//EN
|
6
|
+
X-APPLE-CALENDAR-COLOR:#0E61B9
|
7
|
+
X-WR-TIMEZONE:America/New_York
|
8
|
+
CALSCALE:GREGORIAN
|
9
|
+
BEGIN:VTIMEZONE
|
10
|
+
TZID:America/New_York
|
11
|
+
BEGIN:DAYLIGHT
|
12
|
+
TZOFFSETFROM:-0500
|
13
|
+
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
14
|
+
DTSTART:20070311T020000
|
15
|
+
TZNAME:EDT
|
16
|
+
TZOFFSETTO:-0400
|
17
|
+
END:DAYLIGHT
|
18
|
+
BEGIN:STANDARD
|
19
|
+
TZOFFSETFROM:-0400
|
20
|
+
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
21
|
+
DTSTART:20071104T020000
|
22
|
+
TZNAME:EST
|
23
|
+
TZOFFSETTO:-0500
|
24
|
+
END:STANDARD
|
25
|
+
END:VTIMEZONE
|
26
|
+
BEGIN:VEVENT
|
27
|
+
STATUS:CONFIRMED
|
28
|
+
CREATED:20140731T162556Z
|
29
|
+
UID:7C4A5440-ABA5-4B32-A69D-AFD243B39FE1
|
30
|
+
DTEND;TZID=America/New_York:20140714T100000
|
31
|
+
TRANSP:OPAQUE
|
32
|
+
SUMMARY:9am
|
33
|
+
LAST-MODIFIED:20140731T162556Z
|
34
|
+
DTSTAMP:20140731T164042Z
|
35
|
+
DTSTART;TZID=America/New_York:20140714T090000
|
36
|
+
LOCATION:
|
37
|
+
SEQUENCE:13
|
38
|
+
BEGIN:VALARM
|
39
|
+
X-WR-ALARMUID:6F54CD66-F2A9-491D-8892-7E3209F6A2E4
|
40
|
+
UID:6F54CD66-F2A9-491D-8892-7E3209F6A2E4
|
41
|
+
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
|
42
|
+
ACTION:NONE
|
43
|
+
END:VALARM
|
44
|
+
END:VEVENT
|
45
|
+
BEGIN:VEVENT
|
46
|
+
STATUS:CONFIRMED
|
47
|
+
CREATED:20140731T162556Z
|
48
|
+
UID:A50FA12F-BCA9-4822-A61D-E86EB7440A16
|
49
|
+
DTEND;TZID=America/New_York:20140714T095900
|
50
|
+
TRANSP:OPAQUE
|
51
|
+
SUMMARY:9:01-9:59
|
52
|
+
LAST-MODIFIED:20140731T162556Z
|
53
|
+
DTSTAMP:20140731T164405Z
|
54
|
+
DTSTART;TZID=America/New_York:20140714T090100
|
55
|
+
LOCATION:
|
56
|
+
SEQUENCE:16
|
57
|
+
BEGIN:VALARM
|
58
|
+
X-WR-ALARMUID:295F2CF7-1C48-4E76-A8FC-718A1EBEDB76
|
59
|
+
UID:295F2CF7-1C48-4E76-A8FC-718A1EBEDB76
|
60
|
+
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
|
61
|
+
ACTION:NONE
|
62
|
+
END:VALARM
|
63
|
+
END:VEVENT
|
64
|
+
END:VCALENDAR
|
data/spec/parser_spec.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Icalendar::Parser do
|
4
|
-
|
5
|
-
let(:source) { File.read File.join(File.dirname(__FILE__), 'fixtures', 'single_event.ics') }
|
6
4
|
subject { described_class.new source, false }
|
7
5
|
|
8
6
|
describe '#parse' do
|
7
|
+
let(:source) { File.read File.join(File.dirname(__FILE__), 'fixtures', 'single_event.ics') }
|
8
|
+
|
9
9
|
it 'returns an array of calendars' do
|
10
10
|
expect(subject.parse).to be_instance_of Array
|
11
11
|
expect(subject.parse.count).to eq 1
|
@@ -23,4 +23,23 @@ describe Icalendar::Parser do
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
describe '#parse with bad line' do
|
27
|
+
let(:source) { File.read File.join(File.dirname(__FILE__), 'fixtures', 'single_event_bad_line.ics') }
|
28
|
+
|
29
|
+
it 'returns an array of calendars' do
|
30
|
+
expect(subject.parse).to be_instance_of Array
|
31
|
+
expect(subject.parse.count).to eq 1
|
32
|
+
expect(subject.parse[0]).to be_instance_of Icalendar::Calendar
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'properly splits multi-valued lines' do
|
36
|
+
event = subject.parse.first.events.first
|
37
|
+
expect(event.geo).to eq [37.386013,-122.0829322]
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'saves params' do
|
41
|
+
event = subject.parse.first.events.first
|
42
|
+
expect(event.dtstart.ical_params).to eq('tzid' => ['US-Mountain'])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/roundtrip_spec.rb
CHANGED
@@ -38,6 +38,52 @@ describe Icalendar do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
describe 'sorting daily events' do
|
42
|
+
let(:source) { File.read File.join(File.dirname(__FILE__), 'fixtures', 'two_day_events.ics') }
|
43
|
+
subject { Icalendar.parse(source, true).events }
|
44
|
+
|
45
|
+
it 'sorts day events' do
|
46
|
+
events = subject.sort_by(&:dtstart)
|
47
|
+
|
48
|
+
expect(events.first.dtstart).to eq ::Date.new(2014, 7, 13)
|
49
|
+
expect(events.last.dtstart).to eq ::Date.new(2014, 7, 14)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'sorting time events' do
|
54
|
+
let(:source) { File.read File.join(File.dirname(__FILE__), 'fixtures', 'two_time_events.ics') }
|
55
|
+
subject { Icalendar.parse(source, true).events }
|
56
|
+
|
57
|
+
it 'sorts time events by start time' do
|
58
|
+
events = subject.sort_by(&:dtstart)
|
59
|
+
|
60
|
+
expect(events.first.dtstart).to eq ::DateTime.new(2014, 7, 14, 9, 0, 0, '-4')
|
61
|
+
|
62
|
+
expect(events.last.dtstart).to eq ::DateTime.new(2014, 7, 14, 9, 1, 0, '-4')
|
63
|
+
expect(events.last.dtend).to eq ::DateTime.new(2014, 7, 14, 9, 59, 0, '-4')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'sorts time events by end time' do
|
67
|
+
events = subject.sort_by(&:dtend)
|
68
|
+
|
69
|
+
expect(events.first.dtstart).to eq ::DateTime.new(2014, 7, 14, 9, 1, 0, '-4')
|
70
|
+
expect(events.first.dtend).to eq ::DateTime.new(2014, 7, 14, 9, 59, 0, '-4')
|
71
|
+
expect(events.last.dtstart).to eq ::DateTime.new(2014, 7, 14, 9, 0, 0, '-4')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'sorting date / time events' do
|
76
|
+
let(:source) { File.read File.join(File.dirname(__FILE__), 'fixtures', 'two_date_time_events.ics') }
|
77
|
+
subject { Icalendar.parse(source, true).events }
|
78
|
+
|
79
|
+
it 'sorts time events' do
|
80
|
+
events = subject.sort_by(&:dtstart)
|
81
|
+
|
82
|
+
expect(events.first.dtstart).to eq ::Date.new(2014, 7, 14)
|
83
|
+
expect(events.last.dtstart).to eq ::DateTime.new(2014, 7, 14, 9, 0, 0, '-4')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
41
87
|
describe 'non-standard values' do
|
42
88
|
if defined? File::NULL
|
43
89
|
before(:all) { Icalendar.logger = Icalendar::Logger.new File::NULL }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icalendar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Ahearn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -179,7 +179,11 @@ files:
|
|
179
179
|
- spec/fixtures/nondefault_values.ics
|
180
180
|
- spec/fixtures/nonstandard.ics
|
181
181
|
- spec/fixtures/single_event.ics
|
182
|
+
- spec/fixtures/single_event_bad_line.ics
|
182
183
|
- spec/fixtures/timezone.ics
|
184
|
+
- spec/fixtures/two_date_time_events.ics
|
185
|
+
- spec/fixtures/two_day_events.ics
|
186
|
+
- spec/fixtures/two_time_events.ics
|
183
187
|
- spec/freebusy_spec.rb
|
184
188
|
- spec/journal_spec.rb
|
185
189
|
- spec/parser_spec.rb
|
@@ -200,6 +204,9 @@ metadata: {}
|
|
200
204
|
post_install_message: |
|
201
205
|
HEADS UP! iCalendar 2.0 is not backwards-compatible with 1.x. Please see the README for the new syntax
|
202
206
|
|
207
|
+
HEADS UP! icalendar 2.2.0 switches to non-strict parsing as default. Please see the README if you
|
208
|
+
rely on strict parsing for information on how to enable it.
|
209
|
+
|
203
210
|
ActiveSupport is required for TimeWithZone support, but not required for general use.
|
204
211
|
rdoc_options: []
|
205
212
|
require_paths:
|
@@ -227,7 +234,11 @@ test_files:
|
|
227
234
|
- spec/fixtures/nondefault_values.ics
|
228
235
|
- spec/fixtures/nonstandard.ics
|
229
236
|
- spec/fixtures/single_event.ics
|
237
|
+
- spec/fixtures/single_event_bad_line.ics
|
230
238
|
- spec/fixtures/timezone.ics
|
239
|
+
- spec/fixtures/two_date_time_events.ics
|
240
|
+
- spec/fixtures/two_day_events.ics
|
241
|
+
- spec/fixtures/two_time_events.ics
|
231
242
|
- spec/freebusy_spec.rb
|
232
243
|
- spec/journal_spec.rb
|
233
244
|
- spec/parser_spec.rb
|