From 44e242064533946abe246bc415667983e5d02dee Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Wed, 24 Mar 2021 14:01:10 +0100 Subject: [PATCH] range: Handle zero-length ranges when calculating overlap Zero length ranges, such as for events without a DTEND could be considered to overlap a range if they were at exactly the end of the range. The end of a range however is the first date that is supposed to not overlap, so a zero-length range on exactly this point should not be considered overlapping. This fixes cases where all-day events from the next month could show up on the same day of the current month if they did not have a DTEND. This also adds tests for all possible cases of such zero-length events overlapping. Fixes https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/701 --- src/core/gcal-range.c | 20 +++++++++++++++++++- tests/test-range.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/core/gcal-range.c b/src/core/gcal-range.c index 9aeb5c7f..a85b16b8 100644 --- a/src/core/gcal-range.c +++ b/src/core/gcal-range.c @@ -320,7 +320,25 @@ gcal_range_calculate_overlap (GcalRange *a, } else if (a_end_b_end_diff == 0) { - if (a_start_b_start_diff < 0) + gint a_start_b_end_diff; + gint a_end_b_start_diff; + + a_start_b_end_diff = compare_func (a->range_start, b->range_end); + a_end_b_start_diff = compare_func (a->range_end, b->range_start); + + if (a_start_b_end_diff >= 0) + { + /* Case 5.i for zero length A */ + overlap = GCAL_RANGE_NO_OVERLAP; + position = GCAL_RANGE_AFTER; + } + else if (a_end_b_start_diff <= 0) + { + /* Case 5.ii for zero length B */ + overlap = GCAL_RANGE_NO_OVERLAP; + position = GCAL_RANGE_BEFORE; + } + else if (a_start_b_start_diff < 0) { /* Case 2.iii */ overlap = GCAL_RANGE_SUPERSET; diff --git a/tests/test-range.c b/tests/test-range.c index 68d454d5..43a695cb 100644 --- a/tests/test-range.c +++ b/tests/test-range.c @@ -159,6 +159,38 @@ static struct { GCAL_RANGE_NO_OVERLAP, GCAL_RANGE_AFTER, }, + + /* Zero length */ + { + { "2020-03-10T00:00:00", "2020-03-15T00:00:00" }, + { "2020-03-15T00:00:00", "2020-03-15T00:00:00" }, + GCAL_RANGE_NO_OVERLAP, + GCAL_RANGE_BEFORE, + }, + { + { "2020-03-10T00:00:00", "2020-03-15T00:00:00" }, + { "2020-03-10T00:00:00", "2020-03-10T00:00:00" }, + GCAL_RANGE_SUPERSET, + GCAL_RANGE_AFTER, + }, + { + { "2020-03-15T00:00:00", "2020-03-15T00:00:00" }, + { "2020-03-10T00:00:00", "2020-03-15T00:00:00" }, + GCAL_RANGE_NO_OVERLAP, + GCAL_RANGE_AFTER, + }, + { + { "2020-03-10T00:00:00", "2020-03-10T00:00:00" }, + { "2020-03-10T00:00:00", "2020-03-15T00:00:00" }, + GCAL_RANGE_SUBSET, + GCAL_RANGE_BEFORE, + }, + { + { "2020-03-10T00:00:00", "2020-03-10T00:00:00" }, + { "2020-03-10T00:00:00", "2020-03-10T00:00:00" }, + GCAL_RANGE_EQUAL, + GCAL_RANGE_MATCH, + }, }; static void