diff --git a/src/ParseDiff.Tests/ParseDiff.Tests.csproj b/src/ParseDiff.Tests/ParseDiff.Tests.csproj
index b3631a7..45add9e 100644
--- a/src/ParseDiff.Tests/ParseDiff.Tests.csproj
+++ b/src/ParseDiff.Tests/ParseDiff.Tests.csproj
@@ -53,6 +53,7 @@
+
diff --git a/src/ParseDiff.Tests/TestEquality.cs b/src/ParseDiff.Tests/TestEquality.cs
new file mode 100644
index 0000000..bb1f28d
--- /dev/null
+++ b/src/ParseDiff.Tests/TestEquality.cs
@@ -0,0 +1,179 @@
+namespace ParseDiff.Tests
+{
+
+ using System;
+ using System.Linq;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using static Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
+
+ [TestClass]
+ public class TestEquality
+ {
+ [TestMethod]
+ public void SameDiffShouldBeEqual()
+ {
+ var diff = @"
+diff --git a/file b/file
+index 123..456 789
+--- a/file
++++ b/file
+@@ -1,2 +1,2 @@
+- line1
++ line2";
+
+ var files1 = Diff.Parse(diff, Environment.NewLine).ToArray();
+ var files2 = Diff.Parse(diff, Environment.NewLine).ToArray();
+
+ AreEqual(files1.First(), files2.First());
+ IsTrue(Enumerable.SequenceEqual(files1, files2));
+ }
+
+
+ [TestMethod]
+ public void DifferentDiffShouldNotBeEqual()
+ {
+ var diff1 = @"
+diff --git a/file b/file
+index 123..456 789
+--- a/file
++++ b/file
+@@ -1,2 +1,2 @@
+- line1
++ line2";
+
+ var diff2 = @"
+diff -r 514fc757521e lib/parsers.coffee
+--- a/lib/parsers.coffee Thu Jul 09 00:56:36 2015 +0200
++++ b/lib/parsers.coffee Fri Jul 10 16:23:43 2015 +0200
+@@ -43,6 +43,9 @@
+ files[file] = { added: added, deleted: deleted }
+ files
++ diff: (out) ->
++ files = {}
++
+ module.exports = Parsers
+ module.exports.version = (out) ->
+";
+ var files1 = Diff.Parse(diff1, Environment.NewLine).ToArray();
+ var files2 = Diff.Parse(diff2, Environment.NewLine).ToArray();
+
+ AreNotEqual(files1.First(), files2.First());
+ IsFalse(Enumerable.SequenceEqual(files1, files2));
+ }
+
+ [TestMethod]
+ public void DifferentChunksDiffShouldNotBeEqual()
+ {
+ var diff1 = @"
+diff -r 514fc757521e lib/parsers.coffee
+--- a/lib/parsers.coffee Thu Jul 09 00:56:36 2015 +0200
++++ b/lib/parsers.coffee Fri Jul 10 16:23:43 2015 +0200
+@@ -43,6 +43,9 @@
+ files[file] = { added: added, deleted: deleted }
+ files
++ diff: (out) ->
++ files = {}
++
+ module.exports = Parsers
+ module.exports.version = (out) ->
+";
+
+ var diff2 = @"
+diff -r 514fc757521e lib/parsers.coffee
+--- a/lib/parsers.coffee Thu Jul 09 00:56:36 2015 +0200
++++ b/lib/parsers.coffee Fri Jul 10 16:23:43 2015 +0200
+@@ -43,6 +43,9 @@
+ files[file] = { added: added, deleted: deleted }
+ files
++ diff: (out) ->
++ XXX files = {}
++
+ module.exports = Parsers
+ module.exports.version = (out) ->
+";
+ var files1 = Diff.Parse(diff1, Environment.NewLine).ToArray();
+ var files2 = Diff.Parse(diff2, Environment.NewLine).ToArray();
+
+ AreNotEqual(files1.First(), files2.First());
+ IsFalse(Enumerable.SequenceEqual(files1, files2));
+ }
+
+ [TestMethod]
+ public void RebasedPatchesShouldBeEqual()
+ {
+ var patch1 = @"
+# HG changeset patch
+# User xxx
+# Date 1483371015 -3600
+# Mon Jan 02 16:30:15 2017 +0100
+# Node ID e5c9a138e019a6c2851c2bcd7960046b65c0fa9f
+# Parent b612ff73463ca19be65c7f1235c275bd011a9feb
+Change 111
+
+diff -r b612ff73463c -r e5c9a138e019 1.txt
+--- a/1.txt Thu Dec 22 14:58:46 2016 +0100
++++ b/1.txt Mon Jan 02 16:30:15 2017 +0100
+@@ -1,5 +1,5 @@
+ qwesfsafadsadsadsadsadsad
+-zxcxzczxcxc
++zxCHANGEzxcxc
+
+
+xxx
+";
+ var patch2 = @"
+# HG changeset patch
+# User xxx
+# Date 1483371015 -3600
+# Mon Jan 02 16:30:15 2017 +0100
+# Node ID 43339e170990fe2873b2866d5d916b6ec3ae0956
+# Parent 4afd4b93aa45455be267d5e4541094daea9b02f3
+Change 111
+
+diff -r 4afd4b93aa45 -r 43339e170990 1.txt
+--- a/1.txt Thu Dec 22 14:59:09 2016 +0100
++++ b/1.txt Mon Jan 02 16:30:15 2017 +0100
+@@ -1,5 +1,5 @@
+ qwesfsafadsadsadsadsadsad
+-zxcxzczxcxc
++zxCHANGEzxcxc
+
+
+xxx
+";
+
+ var files1 = Diff.Parse(patch1).ToArray();
+ var files2 = Diff.Parse(patch2).ToArray();
+
+ AreEqual(files1.First(), files2.First());
+ IsTrue(Enumerable.SequenceEqual(files1, files2));
+ }
+
+ [TestMethod]
+ public void DifferentIndexesShouldNotBeEqual()
+ {
+ var diffWithIndexLine = @"
+diff --git a/file b/file
+index 123..456 789
+--- a/file
++++ b/file
+@@ -1,2 +1,2 @@
+- line1
++ line2";
+ var diffWithNoIndexLine = @"
+diff --git a/file b/file
+--- a/file
++++ b/file
+@@ -1,2 +1,2 @@
+- line1
++ line2";
+
+ var files1 = Diff.Parse(diffWithIndexLine, Environment.NewLine).ToArray();
+ var files2 = Diff.Parse(diffWithNoIndexLine, Environment.NewLine).ToArray();
+
+ AreNotEqual(files1.First(), files2.First());
+ AreNotEqual(files2.First(), files1.First());
+ IsFalse(Enumerable.SequenceEqual(files1, files2));
+ }
+ }
+}
diff --git a/src/ParseDiff/ChunkDiff.cs b/src/ParseDiff/ChunkDiff.cs
index e8b3a34..5d22c14 100644
--- a/src/ParseDiff/ChunkDiff.cs
+++ b/src/ParseDiff/ChunkDiff.cs
@@ -1,8 +1,10 @@
namespace ParseDiff
{
+ using System;
using System.Collections.Generic;
+ using System.Linq;
- public class ChunkDiff
+ public class ChunkDiff : IEquatable
{
public ChunkDiff(string content, int oldStart, int oldLines, int newStart, int newLines)
{
@@ -24,5 +26,36 @@ public ChunkDiff(string content, int oldStart, int oldLines, int newStart, int n
public int NewStart { get; }
public int NewLines { get; }
+
+ public bool Equals(ChunkDiff other)
+ {
+ return
+ Equals(Content, other.Content) &&
+ Equals(OldStart, other.OldStart) &&
+ Equals(OldLines, other.OldLines) &&
+ Equals(NewStart, other.NewStart) &&
+ Equals(NewLines, other.NewLines) &&
+ Enumerable.SequenceEqual(Changes, other.Changes);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as ChunkDiff);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hash = 17;
+ hash = hash * 23 + Content?.GetHashCode() ?? 0;
+ hash = hash * 23 + OldStart;
+ hash = hash * 23 + OldLines;
+ hash = hash * 23 + NewStart;
+ hash = hash * 23 + NewLines;
+ hash = hash * 23 + Changes.GetHashCode();
+ return hash;
+ }
+ }
}
}
diff --git a/src/ParseDiff/FileDiff.cs b/src/ParseDiff/FileDiff.cs
index 1ac809c..f6376f8 100644
--- a/src/ParseDiff/FileDiff.cs
+++ b/src/ParseDiff/FileDiff.cs
@@ -5,7 +5,7 @@
using System.Linq;
using System.Text.RegularExpressions;
- public class FileDiff
+ public class FileDiff : IEquatable
{
public ICollection Chunks { get; } = new List();
@@ -188,5 +188,46 @@ private static string parseFileFallback(string s)
? s.Substring(2)
: s;
}
+
+ public bool Equals(FileDiff other)
+ {
+ return
+ Equals(Deletions, other.Deletions) &&
+ Equals(Additions, other.Additions) &&
+ Equals(To, other.To) &&
+ Equals(From, other.From) &&
+ Equals(Type, other.Type) &&
+ IndexEquals(other.Index) &&
+ Enumerable.SequenceEqual(Chunks, other.Chunks);
+ }
+
+ private bool IndexEquals(IEnumerable otherIndex)
+ {
+ return
+ Index == null
+ ? otherIndex == null
+ : (otherIndex != null && Enumerable.SequenceEqual(Index, otherIndex));
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as FileDiff);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hash = 17;
+ hash = hash * 23 + Deletions;
+ hash = hash * 23 + Additions;
+ hash = hash * 23 + To?.GetHashCode() ?? 0;
+ hash = hash * 23 + From?.GetHashCode() ?? 0;
+ hash = hash * 23 + Type.GetHashCode();
+ hash = hash * 23 + Index?.GetHashCode() ?? 0;
+ hash = hash * 23 + Chunks.GetHashCode();
+ return hash;
+ }
+ }
}
}
diff --git a/src/ParseDiff/LineDiff.cs b/src/ParseDiff/LineDiff.cs
index fac8f62..f97fb44 100644
--- a/src/ParseDiff/LineDiff.cs
+++ b/src/ParseDiff/LineDiff.cs
@@ -1,6 +1,8 @@
namespace ParseDiff
{
- public class LineDiff
+ using System;
+
+ public class LineDiff : IEquatable
{
public LineDiff(LineChangeType type, int index, string content)
{
@@ -32,5 +34,34 @@ public LineDiff(int oldIndex, int newIndex, string content)
public int NewIndex { get; }
public LineChangeType Type { get; }
+
+ public bool Equals(LineDiff other)
+ {
+ return
+ Equals(Content, other.Content) &&
+ Equals(Index, other.Index) &&
+ Equals(OldIndex, other.OldIndex) &&
+ Equals(NewIndex, other.NewIndex) &&
+ Equals(Type, other.Type);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as LineDiff);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hash = 17;
+ hash = hash * 23 + Content?.GetHashCode() ?? 0;
+ hash = hash * 23 + Index;
+ hash = hash * 23 + OldIndex;
+ hash = hash * 23 + NewIndex;
+ hash = hash * 23 + Type.GetHashCode();
+ return hash;
+ }
+ }
}
}