From 33298918c64b128c08557a8dc8a5377f23497e33 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Sun, 17 Mar 2024 16:08:30 +0000 Subject: [PATCH 01/10] Refactor time tests --- .../tests/calendars/property_params.ics | 21 +++++++++++ src/icalendar/tests/conftest.py | 8 ++++ src/icalendar/tests/test_time.py | 37 +++++++++---------- 3 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 src/icalendar/tests/calendars/property_params.ics diff --git a/src/icalendar/tests/calendars/property_params.ics b/src/icalendar/tests/calendars/property_params.ics new file mode 100644 index 0000000..7563d2f --- /dev/null +++ b/src/icalendar/tests/calendars/property_params.ics @@ -0,0 +1,21 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID://RESEARCH IN MOTION//BIS 3.0 +METHOD:REQUEST +BEGIN:VEVENT +SEQUENCE:2 +X-RIM-REVISION:0 +SUMMARY:Test meeting from BB +X-MICROSOFT-CDO-ALLDAYEVENT:TRUE +CLASS:PUBLIC +ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandXS":MAILTO:rembrand@xs4all.nl +ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandDX":MAILTO:rembrand@daxlab.com +ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandSB":MAILTO:rembspam@xs4all.nl +UID:XRIMCAL-628059586-522954492-9750559 +DTSTART;VALUE=DATE:20120814 +DTEND;VALUE=DATE:20120815 +DESCRIPTION:Test meeting from BB +DTSTAMP:20120813T151458Z +ORGANIZER:mailto:rembrand@daxlab.com +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/conftest.py b/src/icalendar/tests/conftest.py index b9e12d0..ca3863b 100644 --- a/src/icalendar/tests/conftest.py +++ b/src/icalendar/tests/conftest.py @@ -104,3 +104,11 @@ FUZZ_V1 = [os.path.join(CALENDARS_FOLDER, key) for key in os.listdir(CALENDARS_F def fuzz_v1_calendar(request): """Clusterfuzz calendars.""" return request.param + + +@pytest.fixture() +def x_sometime(): + """Map x_sometime to time""" + icalendar.cal.types_factory.types_map['X-SOMETIME'] = 'time' + yield + icalendar.cal.types_factory.types_map.pop('X-SOMETIME') diff --git a/src/icalendar/tests/test_time.py b/src/icalendar/tests/test_time.py index f2aa36c..b31cb7c 100644 --- a/src/icalendar/tests/test_time.py +++ b/src/icalendar/tests/test_time.py @@ -1,29 +1,28 @@ -import unittest - import datetime import icalendar import os +def test_value_type_is_not_mapped(): + """Usually, the value should be absent.""" + assert 'X-SOMETIME' not in icalendar.cal.types_factory.types_map -class TestTime(unittest.TestCase): - def setUp(self): - icalendar.cal.types_factory.types_map['X-SOMETIME'] = 'time' +def test_value_type_is_mapped(x_sometime): + """The value is mapped for the test.""" + assert 'X-SOMETIME' in icalendar.cal.types_factory.types_map - def tearDown(self): - icalendar.cal.types_factory.types_map.pop('X-SOMETIME') - def test_create_from_ical(self): - directory = os.path.dirname(__file__) - ics = open(os.path.join(directory, 'calendars', 'time.ics'), 'rb') - cal = icalendar.Calendar.from_ical(ics.read()) - ics.close() +def test_create_from_ical(x_sometime): + directory = os.path.dirname(__file__) + ics = open(os.path.join(directory, 'calendars', 'time.ics'), 'rb') + cal = icalendar.Calendar.from_ical(ics.read()) + ics.close() - self.assertEqual(cal['X-SOMETIME'].dt, datetime.time(17, 20, 10)) - self.assertEqual(cal['X-SOMETIME'].to_ical(), '172010') + assert cal['X-SOMETIME'].dt == datetime.time(17, 20, 10) + assert cal['X-SOMETIME'].to_ical() == '172010' - def test_create_to_ical(self): - cal = icalendar.Calendar() - cal.add('X-SOMETIME', datetime.time(17, 20, 10)) - self.assertTrue(b'X-SOMETIME;VALUE=TIME:172010' in - cal.to_ical().splitlines()) + +def test_create_to_ical(x_sometime): + cal = icalendar.Calendar() + cal.add('X-SOMETIME', datetime.time(17, 20, 10)) + assert b'X-SOMETIME;VALUE=TIME:172010' in cal.to_ical().splitlines() From 8f377be9e33ac377cd50d413c38a991e1750f6fa Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 18 Mar 2024 17:41:02 +0000 Subject: [PATCH 02/10] Analyse code coverage in tests By analysing the code coverage in the test files, we can make sure that we do not accidentially remove a test and that all test code actually is used --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index de95111..54e7050 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ deps = coverage hypothesis commands = - coverage run --source=src/icalendar --omit=*/tests/* --module pytest [] + coverage run --source=src/icalendar --omit=*/tests/hypothesis/* --omit=*/tests/fuzzed/* --module pytest [] coverage report coverage html From 37dd7cd18ade468408bda8a4431ac1ba12e63100 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 18 Mar 2024 17:44:16 +0000 Subject: [PATCH 03/10] log changes --- CHANGES.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.rst b/CHANGES.rst index 4b40d36..fcd4c3e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,7 @@ Changelog Minor changes: +- Analyse code coverage of test files - Added corpus to fuzzing directory - Added exclusion of fuzzing corpus in MANIFEST.in - Augmented fuzzer to optionally convert multiple calendars from a source string From a09daf64936d587c1c8a1083f0518b0fef1cdb46 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Sun, 17 Mar 2024 12:04:37 +0000 Subject: [PATCH 04/10] Refactor property parameter tests --- src/icalendar/tests/test_property_params.py | 91 ++++++++------------- 1 file changed, 34 insertions(+), 57 deletions(-) diff --git a/src/icalendar/tests/test_property_params.py b/src/icalendar/tests/test_property_params.py index 18ad9fb..63b2ffe 100644 --- a/src/icalendar/tests/test_property_params.py +++ b/src/icalendar/tests/test_property_params.py @@ -38,17 +38,21 @@ def test_parameter_to_ical_is_inverse_of_from_ical(parameter, expected): assert parameter.to_ical() == expected assert Parameters.from_ical(expected.decode('utf-8')) == parameter + def test_parse_parameter_string_without_quotes(): assert Parameters.from_ical('PARAM1=Value 1;PARA2=Value 2') == Parameters({'PARAM1': 'Value 1', 'PARA2': 'Value 2'}) + def test_parametr_is_case_insensitive(): parameter = Parameters(parameter1='Value1') assert parameter['parameter1'] == parameter['PARAMETER1'] == parameter['PaRaMeTer1'] + def test_parameter_keys_are_uppercase(): parameter = Parameters(parameter1='Value1') assert list(parameter.keys()) == ['PARAMETER1'] + @pytest.mark.parametrize('cn_param, cn_quoted', [ # not double-quoted ('Aramis', 'Aramis'), @@ -67,68 +71,41 @@ def test_quoting(cn_param, cn_quoted): event.add('ATTENDEE', attendee) assert f'ATTENDEE;CN={cn_quoted}:test@example.com' in event.to_ical().decode('utf-8') -class TestPropertyParams(unittest.TestCase): - def test_property_params(self): - # Property parameters with values containing a COLON character, a - # SEMICOLON character or a COMMA character MUST be placed in quoted - # text. - cal_address = vCalAddress('mailto:john.doe@example.org') - cal_address.params["CN"] = "Doe, John" - ical = Calendar() - ical.add('organizer', cal_address) +def test_property_params(): + """Property parameters with values containing a COLON character, a + SEMICOLON character or a COMMA character MUST be placed in quoted + text.""" + cal_address = vCalAddress('mailto:john.doe@example.org') + cal_address.params["CN"] = "Doe, John" + ical = Calendar() + ical.add('organizer', cal_address) - ical_str = Calendar.to_ical(ical) - exp_str = b"""BEGIN:VCALENDAR\r\nORGANIZER;CN="Doe, John":"""\ - b"""mailto:john.doe@example.org\r\nEND:VCALENDAR\r\n""" + ical_str = Calendar.to_ical(ical) + exp_str = b"""BEGIN:VCALENDAR\r\nORGANIZER;CN="Doe, John":"""\ + b"""mailto:john.doe@example.org\r\nEND:VCALENDAR\r\n""" - self.assertEqual(ical_str, exp_str) + assert ical_str == exp_str - # other way around: ensure the property parameters can be restored from - # an icalendar string. - ical2 = Calendar.from_ical(ical_str) - self.assertEqual(ical2.get('ORGANIZER').params.get('CN'), 'Doe, John') + # other way around: ensure the property parameters can be restored from + # an icalendar string. + ical2 = Calendar.from_ical(ical_str) + assert ical2.get('ORGANIZER').params.get('CN') == 'Doe, John' - def test_parse_and_access_property_params(self): - """Parse an ics string and access some property parameters then. - This is a follow-up of a question received per email. - """ - ics = """BEGIN:VCALENDAR -VERSION:2.0 -PRODID://RESEARCH IN MOTION//BIS 3.0 -METHOD:REQUEST -BEGIN:VEVENT -SEQUENCE:2 -X-RIM-REVISION:0 -SUMMARY:Test meeting from BB -X-MICROSOFT-CDO-ALLDAYEVENT:TRUE -CLASS:PUBLIC -ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandXS":MAILTO:rembrand@xs4all.nl -ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandDX":MAILTO:rembrand@daxlab.com -ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandSB":MAILTO:rembspam@xs4all.nl -UID:XRIMCAL-628059586-522954492-9750559 -DTSTART;VALUE=DATE:20120814 -DTEND;VALUE=DATE:20120815 -DESCRIPTION:Test meeting from BB -DTSTAMP:20120813T151458Z -ORGANIZER:mailto:rembrand@daxlab.com -END:VEVENT -END:VCALENDAR""" +def test_parse_and_access_property_params(calendars): + """Parse an ics string and access some property parameters then. + This is a follow-up of a question received per email. - cal = icalendar.Calendar.from_ical(ics) - event = cal.walk("VEVENT")[0] - event['attendee'][0] - self.assertEqual(event['attendee'][0].to_ical(), - b'MAILTO:rembrand@xs4all.nl') - self.assertEqual(event['attendee'][0].params.to_ical(), - b'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE') - self.assertEqual(event['attendee'][0].params['cn'], 'RembrandXS') + """ + event = calendars.property_params.walk("VEVENT")[0] + attendee = event['attendee'][0] + assert attendee.to_ical() == b'MAILTO:rembrand@xs4all.nl' + assert attendee.params.to_ical() == b'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE' + assert attendee.params['cn'] == 'RembrandXS' - def test_repr(self): - """Test correct class representation. - """ - it = Parameters(parameter1='Value1') - self.assertTrue( - re.match(r"Parameters\({u?'PARAMETER1': u?'Value1'}\)", str(it)) - ) +def test_repr(): + """Test correct class representation. + """ + it = Parameters(parameter1='Value1') + assert re.match(r"Parameters\({u?'PARAMETER1': u?'Value1'}\)", str(it)) From df92604aa209f8842be455dd71fce2c7d706a952 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Tue, 19 Mar 2024 17:17:57 +0000 Subject: [PATCH 05/10] Add missing test file --- .../tests/calendars/property_params.ics | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/icalendar/tests/calendars/property_params.ics diff --git a/src/icalendar/tests/calendars/property_params.ics b/src/icalendar/tests/calendars/property_params.ics new file mode 100644 index 0000000..7563d2f --- /dev/null +++ b/src/icalendar/tests/calendars/property_params.ics @@ -0,0 +1,21 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID://RESEARCH IN MOTION//BIS 3.0 +METHOD:REQUEST +BEGIN:VEVENT +SEQUENCE:2 +X-RIM-REVISION:0 +SUMMARY:Test meeting from BB +X-MICROSOFT-CDO-ALLDAYEVENT:TRUE +CLASS:PUBLIC +ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandXS":MAILTO:rembrand@xs4all.nl +ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandDX":MAILTO:rembrand@daxlab.com +ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="RembrandSB":MAILTO:rembspam@xs4all.nl +UID:XRIMCAL-628059586-522954492-9750559 +DTSTART;VALUE=DATE:20120814 +DTEND;VALUE=DATE:20120815 +DESCRIPTION:Test meeting from BB +DTSTAMP:20120813T151458Z +ORGANIZER:mailto:rembrand@daxlab.com +END:VEVENT +END:VCALENDAR From 5551ad90619e9d06d76e12555212efdea85733a3 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Tue, 19 Mar 2024 22:04:34 +0000 Subject: [PATCH 06/10] version 5.0.12 see https://icalendar.readthedocs.io/en/latest/maintenance.html --- CHANGES.rst | 4 +++- docs/install.rst | 2 +- news/591.minor-changes | 1 - src/icalendar/__init__.py | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) delete mode 100644 news/591.minor-changes diff --git a/CHANGES.rst b/CHANGES.rst index 4b40d36..f39e53a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -5.0.12 (unreleased) +5.0.12 (2024-03-19) ------------------- Minor changes: @@ -15,6 +15,8 @@ Minor changes: - Rename "contributor" to "collaborator" in documentation - Correct the outdated "icalendar view myfile.ics" command in documentation. #588 - Update GitHub Actions steps versions +- Keep GitHub Actions up to date with GitHub's Dependabot + Breaking changes: diff --git a/docs/install.rst b/docs/install.rst index ede5e87..e17be5a 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -112,7 +112,7 @@ Try it out: Type "help", "copyright", "credits" or "license" for more information. >>> import icalendar >>> icalendar.__version__ - '5.0.11' + '5.0.12' Building the documentation locally ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/news/591.minor-changes b/news/591.minor-changes deleted file mode 100644 index 3b07a12..0000000 --- a/news/591.minor-changes +++ /dev/null @@ -1 +0,0 @@ -Keep GitHub Actions up to date with GitHub's Dependabot diff --git a/src/icalendar/__init__.py b/src/icalendar/__init__.py index f359479..622d114 100644 --- a/src/icalendar/__init__.py +++ b/src/icalendar/__init__.py @@ -1,4 +1,4 @@ -__version__ = '5.0.11' +__version__ = '5.0.12' from icalendar.cal import ( Calendar, From 68893d7caeab25cc8ce930fff0875cba89827511 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Tue, 19 Mar 2024 22:12:20 +0000 Subject: [PATCH 07/10] Add new CHANGELOG section for future release See https://icalendar.readthedocs.io/en/latest/maintenance.html#new-releases --- CHANGES.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index f39e53a..06c160d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,26 @@ Changelog ========= +5.0.13 (unreleased) +------------------- + +Minor changes: + +- ... + +Breaking changes: + +- ... + +New features: + +- ... + +Bug fixes: + +- ... + + 5.0.12 (2024-03-19) ------------------- From 6bcf40e40579e4b4be3ed37da7a39cb6dfc7adc8 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Tue, 19 Mar 2024 22:26:17 +0000 Subject: [PATCH 08/10] Create GitHub Releases --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e747a30..122aaf5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -124,6 +124,6 @@ jobs: - name: create release uses: elgohr/Github-Release-Action@v5 env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GH_TOKEN: ${{ github.token }} with: title: ${{ github.ref_name }} From 245ffb6dae930ef101243bc2ad1d075dc391d855 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Tue, 19 Mar 2024 22:37:40 +0000 Subject: [PATCH 09/10] use different release action --- .github/workflows/tests.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 122aaf5..566a290 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -122,8 +122,4 @@ jobs: steps: - uses: actions/checkout@v4 - name: create release - uses: elgohr/Github-Release-Action@v5 - env: - GH_TOKEN: ${{ github.token }} - with: - title: ${{ github.ref_name }} + uses: ncipollo/release-action@v1 From b819df2bb48e97ca84a517b3e075c3219c9bb480 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Tue, 19 Mar 2024 22:52:27 +0000 Subject: [PATCH 10/10] log changes --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 06c160d..0ea7c77 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,7 +14,7 @@ Breaking changes: New features: -- ... +- Create GitHub releases for each tag. Bug fixes: