diff --git a/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs b/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs
new file mode 100644
index 0000000000..05515d1491
--- /dev/null
+++ b/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs
@@ -0,0 +1,143 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Tests.Colors
+{
+ using System.Numerics;
+ using Xunit;
+
+ ///
+ /// Test implementations of IEquatable
+ ///
+ public class ColorEqualityTests
+ {
+ public static readonly TheoryData EqualityData =
+ new TheoryData()
+ {
+ { new Alpha8(.5F), new Alpha8(.5F) },
+ { new Argb(Vector4.One), new Argb(Vector4.One) },
+ { new Bgr565(Vector3.One), new Bgr565(Vector3.One) },
+ { new Bgra4444(Vector4.One), new Bgra4444(Vector4.One) },
+ { new Bgra5551(Vector4.One), new Bgra5551(Vector4.One) },
+ { new Byte4(Vector4.One * 255), new Byte4(Vector4.One * 255) },
+ { new HalfSingle(-1F), new HalfSingle(-1F) },
+ { new HalfVector2(0.1f, -0.3f), new HalfVector2(0.1f, -0.3f) },
+ { new HalfVector4(Vector4.One), new HalfVector4(Vector4.One) },
+ { new NormalizedByte2(-Vector2.One), new NormalizedByte2(-Vector2.One) },
+ { new NormalizedByte4(Vector4.One), new NormalizedByte4(Vector4.One) },
+ { new NormalizedShort2(Vector2.One), new NormalizedShort2(Vector2.One) },
+ { new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.One) },
+ { new Rg32(Vector2.One), new Rg32(Vector2.One) },
+ { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.One) },
+ { new Rgba64(Vector4.One), new Rgba64(Vector4.One) },
+ { new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.One * 0x7FFF) },
+ { new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.One * 0x7FFF) },
+ };
+
+ public static readonly TheoryData NotEqualityDataNulls =
+ new TheoryData()
+ {
+ // Valid object against null
+ { new Alpha8(.5F), null },
+ { new Argb(Vector4.One), null },
+ { new Bgr565(Vector3.One), null },
+ { new Bgra4444(Vector4.One), null },
+ { new Bgra5551(Vector4.One), null },
+ { new Byte4(Vector4.One * 255), null },
+ { new HalfSingle(-1F), null },
+ { new HalfVector2(0.1f, -0.3f), null },
+ { new HalfVector4(Vector4.One), null },
+ { new NormalizedByte2(-Vector2.One), null },
+ { new NormalizedByte4(Vector4.One), null },
+ { new NormalizedShort2(Vector2.One), null },
+ { new NormalizedShort4(Vector4.One), null },
+ { new Rg32(Vector2.One), null },
+ { new Rgba1010102(Vector4.One), null },
+ { new Rgba64(Vector4.One), null },
+ { new Short2(Vector2.One * 0x7FFF), null },
+ { new Short4(Vector4.One * 0x7FFF), null },
+ };
+
+ public static readonly TheoryData NotEqualityDataDifferentObjects =
+ new TheoryData()
+ {
+ // Valid objects of different types but not equal
+ { new Alpha8(.5F), new Argb(Vector4.Zero) },
+ { new HalfSingle(-1F), new NormalizedShort2(Vector2.Zero) },
+ { new Rgba1010102(Vector4.One), new Bgra5551(Vector4.Zero) },
+ };
+
+ public static readonly TheoryData NotEqualityData =
+ new TheoryData()
+ {
+ // Valid objects of the same type but not equal
+ { new Alpha8(.5F), new Alpha8(.8F) },
+ { new Argb(Vector4.One), new Argb(Vector4.Zero) },
+ { new Bgr565(Vector3.One), new Bgr565(Vector3.Zero) },
+ { new Bgra4444(Vector4.One), new Bgra4444(Vector4.Zero) },
+ { new Bgra5551(Vector4.One), new Bgra5551(Vector4.Zero) },
+ { new Byte4(Vector4.One * 255), new Byte4(Vector4.Zero * 255) },
+ { new HalfSingle(-1F), new HalfSingle(1F) },
+ { new HalfVector2(0.1f, -0.3f), new HalfVector2(0.1f, 0.3f) },
+ //{ new HalfVector4(Vector4.One), new HalfVector4(Vector4.Zero) }, // same hashcode??
+ { new NormalizedByte2(-Vector2.One), new NormalizedByte2(-Vector2.Zero) },
+ { new NormalizedByte4(Vector4.One), new NormalizedByte4(Vector4.Zero) },
+ { new NormalizedShort2(Vector2.One), new NormalizedShort2(Vector2.Zero) },
+ //{ new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.Zero) }, // same hashcode??
+ { new Rg32(Vector2.One), new Rg32(Vector2.Zero) },
+ { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.Zero) },
+ //{ new Rgba64(Vector4.One), new Rgba64(Vector4.Zero) }, // same hashcode??
+ //{ new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.Zero * 0x7FFF) }, // same hashcode??
+ //{ new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.Zero * 0x7FFF) }, // same hashcode??
+ };
+
+ [Theory]
+ [MemberData("EqualityData")]
+ public void Equality(object first, object second)
+ {
+ // Act
+ var equal = first.Equals(second);
+
+ // Assert
+ Assert.True(equal);
+ }
+
+ [Theory]
+ [MemberData("NotEqualityDataNulls")]
+ [MemberData("NotEqualityDataDifferentObjects")]
+ [MemberData("NotEqualityData")]
+ public void NotEquality(object first, object second)
+ {
+ // Act
+ var equal = first.Equals(second);
+
+ // Assert
+ Assert.False(equal);
+ }
+
+ [Theory]
+ [MemberData("EqualityData")]
+ public void HashCodeEqual(object first, object second)
+ {
+ // Act
+ var equal = first.GetHashCode() == second.GetHashCode();
+
+ // Assert
+ Assert.True(equal);
+ }
+
+ [Theory]
+ [MemberData("NotEqualityData")]
+ [MemberData("NotEqualityDataDifferentObjects")]
+ public void HashCodeNotEqual(object first, object second)
+ {
+ // Act
+ var equal = first.GetHashCode() == second.GetHashCode();
+
+ // Assert
+ Assert.False(equal);
+ }
+ }
+}