diff --git a/lib/vobject/component.rb b/lib/vobject/component.rb index 637ef7d..0d3a06b 100644 --- a/lib/vobject/component.rb +++ b/lib/vobject/component.rb @@ -37,7 +37,7 @@ def initialize(key, cs, err) end end end - self.errors = err + self.errors = err.select { |e| !e.nil? } self.norm = nil end diff --git a/lib/vobject/propertyvalue.rb b/lib/vobject/propertyvalue.rb index d3b47d3..b82e668 100644 --- a/lib/vobject/propertyvalue.rb +++ b/lib/vobject/propertyvalue.rb @@ -8,7 +8,7 @@ def <=>(another) def initialize(val) self.value = val - self.type = "property" + self.type = "text" # safe default self.norm = nil end diff --git a/lib/vobject/vcard/v4_0/property.rb b/lib/vobject/vcard/v4_0/property.rb index a92d797..f321f94 100644 --- a/lib/vobject/vcard/v4_0/property.rb +++ b/lib/vobject/vcard/v4_0/property.rb @@ -1,38 +1,63 @@ require "vobject/property" +require "vobject/parameter" +require "pp" module Vcard::V4_0 class Property < Vobject::Property - end - - def parameter_base_class - version_class.const_get(:Parameter) - end +=begin + def parameter_base_class + version_class.const_get(:Parameter) + end +=end - def property_base_class - version_class.const_get(:Property) - end + def property_base_class + version_class.const_get(:Property) + end +=begin + def to_norm + puts "XXX" + if norm.nil? + if multiple.nil? || multiple.empty? + ret = to_norm_line + else + arr = [] + multiple.sort.each do |x| + arr << x.to_norm_line + end + ret = arr.join("") + end + norm = ret + end + norm + end +=end - def to_norm_line - line = group ? "#{group}." : "" - line << name.to_s.tr("_", "-").upcase + def to_norm_line + line = group ? "#{group}." : "" + line << name.to_s.tr("_", "-").upcase - # add mandatory VALUE param - outparams = params - outparams[:VALUE] = value.type + # add mandatory VALUE param + outparams = params + if outparams.nil? + outparams = [] + end + outparams = outparams.select { |p| p.param_name != :VALUE } + outparams << Vobject::Parameter.new(:VALUE, value.type) - (outparams || {}).sort.each do |p| - line << ";#{p.to_norm}" - end + (outparams || {}).sort.each do |p| + line << ";#{p.to_norm}" + end - line << ":#{value.to_norm}" + line << ":#{value.to_norm}" - line = Vobject::fold_line(line) << "\n" + line = Vobject::fold_line(line) << "\n" - line - end + line + end - def version_class - Vcard::V4_0 + def version_class + Vcard::V4_0 + end end end diff --git a/lib/vobject/vcard/v4_0/propertyvalue.rb b/lib/vobject/vcard/v4_0/propertyvalue.rb index fc5a6be..c765ab4 100644 --- a/lib/vobject/vcard/v4_0/propertyvalue.rb +++ b/lib/vobject/vcard/v4_0/propertyvalue.rb @@ -92,6 +92,7 @@ def to_s class Clientpidmap < Text def initialize(val) self.value = val + # not explicitly specified in spec self.type = "text" end @@ -381,7 +382,7 @@ def to_hash class Address < Vobject::PropertyValue def initialize(val) self.value = val - self.type = "address" + self.type = "text" end def to_s diff --git a/lib/vobject/vcard/v4_0/typegrammars.rb b/lib/vobject/vcard/v4_0/typegrammars.rb index a7f729b..2e9884b 100644 --- a/lib/vobject/vcard/v4_0/typegrammars.rb +++ b/lib/vobject/vcard/v4_0/typegrammars.rb @@ -213,7 +213,9 @@ def timestamp h end timestamp = seq(date_complete << "T".r, time_complete) do |d, t| - PropertyValue::DateTimeLocal.new(d.merge(t)) + ret = PropertyValue::DateTimeLocal.new(d.merge(t)) + ret.type = 'timestamp' + ret end timestamp.eof end @@ -279,9 +281,19 @@ def date_and_or_time end | seq("-", "-", second) do |_, _, s| { sec: s } end - date_and_or_time = date_time.map { |d| PropertyValue::DateTimeLocal.new d } | - date.map { |d| PropertyValue::Date.new d } | - seq("T".r >> time).map { |t| PropertyValue::Time.new t } + date_and_or_time = date_time.map do |d| + ret = PropertyValue::DateTimeLocal.new d + ret.type = "date-and-or-time" + ret + end | date.map do |d| + ret = PropertyValue::Date.new d + ret.type = "date-and-or-time" + ret + end | seq("T".r >> time).map do |t| + ret = PropertyValue::Time.new t + ret.type = "date-and-or-time" + ret + end date_and_or_time.eof end diff --git a/spec/examples/vcard/apple5.norm.vcf b/spec/examples/vcard/apple5.norm.vcf new file mode 100644 index 0000000..b03ea61 --- /dev/null +++ b/spec/examples/vcard/apple5.norm.vcf @@ -0,0 +1,25 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +FN;VALUE="text":Apple Inc. +IMPP;TYPE="HOME","PREF";VALUE="uri";X-SERVICE-TYPE="AIM":aim:aimuser +IMPP;TYPE="WORK";VALUE="uri";X-SERVICE-TYPE="AIM":aim:workaimuser +item10.IMPP;VALUE="uri";X-SERVICE-TYPE="ICQ":aim:i%20seek%20you +item11.IMPP;VALUE="uri";X-SERVICE-TYPE="QQ":x-apple:QQmoar +item12.IMPP;VALUE="uri";X-SERVICE-TYPE="SKYPE":skype:skypie +item13.IMPP;VALUE="uri";X-SERVICE-TYPE="MSN":msnim:msnisnomore +item7.IMPP;VALUE="uri";X-SERVICE-TYPE="FACEBOOK":xmpp:facebookuser +item8.IMPP;VALUE="uri";X-SERVICE-TYPE="GADUGADU":x-apple:gadugaduser +item9.IMPP;VALUE="uri";X-SERVICE-TYPE="GOOGLETALK":xmpp:googleuser +N;VALUE="text":Surnom;Nom;;; +ORG;VALUE="text":Apple Inc.; +PRODID;VALUE="text":-//Apple Inc.//Mac OS X 10.8.4//EN +X-ABSHOWAS;VALUE="text":COMPANY +X-ABUID;VALUE="text":904132B1-9C20-4D38-A1B9-32DE9A621DB8:ABPerson +item10.X-ABLABEL;VALUE="text":other tag +item11.X-ABLABEL;VALUE="text":other tag +item12.X-ABLABEL;VALUE="text":other tag +item13.X-ABLABEL;VALUE="text":other tag +item7.X-ABLABEL;VALUE="text":other tag +item8.X-ABLABEL;VALUE="text":_$!!$_ +item9.X-ABLABEL;VALUE="text":other tag +END:VCARD diff --git a/spec/examples/vcard/bubba4.norm.vcf b/spec/examples/vcard/bubba4.norm.vcf new file mode 100644 index 0000000..5d2240d --- /dev/null +++ b/spec/examples/vcard/bubba4.norm.vcf @@ -0,0 +1,18 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +ADR;TYPE="HOME";VALUE="text":;;42 Plantation St.;Baytown;LA;30314;United St + ates of America +ADR;TYPE="PREF","WORK";VALUE="text":;;100 Waters Edge;Baytown;LA;30314;Unit + ed States of America +EMAIL;VALUE="text":forrestgump@example.com +FN;VALUE="text":Forrest Gump +N;VALUE="text":Forrest;Gump;;Mr.; +ORG;VALUE="text":Bubba Gump Shrimp Co. +PHOTO;MEDIATYPE="image/gif";VALUE="uri":http://www.example.com/dir_photos/m + y_photo.gif +REV;VALUE="timestamp":20080424T195243Z +TEL;TYPE="HOME","VOICE";VALUE="uri":tel:+1-404-555-1212 +TEL;TYPE="VOICE","WORK";VALUE="uri":tel:+1-111-555-1212 +TITLE;VALUE="text":Shrimp Man +X-QQ;VALUE="text":21588891 +END:VCARD diff --git a/spec/examples/vcard/example1.norm.vcf b/spec/examples/vcard/example1.norm.vcf new file mode 100644 index 0000000..382872b --- /dev/null +++ b/spec/examples/vcard/example1.norm.vcf @@ -0,0 +1,13 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +CLIENTPIDMAP;VALUE="text":1;urn:uuid:53e374d9-337e-4727-8803-a1e9c14e0556 +CLIENTPIDMAP;VALUE="text":2;urn:uuid:1f762d2b-03c4-4a83-9a03-75ff658a6eee +EMAIL;PID="1.1";VALUE="text":jdoe@example.com +EMAIL;PID="2.1";VALUE="text":boss@example.com +EMAIL;PID="2.2";VALUE="text":ceo@example.com +FN;VALUE="text":J. Doe +N;VALUE="text":Doe;J.;;; +TEL;PID="1.1";VALUE="uri":tel:+1-555-555-5555 +TEL;PID="2.1","2.2";VALUE="uri":tel:+1-666-666-6666 +UID;VALUE="uri":urn:uuid:4fbe8971-0bc3-424c-9c26-36c3e1eff6b1 +END:VCARD diff --git a/spec/examples/vcard/example2.norm.vcf b/spec/examples/vcard/example2.norm.vcf new file mode 100644 index 0000000..6b15a31 --- /dev/null +++ b/spec/examples/vcard/example2.norm.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +FN;VALUE="text":Testing Vcard +END:VCARD diff --git a/spec/examples/vcard/fullcontact.norm.vcf b/spec/examples/vcard/fullcontact.norm.vcf new file mode 100644 index 0000000..37b4e40 --- /dev/null +++ b/spec/examples/vcard/fullcontact.norm.vcf @@ -0,0 +1,96 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +ADR;TYPE="CUSTOMTYPE";VALUE="text":;CustomExtended;CustomStreet;CustomCity; + CustomState;CustomPostal;CustomCountry +ADR;TYPE="HOME";VALUE="text":;HomeExtended;HomeStreet;HomeCity;HomeState;Ho + mePostal;HomeCountry +ADR;TYPE="OTHER";VALUE="text":;OtherExtended;OtherStreet;OtherCity;OtherSta + te;OtherPostal;OtherCountry +ADR;TYPE="WORK";VALUE="text":;WorkExtended;WorkStreet;WorkCity;WorkState;Wo + rkPostal;WorkCountry +BDAY;ALTID="1";VALUE="date-and-or-time":20160801 +BDAY;ALTID="1";VALUE="text":2016-08-01 +CATEGORIES;VALUE="text":Tag +EMAIL;TYPE="CUSTOMTYPE";VALUE="text":custom@example.com +EMAIL;TYPE="HOME";VALUE="text":home@example.com +EMAIL;TYPE="OTHER";VALUE="text":other@example.com +EMAIL;TYPE="SCHOOL";VALUE="text":school@example.com +EMAIL;TYPE="WORK";VALUE="text":work@example.com +FN;VALUE="text":Prefix FirstName MiddleName LastName Suffix +GENDER;VALUE="text":M +IMPP;VALUE="uri";X-SERVICE-TYPE="AIM":aim:aim +IMPP;VALUE="uri";X-SERVICE-TYPE="CUSTOMTYPE":customtype:custom +IMPP;VALUE="uri";X-SERVICE-TYPE="GTALK":xmpp:gtalk +IMPP;VALUE="uri";X-SERVICE-TYPE="JABBER":xmpp:jabber +IMPP;VALUE="uri";X-SERVICE-TYPE="OTHER":other:other +IMPP;VALUE="uri";X-SERVICE-TYPE="SKYPE":skype:skype +IMPP;VALUE="uri";X-SERVICE-TYPE="YAHOO":ymsgr:yahoo +N;VALUE="text":LastName;FirstName;MiddleName;Prefix;Suffix +NICKNAME;VALUE="text":NickName +NOTE;VALUE="text":Notes line 1\nNotes line 2 +ORG;VALUE="text":Organization1;Department1 +ORG;VALUE="text":Organization2;Department2 +PHOTO;VALUE="uri":https://d2ojpxxtu63wzl.cloudfront.net/static/aa915d1f29f1 + 9baf560e5491decdd30a_67c95da9133249fde8b0da7ceebc298bf680117e6f52054f7f5f7 + a95e8377238 +PHOTO;VALUE="uri":https://d3m0kzytmr41b1.cloudfront.net/c335e945d1b60edd9d7 + 5eb4837c432f637e95c8a +PHOTO;VALUE="uri":https://d3m0kzytmr41b1.cloudfront.net/c335e945d1b60edd9d7 + 5eb4837c432f637e95c8a +PRODID;VALUE="text":ez-vcard 0.9.14-fc +TEL;TYPE="CELL","VOICE";VALUE="text":555-555-1113 +TEL;TYPE="CELL","VOICE";VALUE="text":555-555-1114 +TEL;TYPE="FAX","HOME";VALUE="text":555-555-1116 +TEL;TYPE="FAX","WORK";VALUE="text":555-555-1117 +TEL;TYPE="HOME","VOICE";VALUE="text":555-555-1111 +TEL;TYPE="VOICE","WORK";VALUE="text":555-555-1112 +TEL;TYPE="VOICE";VALUE="text":555-555-1115 +TEL;TYPE="VOICE";VALUE="text":555-555-1118 +TEL;TYPE="VOICE";VALUE="text":555-555-1119 +TITLE;VALUE="text":Title1 +TITLE;VALUE="text":Title2 +URL;VALUE="uri":http://www.blog.com +URL;VALUE="uri":http://www.custom.com +URL;VALUE="uri":http://www.homepage.com +URL;VALUE="uri":http://www.other.com +X-ETAG;VALUE="text":fffffea9056d8166e2b7a427977e570c87dd51279d11d9b137c593e + b +X-FC-LIST-ID;VALUE="text":8ad23200aa3e1984736b11e688dc0add41994b95 +X-FC-TAGS;VALUE="text":579c773f-736d-11e6-8dff-0ac8448704fb +X-FCENCODED-582D46432D4F7468657244617465733A416E6E6976657273617279;VALUE="t + ext":2016-08-02 +X-FCENCODED-582D46432D4F7468657244617465733A437573746F6D54595045;VALUE="tex + t":2016-08-04 +X-FCENCODED-582D46432D4F7468657244617465733A4F74686572;VALUE="text":2016-08 + -03 +X-FCENCODED-582D46432D52656C617465644E616D65733A417373697374616E74;VALUE="t + ext":Assistant +X-FCENCODED-582D46432D52656C617465644E616D65733A42726F74686572;VALUE="text" + :Brother +X-FCENCODED-582D46432D52656C617465644E616D65733A4368696C64;VALUE="text":Chi + ld +X-FCENCODED-582D46432D52656C617465644E616D65733A437573746F6D54595045;VALUE= + "text":Custom +X-FCENCODED-582D46432D52656C617465644E616D65733A466174686572;VALUE="text":F + ather +X-FCENCODED-582D46432D52656C617465644E616D65733A4669616E63C3A9;VALUE="text" + :Fiance +X-FCENCODED-582D46432D52656C617465644E616D65733A467269656E64;VALUE="text":F + riend +X-FCENCODED-582D46432D52656C617465644E616D65733A4D616E61676572;VALUE="text" + :Manager +X-FCENCODED-582D46432D52656C617465644E616D65733A4D6F74686572;VALUE="text":M + other +X-FCENCODED-582D46432D52656C617465644E616D65733A4F74686572;VALUE="text":Oth + er +X-FCENCODED-582D46432D52656C617465644E616D65733A506172656E74;VALUE="text":P + arent +X-FCENCODED-582D46432D52656C617465644E616D65733A506172746E6572;VALUE="text" + :Partner +X-FCENCODED-582D46432D52656C617465644E616D65733A536973746572;VALUE="text":S + ister +X-FCENCODED-582D46432D52656C617465644E616D65733A53706F757365;VALUE="text":S + pouse +X-GENDER;VALUE="text":male +X-ID;VALUE="text":14f9aba0c9422da9ae376fe28bd89c2a.0 +END:VCARD diff --git a/spec/examples/vcard/rfc6473.norm.vcf b/spec/examples/vcard/rfc6473.norm.vcf new file mode 100644 index 0000000..27f0973 --- /dev/null +++ b/spec/examples/vcard/rfc6473.norm.vcf @@ -0,0 +1,14 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +EMAIL;VALUE="text":xmpp@jabber.org +FN;VALUE="text":jabber.org IM service +GEO;VALUE="uri":geo:42.25\,-91.05 +IMPP;VALUE="uri":xmpp:jabber.org +KIND;VALUE="text":application +LANG;PREF="1";VALUE="language-tag":en +LOGO;VALUE="uri":http://www.jabber.org/images/logo.png +REV;VALUE="timestamp":19990104T122100Z +SOURCE;VALUE="uri":xmpp:jabber.org?vcard +TZ;VALUE="text":America/Chicago +URL;VALUE="uri":http://www.jabber.org/ +END:VCARD diff --git a/spec/examples/vcard/rfc6474.1.norm.vcf b/spec/examples/vcard/rfc6474.1.norm.vcf new file mode 100644 index 0000000..2d541bf --- /dev/null +++ b/spec/examples/vcard/rfc6474.1.norm.vcf @@ -0,0 +1,8 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +BIRTHPLACE;VALUE="text":Babies'R'Us Hospital +DEATHDATE;VALUE="date-and-or-time":--0415 +DEATHPLACE;VALUE="text":Aboard the Titanic\, near Newfoundland +FN;VALUE="text":Simon Perreault +N;VALUE="text":Perreault;Simon;;;ing. jr,M.Sc. +END:VCARD diff --git a/spec/examples/vcard/rfc6474.2.norm.vcf b/spec/examples/vcard/rfc6474.2.norm.vcf new file mode 100644 index 0000000..f9850bc --- /dev/null +++ b/spec/examples/vcard/rfc6474.2.norm.vcf @@ -0,0 +1,8 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +BIRTHPLACE;VALUE="uri":http://example.com/hospitals/babiesrus.vcf +DEATHDATE;VALUE="date-and-or-time":19531015T231000Z +DEATHPLACE;VALUE="uri":http://example.com/ships/titanic.vcf +FN;VALUE="text":Simon Perreault +N;VALUE="text":Perreault;Simon;;;ing. jr,M.Sc. +END:VCARD diff --git a/spec/examples/vcard/rfc6474.3.norm.vcf b/spec/examples/vcard/rfc6474.3.norm.vcf new file mode 100644 index 0000000..9e48eb5 --- /dev/null +++ b/spec/examples/vcard/rfc6474.3.norm.vcf @@ -0,0 +1,8 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +BIRTHPLACE;VALUE="uri":geo:46.769307\,-71.283079 +DEATHDATE;VALUE="text":circa 1800 +DEATHPLACE;VALUE="uri":geo:41.731944\,-49.945833 +FN;VALUE="text":Simon Perreault +N;VALUE="text":Perreault;Simon;;;ing. jr,M.Sc. +END:VCARD diff --git a/spec/examples/vcard/rfc6715.1.norm.vcf b/spec/examples/vcard/rfc6715.1.norm.vcf new file mode 100644 index 0000000..f2661ed --- /dev/null +++ b/spec/examples/vcard/rfc6715.1.norm.vcf @@ -0,0 +1,14 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +EXPERTISE;INDEX="1";LEVEL="EXPERT";VALUE="text":chemistry +EXPERTISE;INDEX="2";LEVEL="BEGINNER";VALUE="text":chinese literature +FN;VALUE="text":Simon Perreault +HOBBY;INDEX="1";LEVEL="HIGH";VALUE="text":reading +HOBBY;INDEX="2";LEVEL="HIGH";VALUE="text":sewing +INTEREST;INDEX="1";LEVEL="MEDIUM";VALUE="text":r&b music +INTEREST;INDEX="2";LEVEL="HIGH";VALUE="text":rock 'n' roll music +N;VALUE="text":Perreault;Simon;;;ing. jr,M.Sc. +ORG-DIRECTORY;INDEX="1";VALUE="uri":http://directory.mycompany.example.com +ORG-DIRECTORY;PREF="1";VALUE="uri":ldap://ldap.tech.example/o=Example%20Tec + h,ou=Engineering +END:VCARD diff --git a/spec/examples/vcard/trafalgar.norm.vcf b/spec/examples/vcard/trafalgar.norm.vcf new file mode 100644 index 0000000..d4b9607 --- /dev/null +++ b/spec/examples/vcard/trafalgar.norm.vcf @@ -0,0 +1,13 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +ADR;PREF="1";TYPE="HOME";VALUE="text":;;1 Trafalgar Square;London;;WC2N;Uni + ted Kingdom +EMAIL;PREF="1";TYPE="HOME";VALUE="text":me@joebloggs.com +FN;VALUE="text":Joe Bloggs +IMPP;PREF="1";TYPE="HOME";VALUE="uri":skype:joe.bloggs +N;VALUE="text":Bloggs;Joe;;; +TEL;PREF="1";TYPE="CELL","HOME";VALUE="text":tel:+44 20 1234 5678 +URL;PREF="1";TYPE="HOME";VALUE="uri":http://joebloggs.com +X-SOCIALPROFILE;PREF="1";TYPE="HOME";VALUE="text":twitter:https://twitter.c + om/joebloggs +END:VCARD diff --git a/spec/examples/vcard/ujb3.norm.vcf b/spec/examples/vcard/ujb3.norm.vcf new file mode 100644 index 0000000..0b8819a --- /dev/null +++ b/spec/examples/vcard/ujb3.norm.vcf @@ -0,0 +1,15 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +ADR;TYPE="PREF","WORK";VALUE="text":;;aweg223;323;;;223 +EMAIL;TYPE="INTERNET","PREF","WORK";VALUE="text":hahahahahaahhajaneqblogg@a + sdf.example.com +FN;VALUE="text":Jane Q Blogg +N;VALUE="text":Q Blogg;Jane;;; +OFFICE;VALUE="text":aowi +ORG;VALUE="text":oi;oiwgo +PRODID;VALUE="text":Microsoft-MacOutlook/14.10.0.110310 +TEL;TYPE="CELL";VALUE="text":aweg +TEL;TYPE="WORK";VALUE="text":23g23 +TITLE;VALUE="text":messiah +X-MS-IMADDRESS;TYPE="PREF";VALUE="text":mehemehehe@asdf.example.com +END:VCARD diff --git a/spec/examples/vcard/vcard4.norm.vcf b/spec/examples/vcard/vcard4.norm.vcf new file mode 100644 index 0000000..0d12133 --- /dev/null +++ b/spec/examples/vcard/vcard4.norm.vcf @@ -0,0 +1,37 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +ADR;TYPE="WORK";VALUE="text":pobox;apt;street;city;state;zipcode;country +ANNIVERSARY;VALUE="date-and-or-time":19960415 +BDAY;VALUE="date-and-or-time":--0203 +CALADRURI;VALUE="uri":http://example.com/calendar/jdoe +CALURI;MEDIATYPE="text/calendar";VALUE="uri":ftp://ftp.example.com/calA.ics +CLIENTPIDMAP;VALUE="text":1;urn:uuid:3df403f4-5924-4bb7-b077-3c711d9eb34b +EMAIL;TYPE="WORK";VALUE="text":jqpublic@xyz.example.com +FBURL;MEDIATYPE="text/calendar";VALUE="uri":ftp://example.com/busy/project- + a.ifb +FN;VALUE="text":J. Doe +GENDER;VALUE="text":M;Fellow;Fellow;Fellow;Fellow +GEO;VALUE="uri":geo:37.386013\,-122.082932 +IMPP;PREF="1";VALUE="uri":xmpp:alice@example.com +KEY;VALUE="uri":http://www.example.com/keys/jdoe.cer +KIND;VALUE="text":individual +LANG;PREF="1";VALUE="language-tag":fr +LOGO;VALUE="uri":http://www.example.com/pub/logos/abccorp.jpg +MEMBER;VALUE="uri":urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af +N;VALUE="text":Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P. +NICKNAME;TYPE="WORK";VALUE="text":Boss +NOTE;VALUE="text":This fax number is operational 0800 to 1715 EST\, Mon-Fri +ORG;VALUE="text":ABC\, Inc.;North American Division;Marketing +PHOTO;VALUE="uri":http://www.example.com/pub/photos/jqpublic.gif +RELATED;TYPE="FRIEND";VALUE="text":urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91 + e6bf6 +REV;VALUE="timestamp":19951031T222710Z +ROLE;VALUE="text":Project Leader +SOUND;VALUE="uri":CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com +SOURCE;VALUE="uri":ldap://ldap.example.com/cn=Babs%20Jensen\,%20o=Babsco\,% + 20c=US +TEL;TYPE="HOME";VALUE="uri":tel:+33-01-23-45-67 +TITLE;VALUE="text":Research Scientist +TZ;VALUE="text":-0500 +XML;VALUE="text": +END:VCARD diff --git a/spec/examples/vcard/vcard4author.norm.vcf b/spec/examples/vcard/vcard4author.norm.vcf new file mode 100644 index 0000000..32d3eec --- /dev/null +++ b/spec/examples/vcard/vcard4author.norm.vcf @@ -0,0 +1,22 @@ +BEGIN:VCARD +VERSION;VALUE="text":4.0 +ADR;TYPE="WORK";VALUE="text":;Suite D2-630;2875 Laurier;Quebec;QC;G1V 2M2;C + anada +ANNIVERSARY;VALUE="date-and-or-time":20090808T1430-0500 +BDAY;VALUE="date-and-or-time":--0203 +EMAIL;TYPE="WORK";VALUE="text":simon.perreault@viagenie.ca +FN;VALUE="text":Simon Perreault +GENDER;VALUE="text":M +GEO;TYPE="WORK";VALUE="uri":geo:46.772673\,-71.282945 +KEY;TYPE="WORK";VALUE="uri":http://www.viagenie.ca/simon.perreault/simon.as + c +LANG;PREF="1";VALUE="language-tag":fr +LANG;PREF="2";VALUE="language-tag":en +N;VALUE="text":Perreault;Simon;;;ing. jr,M.Sc. +ORG;TYPE="WORK";VALUE="text":Viagenie +TEL;PREF="1";TYPE="VOICE","WORK";VALUE="uri":tel:+1-418-656-9254;ext=102 +TEL;TYPE="CELL","TEXT","VIDEO","VOICE","WORK";VALUE="uri":tel:+1-418-262-65 + 01 +TZ;VALUE="text":-0500 +URL;TYPE="HOME";VALUE="uri":http://nomis80.org +END:VCARD diff --git a/spec/vobject_spec.rb b/spec/vobject_spec.rb index dcc2069..d3a7b56 100644 --- a/spec/vobject_spec.rb +++ b/spec/vobject_spec.rb @@ -938,6 +938,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics, "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics)) end + it "should normalise VCF" do + ics = File.read "spec/examples/vcard/example1.vcf" + vobj_json = Vcard.parse(ics, "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/example1.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should parse VCF properly" do ics = File.read "spec/examples/vcard/example2.vcf" @@ -950,6 +956,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics, "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics)) end + it "should normalise VCF" do + ics = File.read "spec/examples/vcard/example2.vcf" + vobj_json = Vcard.parse(ics, "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/example2.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should parse VCF with binary photo properly" do ics = File.read "spec/examples/vcard/example3.vcf" @@ -1018,6 +1030,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF that does not reject X-parameters on IMPP in v4" do + ics = File.read "spec/examples/vcard/apple5.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/apple5.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF from Apple" do ics = File.read "spec/examples/vcard/ujb.vcf" @@ -1052,6 +1070,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF that does not reject TYPE parameter on X-property in v4" do + ics = File.read "spec/examples/vcard/ujb3.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/ujb3.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should reject VCF with FN but no N in v3" do ics = File.read "spec/examples/vcard/example51.vcf" @@ -1098,6 +1122,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4" do + ics = File.read "spec/examples/vcard/vcard4.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/vcard4.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF v4" do ics = File.read "spec/examples/vcard/vcard4author.vcf" @@ -1110,6 +1140,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4" do + ics = File.read "spec/examples/vcard/vcard4author.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/vcard4author.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF v3" do ics = File.read "spec/examples/vcard/vcard3.vcf" @@ -1146,6 +1182,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4" do + ics = File.read "spec/examples/vcard/bubba4.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/bubba4.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should reject VCF4 with LABEL property" do ics = File.read "spec/examples/vcard/example61.vcf" @@ -1244,6 +1286,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4" do + ics = File.read "spec/examples/vcard/fullcontact.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/fullcontact.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process GMAIL VCF v3" do ics = File.read "spec/examples/vcard/gmail-single.vcf" @@ -1309,6 +1357,12 @@ def norm_vcard(ics) exp_json = JSON.parse(File.read("spec/examples/vcard/trafalgar.json")) expect(vobj_json).to include_json(exp_json) end + it "should normalise VCF v4" do + ics = File.read "spec/examples/vcard/trafalgar.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/trafalgar.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF v4 additions from RFC 6474" do ics = File.read "spec/examples/vcard/rfc6474.1.vcf" @@ -1321,6 +1375,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4 additions from RFC 6474" do + ics = File.read "spec/examples/vcard/rfc6474.1.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/rfc6474.1.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF v4 additions from RFC 6474" do ics = File.read "spec/examples/vcard/rfc6474.2.vcf" @@ -1333,6 +1393,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4 additions from RFC 6474" do + ics = File.read "spec/examples/vcard/rfc6474.2.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/rfc6474.2.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF v4 additions from RFC 6474" do ics = File.read "spec/examples/vcard/rfc6474.3.vcf" @@ -1345,6 +1411,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4 additions from RFC 6474" do + ics = File.read "spec/examples/vcard/rfc6474.3.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/rfc6474.3.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF v4 additions from RFC 6715" do ics = File.read "spec/examples/vcard/rfc6715.1.vcf" @@ -1357,6 +1429,12 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4 additions from RFC 6715" do + ics = File.read "spec/examples/vcard/rfc6715.1.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/rfc6715.1.norm.vcf" + expect(vobj_json).to eql(ics2) + end it "should process VCF v4 additions from RFC 6473" do ics = File.read "spec/examples/vcard/rfc6473.vcf" @@ -1369,5 +1447,11 @@ def norm_vcard(ics) roundtrip = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_s expect(norm_vcard(roundtrip)).to eql(norm_vcard(ics.gsub(/\r\n?/, "\n"))) end + it "should normalise VCF v4 additions from RFC 6715" do + ics = File.read "spec/examples/vcard/rfc6473.vcf" + vobj_json = Vcard.parse(ics.gsub(/\r\n?/, "\n"), "4.0", true).to_norm + ics2 = File.read "spec/examples/vcard/rfc6473.norm.vcf" + expect(vobj_json).to eql(ics2) + end end # rubocop:enable LineLength