Skip to content

Commit b27365b

Browse files
committed
test(ui): Add test_parameter_metadata.cpp
Split from monolithic test_parameter_validation.cpp into focused metadata validation tests covering: - Range boundary checks (min, max, exact boundaries) - Extreme limit validation (numeric_limits) - Integer vs double type validation - Builder API: name, description, required, typical, units, category - format_info() output verification for user-facing summaries Improves test isolation and speeds discovery under single-invocation runner. Part of UI parameter validation refactoring to align with "laboratory, not fortress" philosophy.
1 parent 869d596 commit b27365b

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// SPDX-FileCopyrightText: 2025 VTT Technical Research Centre of Finland Ltd
2+
// SPDX-License-Identifier: AGPL-3.0-or-later
3+
4+
#include "openpfc/ui/parameter_metadata.hpp"
5+
#include <catch2/catch_all.hpp>
6+
7+
using namespace pfc::ui;
8+
9+
TEST_CASE("ParameterMetadata double validation", "[parameter_metadata][unit]") {
10+
SECTION("Valid value within range") {
11+
auto meta = ParameterMetadata<double>::builder()
12+
.name("temperature")
13+
.description("Temperature in Kelvin")
14+
.min(0.0)
15+
.max(10000.0)
16+
.build();
17+
18+
auto error = meta.validate(3300.0);
19+
REQUIRE_FALSE(error.has_value());
20+
}
21+
22+
SECTION("Value below minimum") {
23+
auto meta =
24+
ParameterMetadata<double>::builder().name("temperature").min(0.0).build();
25+
26+
auto error = meta.validate(-100.0);
27+
REQUIRE(error.has_value());
28+
REQUIRE(error->find("below minimum") != std::string::npos);
29+
REQUIRE(error->find("temperature") != std::string::npos);
30+
}
31+
32+
SECTION("Value above maximum") {
33+
auto meta = ParameterMetadata<double>::builder()
34+
.name("temperature")
35+
.max(10000.0)
36+
.build();
37+
38+
auto error = meta.validate(15000.0);
39+
REQUIRE(error.has_value());
40+
REQUIRE(error->find("exceeds maximum") != std::string::npos);
41+
REQUIRE(error->find("temperature") != std::string::npos);
42+
}
43+
44+
SECTION("Value exactly at boundary") {
45+
auto meta = ParameterMetadata<double>::builder()
46+
.name("density")
47+
.range(-1.0, 0.0)
48+
.build();
49+
50+
REQUIRE_FALSE(meta.validate(-1.0).has_value());
51+
REQUIRE_FALSE(meta.validate(0.0).has_value());
52+
REQUIRE(meta.validate(-1.1).has_value());
53+
REQUIRE(meta.validate(0.1).has_value());
54+
}
55+
56+
SECTION("Extreme boundary values") {
57+
auto meta = ParameterMetadata<double>::builder()
58+
.name("extreme")
59+
.range(std::numeric_limits<double>::lowest(),
60+
std::numeric_limits<double>::max())
61+
.build();
62+
63+
REQUIRE_FALSE(meta.validate(std::numeric_limits<double>::lowest()).has_value());
64+
REQUIRE_FALSE(meta.validate(std::numeric_limits<double>::max()).has_value());
65+
REQUIRE_FALSE(meta.validate(0.0).has_value());
66+
}
67+
}
68+
69+
TEST_CASE("ParameterMetadata integer validation", "[parameter_metadata][unit]") {
70+
SECTION("Valid integer value") {
71+
auto meta =
72+
ParameterMetadata<int>::builder().name("num_steps").range(1, 1000).build();
73+
74+
REQUIRE_FALSE(meta.validate(100).has_value());
75+
}
76+
77+
SECTION("Integer out of range") {
78+
auto meta =
79+
ParameterMetadata<int>::builder().name("num_steps").range(1, 1000).build();
80+
81+
REQUIRE(meta.validate(0).has_value());
82+
REQUIRE(meta.validate(1001).has_value());
83+
}
84+
}
85+
86+
TEST_CASE("ParameterMetadata format_info", "[parameter_metadata][unit]") {
87+
auto meta = ParameterMetadata<double>::builder()
88+
.name("temperature")
89+
.description("Effective temperature")
90+
.required(true)
91+
.range(0.0, 10000.0)
92+
.typical(3300.0)
93+
.units("K")
94+
.category("Thermodynamics")
95+
.build();
96+
97+
std::string info = meta.format_info();
98+
99+
REQUIRE(info.find("temperature") != std::string::npos);
100+
REQUIRE(info.find("Effective temperature") != std::string::npos);
101+
REQUIRE(info.find("K") != std::string::npos);
102+
REQUIRE(info.find("0") != std::string::npos);
103+
REQUIRE(info.find("10000") != std::string::npos);
104+
REQUIRE(info.find("3300") != std::string::npos);
105+
REQUIRE(info.find("yes") != std::string::npos);
106+
}

0 commit comments

Comments
 (0)