vpim 0.619 → 0.658

Sign up to get free protection for your applications and to get access to all the features.
@@ -118,7 +118,7 @@ end
118
118
  puts
119
119
 
120
120
  def start_of_first_occurrence(t0, t1, e)
121
- e.occurrences.each_until(t1).each do |t|
121
+ e.occurrences(t1) do |t|
122
122
  # An event might start before t0, but end after it..., in which case
123
123
  # we are still interested.
124
124
  if (t + (e.duration || 0)) >= t0
@@ -1,14 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'pp'
4
+
3
5
  $-w = true
4
- $:.unshift File.dirname($0)
6
+
7
+ $:.unshift File.dirname(__FILE__) + "/../lib"
8
+
9
+
10
+ pp [__LINE__, $:, $"]
5
11
 
6
12
  require 'test/unit'
7
13
 
8
- require 'test_date.rb'
9
- require 'test_dur.rb'
10
- require 'test_field.rb'
11
- require 'test_ical.rb'
12
- require 'test_rrule.rb'
13
- require 'test_vcard.rb'
14
+ Dir[File.dirname(__FILE__) + "/test_*.rb"].each do |test|
15
+ require test unless test =~ /test_all/
16
+ end
14
17
 
@@ -8,8 +8,8 @@ class TestVpimDate < Test::Unit::TestCase
8
8
 
9
9
  def test_to_time
10
10
  # Need to test with DateTime, but I don't have that with ruby 1.6.
11
- assert_equal(Time.at(0), Date.new(1970, 1, 1).to_time)
12
- assert_equal(Time.at(24 * 60 * 60), Date.new(1970, 1, 2).to_time)
11
+ assert_equal(Time.at(0), Date.new(1970, 1, 1).vpim_to_time)
12
+ assert_equal(Time.at(24 * 60 * 60), Date.new(1970, 1, 2).vpim_to_time)
13
13
  end
14
14
 
15
15
  def test_date_weekstart
@@ -3,6 +3,14 @@
3
3
  require 'vpim/icalendar'
4
4
  require 'test/unit'
5
5
 
6
+
7
+ # Sorry for the donkey patching...
8
+ module Enumerable
9
+ def first
10
+ find{true}
11
+ end
12
+ end
13
+
6
14
  include Vpim
7
15
 
8
16
  Req_1 =<<___
@@ -86,6 +94,10 @@ ___
86
94
 
87
95
  class TestIcal < Test::Unit::TestCase
88
96
 
97
+ def assert_time(expected, actual, msg = nil)
98
+ assert_in_delta(expected, actual, 1, msg)
99
+ end
100
+
89
101
  # Reported by Kyle Maxwell
90
102
  def test_serialize_todo
91
103
  icstodo =<<___
@@ -171,10 +183,12 @@ ___
171
183
 
172
184
  # FIXME - test bad durations, like 'PT1D'
173
185
 
174
- def test_duration
175
- event = Icalendar::Vevent.create(Date.new(2000, 1, 21))
176
- assert_equal(nil, event.duration)
177
- assert_equal(nil, event.dtend)
186
+ def test_event_duration
187
+ now = Time.now
188
+ event = Icalendar::Vevent.create(now)
189
+ assert_time(now, event.dtstart)
190
+ assert_nil(event.duration)
191
+ assert_nil(event.dtend)
178
192
 
179
193
  event = Icalendar::Vevent.create(Date.new(2000, 1, 21),
180
194
  'DURATION' => 'PT1H')
@@ -185,6 +199,33 @@ ___
185
199
  assert_equal(24*60*60, event.duration)
186
200
  end
187
201
 
202
+ def test_todo_duration
203
+ todo = Icalendar::Vtodo.create()
204
+ assert_nil(todo.dtstart)
205
+ assert_nil(todo.duration)
206
+ assert_nil(todo.due)
207
+
208
+ todo = Icalendar::Vtodo.create('DTSTART' => Date.new(2000, 1, 21),
209
+ 'DURATION' => 'PT1H')
210
+ assert_equal(Time.gm(2000, 1, 21, 1), todo.due)
211
+
212
+ todo = Icalendar::Vtodo.create('DTSTART' => Date.new(2000, 1, 21),
213
+ 'DUE' => Date.new(2000, 1, 22))
214
+ assert_equal(24*60*60, todo.duration)
215
+ end
216
+
217
+ def test_journal_create
218
+ vj = Icalendar::Vjournal.create('DESCRIPTION' => "description")
219
+ assert_equal("description", vj.description)
220
+ end
221
+
222
+ def TODO_test_occurrence_with_date_start
223
+ d = Date.new(2000, 1, 21)
224
+ event = Icalendar::Vevent.create(d)
225
+ d1 = event.occurences.to_a.first
226
+ assert_equal(d.class, d1.class)
227
+ end
228
+
188
229
  def test_decode_duration_four_weeks
189
230
  assert_equal 4*7*86400, Icalendar.decode_duration('P4W')
190
231
  end
@@ -216,5 +257,159 @@ ___
216
257
  def test_decode_duration_with_composite_duration
217
258
  assert_equal((15*86400+5*3600+20), Icalendar.decode_duration('P15DT5H0M20S'))
218
259
  end
260
+
261
+ def test_create_with_prodid
262
+ prodid = "me//here/non-sgml"
263
+ cal = Icalendar.create2(prodid) do |cal|
264
+ assert_respond_to(cal, :push)
265
+ end
266
+ assert_equal(prodid, cal.producer)
267
+ end
268
+
269
+ def test_occurences
270
+ t0 = Time.now
271
+ vc = Icalendar.create2 do |vc|
272
+ vc.add_event do |ve|
273
+ ve.dtstart t0
274
+ end
275
+ end
276
+ ve = vc.components(Icalendar::Vevent).first
277
+ assert_time(t0, ve.occurences.select{true}.first)
278
+ ve.occurences do |t|
279
+ assert_time(t0, t)
280
+ end
281
+
282
+ vc = Icalendar.decode(<<__).first
283
+ BEGIN:VCALENDAR
284
+ BEGIN:VEVENT
285
+ END:VEVENT
286
+ END:VCALENDAR
287
+ __
288
+ ve = vc.components(Icalendar::Vevent).first
289
+ assert_raises(ArgumentError) { ve.occurences }
290
+ end
291
+
292
+ def test_each
293
+ vc = Icalendar.decode(<<__).first
294
+ BEGIN:VCALENDAR
295
+ BEGIN:VEVENT
296
+ END:VEVENT
297
+ BEGIN:VTODO
298
+ END:VTODO
299
+ BEGIN:VJOURNAL
300
+ END:VJOURNAL
301
+ BEGIN:VTIMEZONE
302
+ END:VTIMEZONE
303
+ BEGIN:X-UNKNOWN
304
+ END:X-UNKNOWN
305
+ END:VCALENDAR
306
+ __
307
+ count = Hash.new(0)
308
+
309
+ vc.each do |c| count[c.class] += 1 end
310
+
311
+ assert_equal(3, count.size)
312
+ count.each do |_,v| assert_equal(1, v) end
313
+
314
+ count = Hash.new(0)
315
+ vc.events do |c| count[c.class] += 1 end
316
+ vc.todos do |c| count[c.class] += 1 end
317
+ vc.journals do |c| count[c.class] += 1 end
318
+ assert_equal(3, count.size)
319
+ count.each do |_,v| assert_equal(1, v) end
320
+
321
+ assert_equal(3, vc.each.to_a.size)
322
+ assert_equal(1, vc.each.select{|c| Vpim::Icalendar::Vevent === c}.size)
323
+ assert_equal(1, vc.each.select{|c| Vpim::Icalendar::Vtodo === c}.size)
324
+ assert_equal(1, vc.each.select{|c| Vpim::Icalendar::Vjournal === c}.size)
325
+
326
+ assert_equal(1, vc.events.to_a.size)
327
+ assert_equal(1, vc.todos.to_a.size)
328
+ assert_equal(1, vc.journals.to_a.size)
329
+
330
+ vc.to_s # Shouldn't raise...
331
+ # TODO - encode isn't round-tripping, unknown components are lost, which is
332
+ # not good.
333
+ end
334
+
335
+ def test_calscale
336
+ req = Icalendar.decode(<<__).first
337
+ BEGIN:VCALENDAR
338
+ END:VCALENDAR
339
+ __
340
+ assert_equal("GREGORIAN", req.calscale)
341
+ req = Icalendar.decode(<<__).first
342
+ BEGIN:VCALENDAR
343
+ CALSCALE:GREGORIAN
344
+ END:VCALENDAR
345
+ __
346
+ assert_equal("GREGORIAN", req.calscale)
347
+ end
348
+
349
+ def test_version
350
+ req = Icalendar.decode(<<__).first
351
+ BEGIN:VCALENDAR
352
+ END:VCALENDAR
353
+ __
354
+ assert_raises(InvalidEncodingError) { req.version }
355
+
356
+ req = Icalendar.decode(<<__).first
357
+ BEGIN:VCALENDAR
358
+ VERSION:2.0
359
+ END:VCALENDAR
360
+ __
361
+ assert_equal(20, req.version)
362
+ end
363
+
364
+ def test_protocol
365
+ req = Icalendar.decode(<<__).first
366
+ BEGIN:VCALENDAR
367
+ METHOD:GET
368
+ END:VCALENDAR
369
+ __
370
+ assert(req.protocol?("get"))
371
+ assert(!req.protocol?("set"))
372
+ end
373
+
374
+ def test_transparency
375
+ transparency = Icalendar.decode(<<__).first.to_a.first.transparency
376
+ BEGIN:VCALENDAR
377
+ BEGIN:VEVENT
378
+ END:VEVENT
379
+ END:VCALENDAR
380
+ __
381
+ assert_equal("OPAQUE", transparency, "check default")
382
+
383
+ transparency = Icalendar.decode(<<__).first.to_a.first.transparency
384
+ BEGIN:VCALENDAR
385
+ BEGIN:VEVENT
386
+ TRANSP:Opaque
387
+ END:VEVENT
388
+ END:VCALENDAR
389
+ __
390
+ assert_equal("OPAQUE", transparency, "check opaque")
391
+
392
+ transparency = Icalendar.decode(<<__).first.to_a.first.transparency
393
+ BEGIN:VCALENDAR
394
+ BEGIN:VEVENT
395
+ TRANSP:TrANSPARENT
396
+ END:VEVENT
397
+ END:VCALENDAR
398
+ __
399
+ assert_equal("TRANSPARENT", transparency, "check transparent")
400
+
401
+ end
402
+
403
+ def test_event_maker_w_rrule
404
+ vc = Icalendar.create2 do |vc|
405
+ vc.add_event do |m|
406
+ m.add_rrule("freq=monthly")
407
+ m.set_rrule do |_| _.frequency = "daily" end
408
+ end
409
+ end
410
+ assert_no_match(/RRULE:FREQ=MONTHLY/, vc.to_s)
411
+ assert_match(/RRULE:FREQ=DAILY/, vc.to_s)
412
+ end
413
+
219
414
  end
220
415
 
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'vpim/repo'
4
+ require 'vpim/agent/calendars'
5
+ require 'test/unit'
6
+
7
+ require 'pp'
8
+
9
+ module Enumerable
10
+ def count
11
+ self.inject(0){|i,_| i + 1}
12
+ end
13
+ end
14
+
15
+ class TestRepo < Test::Unit::TestCase
16
+ Apple3 = Vpim::Repo::Apple3
17
+ Directory = Vpim::Repo::Directory
18
+ Agent = Vpim::Agent
19
+ Path = Agent::Path
20
+ NotFound = Agent::NotFound
21
+
22
+ def setup
23
+ @testdir = Dir.getwd + "/test" #File.dirname($0) doesn't work with rcov :-(
24
+ @caldir = @testdir + "/calendars"
25
+ @eventsz = Dir[@caldir + "/**/*.ics"].size
26
+ assert(@testdir)
27
+ assert(test(?d, @caldir), "no caldir "+@caldir)
28
+ end
29
+
30
+ def _test_each(repo, eventsz)
31
+ repo.each do |cal|
32
+ assert_equal(eventsz, cal.events.count, cal.name)
33
+ assert("", File.extname(cal.name))
34
+ assert_equal(cal.displayed, true)
35
+ cal.events do |c|
36
+ assert_instance_of(Vpim::Icalendar::Vevent, c)
37
+ end
38
+ cal.events.each do |c|
39
+ assert_instance_of(Vpim::Icalendar::Vevent, c)
40
+ end
41
+ assert_equal(0, cal.todos.count)
42
+ assert(cal.encode)
43
+ end
44
+ end
45
+
46
+ def test_apple3
47
+ repo = Apple3.new(@caldir)
48
+
49
+ assert_equal(1, repo.count)
50
+
51
+ _test_each(repo, @eventsz)
52
+ end
53
+
54
+ def test_dir
55
+ assert(test(?d, @caldir))
56
+
57
+ repo = Directory.new(@caldir)
58
+
59
+ assert_equal(@eventsz, repo.count)
60
+
61
+ _test_each(repo, 1)
62
+ end
63
+
64
+ def assert_is_text_calendar(text)
65
+ lines = text.split("\n")
66
+ lines = lines.first, lines.last
67
+ assert_equal("BEGIN:VCALENDAR", lines.first.upcase, lines)
68
+ assert_equal("END:VCALENDAR", lines.last.upcase, lines)
69
+ end
70
+
71
+ def test_agent_calendars
72
+ repo = Apple3.new(@caldir)
73
+ rest = Agent::Calendars.new(repo)
74
+
75
+ out1, form = rest.get(Path.new("http://host/here", "/here"))
76
+ assert_equal("text/html", form)
77
+ #puts(out1)
78
+
79
+ out1, form = rest.get(Path.new("http://host/here/weather%2fLeavenworth", "/here"))
80
+ assert_equal("text/html", form)
81
+ #puts(out1)
82
+
83
+ out2, form = rest.get(Path.new("http://host/here/weather%2fLeavenworth/calendar", "/here"))
84
+ assert_equal("text/calendar", form)
85
+ assert_is_text_calendar(out2)
86
+
87
+ #assert_equal(out1, out2)
88
+
89
+ assert_raise(Vpim::Agent::NotFound) do
90
+ rest.get(Path.new("http://host/here/weather%2fLeavenworth/an_unknown_protocol", "/here"))
91
+ end
92
+ assert_raise(Vpim::Agent::NotFound) do
93
+ rest.get(Path.new("http://host/here/no_such_calendar", "/here"))
94
+ end
95
+
96
+ assert_equal(["","/","/"], Vpim::Agent::Path.split_path("/%2F/%2F"))
97
+ assert_equal(["/","/"], Vpim::Agent::Path.split_path("%2F/%2F"))
98
+ assert_equal(["calendars", "weather/Leavenworth"],
99
+ Vpim::Agent::Path.split_path("calendars/weather%2FLeavenworth"))
100
+ end
101
+
102
+ def test_agent_calendar_atom
103
+ repo = Apple3.new(@caldir)
104
+ rest = Agent::Calendars.new(repo)
105
+
106
+ out, form = rest.get(Path.new("http://host/here/weather%2fLeavenworth/atom", "/here"))
107
+ assert_equal("application/atom+xml", form)
108
+ #pp out
109
+ #assert_is_atom(out)
110
+ end
111
+
112
+ def _test_path_shift(url, shifts)
113
+ # last shift should be a nil
114
+ shifts << nil
115
+
116
+ # presence or absence of a trailing / should not affect shifting
117
+ ["", "/"].each do |trailer|
118
+ path = Path.new(url + trailer)
119
+ shifts.each do |_|
120
+ assert_equal(_, path.shift)
121
+ end
122
+ end
123
+ end
124
+
125
+ def test_path_shift
126
+ _test_path_shift("http://host.ex", [])
127
+ _test_path_shift("http://host.ex/a", ["a"])
128
+ _test_path_shift("http://host.ex/a/b", ["a", "b"])
129
+ _test_path_shift("http://host.ex/a/b/c", ["a", "b", "c"])
130
+ end
131
+
132
+ def _test_path_prefix(base, parts, shifts, prefix)
133
+ path = Path.new(base+parts.join("/"))
134
+ shifts.times{ path.shift }
135
+ assert_equal(prefix, path.prefix)
136
+ end
137
+
138
+ def test_path_prefix
139
+ _test_path_prefix("http://host.ex/", [], 0, "/")
140
+ _test_path_prefix("http://host.ex/", ["a"], 0, "/")
141
+ _test_path_prefix("http://host.ex/", ["a"], 1, "/")
142
+ _test_path_prefix("http://host.ex/", ["a"], 2, "/a/")
143
+ _test_path_prefix("http://host.ex/", ["a"], 3, "/a/")
144
+ _test_path_prefix("http://host.ex/", ["a", "b"], 0, "/")
145
+ _test_path_prefix("http://host.ex/", ["a", "b"], 1, "/")
146
+ _test_path_prefix("http://host.ex/", ["a", "b"], 2, "/a/")
147
+ _test_path_prefix("http://host.ex/", ["a", "b"], 3, "/a/b/")
148
+ end
149
+
150
+ def test_atomize
151
+ repo = Apple3.new(@caldir)
152
+ cal = repo.find{true}
153
+ a = Vpim::Agent::Atomize.new(cal)
154
+ assert( a.get(Path.new("http://example.com/path")))
155
+ end
156
+
157
+ end
158
+
@@ -3,6 +3,7 @@
3
3
  ENV['TZ'] = 'EST5EDT'
4
4
 
5
5
  require 'vpim/rrule'
6
+ require 'vpim/icalendar'
6
7
  require 'test/unit'
7
8
 
8
9
  require 'pp'
@@ -14,6 +15,8 @@ end
14
15
  =end
15
16
 
16
17
  class TestRrule < Test::Unit::TestCase
18
+ Rrule = Vpim::Rrule
19
+
17
20
  #=begin
18
21
  # Comment out these if you want printing!
19
22
  def puts(*args)
@@ -975,5 +978,53 @@ RRULE:FREQ=MONTHLY;BYMONTH=12;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;BYMONTHDAY=26,27,2
975
978
  END:VEVENT
976
979
  =end
977
980
 
981
+
982
+ def test_reccurrence_with_utc_dtstart
983
+ # Its wrong that the times yielded aren't in the timezone of DTSTART, but
984
+ # until vPim supports timezones, its the best it'll get.
985
+ txt = <<'__'
986
+ BEGIN:VCALENDAR
987
+ BEGIN:VEVENT
988
+ DTSTAMP:20080416T174954Z
989
+ ORGANIZER;CN=Anonymous:MAILTO:ano@nymo.us
990
+ CREATED:20080401T090904Z
991
+ LAST-MODIFIED:20080401T090904Z
992
+ SUMMARY:Very important recurring event
993
+ RRULE:FREQ=WEEKLY;UNTIL=20080415T093000Z;BYDAY=TU;BYHOUR=9
994
+ DTSTART:20080401T093000Z
995
+ DTEND:20080401T110000Z
996
+ TRANSP:OPAQUE
997
+ END:VEVENT
998
+ END:VCALENDAR
999
+ __
1000
+ cal = Vpim::Icalendar.decode(txt).first
1001
+ occurs = cal.events.to_a.first.occurrences.to_a
1002
+ #p occurs
1003
+ utc = occurs.map{|y| y.utc}
1004
+ #p utc
1005
+ expects = [
1006
+ Time.utc(2008, 4, 1, 9, 30),
1007
+ Time.utc(2008, 4, 8, 9, 30),
1008
+ Time.utc(2008, 4,15, 9, 30),
1009
+ ]
1010
+ assert_equal(expects, utc)
1011
+ end
1012
+
1013
+ def test_maker
1014
+ assert_equal("FREQ=WEEKLY",
1015
+ Rrule::Maker.new{|m|m.frequency = "WEEKLY"}.encode)
1016
+ assert_equal("FREQ=WEEKLY;COUNT=2",
1017
+ Rrule::Maker.new{|m|m.frequency = "WEEKLY"; m.count = 2}.encode)
1018
+ assert_raises(ArgumentError) do
1019
+ Rrule::Maker.new{|m|m.count = 2; m.until = Time.now}
1020
+ end
1021
+ assert_raises(ArgumentError) do
1022
+ Rrule::Maker.new{|m|m.until = Time.now; m.count = 4}
1023
+ end
1024
+ assert_raises(ArgumentError) do
1025
+ Rrule::Maker.new.encode
1026
+ end
1027
+ end
1028
+
978
1029
  end
979
1030