Skip to content

Commit 6c1edad

Browse files
committed
Period StartTime, EndTime and Duration properties are immutable
- Adjust code in ' EventEvaluator` and `PeriodSerializer` - Method `GetPeriodKind()` is replace with internal property `PeriodKind` - Add internal `Period.Create` to centralize logic if end time and duration exist - Modified unit test
1 parent eaea8d5 commit 6c1edad

File tree

11 files changed

+137
-158
lines changed

11 files changed

+137
-158
lines changed

Ical.Net.Tests/CollectionHelpersTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void ExDateTests()
2929
});
3030

3131
var changedPeriod = GetExceptionDates();
32-
changedPeriod.First().First().StartTime = new CalDateTime(_now.AddHours(-1));
32+
changedPeriod[0][0] = new Period(new CalDateTime(_now.AddHours(-1)), changedPeriod[0][0].EndTime);
3333

3434
Assert.That(changedPeriod, Is.Not.EqualTo(GetExceptionDates()));
3535
}

Ical.Net.Tests/CopyComponentTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public void CopyFreeBusyTest()
110110
{
111111
Start = new CalDateTime(_now),
112112
End = new CalDateTime(_later),
113-
Entries = { new FreeBusyEntry { Language = "English", StartTime = new CalDateTime(2024, 10, 1), Duration = Duration.FromDays(1), Status = FreeBusyStatus.Busy } }
113+
Entries = { new FreeBusyEntry(new Period(new CalDateTime(2024, 10, 1), Duration.FromDays(1)), FreeBusyStatus.Busy) { Language = "English" }}
114114
};
115115

116116
var copy = orig.Copy<FreeBusy>();

Ical.Net.Tests/GetOccurrenceTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,9 @@ public void GetOccurrencesWithRecurrenceIdShouldEnumerate()
178178
BEGIN:VEVENT
179179
BACKGROUND:BUSY
180180
DESCRIPTION:Backup Daten
181+
DTSTART;TZID=W. Europe Standard Time:20150305T000100
181182
DTEND;TZID=W. Europe Standard Time:20150305T043000
182183
DTSTAMP:20161122T120652Z
183-
DTSTART;TZID=W. Europe Standard Time:20150305T000100
184184
RESOURCES:server
185185
RRULE:FREQ=WEEKLY;BYDAY=MO;BYHOUR=0,12
186186
SUMMARY:Server
@@ -192,9 +192,9 @@ public void GetOccurrencesWithRecurrenceIdShouldEnumerate()
192192
BEGIN:VEVENT
193193
BACKGROUND:BUSY
194194
DESCRIPTION:Backup Daten
195-
DTEND;TZID=W. Europe Standard Time:20161128T043000
195+
DTSTART;TZID=W. Europe Standard Time:20161128T043000
196+
DTEND;TZID=W. Europe Standard Time:20161128T150100
196197
DTSTAMP:20161122T120652Z
197-
DTSTART;TZID=W. Europe Standard Time:20161128T150100
198198
RECURRENCE-ID:20161128T000100
199199
RESOURCES:server
200200
SEQUENCE:0
@@ -216,13 +216,13 @@ public void GetOccurrencesWithRecurrenceIdShouldEnumerate()
216216
new CalDateTime("20161114T120100", "W. Europe Standard Time"),
217217
new CalDateTime("20161121T000100", "W. Europe Standard Time"),
218218
new CalDateTime("20161121T120100", "W. Europe Standard Time"),
219+
new CalDateTime("20161128T043000", "W. Europe Standard Time"), // The replaced entry
219220
new CalDateTime("20161128T120100", "W. Europe Standard Time"),
220-
new CalDateTime("20161128T150100", "W. Europe Standard Time"), // The replaced entry
221221
new CalDateTime("20161205T000100", "W. Europe Standard Time"),
222222
new CalDateTime("20161205T120100", "W. Europe Standard Time")
223223
];
224224

225-
// Specify end time that is between the original occurrence ta 20161128T0001 and the overridden one at 20161128T0030.
225+
// Specify end time that is between the original occurrence at 20161128T0001 and the overridden one at 20161128T0030.
226226
// The overridden one shouldn't be returned, because it was replaced and the other one is in the future.
227227
var occurrences2 = collection.GetOccurrences<CalendarEvent>(new CalDateTime(startCheck), new CalDateTime("20161128T002000", "W. Europe Standard Time"))
228228
.ToList();

Ical.Net.Tests/PeriodTests.cs

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
#nullable enable
77
using System;
8-
using System.ComponentModel.Design;
9-
using System.Linq;
108
using Ical.Net.DataTypes;
119
using NUnit.Framework;
1210

@@ -35,51 +33,38 @@ public void CreatePeriodWithArguments()
3533
Assert.That(periodWithDuration.StartTime, Is.EqualTo(new CalDateTime(2025, 1, 1, 0, 0, 0, "America/New_York")));
3634
Assert.That(periodWithDuration.EffectiveEndTime, Is.EqualTo(new CalDateTime(2025, 1, 1, 1, 0, 0, "America/New_York")));
3735
Assert.That(periodWithDuration.EffectiveDuration, Is.EqualTo(Duration.FromHours(1)));
36+
37+
Assert.That(Period.Create(period.StartTime).Duration, Is.Null);
38+
Assert.That(Period.Create(period.StartTime).EffectiveDuration, Is.Null);
3839
});
3940
}
4041

4142
[Test]
4243
public void CreatePeriodWithInvalidArgumentsShouldThrow()
4344
{
44-
Assert.Throws<ArgumentException>(() => _ = new Period(new CalDateTime(2025, 1, 1, 0, 0, 0, "America/New_York"),
45-
new CalDateTime(2025, 1, 1, 0, 0, 0, "America/New_York")));
46-
Assert.Throws<ArgumentException>(() =>
47-
_ = new Period(new CalDateTime(2025, 1, 1, 0, 0, 0, "America/New_York"), Duration.FromHours(-1)));
48-
}
49-
[Test]
50-
public void SetAndGetStartTime()
51-
{
52-
var period = new Period(new CalDateTime(DateTime.UtcNow));
53-
var startTime = new CalDateTime(2025, 1, 1, 0, 0, 0);
54-
period.StartTime = startTime;
55-
56-
Assert.That(period.StartTime, Is.EqualTo(startTime));
57-
}
45+
Assert.Multiple(() =>
46+
{
47+
// StartTime is null
48+
Assert.Throws<ArgumentNullException>(() => _ = new Period(null!));
5849

59-
[Test]
60-
public void SetEndTime_GetDuration()
61-
{
62-
var period = new Period(new CalDateTime(2025, 1, 1, 0, 0, 0));
63-
var endTime = new CalDateTime(2025, 1, 31, 0, 0, 0);
64-
period.EndTime = endTime;
50+
// EndTime is before StartTime
51+
Assert.Throws<ArgumentException>(() => _ = new Period(
52+
new CalDateTime(2025, 1, 2, 0, 0, 0, "America/New_York"),
53+
new CalDateTime(2025, 1, 1, 0, 0, 0, "America/New_York")));
6554

66-
Assert.That(period.EndTime, Is.EqualTo(endTime));
67-
Assert.That(period.Duration, Is.Null);
68-
Assert.That(period.EffectiveDuration, Is.EqualTo(Duration.FromDays(30)));
69-
Assert.That(period.EffectiveEndTime, Is.EqualTo(endTime));
70-
}
55+
// Duration is negative
56+
Assert.Throws<ArgumentException>(() =>
57+
_ = new Period(new CalDateTime(2025, 1, 1, 0, 0, 0, "America/New_York"), Duration.FromHours(-1)));
7158

72-
[Test]
73-
public void SetDuration_GetEndTime()
74-
{
75-
var period = new Period(new CalDateTime(2025, 1, 1, 0, 0, 0));
76-
var duration = Duration.FromHours(1);
77-
period.Duration = duration;
59+
// Timezones are different
60+
Assert.Throws<ArgumentException>(() => _ = new Period(
61+
new CalDateTime(2025, 1, 2, 0, 0, 0, "America/New_York"),
62+
new CalDateTime(2025, 1, 1, 0, 0, 0, "Europe/Vienna")));
7863

79-
Assert.That(period.Duration, Is.EqualTo(duration));
80-
Assert.That(period.EndTime, Is.Null);
81-
Assert.That(period.EffectiveEndTime, Is.EqualTo(new CalDateTime(2025, 1, 1, 1, 0, 0)));
82-
Assert.That(period.EffectiveDuration, Is.EqualTo(duration));
64+
// StartTime is date-only while EndTime has time
65+
Assert.Throws<ArgumentException>(() => _ = new Period(new CalDateTime(2025, 1, 2, 0, 0, 0),
66+
new CalDateTime(2025, 1, 1)));
67+
});
8368
}
8469

8570
[Test]

Ical.Net.Tests/RecurrenceTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ int eventIndex
6565
// Associate each incoming date/time with the calendar.
6666
expectedPeriods[i].AssociatedObject = cal;
6767

68-
var period = expectedPeriods[i].Copy<Period>();
69-
period.EndTime = period.EffectiveEndTime;
68+
var period = new Period(expectedPeriods[i].StartTime, expectedPeriods[i].EffectiveEndTime) {AssociatedObject = cal};
7069

7170
Assert.That(occurrences[i].Period, Is.EqualTo(period), "Event should occur on " + period);
7271
if (timeZones != null)
@@ -2563,11 +2562,12 @@ public void DurationOfRecurrencesOverDst(string dtStart, string dtEnd, string d1
25632562
.Where(x => x != null)
25642563
.Select(x => (Period)periodSerializer.Deserialize(new StringReader(x)))
25652564
.ToArray();
2566-
2567-
foreach (var p in expectedPeriods)
2565+
2566+
for (var index = 0; index < expectedPeriods.Length; index++)
25682567
{
2569-
p.StartTime = p.StartTime.ToTimeZone(start.TzId);
2570-
p.EndTime = p.StartTime.Add(p.Duration!.Value);
2568+
var p = expectedPeriods[index];
2569+
var newStart = p.StartTime.ToTimeZone(start.TzId);
2570+
expectedPeriods[index] = Period.Create(newStart, end: newStart.Add(p.Duration!.Value));
25712571
}
25722572

25732573
// date only cannot have a time zone

Ical.Net/Collections/PeriodCollectionBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ protected List<PeriodList> ToListOfPeriodList()
134134
/// <param name="tzId">The timezone ID to filter periods by.</param>
135135
/// <returns>An <see cref="IEnumerable{T}"/> of unique <see cref="PeriodKind"/> values that match the specified timezone ID.</returns>
136136
internal IEnumerable<PeriodKind> GetDistinctPeriodKindsByTzId(string? tzId) =>
137-
Periods.Where(p => p.TzId == tzId).Select(p => p.GetPeriodKind()).Distinct();
137+
Periods.Where(p => p.TzId == tzId).Select(p => p.PeriodKind).Distinct();
138138

139139
/// <summary>
140140
/// Gets an <see cref="IEnumerable{T}"/> of periods with the same <see cref="PeriodKind"/> for a given timezone ID.
@@ -143,7 +143,7 @@ internal IEnumerable<PeriodKind> GetDistinctPeriodKindsByTzId(string? tzId) =>
143143
/// <param name="periodKind">The <see cref="PeriodKind"/> to filter periods by.</param>
144144
/// <returns>An <see cref="IEnumerable{T}"/> of periods that match the specified timezone ID and <see cref="PeriodKind"/>.</returns>
145145
internal IEnumerable<Period> GetPeriodsByTzIdAndKind(string? tzId, PeriodKind periodKind) =>
146-
Periods.Where(p => p.TzId == tzId && p.GetPeriodKind() == periodKind);
146+
Periods.Where(p => p.TzId == tzId && p.PeriodKind == periodKind);
147147

148148
/// <inheritdoc/>
149149
[ExcludeFromCodeCoverage]

0 commit comments

Comments
 (0)