tilia-vobject 4.0.0.pre.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +32 -0
  4. data/.simplecov +4 -0
  5. data/.travis.yml +3 -0
  6. data/CHANGELOG.sabre.md +626 -0
  7. data/CONTRIBUTING.md +25 -0
  8. data/Gemfile +17 -0
  9. data/Gemfile.lock +68 -0
  10. data/LICENSE +27 -0
  11. data/LICENSE.sabre +27 -0
  12. data/README.md +63 -0
  13. data/Rakefile +17 -0
  14. data/bin/vobject +7 -0
  15. data/lib/tilia/v_object/birthday_calendar_generator.rb +142 -0
  16. data/lib/tilia/v_object/cli.rb +582 -0
  17. data/lib/tilia/v_object/component/available.rb +107 -0
  18. data/lib/tilia/v_object/component/v_alarm.rb +114 -0
  19. data/lib/tilia/v_object/component/v_availability.rb +128 -0
  20. data/lib/tilia/v_object/component/v_calendar.rb +468 -0
  21. data/lib/tilia/v_object/component/v_card.rb +457 -0
  22. data/lib/tilia/v_object/component/v_event.rb +127 -0
  23. data/lib/tilia/v_object/component/v_free_busy.rb +81 -0
  24. data/lib/tilia/v_object/component/v_journal.rb +75 -0
  25. data/lib/tilia/v_object/component/v_time_zone.rb +51 -0
  26. data/lib/tilia/v_object/component/v_todo.rb +147 -0
  27. data/lib/tilia/v_object/component.rb +591 -0
  28. data/lib/tilia/v_object/date_time_parser.rb +486 -0
  29. data/lib/tilia/v_object/document.rb +218 -0
  30. data/lib/tilia/v_object/element_list.rb +18 -0
  31. data/lib/tilia/v_object/eof_exception.rb +8 -0
  32. data/lib/tilia/v_object/free_busy_data.rb +149 -0
  33. data/lib/tilia/v_object/free_busy_generator.rb +465 -0
  34. data/lib/tilia/v_object/i_tip/broker.rb +909 -0
  35. data/lib/tilia/v_object/i_tip/i_tip_exception.rb +9 -0
  36. data/lib/tilia/v_object/i_tip/message.rb +109 -0
  37. data/lib/tilia/v_object/i_tip/same_organizer_for_all_components_exception.rb +13 -0
  38. data/lib/tilia/v_object/i_tip.rb +10 -0
  39. data/lib/tilia/v_object/node.rb +192 -0
  40. data/lib/tilia/v_object/parameter.rb +327 -0
  41. data/lib/tilia/v_object/parse_exception.rb +7 -0
  42. data/lib/tilia/v_object/parser/json.rb +149 -0
  43. data/lib/tilia/v_object/parser/mime_dir.rb +543 -0
  44. data/lib/tilia/v_object/parser/parser.rb +61 -0
  45. data/lib/tilia/v_object/parser/xml/element/key_value.rb +60 -0
  46. data/lib/tilia/v_object/parser/xml/element.rb +11 -0
  47. data/lib/tilia/v_object/parser/xml.rb +322 -0
  48. data/lib/tilia/v_object/parser.rb +10 -0
  49. data/lib/tilia/v_object/property/binary.rb +96 -0
  50. data/lib/tilia/v_object/property/boolean.rb +57 -0
  51. data/lib/tilia/v_object/property/flat_text.rb +52 -0
  52. data/lib/tilia/v_object/property/float_value.rb +107 -0
  53. data/lib/tilia/v_object/property/i_calendar/cal_address.rb +49 -0
  54. data/lib/tilia/v_object/property/i_calendar/date.rb +15 -0
  55. data/lib/tilia/v_object/property/i_calendar/date_time.rb +330 -0
  56. data/lib/tilia/v_object/property/i_calendar/duration.rb +65 -0
  57. data/lib/tilia/v_object/property/i_calendar/period.rb +124 -0
  58. data/lib/tilia/v_object/property/i_calendar/recur.rb +173 -0
  59. data/lib/tilia/v_object/property/i_calendar.rb +14 -0
  60. data/lib/tilia/v_object/property/integer_value.rb +60 -0
  61. data/lib/tilia/v_object/property/text.rb +352 -0
  62. data/lib/tilia/v_object/property/time.rb +85 -0
  63. data/lib/tilia/v_object/property/unknown.rb +30 -0
  64. data/lib/tilia/v_object/property/uri.rb +78 -0
  65. data/lib/tilia/v_object/property/utc_offset.rb +56 -0
  66. data/lib/tilia/v_object/property/v_card/date.rb +31 -0
  67. data/lib/tilia/v_object/property/v_card/date_and_or_time.rb +343 -0
  68. data/lib/tilia/v_object/property/v_card/date_time.rb +22 -0
  69. data/lib/tilia/v_object/property/v_card/language_tag.rb +41 -0
  70. data/lib/tilia/v_object/property/v_card/time_stamp.rb +74 -0
  71. data/lib/tilia/v_object/property/v_card.rb +13 -0
  72. data/lib/tilia/v_object/property.rb +532 -0
  73. data/lib/tilia/v_object/reader.rb +73 -0
  74. data/lib/tilia/v_object/recur/event_iterator.rb +417 -0
  75. data/lib/tilia/v_object/recur/no_instances_exception.rb +11 -0
  76. data/lib/tilia/v_object/recur/r_date_iterator.rb +138 -0
  77. data/lib/tilia/v_object/recur/r_rule_iterator.rb +717 -0
  78. data/lib/tilia/v_object/recur.rb +10 -0
  79. data/lib/tilia/v_object/settings.rb +32 -0
  80. data/lib/tilia/v_object/splitter/i_calendar.rb +95 -0
  81. data/lib/tilia/v_object/splitter/splitter_interface.rb +31 -0
  82. data/lib/tilia/v_object/splitter/v_card.rb +56 -0
  83. data/lib/tilia/v_object/splitter.rb +9 -0
  84. data/lib/tilia/v_object/string_util.rb +58 -0
  85. data/lib/tilia/v_object/time_zone_data/exchange_zones.rb +96 -0
  86. data/lib/tilia/v_object/time_zone_data/lotus_zones.rb +104 -0
  87. data/lib/tilia/v_object/time_zone_data/php_zones.rb +49 -0
  88. data/lib/tilia/v_object/time_zone_data/windows_zones.rb +121 -0
  89. data/lib/tilia/v_object/time_zone_data.rb +10 -0
  90. data/lib/tilia/v_object/time_zone_util.rb +213 -0
  91. data/lib/tilia/v_object/uuid_util.rb +51 -0
  92. data/lib/tilia/v_object/v_card_converter.rb +354 -0
  93. data/lib/tilia/v_object/version.rb +9 -0
  94. data/lib/tilia/v_object/writer.rb +56 -0
  95. data/lib/tilia/v_object.rb +45 -0
  96. data/lib/tilia/vobject.rb +1 -0
  97. data/resources/schema/xcal.rng +1192 -0
  98. data/resources/schema/xcard.rng +388 -0
  99. data/test/test_helper.rb +56 -0
  100. data/test/v_object/attach_issue_test.rb +19 -0
  101. data/test/v_object/birthday_calendar_generator_test.rb +463 -0
  102. data/test/v_object/cli_mock.rb +19 -0
  103. data/test/v_object/cli_test.rb +460 -0
  104. data/test/v_object/component/available_test.rb +59 -0
  105. data/test/v_object/component/v_alarm_test.rb +160 -0
  106. data/test/v_object/component/v_availability_test.rb +388 -0
  107. data/test/v_object/component/v_calendar_test.rb +646 -0
  108. data/test/v_object/component/v_card_test.rb +258 -0
  109. data/test/v_object/component/v_event_test.rb +85 -0
  110. data/test/v_object/component/v_free_busy_test.rb +59 -0
  111. data/test/v_object/component/v_journal_test.rb +85 -0
  112. data/test/v_object/component/v_time_zone_test.rb +47 -0
  113. data/test/v_object/component/v_todo_test.rb +172 -0
  114. data/test/v_object/component_test.rb +419 -0
  115. data/test/v_object/date_time_parser_test.rb +526 -0
  116. data/test/v_object/document_test.rb +71 -0
  117. data/test/v_object/element_list_test.rb +27 -0
  118. data/test/v_object/em_client_test.rb +53 -0
  119. data/test/v_object/empty_parameter_test.rb +65 -0
  120. data/test/v_object/empty_value_issue_test.rb +25 -0
  121. data/test/v_object/fake_component.rb +21 -0
  122. data/test/v_object/free_busy_data_test.rb +285 -0
  123. data/test/v_object/free_busy_generator_test.rb +637 -0
  124. data/test/v_object/google_colon_escaping_test.rb +27 -0
  125. data/test/v_object/i_calendar/attach_parse_test.rb +24 -0
  126. data/test/v_object/i_tip/broker_attendee_reply_test.rb +1042 -0
  127. data/test/v_object/i_tip/broker_delete_event_test.rb +175 -0
  128. data/test/v_object/i_tip/broker_new_event_test.rb +440 -0
  129. data/test/v_object/i_tip/broker_process_message_test.rb +153 -0
  130. data/test/v_object/i_tip/broker_process_reply_test.rb +402 -0
  131. data/test/v_object/i_tip/broker_tester.rb +71 -0
  132. data/test/v_object/i_tip/broker_update_event_test.rb +763 -0
  133. data/test/v_object/i_tip/evolution_test.rb +2644 -0
  134. data/test/v_object/i_tip/message_test.rb +25 -0
  135. data/test/v_object/issue153.vcf +352 -0
  136. data/test/v_object/issue153_test.rb +12 -0
  137. data/test/v_object/issue26_test.rb +25 -0
  138. data/test/v_object/issue36_work_around_test.rb +37 -0
  139. data/test/v_object/issue40_test.rb +26 -0
  140. data/test/v_object/issue64.vcf +351 -0
  141. data/test/v_object/issue64_test.rb +17 -0
  142. data/test/v_object/issue96_test.rb +22 -0
  143. data/test/v_object/issue_undefined_index_test.rb +24 -0
  144. data/test/v_object/j_cal_test.rb +150 -0
  145. data/test/v_object/j_card_test.rb +192 -0
  146. data/test/v_object/line_folding_issue_test.rb +19 -0
  147. data/test/v_object/mock_document.rb +6 -0
  148. data/test/v_object/parameter_test.rb +109 -0
  149. data/test/v_object/parser/json_test.rb +370 -0
  150. data/test/v_object/parser/mime_dir_test.rb +14 -0
  151. data/test/v_object/parser/quoted_printable_test.rb +78 -0
  152. data/test/v_object/parser/xml_test.rb +2563 -0
  153. data/test/v_object/property/binary_test.rb +12 -0
  154. data/test/v_object/property/boolean_test.rb +18 -0
  155. data/test/v_object/property/compound_test.rb +43 -0
  156. data/test/v_object/property/float_test.rb +20 -0
  157. data/test/v_object/property/i_calendar/cal_address_test.rb +26 -0
  158. data/test/v_object/property/i_calendar/date_time_test.rb +303 -0
  159. data/test/v_object/property/i_calendar/duration_test.rb +14 -0
  160. data/test/v_object/property/i_calendar/recur_test.rb +39 -0
  161. data/test/v_object/property/text_test.rb +81 -0
  162. data/test/v_object/property/v_card/date_and_or_time_test.rb +205 -0
  163. data/test/v_object/property/v_card/language_tag_test.rb +35 -0
  164. data/test/v_object/property_test.rb +338 -0
  165. data/test/v_object/reader_test.rb +403 -0
  166. data/test/v_object/recur/event_iterator/by_month_in_daily_test.rb +52 -0
  167. data/test/v_object/recur/event_iterator/by_set_pos_hang_test.rb +55 -0
  168. data/test/v_object/recur/event_iterator/expand_floating_times_test.rb +109 -0
  169. data/test/v_object/recur/event_iterator/fifth_tuesday_problem_test.rb +45 -0
  170. data/test/v_object/recur/event_iterator/incorrect_expand_test.rb +53 -0
  171. data/test/v_object/recur/event_iterator/infinite_loop_problem_test.rb +75 -0
  172. data/test/v_object/recur/event_iterator/issue48_test.rb +43 -0
  173. data/test/v_object/recur/event_iterator/issue50_test.rb +123 -0
  174. data/test/v_object/recur/event_iterator/main_test.rb +1222 -0
  175. data/test/v_object/recur/event_iterator/missing_overridden_test.rb +55 -0
  176. data/test/v_object/recur/event_iterator/no_instances_test.rb +32 -0
  177. data/test/v_object/recur/event_iterator/override_first_event_test.rb +106 -0
  178. data/test/v_object/recur/r_date_iterator_test.rb +44 -0
  179. data/test/v_object/recur/r_rule_iterator_test.rb +608 -0
  180. data/test/v_object/recurrence_iterator/UntilRespectsTimezoneTest.ics +39 -0
  181. data/test/v_object/slash_r_test.rb +15 -0
  182. data/test/v_object/splitter/i_calendar_test.rb +299 -0
  183. data/test/v_object/splitter/v_card_test.rb +173 -0
  184. data/test/v_object/string_util_test.rb +37 -0
  185. data/test/v_object/test_case.rb +42 -0
  186. data/test/v_object/time_zone_util_test.rb +271 -0
  187. data/test/v_object/uuid_util_test.rb +18 -0
  188. data/test/v_object/v_card21_test.rb +43 -0
  189. data/test/v_object/v_card_converter_test.rb +419 -0
  190. data/test/v_object/version_test.rb +15 -0
  191. data/test/v_object/writer_test.rb +33 -0
  192. data/tilia-vobject.gemspec +17 -0
  193. metadata +308 -0
@@ -0,0 +1,608 @@
1
+ require 'test_helper'
2
+
3
+ module Tilia
4
+ module VObject
5
+ class RRuleIteratorTest < Minitest::Test
6
+ def parse(rule, start, expected, fast_forward = nil, tz = 'UTC')
7
+ tz = ActiveSupport::TimeZone.new(tz)
8
+ dt = tz.parse(start)
9
+ parser = Tilia::VObject::Recur::RRuleIterator.new(rule, dt)
10
+
11
+ parser.fast_forward(tz.parse(fast_forward)) if fast_forward
12
+
13
+ result = []
14
+ while parser.valid
15
+ item = parser.current
16
+ result << item.strftime('%Y-%m-%d %H:%M:%S')
17
+
18
+ break if parser.infinite? && result.size >= expected.size
19
+ parser.next
20
+ end
21
+
22
+ assert_equal(expected, result)
23
+ end
24
+
25
+ def test_hourly
26
+ parse(
27
+ 'FREQ=HOURLY;INTERVAL=3;COUNT=12',
28
+ '2011-10-07 12:00:00',
29
+ [
30
+ '2011-10-07 12:00:00',
31
+ '2011-10-07 15:00:00',
32
+ '2011-10-07 18:00:00',
33
+ '2011-10-07 21:00:00',
34
+ '2011-10-08 00:00:00',
35
+ '2011-10-08 03:00:00',
36
+ '2011-10-08 06:00:00',
37
+ '2011-10-08 09:00:00',
38
+ '2011-10-08 12:00:00',
39
+ '2011-10-08 15:00:00',
40
+ '2011-10-08 18:00:00',
41
+ '2011-10-08 21:00:00'
42
+ ]
43
+ )
44
+ end
45
+
46
+ def test_daily
47
+ parse(
48
+ 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z',
49
+ '2011-10-07',
50
+ [
51
+ '2011-10-07 00:00:00',
52
+ '2011-10-10 00:00:00',
53
+ '2011-10-13 00:00:00',
54
+ '2011-10-16 00:00:00',
55
+ '2011-10-19 00:00:00',
56
+ '2011-10-22 00:00:00',
57
+ '2011-10-25 00:00:00'
58
+ ]
59
+ )
60
+ end
61
+
62
+ def test_daily_by_day_by_hour
63
+ parse(
64
+ 'FREQ=DAILY;BYDAY=SA,SU;BYHOUR=6,7',
65
+ '2011-10-08 06:00:00',
66
+ [
67
+ '2011-10-08 06:00:00',
68
+ '2011-10-08 07:00:00',
69
+ '2011-10-09 06:00:00',
70
+ '2011-10-09 07:00:00',
71
+ '2011-10-15 06:00:00',
72
+ '2011-10-15 07:00:00',
73
+ '2011-10-16 06:00:00',
74
+ '2011-10-16 07:00:00',
75
+ '2011-10-22 06:00:00',
76
+ '2011-10-22 07:00:00',
77
+ '2011-10-23 06:00:00',
78
+ '2011-10-23 07:00:00'
79
+ ]
80
+ )
81
+ end
82
+
83
+ def test_daily_by_hour
84
+ parse(
85
+ 'FREQ=DAILY;INTERVAL=2;BYHOUR=10,11,12,13,14,15',
86
+ '2012-10-11 12:00:00',
87
+ [
88
+ '2012-10-11 12:00:00',
89
+ '2012-10-11 13:00:00',
90
+ '2012-10-11 14:00:00',
91
+ '2012-10-11 15:00:00',
92
+ '2012-10-13 10:00:00',
93
+ '2012-10-13 11:00:00',
94
+ '2012-10-13 12:00:00',
95
+ '2012-10-13 13:00:00',
96
+ '2012-10-13 14:00:00',
97
+ '2012-10-13 15:00:00',
98
+ '2012-10-15 10:00:00',
99
+ '2012-10-15 11:00:00'
100
+ ]
101
+ )
102
+ end
103
+
104
+ def test_daily_by_day
105
+ parse(
106
+ 'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR',
107
+ '2011-10-07 12:00:00',
108
+ [
109
+ '2011-10-07 12:00:00',
110
+ '2011-10-11 12:00:00',
111
+ '2011-10-19 12:00:00',
112
+ '2011-10-21 12:00:00',
113
+ '2011-10-25 12:00:00',
114
+ '2011-11-02 12:00:00',
115
+ '2011-11-04 12:00:00',
116
+ '2011-11-08 12:00:00',
117
+ '2011-11-16 12:00:00',
118
+ '2011-11-18 12:00:00',
119
+ '2011-11-22 12:00:00',
120
+ '2011-11-30 12:00:00'
121
+ ]
122
+ )
123
+ end
124
+
125
+ def test_daily_count
126
+ parse(
127
+ 'FREQ=DAILY;COUNT=5',
128
+ '2014-08-01 18:03:00',
129
+ [
130
+ '2014-08-01 18:03:00',
131
+ '2014-08-02 18:03:00',
132
+ '2014-08-03 18:03:00',
133
+ '2014-08-04 18:03:00',
134
+ '2014-08-05 18:03:00'
135
+ ]
136
+ )
137
+ end
138
+
139
+ def test_daily_by_month
140
+ parse(
141
+ 'FREQ=DAILY;BYMONTH=9,10;BYDAY=SU',
142
+ '2007-10-04 16:00:00',
143
+ [
144
+ '2013-09-29 16:00:00',
145
+ '2013-10-06 16:00:00',
146
+ '2013-10-13 16:00:00',
147
+ '2013-10-20 16:00:00',
148
+ '2013-10-27 16:00:00',
149
+ '2014-09-07 16:00:00'
150
+ ],
151
+ '2013-09-28'
152
+ )
153
+ end
154
+
155
+ def test_weekly
156
+ parse(
157
+ 'FREQ=WEEKLY;INTERVAL=2;COUNT=10',
158
+ '2011-10-07 00:00:00',
159
+ [
160
+ '2011-10-07 00:00:00',
161
+ '2011-10-21 00:00:00',
162
+ '2011-11-04 00:00:00',
163
+ '2011-11-18 00:00:00',
164
+ '2011-12-02 00:00:00',
165
+ '2011-12-16 00:00:00',
166
+ '2011-12-30 00:00:00',
167
+ '2012-01-13 00:00:00',
168
+ '2012-01-27 00:00:00',
169
+ '2012-02-10 00:00:00'
170
+ ]
171
+ )
172
+ end
173
+
174
+ def test_weekly_by_day
175
+ parse(
176
+ 'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=MO;WKST=SA',
177
+ '2014-08-01 00:00:00',
178
+ [
179
+ '2014-08-01 00:00:00',
180
+ '2014-08-04 00:00:00',
181
+ '2014-08-11 00:00:00',
182
+ '2014-08-18 00:00:00'
183
+ ]
184
+ )
185
+ end
186
+
187
+ def test_weekly_by_day2
188
+ parse(
189
+ 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
190
+ '2011-10-07 00:00:00',
191
+ [
192
+ '2011-10-07 00:00:00',
193
+ '2011-10-18 00:00:00',
194
+ '2011-10-19 00:00:00',
195
+ '2011-10-21 00:00:00',
196
+ '2011-11-01 00:00:00',
197
+ '2011-11-02 00:00:00',
198
+ '2011-11-04 00:00:00',
199
+ '2011-11-15 00:00:00',
200
+ '2011-11-16 00:00:00',
201
+ '2011-11-18 00:00:00',
202
+ '2011-11-29 00:00:00',
203
+ '2011-11-30 00:00:00'
204
+ ]
205
+ )
206
+ end
207
+
208
+ def test_weekly_by_day_by_hour
209
+ parse(
210
+ 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=MO;BYHOUR=8,9,10',
211
+ '2011-10-07 08:00:00',
212
+ [
213
+ '2011-10-07 08:00:00',
214
+ '2011-10-07 09:00:00',
215
+ '2011-10-07 10:00:00',
216
+ '2011-10-18 08:00:00',
217
+ '2011-10-18 09:00:00',
218
+ '2011-10-18 10:00:00',
219
+ '2011-10-19 08:00:00',
220
+ '2011-10-19 09:00:00',
221
+ '2011-10-19 10:00:00',
222
+ '2011-10-21 08:00:00',
223
+ '2011-10-21 09:00:00',
224
+ '2011-10-21 10:00:00',
225
+ '2011-11-01 08:00:00',
226
+ '2011-11-01 09:00:00',
227
+ '2011-11-01 10:00:00'
228
+ ]
229
+ )
230
+ end
231
+
232
+ def test_weekly_by_day_specific_hour
233
+ parse(
234
+ 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
235
+ '2011-10-07 18:00:00',
236
+ [
237
+ '2011-10-07 18:00:00',
238
+ '2011-10-18 18:00:00',
239
+ '2011-10-19 18:00:00',
240
+ '2011-10-21 18:00:00',
241
+ '2011-11-01 18:00:00',
242
+ '2011-11-02 18:00:00',
243
+ '2011-11-04 18:00:00',
244
+ '2011-11-15 18:00:00',
245
+ '2011-11-16 18:00:00',
246
+ '2011-11-18 18:00:00',
247
+ '2011-11-29 18:00:00',
248
+ '2011-11-30 18:00:00'
249
+ ]
250
+ )
251
+ end
252
+
253
+ def test_monthly
254
+ parse(
255
+ 'FREQ=MONTHLY;INTERVAL=3;COUNT=5',
256
+ '2011-12-05 00:00:00',
257
+ [
258
+ '2011-12-05 00:00:00',
259
+ '2012-03-05 00:00:00',
260
+ '2012-06-05 00:00:00',
261
+ '2012-09-05 00:00:00',
262
+ '2012-12-05 00:00:00'
263
+ ]
264
+ )
265
+ end
266
+
267
+ def test_monlthy_end_of_month
268
+ parse(
269
+ 'FREQ=MONTHLY;INTERVAL=2;COUNT=12',
270
+ '2011-12-31 00:00:00',
271
+ [
272
+ '2011-12-31 00:00:00',
273
+ '2012-08-31 00:00:00',
274
+ '2012-10-31 00:00:00',
275
+ '2012-12-31 00:00:00',
276
+ '2013-08-31 00:00:00',
277
+ '2013-10-31 00:00:00',
278
+ '2013-12-31 00:00:00',
279
+ '2014-08-31 00:00:00',
280
+ '2014-10-31 00:00:00',
281
+ '2014-12-31 00:00:00',
282
+ '2015-08-31 00:00:00',
283
+ '2015-10-31 00:00:00'
284
+ ]
285
+ )
286
+ end
287
+
288
+ def test_monthly_by_month_day
289
+ parse(
290
+ 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7',
291
+ '2011-01-01 00:00:00',
292
+ [
293
+ '2011-01-01 00:00:00',
294
+ '2011-01-25 00:00:00',
295
+ '2011-01-31 00:00:00',
296
+ '2011-06-01 00:00:00',
297
+ '2011-06-24 00:00:00',
298
+ '2011-11-01 00:00:00',
299
+ '2011-11-24 00:00:00',
300
+ '2012-04-01 00:00:00',
301
+ '2012-04-24 00:00:00'
302
+ ]
303
+ )
304
+ end
305
+
306
+ def test_monthly_by_day
307
+ parse(
308
+ 'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH',
309
+ '2011-01-03 00:00:00',
310
+ [
311
+ '2011-01-03 00:00:00',
312
+ '2011-01-05 00:00:00',
313
+ '2011-01-10 00:00:00',
314
+ '2011-01-17 00:00:00',
315
+ '2011-01-18 00:00:00',
316
+ '2011-01-20 00:00:00',
317
+ '2011-01-24 00:00:00',
318
+ '2011-01-31 00:00:00',
319
+ '2011-03-02 00:00:00',
320
+ '2011-03-07 00:00:00',
321
+ '2011-03-14 00:00:00',
322
+ '2011-03-17 00:00:00',
323
+ '2011-03-21 00:00:00',
324
+ '2011-03-22 00:00:00',
325
+ '2011-03-28 00:00:00',
326
+ '2011-05-02 00:00:00'
327
+ ]
328
+ )
329
+ end
330
+
331
+ def test_monthly_by_day_by_month_day
332
+ parse(
333
+ 'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1',
334
+ '2011-08-01 00:00:00',
335
+ [
336
+ '2011-08-01 00:00:00',
337
+ '2012-10-01 00:00:00',
338
+ '2013-04-01 00:00:00',
339
+ '2013-07-01 00:00:00',
340
+ '2014-09-01 00:00:00',
341
+ '2014-12-01 00:00:00',
342
+ '2015-06-01 00:00:00',
343
+ '2016-02-01 00:00:00',
344
+ '2016-08-01 00:00:00',
345
+ '2017-05-01 00:00:00'
346
+ ]
347
+ )
348
+ end
349
+
350
+ def test_monthly_by_day_by_set_pos
351
+ parse(
352
+ 'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1',
353
+ '2011-01-03 00:00:00',
354
+ [
355
+ '2011-01-03 00:00:00',
356
+ '2011-01-31 00:00:00',
357
+ '2011-02-01 00:00:00',
358
+ '2011-02-28 00:00:00',
359
+ '2011-03-01 00:00:00',
360
+ '2011-03-31 00:00:00',
361
+ '2011-04-01 00:00:00',
362
+ '2011-04-29 00:00:00',
363
+ '2011-05-02 00:00:00',
364
+ '2011-05-31 00:00:00'
365
+ ]
366
+ )
367
+ end
368
+
369
+ def test_yearly
370
+ parse(
371
+ 'FREQ=YEARLY;COUNT=10;INTERVAL=3',
372
+ '2011-01-01 00:00:00',
373
+ [
374
+ '2011-01-01 00:00:00',
375
+ '2014-01-01 00:00:00',
376
+ '2017-01-01 00:00:00',
377
+ '2020-01-01 00:00:00',
378
+ '2023-01-01 00:00:00',
379
+ '2026-01-01 00:00:00',
380
+ '2029-01-01 00:00:00',
381
+ '2032-01-01 00:00:00',
382
+ '2035-01-01 00:00:00',
383
+ '2038-01-01 00:00:00'
384
+ ]
385
+ )
386
+ end
387
+
388
+ def test_yearly_leap_year
389
+ parse(
390
+ 'FREQ=YEARLY;COUNT=3',
391
+ '2012-02-29 00:00:00',
392
+ [
393
+ '2012-02-29 00:00:00',
394
+ '2016-02-29 00:00:00',
395
+ '2020-02-29 00:00:00'
396
+ ]
397
+ )
398
+ end
399
+
400
+ def test_yearly_by_month
401
+ parse(
402
+ 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10',
403
+ '2011-04-07 00:00:00',
404
+ [
405
+ '2011-04-07 00:00:00',
406
+ '2011-10-07 00:00:00',
407
+ '2015-04-07 00:00:00',
408
+ '2015-10-07 00:00:00',
409
+ '2019-04-07 00:00:00',
410
+ '2019-10-07 00:00:00',
411
+ '2023-04-07 00:00:00',
412
+ '2023-10-07 00:00:00'
413
+ ]
414
+ )
415
+ end
416
+
417
+ def test_yearly_by_month_by_day
418
+ parse(
419
+ 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
420
+ '2011-04-04 00:00:00',
421
+ [
422
+ '2011-04-04 00:00:00',
423
+ '2011-04-24 00:00:00',
424
+ '2011-10-03 00:00:00',
425
+ '2011-10-30 00:00:00',
426
+ '2016-04-04 00:00:00',
427
+ '2016-04-24 00:00:00',
428
+ '2016-10-03 00:00:00',
429
+ '2016-10-30 00:00:00'
430
+ ]
431
+ )
432
+ end
433
+
434
+ def test_fast_forward
435
+ # The idea is that we're fast-forwarding too far in the future, so
436
+ # there will be no results left.
437
+ parse(
438
+ 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
439
+ '2011-04-04 00:00:00',
440
+ [],
441
+ '2020-05-05 00:00:00'
442
+ )
443
+ end
444
+
445
+ # The bug that was in the
446
+ # system before would fail on the 5th tuesday of the month, if the 5th
447
+ # tuesday did not exist.
448
+ #
449
+ # A pretty slow test. Had to be marked as 'medium' for phpunit to not die
450
+ # after 1 second. Would be good to optimize later.
451
+ def test_fifth_tuesday_problem
452
+ parse(
453
+ 'FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU',
454
+ '2007-10-04 14:46:42',
455
+ [
456
+ '2007-10-04 14:46:42'
457
+ ]
458
+ )
459
+ end
460
+
461
+ # This bug came from a Fruux customer. This would result in a never-ending
462
+ # request.
463
+ def test_fast_foward_too_far
464
+ parse(
465
+ 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1',
466
+ '2009-04-20 18:00:00',
467
+ [
468
+ '2009-04-20 18:00:00',
469
+ '2009-04-27 18:00:00',
470
+ '2009-05-04 18:00:00',
471
+ '2009-05-11 18:00:00',
472
+ '2009-05-18 18:00:00',
473
+ '2009-05-25 18:00:00',
474
+ '2009-06-01 18:00:00',
475
+ '2009-06-08 18:00:00',
476
+ '2009-06-15 18:00:00',
477
+ '2009-06-22 18:00:00',
478
+ '2009-06-29 18:00:00'
479
+ ]
480
+ )
481
+ end
482
+
483
+ # This also at one point caused an infinite loop. We're keeping the test.
484
+ def test_yearly_by_month_loop
485
+ parse(
486
+ 'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
487
+ '2012-01-01 15:45:00',
488
+ [
489
+ '2012-02-01 15:45:00'
490
+ ],
491
+ '2012-01-29 23:00:00'
492
+ )
493
+ end
494
+
495
+ # Something, somewhere produced an ics with an interval set to 0. Because
496
+ # this means we increase the current day (or week, month) by 0, this also
497
+ # results in an infinite loop.
498
+ def test_zero_interval
499
+ assert_raises(ArgumentError) do
500
+ parse(
501
+ 'FREQ=YEARLY;INTERVAL=0',
502
+ '2012-08-24 14:57:00',
503
+ [],
504
+ '2013-01-01 23:00:00'
505
+ )
506
+ end
507
+ end
508
+
509
+ def test_invalid_freq
510
+ assert_raises(ArgumentError) do
511
+ parse(
512
+ 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z',
513
+ '2011-10-07',
514
+ []
515
+ )
516
+ end
517
+ end
518
+
519
+ def test_by_day_bad_offset
520
+ assert_raises(ArgumentError) do
521
+ parse(
522
+ 'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=0MO;WKST=SA',
523
+ '2014-08-01 00:00:00',
524
+ []
525
+ )
526
+ end
527
+ end
528
+
529
+ def test_until_begin_has_timezone
530
+ parse(
531
+ 'FREQ=WEEKLY;UNTIL=20131118T183000',
532
+ '2013-09-23 18:30:00',
533
+ [
534
+ '2013-09-23 18:30:00',
535
+ '2013-09-30 18:30:00',
536
+ '2013-10-07 18:30:00',
537
+ '2013-10-14 18:30:00',
538
+ '2013-10-21 18:30:00',
539
+ '2013-10-28 18:30:00',
540
+ '2013-11-04 18:30:00',
541
+ '2013-11-11 18:30:00',
542
+ '2013-11-18 18:30:00'
543
+ ],
544
+ nil,
545
+ 'America/New_York'
546
+ )
547
+ end
548
+
549
+ def test_until_before_dt_start
550
+ parse(
551
+ 'FREQ=DAILY;UNTIL=20140101T000000Z',
552
+ '2014-08-02 00:15:00',
553
+ [
554
+ '2014-08-02 00:15:00'
555
+ ]
556
+ )
557
+ end
558
+
559
+ def test_ignored_stuff
560
+ parse(
561
+ 'FREQ=DAILY;BYSECOND=1;BYMINUTE=1;BYYEARDAY=1;BYWEEKNO=1;COUNT=2',
562
+ '2014-08-02 00:15:00',
563
+ [
564
+ '2014-08-02 00:15:00',
565
+ '2014-08-03 00:15:00'
566
+ ]
567
+ )
568
+ end
569
+
570
+ def test_minus_fifth_thursday
571
+ parse(
572
+ 'FREQ=MONTHLY;BYDAY=-4TH,-5TH;COUNT=4',
573
+ '2015-01-01 00:15:00',
574
+ [
575
+ '2015-01-01 00:15:00',
576
+ '2015-01-08 00:15:00',
577
+ '2015-02-05 00:15:00',
578
+ '2015-03-05 00:15:00'
579
+ ]
580
+ )
581
+ end
582
+
583
+ def test_unsupported_part
584
+ assert_raises(ArgumentError) do
585
+ parse(
586
+ 'FREQ=DAILY;BYWODAN=1',
587
+ '2014-08-02 00:15:00',
588
+ []
589
+ )
590
+ end
591
+ end
592
+
593
+ def test_iterator_functions
594
+ parser = Tilia::VObject::Recur::RRuleIterator.new('FREQ=DAILY', Time.zone.parse('2014-08-02 00:00:13'))
595
+ parser.next
596
+ assert_equal(Time.zone.parse('2014-08-03 00:00:13'), parser.current)
597
+
598
+ assert_equal(1, parser.key)
599
+
600
+ parser.rewind
601
+
602
+ assert_equal(Time.zone.parse('2014-08-02 00:00:13'), parser.current)
603
+
604
+ assert_equal(0, parser.key)
605
+ end
606
+ end
607
+ end
608
+ end
@@ -0,0 +1,39 @@
1
+ BEGIN:VCALENDAR
2
+ VERSION:2.0
3
+ X-WR-TIMEZONE:America/New_York
4
+ PRODID:-//www.churchcommunitybuilder.com//Church Community Builder//EN
5
+ CALSCALE:GREGORIAN
6
+ METHOD:PUBLISH
7
+ X-WR-CALNAME:Test Event
8
+ BEGIN:VTIMEZONE
9
+ TZID:America/New_York
10
+ X-LIC-LOCATION:America/New_York
11
+ BEGIN:DAYLIGHT
12
+ TZOFFSETFROM:-0500
13
+ TZOFFSETTO:-0400
14
+ TZNAME:EDT
15
+ DTSTART:19700308T020000
16
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
17
+ END:DAYLIGHT
18
+ BEGIN:STANDARD
19
+ TZOFFSETFROM:-0400
20
+ TZOFFSETTO:-0500
21
+ TZNAME:EST
22
+ DTSTART:19701101T020000
23
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
24
+ END:STANDARD
25
+ END:VTIMEZONE
26
+ BEGIN:VEVENT
27
+ UID:10621-1440@ccbchurch.com
28
+ DTSTART;TZID=America/New_York:20130923T183000
29
+ DTEND;TZID=America/New_York:20130923T203000
30
+ DTSTAMP:20131216T170211
31
+ RRULE:FREQ=WEEKLY;UNTIL=20131118T183000
32
+ CREATED:20130423T161111
33
+ DESCRIPTION:Test Event ending November 11, 2013
34
+ LAST-MODIFIED:20131126T163428
35
+ SEQUENCE:1387231331
36
+ SUMMARY:Test
37
+ TRANSP:OPAQUE
38
+ END:VEVENT
39
+ END:VCALENDAR
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ module Tilia
4
+ module VObject
5
+ # This issue was pointed out in Issue 55. \r should be stripped completely
6
+ # when encoding property values.
7
+ class SlashRTest < Minitest::Test
8
+ def test_encode
9
+ vcal = Tilia::VObject::Component::VCalendar.new
10
+ prop = vcal.add('test', "abc\r\ndef")
11
+ assert_equal("TEST:abc\\ndef\r\n", prop.serialize)
12
+ end
13
+ end
14
+ end
15
+ end