Skip to content

Commit

Permalink
Merge pull request #185 from rianjs/PeriodSortingAndEquality
Browse files Browse the repository at this point in the history
Fixed some bugs when comparing collections of periods (PeriodList) and
  • Loading branch information
rianjs authored Oct 24, 2016
2 parents 62419bc + 0ddc812 commit f1002f1
Show file tree
Hide file tree
Showing 29 changed files with 339 additions and 90 deletions.
2 changes: 1 addition & 1 deletion v2/Ical.Net.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Ical.Net</id>
<version>2.2.18</version>
<version>2.2.19</version>
<title>Ical.Net</title>
<authors>Rian Stockbower, Douglas Day, M. David Peterson</authors>
<owners>Rian Stockbower</owners>
Expand Down
1 change: 0 additions & 1 deletion v2/ical.NET.UnitTests/AttendeeTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Ical.Net.DataTypes;
using Ical.Net.Serialization;
using Ical.Net.Serialization.iCalendar.Serializers;
using NUnit.Framework;
using System;
Expand Down
34 changes: 34 additions & 0 deletions v2/ical.NET.UnitTests/CollectionHelpersTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Ical.Net.DataTypes;
using Ical.Net.Interfaces.DataTypes;
using NUnit.Framework;

namespace Ical.Net.UnitTests
{
internal class CollectionHelpersTests
{
private static readonly DateTime _now = DateTime.UtcNow;
private static readonly DateTime _later = _now.AddHours(1);
private static readonly string _uid = Guid.NewGuid().ToString();

private static List<IRecurrencePattern> GetSimpleRecurrenceList()
=> new List<IRecurrencePattern> { new RecurrencePattern(FrequencyType.Daily, 1) { Count = 5 } };
private static List<IPeriodList> GetExceptionDates()
=> new List<IPeriodList> { new PeriodList { new Period(new CalDateTime(_now.AddDays(1).Date)) } };

[Test]
public void ExDateTests()
{
Assert.AreEqual(GetExceptionDates(), GetExceptionDates());
Assert.AreNotEqual(GetExceptionDates(), null);
Assert.AreNotEqual(null, GetExceptionDates());

var changedPeriod = GetExceptionDates();
changedPeriod.First().First().StartTime = new CalDateTime(_now.AddHours(-1));

Assert.AreNotEqual(GetExceptionDates(), changedPeriod);
}
}
}
65 changes: 64 additions & 1 deletion v2/ical.NET.UnitTests/EventTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.IO;
using System.Linq;
using Ical.Net.Interfaces.DataTypes;
using NUnit.Framework.Internal;
using Ical.Net.Serialization.iCalendar.Serializers;

namespace Ical.Net.UnitTests
{
Expand All @@ -16,6 +16,7 @@ public class EventTest
{
private static readonly DateTime _now = DateTime.UtcNow;
private static readonly DateTime _later = _now.AddHours(1);
private static readonly string _uid = Guid.NewGuid().ToString();

/// <summary>
/// Ensures that events can be properly added to a calendar.
Expand Down Expand Up @@ -222,6 +223,7 @@ public void EventWithExDateShouldNotBeEqualToSameEventWithoutExDate()
{
DtStart = new CalDateTime(_now),
DtEnd = new CalDateTime(_later),
Uid = _uid,
};

[Test]
Expand All @@ -240,5 +242,66 @@ public void RrulesAreSignificantTests()
Assert.AreNotEqual(simpleEvent, testRdate);
Assert.AreNotEqual(simpleEvent.GetHashCode(), testRdate.GetHashCode());
}

private static List<IRecurrencePattern> GetSimpleRecurrenceList()
=> new List<IRecurrencePattern> {new RecurrencePattern(FrequencyType.Daily, 1) {Count = 5}};
private static List<IPeriodList> GetExceptionDates()
=> new List<IPeriodList> { new PeriodList { new Period(new CalDateTime(_now.AddDays(1).Date)) } };

[Test]
public void EventWithRecurrenceAndExceptionComparison()
{
var vEvent = GetSimpleEvent();
vEvent.RecurrenceRules = GetSimpleRecurrenceList();
vEvent.ExceptionDates = GetExceptionDates();

var calendar = new Calendar();
calendar.Events.Add(vEvent);

var vEvent2 = GetSimpleEvent();
vEvent2.RecurrenceRules = GetSimpleRecurrenceList();
vEvent2.ExceptionDates = GetExceptionDates();

var cal2 = new Calendar();
cal2.Events.Add(vEvent2);

var eventA = calendar.Events.First();
var eventB = cal2.Events.First();

Assert.AreEqual(eventA.RecurrenceRules.First(), eventB.RecurrenceRules.First());
Assert.AreEqual(eventA.RecurrenceRules.First().GetHashCode(), eventB.RecurrenceRules.First().GetHashCode());
Assert.AreEqual(eventA.ExceptionDates.First(), eventB.ExceptionDates.First());
Assert.AreEqual(eventA.ExceptionDates.First().GetHashCode(), eventB.ExceptionDates.First().GetHashCode());
Assert.AreEqual(eventA.GetHashCode(), eventB.GetHashCode());
Assert.AreEqual(eventA, eventB);
Assert.AreEqual(calendar, cal2);
}

[Test]
public void AddingExdateToEventShouldNotBeEqualToOriginal()
{
//Create a calendar with an event with a recurrence rule
//Serialize to string, and deserialize
//Change the original calendar.Event to have an ExDate
//Serialize to string, and deserialize
//Event and Calendar hash codes and equality should NOT be the same
var serializer = new CalendarSerializer();

var vEvent = GetSimpleEvent();
vEvent.RecurrenceRules = GetSimpleRecurrenceList();
var cal1 = new Calendar();
cal1.Events.Add(vEvent);
var serialized = serializer.SerializeToString(cal1);
var deserializedNoExDate = Calendar.LoadFromStream(new StringReader(serialized)).First() as Calendar;
Assert.AreEqual(cal1, deserializedNoExDate);

vEvent.ExceptionDates = GetExceptionDates();
serialized = serializer.SerializeToString(cal1);
var deserializedWithExDate = Calendar.LoadFromStream(new StringReader(serialized)).First() as Calendar;

Assert.AreNotEqual(deserializedNoExDate.Events.First(), deserializedWithExDate.Events.First());
Assert.AreNotEqual(deserializedNoExDate.Events.First().GetHashCode(), deserializedWithExDate.Events.First().GetHashCode());
Assert.AreNotEqual(deserializedNoExDate, deserializedWithExDate);
}
}
}
1 change: 1 addition & 0 deletions v2/ical.NET.UnitTests/Ical.Net.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
<Compile Include="AlarmTest.cs" />
<Compile Include="AttendeeTest.cs" />
<Compile Include="CalendarPropertiesTest.cs" />
<Compile Include="CollectionHelpersTests.cs" />
<Compile Include="ComponentTest.cs" />
<Compile Include="ConcurrentDeserializationTests.cs" />
<Compile Include="DateTimeSerializerTests.cs" />
Expand Down
2 changes: 0 additions & 2 deletions v2/ical.NET.UnitTests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
using System.Linq;
using System.Text.RegularExpressions;
using Ical.Net.DataTypes;
using Ical.Net.ExtensionMethods;
using Ical.Net.Interfaces;
using Ical.Net.Interfaces.Components;
using Ical.Net.Interfaces.DataTypes;
using Ical.Net.Serialization;
using Ical.Net.Serialization.iCalendar.Serializers;
using Ical.Net.Serialization.iCalendar.Serializers.Other;
using Ical.Net.UnitTests.ExtensionMethods;
Expand Down
12 changes: 6 additions & 6 deletions v2/ical.NET/Calendar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,12 @@ protected override void OnDeserializing(StreamingContext context)
protected bool Equals(Calendar other)
{
return string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase)
&& UniqueComponents.SequenceEqual(other.UniqueComponents)
&& Events.SequenceEqual(other.Events)
&& Todos.SequenceEqual(other.Todos)
&& Journals.SequenceEqual(other.Journals)
&& FreeBusy.SequenceEqual(other.FreeBusy)
&& TimeZones.SequenceEqual(other.TimeZones);
&& CollectionHelpers.Equals(UniqueComponents, other.UniqueComponents)
&& CollectionHelpers.Equals(Events, other.Events)
&& CollectionHelpers.Equals(Todos, other.Todos)
&& CollectionHelpers.Equals(Journals, other.Journals)
&& CollectionHelpers.Equals(FreeBusy, other.FreeBusy)
&& CollectionHelpers.Equals(TimeZones, other.TimeZones);
}

public override bool Equals(object obj)
Expand Down
10 changes: 2 additions & 8 deletions v2/ical.NET/CalendarCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,9 @@ public IFreeBusy GetFreeBusy(IOrganizer organizer, IAttendee[] contacts, IDateTi
return this.Aggregate<ICalendar, IFreeBusy>(null, (current, iCal) => CombineFreeBusy(current, iCal.GetFreeBusy(organizer, contacts, fromInclusive, toExclusive)));
}

public override int GetHashCode()
{
return CollectionHelpers.GetHashCode(this);
}
public override int GetHashCode() => CollectionHelpers.GetHashCode(this);

protected bool Equals(CalendarCollection obj)
{
return this.SequenceEqual(obj);
}
protected bool Equals(CalendarCollection obj) => CollectionHelpers.Equals(this, obj);

public override bool Equals(object obj)
{
Expand Down
27 changes: 22 additions & 5 deletions v2/ical.NET/Components/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace Ical.Net
/// <item>Create a TextCollection DataType for 'text' items separated by commas</item>
/// </list>
/// </note>
public class Event : RecurringComponent, IEvent
public class Event : RecurringComponent, IEvent, IComparable<Event>
{
internal const string ComponentName = "VEVENT";

Expand Down Expand Up @@ -295,10 +295,10 @@ protected bool Equals(Event other)
&& Transparency.Equals(other.Transparency)
&& EvaluationIncludesReferenceDate == other.EvaluationIncludesReferenceDate
&& Attachments.SequenceEqual(other.Attachments)
&& (ExceptionDates != null && CollectionHelpers.Equals(ExceptionDates, other.ExceptionDates))
&& (ExceptionRules != null && CollectionHelpers.Equals(ExceptionRules, other.ExceptionRules))
&& (RecurrenceRules != null && CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, true))
&& (RecurrenceDates != null && CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, true));
&& CollectionHelpers.Equals(ExceptionDates, other.ExceptionDates)
&& CollectionHelpers.Equals(ExceptionRules, other.ExceptionRules)
&& CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, true)
&& CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, true);

return result;
}
Expand Down Expand Up @@ -329,5 +329,22 @@ public override int GetHashCode()
return hashCode;
}
}

public int CompareTo(Event other)
{
if (DtStart.Equals(other.DtStart))
{
return 0;
}
if (DtStart.LessThan(other.DtStart))
{
return -1;
}
if (DtStart.GreaterThan(other.DtStart))
{
return 1;
}
throw new Exception("An error occurred while comparing two CalDateTimes.");
}
}
}
9 changes: 4 additions & 5 deletions v2/ical.NET/Components/UniqueComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Ical.Net
/// Represents a unique component, a component with a unique UID,
/// which can be used to uniquely identify the component.
/// </summary>
public class UniqueComponent : CalendarComponent, IUniqueComponent
public class UniqueComponent : CalendarComponent, IUniqueComponent, IComparable<UniqueComponent>
{
// TODO: Add AddRelationship() public method.
// This method will add the UID of a related component
Expand Down Expand Up @@ -93,6 +93,8 @@ protected override void OnDeserialized(StreamingContext context)
EnsureProperties();
}

public int CompareTo(UniqueComponent other) => string.Compare(Uid, other.Uid, StringComparison.OrdinalIgnoreCase);

public override bool Equals(object obj)
{
if (obj is RecurringComponent && obj != this)
Expand All @@ -107,10 +109,7 @@ public override bool Equals(object obj)
return base.Equals(obj);
}

public override int GetHashCode()
{
return Uid?.GetHashCode() ?? base.GetHashCode();
}
public override int GetHashCode() => Uid?.GetHashCode() ?? base.GetHashCode();

public virtual string Uid
{
Expand Down
19 changes: 18 additions & 1 deletion v2/ical.NET/DataTypes/Period.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace Ical.Net.DataTypes
{
/// <summary> Represents an iCalendar period of time. </summary>
public class Period : EncodableDataType, IPeriod
public class Period : EncodableDataType, IPeriod, IComparable<Period>
{
public Period() { }

Expand Down Expand Up @@ -84,6 +84,23 @@ public override int GetHashCode()
}
}

public int CompareTo(Period other)
{
if (StartTime.Equals(other.StartTime))
{
return 0;
}
if (StartTime.LessThan(other.StartTime))
{
return -1;
}
if (StartTime.GreaterThan(other.StartTime))
{
return 1;
}
throw new Exception("An error occurred while comparing two Periods.");
}

public override string ToString()
{
var periodSerializer = new PeriodSerializer();
Expand Down
10 changes: 5 additions & 5 deletions v2/ical.NET/DataTypes/PeriodList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Ical.Net.Interfaces.DataTypes;
using Ical.Net.Interfaces.General;
using Ical.Net.Serialization.iCalendar.Serializers.DataTypes;
using Ical.Net.Utility;

namespace Ical.Net.DataTypes
{
Expand All @@ -18,7 +19,6 @@ public class PeriodList : EncodableDataType, IPeriodList

protected IList<IPeriod> Periods { get; set; } = new List<IPeriod>(64);


public PeriodList()
{
SetService(new PeriodListEvaluator(this));
Expand All @@ -32,22 +32,22 @@ public PeriodList(string value) : this()

protected bool Equals(PeriodList other)
{
return Equals(Periods, other.Periods) && string.Equals(TzId, other.TzId);
return string.Equals(TzId, other.TzId) && CollectionHelpers.Equals(Periods, other.Periods);
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((PeriodList)obj);
if (obj.GetType() != this.GetType()) return false;
return Equals((PeriodList) obj);
}

public override int GetHashCode()
{
unchecked
{
return ((Periods?.GetHashCode() ?? 0) * 397) ^ (TzId?.GetHashCode() ?? 0);
return ((TzId?.GetHashCode() ?? 0) * 397) ^ CollectionHelpers.GetHashCode(Periods);
}
}

Expand Down
1 change: 0 additions & 1 deletion v2/ical.NET/General/CalendarProperty.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Ical.Net.ExtensionMethods;
using Ical.Net.Interfaces.General;

namespace Ical.Net.General
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Linq;
using System.Text.RegularExpressions;
using Ical.Net.DataTypes;
using Ical.Net.ExtensionMethods;
using Ical.Net.Interfaces.DataTypes;
using Ical.Net.Interfaces.Serialization;
using Ical.Net.Interfaces.Serialization.Factory;
Expand Down
Loading

0 comments on commit f1002f1

Please sign in to comment.