Skip to content

Commit 0caa4ad

Browse files
committed
Fix tests
1 parent 7b974c5 commit 0caa4ad

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

tests/yup_graphics/yup_Color.cpp

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,63 @@
2828

2929
using namespace yup;
3030

31+
namespace
32+
{
33+
uint8 toByte (double value)
34+
{
35+
return static_cast<uint8> (roundToInt (jlimit (0.0, 1.0, value) * 255.0));
36+
}
37+
38+
Color colorFromFloat (double r, double g, double b)
39+
{
40+
return Color (255, toByte (r), toByte (g), toByte (b));
41+
}
42+
43+
double blendChannelExpected (BlendMode mode, double backdrop, double source)
44+
{
45+
switch (mode)
46+
{
47+
case BlendMode::SrcOver:
48+
return source;
49+
case BlendMode::Screen:
50+
return 1.0 - (1.0 - backdrop) * (1.0 - source);
51+
case BlendMode::Overlay:
52+
return backdrop <= 0.5 ? 2.0 * backdrop * source : 1.0 - 2.0 * (1.0 - backdrop) * (1.0 - source);
53+
case BlendMode::Darken:
54+
return jmin (backdrop, source);
55+
case BlendMode::Lighten:
56+
return jmax (backdrop, source);
57+
case BlendMode::ColorDodge:
58+
return source >= 1.0 ? 1.0 : jmin (1.0, backdrop / (1.0 - source));
59+
case BlendMode::ColorBurn:
60+
return source <= 0.0 ? 0.0 : 1.0 - jmin (1.0, (1.0 - backdrop) / source);
61+
case BlendMode::HardLight:
62+
return source <= 0.5 ? 2.0 * backdrop * source : 1.0 - 2.0 * (1.0 - backdrop) * (1.0 - source);
63+
case BlendMode::SoftLight:
64+
{
65+
if (source <= 0.5)
66+
return backdrop - (1.0 - 2.0 * source) * backdrop * (1.0 - backdrop);
67+
68+
const double d = backdrop <= 0.25 ? ((16.0 * backdrop - 12.0) * backdrop + 4.0) * backdrop : std::sqrt (backdrop);
69+
return backdrop + (2.0 * source - 1.0) * (d - backdrop);
70+
}
71+
case BlendMode::Difference:
72+
return std::abs (backdrop - source);
73+
case BlendMode::Exclusion:
74+
return backdrop + source - 2.0 * backdrop * source;
75+
case BlendMode::Multiply:
76+
return backdrop * source;
77+
case BlendMode::Hue:
78+
case BlendMode::Saturation:
79+
case BlendMode::Color:
80+
case BlendMode::Luminosity:
81+
return source;
82+
default:
83+
return source;
84+
}
85+
}
86+
} // namespace
87+
3188
TEST (ColorTests, Default_Constructor)
3289
{
3390
Color c;
@@ -1006,6 +1063,84 @@ TEST (ColorTests, BlendWith_Opacity)
10061063
EXPECT_EQ (blended.getARGB(), expected.getARGB());
10071064
}
10081065

1066+
TEST (ColorTests, BlendWith_SrcAlphaZero_NoChange)
1067+
{
1068+
const Color dest (200, 10, 20, 30);
1069+
const Color src (0, 200, 100, 50);
1070+
const auto blended = dest.blendedWith (src, BlendMode::SrcOver);
1071+
EXPECT_EQ (blended.getARGB(), dest.getARGB());
1072+
}
1073+
1074+
TEST (ColorTests, BlendWith_DestAlphaZero_ReturnsSrc)
1075+
{
1076+
const Color dest (0, 10, 20, 30);
1077+
const Color src (100, 40, 50, 60);
1078+
const auto blended = dest.blendedWith (src, BlendMode::Screen);
1079+
EXPECT_EQ (blended.getARGB(), src.getARGB());
1080+
}
1081+
1082+
TEST (ColorTests, BlendWith_ChannelModes)
1083+
{
1084+
const double backdropValue = 0.2;
1085+
const double sourceValue = 0.7;
1086+
const auto backdrop = colorFromFloat (backdropValue, backdropValue, backdropValue);
1087+
const auto source = colorFromFloat (sourceValue, sourceValue, sourceValue);
1088+
1089+
const BlendMode modes[] = {
1090+
BlendMode::SrcOver,
1091+
BlendMode::Screen,
1092+
BlendMode::Overlay,
1093+
BlendMode::Darken,
1094+
BlendMode::Lighten,
1095+
BlendMode::ColorDodge,
1096+
BlendMode::ColorBurn,
1097+
BlendMode::HardLight,
1098+
BlendMode::SoftLight,
1099+
BlendMode::Difference,
1100+
BlendMode::Exclusion,
1101+
BlendMode::Multiply
1102+
};
1103+
1104+
for (const auto mode : modes)
1105+
{
1106+
const auto blended = backdrop.blendedWith (source, mode);
1107+
const double expected = blendChannelExpected (mode, backdropValue, sourceValue);
1108+
EXPECT_NEAR (blended.getRedFloat(), expected, 1.0f / 255.0f);
1109+
EXPECT_NEAR (blended.getGreenFloat(), expected, 1.0f / 255.0f);
1110+
EXPECT_NEAR (blended.getBlueFloat(), expected, 1.0f / 255.0f);
1111+
}
1112+
}
1113+
1114+
TEST (ColorTests, BlendWith_HslModes)
1115+
{
1116+
const auto backdrop = Color::fromHSL (0.1f, 0.7f, 0.4f);
1117+
const auto source = Color::fromHSL (0.7f, 0.3f, 0.8f);
1118+
1119+
const auto hueResult = backdrop.blendedWith (source, BlendMode::Hue);
1120+
const auto [hueH, hueS, hueL] = hueResult.toHSL();
1121+
EXPECT_NEAR (hueH, std::get<0> (source.toHSL()), 0.02f);
1122+
EXPECT_NEAR (hueS, std::get<1> (backdrop.toHSL()), 0.02f);
1123+
EXPECT_NEAR (hueL, std::get<2> (backdrop.toHSL()), 0.02f);
1124+
1125+
const auto satResult = backdrop.blendedWith (source, BlendMode::Saturation);
1126+
const auto [satH, satS, satL] = satResult.toHSL();
1127+
EXPECT_NEAR (satH, std::get<0> (backdrop.toHSL()), 0.02f);
1128+
EXPECT_NEAR (satS, std::get<1> (source.toHSL()), 0.02f);
1129+
EXPECT_NEAR (satL, std::get<2> (backdrop.toHSL()), 0.02f);
1130+
1131+
const auto colorResult = backdrop.blendedWith (source, BlendMode::Color);
1132+
const auto [colH, colS, colL] = colorResult.toHSL();
1133+
EXPECT_NEAR (colH, std::get<0> (source.toHSL()), 0.02f);
1134+
EXPECT_NEAR (colS, std::get<1> (source.toHSL()), 0.02f);
1135+
EXPECT_NEAR (colL, std::get<2> (backdrop.toHSL()), 0.02f);
1136+
1137+
const auto lumResult = backdrop.blendedWith (source, BlendMode::Luminosity);
1138+
const auto [lumH, lumS, lumL] = lumResult.toHSL();
1139+
EXPECT_NEAR (lumH, std::get<0> (backdrop.toHSL()), 0.02f);
1140+
EXPECT_NEAR (lumS, std::get<1> (backdrop.toHSL()), 0.02f);
1141+
EXPECT_NEAR (lumL, std::get<2> (source.toHSL()), 0.02f);
1142+
}
1143+
10091144
TEST (ColorTests, MixWith_ModifiesInPlace)
10101145
{
10111146
Color base (255, 20, 40, 60);
@@ -1016,3 +1151,15 @@ TEST (ColorTests, MixWith_ModifiesInPlace)
10161151
const auto expected = base.mixedWith (other, 0.35f, ColorSpace::SRGB);
10171152
EXPECT_EQ (copy.getARGB(), expected.getARGB());
10181153
}
1154+
1155+
TEST (ColorTests, MixWith_RgbUsesSrcOver)
1156+
{
1157+
const Color base (128, 40, 80, 120);
1158+
const Color other (200, 200, 20, 40);
1159+
const float amount = 0.3f;
1160+
1161+
auto rgbMix = base;
1162+
rgbMix.mixWith (other, amount, ColorSpace::RGB);
1163+
const auto expected = base.blendedWith (other.withMultipliedAlpha (amount), BlendMode::SrcOver);
1164+
EXPECT_EQ (rgbMix.getARGB(), expected.getARGB());
1165+
}

tests/yup_graphics/yup_ColorGradient.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,3 +660,88 @@ TEST (ColorGradientTests, AddColorStop_Delta_Only_Edge_Cases)
660660
// Should now have at least the stops we added
661661
EXPECT_GE (gradient.getNumStops(), 3);
662662
}
663+
664+
TEST (ColorGradientTests, GetColorAt_EmptyAndSingleStop)
665+
{
666+
ColorGradient empty;
667+
EXPECT_EQ (empty.getColorAt (0.5f).getARGB(), Color().getARGB());
668+
EXPECT_EQ (empty.getColorAt (10.0f, 20.0f).getARGB(), Color().getARGB());
669+
EXPECT_EQ (empty.getColorAt (Point<float> (5.0f, 5.0f)).getARGB(), Color().getARGB());
670+
671+
ColorGradient single;
672+
const Color only (0xff123456);
673+
single.addColorStop (only, 4.0f, 5.0f, 0.3f);
674+
EXPECT_EQ (single.getColorAt (0.0f).getARGB(), only.getARGB());
675+
EXPECT_EQ (single.getColorAt (1.0f).getARGB(), only.getARGB());
676+
EXPECT_EQ (single.getColorAt (10.0f, 10.0f).getARGB(), only.getARGB());
677+
}
678+
679+
TEST (ColorGradientTests, GetColorAt_T_ClampsAndInterpolates)
680+
{
681+
ColorGradient gradient;
682+
const Color start (0xffff0000);
683+
const Color end (0xff0000ff);
684+
gradient.addColorStop (start, 0.0f, 0.0f, 0.2f);
685+
gradient.addColorStop (end, 10.0f, 0.0f, 0.8f);
686+
687+
EXPECT_EQ (gradient.getColorAt (0.1f).getARGB(), start.getARGB());
688+
EXPECT_EQ (gradient.getColorAt (0.9f).getARGB(), end.getARGB());
689+
690+
const float localT = (0.5f - 0.2f) / (0.8f - 0.2f);
691+
const auto expected = start.mixedWith (end, localT, ColorSpace::SRGB);
692+
EXPECT_EQ (gradient.getColorAt (0.5f).getARGB(), expected.getARGB());
693+
}
694+
695+
TEST (ColorGradientTests, GetColorAt_T_DuplicateDelta)
696+
{
697+
std::vector<ColorGradient::ColorStop> stops;
698+
stops.emplace_back (Color (0xff000000), 0.0f, 0.0f, 0.5f);
699+
stops.emplace_back (Color (0xffffffff), 10.0f, 0.0f, 0.5f);
700+
701+
ColorGradient gradient (ColorGradient::Linear, stops);
702+
const auto sampled = gradient.getColorAt (0.5f).getARGB();
703+
const auto first = stops[0].color.getARGB();
704+
const auto second = stops[1].color.getARGB();
705+
EXPECT_TRUE (sampled == first || sampled == second);
706+
}
707+
708+
TEST (ColorGradientTests, GetColorAt_XY_LinearAndPointOverload)
709+
{
710+
Color start (0xffff0000);
711+
Color end (0xff0000ff);
712+
ColorGradient gradient (start, 0.0f, 0.0f, end, 10.0f, 0.0f, ColorGradient::Linear);
713+
714+
const auto expected = gradient.getColorAt (0.5f);
715+
EXPECT_EQ (gradient.getColorAt (5.0f, 0.0f).getARGB(), expected.getARGB());
716+
EXPECT_EQ (gradient.getColorAt (Point<float> (5.0f, 0.0f)).getARGB(), expected.getARGB());
717+
718+
EXPECT_EQ (gradient.getColorAt (20.0f, 0.0f).getARGB(), end.getARGB());
719+
}
720+
721+
TEST (ColorGradientTests, GetColorAt_XY_Linear_ZeroLength)
722+
{
723+
Color start (0xffff0000);
724+
Color end (0xff0000ff);
725+
ColorGradient gradient (start, 1.0f, 1.0f, end, 1.0f, 1.0f, ColorGradient::Linear);
726+
727+
EXPECT_EQ (gradient.getColorAt (5.0f, 5.0f).getARGB(), start.getARGB());
728+
}
729+
730+
TEST (ColorGradientTests, GetColorAt_XY_Radial)
731+
{
732+
Color start (0xffff0000);
733+
Color end (0xff0000ff);
734+
ColorGradient gradient (start, 0.0f, 0.0f, end, 0.0f, 10.0f, ColorGradient::Radial);
735+
736+
const auto expected = gradient.getColorAt (0.5f);
737+
EXPECT_EQ (gradient.getColorAt (0.0f, 5.0f).getARGB(), expected.getARGB());
738+
}
739+
740+
TEST (ColorGradientTests, GetColorAt_XY_Radial_ZeroRadius)
741+
{
742+
Color start (0xffff0000);
743+
Color end (0xff0000ff);
744+
ColorGradient gradient (start, 2.0f, 2.0f, end, 2.0f, 2.0f, ColorGradient::Radial);
745+
746+
EXPECT_EQ (gradient.getColorAt (10.0f, 10.0f).getARGB(), start.getARGB());
747+
}

0 commit comments

Comments
 (0)