"""Long or boring tests for vobjects.""" import vobject from vobject import base, icalendar, behavior, vcard, hcalendar import StringIO, re, dateutil.tz, datetime import doctest, test_vobject, unittest from pkg_resources import resource_stream base.logger.setLevel(base.logging.FATAL) #------------------- Testing and running functions ----------------------------- # named additional_tests for setuptools def additional_tests(): flags = doctest.NORMALIZE_WHITESPACE | doctest.REPORT_ONLY_FIRST_FAILURE | doctest.ELLIPSIS suite = unittest.TestSuite() for module in base, test_vobject, icalendar, vobject, vcard: suite.addTest(doctest.DocTestSuite(module, optionflags=flags)) suite.addTest(doctest.DocFileSuite( 'README.txt', 'test_files/more_tests.txt', package='__main__', optionflags=flags )) return suite if __name__ == '__main__': runner = unittest.TextTestRunner() runner.run(additional_tests()) testSilly=""" sillyname:name profile:sillyprofile stuff:folded line """ + "morestuff;asinine:this line is not folded, \ but in practice probably ought to be, as it is exceptionally long, \ and moreover demonstratively stupid" icaltest=r"""BEGIN:VCALENDAR CALSCALE:GREGORIAN X-WR-TIMEZONE;VALUE=TEXT:US/Pacific METHOD:PUBLISH PRODID:-//Apple Computer\, Inc//iCal 1.0//EN X-WR-CALNAME;VALUE=TEXT:Example VERSION:2.0 BEGIN:VEVENT SEQUENCE:5 DTSTART;TZID=US/Pacific:20021028T140000 RRULE:FREQ=Weekly;COUNT=10 DTSTAMP:20021028T011706Z SUMMARY:Coffee with Jason UID:EC9439B1-FF65-11D6-9973-003065F99D04 DTEND;TZID=US/Pacific:20021028T150000 BEGIN:VALARM TRIGGER;VALUE=DURATION:-P1D ACTION:DISPLAY DESCRIPTION:Event reminder\, with comma\nand line feed END:VALARM END:VEVENT BEGIN:VTIMEZONE X-LIC-LOCATION:Random location TZID:US/Pacific LAST-MODIFIED:19870101T000000Z BEGIN:STANDARD DTSTART:19671029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZOFFSETFROM:-0700 TZOFFSETTO:-0800 TZNAME:PST END:STANDARD BEGIN:DAYLIGHT DTSTART:19870405T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 TZOFFSETFROM:-0800 TZOFFSETTO:-0700 TZNAME:PDT END:DAYLIGHT END:VTIMEZONE END:VCALENDAR""" badDtStartTest="""BEGIN:VCALENDAR METHOD:PUBLISH VERSION:2.0 BEGIN:VEVENT DTSTART:20021028 DTSTAMP:20021028T011706Z SUMMARY:Coffee with Jason UID:EC9439B1-FF65-11D6-9973-003065F99D04 END:VEVENT END:VCALENDAR""" badLineTest="""BEGIN:VCALENDAR METHOD:PUBLISH VERSION:2.0 BEGIN:VEVENT DTSTART:19870405T020000 X-BAD/SLASH:TRUE X-BAD_UNDERSCORE:TRUE UID:EC9439B1-FF65-11D6-9973-003065F99D04 END:VEVENT END:VCALENDAR""" vcardtest =r"""BEGIN:VCARD VERSION:3.0 FN:Daffy Duck Knudson (with Bugs Bunny and Mr. Pluto) N:Knudson;Daffy Duck (with Bugs Bunny and Mr. Pluto) NICKNAME:gnat and gnu and pluto BDAY;value=date:02-10 TEL;type=HOME:+01-(0)2-765.43.21 TEL;type=CELL:+01-(0)5-555.55.55 ACCOUNT;type=HOME:010-1234567-05 ADR;type=HOME:;;Haight Street 512\;\nEscape\, Test;Novosibirsk;;80214;Gnuland TEL;type=HOME:+01-(0)2-876.54.32 ORG:University of Novosibirsk\, Department of Octopus Parthenogenesis END:VCARD""" vcardWithGroups = r"""home.begin:vcard version:3.0 source:ldap://cn=Meister%20Berger,o=Universitaet%20Goerlitz,c=DE name:Meister Berger fn:Meister Berger n:Berger;Meister bday;value=date:1963-09-21 o:Universit=E6t G=F6rlitz title:Mayor title;language=de;value=text:Burgermeister note:The Mayor of the great city of Goerlitz in the great country of Germany.\nNext line. email;internet:mb@goerlitz.de home.tel;type=fax,voice;type=msg:+49 3581 123456 home.label:Hufenshlagel 1234\n 02828 Goerlitz\n Deutschland END:VCARD""" lowercaseComponentNames = r"""begin:vcard fn:Anders Bobo n:Bobo;Anders org:Bobo A/S;Vice President, Technical Support adr:Rockfeller Center;;Mekastreet;Bobocity;;2100;Myworld email;internet:bobo@example.com tel;work:+123455 tel;fax:+123456 tel;cell:+123457 x-mozilla-html:FALSE url:http://www.example.com version:2.1 end:vcard""" icalWeirdTrigger = r"""BEGIN:VCALENDAR CALSCALE:GREGORIAN X-WR-TIMEZONE;VALUE=TEXT:US/Pacific METHOD:PUBLISH PRODID:-//Apple Computer\, Inc//iCal 1.0//EN X-WR-CALNAME;VALUE=TEXT:Example VERSION:2.0 BEGIN:VEVENT DTSTART:20021028T140000Z BEGIN:VALARM TRIGGER:20021028T120000Z ACTION:DISPLAY DESCRIPTION:This trigger is a date-time without a VALUE=DATE-TIME parameter END:VALARM END:VEVENT END:VCALENDAR""" badstream = r"""BEGIN:VCALENDAR CALSCALE:GREGORIAN X-WR-TIMEZONE;VALUE=TEXT:US/Pacific METHOD:PUBLISH PRODID:-//Apple Computer\, Inc//iCal 1.0//EN X-WR-CALNAME;VALUE=TEXT:Example VERSION:2.0 BEGIN:VEVENT DTSTART:20021028T140000Z BEGIN:VALARM TRIGGER:a20021028120000 ACTION:DISPLAY DESCRIPTION:This trigger has a nonsensical value END:VALARM END:VEVENT END:VCALENDAR""" timezones = r""" BEGIN:VTIMEZONE TZID:US/Pacific BEGIN:STANDARD DTSTART:19671029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZOFFSETFROM:-0700 TZOFFSETTO:-0800 TZNAME:PST END:STANDARD BEGIN:DAYLIGHT DTSTART:19870405T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 TZOFFSETFROM:-0800 TZOFFSETTO:-0700 TZNAME:PDT END:DAYLIGHT END:VTIMEZONE BEGIN:VTIMEZONE TZID:US/Eastern BEGIN:STANDARD DTSTART:19671029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZOFFSETFROM:-0400 TZOFFSETTO:-0500 TZNAME:EST END:STANDARD BEGIN:DAYLIGHT DTSTART:19870405T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 TZOFFSETFROM:-0500 TZOFFSETTO:-0400 TZNAME:EDT END:DAYLIGHT END:VTIMEZONE BEGIN:VTIMEZONE TZID:Santiago BEGIN:STANDARD DTSTART:19700314T000000 TZOFFSETFROM:-0300 TZOFFSETTO:-0400 RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SA TZNAME:Pacific SA Standard Time END:STANDARD BEGIN:DAYLIGHT DTSTART:19701010T000000 TZOFFSETFROM:-0400 TZOFFSETTO:-0300 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=2SA TZNAME:Pacific SA Daylight Time END:DAYLIGHT END:VTIMEZONE BEGIN:VTIMEZONE TZID:W. Europe BEGIN:STANDARD DTSTART:19701025T030000 TZOFFSETFROM:+0200 TZOFFSETTO:+0100 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU TZNAME:W. Europe Standard Time END:STANDARD BEGIN:DAYLIGHT DTSTART:19700329T020000 TZOFFSETFROM:+0100 TZOFFSETTO:+0200 RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU TZNAME:W. Europe Daylight Time END:DAYLIGHT END:VTIMEZONE BEGIN:VTIMEZONE TZID:US/Fictitious-Eastern LAST-MODIFIED:19870101T000000Z BEGIN:STANDARD DTSTART:19671029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZOFFSETFROM:-0400 TZOFFSETTO:-0500 TZNAME:EST END:STANDARD BEGIN:DAYLIGHT DTSTART:19870405T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T070000Z TZOFFSETFROM:-0500 TZOFFSETTO:-0400 TZNAME:EDT END:DAYLIGHT END:VTIMEZONE BEGIN:VTIMEZONE TZID:America/Montreal LAST-MODIFIED:20051013T233643Z BEGIN:DAYLIGHT DTSTART:20050403T070000 TZOFFSETTO:-0400 TZOFFSETFROM:+0000 TZNAME:EDT END:DAYLIGHT BEGIN:STANDARD DTSTART:20051030T020000 TZOFFSETTO:-0500 TZOFFSETFROM:-0400 TZNAME:EST END:STANDARD END:VTIMEZONE """ __test__ = { "Test readOne" : r""" >>> silly = base.readOne(testSilly, findBegin=False) >>> silly , , ]> >>> silly.stuff >>> original = silly.serialize() >>> f3 = StringIO.StringIO(original.decode("utf-8")) >>> silly2 = base.readOne(f3) >>> silly2.serialize()==original True >>> s3 = StringIO.StringIO('cn:Babs Jensen\r\ncn:Barbara J Jensen\r\nsn:Jensen\r\nemail:babs@umich.edu\r\nphone:+1 313 747-4454\r\nx-id:1234567890\r\n') >>> ex1 = base.readOne(s3, findBegin=False) >>> ex1 <*unnamed*| [, , , , , ]> >>> ex1.serialize() 'CN:Babs Jensen\r\nCN:Barbara J Jensen\r\nEMAIL:babs@umich.edu\r\nPHONE:+1 313 747-4454\r\nSN:Jensen\r\nX-ID:1234567890\r\n' """, "Import icaltest" : r""" >>> c = base.readOne(icaltest, validate=True) >>> c.vevent.valarm.trigger >>> c.vevent.dtstart.value datetime.datetime(2002, 10, 28, 14, 0, tzinfo=) >>> c.vevent.dtend.value datetime.datetime(2002, 10, 28, 15, 0, tzinfo=) >>> c.vevent.dtstamp.value datetime.datetime(2002, 10, 28, 1, 17, 6, tzinfo=tzutc()) >>> c.vevent.valarm.description.value u'Event reminder, with comma\nand line feed' >>> c.vevent.valarm.description.serialize() 'DESCRIPTION:Event reminder\\, with comma\\nand line feed\r\n' >>> vevent = c.vevent.transformFromNative() >>> vevent.rrule """, "Parsing tests" : """ >>> parseRDate = icalendar.MultiDateBehavior.transformToNative >>> icalendar.stringToTextValues('') [''] >>> icalendar.stringToTextValues('abcd,efgh') ['abcd', 'efgh'] >>> icalendar.stringToPeriod("19970101T180000Z/19970102T070000Z") (datetime.datetime(1997, 1, 1, 18, 0, tzinfo=tzutc()), datetime.datetime(1997, 1, 2, 7, 0, tzinfo=tzutc())) >>> icalendar.stringToPeriod("19970101T180000Z/PT1H") (datetime.datetime(1997, 1, 1, 18, 0, tzinfo=tzutc()), datetime.timedelta(0, 3600)) >>> parseRDate(base.textLineToContentLine("RDATE;VALUE=DATE:19970304,19970504,19970704,19970904")) >>> parseRDate(base.textLineToContentLine("RDATE;VALUE=PERIOD:19960403T020000Z/19960403T040000Z,19960404T010000Z/PT3H")) """, "read failure" : """ >>> vevent = base.readOne(badstream) Traceback (most recent call last): ... ParseError: At line 11: TRIGGER with no VALUE not recognized as DURATION or as DATE-TIME >>> cal = base.readOne(badLineTest) Traceback (most recent call last): ... ParseError: At line 6: Failed to parse line: X-BAD/SLASH:TRUE >>> cal = base.readOne(badLineTest, ignoreUnreadable=True) >>> cal.vevent.x_bad_slash Traceback (most recent call last): ... AttributeError: x_bad_slash >>> cal.vevent.x_bad_underscore """, "ical trigger workaround" : """ >>> badical = base.readOne(icalWeirdTrigger) >>> badical.vevent.valarm.description.value u'This trigger is a date-time without a VALUE=DATE-TIME parameter' >>> badical.vevent.valarm.trigger.value datetime.datetime(2002, 10, 28, 12, 0, tzinfo=tzutc()) """, "unicode test" : r""" >>> f = resource_stream(__name__, 'test_files/utf8_test.ics') >>> vevent = base.readOne(f).vevent >>> vevent.summary.value u'The title \u3053\u3093\u306b\u3061\u306f\u30ad\u30c6\u30a3' >>> summary = vevent.summary.value >>> test = str(vevent.serialize()), """, # make sure date valued UNTILs in rrules are in a reasonable timezone, # and include that day (12/28 in this test) "recurrence test" : r""" >>> f = resource_stream(__name__, 'test_files/recurrence.ics') >>> cal = base.readOne(f) >>> dates = list(cal.vevent.rruleset) >>> dates[0] datetime.datetime(2006, 1, 26, 23, 0, tzinfo=tzutc()) >>> dates[1] datetime.datetime(2006, 2, 23, 23, 0, tzinfo=tzutc()) >>> dates[-1] datetime.datetime(2006, 12, 28, 23, 0, tzinfo=tzutc()) """, "regular expression test" : """ >>> re.findall(base.patterns['name'], '12foo-bar:yay') ['12foo-bar', 'yay'] >>> re.findall(base.patterns['safe_char'], 'a;b"*,cd') ['a', 'b', '*', 'c', 'd'] >>> re.findall(base.patterns['qsafe_char'], 'a;b"*,cd') ['a', ';', 'b', '*', ',', 'c', 'd'] >>> re.findall(base.patterns['param_value'], '"quoted";not-quoted;start"after-illegal-quote', re.VERBOSE) ['"quoted"', '', 'not-quoted', '', 'start', '', 'after-illegal-quote', ''] >>> match = base.line_re.match('TEST;ALTREP="http://www.wiz.org":value:;"') >>> match.group('value') 'value:;"' >>> match.group('name') 'TEST' >>> match.group('params') ';ALTREP="http://www.wiz.org"' """, "VTIMEZONE creation test:" : """ >>> f = StringIO.StringIO(timezones) >>> tzs = dateutil.tz.tzical(f) >>> tzs.get("US/Pacific") >>> icalendar.TimezoneComponent(_) > >>> pacific = _ >>> print pacific.serialize() BEGIN:VTIMEZONE TZID:US/Pacific BEGIN:STANDARD DTSTART:20001029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZNAME:PST TZOFFSETFROM:-0700 TZOFFSETTO:-0800 END:STANDARD BEGIN:DAYLIGHT DTSTART:20000402T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 TZNAME:PDT TZOFFSETFROM:-0800 TZOFFSETTO:-0700 END:DAYLIGHT END:VTIMEZONE >>> (_) > >>> santiago = icalendar.TimezoneComponent(tzs.get('Santiago')) >>> ser = santiago.serialize() >>> print ser BEGIN:VTIMEZONE TZID:Santiago BEGIN:STANDARD DTSTART:20000311T000000 RRULE:FREQ=YEARLY;BYDAY=2SA;BYMONTH=3 TZNAME:Pacific SA Standard Time TZOFFSETFROM:-0300 TZOFFSETTO:-0400 END:STANDARD BEGIN:DAYLIGHT DTSTART:20001014T000000 RRULE:FREQ=YEARLY;BYDAY=2SA;BYMONTH=10 TZNAME:Pacific SA Daylight Time TZOFFSETFROM:-0400 TZOFFSETTO:-0300 END:DAYLIGHT END:VTIMEZONE >>> roundtrip = dateutil.tz.tzical(StringIO.StringIO(str(ser))).get() >>> for year in range(2001, 2010): ... for month in (2, 9): ... dt = datetime.datetime(year, month, 15, tzinfo = roundtrip) ... if dt.replace(tzinfo=tzs.get('Santiago')) != dt: ... print "Failed for:", dt >>> fict = icalendar.TimezoneComponent(tzs.get('US/Fictitious-Eastern')) >>> print fict.serialize() BEGIN:VTIMEZONE TZID:US/Fictitious-Eastern BEGIN:STANDARD DTSTART:20001029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZNAME:EST TZOFFSETFROM:-0400 TZOFFSETTO:-0500 END:STANDARD BEGIN:DAYLIGHT DTSTART:20000402T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T070000Z TZNAME:EDT TZOFFSETFROM:-0500 TZOFFSETTO:-0400 END:DAYLIGHT END:VTIMEZONE """, "Create iCalendar from scratch" : """ >>> cal = base.newFromBehavior('vcalendar', '2.0') >>> cal.add('vevent') >>> cal.vevent.add('dtstart').value = datetime.datetime(2006, 5, 9) >>> cal.vevent.add('description').value = "Test event" >>> pacific = dateutil.tz.tzical(StringIO.StringIO(timezones)).get('US/Pacific') >>> cal.vevent.add('created').value = datetime.datetime(2006, 1, 1, 10, tzinfo=pacific) >>> cal.vevent.add('uid').value = "Not very random UID" >>> print cal.serialize() BEGIN:VCALENDAR VERSION:2.0 PRODID:-//PYVOBJECT//NONSGML Version 1//EN BEGIN:VEVENT UID:Not very random UID DTSTART:20060509T000000 CREATED:20060101T180000Z DESCRIPTION:Test event END:VEVENT END:VCALENDAR """, "Serializing with timezones test" : """ >>> from dateutil.rrule import rrule, rruleset, WEEKLY, MONTHLY >>> pacific = dateutil.tz.tzical(StringIO.StringIO(timezones)).get('US/Pacific') >>> cal = base.Component('VCALENDAR') >>> cal.setBehavior(icalendar.VCalendar2_0) >>> ev = cal.add('vevent') >>> ev.add('dtstart').value = datetime.datetime(2005, 10, 12, 9, tzinfo = pacific) >>> set = rruleset() >>> set.rrule(rrule(WEEKLY, interval=2, byweekday=[2,4], until=datetime.datetime(2005, 12, 15, 9))) >>> set.rrule(rrule(MONTHLY, bymonthday=[-1,-5])) >>> set.exdate(datetime.datetime(2005, 10, 14, 9, tzinfo = pacific)) >>> ev.rruleset = set >>> ev.add('duration').value = datetime.timedelta(hours=1) >>> print cal.serialize() BEGIN:VCALENDAR VERSION:2.0 PRODID:-//PYVOBJECT//NONSGML Version 1//EN BEGIN:VTIMEZONE TZID:US/Pacific BEGIN:STANDARD DTSTART:20001029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZNAME:PST TZOFFSETFROM:-0700 TZOFFSETTO:-0800 END:STANDARD BEGIN:DAYLIGHT DTSTART:20000402T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 TZNAME:PDT TZOFFSETFROM:-0800 TZOFFSETTO:-0700 END:DAYLIGHT END:VTIMEZONE BEGIN:VEVENT UID:... DTSTART;TZID=US/Pacific:20051012T090000 DURATION:PT1H EXDATE;TZID=US/Pacific:20051014T090000 RRULE:FREQ=WEEKLY;BYDAY=WE,FR;INTERVAL=2;UNTIL=20051215T090000 RRULE:FREQ=MONTHLY;BYMONTHDAY=-1,-5 END:VEVENT END:VCALENDAR >>> apple = dateutil.tz.tzical(StringIO.StringIO(timezones)).get('America/Montreal') >>> ev.dtstart.value = datetime.datetime(2005, 10, 12, 9, tzinfo = apple) >>> print cal.serialize() BEGIN:VCALENDAR VERSION:2.0 PRODID:-//PYVOBJECT//NONSGML Version 1//EN BEGIN:VTIMEZONE TZID:US/Pacific BEGIN:STANDARD DTSTART:20001029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZNAME:PST TZOFFSETFROM:-0700 TZOFFSETTO:-0800 END:STANDARD BEGIN:DAYLIGHT DTSTART:20000402T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 TZNAME:PDT TZOFFSETFROM:-0800 TZOFFSETTO:-0700 END:DAYLIGHT END:VTIMEZONE BEGIN:VTIMEZONE TZID:America/Montreal BEGIN:STANDARD DTSTART:20000101T000000 RRULE:FREQ=YEARLY;BYMONTH=1;UNTIL=20040101T050000Z TZNAME:EST TZOFFSETFROM:-0500 TZOFFSETTO:-0500 END:STANDARD BEGIN:STANDARD DTSTART:20051030T020000 RRULE:FREQ=YEARLY;BYDAY=5SU;BYMONTH=10 TZNAME:EST TZOFFSETFROM:-0400 TZOFFSETTO:-0500 END:STANDARD BEGIN:DAYLIGHT DTSTART:20050403T070000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T120000Z TZNAME:EDT TZOFFSETFROM:-0500 TZOFFSETTO:-0400 END:DAYLIGHT END:VTIMEZONE BEGIN:VEVENT UID:... DTSTART;TZID=America/Montreal:20051012T090000 DURATION:PT1H EXDATE;TZID=US/Pacific:20051014T090000 RRULE:FREQ=WEEKLY;BYDAY=WE,FR;INTERVAL=2;UNTIL=20051215T090000 RRULE:FREQ=MONTHLY;BYMONTHDAY=-1,-5 END:VEVENT END:VCALENDAR """, "Handling DATE without a VALUE=DATE" : """ >>> cal = base.readOne(badDtStartTest) >>> cal.vevent.dtstart.value datetime.date(2002, 10, 28) """, "Serializing iCalendar to hCalendar" : """ >>> cal = base.newFromBehavior('hcalendar') >>> cal.behavior >>> pacific = dateutil.tz.tzical(StringIO.StringIO(timezones)).get('US/Pacific') >>> cal.add('vevent') >>> cal.vevent.add('summary').value = "this is a note" >>> cal.vevent.add('url').value = "http://microformats.org/code/hcalendar/creator" >>> cal.vevent.add('dtstart').value = datetime.date(2006,2,27) >>> cal.vevent.add('location').value = "a place" >>> cal.vevent.add('dtend').value = datetime.date(2006,2,27) + datetime.timedelta(days = 2) >>> event2 = cal.add('vevent') >>> event2.add('summary').value = "Another one" >>> event2.add('description').value = "The greatest thing ever!" >>> event2.add('dtstart').value = datetime.datetime(1998, 12, 17, 16, 42, tzinfo = pacific) >>> event2.add('location').value = "somewhere else" >>> event2.add('dtend').value = event2.dtstart.value + datetime.timedelta(days = 6) >>> hcal = cal.serialize() >>> print hcal this is a note: Monday, February 27 - Tuesday, February 28 at a place Another one: Thursday, December 17, 16:42 - Wednesday, December 23, 16:42 at somewhere else
The greatest thing ever!
""", "Generate UIDs automatically test:" : """ >>> cal = base.newFromBehavior('vcalendar') >>> cal.add('vevent').add('dtstart').value = datetime.datetime(2006,2,2,10) >>> ser = cal.serialize() >>> len(cal.vevent.uid_list) 1 """, "VCARD 3.0 parse test:" : r""" >>> card = base.readOne(vcardtest) >>> card.adr.value >>> print card.adr.value Haight Street 512; Escape, Test Novosibirsk, 80214 Gnuland >>> card.org.value [u'University of Novosibirsk, Department of Octopus Parthenogenesis'] >>> print card.serialize() BEGIN:VCARD VERSION:3.0 ACCOUNT;TYPE=HOME:010-1234567-05 ADR;TYPE=HOME:;;Haight Street 512\;\nEscape\, Test;Novosibirsk;;80214;Gnul and BDAY;VALUE=date:02-10 FN:Daffy Duck Knudson (with Bugs Bunny and Mr. Pluto) N:Knudson;Daffy Duck (with Bugs Bunny and Mr. Pluto);;; NICKNAME:gnat and gnu and pluto ORG:University of Novosibirsk\, Department of Octopus Parthenogenesis TEL;TYPE=HOME:+01-(0)2-765.43.21 TEL;TYPE=CELL:+01-(0)5-555.55.55 TEL;TYPE=HOME:+01-(0)2-876.54.32 END:VCARD """, "Multi-text serialization test:" : """ >>> category = base.newFromBehavior('categories') >>> category.value = ['Random category'] >>> print category.serialize().strip() CATEGORIES:Random category >>> category.value.append('Other category') >>> print category.serialize().strip() CATEGORIES:Random category,Other category """, "Semi-colon separated multi-text serialization test:" : """ >>> requestStatus = base.newFromBehavior('request-status') >>> requestStatus.value = ['5.1', 'Service unavailable'] >>> print requestStatus.serialize().strip() REQUEST-STATUS:5.1;Service unavailable """, "vCard groups test:" : """ >>> card = base.readOne(vcardWithGroups) >>> card.group u'home' >>> card.tel.group u'home' >>> card.group = card.tel.group = 'new' >>> card.tel.serialize().strip() 'new.TEL;TYPE=fax,voice,msg:+49 3581 123456' >>> card.serialize().splitlines()[0] 'new.BEGIN:VCARD' >>> dtstart = base.newFromBehavior('dtstart') >>> dtstart.group = "badgroup" >>> dtstart.serialize() Traceback (most recent call last): ... VObjectError: " has a group, but this object doesn't support groups" """, "Lowercase components test:" : """ >>> card = base.readOne(lowercaseComponentNames) >>> card.version """, "Default behavior test" : """ >>> card = base.readOne(vcardWithGroups) >>> base.getBehavior('note') == None True >>> card.note.behavior >>> print card.note.value The Mayor of the great city of Goerlitz in the great country of Germany. Next line. """ }