Files
MeanField_SERiF/tests/utils/laneemden/formatting.cpp
Emily Boudreaux cb20faeb3d test(tests): added test suite
The test suite is extensive. Note that LLMs were used to aid in the development of the test suite. All LLM generated code was manually reviewed.
2026-11-09 13:53:17 -05:00

72 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <array>
#include <format>
#include <iterator>
#include <string>
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_string.hpp>
#include "serif/utils/laneemden/solution.hpp"
namespace {
namespace laneemden = serif::utils::laneemden;
constexpr laneemden::Sample sample{.xi = 2.0, .theta = 0.5, .derivative = -0.25};
/** @brief Use distinct profile and surface values so selection forwarding is observable. */
[[nodiscard]] laneemden::Solution example_solution() {
return {
.n = 1.0,
.samples = {{.xi = 0.0, .theta = 1.0, .derivative = 0.0}, sample},
.surface = laneemden::Sample{.xi = 3.0, .theta = 0.0, .derivative = -0.5}
};
}
}
TEST_CASE("Lane Emden sample formatting selects complete or individual values", "[laneemden][formatting]") {
CHECK(std::format("{}", sample) == "(ξ=2, θ=0.5, dθ/dξ=-0.25)");
CHECK(std::format("{:}", sample) == std::format("{}", sample));
CHECK(std::format("{:all}", sample) == std::format("{}", sample));
CHECK(std::format("{:xi}", sample) == "2");
CHECK(std::format("{:theta}", sample) == "0.5");
CHECK(std::format("{:derivative}", sample) == "-0.25");
CHECK(std::format("{1:theta} / {0:xi}", sample, sample) == "0.5 / 2");
CHECK(std::format("{{{:xi}}}", sample) == "{2}");
}
TEST_CASE("Lane Emden solution formatting forwards selection to its profile and surface", "[laneemden][formatting]") {
const auto solution = example_solution();
CHECK(std::format("{}", solution) == "Solution(n=1, samples=[(ξ=0, θ=1, dθ/dξ=0), (ξ=2, θ=0.5, dθ/dξ=-0.25)], surface=(ξ=3, θ=0, dθ/dξ=-0.5))");
CHECK(std::format("{:}", solution) == std::format("{}", solution));
CHECK(std::format("{:all}", solution) == std::format("{}", solution));
CHECK(std::format("{:xi}", solution) == "Solution(n=1, samples=[0, 2], surface=3)");
CHECK(std::format("{:theta}", solution) == "Solution(n=1, samples=[1, 0.5], surface=0)");
CHECK(std::format("{:derivative}", solution) == "Solution(n=1, samples=[0, -0.25], surface=-0.5)");
const laneemden::Solution empty{.n = 5.0, .samples = {}, .surface = {}};
CHECK(std::format("{}", empty) == "Solution(n=5, samples=[], surface=none)");
CHECK(std::format("{:theta}", empty) == "Solution(n=5, samples=[], surface=none)");
}
TEST_CASE("Lane Emden formatters preserve surrounding output and independent selectors", "[laneemden][formatting]") {
const auto solution = example_solution();
const std::string expected = "prefix Solution(n=1, samples=[1, 0.5], surface=0) | 2 | Solution(n=1, samples=[0, -0.25], surface=-0.5) suffix";
std::string appended = "prefix ";
std::format_to(std::back_inserter(appended), "{:theta} | {:xi} | {:derivative} suffix", solution, sample, solution);
CHECK(appended == expected);
std::array<char, 512> buffer{};
const auto end = std::format_to(buffer.data(), "prefix {:theta} | {:xi} | {:derivative} suffix", solution, sample, solution);
CHECK(std::string(buffer.data(), end) == expected);
}
TEST_CASE("Lane Emden formatters reject unsupported selectors through the central error helper", "[laneemden][formatting]") {
const auto solution = example_solution();
for (const std::string specifier : {"radius", "xi,theta", "theta ", ".2f", "theta:.2f"}) {
CAPTURE(specifier);
const std::string format = "{:" + specifier + "}";
CHECK_THROWS_AS(std::vformat(format, std::make_format_args(sample)), std::format_error);
CHECK_THROWS_AS(std::vformat(format, std::make_format_args(solution)), std::format_error);
CHECK_THROWS_WITH(std::vformat(format, std::make_format_args(sample)), Catch::Matchers::ContainsSubstring("Unknown Lane–Emden sample selector"));
}
CHECK_THROWS_AS(std::vformat("{:xi", std::make_format_args(sample)), std::format_error);
CHECK_THROWS_AS(std::vformat("{:theta", std::make_format_args(solution)), std::format_error);
}