Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Build
run: dotnet build --no-restore --configuration Release -p:nowarn=1591
- name: Test
run: dotnet test --no-build --configuration Release --verbosity quiet /p:AltCover=true /p:AltCoverXmlReport="coverage.xml" /p:AltCoverStrongNameKey="../IcalNetStrongnameKey.snk" /p:AltCoverAssemblyExcludeFilter="Ical.Net.Tests|NUnit3.TestAdapter|AltCover" /p:AltCoverAttributeFilter="ExcludeFromCodeCoverage" /p:AltCoverLineCover="false"
run: dotnet test --no-build --configuration Release --verbosity normal /p:AltCover=true /p:AltCoverXmlReport="coverage.xml" /p:AltCoverStrongNameKey="../IcalNetStrongnameKey.snk" /p:AltCoverAssemblyExcludeFilter="Ical.Net.Tests|NUnit3.TestAdapter|AltCover" /p:AltCoverAttributeFilter="ExcludeFromCodeCoverage" /p:AltCoverLineCover="false"

- name: Store coverage report as artifact
uses: actions/upload-artifact@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ jobs:
- name: Build
run: dotnet build --no-restore --configuration Release -p:nowarn=1591
- name: Test
run: dotnet test --no-build --configuration Release --verbosity quiet
run: dotnet test --no-build --configuration Release --verbosity normal
200 changes: 62 additions & 138 deletions Ical.Net.Tests/RecurrenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,30 @@ int eventIndex
.OrderBy(o => o.Period.StartTime)
.ToList();

Assert.That(
occurrences,
Has.Count.EqualTo(dateTimes.Length),
"There should be exactly " + dateTimes.Length + " occurrences; there were " + occurrences.Count);

if (evt.RecurrenceRules.Count > 0)
Assert.Multiple(() =>
{
Assert.That(evt.RecurrenceRules, Has.Count.EqualTo(1));
}
Assert.That(
occurrences,
Has.Count.EqualTo(dateTimes.Length),
"There should have been " + dateTimes.Length + " occurrences; there were " + occurrences.Count);

for (var i = 0; i < dateTimes.Length; i++)
{
// Associate each incoming date/time with the calendar.
dateTimes[i].AssociatedObject = cal;
if (evt.RecurrenceRules.Count > 0)
{
Assert.That(evt.RecurrenceRules, Has.Count.EqualTo(1));
}

for (var i = 0; i < dateTimes.Length; i++)
{
// Associate each incoming date/time with the calendar.
dateTimes[i].AssociatedObject = cal;

var dt = dateTimes[i];
Assert.That(occurrences[i].Period.StartTime, Is.EqualTo(dt), "Event should occur on " + dt);
if (timeZones != null)
Assert.That(dt.TimeZoneName, Is.EqualTo(timeZones[i]), "Event " + dt + " should occur in the " + timeZones[i] + " timezone");
}
var dt = dateTimes[i];
Assert.That(occurrences[i].Period.StartTime, Is.EqualTo(dt), "Event should occur on " + dt);
if (timeZones != null)
Assert.That(dt.TimeZoneName, Is.EqualTo(timeZones[i]),
"Event " + dt + " should occur in the " + timeZones[i] + " timezone");
}
});
}

private void EventOccurrenceTest(
Expand Down Expand Up @@ -1867,134 +1871,55 @@ public void Bug1741093()
);
}

/// <summary>
/// Ensures that, by default, SECONDLY recurrence rules are not allowed.
/// </summary>
[Test, Category("Recurrence")]
public void Secondly1()
{
Assert.That(() =>
{
var iCal = Calendar.Load(IcsFiles.Secondly1);
_ = iCal.GetOccurrences(new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid), new CalDateTime(2007, 7, 21, 8, 0, 0, _tzid));
}, Throws.Exception.TypeOf<ArgumentException>(), "Evaluation engine should have failed.");
}

/// <summary>
/// Ensures that the proper behavior occurs when the evaluation
/// mode is set to adjust automatically for SECONDLY evaluation
/// </summary>
[Test, Category("Recurrence")]
public void Secondly1_1()
public void Secondly_DefinedNumberOfOccurrences_ShouldSucceed()
{
var iCal = Calendar.Load(IcsFiles.Secondly1);
iCal.RecurrenceEvaluationMode = RecurrenceEvaluationModeType.AdjustAutomatically;

EventOccurrenceTest(
iCal,
new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 10, 1, _tzid), // End period is exclusive, not inclusive.
new[]
{
new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 1, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 2, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 3, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 4, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 5, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 6, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 7, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 8, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 9, 0, _tzid),
new CalDateTime(2007, 6, 21, 8, 10, 0, _tzid)
},
null
);
}
var start = new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid);
var end = new CalDateTime(2007, 6, 21, 8, 1, 0, _tzid); // End period is exclusive, not inclusive.

/// <summary>
/// Ensures that if configured, MINUTELY recurrence rules are not allowed.
/// </summary>
[Test, Category("Recurrence")]
public void Minutely1()
{
Assert.That(() =>
var dateTimes = new List<IDateTime>();
for (var dt = start; dt.LessThan(end); dt = (CalDateTime) dt.AddSeconds(1))
{
var iCal = Calendar.Load(IcsFiles.Minutely1);
iCal.RecurrenceRestriction = RecurrenceRestrictionType.RestrictMinutely;
var occurrences = iCal.GetOccurrences(
new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid),
new CalDateTime(2007, 7, 21, 8, 0, 0, _tzid));
}, Throws.Exception.TypeOf<ArgumentException>());
dateTimes.Add(new CalDateTime(dt));
}

EventOccurrenceTest(iCal, start, end, dateTimes.ToArray(), null);
}

/// <summary>
/// Ensures that the proper behavior occurs when the evaluation
/// mode is set to adjust automatically for MINUTELY evaluation
/// </summary>
[Test, Category("Recurrence")]
public void Minutely1_1()
public void Minutely_DefinedNumberOfOccurrences_ShouldSucceed()
{
var iCal = Calendar.Load(IcsFiles.Minutely1);
iCal.RecurrenceRestriction = RecurrenceRestrictionType.RestrictMinutely;
iCal.RecurrenceEvaluationMode = RecurrenceEvaluationModeType.AdjustAutomatically;

EventOccurrenceTest(
iCal,
new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 21, 12, 0, 1, _tzid), // End period is exclusive, not inclusive.
new[]
{
new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 21, 9, 0, 0, _tzid),
new CalDateTime(2007, 6, 21, 10, 0, 0, _tzid),
new CalDateTime(2007, 6, 21, 11, 0, 0, _tzid),
new CalDateTime(2007, 6, 21, 12, 0, 0, _tzid)
},
null
);
}
var start = new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid);
var end = new CalDateTime(2007, 6, 21, 12, 0, 1, _tzid); // End period is exclusive, not inclusive.

/// <summary>
/// Ensures that if configured, HOURLY recurrence rules are not allowed.
/// </summary>
[Test, Category("Recurrence")/*, ExpectedException(typeof(EvaluationEngineException))*/]
public void Hourly1()
{
Assert.That(() =>
var dateTimes = new List<IDateTime>();
for (var dt = start; dt.LessThan(end); dt = (CalDateTime)dt.AddMinutes(1))
{
var iCal = Calendar.Load(IcsFiles.Hourly1);
iCal.RecurrenceRestriction = RecurrenceRestrictionType.RestrictHourly;
_ = iCal.GetOccurrences(new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid), new CalDateTime(2007, 7, 21, 8, 0, 0, _tzid));
dateTimes.Add(new CalDateTime(dt));
}

}, Throws.Exception.TypeOf<ArgumentException>());
EventOccurrenceTest(iCal, start, end, dateTimes.ToArray(), null);
}

/// <summary>
/// Ensures that the proper behavior occurs when the evaluation
/// mode is set to adjust automatically for HOURLY evaluation
/// </summary>
[Test, Category("Recurrence")]
public void Hourly1_1()
public void Hourly_DefinedNumberOfOccurrences_ShouldSucceed()
{
var iCal = Calendar.Load(IcsFiles.Hourly1);
iCal.RecurrenceRestriction = RecurrenceRestrictionType.RestrictHourly;
iCal.RecurrenceEvaluationMode = RecurrenceEvaluationModeType.AdjustAutomatically;

EventOccurrenceTest(
iCal,
new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 25, 8, 0, 1, _tzid), // End period is exclusive, not inclusive.
new[]
{
new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 22, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 23, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 24, 8, 0, 0, _tzid),
new CalDateTime(2007, 6, 25, 8, 0, 0, _tzid)
},
null
);
var start = new CalDateTime(2007, 6, 21, 8, 0, 0, _tzid);
var end = new CalDateTime(2007, 6, 25, 8, 0, 1, _tzid); // End period is exclusive, not inclusive.

var dateTimes = new List<IDateTime>();
for (var dt = start; dt.LessThan(end); dt = (CalDateTime)dt.AddHours(1))
{
dateTimes.Add(new CalDateTime(dt));
}

EventOccurrenceTest(iCal, start, end, dateTimes.ToArray(), null);
}

/// <summary>
Expand Down Expand Up @@ -2038,7 +1963,7 @@ public void YearlyInterval1()
}

/// <summary>
/// Ensures that "off-day" calcuation works correctly
/// Ensures that "off-day" calculation works correctly
/// </summary>
[Test, Category("Recurrence")]
public void DailyInterval1()
Expand Down Expand Up @@ -2841,10 +2766,7 @@ public void Evaluate1(string freq, int secsPerInterval, bool hasTime)

// This case (DTSTART of type DATE and FREQ=MINUTELY) is undefined in RFC 5545.
// ical.net handles the case by pretending DTSTART has the time set to midnight.
evt.RecurrenceRules.Add(new RecurrencePattern($"FREQ={freq};INTERVAL=10;COUNT=5")
{
RestrictionType = RecurrenceRestrictionType.NoRestriction,
});
evt.RecurrenceRules.Add(new RecurrencePattern($"FREQ={freq};INTERVAL=10;COUNT=5"));

var occurrences = evt.GetOccurrences(CalDateTime.Today.AddDays(-1), CalDateTime.Today.AddDays(100))
.OrderBy(x => x)
Expand All @@ -2868,8 +2790,7 @@ public void RecurrencePattern1()
{
// NOTE: evaluators are not generally meant to be used directly like this.
// However, this does make a good test to ensure they behave as they should.
RecurrencePattern pattern = new RecurrencePattern("FREQ=SECONDLY;INTERVAL=10");
pattern.RestrictionType = RecurrenceRestrictionType.NoRestriction;
var pattern = new RecurrencePattern("FREQ=SECONDLY;INTERVAL=10");

var us = new CultureInfo("en-US");

Expand Down Expand Up @@ -3177,10 +3098,14 @@ public void OccurrenceMustBeCompletelyContainedWithinSearchRange()
Assert.That(occurrences.Last().StartTime.Equals(lastExpected), Is.True);
}

[Test, Ignore("Turn on in v3")]
/// <summary>
/// Evaluate relevancy and validity of the request.
/// Find a solution for issue #120 or close forever
/// </summary>
[Test, Ignore("Turn on in v3", Until = "2024-12-31")]
public void EventsWithShareUidsShouldGenerateASingleRecurrenceSet()
{
//https://github.com/rianjs/ical.net/issues/120
//https://github.com/rianjs/ical.net/issues/120 dated Sep 5, 2016
const string ical =
@"BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
Expand Down Expand Up @@ -3757,7 +3682,9 @@ private static IEnumerable<RecurrenceTestCase> TestLibicalTestCasesSource

[TestCaseSource(nameof(TestLibicalTestCasesSource))]
public void TestLibicalTestCases(RecurrenceTestCase testCase)
=> ExecuteRecurrenceTestCase(testCase);
{
ExecuteRecurrenceTestCase(testCase);
}

private static IEnumerable<RecurrenceTestCase> TestFileBasedRecurrenceTestCaseSource
=> ParseTestCaseFile(IcsFiles.RecurrrenceTestCases);
Expand All @@ -3775,10 +3702,7 @@ public void ExecuteRecurrenceTestCase(RecurrenceTestCase testCase)

// Start at midnight, UTC time
evt.Start = testCase.DtStart;
evt.RecurrenceRules.Add(new RecurrencePattern(testCase.RRule)
{
RestrictionType = RecurrenceRestrictionType.NoRestriction,
});
evt.RecurrenceRules.Add(new RecurrencePattern(testCase.RRule));

var occurrences = evt.GetOccurrences(testCase.StartAt?.Value ?? DateTime.MinValue, DateTime.MaxValue)
.OrderBy(x => x)
Expand Down
Loading
Loading