|
|
|
@ -7,6 +7,7 @@ namespace ImageSharp.Tests.Colors |
|
|
|
{ |
|
|
|
using System; |
|
|
|
using System.Numerics; |
|
|
|
using ImageSharp.Colors.Spaces; |
|
|
|
using Xunit; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -37,6 +38,38 @@ namespace ImageSharp.Tests.Colors |
|
|
|
{ new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.One * 0x7FFF), typeof(Short4) }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type> EqualityDataColorSpaces = |
|
|
|
new TheoryData<object, object, Type>() |
|
|
|
{ |
|
|
|
{ new Bgra32(0, 0, 0), new Bgra32(0, 0, 0), typeof(Bgra32) }, |
|
|
|
{ new Bgra32(0, 0, 0, 0), new Bgra32(0, 0, 0, 0), typeof(Bgra32) }, |
|
|
|
{ new Bgra32(100, 100, 0, 0), new Bgra32(100, 100, 0, 0), typeof(Bgra32) }, |
|
|
|
{ new Bgra32(255, 255, 255), new Bgra32(255, 255, 255), typeof(Bgra32) }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab) }, |
|
|
|
{ new CieLab(1f, 1f, 1f), new CieLab(1f, 1f, 1f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, -100f, -100f), new CieLab(0f, -100f, -100f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, 100f, -100f), new CieLab(0f, 100f, -100f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, -100f, 100f), new CieLab(0f, -100f, 100f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, -100f, 50f), new CieLab(0f, -100f, 50f), typeof(CieLab) }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380f), typeof(CieXyz) }, |
|
|
|
{ new CieXyz(780f, 780f, 780f), new CieXyz(780f, 780f, 780f), typeof(CieXyz) }, |
|
|
|
{ new CieXyz(380f, 780f, 780f), new CieXyz(380f, 780f, 780f), typeof(CieXyz) }, |
|
|
|
{ new CieXyz(50f, 20f, 60f), new CieXyz(50f, 20f, 60f), typeof(CieXyz) }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0f), typeof(Cmyk) }, |
|
|
|
{ new Cmyk(1f, 1f, 1f, 1f), new Cmyk(1f, 1f, 1f, 1f), typeof(Cmyk) }, |
|
|
|
{ new Cmyk(10f, 10f, 10f, 10f), new Cmyk(10f, 10f, 10f, 10f), typeof(Cmyk) }, |
|
|
|
{ new Cmyk(.4f, .5f, .1f, .2f), new Cmyk(.4f, .5f, .1f, .2f), typeof(Cmyk) }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0f), typeof(Hsl) }, |
|
|
|
{ new Hsl(360f, 1f, 1f), new Hsl(360f, 1f, 1f), typeof(Hsl) }, |
|
|
|
{ new Hsl(100f, .5f, .1f), new Hsl(100f, .5f, .1f), typeof(Hsl) }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0f), typeof(Hsv) }, |
|
|
|
{ new Hsv(360f, 1f, 1f), new Hsv(360f, 1f, 1f), typeof(Hsv) }, |
|
|
|
{ new Hsv(100f, .5f, .1f), new Hsv(100f, .5f, .1f), typeof(Hsv) }, |
|
|
|
{ new YCbCr(0, 0, 0), new YCbCr(0, 0, 0), typeof(YCbCr) }, |
|
|
|
{ new YCbCr(255, 255, 255), new YCbCr(255, 255, 255), typeof(YCbCr) }, |
|
|
|
{ new YCbCr(100, 100, 0), new YCbCr(100, 100, 0), typeof(YCbCr) }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type> NotEqualityDataNulls = |
|
|
|
new TheoryData<object, object, Type>() |
|
|
|
{ |
|
|
|
@ -61,6 +94,18 @@ namespace ImageSharp.Tests.Colors |
|
|
|
{ new Short4(Vector4.One * 0x7FFF), null, typeof(Short4) }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type> NotEqualityDataNullsColorSpaces = |
|
|
|
new TheoryData<object, object, Type>() |
|
|
|
{ |
|
|
|
{ new Bgra32(0, 0, 0), null, typeof(Bgra32) }, |
|
|
|
{ new CieLab(0f, 0f, 0f), null, typeof(CieLab) }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), null, typeof(CieXyz) }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), null, typeof(Cmyk) }, |
|
|
|
{ new Hsl(0f, 0f, 0f), null, typeof(Hsl) }, |
|
|
|
{ new Hsv(360f, 1f, 1f), null, typeof(Hsv) }, |
|
|
|
{ new YCbCr(0, 0, 0), null, typeof(YCbCr) }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type> NotEqualityDataDifferentObjects = |
|
|
|
new TheoryData<object, object, Type>() |
|
|
|
{ |
|
|
|
@ -70,6 +115,16 @@ namespace ImageSharp.Tests.Colors |
|
|
|
{ new Rgba1010102(Vector4.One), new Bgra5551(Vector4.Zero), null }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type> NotEqualityDataDifferentObjectsColorSpaces = |
|
|
|
new TheoryData<object, object, Type>() |
|
|
|
{ |
|
|
|
// Valid objects of different types but not equal
|
|
|
|
{ new Bgra32(0, 0, 0), new CieLab(0f, 0f, 0f), null }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new Cmyk(0f, 0f, 0f, 0f), null }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsv(360f, 1f, 1f), null }, |
|
|
|
{ new YCbCr(0, 0, 0), new Hsv(360f, 1f, 1f), null }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type> NotEqualityData = |
|
|
|
new TheoryData<object, object, Type>() |
|
|
|
{ |
|
|
|
@ -94,8 +149,92 @@ namespace ImageSharp.Tests.Colors |
|
|
|
{ new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.Zero), typeof(Short4) }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type> NotEqualityDataColorSpaces = |
|
|
|
new TheoryData<object, object, Type>() |
|
|
|
{ |
|
|
|
{ new Bgra32(0, 0, 0), new Bgra32(0, 1, 0), typeof(Bgra32) }, |
|
|
|
{ new Bgra32(0, 0, 0, 0), new Bgra32(0, 1, 0, 0), typeof(Bgra32) }, |
|
|
|
{ new Bgra32(100, 100, 0, 0), new Bgra32(100, 0, 0, 0), typeof(Bgra32) }, |
|
|
|
{ new Bgra32(255, 255, 255), new Bgra32(255, 0, 255), typeof(Bgra32) }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 1f, 0f), typeof(CieLab) }, |
|
|
|
{ new CieLab(1f, 1f, 1f), new CieLab(1f, 0f, 1f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, -100f, -100f), new CieLab(0f, 100f, -100f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, 100f, -100f), new CieLab(0f, -100f, -100f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, -100f, 100f), new CieLab(0f, 100f, 100f), typeof(CieLab) }, |
|
|
|
{ new CieLab(0f, -100f, 50f), new CieLab(0f, 100f, 20f), typeof(CieLab) }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 0f, 380f), typeof(CieXyz) }, |
|
|
|
{ new CieXyz(780f, 780f, 780f), new CieXyz(780f, 0f, 780f), typeof(CieXyz) }, |
|
|
|
{ new CieXyz(380f, 780f, 780f), new CieXyz(380f, 0f, 780f), typeof(CieXyz) }, |
|
|
|
{ new CieXyz(50f, 20f, 60f), new CieXyz(50f, 0f, 60f), typeof(CieXyz) }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 1f, 0f, 0f), typeof(Cmyk) }, |
|
|
|
{ new Cmyk(1f, 1f, 1f, 1f), new Cmyk(1f, 1f, 0f, 1f), typeof(Cmyk) }, |
|
|
|
{ new Cmyk(10f, 10f, 10f, 10f), new Cmyk(10f, 10f, 0f, 10f), typeof(Cmyk) }, |
|
|
|
{ new Cmyk(.4f, .5f, .1f, .2f), new Cmyk(.4f, .5f, 5f, .2f), typeof(Cmyk) }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 5f, 0f), typeof(Hsl) }, |
|
|
|
{ new Hsl(360f, 1f, 1f), new Hsl(360f, .5f, 1f), typeof(Hsl) }, |
|
|
|
{ new Hsl(100f, .5f, .1f), new Hsl(100f, 9f, .1f), typeof(Hsl) }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 1f, 0f), typeof(Hsv) }, |
|
|
|
{ new Hsv(360f, 1f, 1f), new Hsv(0f, 1f, 1f), typeof(Hsv) }, |
|
|
|
{ new Hsv(100f, .5f, .1f), new Hsv(2f, .5f, .1f), typeof(Hsv) }, |
|
|
|
{ new YCbCr(0, 0, 0), new YCbCr(0, 1, 0), typeof(YCbCr) }, |
|
|
|
{ new YCbCr(255, 255, 255), new YCbCr(255, 0, 255), typeof(YCbCr) }, |
|
|
|
{ new YCbCr(100, 100, 0), new YCbCr(100, 20, 0), typeof(YCbCr) }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type, float> AlmostEqualsData = |
|
|
|
new TheoryData<object, object, Type, float>() |
|
|
|
{ |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), 0f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), .001f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), .0001f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), .0005f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, .001f, 0f), typeof(CieLab), .001f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, .0001f), typeof(CieLab), .0001f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(.0005f, 0f, 0f), typeof(CieLab), .0005f }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380f), typeof(CieXyz), 0f }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380.001f, 380f, 380f), typeof(CieXyz), .01f }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380.001f, 380f), typeof(CieXyz), .01f }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380.001f), typeof(CieXyz), .01f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0f), typeof(Cmyk), 0f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0.001f, 0f, 0f, 0f), typeof(Cmyk), .01f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0.001f, 0f, 0f), typeof(Cmyk), .01f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0.001f, 0f), typeof(Cmyk), .01f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0.001f), typeof(Cmyk), .01f }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0f), typeof(Hsl), 0f }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0.001f, 0f, 0f), typeof(Hsl), .01f }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0.001f, 0f), typeof(Hsl), .01f }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0.001f), typeof(Hsl), .01f }, |
|
|
|
{ new Hsv(360f, 1f, 1f), new Hsv(360f, 1f, 1f), typeof(Hsv), 0f }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0f), typeof(Hsv), 0f }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0.001f, 0f, 0f), typeof(Hsv), .01f }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0.001f, 0f), typeof(Hsv), .01f }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0.001f), typeof(Hsv), .01f }, |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object, object, Type, float> AlmostNotEqualsData = |
|
|
|
new TheoryData<object, object, Type, float>() |
|
|
|
{ |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0.1f, 0f, 0f), typeof(CieLab), .001f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0.1f, 0f), typeof(CieLab), .001f }, |
|
|
|
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0.1f), typeof(CieLab), .001f }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380.1f, 380f, 380f), typeof(CieXyz), .001f }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380.1f, 380f), typeof(CieXyz), .001f }, |
|
|
|
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380.1f), typeof(CieXyz), .001f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0.1f, 0f, 0f, 0f), typeof(Cmyk), .001f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0.1f, 0f, 0f), typeof(Cmyk), .001f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0.1f, 0f), typeof(Cmyk), .001f }, |
|
|
|
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0.1f), typeof(Cmyk), .001f }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0.1f, 0f, 0f), typeof(Hsl), .001f }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0.1f, 0f), typeof(Hsl), .001f }, |
|
|
|
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0.1f), typeof(Hsl), .001f }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0.1f, 0f, 0f), typeof(Hsv), .001f }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0.1f, 0f), typeof(Hsv), .001f }, |
|
|
|
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0.1f), typeof(Hsv), .001f }, |
|
|
|
}; |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(EqualityData))] |
|
|
|
[MemberData(nameof(EqualityDataColorSpaces))] |
|
|
|
public void Equality(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Act
|
|
|
|
@ -107,8 +246,11 @@ namespace ImageSharp.Tests.Colors |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(NotEqualityDataNulls))] |
|
|
|
[MemberData(nameof(NotEqualityDataNullsColorSpaces))] |
|
|
|
[MemberData(nameof(NotEqualityDataDifferentObjects))] |
|
|
|
[MemberData(nameof(NotEqualityDataDifferentObjectsColorSpaces))] |
|
|
|
[MemberData(nameof(NotEqualityData))] |
|
|
|
[MemberData(nameof(NotEqualityDataColorSpaces))] |
|
|
|
public void NotEquality(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Act
|
|
|
|
@ -120,6 +262,7 @@ namespace ImageSharp.Tests.Colors |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(EqualityData))] |
|
|
|
[MemberData(nameof(EqualityDataColorSpaces))] |
|
|
|
public void HashCodeEqual(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Act
|
|
|
|
@ -131,6 +274,7 @@ namespace ImageSharp.Tests.Colors |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(NotEqualityDataDifferentObjects))] |
|
|
|
[MemberData(nameof(NotEqualityDataDifferentObjectsColorSpaces))] |
|
|
|
public void HashCodeNotEqual(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Act
|
|
|
|
@ -142,6 +286,7 @@ namespace ImageSharp.Tests.Colors |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(EqualityData))] |
|
|
|
[MemberData(nameof(EqualityDataColorSpaces))] |
|
|
|
public void EqualityObject(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
@ -160,6 +305,7 @@ namespace ImageSharp.Tests.Colors |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(NotEqualityData))] |
|
|
|
[MemberData(nameof(NotEqualityDataColorSpaces))] |
|
|
|
public void NotEqualityObject(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
@ -178,6 +324,7 @@ namespace ImageSharp.Tests.Colors |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(EqualityData))] |
|
|
|
[MemberData(nameof(EqualityDataColorSpaces))] |
|
|
|
public void EqualityOperator(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
@ -196,6 +343,7 @@ namespace ImageSharp.Tests.Colors |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(NotEqualityData))] |
|
|
|
[MemberData(nameof(NotEqualityDataColorSpaces))] |
|
|
|
public void NotEqualityOperator(object first, object second, Type type) |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
@ -211,5 +359,41 @@ namespace ImageSharp.Tests.Colors |
|
|
|
// Assert
|
|
|
|
Assert.True(notEqual); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(AlmostEqualsData))] |
|
|
|
public void AlmostEquals(object first, object second, Type type, float precision) |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
// Cast to the known object types, this is so that we can hit the
|
|
|
|
// equality operator on the concrete type, otherwise it goes to the
|
|
|
|
// default "object" one :)
|
|
|
|
dynamic firstObject = Convert.ChangeType(first, type); |
|
|
|
dynamic secondObject = Convert.ChangeType(second, type); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var almostEqual = firstObject.AlmostEquals(secondObject, precision); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.True(almostEqual); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(AlmostNotEqualsData))] |
|
|
|
public void AlmostNotEquals(object first, object second, Type type, float precision) |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
// Cast to the known object types, this is so that we can hit the
|
|
|
|
// equality operator on the concrete type, otherwise it goes to the
|
|
|
|
// default "object" one :)
|
|
|
|
dynamic firstObject = Convert.ChangeType(first, type); |
|
|
|
dynamic secondObject = Convert.ChangeType(second, type); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var almostEqual = firstObject.AlmostEquals(secondObject, precision); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.False(almostEqual); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|