Skip to content

Commit

Permalink
Merge branch 'pigments' into 'main'
Browse files Browse the repository at this point in the history
Add pigment mixing (Kubelka-Munk)

See merge request Wacton/Unicolour!75
  • Loading branch information
waacton committed Jan 30, 2025
2 parents ed31194 + 588b4fd commit 8c1bf1f
Show file tree
Hide file tree
Showing 86 changed files with 3,389 additions and 4,008 deletions.
2 changes: 1 addition & 1 deletion Example.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Wacton.Unicolour;
using Wacton.Unicolour.Icc;

var config = new Configuration(iccConfiguration: new("./SWOP2006_Coated5v2.icc", Intent.RelativeColorimetric, "SWOP2006"));
var config = new Configuration(iccConfig: new("./SWOP2006_Coated5v2.icc", Intent.RelativeColorimetric, "SWOP2006"));

var white = new Unicolour("#000000");
var black = new Unicolour("#FFFFFF");
Expand Down
2 changes: 1 addition & 1 deletion Example.Diagrams/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal static List<Unicolour> GetSpectralLocus()
var data = new List<Unicolour>();
for (var nm = 360; nm < 700; nm++)
{
data.Add(new Unicolour(new Spd { { nm, 1.0 } }));
data.Add(new Unicolour(new Spd(start: nm, interval: 1, 1.0)));
}

return data;
Expand Down
55 changes: 55 additions & 0 deletions Example.Gradients/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Wacton.Unicolour;
using Wacton.Unicolour.Datasets;
using Wacton.Unicolour.Example.Gradients;
Expand All @@ -14,6 +15,7 @@
VisionDeficiency();
AlphaInterpolation();
ColourMaps();
Pigments();
return;

void ColourSpaces()
Expand Down Expand Up @@ -222,6 +224,59 @@ void ColourMaps()
double Distance(int columnIndex) => columnIndex / (double) (width - 1);
}

void Pigments()
{
const int width = 791;
const int rowHeight = 240;
const int blocks = 7;
const int columnsPerBlock = width / blocks;

DrawGradientBlocks(ArtistPaint.QuinacridoneMagenta, ArtistPaint.TitaniumWhite, "magenta-white");
DrawGradientBlocks(ArtistPaint.PhthaloBlueRedShade, ArtistPaint.TitaniumWhite, "blue-white");
DrawGradientBlocks(ArtistPaint.CobaltBlue, ArtistPaint.HansaYellowOpaque, "blue-yellow");
return;

void DrawGradientBlocks(Pigment startPigment, Pigment endPigment, string name)
{
double minRgb = 0;
double maxRgb = 0;
List<Unicolour> colours = [];
for (var i = 0; i < blocks; i++)
{
var endAmount = i / (double)(blocks - 1);

var pigments = new[] { startPigment, endPigment };
var weights = new[] { 1 - endAmount, endAmount };

var colour = new Unicolour(pigments, weights);
var rgb = colour.Rgb;
var rgbComponents = new[] { rgb.R, rgb.G, rgb.B };
minRgb = Math.Min(minRgb, rgbComponents.Min());
maxRgb = Math.Max(maxRgb, rgbComponents.Max());
colours.Add(colour);
}

var rows = new List<Image<Rgba32>>
{
Utils.Draw((string.Empty, Css.Transparent), width, rowHeight, GetColour())
};

var image = Utils.DrawRows(rows, width, rowHeight);
image.Mutate(x => x.Rotate(RotateMode.Rotate90));
image.Save(Path.Combine(outputDirectory, $"pigments-{name}.png"));
return;

Utils.GetColour GetColour()
{
return column =>
{
var blockIndex = column / columnsPerBlock;
return colours[blockIndex];
};
}
}
}

internal enum Cvd
{
None,
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
[![GitLab](https://badgen.net/static/gitlab/source/ff1493?icon=gitlab)](https://gitlab.com/Wacton/Unicolour)
[![NuGet](https://badgen.net/nuget/v/Wacton.Unicolour?icon)](https://www.nuget.org/packages/Wacton.Unicolour/)
[![pipeline status](https://gitlab.com/Wacton/Unicolour/badges/main/pipeline.svg)](https://gitlab.com/Wacton/Unicolour/-/commits/main)
[![tests passed](https://badgen.net/static/tests/216,552/green/)](https://gitlab.com/Wacton/Unicolour/-/pipelines)
[![tests passed](https://badgen.net/static/tests/216,919/green/)](https://gitlab.com/Wacton/Unicolour/-/pipelines)
[![coverage report](https://gitlab.com/Wacton/Unicolour/badges/main/coverage.svg)](https://gitlab.com/Wacton/Unicolour/-/pipelines)

Unicolour is the most comprehensive .NET library for working with colour:
- Colour space conversion
- Colour mixing / colour interpolation
- Colour difference / colour distance
- Colour gamut mapping
- Colour chromaticity
- Colour temperature
- Colour chromaticity & colour temperature
- Wavelength attributes
- ICC profiles for CMYK conversion

Expand Down
508 changes: 508 additions & 0 deletions Unicolour.Datasets/ArtistPaint.cs

Large diffs are not rendered by default.

11 changes: 3 additions & 8 deletions Unicolour.Readme/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,8 @@ void FeatureTemperature()

void FeatureSpd()
{
var spd = new Spd
{
{ 575, 0.5 },
{ 580, 1.0 },
{ 585, 0.5 }
};

// [575 nm] -> 0.5 · [580 nm] -> 1.0 · [585 nm] -> 0.5
var spd = new Spd(start: 575, interval: 5, [0.5, 1.0, 0.5]);
var intenseYellow = new Unicolour(spd);
}

Expand Down Expand Up @@ -216,7 +211,7 @@ void FeatureCvd()
void FeatureIcc()
{
var fogra39 = new IccConfiguration("./Fogra39.icc", Intent.RelativeColorimetric);
var config = new Configuration(iccConfiguration: fogra39);
var config = new Configuration(iccConfig: fogra39);

var navyRgb = new Unicolour(config, ColourSpace.Rgb255, 0, 0, 128);
Console.WriteLine(navyRgb.Icc); // 1.0000 0.8977 0.0001 0.2867 CMYK
Expand Down
5 changes: 2 additions & 3 deletions Unicolour.Readme/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
[![GitLab](https://badgen.net/static/gitlab/source/ff1493?icon=gitlab)](https://gitlab.com/Wacton/Unicolour)
[![NuGet](https://badgen.net/nuget/v/Wacton.Unicolour?icon)](https://www.nuget.org/packages/Wacton.Unicolour/)
[![pipeline status](https://gitlab.com/Wacton/Unicolour/badges/main/pipeline.svg)](https://gitlab.com/Wacton/Unicolour/-/commits/main)
[![tests passed](https://badgen.net/static/tests/216,552/green/)](https://gitlab.com/Wacton/Unicolour/-/pipelines)
[![tests passed](https://badgen.net/static/tests/216,919/green/)](https://gitlab.com/Wacton/Unicolour/-/pipelines)
[![coverage report](https://gitlab.com/Wacton/Unicolour/badges/main/coverage.svg)](https://gitlab.com/Wacton/Unicolour/-/pipelines)

Unicolour is the most comprehensive .NET library for working with colour:
- Colour space conversion
- Colour mixing / colour interpolation
- Colour difference / colour distance
- Colour gamut mapping
- Colour chromaticity
- Colour temperature
- Colour chromaticity & colour temperature
- Wavelength attributes
- ICC profiles for CMYK conversion

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Unicolour.Readme/docs/pigments-blue-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Unicolour.Readme/docs/pigments-blue-yellow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Unicolour.Readme/docs/pigments-magenta-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Unicolour.Tests/ChromaticityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void DaylightCct(double cct, string illuminantName, double x, double y)
var illuminant = TestUtils.Illuminants[illuminantName];
var daylightChromaticity = Daylight.GetChromaticity(cct * 1.4388 / 1.4380); // adjust for change in c2 constant

var config = new Configuration(xyzConfiguration: new XyzConfiguration(illuminant, Observer.Degree2));
var config = new Configuration(xyzConfig: new XyzConfiguration(illuminant, Observer.Degree2));
var white = new Unicolour(config, ColourSpace.Rgb, 1, 1, 1);
var whiteChromaticity = white.Chromaticity;

Expand Down
64 changes: 32 additions & 32 deletions Unicolour.Tests/ColourTripletTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ public void AsArray(double first, double second, double third)

private static readonly List<TestCaseData> GetHueTestData =
[
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, null), null),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 0), 7.7),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 1), null),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 2), 9.9)
new(new ColourTriplet(7.7, 8.8, 9.9, null), null),
new(new ColourTriplet(7.7, 8.8, 9.9, 0), 7.7),
new(new ColourTriplet(7.7, 8.8, 9.9, 1), null),
new(new ColourTriplet(7.7, 8.8, 9.9, 2), 9.9)
];

[TestCaseSource(nameof(GetHueTestData))]
Expand All @@ -64,10 +64,10 @@ public void GetHue(ColourTriplet triplet, double? expectedHue)

private static readonly List<TestCaseData> OverrideHueTestData =
[
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, null), 6.6, null),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 0), 6.6, new ColourTriplet(6.6, 8.8, 9.9, 0)),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 1), 6.6, null),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 2), 6.6, new ColourTriplet(7.7, 8.8, 6.6, 2))
new(new ColourTriplet(7.7, 8.8, 9.9, null), 6.6, null),
new(new ColourTriplet(7.7, 8.8, 9.9, 0), 6.6, new ColourTriplet(6.6, 8.8, 9.9, 0)),
new(new ColourTriplet(7.7, 8.8, 9.9, 1), 6.6, null),
new(new ColourTriplet(7.7, 8.8, 9.9, 2), 6.6, new ColourTriplet(7.7, 8.8, 6.6, 2))
];

[TestCaseSource(nameof(OverrideHueTestData))]
Expand All @@ -87,14 +87,14 @@ public void OverrideHue(ColourTriplet triplet, double hueOverride, ColourTriplet

private static readonly List<TestCaseData> DegreeMapTestData =
[
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, null), new Func<double, double>(x => x - 6.6), new ColourTriplet(7.7, 8.8, 9.9, null)),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 0), new Func<double, double>(x => x - 6.6), new ColourTriplet(1.1, 8.8, 9.9, 0)),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 1), new Func<double, double>(x => x - 6.6), null),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 2), new Func<double, double>(x => x - 6.6), new ColourTriplet(7.7, 8.8, 3.3, 2)),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, null), new Func<double, double>(x => x * 10), new ColourTriplet(7.7, 8.8, 9.9, null)),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 0), new Func<double, double>(x => x * 10), new ColourTriplet(77.0, 8.8, 9.9, 0)),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 1), new Func<double, double>(x => x * 10), null),
new TestCaseData(new ColourTriplet(7.7, 8.8, 9.9, 2), new Func<double, double>(x => x * 10), new ColourTriplet(7.7, 8.8, 99.0, 2))
new(new ColourTriplet(7.7, 8.8, 9.9, null), new Func<double, double>(x => x - 6.6), new ColourTriplet(7.7, 8.8, 9.9, null)),
new(new ColourTriplet(7.7, 8.8, 9.9, 0), new Func<double, double>(x => x - 6.6), new ColourTriplet(1.1, 8.8, 9.9, 0)),
new(new ColourTriplet(7.7, 8.8, 9.9, 1), new Func<double, double>(x => x - 6.6), null),
new(new ColourTriplet(7.7, 8.8, 9.9, 2), new Func<double, double>(x => x - 6.6), new ColourTriplet(7.7, 8.8, 3.3, 2)),
new(new ColourTriplet(7.7, 8.8, 9.9, null), new Func<double, double>(x => x * 10), new ColourTriplet(7.7, 8.8, 9.9, null)),
new(new ColourTriplet(7.7, 8.8, 9.9, 0), new Func<double, double>(x => x * 10), new ColourTriplet(77.0, 8.8, 9.9, 0)),
new(new ColourTriplet(7.7, 8.8, 9.9, 1), new Func<double, double>(x => x * 10), null),
new(new ColourTriplet(7.7, 8.8, 9.9, 2), new Func<double, double>(x => x * 10), new ColourTriplet(7.7, 8.8, 99.0, 2))
];

[TestCaseSource(nameof(DegreeMapTestData))]
Expand All @@ -113,10 +113,10 @@ public void DegreeMap(ColourTriplet triplet, Func<double, double> degreeMap, Col

private static readonly List<TestCaseData> ModuloHueTestData =
[
new TestCaseData(new ColourTriplet(-270, 450, 810, null), new ColourTriplet(-270, 450, 810, null)),
new TestCaseData(new ColourTriplet(-270, 450, 810, 0), new ColourTriplet(90, 450, 810, 0)),
new TestCaseData(new ColourTriplet(-270, 450, 810, 1), null),
new TestCaseData(new ColourTriplet(-270, 450, 810, 2), new ColourTriplet(-270, 450, 90, 2))
new(new ColourTriplet(-270, 450, 810, null), new ColourTriplet(-270, 450, 810, null)),
new(new ColourTriplet(-270, 450, 810, 0), new ColourTriplet(90, 450, 810, 0)),
new(new ColourTriplet(-270, 450, 810, 1), null),
new(new ColourTriplet(-270, 450, 810, 2), new ColourTriplet(-270, 450, 90, 2))
];

[TestCaseSource(nameof(ModuloHueTestData))]
Expand Down Expand Up @@ -161,10 +161,10 @@ public void ModuloHue360(ColourTriplet triplet, bool allow360, ColourTriplet exp

private static readonly List<TestCaseData> PremultipliedAlphaTestData =
[
new TestCaseData(new ColourTriplet(2, 10, -8.8, null), 0.5, new ColourTriplet(1, 5, -4.4, null)),
new TestCaseData(new ColourTriplet(2, 10, -8.8, 0), 0.5, new ColourTriplet(2, 5, -4.4, 0)),
new TestCaseData(new ColourTriplet(2, 10, -8.8, 1), 0.5, null),
new TestCaseData(new ColourTriplet(2, 10, -8.8, 2), 0.5, new ColourTriplet(1, 5, -8.8, 2))
new(new ColourTriplet(2, 10, -8.8, null), 0.5, new ColourTriplet(1, 5, -4.4, null)),
new(new ColourTriplet(2, 10, -8.8, 0), 0.5, new ColourTriplet(2, 5, -4.4, 0)),
new(new ColourTriplet(2, 10, -8.8, 1), 0.5, null),
new(new ColourTriplet(2, 10, -8.8, 2), 0.5, new ColourTriplet(1, 5, -8.8, 2))
];

[TestCaseSource(nameof(PremultipliedAlphaTestData))]
Expand All @@ -183,18 +183,18 @@ public void PremultipliedAlpha(ColourTriplet triplet, double alpha, ColourTriple

private static readonly List<TestCaseData> UnpremultipliedAlphaTestData =
[
new TestCaseData(new ColourTriplet(1, 5, -4.4, null), 0.5, new ColourTriplet(2, 10, -8.8, null)),
new TestCaseData(new ColourTriplet(1, 5, -4.4, 0), 0.5, new ColourTriplet(1, 10, -8.8, 0)),
new TestCaseData(new ColourTriplet(1, 5, -4.4, 1), 0.5, null),
new TestCaseData(new ColourTriplet(1, 5, -4.4, 2), 0.5, new ColourTriplet(2, 10, -4.4, 2))
new(new ColourTriplet(1, 5, -4.4, null), 0.5, new ColourTriplet(2, 10, -8.8, null)),
new(new ColourTriplet(1, 5, -4.4, 0), 0.5, new ColourTriplet(1, 10, -8.8, 0)),
new(new ColourTriplet(1, 5, -4.4, 1), 0.5, null),
new(new ColourTriplet(1, 5, -4.4, 2), 0.5, new ColourTriplet(2, 10, -4.4, 2))
];

private static readonly List<TestCaseData> UnpremultipliedZeroAlphaTestData =
[
new TestCaseData(new ColourTriplet(1, 5, -4.4, null), 0.0, new ColourTriplet(1, 5, -4.4, null)),
new TestCaseData(new ColourTriplet(1, 5, -4.4, 0), 0.0, new ColourTriplet(1, 5, -4.4, 0)),
new TestCaseData(new ColourTriplet(1, 5, -4.4, 1), 0.0, null),
new TestCaseData(new ColourTriplet(1, 5, -4.4, 2), 0.0, new ColourTriplet(1, 5, -4.4, 2))
new(new ColourTriplet(1, 5, -4.4, null), 0.0, new ColourTriplet(1, 5, -4.4, null)),
new(new ColourTriplet(1, 5, -4.4, 0), 0.0, new ColourTriplet(1, 5, -4.4, 0)),
new(new ColourTriplet(1, 5, -4.4, 1), 0.0, null),
new(new ColourTriplet(1, 5, -4.4, 2), 0.0, new ColourTriplet(1, 5, -4.4, 2))
];

[TestCaseSource(nameof(UnpremultipliedAlphaTestData))]
Expand Down
4 changes: 2 additions & 2 deletions Unicolour.Tests/ConfigureIccTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public void ConvertBetweenIccProfiles(string sourceFileName, string destinationF
{
var sourceFile = IccFile.Lookup[sourceFileName];
var sourceIccConfig = new IccConfiguration(sourceFile.Path, Intent.Unspecified, "source");
var sourceConfig = new Configuration(iccConfiguration: sourceIccConfig);
var sourceConfig = new Configuration(iccConfig: sourceIccConfig);
var sourceDeviceChannels = IccFile.GetDeviceChannels(sourceFile);
var sourceCmyk = new double[sourceDeviceChannels];
for (var i = 0; i < sourceDeviceChannels; i++)
Expand All @@ -28,7 +28,7 @@ public void ConvertBetweenIccProfiles(string sourceFileName, string destinationF

var destinationFile = IccFile.Lookup[destinationFileName];
var destinationIccConfig = new IccConfiguration(destinationFile.Path, Intent.Unspecified, "destination");
var destinationConfig = new Configuration(iccConfiguration: destinationIccConfig);
var destinationConfig = new Configuration(iccConfig: destinationIccConfig);
var destinationUnicolour = new Unicolour(destinationConfig, ColourSpace.Rgb, connectingRgb.Triplet.Tuple);
var destinationCmyk = destinationUnicolour.Icc;

Expand Down
20 changes: 17 additions & 3 deletions Unicolour.Tests/ContrastTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public void KnownContrast(string colour1Name, string colour2Name, double expecte
var colour1 = StandardRgb.Lookup[colour1Name];
var colour2 = StandardRgb.Lookup[colour2Name];
AssertKnownContrast(colour1, colour2, expected);

}

[Test]
Expand All @@ -24,6 +23,14 @@ public void RandomColourContrast()
AssertKnownContrast(random, random, 1);
}

[Test]
public void DifferentConfigs()
{
var redD65 = new Unicolour(new Configuration(xyzConfig: XyzConfiguration.D65), ColourSpace.Rgb, 1, 0, 0);
var redD50 = new Unicolour(new Configuration(xyzConfig: XyzConfiguration.D50), ColourSpace.Rgb, 1, 0, 0);
AssertKnownContrast(redD65, redD50, 1);
}

[Test]
public void NaNContrast()
{
Expand Down Expand Up @@ -54,15 +61,15 @@ public void BeyondMaxRgbLuminance()
}

[Test]
public void DifferentConfigInGamutLuminance()
public void InGamutLuminance()
{
var standardRgb = new Unicolour(new Configuration(RgbConfiguration.StandardRgb), ColourSpace.Rgb, 1, 1, 0);
var displayP3 = standardRgb.ConvertToConfiguration(new Configuration(RgbConfiguration.DisplayP3));
Assert.That(displayP3.RelativeLuminance, Is.EqualTo(standardRgb.RelativeLuminance));
}

[Test]
public void DifferentConfigOutOfGamutLuminance()
public void OutOfGamutLuminance()
{
var displayP3 = new Unicolour(new Configuration(RgbConfiguration.DisplayP3), ColourSpace.Rgb, 1, 1, 0);
var standardRgb = displayP3.ConvertToConfiguration(new Configuration(RgbConfiguration.StandardRgb));
Expand All @@ -83,6 +90,13 @@ private static void AssertKnownContrast(Unicolour colour1, Unicolour colour2, do
private static void AssertRelativeLuminance(Unicolour unicolour)
{
// WCAG relative luminance is defined according to sRGB https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
// which should match XYZ.Y under D65
// so need to ensure colour is using the correct configuration for the formula to work
if (unicolour.Configuration != Configuration.Default)
{
unicolour = unicolour.ConvertToConfiguration(Configuration.Default);
}

var (r, g, b) = unicolour.RgbLinear.Triplet;
var expected = 0.2126 * r + 0.7152 * g + 0.0722 * b;
Assert.That(unicolour.RelativeLuminance, Is.EqualTo(expected).Within(0.0005));
Expand Down
20 changes: 20 additions & 0 deletions Unicolour.Tests/DatasetArtistPaintTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Linq;
using NUnit.Framework;
using Wacton.Unicolour.Datasets;

namespace Wacton.Unicolour.Tests;

public class DatasetArtistPaintTests
{
[Test]
public void All()
{
Assert.That(ArtistPaint.All.Count(), Is.EqualTo(19));
Assert.That(ArtistPaint.All.Distinct().Count(), Is.EqualTo(19));

foreach (var pigment in ArtistPaint.All)
{
Assert.That(pigment.ToString(), Does.Contain(pigment.Name));
}
}
}
Loading

0 comments on commit 8c1bf1f

Please sign in to comment.