feat(surface): major work on implementing surface constraints in a presciption agnostic manner

This commit is contained in:
2026-08-30 16:41:14 -04:00
parent 36adfa1174
commit 0a7f18c5c7
95 changed files with 30144 additions and 25766 deletions

View File

@@ -3,6 +3,7 @@
#include <catch2/catch_test_case_info.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <chrono>
#include <fstream>
#include <iomanip>
#include <iostream>
@@ -223,6 +224,7 @@ class CheckReporter : public Catch::StreamingReporterBase {
bool passed;
std::size_t assertionsPassed;
std::size_t assertionsFailed;
double durationSeconds;
std::vector<std::string> failureMessages;
std::vector<std::string> infoMessages;
};
@@ -231,6 +233,7 @@ class CheckReporter : public Catch::StreamingReporterBase {
std::vector<std::string> m_currentInfos;
std::unordered_set<unsigned int> m_currentInfoSequences;
std::vector<TestCaseData> m_testRunData;
std::chrono::time_point<std::chrono::steady_clock> m_testStartTime;
void captureInfoMessages(Catch::AssertionStats const &assertionStats) {
for (auto const &message : assertionStats.infoMessages) {
@@ -253,9 +256,8 @@ public:
}
static std::string getDescription() {
return "Console reporter with wrapping, tags, and collapsible HTML "
"export "
"with ANSI color rendering.";
return "Console reporter with wrapping, tags, live test progress, and collapsible HTML "
"export with ANSI color rendering.";
}
void testRunStarting(Catch::TestRunInfo const &_testRunInfo) override {
@@ -263,8 +265,20 @@ public:
std::cout << '\n';
std::cout << std::left << std::setw(85) << "Test Case Name"
<< "Status " << std::right << std::setw(8) << "Passed" << std::setw(8) << "Failed" << '\n';
std::cout << std::string(121, '-') << '\n';
<< "Status " << std::right << std::setw(8) << "Passed" << std::setw(8) << "Failed" << std::setw(12)
<< "Time (s)" << '\n';
std::cout << std::string(133, '-') << '\n';
}
void testCaseStarting(Catch::TestCaseInfo const &testInfo) override {
StreamingReporterBase::testCaseStarting(testInfo);
m_testStartTime = std::chrono::steady_clock::now();
std::string name = testInfo.name;
auto wrappedName = wrapText(name, 83);
// Print progress line, \r to overwrite later, \033[K to clear till end of line
std::cout << "\r\033[K" << std::left << std::setw(85) << (wrappedName[0] + " ...") << std::flush;
}
void assertionEnded(Catch::AssertionStats const &assertionStats) override {
@@ -300,14 +314,20 @@ public:
void testCaseEnded(Catch::TestCaseStats const &stats) override {
StreamingReporterBase::testCaseEnded(stats);
bool passed = stats.totals.assertions.allPassed();
std::string mark = passed ? "\033[32m✓\033[0m" : "\033[31m✗\033[0m";
auto endTime = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed = endTime - m_testStartTime;
double duration_s = elapsed.count();
std::string name = stats.testInfo->name;
auto wrappedName = wrapText(name, 83);
bool passed = stats.totals.assertions.allPassed();
std::string mark = passed ? "\033[32m✓\033[0m" : "\033[31m✗\033[0m";
std::cout << std::left << std::setw(85) << wrappedName[0] << mark << " " << std::right << std::setw(8)
<< stats.totals.assertions.passed << std::setw(8) << stats.totals.assertions.failed << '\n';
std::string name = stats.testInfo->name;
auto wrappedName = wrapText(name, 83);
// Overwrite the loading line with the actual result
std::cout << "\r\033[K" << std::left << std::setw(85) << wrappedName[0] << mark << " " << std::right
<< std::setw(8) << stats.totals.assertions.passed << std::setw(8) << stats.totals.assertions.failed
<< std::setw(11) << std::fixed << std::setprecision(3) << duration_s << "s\n";
for (size_t i = 1; i < wrappedName.size(); ++i) {
std::cout << " \033[90m↳ \033[0m" // Dim indent arrow
@@ -327,12 +347,12 @@ public:
for (auto const &failure : m_currentFailures) {
std::cout << failure << '\n';
}
std::cout << std::string(121, '-') << '\n';
std::cout << std::string(133, '-') << '\n';
}
m_testRunData.push_back(
{name, tagsStr, passed, stats.totals.assertions.passed, stats.totals.assertions.failed, m_currentFailures,
m_currentInfos}
{name, tagsStr, passed, stats.totals.assertions.passed, stats.totals.assertions.failed, duration_s,
m_currentFailures, m_currentInfos}
);
m_currentFailures.clear();
@@ -343,7 +363,7 @@ public:
void testRunEnded(Catch::TestRunStats const &_testRunStats) override {
StreamingReporterBase::testRunEnded(_testRunStats);
std::cout << std::string(121, '=') << '\n';
std::cout << std::string(133, '=') << '\n';
auto const &tc = _testRunStats.totals.testCases;
auto const &as = _testRunStats.totals.assertions;
@@ -444,7 +464,9 @@ private:
html << " </div>\n";
html << " <div class='stats'>\n";
html << " <span class='text-green'>&#10003; " << test.assertionsPassed << "</span> | ";
html << " <span class='text-red'>&#10007; " << test.assertionsFailed << "</span>\n";
html << " <span class='text-red'>&#10007; " << test.assertionsFailed << "</span> | ";
html << " <span style='color: #34495e;'>&#8987; " << std::fixed << std::setprecision(3)
<< test.durationSeconds << "s</span>\n";
html << " </div>\n";
html << " </div>\n";
@@ -589,4 +611,4 @@ int main(
test_utils::set_args(std::move(test_args));
return session.run();
}
}