diff --git a/test/components_test.dart b/test/components_test.dart index fe74458..ab8af18 100644 --- a/test/components_test.dart +++ b/test/components_test.dart @@ -2,10 +2,13 @@ import 'package:enough_icalendar/enough_icalendar.dart'; import 'package:test/test.dart'; void main() { - group('Fold Tests', () { - test('No folding', () { - const input = - '''BEGIN:VCALENDAR + group( + 'Fold Tests', + () { + test( + 'No folding', + () { + const input = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN BEGIN:VEVENT @@ -16,30 +19,34 @@ DTEND:19970715T040000Z SUMMARY:Bastille Day Party END:VEVENT END:VCALENDAR'''; - final output = VComponent.unfold(input); - expect(output, isNotEmpty); - final inputLines = input.split('\n'); - expect(output.length, inputLines.length); - for (var i = 0; i < output.length; i++) { - expect(output[i], inputLines[i]); - } - }); + final output = VComponent.unfold(input); + expect(output, isNotEmpty); + final inputLines = input.split('\n'); + expect(output.length, inputLines.length); + for (var i = 0; i < output.length; i++) { + expect(output[i], inputLines[i]); + } + }, + ); - test('Unfold line spread across 3 lines', () { - const input = - '''DESCRIPTION:This is a lo + test( + 'Unfold line spread across 3 lines', + () { + const input = '''DESCRIPTION:This is a lo ng description that exists on a long line.'''; - final output = VComponent.unfold(input); - expect(output, isNotEmpty); - expect(output.length, 1); - expect(output[0], - 'DESCRIPTION:This is a long description that exists on a long line.'); - }); + final output = VComponent.unfold(input); + expect(output, isNotEmpty); + expect(output.length, 1); + expect(output[0], + 'DESCRIPTION:This is a long description that exists on a long line.'); + }, + ); - test('Last line folded', () { - const input = - '''BEGIN:VCALENDAR + test( + 'Last line folded', + () { + const input = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN BEGIN:VEVENT @@ -51,19 +58,21 @@ SUMMARY:Bastille Day Party END:VEVENT END:VCA LENDAR'''; - final output = VComponent.unfold(input); - expect(output, isNotEmpty); - final inputLines = input.split('\n'); - expect(output.length, inputLines.length - 1); - for (var i = 0; i < output.length - 1; i++) { - expect(output[i], inputLines[i]); - } - expect(output.last, 'END:VCALENDAR'); - }); + final output = VComponent.unfold(input); + expect(output, isNotEmpty); + final inputLines = input.split('\n'); + expect(output.length, inputLines.length - 1); + for (var i = 0; i < output.length - 1; i++) { + expect(output[i], inputLines[i]); + } + expect(output.last, 'END:VCALENDAR'); + }, + ); - test('First line folded', () { - const input = - '''BEGI + test( + 'First line folded', + () { + const input = '''BEGI N:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN @@ -75,19 +84,21 @@ DTEND:19970715T040000Z SUMMARY:Bastille Day Party END:VEVENT END:VCALENDAR'''; - final output = VComponent.unfold(input); - expect(output, isNotEmpty); - final inputLines = input.split('\n'); - expect(output.length, inputLines.length - 1); - for (var i = 1; i < output.length; i++) { - expect(output[i], inputLines[i + 1]); - } - expect(output.first, 'BEGIN:VCALENDAR'); - }); + final output = VComponent.unfold(input); + expect(output, isNotEmpty); + final inputLines = input.split('\n'); + expect(output.length, inputLines.length - 1); + for (var i = 1; i < output.length; i++) { + expect(output[i], inputLines[i + 1]); + } + expect(output.first, 'BEGIN:VCALENDAR'); + }, + ); - test('Some lines folded', () { - const input = - '''BEGI + test( + 'Some lines folded', + () { + const input = '''BEGI N:VCALENDAR VERSION:2.0 PRODID:- @@ -105,9 +116,8 @@ SUMMARY:Bastille END:VEVE NT END:VCALENDAR'''; - final output = VComponent.unfold(input); - final expected = - '''BEGIN:VCALENDAR + final output = VComponent.unfold(input); + final expected = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN BEGIN:VEVENT @@ -119,16 +129,18 @@ SUMMARY:Bastille Day Party END:VEVENT END:VCALENDAR''' .split('\n'); - expect(output, isNotEmpty); - expect(output.length, expected.length); - for (var i = 0; i < output.length; i++) { - expect(output[i], expected[i]); - } - }); + expect(output, isNotEmpty); + expect(output.length, expected.length); + for (var i = 0; i < output.length; i++) { + expect(output[i], expected[i]); + } + }, + ); - test('Some lines folded 2', () { - const input = - '''BEGIN:VCALENDAR + test( + 'Some lines folded 2', + () { + const input = '''BEGIN:VCALENDAR PRODID:-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN VERSION:2.0 BEGIN:VEVENT @@ -146,9 +158,8 @@ DESCRIPTION:Networld+Interop Conference END:VEVENT END:VCALENDAR '''; - final output = VComponent.unfold(input); - final expected = - '''BEGIN:VCALENDAR + final output = VComponent.unfold(input); + final expected = '''BEGIN:VCALENDAR PRODID:-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN VERSION:2.0 BEGIN:VEVENT @@ -165,16 +176,18 @@ END:VEVENT END:VCALENDAR ''' .split('\n'); - expect(output, isNotEmpty); - //expect(output.length, expected.length); - for (var i = 0; i < output.length; i++) { - expect(output[i], expected[i]); - } - }); + expect(output, isNotEmpty); + //expect(output.length, expected.length); + for (var i = 0; i < output.length; i++) { + expect(output[i], expected[i]); + } + }, + ); - test('Some lines folded with LF linebreks in properties', () { - const input = - '''BEGIN:VCALENDAR + test( + 'Some lines folded with LF linebreks in properties', + () { + const input = '''BEGIN:VCALENDAR METHOD:xyz VERSION:2.0 PRODID:-//ABC Corporation//NONSGML My Product//EN @@ -197,9 +210,8 @@ ATTACH;FMTTYPE=application/postscript:ftp://example.com/pub/ END:VEVENT END:VCALENDAR '''; - final output = VComponent.unfold(input); - final expected = - '''BEGIN:VCALENDAR + final output = VComponent.unfold(input); + final expected = '''BEGIN:VCALENDAR METHOD:xyz VERSION:2.0 PRODID:-//ABC Corporation//NONSGML My Product//EN @@ -221,18 +233,23 @@ END:VEVENT END:VCALENDAR ''' .split('\n'); - expect(output, isNotEmpty); - //expect(output.length, expected.length); - for (var i = 0; i < output.length; i++) { - expect(output[i], expected[i]); - } - }); - }); + expect(output, isNotEmpty); + //expect(output.length, expected.length); + for (var i = 0; i < output.length; i++) { + expect(output[i], expected[i]); + } + }, + ); + }, + ); - group('Calendar Tests', () { - test('Calendar simple - unix linebreaks', () { - const text = - '''BEGIN:VCALENDAR + group( + 'Calendar Tests', + () { + test( + 'Calendar simple - unix linebreaks', + () { + const text = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN BEGIN:VEVENT @@ -245,26 +262,57 @@ X-MICROSOFT-SKYPETEAMSMEETINGURL:https://teams.microsoft.com/l/meetup-join/2SDKJ SUMMARY:Bastille Day Party END:VEVENT END:VCALENDAR'''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - expect(calendar.version, '2.0'); - expect(calendar.productId, '-//hacksw/handcal//NONSGML v1.0//EN'); - final event = calendar.children.first; - expect(event, isA()); - expect((event as VEvent).summary, 'Bastille Day Party'); - expect(event.uid, '19970610T172345Z-AF23B2@example.com'); - expect(event.timeStamp, DateTime.utc(1997, 06, 10, 17, 23, 45)); - expect(event.start, DateTime.utc(1997, 07, 14, 17, 00, 00)); - expect(event.end, DateTime.utc(1997, 07, 15, 04, 00, 00)); - expect(event.microsoftTeamsMeetingUrl, - 'https://teams.microsoft.com/l/meetup-join/2SDKJKJKSD%40thread.v2/0?context=%7b%22Tid%22%3a%22bc74e59c-5fa3-4157-9c37-6232986d11a62%22%2c%22Oid%22%3a%22d41e3f0d-b888-4978-bd06-17f697e563aa%22%7d'); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + expect(calendar.version, '2.0'); + expect(calendar.productId, '-//hacksw/handcal//NONSGML v1.0//EN'); + final event = calendar.children.first; + expect(event, isA()); + expect((event as VEvent).summary, 'Bastille Day Party'); + expect(event.uid, '19970610T172345Z-AF23B2@example.com'); + expect(event.timeStamp, DateTime.utc(1997, 06, 10, 17, 23, 45)); + expect(event.start, DateTime.utc(1997, 07, 14, 17, 00, 00)); + expect(event.end, DateTime.utc(1997, 07, 15, 04, 00, 00)); + expect(event.microsoftTeamsMeetingUrl, + 'https://teams.microsoft.com/l/meetup-join/2SDKJKJKSD%40thread.v2/0?context=%7b%22Tid%22%3a%22bc74e59c-5fa3-4157-9c37-6232986d11a62%22%2c%22Oid%22%3a%22d41e3f0d-b888-4978-bd06-17f697e563aa%22%7d'); + }, + ); - test('Calendar with full day event', () { - const text = - '''BEGIN:VCALENDAR + test( + 'UTC time parsing test', + () { + const text = '''BEGIN:VCALENDAR +VERSION:3.0 +BEGIN:VEVENT +UID:19970610T172345Z-AF23B2@example.com +DTSTAMP:20240302T150000Z +DTSTART:20240302T150000Z +DTEND:20240302T170000Z +SUMMARY:🏁 FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2024 - Race +END:VEVENT +END:VCALENDAR'''; + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + expect(calendar.version, '3.0'); + final event = calendar.children.first; + expect(event, isA()); + expect( + (event as VEvent).summary, + '🏁 FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2024 - Race', + ); + expect(event.start, DateTime.utc(2024, 03, 02, 15, 00, 00)); + expect(event.end, DateTime.utc(2024, 03, 02, 17, 00, 00)); + }, + ); + + test( + 'Calendar with full day event', + () { + const text = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN BEGIN:VEVENT @@ -276,25 +324,27 @@ X-MICROSOFT-CDO-ALLDAYEVENT:TRUE SUMMARY:Bastille Day Party END:VEVENT END:VCALENDAR'''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - expect(calendar.version, '2.0'); - expect(calendar.productId, '-//hacksw/handcal//NONSGML v1.0//EN'); - final event = calendar.children.first; - expect(event, isA()); - expect((event as VEvent).summary, 'Bastille Day Party'); - expect(event.uid, '19970610T172345Z-AF23B2@example.com'); - expect(event.timeStamp, DateTime.utc(1997, 06, 10, 17, 23, 45)); - expect(event.start, DateTime.utc(1997, 07, 14, 00, 00, 00)); - expect(event.duration, IsoDuration(days: 1)); - expect(event.isAllDayEvent, isTrue); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + expect(calendar.version, '2.0'); + expect(calendar.productId, '-//hacksw/handcal//NONSGML v1.0//EN'); + final event = calendar.children.first; + expect(event, isA()); + expect((event as VEvent).summary, 'Bastille Day Party'); + expect(event.uid, '19970610T172345Z-AF23B2@example.com'); + expect(event.timeStamp, DateTime.utc(1997, 06, 10, 17, 23, 45)); + expect(event.start, DateTime.utc(1997, 07, 14, 00, 00, 00)); + expect(event.duration, IsoDuration(days: 1)); + expect(event.isAllDayEvent, isTrue); + }, + ); - test('Private event', () { - const text = - '''BEGIN:VEVENT + test( + 'Private event', + () { + const text = '''BEGIN:VEVENT UID:19970901T130000Z-123401@example.com DTSTAMP:19970901T130000Z DTSTART:19970903T163000Z @@ -303,20 +353,22 @@ SUMMARY:Annual Employee Review CLASS:PRIVATE CATEGORIES:BUSINESS,HUMAN RESOURCES END:VEVENT'''; - final event = VComponent.parse(text); - expect(event, isA()); - expect((event as VEvent).summary, 'Annual Employee Review'); - expect(event.uid, '19970901T130000Z-123401@example.com'); - expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00)); - expect(event.start, DateTime.utc(1997, 09, 03, 16, 30, 00)); - expect(event.end, DateTime.utc(1997, 09, 03, 19, 00, 00)); - expect(event.classification, Classification.private); - expect(event.categories, ['BUSINESS', 'HUMAN RESOURCES']); - }); + final event = VComponent.parse(text); + expect(event, isA()); + expect((event as VEvent).summary, 'Annual Employee Review'); + expect(event.uid, '19970901T130000Z-123401@example.com'); + expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00)); + expect(event.start, DateTime.utc(1997, 09, 03, 16, 30, 00)); + expect(event.end, DateTime.utc(1997, 09, 03, 19, 00, 00)); + expect(event.classification, Classification.private); + expect(event.categories, ['BUSINESS', 'HUMAN RESOURCES']); + }, + ); - test('Transparent event', () { - const text = - '''BEGIN:VEVENT + test( + 'Transparent event', + () { + const text = '''BEGIN:VEVENT UID:19970901T130000Z-123402@example.com DTSTAMP:19970901T130000Z DTSTART:19970401T163000Z @@ -327,22 +379,24 @@ CATEGORIES:BUSINESS,HUMAN RESOURCES TRANSP:TRANSPARENT END:VEVENT '''; - final event = VComponent.parse(text); - expect(event, isA()); - expect((event as VEvent).summary, - 'Laurel is in sensitivity awareness class.'); - expect(event.uid, '19970901T130000Z-123402@example.com'); - expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00)); - expect(event.start, DateTime.utc(1997, 04, 01, 16, 30, 00)); - expect(event.end, DateTime.utc(1997, 04, 02, 1, 00, 00)); - expect(event.classification, Classification.public); - expect(event.categories, ['BUSINESS', 'HUMAN RESOURCES']); - expect(event.timeTransparency, TimeTransparency.transparent); - }); + final event = VComponent.parse(text); + expect(event, isA()); + expect((event as VEvent).summary, + 'Laurel is in sensitivity awareness class.'); + expect(event.uid, '19970901T130000Z-123402@example.com'); + expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00)); + expect(event.start, DateTime.utc(1997, 04, 01, 16, 30, 00)); + expect(event.end, DateTime.utc(1997, 04, 02, 1, 00, 00)); + expect(event.classification, Classification.public); + expect(event.categories, ['BUSINESS', 'HUMAN RESOURCES']); + expect(event.timeTransparency, TimeTransparency.transparent); + }, + ); - test('Recurrent event - yearly', () { - const text = - '''BEGIN:VEVENT\r + test( + 'Recurrent event - yearly', + () { + const text = '''BEGIN:VEVENT\r UID:19970901T130000Z-123403@example.com\r DTSTAMP:19970901T130000Z\r DTSTART;VALUE=DATE:19971102\r @@ -353,22 +407,25 @@ CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION\r RRULE:FREQ=YEARLY\r END:VEVENT\r '''; - final event = VComponent.parse(text); - expect(event, isA()); - expect((event as VEvent).summary, 'Our Blissful Anniversary'); - expect(event.uid, '19970901T130000Z-123403@example.com'); - expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00)); - expect(event.start, DateTime(1997, 11, 02)); - expect(event.classification, Classification.confidential); - expect(event.categories, ['ANNIVERSARY', 'PERSONAL', 'SPECIAL OCCASION']); - expect(event.timeTransparency, TimeTransparency.transparent); - expect(event.recurrenceRule, isNotNull); - expect(event.recurrenceRule!.frequency, RecurrenceFrequency.yearly); - }); + final event = VComponent.parse(text); + expect(event, isA()); + expect((event as VEvent).summary, 'Our Blissful Anniversary'); + expect(event.uid, '19970901T130000Z-123403@example.com'); + expect(event.timeStamp, DateTime.utc(1997, 09, 01, 13, 00, 00)); + expect(event.start, DateTime(1997, 11, 02)); + expect(event.classification, Classification.confidential); + expect(event.categories, + ['ANNIVERSARY', 'PERSONAL', 'SPECIAL OCCASION']); + expect(event.timeTransparency, TimeTransparency.transparent); + expect(event.recurrenceRule, isNotNull); + expect(event.recurrenceRule!.frequency, RecurrenceFrequency.yearly); + }, + ); - test('Day ending', () { - const text = - '''BEGIN:VEVENT + test( + 'Day ending', + () { + const text = '''BEGIN:VEVENT UID:20070423T123432Z-541111@example.com DTSTAMP:20070423T123432Z DTSTART;VALUE=DATE:20070628 @@ -377,21 +434,23 @@ SUMMARY:Festival International de Jazz de Montreal TRANSP:TRANSPARENT END:VEVENT '''; - final event = VComponent.parse(text); - expect(event, isA()); - expect((event as VEvent).summary, - 'Festival International de Jazz de Montreal'); - expect(event.uid, '20070423T123432Z-541111@example.com'); - expect(event.timeStamp, DateTime.utc(2007, 04, 23, 12, 34, 32)); - expect(event.start, DateTime(2007, 06, 28)); - expect(event.end, DateTime(2007, 07, 09)); - expect(event.timeTransparency, TimeTransparency.transparent); - expect(event.recurrenceRule, isNull); - }); + final event = VComponent.parse(text); + expect(event, isA()); + expect((event as VEvent).summary, + 'Festival International de Jazz de Montreal'); + expect(event.uid, '20070423T123432Z-541111@example.com'); + expect(event.timeStamp, DateTime.utc(2007, 04, 23, 12, 34, 32)); + expect(event.start, DateTime(2007, 06, 28)); + expect(event.end, DateTime(2007, 07, 09)); + expect(event.timeTransparency, TimeTransparency.transparent); + expect(event.recurrenceRule, isNull); + }, + ); - test('three-day conference example with CRLF line breaks', () { - const text = - '''BEGIN:VCALENDAR\r + test( + 'three-day conference example with CRLF line breaks', + () { + const text = '''BEGIN:VCALENDAR\r PRODID:-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN\r VERSION:2.0\r BEGIN:VEVENT\r @@ -409,33 +468,33 @@ DESCRIPTION:Networld+Interop Conference \r END:VEVENT\r END:VCALENDAR\r '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).productId, - '-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN'); - expect(calendar.version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - final event = calendar.children.first; - expect(event, isA()); - expect((event as VEvent).uid, 'uid1@example.com'); - expect(event.timeStamp, DateTime.utc(1996, 07, 04, 12, 00, 00)); - expect(event.start, DateTime.utc(1996, 09, 18, 14, 30, 00)); - expect(event.end, DateTime.utc(1996, 09, 20, 22, 00, 00)); - expect(event.categories, ['CONFERENCE']); - expect(event.status, EventStatus.confirmed); - expect(event.organizer?.email, 'jsmith@example.com'); - expect(event.summary, 'Networld+Interop Conference'); - expect(event.description, - 'Networld+Interop Conference and Exhibit\nAtlanta World Congress Center\nAtlanta, Georgia'); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).productId, + '-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN'); + expect(calendar.version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + final event = calendar.children.first; + expect(event, isA()); + expect((event as VEvent).uid, 'uid1@example.com'); + expect(event.timeStamp, DateTime.utc(1996, 07, 04, 12, 00, 00)); + expect(event.start, DateTime.utc(1996, 09, 18, 14, 30, 00)); + expect(event.end, DateTime.utc(1996, 09, 20, 22, 00, 00)); + expect(event.categories, ['CONFERENCE']); + expect(event.status, EventStatus.confirmed); + expect(event.organizer?.email, 'jsmith@example.com'); + expect(event.summary, 'Networld+Interop Conference'); + expect(event.description, + 'Networld+Interop Conference and Exhibit\nAtlanta World Congress Center\nAtlanta, Georgia'); + }, + ); - test( + test( 'three-day conference example with LF line breaks and LF breaks in DESCRIPTION', () { - const text = - '''BEGIN:VCALENDAR + const text = '''BEGIN:VCALENDAR PRODID:-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN VERSION:2.0 BEGIN:VEVENT @@ -453,31 +512,33 @@ DESCRIPTION:"Networld+Interop Conference END:VEVENT END:VCALENDAR '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).productId, - '-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN'); - expect(calendar.version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - final event = calendar.children.first; - expect(event, isA()); - expect((event as VEvent).uid, 'uid1@example.com'); - expect(event.timeStamp, DateTime.utc(1996, 07, 04, 12, 00, 00)); - expect(event.start, DateTime.utc(1996, 09, 18, 14, 30, 00)); - expect(event.end, DateTime.utc(1996, 09, 20, 22, 00, 00)); - expect(event.categories, ['CONFERENCE']); - expect(event.status, EventStatus.confirmed); - expect(event.organizer?.email, 'jsmith@example.com'); - expect(event.summary, 'Networld+Interop Conference'); - expect(event.description, - '"Networld+Interop Conference and Exhibit\nAtlanta World Congress Center\nAtlanta, Georgia"'); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).productId, + '-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN'); + expect(calendar.version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + final event = calendar.children.first; + expect(event, isA()); + expect((event as VEvent).uid, 'uid1@example.com'); + expect(event.timeStamp, DateTime.utc(1996, 07, 04, 12, 00, 00)); + expect(event.start, DateTime.utc(1996, 09, 18, 14, 30, 00)); + expect(event.end, DateTime.utc(1996, 09, 20, 22, 00, 00)); + expect(event.categories, ['CONFERENCE']); + expect(event.status, EventStatus.confirmed); + expect(event.organizer?.email, 'jsmith@example.com'); + expect(event.summary, 'Networld+Interop Conference'); + expect(event.description, + '"Networld+Interop Conference and Exhibit\nAtlanta World Congress Center\nAtlanta, Georgia"'); + }, + ); - test('group-scheduled meeting with VTIMEZONE', () { - const text = - '''BEGIN:VCALENDAR + test( + 'group-scheduled meeting with VTIMEZONE', + () { + const text = '''BEGIN:VCALENDAR PRODID:-//RDU Software//NONSGML HandCal//EN VERSION:2.0 BEGIN:VTIMEZONE @@ -512,59 +573,61 @@ LOCATION:1CP Conference Room 4350 END:VEVENT END:VCALENDAR '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).productId, - '-//RDU Software//NONSGML HandCal//EN'); - expect(calendar.version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 2); - final event = calendar.children[1]; - expect(event, isA()); - expect((event as VEvent).uid, 'guid-1.example.com'); - expect(event.timeStamp, DateTime.utc(1998, 03, 09, 23, 10, 00)); - expect(event.created, DateTime.utc(1998, 03, 09, 13, 00, 00)); - expect(event.start, DateTime(1998, 03, 12, 08, 30, 00)); - expect(event.end, DateTime(1998, 03, 12, 09, 30, 00)); - expect(event.location, '1CP Conference Room 4350'); - expect(event.classification, Classification.public); - expect(event.categories, ['MEETING']); - expect(event.organizer?.email, 'mrbig@example.com'); - expect(event.summary, 'XYZ Project Review'); - expect(event.attendees, isNotEmpty); - expect(event.attendees.length, 1); - final attendee = event.attendees.first; - expect(attendee.rsvp, isTrue); - expect(attendee.role, Role.requiredParticipant); - expect(attendee.userType, CalendarUserType.group); - expect(attendee.email, 'employee-A@example.com'); - final timezone = calendar.children.first; - expect(timezone, isA()); - expect((timezone as VTimezone).timezoneId, 'America/New_York'); - expect(timezone.children, isNotEmpty); - expect(timezone.children.length, 2); - var phase = timezone.children.first; - expect(phase, isA()); - expect(phase.name, 'STANDARD'); - expect(phase.componentType, VComponentType.timezonePhaseStandard); - expect((phase as VTimezonePhase).timezoneName, 'EST'); - expect(phase.start, DateTime(1998, 10, 25, 02, 00, 00)); - expect(phase.from, UtcOffset.value(offsetHour: -4, offsetMinute: 0)); - expect(phase.to, UtcOffset.value(offsetHour: -5, offsetMinute: 0)); - phase = timezone.children[1]; - expect(phase, isA()); - expect(phase.name, 'DAYLIGHT'); - expect(phase.componentType, VComponentType.timezonePhaseDaylight); - expect((phase as VTimezonePhase).timezoneName, 'EDT'); - expect(phase.start, DateTime(1999, 04, 04, 02, 00, 00)); - expect(phase.from, UtcOffset.value(offsetHour: -5, offsetMinute: 0)); - expect(phase.to, UtcOffset.value(offsetHour: -4, offsetMinute: 0)); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).productId, + '-//RDU Software//NONSGML HandCal//EN'); + expect(calendar.version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 2); + final event = calendar.children[1]; + expect(event, isA()); + expect((event as VEvent).uid, 'guid-1.example.com'); + expect(event.timeStamp, DateTime.utc(1998, 03, 09, 23, 10, 00)); + expect(event.created, DateTime.utc(1998, 03, 09, 13, 00, 00)); + expect(event.start, DateTime(1998, 03, 12, 08, 30, 00)); + expect(event.end, DateTime(1998, 03, 12, 09, 30, 00)); + expect(event.location, '1CP Conference Room 4350'); + expect(event.classification, Classification.public); + expect(event.categories, ['MEETING']); + expect(event.organizer?.email, 'mrbig@example.com'); + expect(event.summary, 'XYZ Project Review'); + expect(event.attendees, isNotEmpty); + expect(event.attendees.length, 1); + final attendee = event.attendees.first; + expect(attendee.rsvp, isTrue); + expect(attendee.role, Role.requiredParticipant); + expect(attendee.userType, CalendarUserType.group); + expect(attendee.email, 'employee-A@example.com'); + final timezone = calendar.children.first; + expect(timezone, isA()); + expect((timezone as VTimezone).timezoneId, 'America/New_York'); + expect(timezone.children, isNotEmpty); + expect(timezone.children.length, 2); + var phase = timezone.children.first; + expect(phase, isA()); + expect(phase.name, 'STANDARD'); + expect(phase.componentType, VComponentType.timezonePhaseStandard); + expect((phase as VTimezonePhase).timezoneName, 'EST'); + expect(phase.start, DateTime(1998, 10, 25, 02, 00, 00)); + expect(phase.from, UtcOffset.value(offsetHour: -4, offsetMinute: 0)); + expect(phase.to, UtcOffset.value(offsetHour: -5, offsetMinute: 0)); + phase = timezone.children[1]; + expect(phase, isA()); + expect(phase.name, 'DAYLIGHT'); + expect(phase.componentType, VComponentType.timezonePhaseDaylight); + expect((phase as VTimezonePhase).timezoneName, 'EDT'); + expect(phase.start, DateTime(1999, 04, 04, 02, 00, 00)); + expect(phase.from, UtcOffset.value(offsetHour: -5, offsetMinute: 0)); + expect(phase.to, UtcOffset.value(offsetHour: -4, offsetMinute: 0)); + }, + ); - test('with attachments and sequence', () { - const text = - '''BEGIN:VCALENDAR + test( + 'with attachments and sequence', + () { + const text = '''BEGIN:VCALENDAR METHOD:PUBLISH VERSION:2.0 PRODID:-//ABC Corporation//NONSGML My Product//EN @@ -587,42 +650,45 @@ ATTACH;FMTTYPE=application/postscript:ftp://example.com/pub/ END:VEVENT END:VCALENDAR '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).productId, - '-//ABC Corporation//NONSGML My Product//EN'); - expect(calendar.version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.method, Method.publish); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - final event = calendar.children.first; - expect(event, isA()); - expect((event as VEvent).uid, 'uid3@example.com'); - expect(event.timeStamp, DateTime.utc(1997, 03, 24, 12, 00, 00)); - expect(event.start, DateTime.utc(1997, 03, 24, 12, 30, 00)); - expect(event.end, DateTime.utc(1997, 03, 24, 21, 00, 00)); - expect(event.organizer?.email, 'jdoe@example.com'); - expect(event.attendees.length, 1); - expect(event.attendees[0].rsvp, isTrue); - expect(event.attendees[0].email, 'jsmith@example.com'); - expect(event.categories, ['MEETING', 'PROJECT']); - expect(event.classification, Classification.public); - expect(event.summary, 'Calendaring Interoperability Planning Meeting'); - expect(event.description, - 'Discuss how we can test c&s interoperability\nusing iCalendar and other IETF standards.'); - expect(event.location, 'LDB Lobby'); - // ATTACH;FMTTYPE=application/postscript:ftp://example.com/pub/conf/bkgrnd.ps - expect(event.attachments, isNotEmpty); - expect(event.attachments[0].mediaType, 'application/postscript'); - expect(event.attachments[0].uri, - Uri.parse('ftp://example.com/pub/conf/bkgrnd.ps')); - expect(event.sequence, 0); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).productId, + '-//ABC Corporation//NONSGML My Product//EN'); + expect(calendar.version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.method, Method.publish); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + final event = calendar.children.first; + expect(event, isA()); + expect((event as VEvent).uid, 'uid3@example.com'); + expect(event.timeStamp, DateTime.utc(1997, 03, 24, 12, 00, 00)); + expect(event.start, DateTime.utc(1997, 03, 24, 12, 30, 00)); + expect(event.end, DateTime.utc(1997, 03, 24, 21, 00, 00)); + expect(event.organizer?.email, 'jdoe@example.com'); + expect(event.attendees.length, 1); + expect(event.attendees[0].rsvp, isTrue); + expect(event.attendees[0].email, 'jsmith@example.com'); + expect(event.categories, ['MEETING', 'PROJECT']); + expect(event.classification, Classification.public); + expect( + event.summary, 'Calendaring Interoperability Planning Meeting'); + expect(event.description, + 'Discuss how we can test c&s interoperability\nusing iCalendar and other IETF standards.'); + expect(event.location, 'LDB Lobby'); + // ATTACH;FMTTYPE=application/postscript:ftp://example.com/pub/conf/bkgrnd.ps + expect(event.attachments, isNotEmpty); + expect(event.attachments[0].mediaType, 'application/postscript'); + expect(event.attachments[0].uri, + Uri.parse('ftp://example.com/pub/conf/bkgrnd.ps')); + expect(event.sequence, 0); + }, + ); - test('Todo with audio alarm', () { - const text = - '''BEGIN:VCALENDAR + test( + 'Todo with audio alarm', + () { + const text = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:-//ABC Corporation//NONSGML My Product//EN BEGIN:VTODO @@ -645,46 +711,49 @@ END:VALARM END:VTODO END:VCALENDAR '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).productId, - '-//ABC Corporation//NONSGML My Product//EN'); - expect(calendar.version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - final todo = calendar.children.first; - expect(todo, isA()); - expect((todo as VTodo).uid, 'uid4@example.com'); - expect(todo.timeStamp, DateTime.utc(1998, 01, 30, 13, 45, 00)); - expect(todo.sequence, 2); - expect(todo.organizer?.email, 'unclesam@example.com'); - expect(todo.attendees.length, 1); - expect(todo.attendees[0].rsvp, isFalse); - expect(todo.attendees[0].participantStatus, ParticipantStatus.accepted); - expect(todo.attendees[0].email, 'jqpublic@example.com'); - expect(todo.summary, 'Submit Income Taxes'); - expect(todo.status, TodoStatus.needsAction); - expect(todo.due, DateTime.utc(1998, 04, 15, 00, 00, 00)); - expect(todo.children, isNotEmpty); - expect(todo.children.length, 1); - final alarm = todo.children.first; - expect(alarm, isA()); - expect((alarm as VAlarm).componentType, VComponentType.alarm); - expect(alarm.action, AlarmAction.audio); - expect(alarm.triggerDate, DateTime.utc(1998, 04, 03, 12, 00, 00)); - expect(alarm.repeat, 4); - expect(alarm.duration, IsoDuration(hours: 1)); - expect(alarm.attachments, isNotEmpty); - expect(alarm.attachments.length, 1); - expect(alarm.attachments[0].mediaType, 'audio/basic'); - expect(alarm.attachments[0].uri, - Uri.parse('http://example.com/pub/audio-files/ssbanner.aud')); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).productId, + '-//ABC Corporation//NONSGML My Product//EN'); + expect(calendar.version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + final todo = calendar.children.first; + expect(todo, isA()); + expect((todo as VTodo).uid, 'uid4@example.com'); + expect(todo.timeStamp, DateTime.utc(1998, 01, 30, 13, 45, 00)); + expect(todo.sequence, 2); + expect(todo.organizer?.email, 'unclesam@example.com'); + expect(todo.attendees.length, 1); + expect(todo.attendees[0].rsvp, isFalse); + expect( + todo.attendees[0].participantStatus, ParticipantStatus.accepted); + expect(todo.attendees[0].email, 'jqpublic@example.com'); + expect(todo.summary, 'Submit Income Taxes'); + expect(todo.status, TodoStatus.needsAction); + expect(todo.due, DateTime.utc(1998, 04, 15, 00, 00, 00)); + expect(todo.children, isNotEmpty); + expect(todo.children.length, 1); + final alarm = todo.children.first; + expect(alarm, isA()); + expect((alarm as VAlarm).componentType, VComponentType.alarm); + expect(alarm.action, AlarmAction.audio); + expect(alarm.triggerDate, DateTime.utc(1998, 04, 03, 12, 00, 00)); + expect(alarm.repeat, 4); + expect(alarm.duration, IsoDuration(hours: 1)); + expect(alarm.attachments, isNotEmpty); + expect(alarm.attachments.length, 1); + expect(alarm.attachments[0].mediaType, 'audio/basic'); + expect(alarm.attachments[0].uri, + Uri.parse('http://example.com/pub/audio-files/ssbanner.aud')); + }, + ); - test('journal example', () { - const text = - '''BEGIN:VCALENDAR + test( + 'journal example', + () { + const text = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:-//RDU Software//NONSGML HandCal//EN BEGIN:VFREEBUSY @@ -700,49 +769,52 @@ URL:http://www.example.com/calendar/busytime/jsmith.ifb END:VFREEBUSY END:VCALENDAR '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).productId, - '-//RDU Software//NONSGML HandCal//EN'); - expect(calendar.version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - final freebusy = calendar.children.first; - expect(freebusy, isA()); - expect((freebusy as VFreeBusy).organizer?.email, 'jsmith@example.com'); - expect(freebusy.timeStamp, DateTime.utc(1997, 09, 01, 12, 00, 00)); - expect(freebusy.uid, '19970901T115957Z-76A912@example.com'); - expect(freebusy.organizer?.email, 'jsmith@example.com'); - expect(freebusy.start, DateTime.utc(1998, 03, 13, 14, 17, 11)); - expect(freebusy.end, DateTime.utc(1998, 04, 10, 14, 17, 11)); - expect(freebusy.url, - Uri.parse('http://www.example.com/calendar/busytime/jsmith.ifb')); - expect(freebusy.freeBusyProperties, isNotEmpty); - expect(freebusy.freeBusyProperties.length, 3); - expect(freebusy.freeBusyProperties[0].periods, isNotEmpty); - expect(freebusy.freeBusyProperties[0].periods.length, 1); - expect(freebusy.freeBusyProperties[0].periods[0].startDate, - DateTime.utc(1998, 03, 14, 23, 30, 00)); - expect(freebusy.freeBusyProperties[0].periods[0].endDate, - DateTime.utc(1998, 03, 15, 00, 30, 00)); - expect( - freebusy.freeBusyProperties[0].freeBusyType, FreeBusyTimeType.busy); - expect(freebusy.freeBusyProperties[1].periods.length, 1); - expect(freebusy.freeBusyProperties[1].periods[0].startDate, - DateTime.utc(1998, 03, 16, 15, 30, 00)); - expect(freebusy.freeBusyProperties[1].periods[0].endDate, - DateTime.utc(1998, 03, 16, 16, 30, 00)); - expect(freebusy.freeBusyProperties[2].periods.length, 1); - expect(freebusy.freeBusyProperties[2].periods[0].startDate, - DateTime.utc(1998, 03, 18, 03, 00, 00)); - expect(freebusy.freeBusyProperties[2].periods[0].endDate, - DateTime.utc(1998, 03, 18, 04, 00, 00)); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).productId, + '-//RDU Software//NONSGML HandCal//EN'); + expect(calendar.version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + final freebusy = calendar.children.first; + expect(freebusy, isA()); + expect( + (freebusy as VFreeBusy).organizer?.email, 'jsmith@example.com'); + expect(freebusy.timeStamp, DateTime.utc(1997, 09, 01, 12, 00, 00)); + expect(freebusy.uid, '19970901T115957Z-76A912@example.com'); + expect(freebusy.organizer?.email, 'jsmith@example.com'); + expect(freebusy.start, DateTime.utc(1998, 03, 13, 14, 17, 11)); + expect(freebusy.end, DateTime.utc(1998, 04, 10, 14, 17, 11)); + expect(freebusy.url, + Uri.parse('http://www.example.com/calendar/busytime/jsmith.ifb')); + expect(freebusy.freeBusyProperties, isNotEmpty); + expect(freebusy.freeBusyProperties.length, 3); + expect(freebusy.freeBusyProperties[0].periods, isNotEmpty); + expect(freebusy.freeBusyProperties[0].periods.length, 1); + expect(freebusy.freeBusyProperties[0].periods[0].startDate, + DateTime.utc(1998, 03, 14, 23, 30, 00)); + expect(freebusy.freeBusyProperties[0].periods[0].endDate, + DateTime.utc(1998, 03, 15, 00, 30, 00)); + expect(freebusy.freeBusyProperties[0].freeBusyType, + FreeBusyTimeType.busy); + expect(freebusy.freeBusyProperties[1].periods.length, 1); + expect(freebusy.freeBusyProperties[1].periods[0].startDate, + DateTime.utc(1998, 03, 16, 15, 30, 00)); + expect(freebusy.freeBusyProperties[1].periods[0].endDate, + DateTime.utc(1998, 03, 16, 16, 30, 00)); + expect(freebusy.freeBusyProperties[2].periods.length, 1); + expect(freebusy.freeBusyProperties[2].periods[0].startDate, + DateTime.utc(1998, 03, 18, 03, 00, 00)); + expect(freebusy.freeBusyProperties[2].periods[0].endDate, + DateTime.utc(1998, 03, 18, 04, 00, 00)); + }, + ); - test('free busy example', () { - const text = - '''BEGIN:VCALENDAR\r + test( + 'free busy example', + () { + const text = '''BEGIN:VCALENDAR\r VERSION:2.0\r PRODID:-//ABC Corporation//NONSGML My Product//EN\r BEGIN:VJOURNAL\r @@ -766,24 +838,25 @@ DESCRIPTION:Project xyz Review Meeting Minutes\n\r END:VJOURNAL\r END:VCALENDAR\r '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).productId, - '-//ABC Corporation//NONSGML My Product//EN'); - expect(calendar.version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - final journal = calendar.children.first; - expect(journal, isA()); - expect((journal as VJournal).uid, 'uid5@example.com'); - expect(journal.timeStamp, DateTime.utc(1997, 03, 24, 12, 00, 00)); - expect(journal.organizer?.email, 'jsmith@example.com'); - expect(journal.classification, Classification.public); - expect(journal.status, JournalStatus.draft); - expect(journal.categories, ['Project Report', 'XYZ', 'Weekly Meeting']); - expect(journal.description, - '''Project xyz Review Meeting Minutes\nAgenda + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).productId, + '-//ABC Corporation//NONSGML My Product//EN'); + expect(calendar.version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + final journal = calendar.children.first; + expect(journal, isA()); + expect((journal as VJournal).uid, 'uid5@example.com'); + expect(journal.timeStamp, DateTime.utc(1997, 03, 24, 12, 00, 00)); + expect(journal.organizer?.email, 'jsmith@example.com'); + expect(journal.classification, Classification.public); + expect(journal.status, JournalStatus.draft); + expect( + journal.categories, ['Project Report', 'XYZ', 'Weekly Meeting']); + expect( + journal.description, '''Project xyz Review Meeting Minutes\nAgenda 1. Review of project version 1.0 requirements. 2. Definition of project processes. 3. Review of project schedule. @@ -792,11 +865,13 @@ Participants: John Smith, Jane Doe, Jim Dandy\n-It was decided that the requirem -Project schedule needs to account for scheduled holidays and employee vacation time. Check with HR for specific dates. -New schedule will be distributed by Friday. -Next weeks meeting is cancelled. No meeting until 3/23.'''); - }); + }, + ); - test('Real world 1', () { - const text = - '''BEGIN:VCALENDAR + test( + 'Real world 1', + () { + const text = '''BEGIN:VCALENDAR VERSION:2.0 PRODID:http://ticket.io/ METHOD:PUBLISH @@ -813,36 +888,39 @@ DESCRIPTION: ORGANIZER;CN="Covidzentrum Bremen":MAILTO:sofortsupport@ticket.io END:VEVENT END:VCALENDAR'''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.calendarScale, 'GREGORIAN'); - expect(calendar.isGregorian, isTrue); - expect(calendar.productId, 'http://ticket.io/'); - expect(calendar.timezoneId, 'Europe/Berlin'); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 1); - final event = calendar.children.first; - expect(event, isA()); - expect( - (event as VEvent).summary, 'Kostenloser Antigen-Schnelltest Bremen'); - expect(event.uid, 'ticketioa7a690b342c3a9fdbc20206572744d64'); - expect(event.classification, Classification.public); - expect(event.timeStamp, DateTime(2021, 07, 06, 10, 30, 42)); - expect(event.start, DateTime(2021, 07, 06, 09, 00, 00)); - expect(event.end, DateTime(2021, 07, 06, 21, 00, 00)); - expect(event.description, ''); - expect(event.location, ', Außer der Schleifmühle 4, 28203 Bremen'); - expect(event.organizer, isNotNull); - expect(event.organizer!.uri, Uri.parse('MAILTO:sofortsupport@ticket.io')); - expect(event.organizer!.email, 'sofortsupport@ticket.io'); - expect(event.organizer!.commonName, 'Covidzentrum Bremen'); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.calendarScale, 'GREGORIAN'); + expect(calendar.isGregorian, isTrue); + expect(calendar.productId, 'http://ticket.io/'); + expect(calendar.timezoneId, 'Europe/Berlin'); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 1); + final event = calendar.children.first; + expect(event, isA()); + expect((event as VEvent).summary, + 'Kostenloser Antigen-Schnelltest Bremen'); + expect(event.uid, 'ticketioa7a690b342c3a9fdbc20206572744d64'); + expect(event.classification, Classification.public); + expect(event.timeStamp, DateTime(2021, 07, 06, 10, 30, 42)); + expect(event.start, DateTime(2021, 07, 06, 09, 00, 00)); + expect(event.end, DateTime(2021, 07, 06, 21, 00, 00)); + expect(event.description, ''); + expect(event.location, ', Außer der Schleifmühle 4, 28203 Bremen'); + expect(event.organizer, isNotNull); + expect(event.organizer!.uri, + Uri.parse('MAILTO:sofortsupport@ticket.io')); + expect(event.organizer!.email, 'sofortsupport@ticket.io'); + expect(event.organizer!.commonName, 'Covidzentrum Bremen'); + }, + ); - test('Real world 2', () { - const text = - '''BEGIN:VCALENDAR\r + test( + 'Real world 2', + () { + const text = '''BEGIN:VCALENDAR\r VERSION:2.0\r PRODID:-//Open-Xchange//7.10.3-Rev34//EN\r METHOD:REQUEST\r @@ -888,167 +966,181 @@ X-MICROSOFT-CDO-BUSYSTATUS:BUSY\r END:VEVENT\r END:VCALENDAR\r '''; - final calendar = VComponent.parse(text); - expect(calendar, isA()); - expect((calendar as VCalendar).version, '2.0'); - expect(calendar.isVersion2, isTrue); - expect(calendar.isGregorian, isTrue); - expect(calendar.productId, '-//Open-Xchange//7.10.3-Rev34//EN'); - expect(calendar.timezoneId, 'Europe/Rome'); - expect(calendar.children, isNotEmpty); - expect(calendar.children.length, 2); - final event = calendar.children[1]; - expect(event, isA()); - expect((event as VEvent).summary, 'Example meeting'); - expect(event.uid, '1dbfc3a9-a285-46ae-944a-15c3927ab7ac'); - expect(event.classification, Classification.public); - expect(event.start, DateTime(2021, 07, 22, 14, 00, 00)); - expect(event.end, DateTime(2021, 07, 22, 16, 00, 00)); - //print(event.description); - expect(event.description, - 'Hey, here\'s the event description, with\nsome commas.'); - expect(event.location, 'When in Rome...'); - expect(event.organizer, isNotNull); - expect( - event.organizer!.uri, Uri.parse('MAILTO:mrs.organizer@example.com')); - expect(event.organizer!.email, 'mrs.organizer@example.com'); - expect(event.organizer!.commonName, 'Mrs Organizer'); - expect(event.busyStatus, EventBusyStatus.busy); - expect(calendar.timezone?.location, 'Europe/Rome'); - }); - }); + final calendar = VComponent.parse(text); + expect(calendar, isA()); + expect((calendar as VCalendar).version, '2.0'); + expect(calendar.isVersion2, isTrue); + expect(calendar.isGregorian, isTrue); + expect(calendar.productId, '-//Open-Xchange//7.10.3-Rev34//EN'); + expect(calendar.timezoneId, 'Europe/Rome'); + expect(calendar.children, isNotEmpty); + expect(calendar.children.length, 2); + final event = calendar.children[1]; + expect(event, isA()); + expect((event as VEvent).summary, 'Example meeting'); + expect(event.uid, '1dbfc3a9-a285-46ae-944a-15c3927ab7ac'); + expect(event.classification, Classification.public); + expect(event.start, DateTime(2021, 07, 22, 14, 00, 00)); + expect(event.end, DateTime(2021, 07, 22, 16, 00, 00)); + //print(event.description); + expect(event.description, + 'Hey, here\'s the event description, with\nsome commas.'); + expect(event.location, 'When in Rome...'); + expect(event.organizer, isNotNull); + expect(event.organizer!.uri, + Uri.parse('MAILTO:mrs.organizer@example.com')); + expect(event.organizer!.email, 'mrs.organizer@example.com'); + expect(event.organizer!.commonName, 'Mrs Organizer'); + expect(event.busyStatus, EventBusyStatus.busy); + expect(calendar.timezone?.location, 'Europe/Rome'); + }, + ); + }, + ); - group('Create Calendar Invites', () { - test('Simple event', () { - final invite = VCalendar.createEvent( - organizerEmail: 'a@example.com', - attendeeEmails: ['a@example.com', 'b@example.com', 'c@example.com'], - rsvp: true, - start: DateTime(2021, 07, 21, 10, 00), - end: DateTime(2021, 07, 21, 11, 00), - location: 'Big meeting room', - url: Uri.parse('https://enough.de'), - summary: 'Discussion', - description: - 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?', - productId: 'enough_icalendar/v1', + group( + 'Create Calendar Invites', + () { + test( + 'Simple event', + () { + final invite = VCalendar.createEvent( + organizerEmail: 'a@example.com', + attendeeEmails: ['a@example.com', 'b@example.com', 'c@example.com'], + rsvp: true, + start: DateTime(2021, 07, 21, 10, 00), + end: DateTime(2021, 07, 21, 11, 00), + location: 'Big meeting room', + url: Uri.parse('https://enough.de'), + summary: 'Discussion', + description: + 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?', + productId: 'enough_icalendar/v1', + ); + // print(invite); + invite.checkValidity(); + expect(invite.isVersion2, isTrue); + expect(invite.isGregorian, isTrue); + expect(invite.productId, 'enough_icalendar/v1'); + expect(invite.children, isNotEmpty); + final event = invite.children.first; + event.checkValidity(); + expect(event, isA()); + expect((event as VEvent).start, DateTime(2021, 07, 21, 10, 00)); + expect(event.end, DateTime(2021, 07, 21, 11, 00)); + expect(event.location, 'Big meeting room'); + expect(event.url, Uri.parse('https://enough.de')); + expect(event.summary, 'Discussion'); + expect(event.description, + 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?'); + expect(event.attendees, isNotEmpty); + expect(event.attendees.length, 3); + expect(event.attendees[0].rsvp, isTrue); + expect(event.attendees[0].email, 'a@example.com'); + expect(event.attendees[1].rsvp, isTrue); + expect(event.attendees[1].email, 'b@example.com'); + expect(event.attendees[2].rsvp, isTrue); + expect(event.attendees[2].email, 'c@example.com'); + expect(event.organizer, isNotNull); + expect(event.organizer?.email, 'a@example.com'); + }, ); - // print(invite); - invite.checkValidity(); - expect(invite.isVersion2, isTrue); - expect(invite.isGregorian, isTrue); - expect(invite.productId, 'enough_icalendar/v1'); - expect(invite.children, isNotEmpty); - final event = invite.children.first; - event.checkValidity(); - expect(event, isA()); - expect((event as VEvent).start, DateTime(2021, 07, 21, 10, 00)); - expect(event.end, DateTime(2021, 07, 21, 11, 00)); - expect(event.location, 'Big meeting room'); - expect(event.url, Uri.parse('https://enough.de')); - expect(event.summary, 'Discussion'); - expect(event.description, - 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?'); - expect(event.attendees, isNotEmpty); - expect(event.attendees.length, 3); - expect(event.attendees[0].rsvp, isTrue); - expect(event.attendees[0].email, 'a@example.com'); - expect(event.attendees[1].rsvp, isTrue); - expect(event.attendees[1].email, 'b@example.com'); - expect(event.attendees[2].rsvp, isTrue); - expect(event.attendees[2].email, 'c@example.com'); - expect(event.organizer, isNotNull); - expect(event.organizer?.email, 'a@example.com'); - }); - test('Simple event with UTC timing', () { - final invite = VCalendar.createEvent( - organizerEmail: 'a@example.com', - attendeeEmails: ['a@example.com', 'b@example.com', 'c@example.com'], - rsvp: true, - start: DateTime.utc(2021, 07, 21, 10, 00), - end: DateTime.utc(2021, 07, 21, 11, 00), - location: 'Big meeting room', - url: Uri.parse('https://enough.de'), - summary: 'Discussion', - description: - 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?', - productId: 'enough_icalendar/v1', + test( + 'Simple event with UTC timing', + () { + final invite = VCalendar.createEvent( + organizerEmail: 'a@example.com', + attendeeEmails: ['a@example.com', 'b@example.com', 'c@example.com'], + rsvp: true, + start: DateTime.utc(2021, 07, 21, 10, 00), + end: DateTime.utc(2021, 07, 21, 11, 00), + location: 'Big meeting room', + url: Uri.parse('https://enough.de'), + summary: 'Discussion', + description: + 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?', + productId: 'enough_icalendar/v1', + ); + // print(invite); + invite.checkValidity(); + expect(invite.isVersion2, isTrue); + expect(invite.isGregorian, isTrue); + expect(invite.productId, 'enough_icalendar/v1'); + expect(invite.children, isNotEmpty); + final event = invite.children.first; + event.checkValidity(); + expect(event, isA()); + expect((event as VEvent).start, DateTime.utc(2021, 07, 21, 10, 00)); + expect(event['DTSTART']?.textValue, '20210721T100000Z'); + expect(event.end, DateTime.utc(2021, 07, 21, 11, 00)); + expect(event['DTEND']?.textValue, '20210721T110000Z'); + expect(event.location, 'Big meeting room'); + expect(event.url, Uri.parse('https://enough.de')); + expect(event.summary, 'Discussion'); + expect(event.description, + 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?'); + expect(event.attendees, isNotEmpty); + expect(event.attendees.length, 3); + expect(event.attendees[0].rsvp, isTrue); + expect(event.attendees[0].email, 'a@example.com'); + expect(event.attendees[1].rsvp, isTrue); + expect(event.attendees[1].email, 'b@example.com'); + expect(event.attendees[2].rsvp, isTrue); + expect(event.attendees[2].email, 'c@example.com'); + expect(event.organizer, isNotNull); + expect(event.organizer?.email, 'a@example.com'); + }, ); - // print(invite); - invite.checkValidity(); - expect(invite.isVersion2, isTrue); - expect(invite.isGregorian, isTrue); - expect(invite.productId, 'enough_icalendar/v1'); - expect(invite.children, isNotEmpty); - final event = invite.children.first; - event.checkValidity(); - expect(event, isA()); - expect((event as VEvent).start, DateTime.utc(2021, 07, 21, 10, 00)); - expect(event['DTSTART']?.textValue, '20210721T100000Z'); - expect(event.end, DateTime.utc(2021, 07, 21, 11, 00)); - expect(event['DTEND']?.textValue, '20210721T110000Z'); - expect(event.location, 'Big meeting room'); - expect(event.url, Uri.parse('https://enough.de')); - expect(event.summary, 'Discussion'); - expect(event.description, - 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?'); - expect(event.attendees, isNotEmpty); - expect(event.attendees.length, 3); - expect(event.attendees[0].rsvp, isTrue); - expect(event.attendees[0].email, 'a@example.com'); - expect(event.attendees[1].rsvp, isTrue); - expect(event.attendees[1].email, 'b@example.com'); - expect(event.attendees[2].rsvp, isTrue); - expect(event.attendees[2].email, 'c@example.com'); - expect(event.organizer, isNotNull); - expect(event.organizer?.email, 'a@example.com'); - }); - test('Full day event with UTC timing', () { - final invite = VCalendar.createEvent( - organizerEmail: 'a@example.com', - attendeeEmails: ['a@example.com', 'b@example.com', 'c@example.com'], - rsvp: true, - start: DateTime.utc(2021, 07, 21, 0, 00), - duration: IsoDuration(days: 1), - isAllDayEvent: true, - location: 'Big meeting room', - url: Uri.parse('https://enough.de'), - summary: 'Discussion', - description: - 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?', - productId: 'enough_icalendar/v1', + test( + 'Full day event with UTC timing', + () { + final invite = VCalendar.createEvent( + organizerEmail: 'a@example.com', + attendeeEmails: ['a@example.com', 'b@example.com', 'c@example.com'], + rsvp: true, + start: DateTime.utc(2021, 07, 21, 0, 00), + duration: IsoDuration(days: 1), + isAllDayEvent: true, + location: 'Big meeting room', + url: Uri.parse('https://enough.de'), + summary: 'Discussion', + description: + 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?', + productId: 'enough_icalendar/v1', + ); + // print(invite); + invite.checkValidity(); + expect(invite.isVersion2, isTrue); + expect(invite.isGregorian, isTrue); + expect(invite.productId, 'enough_icalendar/v1'); + expect(invite.children, isNotEmpty); + final event = invite.children.first; + event.checkValidity(); + expect(event, isA()); + expect((event as VEvent).start, DateTime.utc(2021, 07, 21, 0, 00)); + expect(event['DTSTART']?.textValue, '20210721T000000Z'); + expect(event.end, isNull); + expect(event.duration, IsoDuration(days: 1)); + expect(event.isAllDayEvent, isTrue); + expect(event.location, 'Big meeting room'); + expect(event.url, Uri.parse('https://enough.de')); + expect(event.summary, 'Discussion'); + expect(event.description, + 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?'); + expect(event.attendees, isNotEmpty); + expect(event.attendees.length, 3); + expect(event.attendees[0].rsvp, isTrue); + expect(event.attendees[0].email, 'a@example.com'); + expect(event.attendees[1].rsvp, isTrue); + expect(event.attendees[1].email, 'b@example.com'); + expect(event.attendees[2].rsvp, isTrue); + expect(event.attendees[2].email, 'c@example.com'); + expect(event.organizer, isNotNull); + expect(event.organizer?.email, 'a@example.com'); + }, ); - // print(invite); - invite.checkValidity(); - expect(invite.isVersion2, isTrue); - expect(invite.isGregorian, isTrue); - expect(invite.productId, 'enough_icalendar/v1'); - expect(invite.children, isNotEmpty); - final event = invite.children.first; - event.checkValidity(); - expect(event, isA()); - expect((event as VEvent).start, DateTime.utc(2021, 07, 21, 0, 00)); - expect(event['DTSTART']?.textValue, '20210721T000000Z'); - expect(event.end, isNull); - expect(event.duration, IsoDuration(days: 1)); - expect(event.isAllDayEvent, isTrue); - expect(event.location, 'Big meeting room'); - expect(event.url, Uri.parse('https://enough.de')); - expect(event.summary, 'Discussion'); - expect(event.description, - 'Let us discuss how to proceed with the enough_icalendar development. It seems that basic functionality is now covered. What\'s next?'); - expect(event.attendees, isNotEmpty); - expect(event.attendees.length, 3); - expect(event.attendees[0].rsvp, isTrue); - expect(event.attendees[0].email, 'a@example.com'); - expect(event.attendees[1].rsvp, isTrue); - expect(event.attendees[1].email, 'b@example.com'); - expect(event.attendees[2].rsvp, isTrue); - expect(event.attendees[2].email, 'c@example.com'); - expect(event.organizer, isNotNull); - expect(event.organizer?.email, 'a@example.com'); - }); - }); + }, + ); }