Skip to content

Commit 32a7c86

Browse files
committed
- make more test cases for color tests, specially< the literals, so that everything in color_literals.hpp is covered
- fix a few minor mistakes in the process
1 parent 7bd5b44 commit 32a7c86

File tree

2 files changed

+91
-30
lines changed

2 files changed

+91
-30
lines changed

src/helper/color_literals.hpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,16 @@ namespace {
164164
return const_utils::expected<DoubleReturnValue>::error_result("unreachable");
165165
}
166166

167-
using AnyColorReturnValue = CharIteratorResult<std::size_t>;
167+
using AnySizeType = u32;
168+
169+
using AnyColorReturnValue = CharIteratorResult<AnySizeType>;
168170

169171
// decode a single_hex_number
170172
[[nodiscard]] constexpr const_utils::expected<AnyColorReturnValue> single_color_value_any(const char* value) {
171173

172174
bool accept_hex = false;
173-
std::size_t start = 0;
174-
std::size_t mul_unit = 10;
175+
AnySizeType start = 0;
176+
AnySizeType mul_unit = 10;
175177

176178
// skip leading white space
177179
while (value[start] == ' ') {
@@ -185,14 +187,14 @@ namespace {
185187
}
186188

187189

188-
std::size_t result{ 0 };
190+
AnySizeType result{ 0 };
189191

190192
const auto max_value_before_multiplication = (std::numeric_limits<decltype(result)>::max() / mul_unit);
191193

192194
const auto max_value_before_multiplication_rest =
193195
std::numeric_limits<decltype(result)>::max() - (max_value_before_multiplication * mul_unit);
194196

195-
for (std::size_t i = start;; ++i) {
197+
for (AnySizeType i = start;; ++i) {
196198

197199
const char current_char = value[i];
198200

@@ -335,7 +337,7 @@ namespace {
335337
if (input[3] == 'a' && input[4] == '(') {
336338

337339

338-
const auto r_result = single_double_color_value(input + 5);
340+
const auto r_result = single_color_value_any(input + 5);
339341

340342
PROPAGATE(r_result, Color);
341343

@@ -350,7 +352,7 @@ namespace {
350352
}
351353

352354

353-
const auto g_result = single_double_color_value(next_g + 1);
355+
const auto g_result = single_color_value_any(next_g + 1);
354356

355357
PROPAGATE(g_result, Color);
356358

@@ -365,7 +367,7 @@ namespace {
365367
}
366368

367369

368-
const auto b_result = single_double_color_value(next_b + 1);
370+
const auto b_result = single_color_value_any(next_b + 1);
369371

370372
PROPAGATE(b_result, Color);
371373

@@ -405,7 +407,7 @@ namespace {
405407
}
406408

407409

408-
return const_utils::expected<Color>::error_result("Unrecognized HSV literal");
410+
return const_utils::expected<Color>::error_result("Unrecognized RGB literal");
409411
}
410412

411413
[[nodiscard]] constexpr const_utils::expected<Color>

tests/core/color.cpp

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ MATCHER(ExpectedHasValue, "expected has value") {
4444
return arg.has_value();
4545
}
4646

47-
MATCHER(ExpectedHasError, "expected has value") {
47+
MATCHER(ExpectedHasError, "expected has error") {
4848
return not arg.has_value();
4949
}
5050

@@ -64,36 +64,95 @@ TEST(Color, ConstructorProperties) {
6464

6565
TEST(Color, FromStringValid) {
6666

67-
const std::vector<std::string> valid_strings{ "#FFAA33", "#FF00FF00", "rgb(0,0,0)",
68-
"rgba(0,0,0,0)", "hsv(0,0,0)", "hsva(340,0,0.5,0)" };
67+
const std::vector<std::tuple<std::string, Color>> valid_strings{
68+
{ "#FFAA33", Color{ 0xFF, 0xAA, 0x33 }},
69+
{ "#FF00FF00", Color{ 0xFF, 0x00, 0xFF, 0x00 }},
70+
{ "rgb(0,0,0)", Color{ 0, 0, 0 }},
71+
{ "rgba(0,0,0,0)", Color{ 0, 0, 0, 0 }},
72+
{ "hsv(0,0,0)", HSVColor{ 0, 0, 0 }},
73+
{ "hsva(340,0,0.5,0)", HSVColor{ 340, 0, 0.5, 0 }},
74+
{ "#ffaa33", Color{ 0xff, 0xaa, 0x33 }},
75+
{"hsv(0, 0.00_000_000_1, 0)", HSVColor{ 0, 0.000000001, 0 }},
76+
{ "hsva(0, 0, 0, 0xFF)", HSVColor{ 0, 0, 0, 0xFF }},
77+
{ "rgba(0, 0xFF, 0, 255)", Color{ 0, 0xFF, 0, 255 }},
78+
{ "rgba(0, 0xFF, 0, 1_0_0)", Color{ 0, 0xFF, 0, 100 }},
79+
};
6980

70-
for (const auto& valid_string : valid_strings) {
81+
for (const auto& [valid_string, expected_color] : valid_strings) {
7182
const auto result = Color::from_string(valid_string);
7283
EXPECT_THAT(result, ExpectedHasValue()) << "Input was: " << valid_string;
84+
if (result.has_value()) {
85+
EXPECT_EQ(result.value(), expected_color) << "Input was: " << valid_string;
86+
}
7387
}
7488
}
7589

7690
TEST(Color, FromStringInvalid) {
7791

78-
const std::vector<std::string> invalid_strings{ "",
79-
"#44",
80-
"#Z",
81-
"#ZZFF",
82-
"u",
83-
"#FFFFFFII",
84-
"#FFFF4T",
85-
"#0000001",
86-
"hsl(0,0,0)",
87-
"hsva(9,9,9)",
88-
"hsva(9,9,9,10212)",
89-
"hsv(-1,0,0)",
90-
"hsv(404040,0,0)",
91-
"hsv(0,1.4,0)",
92-
"hsv(0,0,1.7)" };
93-
94-
for (const auto& invalid_string : invalid_strings) {
92+
const std::vector<std::tuple<std::string, std::string>> invalid_strings{
93+
{ "", "not enough data to determine the literal type"},
94+
{ "#44", "Unrecognized HEX literal"},
95+
{ "#Z", "Unrecognized HEX literal"},
96+
{ "#ZZFF", "Unrecognized HEX literal"},
97+
{ "u", "Unrecognized color literal"},
98+
{ "#FFFFFFII", "the input must be a valid hex character"},
99+
{ "#FFFF4T", "the input must be a valid hex character"},
100+
{ "#0000001", "Unrecognized HEX literal"},
101+
{ "hsl(0,0,0)", "Unrecognized HSV literal"},
102+
{ "rgg(0,0,0)", "Unrecognized RGB literal"},
103+
{ "hsva(9,9,9)", "s has to be in range 0.0 - 1.0"},
104+
{ "hsva(9,9,9,10212)", "s has to be in range 0.0 - 1.0"},
105+
{ "hsv(-1,0,0)", "the input must be a valid decimal character"},
106+
{ "hsv(404040,0,0)", "h has to be in range 0.0 - 360.0"},
107+
{ "hsv(0,1.4,0)", "s has to be in range 0.0 - 1.0"},
108+
{ "hsv(0,0,1.7)", "v has to be in range 0.0 - 1.0"},
109+
{ "hsva(1321.4,0,0,0)", "h has to be in range 0.0 - 360.0"},
110+
{ "hsva(0,1.4,0,0)", "s has to be in range 0.0 - 1.0"},
111+
{ "hsva(0,0,1.7,0)", "v has to be in range 0.0 - 1.0"},
112+
{ "hsva(0, 0, 0, 256)", "a has to be in range 0 - 255"},
113+
{ "hsv(0,0,1.7.8)", "only one comma allowed"},
114+
{ "hsv(0", "input ended too early"},
115+
{ "rgba(0, 0xFFF, 0, 255)", "g has to be in range 0 - 255"},
116+
{ "rgba(0, 0xFF, 0)", "expected ','"},
117+
{ "rgb(0, 0xFF, 0, 255)", "expected ')'"},
118+
{ "rgba(0, 0xFF, 0, 256)", "a has to be in range 0 - 255"},
119+
{ "rgba(0", "input ended too early"},
120+
{ "rgba(0, 0xFF, 0, 4_294_967_296)", "overflow detected"},
121+
{ "rgba(0, 0xFF, 0, 4_294_967_300)", "overflow detected"},
122+
{"rgba(0, 0xFF, 0, 121_123_124_294_967_300)", "overflow detected"},
123+
{ "rgb(256,0,0)", "r has to be in range 0 - 255"},
124+
{ "rgb(0)", "expected ','"},
125+
{ "rgb(0,256,0)", "g has to be in range 0 - 255"},
126+
{ "rgb(0,0)", "expected ','"},
127+
{ "rgb(0,0,256)", "b has to be in range 0 - 255"},
128+
{ "rgb(0,0,0,", "expected ')'"},
129+
{ "rgb(0,0,255) ", "expected end of string"},
130+
{ "rgba(256,0,0,0)", "r has to be in range 0 - 255"},
131+
{ "rgba(0)", "expected ','"},
132+
{ "rgba(0,256,0,0)", "g has to be in range 0 - 255"},
133+
{ "rgba(0,0)", "expected ','"},
134+
{ "rgba(0,0,256,0)", "b has to be in range 0 - 255"},
135+
{ "rgba(0,0,0)", "expected ','"},
136+
{ "rgba(0,0,0,256)", "a has to be in range 0 - 255"},
137+
{ "rgba(0,0,0,0,", "expected ')'"},
138+
{ "rgba(0,0,0,255) ", "expected end of string"},
139+
{ "hsv(0)", "expected ','"},
140+
{ "hsv(0,0)", "expected ','"},
141+
{ "hsv(0,0,0,", "expected ')'"},
142+
{ "hsv(0,0,0) ", "expected end of string"},
143+
{ "hsva(0)", "expected ','"},
144+
{ "hsva(0,0)", "expected ','"},
145+
{ "hsva(0,0,0)", "expected ','"},
146+
{ "hsva(0,0,0,0,", "expected ')'"},
147+
{ "hsva(0,0,0,255) ", "expected end of string"},
148+
};
149+
150+
for (const auto& [invalid_string, error_message] : invalid_strings) {
95151
const auto result = Color::from_string(invalid_string);
96152
EXPECT_THAT(result, ExpectedHasError()) << "Input was: " << invalid_string;
153+
if (not result.has_value()) {
154+
EXPECT_EQ(result.error(), error_message) << "Input was: " << invalid_string;
155+
}
97156
}
98157
}
99158

0 commit comments

Comments
 (0)