Skip to content

Commit

Permalink
Journals, Todos, Events have symmetrical GetHashCode and Equals methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Rian Stockbower committed Apr 28, 2017
1 parent 56414c3 commit 1a7b996
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 29 deletions.
43 changes: 33 additions & 10 deletions net-core/Ical.Net/Ical.Net.UnitTests/EqualityAndHashingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,23 +257,46 @@ public void Resources_Tests()
Assert.IsFalse(serialized.Contains("Hello"));
}

[Test]
public void Attachment_Tests()
internal static (byte[] original, byte[] copy) GetAttachments()
{
var payload = Encoding.UTF8.GetBytes("This is an attachment!");
var payloadCopy = new byte[payload.Length];
Array.Copy(payload, payloadCopy, payload.Length);
return (payload, payloadCopy);
}

[Test, TestCaseSource(nameof(RecurringComponentAttachment_TestCases))]
public void RecurringComponentAttachmentTests(RecurringComponent noAttachment, RecurringComponent withAttachment)
{
var attachments = GetAttachments();

var withAttachment = GetSimpleEvent();
withAttachment.Attachments.Add(new Attachment(payload));
Assert.AreNotEqual(noAttachment, withAttachment);
Assert.AreNotEqual(noAttachment.GetHashCode(), withAttachment.GetHashCode());

var noAttachment = GetSimpleEvent();
Assert.AreNotEqual(withAttachment, noAttachment);
Assert.AreNotEqual(withAttachment.GetHashCode(), noAttachment.GetHashCode());
noAttachment.Attachments.Add(new Attachment(attachments.copy));

noAttachment.Attachments.Add(new Attachment(payloadCopy));
Assert.AreEqual(withAttachment, noAttachment);
Assert.AreEqual(withAttachment.GetHashCode(), noAttachment.GetHashCode());
Assert.AreEqual(noAttachment, withAttachment);
Assert.AreEqual(noAttachment.GetHashCode(), withAttachment.GetHashCode());
}

public static IEnumerable<ITestCaseData> RecurringComponentAttachment_TestCases()
{
var attachments = GetAttachments();

var journalNoAttach = new Journal { Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!" };
var journalWithAttach = new Journal { Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!" };
journalWithAttach.Attachments.Add(new Attachment(attachments.original));
yield return new TestCaseData(journalNoAttach, journalWithAttach).SetName("Journal recurring component attachment");

var todoNoAttach = new Todo { Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!" };
var todoWithAttach = new Todo { Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!" };
todoWithAttach.Attachments.Add(new Attachment(attachments.original));
yield return new TestCaseData(todoNoAttach, todoWithAttach).SetName("Todo recurring component attachment");

var eventNoAttach = GetSimpleEvent();
var eventWithAttach = GetSimpleEvent();
eventWithAttach.Attachments.Add(new Attachment(attachments.original));
yield return new TestCaseData(eventNoAttach, eventWithAttach).SetName("Event recurring component attachment");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.6.0" />
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\antlr.runtime\antlr.runtime.csproj" />
Expand Down
7 changes: 3 additions & 4 deletions net-core/Ical.Net/Ical.Net/Components/CalendarEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ protected bool Equals(CalendarEvent other)
&& Attachments.SequenceEqual(other.Attachments)
&& CollectionHelpers.Equals(ExceptionDates, other.ExceptionDates)
&& CollectionHelpers.Equals(ExceptionRules, other.ExceptionRules)
&& CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, true)
&& CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, true);
&& CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, orderSignificant: true)
&& CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, orderSignificant: true);

return result;
}
Expand All @@ -326,12 +326,11 @@ public override int GetHashCode()
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Resources);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionRules);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceRules);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceRules);
return hashCode;
}
}

public int CompareTo(CalendarEvent other)
{
if (DtStart.Equals(other.DtStart))
Expand Down
17 changes: 16 additions & 1 deletion net-core/Ical.Net/Ical.Net/Components/Journal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,23 @@ private void Initialize()
protected override void OnDeserializing(StreamingContext context)
{
base.OnDeserializing(context);

Initialize();
}

protected bool Equals(Journal other) => Start.Equals(other.Start) && Equals(other as RecurringComponent);

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

public override int GetHashCode()
{
var hashCode = Start?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ base.GetHashCode();
return hashCode;
}
}
}
47 changes: 47 additions & 0 deletions net-core/Ical.Net/Ical.Net/Components/RecurringComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,5 +226,52 @@ public virtual IList<AlarmOccurrence> PollAlarms(IDateTime startTime, IDateTime
}
return occurrences;
}

protected bool Equals(RecurringComponent other)
{
var result = Equals(DtStart, other.DtStart)
&& Equals(Priority, other.Priority)
&& string.Equals(Summary, other.Summary, StringComparison.OrdinalIgnoreCase)
&& string.Equals(Class, other.Class, StringComparison.OrdinalIgnoreCase)
&& string.Equals(Description, other.Description, StringComparison.OrdinalIgnoreCase)
&& Equals(RecurrenceId, other.RecurrenceId)
&& Attachments.SequenceEqual(other.Attachments)
&& CollectionHelpers.Equals(Categories, other.Categories)
&& CollectionHelpers.Equals(Contacts, other.Contacts)
&& CollectionHelpers.Equals(ExceptionDates, other.ExceptionDates)
&& CollectionHelpers.Equals(ExceptionRules, other.ExceptionRules)
&& CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, orderSignificant: true)
&& CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, orderSignificant: true);

return result;
}

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

public override int GetHashCode()
{
unchecked
{
var hashCode = DtStart?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ Priority.GetHashCode();
hashCode = (hashCode * 397) ^ (Summary?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (Class?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (Description?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (RecurrenceId?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Attachments);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Categories);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Contacts);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionRules);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceRules);
return hashCode;
}
}
}
}
43 changes: 33 additions & 10 deletions v2/ical.NET.UnitTests/EqualityAndHashingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,23 +257,46 @@ public void Resources_Tests()
Assert.IsFalse(serialized.Contains("Hello"));
}

[Test]
public void Attachment_Tests()
internal static (byte[] original, byte[] copy) GetAttachments()
{
var payload = Encoding.UTF8.GetBytes("This is an attachment!");
var payloadCopy = new byte[payload.Length];
Array.Copy(payload, payloadCopy, payload.Length);
return (payload, payloadCopy);
}

[Test, TestCaseSource(nameof(RecurringComponentAttachment_TestCases))]
public void RecurringComponentAttachmentTests(RecurringComponent noAttachment, RecurringComponent withAttachment)
{
var attachments = GetAttachments();

var withAttachment = GetSimpleEvent();
withAttachment.Attachments.Add(new Attachment(payload));
Assert.AreNotEqual(noAttachment, withAttachment);
Assert.AreNotEqual(noAttachment.GetHashCode(), withAttachment.GetHashCode());

var noAttachment = GetSimpleEvent();
Assert.AreNotEqual(withAttachment, noAttachment);
Assert.AreNotEqual(withAttachment.GetHashCode(), noAttachment.GetHashCode());
noAttachment.Attachments.Add(new Attachment(attachments.copy));

noAttachment.Attachments.Add(new Attachment(payloadCopy));
Assert.AreEqual(withAttachment, noAttachment);
Assert.AreEqual(withAttachment.GetHashCode(), noAttachment.GetHashCode());
Assert.AreEqual(noAttachment, withAttachment);
Assert.AreEqual(noAttachment.GetHashCode(), withAttachment.GetHashCode());
}

public static IEnumerable<ITestCaseData> RecurringComponentAttachment_TestCases()
{
var attachments = GetAttachments();

var journalNoAttach = new Journal {Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!"};
var journalWithAttach = new Journal {Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!"};
journalWithAttach.Attachments.Add(new Attachment(attachments.original));
yield return new TestCaseData(journalNoAttach, journalWithAttach).SetName("Journal recurring component attachment");

var todoNoAttach = new Todo { Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!" };
var todoWithAttach = new Todo { Start = new CalDateTime(_nowTime), Summary = "A summary!", Class = "Some class!"};
todoWithAttach.Attachments.Add(new Attachment(attachments.original));
yield return new TestCaseData(todoNoAttach, todoWithAttach).SetName("Todo recurring component attachment");

var eventNoAttach = GetSimpleEvent();
var eventWithAttach = GetSimpleEvent();
eventWithAttach.Attachments.Add(new Attachment(attachments.original));
yield return new TestCaseData(eventNoAttach, eventWithAttach).SetName("Event recurring component attachment");
}
}
}
3 changes: 3 additions & 0 deletions v2/ical.NET.UnitTests/Ical.Net.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.3.0\lib\portable-net40+sl4+win8+wp8\System.ValueTuple.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AlarmTest.cs" />
Expand Down
1 change: 1 addition & 0 deletions v2/ical.NET.UnitTests/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
<packages>
<package id="NodaTime" version="1.3.1" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net40" />
<package id="System.ValueTuple" version="4.3.0" targetFramework="net40" />
</packages>
6 changes: 3 additions & 3 deletions v2/ical.NET/Components/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ protected bool Equals(Event other)
&& Attachments.SequenceEqual(other.Attachments)
&& CollectionHelpers.Equals(ExceptionDates, other.ExceptionDates)
&& CollectionHelpers.Equals(ExceptionRules, other.ExceptionRules)
&& CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, true)
&& CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, true);
&& CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, orderSignificant: true)
&& CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, orderSignificant: true);

return result;
}
Expand All @@ -325,8 +325,8 @@ public override int GetHashCode()
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Resources);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionRules);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceRules);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceRules);
return hashCode;
}
}
Expand Down
17 changes: 16 additions & 1 deletion v2/ical.NET/Components/Journal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,23 @@ private void Initialize()
protected override void OnDeserializing(StreamingContext context)
{
base.OnDeserializing(context);

Initialize();
}

protected bool Equals(Journal other) => Start.Equals(other.Start) && Equals(other as RecurringComponent);

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

public override int GetHashCode()
{
var hashCode = Start?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ base.GetHashCode();
return hashCode;
}
}
}
47 changes: 47 additions & 0 deletions v2/ical.NET/Components/RecurringComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,5 +226,52 @@ public virtual IList<AlarmOccurrence> PollAlarms(IDateTime startTime, IDateTime
}
return occurrences;
}

protected bool Equals(RecurringComponent other)
{
var result = Equals(DtStart, other.DtStart)
&& Equals(Priority, other.Priority)
&& string.Equals(Summary, other.Summary, StringComparison.OrdinalIgnoreCase)
&& string.Equals(Class, other.Class, StringComparison.OrdinalIgnoreCase)
&& string.Equals(Description, other.Description, StringComparison.OrdinalIgnoreCase)
&& Equals(RecurrenceId, other.RecurrenceId)
&& Attachments.SequenceEqual(other.Attachments)
&& CollectionHelpers.Equals(Categories, other.Categories)
&& CollectionHelpers.Equals(Contacts, other.Contacts)
&& CollectionHelpers.Equals(ExceptionDates, other.ExceptionDates)
&& CollectionHelpers.Equals(ExceptionRules, other.ExceptionRules)
&& CollectionHelpers.Equals(RecurrenceDates, other.RecurrenceDates, orderSignificant: true)
&& CollectionHelpers.Equals(RecurrenceRules, other.RecurrenceRules, orderSignificant: true);

return result;
}

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

public override int GetHashCode()
{
unchecked
{
var hashCode = DtStart?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ Priority.GetHashCode();
hashCode = (hashCode * 397) ^ (Summary?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (Class?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (Description?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (RecurrenceId?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Attachments);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Categories);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(Contacts);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(ExceptionRules);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceDates);
hashCode = (hashCode * 397) ^ CollectionHelpers.GetHashCode(RecurrenceRules);
return hashCode;
}
}
}
}

0 comments on commit 1a7b996

Please sign in to comment.