mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-29 18:07:16 +02:00
test: runtime unit tests refactored to have a bigger granularity (less top level tests)
This commit is contained in:
@ -43,8 +43,10 @@ import mp_units;
|
||||
|
||||
using namespace mp_units;
|
||||
|
||||
TEST_CASE("uniform_int_distribution")
|
||||
TEST_CASE("distributions", "[random][distribution]")
|
||||
{
|
||||
SECTION("uniform_int_distribution")
|
||||
{
|
||||
using rep = std::int64_t;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -69,10 +71,10 @@ TEST_CASE("uniform_int_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("uniform_real_distribution")
|
||||
{
|
||||
SECTION("uniform_real_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -97,10 +99,10 @@ TEST_CASE("uniform_real_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("binomial_distribution")
|
||||
{
|
||||
SECTION("binomial_distribution")
|
||||
{
|
||||
using rep = std::int64_t;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -125,10 +127,10 @@ TEST_CASE("binomial_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("negative_binomial_distribution")
|
||||
{
|
||||
SECTION("negative_binomial_distribution")
|
||||
{
|
||||
using rep = std::int64_t;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -153,10 +155,10 @@ TEST_CASE("negative_binomial_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("geometric_distribution")
|
||||
{
|
||||
SECTION("geometric_distribution")
|
||||
{
|
||||
using rep = std::int64_t;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -178,10 +180,10 @@ TEST_CASE("geometric_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("poisson_distribution")
|
||||
{
|
||||
SECTION("poisson_distribution")
|
||||
{
|
||||
using rep = std::int64_t;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -203,10 +205,10 @@ TEST_CASE("poisson_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("exponential_distribution")
|
||||
{
|
||||
SECTION("exponential_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -228,10 +230,10 @@ TEST_CASE("exponential_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gamma_distribution")
|
||||
{
|
||||
SECTION("gamma_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -256,10 +258,10 @@ TEST_CASE("gamma_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("weibull_distribution")
|
||||
{
|
||||
SECTION("weibull_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -284,10 +286,10 @@ TEST_CASE("weibull_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("extreme_value_distribution")
|
||||
{
|
||||
SECTION("extreme_value_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -312,10 +314,10 @@ TEST_CASE("extreme_value_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("normal_distribution")
|
||||
{
|
||||
SECTION("normal_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -340,10 +342,10 @@ TEST_CASE("normal_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("lognormal_distribution")
|
||||
{
|
||||
SECTION("lognormal_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -368,10 +370,10 @@ TEST_CASE("lognormal_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("chi_squared_distribution")
|
||||
{
|
||||
SECTION("chi_squared_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -393,10 +395,10 @@ TEST_CASE("chi_squared_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("cauchy_distribution")
|
||||
{
|
||||
SECTION("cauchy_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -421,10 +423,10 @@ TEST_CASE("cauchy_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("fisher_f_distribution")
|
||||
{
|
||||
SECTION("fisher_f_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -449,10 +451,10 @@ TEST_CASE("fisher_f_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("student_t_distribution")
|
||||
{
|
||||
SECTION("student_t_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -474,10 +476,10 @@ TEST_CASE("student_t_distribution")
|
||||
CHECK(units_dist.min() == stl_dist.min() * si::metre);
|
||||
CHECK(units_dist.max() == stl_dist.max() * si::metre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("discrete_distribution")
|
||||
{
|
||||
SECTION("discrete_distribution")
|
||||
{
|
||||
using rep = std::int64_t;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -521,10 +523,10 @@ TEST_CASE("discrete_distribution")
|
||||
|
||||
CHECK(units_dist.probabilities() == stl_dist.probabilities());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("piecewise_constant_distribution")
|
||||
{
|
||||
SECTION("piecewise_constant_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -589,10 +591,10 @@ TEST_CASE("piecewise_constant_distribution")
|
||||
CHECK(units_dist.intervals() == intervals_qty_vec);
|
||||
CHECK(units_dist.densities() == stl_dist.densities());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("piecewise_linear_distribution")
|
||||
{
|
||||
SECTION("piecewise_linear_distribution")
|
||||
{
|
||||
using rep = long double;
|
||||
using q = quantity<isq::length[si::metre], rep>;
|
||||
|
||||
@ -657,4 +659,5 @@ TEST_CASE("piecewise_linear_distribution")
|
||||
CHECK(units_dist.intervals() == intervals_qty_vec);
|
||||
CHECK(units_dist.densities() == stl_dist.densities());
|
||||
}
|
||||
}
|
||||
}
|
@ -38,8 +38,10 @@ import mp_units;
|
||||
|
||||
using namespace mp_units;
|
||||
|
||||
TEST_CASE("fixed_string::at", "[fixed_string]")
|
||||
TEST_CASE("fixed_string operations", "[fixed_string]")
|
||||
{
|
||||
SECTION("fixed_string::at")
|
||||
{
|
||||
basic_fixed_string txt = "abc";
|
||||
SECTION("in range")
|
||||
{
|
||||
@ -52,6 +54,7 @@ TEST_CASE("fixed_string::at", "[fixed_string]")
|
||||
REQUIRE_THROWS_MATCHES(txt.at(3), std::out_of_range, Catch::Matchers::Message("basic_fixed_string::at"));
|
||||
REQUIRE_THROWS_MATCHES(txt.at(1024), std::out_of_range, Catch::Matchers::Message("basic_fixed_string::at"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("fixed_string text output", "[fixed_string][ostream][fmt]")
|
||||
|
@ -55,7 +55,271 @@ constexpr bool mp_units::is_vector<T> = true;
|
||||
using namespace mp_units;
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
|
||||
TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
|
||||
TEST_CASE("dimension_symbol", "[dimension][symbol]")
|
||||
{
|
||||
using enum text_encoding;
|
||||
|
||||
std::ostringstream os;
|
||||
|
||||
SECTION("default formatting")
|
||||
{
|
||||
os << dimension_symbol(isq::power.dimension);
|
||||
CHECK(os.str() == "L²MT⁻³");
|
||||
}
|
||||
|
||||
SECTION("Portable mode")
|
||||
{
|
||||
os << dimension_symbol<dimension_symbol_formatting{.encoding = portable}>(isq::power.dimension);
|
||||
CHECK(os.str() == "L^2MT^-3");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("unit_symbol", "[unit][symbol]")
|
||||
{
|
||||
using enum text_encoding;
|
||||
using enum unit_symbol_solidus;
|
||||
using enum unit_symbol_separator;
|
||||
|
||||
std::ostringstream os;
|
||||
|
||||
SECTION("default formatting")
|
||||
{
|
||||
os << unit_symbol(m / s2);
|
||||
CHECK(os.str() == "m/s²");
|
||||
}
|
||||
|
||||
SECTION("Portable mode")
|
||||
{
|
||||
os << unit_symbol<unit_symbol_formatting{.encoding = portable}>(m / s2);
|
||||
CHECK(os.str() == "m/s^2");
|
||||
}
|
||||
|
||||
SECTION("solidus")
|
||||
{
|
||||
os << unit_symbol<unit_symbol_formatting{.solidus = never}>(m / s2);
|
||||
CHECK(os.str() == "m s⁻²");
|
||||
}
|
||||
|
||||
SECTION("separator")
|
||||
{
|
||||
os << unit_symbol<unit_symbol_formatting{.solidus = never, .separator = half_high_dot}>(m / s2);
|
||||
CHECK(os.str() == "m⋅s⁻²");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO add dimension formatting tests
|
||||
|
||||
TEST_CASE("unit formatting", "[unit][fmt]")
|
||||
{
|
||||
SECTION("Unit formatting should use proper text encoding")
|
||||
{
|
||||
SECTION("Unicode text output")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", si::kilo<si::ohm>) == "kΩ");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", us) == "µs");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", m / s2) == "m/s²");
|
||||
}
|
||||
|
||||
SECTION("Unicode text output is used by default")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", si::kilo<si::ohm>) == "kΩ");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", us) == "µs");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", m / s2) == "m/s²");
|
||||
}
|
||||
|
||||
SECTION("Portable text output")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", si::kilo<si::ohm>) == "kohm");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", us) == "us");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", m / s2) == "m/s^2");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("unit formatting should print solidus according to specs")
|
||||
{
|
||||
SECTION("Solidus for only one element in denominator")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:1}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:1}", m / s2) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:1}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
}
|
||||
|
||||
SECTION("Solidus for only one element in denominator is used by default")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", m / s2) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
}
|
||||
|
||||
SECTION("Always use solidus")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", m / s2) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", kg / m / s2) == "kg/(m s²)");
|
||||
}
|
||||
|
||||
SECTION("Never use solidus")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:n}", km / h) == "km h⁻¹");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:n}", m / s2) == "m s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:n}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Unit formatting should user proper separator")
|
||||
{
|
||||
SECTION("Space")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:s}", kg * m / s2) == "kg m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:s}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:sa}", kg / m / s2) == "kg/(m s²)");
|
||||
}
|
||||
|
||||
SECTION("Space is used by default")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", kg * m / s2) == "kg m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", kg / m / s2) == "kg/(m s²)");
|
||||
}
|
||||
|
||||
SECTION("Dot")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:d}", kg * m / s2) == "kg⋅m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:d}", kg / m / s2) == "kg⋅m⁻¹⋅s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:ad}", kg / m / s2) == "kg/(m⋅s²)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("unit formatting error handling", "[unit][fmt][exception]")
|
||||
{
|
||||
SECTION("unknown unit modifiers should throw")
|
||||
{
|
||||
SECTION("only the invalid modifier")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:x}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
|
||||
SECTION("invalid modifier in the front")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:xUda}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
|
||||
SECTION("invalid modifier in the end")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:Udax}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
|
||||
SECTION("invalid modifier in the middle")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:Udxa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("repeated unit modifiers should throw")
|
||||
{
|
||||
SECTION("text encoding")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:UdaU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dUaU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dUUa}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("solidus")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:aUda}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:daUa}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:daaU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("separator")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dUad}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dadU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:addU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("more then one modifier of the same kind should throw")
|
||||
{
|
||||
SECTION("text encoding")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:UdaP}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dPaU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dPUa}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("solidus")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:aUdn}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dnUa}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:da1U}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("separator")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:dUas}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:sadU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(
|
||||
MP_UNITS_STD_FMT::vformat("{:adsU}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("half_high_dot separator requested for portable encoding should throw")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dPa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("half_high_dot unit separator allowed only for UTF-8 encoding"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("default quantity formatting", "[quantity][ostream][fmt]")
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
@ -375,266 +639,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("quantity format string with only %N should print quantity value only", "[text][fmt]")
|
||||
{
|
||||
SECTION("integral representation")
|
||||
{
|
||||
SECTION("positive value") { CHECK(MP_UNITS_STD_FMT::format("{:%N}", 123 * isq::speed[km / h]) == "123"); }
|
||||
|
||||
SECTION("negative value")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", 5 * isq::length[m] - 10 * isq::length[m]) == "-5");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("floating-point representation")
|
||||
{
|
||||
SECTION("positive value")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", 221. * isq::length[km] / (2 * isq::time[h])) == "110.5");
|
||||
}
|
||||
|
||||
SECTION("negative value")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", 3.14 * isq::length[m] - 10 * isq::length[m]) == "-6.859999999999999");
|
||||
}
|
||||
|
||||
SECTION("nan")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", std::numeric_limits<double>::quiet_NaN() * isq::length[m]) == "nan");
|
||||
}
|
||||
|
||||
SECTION("inf")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", std::numeric_limits<double>::infinity() * isq::length[m]) == "inf");
|
||||
}
|
||||
|
||||
SECTION("-inf")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", -std::numeric_limits<double>::infinity() * isq::length[m]) == "-inf");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("quantity format string with only %U should print quantity unit symbol only", "[text][fmt]")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::speed[km / h]) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::resistance[si::kilo<si::ohm>]) == "kΩ");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::time[us]) == "µs");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::acceleration[m / s2]) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * percent) == "%");
|
||||
}
|
||||
|
||||
TEST_CASE("Unit formatting should use proper text encoding")
|
||||
{
|
||||
SECTION("Unicode text output")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", si::kilo<si::ohm>) == "kΩ");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", us) == "µs");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:U}", m / s2) == "m/s²");
|
||||
}
|
||||
|
||||
SECTION("Unicode text output is used by default")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", si::kilo<si::ohm>) == "kΩ");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", us) == "µs");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", m / s2) == "m/s²");
|
||||
}
|
||||
|
||||
SECTION("Portable text output")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", si::kilo<si::ohm>) == "kohm");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", us) == "us");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:P}", m / s2) == "m/s^2");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit formatting should print solidus according to specs")
|
||||
{
|
||||
SECTION("Solidus for only one element in denominator")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:1}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:1}", m / s2) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:1}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
}
|
||||
|
||||
SECTION("Solidus for only one element in denominator is used by default")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", m / s2) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
}
|
||||
|
||||
SECTION("Always use solidus")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", km / h) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", m / s2) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", kg / m / s2) == "kg/(m s²)");
|
||||
}
|
||||
|
||||
SECTION("Never use solidus")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:n}", km / h) == "km h⁻¹");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:n}", m / s2) == "m s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:n}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit formatting should user proper separator")
|
||||
{
|
||||
SECTION("Space")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:s}", kg * m / s2) == "kg m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:s}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:sa}", kg / m / s2) == "kg/(m s²)");
|
||||
}
|
||||
|
||||
SECTION("Space is used by default")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", kg * m / s2) == "kg m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{}", kg / m / s2) == "kg m⁻¹ s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:a}", kg / m / s2) == "kg/(m s²)");
|
||||
}
|
||||
|
||||
SECTION("Dot")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:d}", kg * m / s2) == "kg⋅m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:d}", kg / m / s2) == "kg⋅m⁻¹⋅s⁻²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:ad}", kg / m / s2) == "kg/(m⋅s²)");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("unknown unit modifiers should throw", "[text][fmt][exception]")
|
||||
{
|
||||
SECTION("only the invalid modifier")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:x}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
|
||||
SECTION("invalid modifier in the front")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:xUda}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
|
||||
SECTION("invalid modifier in the end")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:Udax}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
|
||||
SECTION("invalid modifier in the middle")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:Udxa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("repeated unit modifiers should throw", "[text][fmt][exception]")
|
||||
{
|
||||
SECTION("text encoding")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:UdaU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dUaU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dUUa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("solidus")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:aUda}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:daUa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:daaU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("separator")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dUad}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dadU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:addU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("more then one modifier of the same kind should throw", "[text][fmt][exception]")
|
||||
{
|
||||
SECTION("text encoding")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:UdaP}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dPaU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dPUa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'UAP' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("solidus")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:aUdn}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dnUa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:da1U}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of '1an' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
|
||||
SECTION("separator")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dUas}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:sadU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:adsU}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("half_high_dot separator requested for portable encoding should throw", "[text][fmt][exception]")
|
||||
{
|
||||
REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dPa}", MP_UNITS_STD_FMT::make_format_args(m)),
|
||||
MP_UNITS_STD_FMT::format_error,
|
||||
Catch::Matchers::Message("half_high_dot unit separator allowed only for UTF-8 encoding"));
|
||||
}
|
||||
|
||||
TEST_CASE("%U and %N can be put anywhere in a format string", "[text][fmt]")
|
||||
{
|
||||
SECTION("no space") { CHECK(MP_UNITS_STD_FMT::format("{:%N%U}", 123 * isq::speed[km / h]) == "123km/h"); }
|
||||
|
||||
SECTION("separator") { CHECK(MP_UNITS_STD_FMT::format("{:%N###%U}", 123 * isq::speed[km / h]) == "123###km/h"); }
|
||||
|
||||
SECTION("opposite order") { CHECK(MP_UNITS_STD_FMT::format("{:%U %N}", 123 * isq::speed[km / h]) == "km/h 123"); }
|
||||
}
|
||||
|
||||
TEST_CASE("quantity fill and align specification", "[text][fmt][ostream]")
|
||||
TEST_CASE("quantity fill and align specification", "[quantity][ostream][fmt]")
|
||||
{
|
||||
SECTION("ostream")
|
||||
{
|
||||
@ -726,8 +731,75 @@ TEST_CASE("quantity fill and align specification", "[text][fmt][ostream]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("sign specification", "[text][fmt]")
|
||||
TEST_CASE("quantity subentities selection", "[quantity][fmt]")
|
||||
{
|
||||
SECTION("quantity format string with only %N should print quantity value only")
|
||||
{
|
||||
SECTION("integral representation")
|
||||
{
|
||||
SECTION("positive value") { CHECK(MP_UNITS_STD_FMT::format("{:%N}", 123 * isq::speed[km / h]) == "123"); }
|
||||
|
||||
SECTION("negative value")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", 5 * isq::length[m] - 10 * isq::length[m]) == "-5");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("floating-point representation")
|
||||
{
|
||||
SECTION("positive value")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", 221. * isq::length[km] / (2 * isq::time[h])) == "110.5");
|
||||
}
|
||||
|
||||
SECTION("negative value")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", 3.14 * isq::length[m] - 10 * isq::length[m]) == "-6.859999999999999");
|
||||
}
|
||||
|
||||
SECTION("nan")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", std::numeric_limits<double>::quiet_NaN() * isq::length[m]) == "nan");
|
||||
}
|
||||
|
||||
SECTION("inf")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", std::numeric_limits<double>::infinity() * isq::length[m]) == "inf");
|
||||
}
|
||||
|
||||
SECTION("-inf")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N}", -std::numeric_limits<double>::infinity() * isq::length[m]) == "-inf");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("quantity format string with only %U should print quantity unit symbol only")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::speed[km / h]) == "km/h");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::resistance[si::kilo<si::ohm>]) == "kΩ");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::time[us]) == "µs");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * isq::acceleration[m / s2]) == "m/s²");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%U}", 123 * percent) == "%");
|
||||
}
|
||||
|
||||
SECTION("%U and %N can be put anywhere in a format string")
|
||||
{
|
||||
SECTION("no space") { CHECK(MP_UNITS_STD_FMT::format("{:%N%U}", 123 * isq::speed[km / h]) == "123km/h"); }
|
||||
|
||||
SECTION("separator") { CHECK(MP_UNITS_STD_FMT::format("{:%N###%U}", 123 * isq::speed[km / h]) == "123###km/h"); }
|
||||
|
||||
SECTION("opposite order") { CHECK(MP_UNITS_STD_FMT::format("{:%U %N}", 123 * isq::speed[km / h]) == "km/h 123"); }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO provide basic tests if format string when provided in a quantity formatter are passed to respective dimensions
|
||||
// and units formatters (detail formatting tests for dimensions and units are done separately)
|
||||
|
||||
TEST_CASE("quantity numerical value formatting for `std` arithmetic types", "[quantity][fmt]")
|
||||
{
|
||||
SECTION("sign specification")
|
||||
{
|
||||
auto inf = std::numeric_limits<double>::infinity() * si::metre;
|
||||
auto nan = std::numeric_limits<double>::quiet_NaN() * si::metre;
|
||||
|
||||
@ -746,14 +818,15 @@ TEST_CASE("sign specification", "[text][fmt]")
|
||||
SECTION("value only format {:%N} on a quantity")
|
||||
{
|
||||
CHECK(MP_UNITS_STD_FMT::format("{0:%N},{0:%N:N[+]},{0:%N:N[-]},{0:%N:N[ ]}", 1 * isq::length[m]) == "1,+1,1, 1");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{0:%N},{0:%N:N[+]},{0:%N:N[-]},{0:%N:N[ ]}", -1 * isq::length[m]) == "-1,-1,-1,-1");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{0:%N},{0:%N:N[+]},{0:%N:N[-]},{0:%N:N[ ]}", -1 * isq::length[m]) ==
|
||||
"-1,-1,-1,-1");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{0:%N},{0:%N:N[+]},{0:%N:N[-]},{0:%N:N[ ]}", inf) == "inf,+inf,inf, inf");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{0:%N},{0:%N:N[+]},{0:%N:N[-]},{0:%N:N[ ]}", nan) == "nan,+nan,nan, nan");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("precision specification", "[text][fmt]")
|
||||
{
|
||||
SECTION("precision specification")
|
||||
{
|
||||
SECTION("full format on a quantity")
|
||||
{
|
||||
SECTION("default spec")
|
||||
@ -800,10 +873,10 @@ TEST_CASE("precision specification", "[text][fmt]")
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N:N[.5f]}", 1.2345 * isq::length[m]) == "1.23450");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N:N[.10f]}", 1.2345 * isq::length[m]) == "1.2345000000");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("type specification", "[text][fmt]")
|
||||
{
|
||||
SECTION("type specification")
|
||||
{
|
||||
SECTION("full format {:%N%?%U} on a quantity")
|
||||
{
|
||||
SECTION("default spec")
|
||||
@ -942,10 +1015,10 @@ TEST_CASE("type specification", "[text][fmt]")
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N:N[.3G]}", 1.2345678 * isq::length[m]) == "1.23");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N:N[.3G]}", 1.2345678e8 * isq::length[m]) == "1.23E+08");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("different base types with the # specifier", "[text][fmt]")
|
||||
{
|
||||
SECTION("different base types with the # specifier")
|
||||
{
|
||||
SECTION("full format {:%N%?%U} on a quantity")
|
||||
{
|
||||
SECTION("default spec")
|
||||
@ -984,10 +1057,10 @@ TEST_CASE("different base types with the # specifier", "[text][fmt]")
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N:N[#x]}", 42 * isq::length[m]) == "0x2a");
|
||||
CHECK(MP_UNITS_STD_FMT::format("{:%N:N[#X]}", 42 * isq::length[m]) == "0X2A");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("localization with the 'L' specifier", "[text][fmt][localization]")
|
||||
{
|
||||
SECTION("localization with the 'L' specifier")
|
||||
{
|
||||
struct group2 : std::numpunct<char> {
|
||||
[[nodiscard]] char do_thousands_sep() const override { return '_'; }
|
||||
[[nodiscard]] std::string do_grouping() const override { return "\2"; }
|
||||
@ -1021,61 +1094,10 @@ TEST_CASE("localization with the 'L' specifier", "[text][fmt][localization]")
|
||||
CHECK(MP_UNITS_STD_FMT::format(grp3, "{:%N%U:N[L]}", 299'792'458 * isq::speed[m / s]) == "299'792'458m/s");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("unit_symbol", "[text]")
|
||||
{
|
||||
using enum text_encoding;
|
||||
using enum unit_symbol_solidus;
|
||||
using enum unit_symbol_separator;
|
||||
|
||||
std::ostringstream os;
|
||||
|
||||
SECTION("default formatting")
|
||||
{
|
||||
os << unit_symbol(m / s2);
|
||||
CHECK(os.str() == "m/s²");
|
||||
}
|
||||
|
||||
SECTION("Portable mode")
|
||||
{
|
||||
os << unit_symbol<unit_symbol_formatting{.encoding = portable}>(m / s2);
|
||||
CHECK(os.str() == "m/s^2");
|
||||
}
|
||||
|
||||
SECTION("solidus")
|
||||
{
|
||||
os << unit_symbol<unit_symbol_formatting{.solidus = never}>(m / s2);
|
||||
CHECK(os.str() == "m s⁻²");
|
||||
}
|
||||
|
||||
SECTION("separator")
|
||||
{
|
||||
os << unit_symbol<unit_symbol_formatting{.solidus = never, .separator = half_high_dot}>(m / s2);
|
||||
CHECK(os.str() == "m⋅s⁻²");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("dimension_symbol", "[text]")
|
||||
{
|
||||
using enum text_encoding;
|
||||
|
||||
std::ostringstream os;
|
||||
|
||||
SECTION("default formatting")
|
||||
{
|
||||
os << dimension_symbol(isq::power.dimension);
|
||||
CHECK(os.str() == "L²MT⁻³");
|
||||
}
|
||||
|
||||
SECTION("Portable mode")
|
||||
{
|
||||
os << dimension_symbol<dimension_symbol_formatting{.encoding = portable}>(isq::power.dimension);
|
||||
CHECK(os.str() == "L^2MT^-3");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("value_cast", "[text][ostream]")
|
||||
TEST_CASE("check if `value_cast` properly changes the numerical value of a quantity", "[value_cast][ostream]")
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
|
@ -43,8 +43,10 @@ using namespace mp_units::si::unit_symbols;
|
||||
|
||||
// classical
|
||||
|
||||
TEST_CASE("'pow<N>()' on quantity changes the value and the dimension accordingly", "[math][pow]")
|
||||
TEST_CASE("math operations", "[math]")
|
||||
{
|
||||
SECTION("'pow<N>()' on quantity changes the value and the dimension accordingly")
|
||||
{
|
||||
SECTION("'pow<0>(q)' returns '1'") { CHECK(pow<0>(2 * isq::length[m]) == 1 * one); }
|
||||
|
||||
SECTION("'pow<1>(q)' returns 'q'") { CHECK(pow<1>(2 * isq::length[m]) == 2 * isq::length[m]); }
|
||||
@ -58,26 +60,26 @@ TEST_CASE("'pow<N>()' on quantity changes the value and the dimension accordingl
|
||||
{
|
||||
CHECK(pow<3>(2 * isq::length[m]) == 8 * isq::volume[m3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("'sqrt()' on quantity changes the value and the dimension accordingly", "[math][sqrt]")
|
||||
{
|
||||
SECTION("'sqrt()' on quantity changes the value and the dimension accordingly")
|
||||
{
|
||||
REQUIRE(sqrt(4 * isq::area[m2]) == 2 * isq::length[m]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("'cbrt()' on quantity changes the value and the dimension accordingly", "[math][cbrt]")
|
||||
{
|
||||
SECTION("'cbrt()' on quantity changes the value and the dimension accordingly")
|
||||
{
|
||||
REQUIRE(cbrt(8 * isq::volume[m3]) == 2 * isq::length[m]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("'fma()' on quantity changes the value and the dimension accordingly", "[math][fma]")
|
||||
{
|
||||
SECTION("'fma()' on quantity changes the value and the dimension accordingly")
|
||||
{
|
||||
REQUIRE(fma(1.0 * isq::length[m], 2.0 * one, 2.0 * isq::length[m]) == 4.0 * isq::length[m]);
|
||||
REQUIRE(fma(isq::speed(10.0 * m / s), isq::time(2.0 * s), isq::height(42.0 * m)) == isq::length(62.0 * m));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("fmod functions", "[math][fmod]")
|
||||
{
|
||||
SECTION("fmod functions")
|
||||
{
|
||||
SECTION("fmod should work on the same quantities")
|
||||
{
|
||||
REQUIRE(fmod(4. * isq::length[km], 3. * isq::length[km]) == 1. * isq::length[km]);
|
||||
@ -92,10 +94,10 @@ TEST_CASE("fmod functions", "[math][fmod]")
|
||||
REQUIRE(fmod(3. * isq::length[km], 2000. * isq::length[m]) == 1000 * isq::length[m]);
|
||||
REQUIRE(fmod(4 * isq::length[km], 2500 * isq::length[m]) == 1500 * isq::length[m]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("remainder functions", "[math][remainder]")
|
||||
{
|
||||
SECTION("remainder functions")
|
||||
{
|
||||
SECTION("remainder should work on the same quantities")
|
||||
{
|
||||
REQUIRE(remainder(4. * isq::length[km], 3. * isq::length[km]) == 1. * isq::length[km]);
|
||||
@ -110,24 +112,24 @@ TEST_CASE("remainder functions", "[math][remainder]")
|
||||
REQUIRE(remainder(3. * isq::length[km], 2000. * isq::length[m]) == -1000 * isq::length[m]);
|
||||
REQUIRE(remainder(4 * isq::length[km], 2750 * isq::length[m]) == 1250 * isq::length[m]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("'isfinite()' accepts dimensioned arguments", "[math][isfinite]") { REQUIRE(isfinite(4.0 * isq::length[m])); }
|
||||
SECTION("'isfinite()' accepts dimensioned arguments") { REQUIRE(isfinite(4.0 * isq::length[m])); }
|
||||
|
||||
TEST_CASE("'isinf()' accepts dimensioned arguments", "[math][isinf]") { REQUIRE(!isinf(4.0 * isq::length[m])); }
|
||||
SECTION("'isinf()' accepts dimensioned arguments") { REQUIRE(!isinf(4.0 * isq::length[m])); }
|
||||
|
||||
TEST_CASE("'isnan()' accepts dimensioned arguments", "[math][isnan]") { REQUIRE(!isnan(4.0 * isq::length[m])); }
|
||||
SECTION("'isnan()' accepts dimensioned arguments") { REQUIRE(!isnan(4.0 * isq::length[m])); }
|
||||
|
||||
|
||||
TEST_CASE("'pow<Num, Den>()' on quantity changes the value and the dimension accordingly", "[math][pow]")
|
||||
{
|
||||
SECTION("'pow<Num, Den>()' on quantity changes the value and the dimension accordingly")
|
||||
{
|
||||
REQUIRE(pow<1, 4>(16 * isq::area[m2]) == sqrt(4 * isq::length[m]));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO add tests for exp()
|
||||
// TODO add tests for exp()
|
||||
|
||||
TEST_CASE("absolute functions on quantity returns the absolute value", "[math][abs][fabs]")
|
||||
{
|
||||
SECTION("absolute functions on quantity returns the absolute value")
|
||||
{
|
||||
SECTION("'abs()' on a negative quantity returns the abs")
|
||||
{
|
||||
SECTION("integral representation") { REQUIRE(abs(-1 * isq::length[m]) == 1 * isq::length[m]); }
|
||||
@ -141,10 +143,10 @@ TEST_CASE("absolute functions on quantity returns the absolute value", "[math][a
|
||||
|
||||
SECTION("floating-point representation") { REQUIRE(abs(1. * isq::length[m]) == 1 * isq::length[m]); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("numeric_limits functions", "[limits]")
|
||||
{
|
||||
SECTION("numeric_limits functions")
|
||||
{
|
||||
SECTION("'epsilon' works as expected using default floating type")
|
||||
{
|
||||
REQUIRE(epsilon<double>(isq::length[m]).numerical_value_in(m) ==
|
||||
@ -155,10 +157,10 @@ TEST_CASE("numeric_limits functions", "[limits]")
|
||||
REQUIRE(epsilon<int>(isq::length[m]).numerical_value_in(m) ==
|
||||
std::numeric_limits<decltype(1 * isq::length[m])::rep>::epsilon());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("floor functions", "[floor]")
|
||||
{
|
||||
SECTION("floor functions")
|
||||
{
|
||||
SECTION("floor 1 second with target unit second should be 1 second")
|
||||
{
|
||||
REQUIRE(floor<si::second>(1 * isq::time[s]) == 1 * isq::time[s]);
|
||||
@ -209,10 +211,10 @@ TEST_CASE("floor functions", "[floor]")
|
||||
}
|
||||
|
||||
// TODO Add tests for `N`, `kN` and `kg * m / s2` i `kg * km / s2`
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ceil functions", "[ceil]")
|
||||
{
|
||||
SECTION("ceil functions")
|
||||
{
|
||||
SECTION("ceil 1 second with target unit second should be 1 second")
|
||||
{
|
||||
REQUIRE(ceil<si::second>(1 * isq::time[s]) == 1 * isq::time[s]);
|
||||
@ -261,10 +263,10 @@ TEST_CASE("ceil functions", "[ceil]")
|
||||
{
|
||||
REQUIRE(ceil<si::second>(-999. * isq::time[ms]) == 0 * isq::time[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("round functions", "[round]")
|
||||
{
|
||||
SECTION("round functions")
|
||||
{
|
||||
SECTION("round 1 second with target unit second should be 1 second")
|
||||
{
|
||||
REQUIRE(round<si::second>(1 * isq::time[s]) == 1 * isq::time[s]);
|
||||
@ -349,10 +351,10 @@ TEST_CASE("round functions", "[round]")
|
||||
{
|
||||
REQUIRE(round<si::second>(-1999. * isq::time[ms]) == -2 * isq::time[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("hypot functions", "[hypot]")
|
||||
{
|
||||
SECTION("hypot functions")
|
||||
{
|
||||
SECTION("hypot should work on the same quantities")
|
||||
{
|
||||
REQUIRE(hypot(3. * isq::length[km], 4. * isq::length[km]) == 5. * isq::length[km]);
|
||||
@ -363,10 +365,10 @@ TEST_CASE("hypot functions", "[hypot]")
|
||||
REQUIRE(hypot(3. * isq::length[km], 4000. * isq::length[m]) == 5. * isq::length[km]);
|
||||
REQUIRE(hypot(2. * isq::length[km], 3000. * isq::length[m], 6. * isq::length[km]) == 7. * isq::length[km]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("SI trigonometric functions", "[trig][si]")
|
||||
{
|
||||
SECTION("SI trigonometric functions")
|
||||
{
|
||||
SECTION("sin")
|
||||
{
|
||||
REQUIRE_THAT(si::sin(0 * deg), AlmostEquals(0. * one));
|
||||
@ -390,10 +392,10 @@ TEST_CASE("SI trigonometric functions", "[trig][si]")
|
||||
REQUIRE_THAT(si::tan(135. * deg), AlmostEquals(-1. * one));
|
||||
REQUIRE_THAT(si::tan(180. * deg), AlmostEquals(0. * one));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("SI inverse trigonometric functions", "[inv trig][si]")
|
||||
{
|
||||
SECTION("SI inverse trigonometric functions")
|
||||
{
|
||||
SECTION("asin")
|
||||
{
|
||||
REQUIRE_THAT(si::asin(-1 * one), AlmostEquals(-90. * deg));
|
||||
@ -414,10 +416,10 @@ TEST_CASE("SI inverse trigonometric functions", "[inv trig][si]")
|
||||
REQUIRE_THAT(si::atan(0 * one), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(si::atan(1 * one), AlmostEquals(45. * deg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("SI atan2 functions", "[atan2][si]")
|
||||
{
|
||||
SECTION("SI atan2 functions")
|
||||
{
|
||||
SECTION("atan2 should work on the same quantities")
|
||||
{
|
||||
REQUIRE_THAT(si::atan2(-1. * isq::length[km], 1. * isq::length[km]), AlmostEquals(-45. * deg));
|
||||
@ -430,11 +432,10 @@ TEST_CASE("SI atan2 functions", "[atan2][si]")
|
||||
REQUIRE_THAT(si::atan2(0. * isq::length[km], 1000. * isq::length[m]), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(si::atan2(1. * isq::length[km], 1000. * isq::length[m]), AlmostEquals(45. * deg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Angle trigonometric functions", "[trig][angle]")
|
||||
{
|
||||
SECTION("Angle trigonometric functions")
|
||||
{
|
||||
using namespace mp_units::angular;
|
||||
using namespace mp_units::angular::unit_symbols;
|
||||
using mp_units::angular::unit_symbols::deg;
|
||||
@ -477,10 +478,10 @@ TEST_CASE("Angle trigonometric functions", "[trig][angle]")
|
||||
REQUIRE_THAT(tan(150 * angle[grad]), AlmostEquals(-1. * one));
|
||||
REQUIRE_THAT(tan(200 * angle[grad]), AlmostEquals(0. * one, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Angle inverse trigonometric functions", "[inv trig][angle]")
|
||||
{
|
||||
SECTION("Angle inverse trigonometric functions")
|
||||
{
|
||||
using namespace mp_units::angular;
|
||||
using namespace mp_units::angular::unit_symbols;
|
||||
using mp_units::angular::unit_symbols::deg;
|
||||
@ -505,10 +506,10 @@ TEST_CASE("Angle inverse trigonometric functions", "[inv trig][angle]")
|
||||
REQUIRE_THAT(atan(0 * one), AlmostEquals(0. * angle[deg]));
|
||||
REQUIRE_THAT(atan(1 * one), AlmostEquals(45. * angle[deg]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Angle atan2 functions", "[atan2][angle]")
|
||||
{
|
||||
SECTION("Angle atan2 functions")
|
||||
{
|
||||
using namespace mp_units::angular;
|
||||
using namespace mp_units::angular::unit_symbols;
|
||||
using mp_units::angular::unit_symbols::deg;
|
||||
@ -525,4 +526,5 @@ TEST_CASE("Angle atan2 functions", "[atan2][angle]")
|
||||
REQUIRE_THAT(atan2(0. * isq::length[km], 1000. * isq::length[m]), AlmostEquals(0. * angle[deg]));
|
||||
REQUIRE_THAT(atan2(1. * isq::length[km], 1000. * isq::length[m]), AlmostEquals(45. * angle[deg]));
|
||||
}
|
||||
}
|
||||
}
|
@ -60,22 +60,25 @@ constexpr bool within_4_ulps(T a, T b)
|
||||
|
||||
} // namespace
|
||||
|
||||
// conversion requiring radical magnitudes
|
||||
TEST_CASE("unit conversions support radical magnitudes", "[conversion][radical]")
|
||||
TEST_CASE("quantity operations", "[quantity]")
|
||||
{
|
||||
// conversion requiring radical magnitudes
|
||||
SECTION("unit conversions support radical magnitudes")
|
||||
{
|
||||
REQUIRE(within_4_ulps(sqrt((1.0 * m) * (1.0 * km)).numerical_value_in(m), sqrt(1000.0)));
|
||||
}
|
||||
}
|
||||
|
||||
// Reproducing issue #474 exactly:
|
||||
TEST_CASE("Issue 474 is fixed", "[conversion][radical]")
|
||||
{
|
||||
// Reproducing issue #474 exactly:
|
||||
SECTION("Issue 474 is fixed")
|
||||
{
|
||||
constexpr auto val_issue_474 = 8.0 * si::si2019::boltzmann_constant * 1000.0 * K / (std::numbers::pi * 10 * Da);
|
||||
REQUIRE(within_4_ulps(sqrt(val_issue_474).numerical_value_in(m / s),
|
||||
sqrt(val_issue_474.numerical_value_in(m * m / s / s))));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Volatile representation type", "[volatile]")
|
||||
{
|
||||
SECTION("Volatile representation type")
|
||||
{
|
||||
volatile std::int16_t vint = 123;
|
||||
REQUIRE(quantity(vint * m).numerical_value_in(m) == 123);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user