vcard 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,152 @@
1
+ require 'test_helper'
2
+
3
+ Field=Vpim::DirectoryInfo::Field
4
+
5
+ class FieldTest < Test::Unit::TestCase
6
+
7
+ def test_encode_decode_text()
8
+ enc_in = "+\\\\+\\n+\\N+\\,+\\;+\\a+\\b+\\c+"
9
+ dec = Vpim.decode_text(enc_in)
10
+ #puts("<#{enc_in}> => <#{dec}>")
11
+ assert_equal("+\\+\n+\n+,+;+a+b+c+", dec)
12
+ enc_out = Vpim.encode_text(dec)
13
+ should_be = "+\\\\+\\n+\\n+\\,+\\;+a+b+c+"
14
+ # Note a, b, and c are allowed to be escaped, but shouldn't be and
15
+ # aren't in output
16
+ #puts("<#{dec}> => <#{enc_out}>")
17
+ assert_equal(should_be, enc_out)
18
+
19
+ end
20
+
21
+ def test_field4
22
+ line = 't;e=a,b: 4 '
23
+ part = Field.decode0(line)
24
+ assert_equal("4", part[ 3 ])
25
+ end
26
+
27
+ def test_field3
28
+ line = 't;e=a,b:4'
29
+ part = Field.decode0(line)
30
+ assert_equal("4", part[ 3 ])
31
+ assert_equal( {'E' => [ 'a','b' ] }, part[ 2 ])
32
+ end
33
+
34
+ def test_field2
35
+ line = 'tel;type=work,voice,msg:+1 313 747-4454'
36
+ part = Field.decode0(line)
37
+ assert_equal("+1 313 747-4454", part[ 3 ])
38
+ assert_equal( {'TYPE' => [ 'work','voice','msg' ] }, part[ 2 ])
39
+ end
40
+
41
+ def test_field1
42
+ line = 'ORGANIZER;CN="xxxx, xxxx [SC100:370:EXCH]":MAILTO:xxxx@americasm01.nt.com'
43
+ parts = Field.decode0(line)
44
+
45
+ assert_equal(nil, parts[0])
46
+ assert_equal('ORGANIZER', parts[1])
47
+ assert_equal({ 'CN' => [ "xxxx, xxxx [SC100:370:EXCH]" ] }, parts[2])
48
+ assert_equal('MAILTO:xxxx@americasm01.nt.com', parts[3])
49
+ end
50
+
51
+ =begin this can not be done :-(
52
+ def test_case_equiv
53
+ line = 'ORGANIZER;CN="xxxx, xxxx [SC100:370:EXCH]":MAILTO:xxxx@americasm01.nt.com'
54
+ field = Field.decode(line)
55
+ assert_equal(true, field.name?('organIZER'))
56
+ assert_equal(true, field === 'organIZER')
57
+
58
+ b = nil
59
+ case field
60
+ when 'organIZER'
61
+ b = true
62
+ end
63
+
64
+ assert_equal(true, b)
65
+ end
66
+ =end
67
+
68
+ def test_field0
69
+ assert_equal('name:', line = Field.encode0(nil, 'name'))
70
+ assert_equal([ nil, 'NAME', {}, ''], Field.decode0(line))
71
+
72
+ assert_equal('name:value', line = Field.encode0(nil, 'name', {}, 'value'))
73
+ assert_equal([ nil, 'NAME', {}, 'value'], Field.decode0(line))
74
+
75
+ assert_equal('name;encoding=B:dmFsdWU=', line = Field.encode0(nil, 'name', { 'encoding'=>:b64 }, 'value'))
76
+ assert_equal([ nil, 'NAME', { 'ENCODING'=>['B']}, ['value'].pack('m').chomp ], Field.decode0(line))
77
+
78
+ assert_equal('group.name:value', line = Field.encode0('group', 'name', {}, 'value'))
79
+ assert_equal([ 'GROUP', 'NAME', {}, 'value'], Field.decode0(line))
80
+ end
81
+
82
+ def tEst_invalid_fields
83
+ [
84
+ 'g.:',
85
+ ':v',
86
+ ].each do |line|
87
+ assert_raises(Vpim::InvalidEncodingError) { Field.decode0(line) }
88
+ end
89
+ end
90
+
91
+ def test_date_encode
92
+ assert_equal("DTSTART:20040101\n", Field.create('DTSTART', Date.new(2004, 1, 1) ).to_s)
93
+ assert_equal("DTSTART:20040101\n", Field.create('DTSTART', [Date.new(2004, 1, 1)]).to_s)
94
+ end
95
+
96
+ def test_field_modify
97
+ f = Field.create('name')
98
+
99
+ assert_equal('', f.value)
100
+ f.value = ''
101
+ assert_equal('', f.value)
102
+ f.value = 'z'
103
+ assert_equal('z', f.value)
104
+
105
+ f.group = 'z.b'
106
+ assert_equal('Z.B', f.group)
107
+ assert_equal("z.b.NAME:z\n", f.encode)
108
+
109
+ assert_raises(TypeError) { f.value = :group }
110
+
111
+ assert_equal('Z.B', f.group)
112
+
113
+ assert_equal("z.b.NAME:z\n", f.encode)
114
+
115
+ assert_raises(TypeError) { f.group = :group }
116
+
117
+ assert_equal("z.b.NAME:z\n", f.encode)
118
+ assert_equal('Z.B', f.group)
119
+
120
+ f['p0'] = "hi julie"
121
+
122
+ assert_equal("Z.B.NAME;P0=hi julie:z\n", f.encode)
123
+ assert_equal(['hi julie'], f.param('p0'))
124
+ assert_equal(['hi julie'], f['p0'])
125
+ assert_equal('NAME', f.name)
126
+ assert_equal('Z.B', f.group)
127
+
128
+ # FAIL assert_raises(ArgumentError) { f.group = 'z.b:' }
129
+
130
+ assert_equal('Z.B', f.group)
131
+
132
+ f.value = 'some text'
133
+
134
+ assert_equal('some text', f.value)
135
+ assert_equal('some text', f.value_raw)
136
+
137
+ f['encoding'] = :b64
138
+
139
+ assert_equal('some text', f.value)
140
+ assert_equal([ 'some text' ].pack('m*').chomp, f.value_raw)
141
+ end
142
+
143
+ def test_field_wrapping
144
+ assert_equal("0:x\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 1).encode(4))
145
+ assert_equal("0:xx\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 2).encode(4))
146
+ assert_equal("0:xx\n x\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 3).encode(4))
147
+ assert_equal("0:xx\n xx\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 4).encode(4))
148
+ assert_equal("0:xx\n xxxx\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 6).encode(4))
149
+ assert_equal("0:xx\n xxxx\n x\n", Vpim::DirectoryInfo::Field.create('0', 'x' * 7).encode(4))
150
+ end
151
+ end
152
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'vcard'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,967 @@
1
+ require 'test_helper'
2
+
3
+ include Vpim
4
+
5
+ # Test equivalence where whitespace is compressed.
6
+ def assert_equal_nospace(expected, got)
7
+ expected = expected.gsub(/\s+/,'')
8
+ got = expected.gsub(/\s+/,'')
9
+ assert_equal(expected, got)
10
+ end
11
+
12
+
13
+ # Test cases: multiple occurrences of type
14
+ =begin
15
+ begin:VCARD
16
+ version:2.1
17
+ v;x1=a;x2=,a;x3=a,;x4=a,,a;x5=,a,:
18
+ source:ldap://cn=bjorn%20Jensen, o=university%20of%20Michigan, c=US
19
+ fn:Bj=F8rn
20
+ Jensen
21
+ other.name:Jensen;Bj=F8rn
22
+ some.other.value:1.2.3
23
+ some.other.value:some.other
24
+ some.other.value:some.other.value
25
+ v;p-1=;p-2=,,;p-3=a;p-4=a b,"v;p-1=;p-2=,,;p-3=a;p-4=a":v-value
26
+ email;type=internet:
27
+ bjorn@umich.edu
28
+ tel;type=work,voice,msg:+1 313 747-4454
29
+ tel:+...
30
+ key;type=x509;encoding=B:dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK
31
+ end:vcard
32
+ =end
33
+
34
+ class VcardTest < Test::Unit::TestCase
35
+
36
+ # RFC2425 - 8.1. Example 1
37
+ # Note that this is NOT a valid vCard, it lacks BEGIN/END.
38
+ EX1 =<<'EOF'
39
+ cn:
40
+ cn:Babs Jensen
41
+ cn:Barbara J Jensen
42
+ sn:Jensen
43
+ email:babs@umich.edu
44
+ phone:+1 313 747-4454
45
+ x-id:1234567890
46
+ EOF
47
+ def test_ex1
48
+ card = nil
49
+ ex1 = EX1
50
+ assert_nothing_thrown { card = Vpim::DirectoryInfo.decode(ex1) }
51
+ assert_equal_nospace(EX1, card.to_s)
52
+
53
+ assert_equal("Babs Jensen", card["cn"])
54
+ assert_equal("Jensen", card["sn"])
55
+
56
+ assert_equal("babs@umich.edu", card[ "email" ])
57
+
58
+ assert_equal("+1 313 747-4454", card[ "PhOnE" ])
59
+ assert_equal("1234567890", card[ "x-id" ])
60
+ assert_equal([], card.groups)
61
+ end
62
+
63
+ # RFC2425 - 8.2. Example 2
64
+ EX2 = <<-END
65
+ begin:VCARD
66
+ source:ldap://cn=bjorn%20Jensen, o=university%20of%20Michigan, c=US
67
+ name:Bjorn Jensen
68
+ fn:Bj=F8rn Jensen
69
+ n:Jensen;Bj=F8rn
70
+ email;type=internet:bjorn@umich.edu
71
+ tel;type=work,voice,msg:+1 313 747-4454
72
+ key;type=x509;encoding=B:dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK
73
+ end:VCARD
74
+ END
75
+
76
+ def test_ex2
77
+ card = nil
78
+ ex2 = EX2
79
+ assert_nothing_thrown { card = Vpim::Vcard.decode(ex2).first }
80
+ assert_equal(EX2, card.encode(0))
81
+ assert_raises(InvalidEncodingError) { card.version }
82
+
83
+ assert_equal("Bj=F8rn Jensen", card.name.fullname)
84
+ assert_equal("Jensen", card.name.family)
85
+ assert_equal("Bj=F8rn", card.name.given)
86
+ assert_equal("", card.name.prefix)
87
+
88
+ assert_equal("Bj=F8rn Jensen", card[ "fn" ])
89
+ assert_equal("+1 313 747-4454", card[ "tEL" ])
90
+
91
+ assert_equal(nil, card[ "not-a-field" ])
92
+ assert_equal([], card.groups)
93
+
94
+ assert_equal(nil, card.enum_by_name("n").entries[0].param("encoding"))
95
+
96
+ assert_equal(["internet"], card.enum_by_name("Email").entries.first.param("Type"))
97
+ assert_equal(nil, card.enum_by_name("Email").entries[0].param("foo"))
98
+
99
+ assert_equal(["B"], card.enum_by_name("kEy").to_a.first.param("encoding"))
100
+ assert_equal("B", card.enum_by_name("kEy").entries[0].encoding)
101
+
102
+ assert_equal(["work", "voice", "msg"], card.enum_by_name("tel").entries[0].param("Type"))
103
+
104
+ assert_equal([card.fields[6]], card.enum_by_name("tel").entries)
105
+
106
+ assert_equal([card.fields[6]], card.enum_by_name("tel").to_a)
107
+
108
+ assert_equal(nil, card.enum_by_name("tel").entries.first.encoding)
109
+
110
+ assert_equal("B", card.enum_by_name("key").entries.first.encoding)
111
+
112
+ assert_equal("dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK", card.enum_by_name("key").entries.first.value_raw)
113
+
114
+ assert_equal("this could be \nmy certificate\n", card.enum_by_name("key").entries.first.value)
115
+
116
+ card.lines
117
+ end
118
+
119
+ =begin
120
+ EX3 = <<-END
121
+ begin:vcard
122
+ source:ldap://cn=Meister%20Berger,o=Universitaet%20Goerlitz,c=DE
123
+ name:Meister Berger
124
+ fn:Meister Berger
125
+ n:Berger;Meister
126
+ bday;value=date:1963-09-21
127
+ o:Universit=E6t G=F6rlitz
128
+ title:Mayor
129
+ title;language=de;value=text:Burgermeister
130
+ note:The Mayor of the great city of
131
+ Goerlitz in the great country of Germany.
132
+ email;internet:mb@goerlitz.de
133
+ home.tel;type=fax,voice,msg:+49 3581 123456
134
+ home.label:Hufenshlagel 1234\n
135
+ 02828 Goerlitz\n
136
+ Deutschland
137
+ key;type=X509;encoding=b:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQ
138
+ AwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zI
139
+ ENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0ZW1zMRwwGgYDVQQD
140
+ ExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNjE5NDc1OVoXDTk3MTIwMzE5NDc
141
+ 1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYDVQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW
142
+ 9ucyBDb3JwLjEYMBYGA1UEAxMPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBF
143
+ hJob3dlc0BuZXRzY2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqG
144
+ SIb3DQEBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2dXc
145
+ oX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MBEGCWCGSAGG+E
146
+ IBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau+hUMbsQukjANBgkqhkiG9
147
+ w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIPmx93HGp0Kgyx1jIVMyNgsemeAwBM+M
148
+ SlhMfcpbTrONwNjZYW8vJDSoi//yrZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8V
149
+ UMk1U7jt8LYpo4YULU7UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ==
150
+ end:vcard
151
+ END
152
+ assert_equal(
153
+ ["other", "some.other"],
154
+ card.groups_all
155
+ )
156
+ #a = []
157
+ #card.enum_by_group("some.other").each { |field| a << field }
158
+ #assert_equal(card.fields.indexes(6, 7, 8), a)
159
+ #assert_equal(card.fields.indexes(6, 7, 8), card.fields_by_group("some.other"))
160
+ =end
161
+
162
+ # This is my vCard exported from OS X's AddressBook.app.
163
+ EX_APPLE1 =<<'EOF'
164
+ BEGIN:VCARD
165
+ VERSION:3.0
166
+ N:Roberts;Sam;;;
167
+ FN:Roberts Sam
168
+ EMAIL;type=HOME;type=pref:sroberts@uniserve.com
169
+ TEL;type=WORK;type=pref:905-501-3781
170
+ TEL;type=FAX:905-907-4230
171
+ TEL;type=HOME:416 535 5341
172
+ ADR;type=HOME;type=pref:;;376 Westmoreland Ave.;Toronto;ON;M6H 3
173
+ A6;Canada
174
+ NOTE:CATEGORIES: Amis/Famille
175
+ BDAY;value=date:1970-07-14
176
+ END:VCARD
177
+ EOF
178
+ def test_ex_apple1
179
+ card = nil
180
+ assert_nothing_thrown { card = Vpim::Vcard.decode(EX_APPLE1).first }
181
+
182
+ assert_equal("Roberts Sam", card.name.fullname)
183
+ assert_equal("Roberts", card.name.family)
184
+ assert_equal("Sam", card.name.given)
185
+ assert_equal("", card.name.prefix)
186
+ assert_equal("", card.name.suffix)
187
+
188
+ assert_equal(EX_APPLE1, card.to_s(64))
189
+
190
+ check_ex_apple1(card)
191
+ end
192
+
193
+ NICKNAME0=<<'EOF'
194
+ begin:vcard
195
+ end:vcard
196
+ EOF
197
+ NICKNAME1=<<'EOF'
198
+ begin:vcard
199
+ nickname:
200
+ end:vcard
201
+ EOF
202
+ NICKNAME2=<<'EOF'
203
+ begin:vcard
204
+ nickname:
205
+ end:vcard
206
+ EOF
207
+ NICKNAME3=<<'EOF'
208
+ begin:vcard
209
+ nickname: Big Joey
210
+ end:vcard
211
+ EOF
212
+ NICKNAME4=<<'EOF'
213
+ begin:vcard
214
+ nickname:
215
+ nickname: Big Joey
216
+ end:vcard
217
+ EOF
218
+ NICKNAME5=<<'EOF'
219
+ begin:vcard
220
+ nickname:
221
+ nickname: Big Joey
222
+ nickname:Bob
223
+ end:vcard
224
+ EOF
225
+ def test_nickname
226
+ assert_equal(nil, Vpim::Vcard.decode(NICKNAME0).first.nickname)
227
+ assert_equal(nil, Vpim::Vcard.decode(NICKNAME1).first.nickname)
228
+ assert_equal(nil, Vpim::Vcard.decode(NICKNAME2).first.nickname)
229
+ assert_equal('Big Joey', Vpim::Vcard.decode(NICKNAME3).first.nickname)
230
+ assert_equal('Big Joey', Vpim::Vcard.decode(NICKNAME4).first['nickname'])
231
+ assert_equal(['Big Joey', 'Bob'], Vpim::Vcard.decode(NICKNAME5).first.nicknames)
232
+ end
233
+
234
+
235
+ def check_ex_apple1(card)
236
+ assert_equal("3.0", card[ "version" ])
237
+ assert_equal(30, card.version)
238
+
239
+ assert_equal("sroberts@uniserve.com", card[ "email" ])
240
+ assert_equal(["HOME", "pref"], card.enum_by_name("email").entries.first.param("type"))
241
+ assert_equal(nil, card.enum_by_name("email").entries.first.group)
242
+
243
+ assert_equal(["WORK","pref"], card.enum_by_name("tel").entries[0].param("type"))
244
+ assert_equal(["FAX"], card.enum_by_name("tel").entries[1].param("type"))
245
+ assert_equal(["HOME"], card.enum_by_name("tel").entries[2].param("type"))
246
+
247
+ assert_equal(nil, card.enum_by_name("bday").entries[0].param("type"))
248
+ assert_equal(["date"], card.enum_by_name("bday").entries[0].param("value"))
249
+
250
+ assert_equal( 1970, card.enum_by_name("bday").entries[0].to_time[0].year)
251
+ assert_equal( 7, card.enum_by_name("bday").entries[0].to_time[0].month)
252
+ assert_equal( 14, card.enum_by_name("bday").entries[0].to_time[0].day)
253
+
254
+ assert_equal("CATEGORIES: Amis/Famille", card[ "note" ])
255
+ end
256
+
257
+ # Test data for Vpim.expand
258
+ EX_EXPAND =<<'EOF'
259
+ BEGIN:a
260
+ a1:
261
+ BEGIN:b
262
+ BEGIN:c
263
+ c1:
264
+ c2:
265
+ END:c
266
+ V1:
267
+ V2:
268
+ END:b
269
+ a2:
270
+ END:a
271
+ EOF
272
+ def test_expand
273
+ src = Vpim.decode(EX_EXPAND)
274
+ dst = Vpim.expand(src)
275
+
276
+ assert_equal('a', dst[0][0].value)
277
+ assert_equal('A1', dst[0][1].name)
278
+ assert_equal('b', dst[0][2][0].value)
279
+ assert_equal('c', dst[0][2][1][0].value)
280
+ assert_equal('C1', dst[0][2][1][1].name)
281
+ assert_equal('C2', dst[0][2][1][2].name)
282
+ assert_equal('c', dst[0][2][1][3].value)
283
+
284
+ cards = Vpim::Vcard.decode(EX_APPLE1)
285
+
286
+ assert_equal(1, cards.length)
287
+
288
+ check_ex_apple1(cards[0])
289
+ end
290
+
291
+ # An iCalendar for Vpim.expand
292
+ EX_ICAL_1 =<<'EOF'
293
+ BEGIN:VCALENDAR
294
+ CALSCALE:GREGORIAN
295
+ X-WR-TIMEZONE;VALUE=TEXT:Canada/Eastern
296
+ METHOD:PUBLISH
297
+ PRODID:-//Apple Computer\, Inc//iCal 1.0//EN
298
+ X-WR-RELCALID;VALUE=TEXT:18E75B8C-5722-11D7-AB0B-000393AD088C
299
+ X-WR-CALNAME;VALUE=TEXT:Events
300
+ VERSION:2.0
301
+ BEGIN:VEVENT
302
+ SEQUENCE:14
303
+ UID:18E74C28-5722-11D7-AB0B-000393AD088C
304
+ DTSTAMP:20030301T171521Z
305
+ SUMMARY:Bob Log III
306
+ DTSTART;TZID=Canada/Eastern:20030328T200000
307
+ DTEND;TZID=Canada/Eastern:20030328T230000
308
+ DESCRIPTION:Healey's\n\nLook up exact time.\n
309
+ BEGIN:VALARM
310
+ TRIGGER;VALUE=DURATION:-P2D
311
+ ACTION:DISPLAY
312
+ DESCRIPTION:Event reminder
313
+ END:VALARM
314
+ BEGIN:VALARM
315
+ ATTENDEE:mailto:sroberts@uniserve.com
316
+ TRIGGER;VALUE=DURATION:-P1D
317
+ ACTION:EMAIL
318
+ SUMMARY:Alarm notification
319
+ DESCRIPTION:This is an event reminder
320
+ END:VALARM
321
+ END:VEVENT
322
+ BEGIN:VEVENT
323
+ SEQUENCE:1
324
+ DTSTAMP:20030312T043534Z
325
+ SUMMARY:Small Potatoes 10\nFriday\, March 14th\, 8:00 p.m.\n361 Danforth
326
+ Avenue (at Hampton -- Chester subway)\nInfo:_ (416) 480-2802 or (416)
327
+ 323-1715\n
328
+ UID:18E750A8-5722-11D7-AB0B-000393AD088C
329
+ DTSTART;TZID=Canada/Eastern:20030315T000000
330
+ DURATION:PT1H
331
+ BEGIN:VALARM
332
+ ATTENDEE:mailto:sroberts@uniserve.com
333
+ TRIGGER;VALUE=DURATION:-P1D
334
+ ACTION:EMAIL
335
+ SUMMARY:Alarm notification
336
+ DESCRIPTION:This is an event reminder
337
+ END:VALARM
338
+ END:VEVENT
339
+ END:VCALENDAR
340
+ EOF
341
+ def test_ical_1
342
+ src = nil
343
+ dst = nil
344
+ assert_nothing_thrown {
345
+ src = Vpim.decode(EX_ICAL_1)
346
+ dst = Vpim.expand(src)
347
+ }
348
+
349
+ #p dst
350
+ end
351
+
352
+ # Constructed data.
353
+ TST1 =<<'EOF'
354
+ BEGIN:vCard
355
+ DESCRIPTION:Healey's\n\nLook up exact time.\n
356
+ email;type=work:work@example.com
357
+ email;type=internet,home;type=pref:home@example.com
358
+ fax;type=foo,pref;bar:fax
359
+ name:firstname
360
+ name:secondname
361
+ time;value=time:
362
+ END:vCARD
363
+ EOF
364
+ def _test_cons # FIXME
365
+ card = nil
366
+ assert_nothing_thrown { card = Vpim::Vcard.decode(TST1).first }
367
+ assert_equal(TST1, card.to_s)
368
+ assert_equal('Healey\'s\n\nLook up exact time.\n', card[ "description" ])
369
+
370
+ # Test the [] API
371
+ assert_equal(nil, card[ "not-a-field" ])
372
+
373
+ assert_equal('firstname', card[ "name" ])
374
+
375
+ assert_equal('home@example.com', card[ "email" ])
376
+ assert_equal('home@example.com', card[ "email", "pref" ])
377
+ assert_equal('home@example.com', card[ "email", "internet" ])
378
+ assert_equal('work@example.com', card[ "email", "work" ])
379
+
380
+
381
+ # Test the merging of vCard 2.1 type fields.
382
+ #p card
383
+ #p card.enum_by_name('fax').entries[0].each_param { |p,v| puts "#{p} = #{v}\n" }
384
+
385
+ assert_equal('fax', card[ "fax" ])
386
+ assert_equal('fax', card[ "fax", 'bar' ])
387
+ end
388
+
389
+ =begin
390
+ def test_bad
391
+ # FIXME: this should THROW, it's badly encoded!
392
+ assert_nothing_thrown {
393
+ Vpim::Vcard.decode(
394
+ "BEGIN:VCARD\nVERSION:3.0\nKEYencoding=b:this could be \nmy certificate\n\nEND:VCARD\n"
395
+ )
396
+ }
397
+ end
398
+ =end
399
+
400
+ def test_create
401
+ card = Vpim::Vcard.create
402
+
403
+ key = Vpim::DirectoryInfo.decode("key;type=x509;encoding=B:dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK\n")['key']
404
+
405
+ card << Vpim::DirectoryInfo::Field.create('key', key, 'encoding' => :b64)
406
+
407
+ assert_equal(key, card['key'])
408
+
409
+ #p card.to_s
410
+ end
411
+
412
+ def test_values
413
+
414
+ # date
415
+ assert_equal([2002, 4, 22], Vpim.decode_date(" 20020422 "))
416
+ assert_equal([2002, 4, 22], Vpim.decode_date(" 2002-04-22 "))
417
+ assert_equal([2002, 4, 22], Vpim.decode_date(" 2002-04-22 \n"))
418
+
419
+ assert_equal([[2002, 4, 22]],
420
+ Vpim.decode_date_list(" 2002-04-22 "))
421
+
422
+ assert_equal([[2002, 4, 22],[2002, 4, 22]],
423
+ Vpim.decode_date_list(" 2002-04-22, 2002-04-22,"))
424
+
425
+ assert_equal([[2002, 4, 22],[2002, 4, 22]],
426
+ Vpim.decode_date_list(" 2002-04-22,,, , ,2002-04-22, , \n"))
427
+
428
+ assert_equal([],
429
+ Vpim.decode_date_list(" , , "))
430
+
431
+ # time
432
+ assert_equal(
433
+ [4, 53, 22, 0, nil],
434
+ Vpim.decode_time(" 04:53:22 \n")
435
+ )
436
+ assert_equal(
437
+ [4, 53, 22, 0.10, nil],
438
+ Vpim.decode_time(" 04:53:22.10 \n")
439
+ )
440
+ assert_equal(
441
+ [4, 53, 22, 0.10, "Z"],
442
+ Vpim.decode_time(" 04:53:22.10Z \n")
443
+ )
444
+ assert_equal(
445
+ [4, 53, 22, 0, "Z"],
446
+ Vpim.decode_time(" 045322Z \n")
447
+ )
448
+ assert_equal(
449
+ [4, 53, 22, 0, "+0530"],
450
+ Vpim.decode_time(" 04:5322+0530 \n")
451
+ )
452
+ assert_equal(
453
+ [4, 53, 22, 0.10, "Z"],
454
+ Vpim.decode_time(" 045322.10Z \n")
455
+ )
456
+
457
+ # date-time
458
+ assert_equal(
459
+ [2002, 4, 22, 4, 53, 22, 0, nil],
460
+ Vpim.decode_date_time("20020422T04:53:22 \n")
461
+ )
462
+ assert_equal(
463
+ [2002, 4, 22, 4, 53, 22, 0.10, nil],
464
+ Vpim.decode_date_time(" 2002-04-22T04:53:22.10 \n")
465
+ )
466
+ assert_equal(
467
+ [2002, 4, 22, 4, 53, 22, 0.10, "Z"],
468
+ Vpim.decode_date_time(" 20020422T04:53:22.10Z \n")
469
+ )
470
+ assert_equal(
471
+ [2002, 4, 22, 4, 53, 22, 0, "Z"],
472
+ Vpim.decode_date_time(" 20020422T045322Z \n")
473
+ )
474
+ assert_equal(
475
+ [2002, 4, 22, 4, 53, 22, 0, "+0530"],
476
+ Vpim.decode_date_time(" 20020422T04:5322+0530 \n")
477
+ )
478
+ assert_equal(
479
+ [2002, 4, 22, 4, 53, 22, 0.10, "Z"],
480
+ Vpim.decode_date_time(" 20020422T045322.10Z \n")
481
+ )
482
+ assert_equal(
483
+ [2003, 3, 25, 3, 20, 35, 0, "Z"],
484
+ Vpim.decode_date_time("20030325T032035Z")
485
+ )
486
+
487
+ # text
488
+ assert_equal(
489
+ "aa,\n\n,\\,\\a;;b",
490
+ Vpim.decode_text('aa,\\n\\n,\\\\\,\\\\a\;\;b')
491
+ )
492
+ assert_equal(
493
+ ['', "1\n2,3", "bbb", '', "zz", ''],
494
+ Vpim.decode_text_list(',1\\n2\\,3,bbb,,zz,')
495
+ )
496
+ end
497
+
498
+ EX_ENCODE_1 =<<'EOF'
499
+ BEGIN:VCARD
500
+ VERSION:3.0
501
+ N:Roberts;Sam;;;
502
+ FN:Roberts Sam
503
+ EMAIL;type=HOME;type=pref:sroberts@uniserve.com
504
+ TEL;type=HOME:416 535 5341
505
+ ADR;type=HOME;type=pref:;;376 Westmoreland Ave.;Toronto;ON;M6H 3A6;Canada
506
+ NOTE:CATEGORIES: Amis/Famille
507
+ BDAY;value=date:1970-07-14
508
+ END:VCARD
509
+ EOF
510
+
511
+ def test_create_1
512
+ card = Vpim::Vcard.create
513
+
514
+ card << DirectoryInfo::Field.create('n', 'Roberts;Sam;;;')
515
+ card << DirectoryInfo::Field.create('fn', 'Roberts Sam')
516
+ card << DirectoryInfo::Field.create('email', 'sroberts@uniserve.com', 'type' => ['home', 'pref'])
517
+ card << DirectoryInfo::Field.create('tel', '416 535 5341', 'type' => 'home')
518
+ # TODO - allow the value to be an array, in which case it will be
519
+ # concatentated with ';'
520
+ card << DirectoryInfo::Field.create('adr', ';;376 Westmoreland Ave.;Toronto;ON;M6H 3A6;Canada', 'type' => ['home', 'pref'])
521
+ # TODO - allow the date to be a Date, and for value to be set correctly
522
+ card << DirectoryInfo::Field.create('bday', Date.new(1970, 7, 14), 'value' => 'date')
523
+
524
+ # puts card.to_s
525
+ end
526
+
527
+ EX_BDAYS = <<'EOF'
528
+ BEGIN:VCARD
529
+ BDAY;value=date:206-12-15
530
+ END:VCARD
531
+ BEGIN:VCARD
532
+ BDAY;value=date:2003-12-09
533
+ END:VCARD
534
+ BEGIN:VCARD
535
+ END:VCARD
536
+ EOF
537
+
538
+ def test_birthday
539
+ cards = Vpim::Vcard.decode(EX_BDAYS)
540
+
541
+ expected = [
542
+ Date.new(Time.now.year, 12, 15),
543
+ Date.new(2003, 12, 9),
544
+ nil
545
+ ]
546
+
547
+ expected.each_with_index do | d, i|
548
+ #pp d
549
+ #pp i
550
+ #pp cards[i]
551
+ #pp cards[i].birthday.to_s
552
+ #pp cards[i].birthday.class
553
+ assert_equal(d, cards[i].birthday)
554
+ end
555
+
556
+ end
557
+
558
+ EX_ATTACH=<<'---'
559
+ BEGIN:VCARD
560
+ VERSION:3.0
561
+ N:Middle Family;Ny_full
562
+ PHOTO:val\nue
563
+ PHOTO;encoding=8bit:val\nue
564
+ PHOTO;encoding=8bit:val\nue
565
+ PHOTO;encoding=8bit;type=atype:val\nue
566
+ PHOTO;value=binary;encoding=8bit:val\nue
567
+ PHOTO;value=binary;encoding=8bit:val\nue
568
+ PHOTO;value=binary;encoding=8bit;type=atype:val\nue
569
+ PHOTO;value=text;encoding=8bit:val\nue
570
+ PHOTO;value=text;encoding=8bit:val\nue
571
+ PHOTO;value=text;encoding=8bit;type=atype:val\nue
572
+ PHOTO;value=uri:my://
573
+ PHOTO;value=uri;type=atype:my://
574
+ END:VCARD
575
+ ---
576
+ def test_attach
577
+ card = Vpim::Vcard.decode(EX_ATTACH).first
578
+ card.lines # FIXME - assert values are as expected
579
+ end
580
+
581
+ EX_21=<<'---'
582
+ BEGIN:VCARD
583
+ VERSION:2.1
584
+ X-EVOLUTION-FILE-AS:AAA Our Fax
585
+ FN:AAA Our Fax
586
+ N:AAA Our Fax
587
+ ADR;WORK;PREF:
588
+ LABEL;WORK;PREF:
589
+ TEL;WORK;FAX:925 833-7660
590
+ TEL;HOME;FAX:925 833-7660
591
+ TEL;VOICE:1
592
+ TEL;FAX:2
593
+ EMAIL;INTERNET:e@c
594
+ TITLE:
595
+ NOTE:
596
+ UID:pas-id-3F93E22900000001
597
+ END:VCARD
598
+ ---
599
+ def test_v21_modification
600
+ card0 = Vpim::Vcard.decode(EX_21).first
601
+ card1 = Vpim::Vcard::Maker.make2(card0) do |maker|
602
+ maker.nickname = 'nickname'
603
+ end
604
+ card2 = Vpim::Vcard.decode(card1.encode).first
605
+
606
+ assert_equal(card0.version, card1.version)
607
+ assert_equal(card0.version, card2.version)
608
+ end
609
+
610
+ def test_v21_versioned_copy
611
+ card0 = Vpim::Vcard.decode(EX_21).first
612
+ card1 = Vpim::Vcard::Maker.make2(Vpim::DirectoryInfo.create([], 'VCARD')) do |maker|
613
+ maker.copy card0
614
+ end
615
+ card2 = Vpim::Vcard.decode(card1.encode).first
616
+
617
+ assert_equal(card0.version, card2.version)
618
+ end
619
+
620
+ def test_v21_strip_version
621
+ card0 = Vpim::Vcard.decode(EX_21).first
622
+
623
+ card0.delete card0.field('VERSION')
624
+ card0.delete card0.field('TEL')
625
+ card0.delete card0.field('TEL')
626
+ card0.delete card0.field('TEL')
627
+ card0.delete card0.field('TEL')
628
+
629
+ assert_raises(ArgumentError) do
630
+ card0.delete card0.field('END')
631
+ end
632
+ assert_raises(ArgumentError) do
633
+ card0.delete card0.field('BEGIN')
634
+ end
635
+
636
+ card1 = Vpim::Vcard::Maker.make2(Vpim::DirectoryInfo.create([], 'VCARD')) do |maker|
637
+ maker.copy card0
638
+ end
639
+ card2 = Vpim::Vcard.decode(card1.encode).first
640
+
641
+ assert_equal(30, card2.version)
642
+ assert_equal(nil, card2.field('TEL'))
643
+ end
644
+
645
+
646
+ EX_21_CASE0=<<'---'
647
+ BEGIN:VCARD
648
+ VERSION:2.1
649
+ N:Middle Family;Ny_full
650
+ TEL;PREF;HOME;VOICE:0123456789
651
+ TEL;FAX:0123456789
652
+ TEL;CELL;VOICE:0123456789
653
+ TEL;HOME;VOICE:0123456789
654
+ TEL;WORK;VOICE:0123456789
655
+ EMAIL:email@email.com
656
+ EMAIL:work@work.com
657
+ URL:www.email.com
658
+ URL:www.work.com
659
+ LABEL;CHARSET=ISO-8859-1;ENCODING=QUOTED-PRINTABLE:Box 1234=0AWorkv=E4gen =
660
+ 2=0AWorkv=E4gen 1=0AUme=E5=0AV=E4sterbotten=0A12345=0AS
661
+ END:VCARD
662
+ ---
663
+ def test_v21_case0
664
+ card = Vpim::Vcard.decode(EX_21_CASE0).first
665
+ # pp card.field('LABEL').value_raw
666
+ # pp card.field('LABEL').value
667
+ end
668
+
669
+ def test_modify_name
670
+ card = Vcard.decode("begin:vcard\nend:vcard\n").first
671
+
672
+ assert_raises(InvalidEncodingError) do
673
+ card.name
674
+ end
675
+
676
+ assert_raises(Unencodeable) do
677
+ Vcard::Maker.make2(card) {}
678
+ end
679
+
680
+ card.make do |m|
681
+ m.name {}
682
+ end
683
+
684
+ assert_equal('', card.name.given)
685
+ assert_equal('', card.name.fullname)
686
+
687
+ assert_raises(TypeError, RuntimeError) do
688
+ card.name.given = 'given'
689
+ end
690
+
691
+ card.make do |m|
692
+ m.name do |n|
693
+ n.given = 'given'
694
+ end
695
+ end
696
+
697
+ assert_equal('given', card.name.given)
698
+ assert_equal('given', card.name.fullname)
699
+ assert_equal('' , card.name.family)
700
+
701
+ card.make do |m|
702
+ m.name do |n|
703
+ n.family = n.given
704
+ n.prefix = ' Ser '
705
+ n.fullname = 'well given'
706
+ end
707
+ end
708
+
709
+ assert_equal('given', card.name.given)
710
+ assert_equal('given', card.name.family)
711
+ assert_equal('Ser given given', card.name.formatted)
712
+ assert_equal('well given', card.name.fullname)
713
+ end
714
+
715
+ def test_add_note
716
+ note = "hi\' \ \"\",,;; \n \n field"
717
+
718
+ card = Vpim::Vcard::Maker.make2 do |m|
719
+ m.add_note(note)
720
+ m.name {}
721
+ end
722
+
723
+ assert_equal(note, card.note)
724
+ end
725
+
726
+ def test_empty_tel
727
+ cin = <<___
728
+ BEGIN:VCARD
729
+ TEL;HOME;FAX:
730
+ END:VCARD
731
+ ___
732
+
733
+ card = Vpim::Vcard.decode(cin).first
734
+ assert_equal(card.telephone, nil)
735
+ assert_equal(card.telephone('HOME'), nil)
736
+ assert_equal([], card.telephones)
737
+
738
+ end
739
+
740
+ def test_slash_in_field_name
741
+ cin = <<___
742
+ BEGIN:VCARD
743
+ X-messaging/xmpp-All:some@jabber.id
744
+ END:VCARD
745
+ ___
746
+
747
+ card = Vpim::Vcard.decode(cin).first
748
+ assert_equal(card.value("X-messaging/xmpp-All"), "some@jabber.id")
749
+ assert_equal(card["X-messaging/xmpp-All"], "some@jabber.id")
750
+ end
751
+
752
+ def test_url_decode
753
+ cin=<<'---'
754
+ BEGIN:VCARD
755
+ URL:www.email.com
756
+ URL:www.work.com
757
+ END:VCARD
758
+ ---
759
+ card = Vpim::Vcard.decode(cin).first
760
+
761
+ assert_equal("www.email.com", card.url.uri)
762
+ assert_equal("www.email.com", card.url.uri.to_s)
763
+ assert_equal("www.email.com", card.urls.first.uri)
764
+ assert_equal("www.work.com", card.urls.last.uri)
765
+ end
766
+
767
+ def test_bday_decode
768
+ cin=<<'---'
769
+ BEGIN:VCARD
770
+ BDAY:1970-07-14
771
+ END:VCARD
772
+ ---
773
+ card = Vpim::Vcard.decode(cin).first
774
+
775
+ card.birthday
776
+
777
+ assert_equal(Date.new(1970, 7, 14), card.birthday)
778
+ assert_equal(1, card.values("bday").size)
779
+
780
+ # Nobody should have multiple bdays, I hope, but its allowed syntactically,
781
+ # so test it, along with some variant forms of BDAY
782
+ cin=<<'---'
783
+ BEGIN:VCARD
784
+ BDAY:1970-07-14
785
+ BDAY:70-7-14
786
+ BDAY:1970-07-15T03:45:12
787
+ BDAY:1970-07-15T03:45:12Z
788
+ END:VCARD
789
+ ---
790
+ card = Vpim::Vcard.decode(cin).first
791
+
792
+ assert_equal(Date.new(1970, 7, 14), card.birthday)
793
+ assert_equal(4, card.values("bday").size)
794
+ assert_equal(Date.new(1970, 7, 14), card.values("bday").first)
795
+ assert_equal(Date.new(Time.now.year, 7, 14), card.values("bday")[1])
796
+ assert_equal(DateTime.new(1970, 7, 15, 3, 45, 12).to_s, card.values("bday")[2].to_s)
797
+ assert_equal(DateTime.new(1970, 7, 15, 3, 45, 12).to_s, card.values("bday").last.to_s)
798
+ end
799
+
800
+ def utf_name_test(c)
801
+
802
+ begin
803
+ card = Vpim::Vcard.decode(c).first
804
+ assert_equal("name", card.name.family)
805
+ rescue
806
+ $!.message << " #{c.inspect}"
807
+ raise
808
+ end
809
+ end
810
+
811
+ def be(s)
812
+ s.unpack('U*').pack('n*')
813
+ end
814
+ def le(s)
815
+ s.unpack('U*').pack('v*')
816
+ end
817
+
818
+ def test_utf_heuristics
819
+ bom = "\xEF\xBB\xBF"
820
+ dat = "BEGIN:VCARD\nN:name\nEND:VCARD\n"
821
+ utf_name_test(bom+dat)
822
+ utf_name_test(bom+dat.downcase)
823
+ utf_name_test(dat)
824
+ utf_name_test(dat.downcase)
825
+
826
+ utf_name_test(be(bom+dat))
827
+ utf_name_test(be(bom+dat.downcase))
828
+ utf_name_test(be(dat))
829
+ utf_name_test(be(dat.downcase))
830
+
831
+ utf_name_test(le(bom+dat))
832
+ utf_name_test(le(bom+dat.downcase))
833
+ utf_name_test(le(dat))
834
+ utf_name_test(le(dat.downcase))
835
+ end
836
+
837
+ # Broken output from Highrise. Report to support@highrisehq.com
838
+ def test_highrises_invalid_google_talk_field
839
+ c = <<'__'
840
+ BEGIN:VCARD
841
+ VERSION:3.0
842
+ REV:20080409T095515Z
843
+ X-YAHOO;TYPE=HOME:yahoo.john
844
+ X-GOOGLE TALK;TYPE=WORK:gtalk.john
845
+ X-SAMETIME;TYPE=WORK:sametime.john
846
+ X-SKYPE;TYPE=WORK:skype.john
847
+ X-MSN;TYPE=WORK:msn.john
848
+ X-JABBER;TYPE=WORK:jabber.john
849
+ N:Doe;John;;;
850
+ ADR;TYPE=WORK:;;456 Grandview Building\, Wide Street;San Diego;CA;90204;
851
+ United States
852
+ ADR;TYPE=HOME:;;123 Sweet Home\, Narrow Street;New York;NY;91102;United
853
+ States
854
+ URL;TYPE=OTHER:http\://www.homepage.com
855
+ URL;TYPE=HOME:http\://www.home.com
856
+ URL;TYPE=WORK:http\://www.work.com
857
+ URL;TYPE=OTHER:http\://www.other.com
858
+ URL;TYPE=OTHER:http\://www.custom.com
859
+ ORG:John Doe & Partners Limited;;
860
+ TEL;TYPE=WORK:11111111
861
+ TEL;TYPE=CELL:22222222
862
+ TEL;TYPE=HOME:33333333
863
+ TEL;TYPE=OTHER:44444444
864
+ TEL;TYPE=FAX:55555555
865
+ TEL;TYPE=FAX:66666666
866
+ TEL;TYPE=PAGER:77777777
867
+ TEL;TYPE=OTHER:88888888
868
+ TEL;TYPE=OTHER:99999999
869
+ UID:cc548e11-569e-3bf5-a9aa-722de4571f4a
870
+ X-ICQ;TYPE=HOME:icq.john
871
+ EMAIL;TYPE=WORK,INTERNET:john.doe@work.com
872
+ EMAIL;TYPE=HOME,INTERNET:john.doe@home.com
873
+ EMAIL;TYPE=OTHER,INTERNET:john.doe@other.com
874
+ EMAIL;TYPE=OTHER,INTERNET:john.doe@custom.com
875
+ TITLE:Sales Manager
876
+ X-OTHER;TYPE=WORK:other.john
877
+ X-AIM;TYPE=WORK:aim.john
878
+ X-QQ;TYPE=WORK:qq.john
879
+ FN:John Doe
880
+ END:VCARD
881
+ __
882
+
883
+ card = Vpim::Vcard.decode(c).first
884
+ assert_equal("Doe", card.name.family)
885
+ assert_equal("456 Grandview Building, Wide Street", card.address('work').street)
886
+ assert_equal("123 Sweet Home, Narrow Street", card.address('home').street)
887
+ assert_equal("John Doe & Partners Limited", card.org.first)
888
+ assert_equal("gtalk.john", card.value("x-google talk"))
889
+ assert_equal("http\\://www.homepage.com", card.url.uri)
890
+
891
+ end
892
+
893
+ def _test_gmail_vcard_export
894
+ # GOOGLE BUG - Whitespace before the LABEL field values is a broken
895
+ # line continuation.
896
+ # GOOGLE BUG - vCards are being exported with embedded "=" in them, so
897
+ # become unparseable.
898
+ c = <<'__'
899
+ BEGIN:VCARD
900
+ VERSION:3.0
901
+ FN:Stepcase TestUser
902
+ N:TestUser;Stepcase;;;
903
+ EMAIL;TYPE=INTERNET:testuser@stepcase.com
904
+ X-GTALK:gtalk.step
905
+ X-AIM:aim.step
906
+ X-YAHOO:yahoo.step
907
+ X-MSN:msn.step
908
+ X-ICQ:icq.step
909
+ X-JABBER:jabber.step
910
+ TEL;TYPE=FAX:44444444
911
+ TEL;TYPE=PAGER:66666666
912
+ TEL;TYPE=HOME:22222222
913
+ TEL;TYPE=CELL:11111111
914
+ TEL;TYPE=FAX:55555555
915
+ TEL;TYPE=WORK:33333333
916
+ LABEL;TYPE=HOME;ENCODING=QUOTED-PRINTABLE:123 Home, Home Street=0D=0A=
917
+ Kowloon, N/A=0D=0A=
918
+ Hong Kong
919
+ LABEL;TYPE=HOME;ENCODING=QUOTED-PRINTABLE:321 Office, Work Road=0D=0A=
920
+ Tsuen Wan NT=0D=0A=
921
+ Hong Kong
922
+ TITLE:CTO
923
+ ORG:Stepcase.com
924
+ NOTE:Stepcase test user is a robot.
925
+ END:VCARD
926
+ __
927
+ card = Vpim::Vcard.decode(c).first
928
+ assert_equal("123 Home, Home Street\r\n Kowloon, N/A\r\n Hong Kong", card.value("label"))
929
+ end
930
+
931
+ def test_title
932
+ title = "She Who Must Be Obeyed"
933
+ card = Vpim::Vcard::Maker.make2 do |m|
934
+ m.name do |n|
935
+ n.given = "Hilda"
936
+ n.family = "Rumpole"
937
+ end
938
+ m.title = title
939
+ end
940
+ assert_equal(title, card.title)
941
+ card = Vpim::Vcard.decode(card.encode).first
942
+ assert_equal(title, card.title)
943
+ end
944
+
945
+ def _test_org(*org)
946
+ card = Vpim::Vcard::Maker.make2 do |m|
947
+ m.name do |n|
948
+ n.given = "Hilda"
949
+ n.family = "Rumpole"
950
+ end
951
+ m.org = org
952
+ end
953
+ assert_equal(org, card.org)
954
+ card = Vpim::Vcard.decode(card.encode).first
955
+ assert_equal(org, card.org)
956
+ end
957
+
958
+ def test_org_single
959
+ _test_org("Megamix Corp.")
960
+ end
961
+
962
+ def test_org_multiple
963
+ _test_org("Megamix Corp.", "Marketing")
964
+ end
965
+
966
+ end
967
+