mirror of https://github.com/SixLabors/ImageSharp
1 changed files with 237 additions and 0 deletions
@ -0,0 +1,237 @@ |
|||
// <copyright file="ColorEqualityTests.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests.Colors |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using Xunit; |
|||
|
|||
using ImageSharp.Colors.Spaces; |
|||
|
|||
/// <summary>
|
|||
/// Test implementations of IEquatable and IAlmostEquatable in our colorspaces
|
|||
/// </summary>
|
|||
public class ColorSpaceEqualityTests |
|||
{ |
|||
public static readonly TheoryData<object, object, Type> EqualityData = |
|||
new TheoryData<object, object, Type>() |
|||
{ |
|||
{ new CieLab(Vector3.One), new CieLab(Vector3.One), typeof(CieLab) }, |
|||
{ new CieLch(Vector3.One), new CieLch(Vector3.One), typeof(CieLch) }, |
|||
{ new CieXyz(Vector3.One), new CieXyz(Vector3.One), typeof(CieXyz) }, |
|||
}; |
|||
|
|||
public static readonly TheoryData<object, object, Type> NotEqualityDataNulls = |
|||
new TheoryData<object, object, Type>() |
|||
{ |
|||
// Valid object against null
|
|||
{ new CieLab(Vector3.One), null, typeof(CieLab) }, |
|||
{ new CieLch(Vector3.One), null, typeof(CieLch) }, |
|||
{ new CieXyz(Vector3.One), null, typeof(CieXyz) }, |
|||
}; |
|||
|
|||
public static readonly TheoryData<object, object, Type> NotEqualityDataDifferentObjects = |
|||
new TheoryData<object, object, Type>() |
|||
{ |
|||
// Valid objects of different types but not equal
|
|||
{ new CieLab(Vector3.One), new CieLch(Vector3.Zero), null }, |
|||
{ new CieXyz(Vector3.One), new HunterLab(Vector3.Zero), null }, |
|||
{ new Rgb(Vector3.One), new LinearRgb(Vector3.Zero), null }, |
|||
{ new Rgb(Vector3.One), new Lms(Vector3.Zero), null }, |
|||
}; |
|||
|
|||
public static readonly TheoryData<object, object, Type> NotEqualityData = |
|||
new TheoryData<object, object, Type>() |
|||
{ |
|||
// Valid objects of the same type but not equal
|
|||
{ new CieLab(Vector3.One), new CieLab(Vector3.Zero), typeof(CieLab) }, |
|||
{ new CieLch(Vector3.One), new CieLch(Vector3.Zero), typeof(CieLch) }, |
|||
{ new CieXyz(Vector3.One), new CieXyz(Vector3.Zero), typeof(CieXyz) }, |
|||
}; |
|||
|
|||
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 }, |
|||
}; |
|||
|
|||
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 }, |
|||
}; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(EqualityData))] |
|||
public void Equality(object first, object second, Type type) |
|||
{ |
|||
// Act
|
|||
bool equal = first.Equals(second); |
|||
|
|||
// Assert
|
|||
Assert.True(equal); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(NotEqualityDataNulls))] |
|||
[MemberData(nameof(NotEqualityDataDifferentObjects))] |
|||
[MemberData(nameof(NotEqualityData))] |
|||
public void NotEquality(object first, object second, Type type) |
|||
{ |
|||
// Act
|
|||
bool equal = first.Equals(second); |
|||
|
|||
// Assert
|
|||
Assert.False(equal); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(EqualityData))] |
|||
public void HashCodeEqual(object first, object second, Type type) |
|||
{ |
|||
// Act
|
|||
bool equal = first.GetHashCode() == second.GetHashCode(); |
|||
|
|||
// Assert
|
|||
Assert.True(equal); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(NotEqualityDataDifferentObjects))] |
|||
public void HashCodeNotEqual(object first, object second, Type type) |
|||
{ |
|||
// Act
|
|||
bool equal = first.GetHashCode() == second.GetHashCode(); |
|||
|
|||
// Assert
|
|||
Assert.False(equal); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(EqualityData))] |
|||
public void EqualityObject(object first, object second, Type type) |
|||
{ |
|||
// 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
|
|||
dynamic equal = firstObject.Equals(secondObject); |
|||
|
|||
// Assert
|
|||
Assert.True(equal); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(NotEqualityData))] |
|||
public void NotEqualityObject(object first, object second, Type type) |
|||
{ |
|||
// 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
|
|||
dynamic equal = firstObject.Equals(secondObject); |
|||
|
|||
// Assert
|
|||
Assert.False(equal); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(EqualityData))] |
|||
public void EqualityOperator(object first, object second, Type type) |
|||
{ |
|||
// 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
|
|||
dynamic equal = firstObject == secondObject; |
|||
|
|||
// Assert
|
|||
Assert.True(equal); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(NotEqualityData))] |
|||
public void NotEqualityOperator(object first, object second, Type type) |
|||
{ |
|||
// 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
|
|||
dynamic notEqual = firstObject != secondObject; |
|||
|
|||
// 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
|
|||
dynamic 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
|
|||
dynamic almostEqual = firstObject.AlmostEquals(secondObject, precision); |
|||
|
|||
// Assert
|
|||
Assert.False(almostEqual); |
|||
} |
|||
|
|||
} |
|||
} |
|||
Loading…
Reference in new issue