mumboe-vpim 0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +510 -0
- data/COPYING +58 -0
- data/README +185 -0
- data/lib/vpim/address.rb +219 -0
- data/lib/vpim/agent/atomize.rb +104 -0
- data/lib/vpim/agent/base.rb +73 -0
- data/lib/vpim/agent/calendars.rb +173 -0
- data/lib/vpim/agent/handler.rb +26 -0
- data/lib/vpim/agent/ics.rb +161 -0
- data/lib/vpim/attachment.rb +102 -0
- data/lib/vpim/date.rb +222 -0
- data/lib/vpim/dirinfo.rb +277 -0
- data/lib/vpim/duration.rb +119 -0
- data/lib/vpim/enumerator.rb +32 -0
- data/lib/vpim/field.rb +614 -0
- data/lib/vpim/icalendar.rb +384 -0
- data/lib/vpim/maker/vcard.rb +16 -0
- data/lib/vpim/property/base.rb +193 -0
- data/lib/vpim/property/common.rb +315 -0
- data/lib/vpim/property/location.rb +38 -0
- data/lib/vpim/property/priority.rb +43 -0
- data/lib/vpim/property/recurrence.rb +69 -0
- data/lib/vpim/property/resources.rb +24 -0
- data/lib/vpim/repo.rb +261 -0
- data/lib/vpim/rfc2425.rb +367 -0
- data/lib/vpim/rrule.rb +591 -0
- data/lib/vpim/time.rb +40 -0
- data/lib/vpim/vcard.rb +1456 -0
- data/lib/vpim/version.rb +18 -0
- data/lib/vpim/vevent.rb +187 -0
- data/lib/vpim/view.rb +90 -0
- data/lib/vpim/vjournal.rb +58 -0
- data/lib/vpim/vpim.rb +65 -0
- data/lib/vpim/vtodo.rb +103 -0
- data/lib/vpim.rb +13 -0
- data/samples/README.mutt +93 -0
- data/samples/ab-query.rb +57 -0
- data/samples/agent.ru +10 -0
- data/samples/cmd-itip.rb +156 -0
- data/samples/ex_cpvcard.rb +55 -0
- data/samples/ex_get_vcard_photo.rb +22 -0
- data/samples/ex_mkv21vcard.rb +34 -0
- data/samples/ex_mkvcard.rb +64 -0
- data/samples/ex_mkyourown.rb +29 -0
- data/samples/ics-dump.rb +210 -0
- data/samples/ics-to-rss.rb +84 -0
- data/samples/mutt-aliases-to-vcf.rb +45 -0
- data/samples/osx-wrappers.rb +86 -0
- data/samples/reminder.rb +209 -0
- data/samples/rrule.rb +71 -0
- data/samples/tabbed-file-to-vcf.rb +390 -0
- data/samples/vcf-dump.rb +86 -0
- data/samples/vcf-lines.rb +61 -0
- data/samples/vcf-to-ics.rb +22 -0
- data/samples/vcf-to-mutt.rb +121 -0
- data/test/test_agent_atomize.rb +84 -0
- data/test/test_agent_calendars.rb +128 -0
- data/test/test_agent_ics.rb +96 -0
- data/test/test_all.rb +17 -0
- data/test/test_date.rb +120 -0
- data/test/test_dur.rb +41 -0
- data/test/test_field.rb +156 -0
- data/test/test_ical.rb +437 -0
- data/test/test_misc.rb +13 -0
- data/test/test_repo.rb +129 -0
- data/test/test_rrule.rb +1030 -0
- data/test/test_vcard.rb +973 -0
- data/test/test_view.rb +79 -0
- metadata +140 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'test/common'
|
2
|
+
|
3
|
+
require 'vpim/agent/atomize'
|
4
|
+
require 'vpim/icalendar'
|
5
|
+
require 'vpim/view'
|
6
|
+
|
7
|
+
class TextAgentAtomize < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def atomize(cal, feeduri, caluri, filter=nil)
|
10
|
+
ical = Vpim::Icalendar.decode(cal).first
|
11
|
+
if filter
|
12
|
+
ical = filter.call(ical)
|
13
|
+
end
|
14
|
+
feed = Vpim::Agent::Atomize.calendar(ical, feeduri, caluri)
|
15
|
+
return ical, feed
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_minimal
|
19
|
+
ical, feed = atomize(<<'__', "http://example.com/feed", "http://example.com/calendar")
|
20
|
+
BEGIN:VCALENDAR
|
21
|
+
BEGIN:VEVENT
|
22
|
+
DTSTART:20090214T144503
|
23
|
+
END:VEVENT
|
24
|
+
END:VCALENDAR
|
25
|
+
__
|
26
|
+
|
27
|
+
assert_equal(feed.entries.size, 1)
|
28
|
+
assert_equal("http://example.com/feed", feed.id)
|
29
|
+
assert_equal("http://example.com/calendar", feed.title)
|
30
|
+
assert(feed.to_xml.to_str)
|
31
|
+
assert_equal(nil, feed.entries.first.title)
|
32
|
+
assert_equal(nil, feed.entries.first.content)
|
33
|
+
#puts feed.to_xml
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_small
|
37
|
+
ical, feed = atomize(<<'__', "http://example.com/feed", "http://example.com/calendar")
|
38
|
+
BEGIN:VCALENDAR
|
39
|
+
BEGIN:VEVENT
|
40
|
+
DTSTART:20090214T144503
|
41
|
+
SUMMARY:I am summarized
|
42
|
+
DESCRIPTION:And I am described
|
43
|
+
UID:very, very, unique
|
44
|
+
END:VEVENT
|
45
|
+
END:VCALENDAR
|
46
|
+
__
|
47
|
+
|
48
|
+
assert_equal(feed.entries.size, 1)
|
49
|
+
assert_equal("http://example.com/feed", feed.id)
|
50
|
+
assert_equal("http://example.com/calendar", feed.title)
|
51
|
+
assert_equal("I am summarized", feed.entries.first.title)
|
52
|
+
assert_equal("And I am described", feed.entries.first.content)
|
53
|
+
assert(feed.to_xml.to_str)
|
54
|
+
#puts feed.to_xml
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_recurring
|
58
|
+
filter = proc do |cal|
|
59
|
+
Vpim::View.week(cal)
|
60
|
+
end
|
61
|
+
ical, feed = atomize(<<'__', "http://example.com/feed", "http://example.com/calendar", filter)
|
62
|
+
BEGIN:VCALENDAR
|
63
|
+
BEGIN:VEVENT
|
64
|
+
DTSTART:20090214T144503
|
65
|
+
RRULE:FREQ=weekly
|
66
|
+
SUMMARY:I am summarized
|
67
|
+
DESCRIPTION:And I am described
|
68
|
+
UID:very, very, unique
|
69
|
+
END:VEVENT
|
70
|
+
END:VCALENDAR
|
71
|
+
__
|
72
|
+
|
73
|
+
#puts feed.to_xml
|
74
|
+
assert_equal(1, feed.entries.size)
|
75
|
+
assert_equal("http://example.com/feed", feed.id)
|
76
|
+
assert_equal("http://example.com/calendar", feed.title)
|
77
|
+
assert_equal("I am summarized", feed.entries.first.title)
|
78
|
+
assert_equal("And I am described", feed.entries.first.content)
|
79
|
+
assert(feed.to_xml.to_str)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'vpim/repo'
|
4
|
+
require 'vpim/agent/calendars'
|
5
|
+
require 'test/common'
|
6
|
+
|
7
|
+
class TestAgentCalendars < Test::Unit::TestCase
|
8
|
+
Apple3 = Vpim::Repo::Apple3
|
9
|
+
Directory = Vpim::Repo::Directory
|
10
|
+
Uri = Vpim::Repo::Uri
|
11
|
+
Agent = Vpim::Agent
|
12
|
+
Path = Agent::Path
|
13
|
+
NotFound = Agent::NotFound
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@testdir = Dir.getwd + "/test" #File.dirname($0) doesn't work with rcov :-(
|
17
|
+
@caldir = @testdir + "/calendars"
|
18
|
+
@eventsz = Dir[@caldir + "/**/*.ics"].size
|
19
|
+
assert(@testdir)
|
20
|
+
assert(test(?d, @caldir), "no caldir "+@caldir)
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_is_text_calendar(text)
|
24
|
+
lines = text.split("\n")
|
25
|
+
lines = lines.first, lines.last
|
26
|
+
assert_equal("BEGIN:VCALENDAR", lines.first.upcase, lines)
|
27
|
+
assert_equal("END:VCALENDAR", lines.last.upcase, lines)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_agent_calendars
|
31
|
+
repo = Apple3.new(@caldir)
|
32
|
+
rest = Agent::Calendars.new(repo)
|
33
|
+
|
34
|
+
out1, form = rest.get(Path.new("http://host/here", "/here"))
|
35
|
+
assert_equal("text/html", form)
|
36
|
+
#puts(out1)
|
37
|
+
|
38
|
+
out1, form = rest.get(Path.new("http://host/here/weather%2fLeavenworth", "/here"))
|
39
|
+
assert_equal("text/html", form)
|
40
|
+
#puts(out1)
|
41
|
+
|
42
|
+
out2, form = rest.get(Path.new("http://host/here/weather%2fLeavenworth/calendar", "/here"))
|
43
|
+
assert_equal("text/calendar", form)
|
44
|
+
assert_is_text_calendar(out2)
|
45
|
+
|
46
|
+
#assert_equal(out1, out2)
|
47
|
+
|
48
|
+
assert_raise(Vpim::Agent::NotFound) do
|
49
|
+
rest.get(Path.new("http://host/here/weather%2fLeavenworth/an_unknown_protocol", "/here"))
|
50
|
+
end
|
51
|
+
assert_raise(Vpim::Agent::NotFound) do
|
52
|
+
rest.get(Path.new("http://host/here/no_such_calendar", "/here"))
|
53
|
+
end
|
54
|
+
|
55
|
+
assert_equal(["","/","/"], Vpim::Agent::Path.split_path("/%2F/%2F"))
|
56
|
+
assert_equal(["/","/"], Vpim::Agent::Path.split_path("%2F/%2F"))
|
57
|
+
assert_equal(["calendars", "weather/Leavenworth"],
|
58
|
+
Vpim::Agent::Path.split_path("calendars/weather%2FLeavenworth"))
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_agent_calendar_atom
|
62
|
+
repo = Apple3.new(@caldir)
|
63
|
+
rest = Agent::Calendars.new(repo)
|
64
|
+
|
65
|
+
out, form = rest.get(Path.new("http://host/here/weather%2fLeavenworth/atom", "/here"))
|
66
|
+
assert_equal("application/atom+xml", form)
|
67
|
+
#pp out
|
68
|
+
#assert_is_atom(out)
|
69
|
+
end
|
70
|
+
|
71
|
+
def _test_path_shift(url, shifts)
|
72
|
+
# last shift should be a nil
|
73
|
+
shifts << nil
|
74
|
+
|
75
|
+
# presence or absence of a trailing / should not affect shifting
|
76
|
+
["", "/"].each do |trailer|
|
77
|
+
path = Path.new(url + trailer)
|
78
|
+
shifts.each do |_|
|
79
|
+
assert_equal(_, path.shift)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_path_shift
|
85
|
+
_test_path_shift("http://host.ex", [])
|
86
|
+
_test_path_shift("http://host.ex/a", ["a"])
|
87
|
+
_test_path_shift("http://host.ex/a/b", ["a", "b"])
|
88
|
+
_test_path_shift("http://host.ex/a/b/c", ["a", "b", "c"])
|
89
|
+
end
|
90
|
+
|
91
|
+
def _test_path_prefix(base, parts, shifts, prefix)
|
92
|
+
path = Path.new(base+parts.join("/"))
|
93
|
+
shifts.times{ path.shift }
|
94
|
+
assert_equal(prefix, path.prefix)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_path_prefix
|
98
|
+
_test_path_prefix("http://host.ex/", [], 0, "/")
|
99
|
+
_test_path_prefix("http://host.ex/", ["a"], 0, "/")
|
100
|
+
_test_path_prefix("http://host.ex/", ["a"], 1, "/")
|
101
|
+
_test_path_prefix("http://host.ex/", ["a"], 2, "/a/")
|
102
|
+
_test_path_prefix("http://host.ex/", ["a"], 3, "/a/")
|
103
|
+
_test_path_prefix("http://host.ex/", ["a", "b"], 0, "/")
|
104
|
+
_test_path_prefix("http://host.ex/", ["a", "b"], 1, "/")
|
105
|
+
_test_path_prefix("http://host.ex/", ["a", "b"], 2, "/a/")
|
106
|
+
_test_path_prefix("http://host.ex/", ["a", "b"], 3, "/a/b/")
|
107
|
+
end
|
108
|
+
|
109
|
+
=begin
|
110
|
+
def test_atomize
|
111
|
+
repo = Apple3.new(@caldir)
|
112
|
+
cal = repo.find{true}
|
113
|
+
a = Vpim::Agent::Atomize.new(cal)
|
114
|
+
assert( a.get(Path.new("http://example.com/path")))
|
115
|
+
end
|
116
|
+
|
117
|
+
def x_test_uri_query
|
118
|
+
uri = "http://example.com/ics/atom?http://localhost:9876"
|
119
|
+
|
120
|
+
repo = Uri.new("http://localhost:9876")
|
121
|
+
rest = Agent::Calendars.new(repo)
|
122
|
+
out1, form = rest.get(Path.new("http://example.com/ics", "/ics/atom"))
|
123
|
+
p [out1, form]
|
124
|
+
end
|
125
|
+
=end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test/common'
|
2
|
+
require 'sinatra/test'
|
3
|
+
require 'vpim/agent/ics'
|
4
|
+
|
5
|
+
class TestIcsAgent < Test::Unit::TestCase
|
6
|
+
include Sinatra::Test
|
7
|
+
|
8
|
+
def to_str
|
9
|
+
@caldata
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@thrd = data_on_port(self, 9876)
|
14
|
+
@app = Vpim::Agent::Ics
|
15
|
+
end
|
16
|
+
def teardown
|
17
|
+
@thrd.kill
|
18
|
+
end
|
19
|
+
|
20
|
+
def _test_ics_atom_query(scheme)
|
21
|
+
@caldata = open("test/weekly.ics").read
|
22
|
+
|
23
|
+
get "/atom?#{scheme}://127.0.0.1:9876"
|
24
|
+
|
25
|
+
assert_match(/<\?xml/, @response.body)
|
26
|
+
assert_equal(Vpim::Agent::Atomize::MIME, @response["Content-Type"])
|
27
|
+
assert_equal(200, @response.status)
|
28
|
+
assert_match(Regexp.new( Regexp.quote(
|
29
|
+
"<id>http://example.org/atom?#{scheme}://127.0.0.1:9876</id>"
|
30
|
+
)), @response.body)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_ics_atom_query_http
|
34
|
+
_test_ics_atom_query "http"
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_ics_atom_query_webcal
|
38
|
+
_test_ics_atom_query "webcal"
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_ics
|
42
|
+
get ""
|
43
|
+
|
44
|
+
assert_match(/<html/, @response.body)
|
45
|
+
assert_equal("text/html", @response["Content-Type"])
|
46
|
+
assert_equal(200, @response.status)
|
47
|
+
assert_match(Regexp.new(Regexp.quote("<title>Subscribe")), @response.body)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_ics_query
|
51
|
+
@caldata = open("test/calendars/weather.calendar/Events/1205042405-0-0.ics").read
|
52
|
+
|
53
|
+
get "?http://127.0.0.1:9876"
|
54
|
+
|
55
|
+
assert_match(/<html/, @response.body)
|
56
|
+
assert_equal("text/html", @response["Content-Type"])
|
57
|
+
assert_equal(200, @response.status)
|
58
|
+
|
59
|
+
assert_match(Regexp.new(Regexp.quote("Subscribe to")), @response.body)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_ics_post
|
63
|
+
post "/", :url => "http://example.com"
|
64
|
+
assert_equal(302, @response.status)
|
65
|
+
assert_equal("http://example.org?http://example.com", @response.headers["Location"])
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_ics_atom
|
69
|
+
get "/atom"
|
70
|
+
assert_equal(302, @response.status)
|
71
|
+
assert_equal("http://example.org", @response.headers["Location"])
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_ics_style
|
75
|
+
get "/style.css"
|
76
|
+
assert_match(/body \{/, @response.body)
|
77
|
+
assert_equal("text/css", @response["Content-Type"])
|
78
|
+
assert_equal(200, @response.status)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_ics_query_bad
|
82
|
+
get "/?url://example.com"
|
83
|
+
assert_equal(200, @response.status)
|
84
|
+
assert_match(/Sorry/, @response.body)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_ics_atom_query_bad
|
88
|
+
#Vpim::Agent::Ics.enable :raise_errors
|
89
|
+
|
90
|
+
get "/atom?url://example.com"
|
91
|
+
assert_equal(302, @response.status)
|
92
|
+
assert_equal("http://example.org?url://example.com", @response.headers["Location"])
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
data/test/test_all.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
$-w = true
|
6
|
+
|
7
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
8
|
+
|
9
|
+
|
10
|
+
#pp [__LINE__, $:, $"]
|
11
|
+
|
12
|
+
require 'test/unit'
|
13
|
+
|
14
|
+
Dir[File.dirname(__FILE__) + "/test_*.rb"].each do |test|
|
15
|
+
require test unless test =~ /test_all/
|
16
|
+
end
|
17
|
+
|
data/test/test_date.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'vpim/date'
|
4
|
+
require 'vpim/time'
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
class TestVpimDate < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def test_to_time
|
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).vpim_to_time)
|
12
|
+
assert_equal(Time.at(24 * 60 * 60), Date.new(1970, 1, 2).vpim_to_time)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_date_weekstart
|
16
|
+
assert_equal(Date.weekstart(2004, 01, 12, 'tu').to_s, Date.new(2004, 01, 6).to_s)
|
17
|
+
assert_equal(Date.weekstart(2004, 01, 12, 'we').to_s, Date.new(2004, 01, 7).to_s)
|
18
|
+
assert_equal(Date.weekstart(2004, 01, 12, 'th').to_s, Date.new(2004, 01, 8).to_s)
|
19
|
+
assert_equal(Date.weekstart(2004, 01, 12, 'fr').to_s, Date.new(2004, 01, 9).to_s)
|
20
|
+
assert_equal(Date.weekstart(2004, 01, 12, 'sa').to_s, Date.new(2004, 01, 10).to_s)
|
21
|
+
assert_equal(Date.weekstart(2004, 01, 12, 'su').to_s, Date.new(2004, 01, 11).to_s)
|
22
|
+
assert_equal(Date.weekstart(2004, 01, 12, 'mo').to_s, Date.new(2004, 01, 12).to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
def do_bywday(args, expect)
|
26
|
+
# Rewrite 'string' weekday specifications.
|
27
|
+
args = [ args[0], args[1], Date.str2wday(args[2]), args[3] ]
|
28
|
+
date = Date.bywday(*args)
|
29
|
+
dates = DateGen.bywday(*args)
|
30
|
+
need = Date.new(*expect)
|
31
|
+
|
32
|
+
assert_equal(date, need)
|
33
|
+
|
34
|
+
# Date.bywday always produces a single date, so should the generator, in
|
35
|
+
# this case.
|
36
|
+
assert_equal(dates[0], need)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_bywday
|
40
|
+
|
41
|
+
# 2004
|
42
|
+
#
|
43
|
+
# January February March
|
44
|
+
# S M Tu W Th F S S M Tu W Th F S S M Tu W Th F S
|
45
|
+
# 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6
|
46
|
+
# 4 5 6 7 8 9 10 8 9 10 11 12 13 14 7 8 9 10 11 12 13
|
47
|
+
# 11 12 13 14 15 16 17 15 16 17 18 19 20 21 14 15 16 17 18 19 20
|
48
|
+
# 18 19 20 21 22 23 24 22 23 24 25 26 27 28 21 22 23 24 25 26 27
|
49
|
+
# 25 26 27 28 29 30 31 29 28 29 30 31
|
50
|
+
#
|
51
|
+
do_bywday([2004, 1, 4, 1], [2004, 1, 1])
|
52
|
+
do_bywday([2004, 1, 4, 2], [2004, 1, 8])
|
53
|
+
do_bywday([2004, 1, 4, -1], [2004, 1, 29])
|
54
|
+
do_bywday([2004, 1, 4, -2], [2004, 1, 22])
|
55
|
+
do_bywday([2004, 1, 4, -5], [2004, 1, 1])
|
56
|
+
do_bywday([2004,nil, 4, 1], [2004, 1, 1])
|
57
|
+
do_bywday([2004,nil, 4, 2], [2004, 1, 8])
|
58
|
+
do_bywday([2004,-12, 4, 1], [2004, 1, 1])
|
59
|
+
do_bywday([2004,-12, 4, 2], [2004, 1, 8])
|
60
|
+
do_bywday([2004,-12, 4, -1], [2004, 1, 29])
|
61
|
+
do_bywday([2004,-12, 4, -2], [2004, 1, 22])
|
62
|
+
do_bywday([2004,-12, 4, -5], [2004, 1, 1])
|
63
|
+
|
64
|
+
do_bywday([2004, 1, "th", 1], [2004, 1, 1])
|
65
|
+
do_bywday([2004, 1, "th", 2], [2004, 1, 8])
|
66
|
+
do_bywday([2004, 1, "th", -1], [2004, 1, 29])
|
67
|
+
do_bywday([2004, 1, "th", -2], [2004, 1, 22])
|
68
|
+
do_bywday([2004, 1, "th", -5], [2004, 1, 1])
|
69
|
+
do_bywday([2004,nil, "th", 1], [2004, 1, 1])
|
70
|
+
do_bywday([2004,nil, "th", 2], [2004, 1, 8])
|
71
|
+
do_bywday([2004,-12, "th", 1], [2004, 1, 1])
|
72
|
+
do_bywday([2004,-12, "th", 2], [2004, 1, 8])
|
73
|
+
do_bywday([2004,-12, "th", -1], [2004, 1, 29])
|
74
|
+
do_bywday([2004,-12, "th", -2], [2004, 1, 22])
|
75
|
+
do_bywday([2004,-12, "th", -5], [2004, 1, 1])
|
76
|
+
|
77
|
+
# October November December
|
78
|
+
# S M Tu W Th F S S M Tu W Th F S S M Tu W Th F S
|
79
|
+
# 1 2 1 2 3 4 5 6 1 2 3 4
|
80
|
+
# 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11
|
81
|
+
# 10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18
|
82
|
+
# 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25
|
83
|
+
# 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31
|
84
|
+
# 31
|
85
|
+
|
86
|
+
do_bywday([2004, -1, 4, 1], [2004, 12, 2])
|
87
|
+
do_bywday([2004, -1, 4, -1], [2004, 12, 30])
|
88
|
+
do_bywday([2004, -1, 4, -2], [2004, 12, 23])
|
89
|
+
do_bywday([2004, -1, 4, -5], [2004, 12, 2])
|
90
|
+
do_bywday([2004,nil, 4, -1], [2004, 12, 30])
|
91
|
+
do_bywday([2004,nil, 4, -2], [2004, 12, 23])
|
92
|
+
do_bywday([2004,nil, 4, -5], [2004, 12, 2])
|
93
|
+
do_bywday([2004,nil, 4, -7], [2004, 11, 18])
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
def do_gen(args)
|
98
|
+
assert_nothing_thrown do
|
99
|
+
dates = DateGen.bywday(*args)
|
100
|
+
dates.each do |d|
|
101
|
+
assert_equal(args[0], d.year)
|
102
|
+
if(args[1])
|
103
|
+
mon = args[1]
|
104
|
+
if mon < 0
|
105
|
+
mon = 13 + args[1]
|
106
|
+
end
|
107
|
+
assert_equal(mon, d.mon)
|
108
|
+
end
|
109
|
+
assert_equal(args[2], d.wday)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_gen
|
115
|
+
do_gen([2004, 12, 1])
|
116
|
+
do_gen([2004, -1, 1])
|
117
|
+
do_gen([2004, nil, 1])
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
data/test/test_dur.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'vpim/duration'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
include Vpim
|
7
|
+
|
8
|
+
class TestVpimDate < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def duration(d0, h0, m0, s0)
|
11
|
+
# 3 hours, 2 mins, 39 secs
|
12
|
+
d = Duration.secs(d0 * 24 * 60 * 60 + h0 * 60 * 60 + m0 * 60 + s0)
|
13
|
+
|
14
|
+
assert_equal(d.secs, d0 * 24 * 60 * 60 + h0 * 60 * 60 + m0 * 60 + s0)
|
15
|
+
assert_equal(d.mins, d0 * 24 * 60 + h0 * 60 + m0)
|
16
|
+
assert_equal(d.hours, d0 * 24 + h0)
|
17
|
+
assert_equal(d.days, d0)
|
18
|
+
assert_equal(d.by_hours, [d0*24 + h0, m0, s0])
|
19
|
+
assert_equal(d.by_days, [d0, h0, m0, s0])
|
20
|
+
|
21
|
+
h, m, s = d.by_hours
|
22
|
+
|
23
|
+
assert_equal(h, h0 + d0*24)
|
24
|
+
assert_equal(m, m0)
|
25
|
+
assert_equal(s, s0)
|
26
|
+
|
27
|
+
d, h, m, s = d.by_days
|
28
|
+
|
29
|
+
assert_equal(d, d0)
|
30
|
+
assert_equal(h, h0)
|
31
|
+
assert_equal(m, m0)
|
32
|
+
assert_equal(s, s0)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_1
|
36
|
+
duration(0, 3, 2, 39)
|
37
|
+
duration(5, 23, 39, 1)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
data/test/test_field.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'pp'
|
5
|
+
require 'vpim/field'
|
6
|
+
|
7
|
+
Field=Vpim::DirectoryInfo::Field
|
8
|
+
|
9
|
+
class TestField < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def test_encode_decode_text()
|
12
|
+
enc_in = "+\\\\+\\n+\\N+\\,+\\;+\\a+\\b+\\c+"
|
13
|
+
dec = Vpim.decode_text(enc_in)
|
14
|
+
#puts("<#{enc_in}> => <#{dec}>")
|
15
|
+
assert_equal("+\\+\n+\n+,+;+a+b+c+", dec)
|
16
|
+
enc_out = Vpim.encode_text(dec)
|
17
|
+
should_be = "+\\\\+\\n+\\n+\\,+\\;+a+b+c+"
|
18
|
+
# Note a, b, and c are allowed to be escaped, but shouldn't be and
|
19
|
+
# aren't in output
|
20
|
+
#puts("<#{dec}> => <#{enc_out}>")
|
21
|
+
assert_equal(should_be, enc_out)
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_field4
|
26
|
+
line = 't;e=a,b: 4 '
|
27
|
+
part = Field.decode0(line)
|
28
|
+
assert_equal("4", part[ 3 ])
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_field3
|
32
|
+
line = 't;e=a,b:4'
|
33
|
+
part = Field.decode0(line)
|
34
|
+
assert_equal("4", part[ 3 ])
|
35
|
+
assert_equal( {'E' => [ 'a','b' ] }, part[ 2 ])
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_field2
|
39
|
+
line = 'tel;type=work,voice,msg:+1 313 747-4454'
|
40
|
+
part = Field.decode0(line)
|
41
|
+
assert_equal("+1 313 747-4454", part[ 3 ])
|
42
|
+
assert_equal( {'TYPE' => [ 'work','voice','msg' ] }, part[ 2 ])
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_field1
|
46
|
+
line = 'ORGANIZER;CN="xxxx, xxxx [SC100:370:EXCH]":MAILTO:xxxx@americasm01.nt.com'
|
47
|
+
parts = Field.decode0(line)
|
48
|
+
|
49
|
+
assert_equal(nil, parts[0])
|
50
|
+
assert_equal('ORGANIZER', parts[1])
|
51
|
+
assert_equal({ 'CN' => [ "xxxx, xxxx [SC100:370:EXCH]" ] }, parts[2])
|
52
|
+
assert_equal('MAILTO:xxxx@americasm01.nt.com', parts[3])
|
53
|
+
end
|
54
|
+
|
55
|
+
=begin this can not be done :-(
|
56
|
+
def test_case_equiv
|
57
|
+
line = 'ORGANIZER;CN="xxxx, xxxx [SC100:370:EXCH]":MAILTO:xxxx@americasm01.nt.com'
|
58
|
+
field = Field.decode(line)
|
59
|
+
assert_equal(true, field.name?('organIZER'))
|
60
|
+
assert_equal(true, field === 'organIZER')
|
61
|
+
|
62
|
+
b = nil
|
63
|
+
case field
|
64
|
+
when 'organIZER'
|
65
|
+
b = true
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_equal(true, b)
|
69
|
+
end
|
70
|
+
=end
|
71
|
+
|
72
|
+
def test_field0
|
73
|
+
assert_equal('name:', line = Field.encode0(nil, 'name'))
|
74
|
+
assert_equal([ nil, 'NAME', {}, ''], Field.decode0(line))
|
75
|
+
|
76
|
+
assert_equal('name:value', line = Field.encode0(nil, 'name', {}, 'value'))
|
77
|
+
assert_equal([ nil, 'NAME', {}, 'value'], Field.decode0(line))
|
78
|
+
|
79
|
+
assert_equal('name;encoding=B:dmFsdWU=', line = Field.encode0(nil, 'name', { 'encoding'=>:b64 }, 'value'))
|
80
|
+
assert_equal([ nil, 'NAME', { 'ENCODING'=>['B']}, ['value'].pack('m').chomp ], Field.decode0(line))
|
81
|
+
|
82
|
+
assert_equal('group.name:value', line = Field.encode0('group', 'name', {}, 'value'))
|
83
|
+
assert_equal([ 'GROUP', 'NAME', {}, 'value'], Field.decode0(line))
|
84
|
+
end
|
85
|
+
|
86
|
+
def tEst_invalid_fields
|
87
|
+
[
|
88
|
+
'g.:',
|
89
|
+
':v',
|
90
|
+
].each do |line|
|
91
|
+
assert_raises(Vpim::InvalidEncodingError) { Field.decode0(line) }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_date_encode
|
96
|
+
assert_equal("DTSTART:20040101\n", Field.create('DTSTART', Date.new(2004, 1, 1) ).to_s)
|
97
|
+
assert_equal("DTSTART:20040101\n", Field.create('DTSTART', [Date.new(2004, 1, 1)]).to_s)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_field_modify
|
101
|
+
f = Field.create('name')
|
102
|
+
|
103
|
+
assert_equal('', f.value)
|
104
|
+
f.value = ''
|
105
|
+
assert_equal('', f.value)
|
106
|
+
f.value = 'z'
|
107
|
+
assert_equal('z', f.value)
|
108
|
+
|
109
|
+
f.group = 'z.b'
|
110
|
+
assert_equal('Z.B', f.group)
|
111
|
+
assert_equal("z.b.NAME:z\n", f.encode)
|
112
|
+
|
113
|
+
assert_raises(TypeError) { f.value = :group }
|
114
|
+
|
115
|
+
assert_equal('Z.B', f.group)
|
116
|
+
|
117
|
+
assert_equal("z.b.NAME:z\n", f.encode)
|
118
|
+
|
119
|
+
assert_raises(TypeError) { f.group = :group }
|
120
|
+
|
121
|
+
assert_equal("z.b.NAME:z\n", f.encode)
|
122
|
+
assert_equal('Z.B', f.group)
|
123
|
+
|
124
|
+
f['p0'] = "hi julie"
|
125
|
+
|
126
|
+
assert_equal("Z.B.NAME;P0=hi julie:z\n", f.encode)
|
127
|
+
assert_equal(['hi julie'], f.param('p0'))
|
128
|
+
assert_equal(['hi julie'], f['p0'])
|
129
|
+
assert_equal('NAME', f.name)
|
130
|
+
assert_equal('Z.B', f.group)
|
131
|
+
|
132
|
+
# FAIL assert_raises(ArgumentError) { f.group = 'z.b:' }
|
133
|
+
|
134
|
+
assert_equal('Z.B', f.group)
|
135
|
+
|
136
|
+
f.value = 'some text'
|
137
|
+
|
138
|
+
assert_equal('some text', f.value)
|
139
|
+
assert_equal('some text', f.value_raw)
|
140
|
+
|
141
|
+
f['encoding'] = :b64
|
142
|
+
|
143
|
+
assert_equal('some text', f.value)
|
144
|
+
assert_equal([ 'some text' ].pack('m*').chomp, f.value_raw)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_field_wrapping
|
148
|
+
assert_equal("0:x\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 1).encode(4))
|
149
|
+
assert_equal("0:xx\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 2).encode(4))
|
150
|
+
assert_equal("0:xx\n x\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 3).encode(4))
|
151
|
+
assert_equal("0:xx\n xx\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 4).encode(4))
|
152
|
+
assert_equal("0:xx\n xxxx\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 6).encode(4))
|
153
|
+
assert_equal("0:xx\n xxxx\n x\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 7).encode(4))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|