#include "test_harness.h" #include #include #include #include void TestHarness::AddTest(const std::string& name, std::function func) { m_tests.push_back({name, func}); } std::vector TestHarness::Run(const std::string& filter) { std::vector results; for (const auto& test : m_tests) { // Filter check if (!filter.empty() && test.name.find(filter) == std::string::npos) { continue; } TestResult result; result.name = test.name; std::cout << "Running: " << test.name << "... " << std::flush; auto start = std::chrono::steady_clock::now(); try { std::string error; result.passed = test.func(error); result.error_message = error; } catch (const std::exception& e) { result.passed = false; result.error_message = std::string("Exception: ") + e.what(); } catch (...) { result.passed = false; result.error_message = "Unknown exception"; } auto end = std::chrono::steady_clock::now(); result.duration_ms = std::chrono::duration_cast(end - start).count(); if (result.passed) { std::cout << "PASSED (" << result.duration_ms << "ms)\n"; } else { std::cout << "FAILED\n"; std::cout << " Error: " << result.error_message << "\n"; } results.push_back(result); } return results; } void TestHarness::WriteJsonReport(const std::vector& results, const std::string& path) { nlohmann::json report; // Get timestamp auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); std::stringstream ss; ss << std::put_time(std::gmtime(&time), "%Y-%m-%dT%H:%M:%SZ"); report["name"] = "Lua Sandbox Security Tests"; report["timestamp"] = ss.str(); int passed = 0, failed = 0; for (const auto& r : results) { if (r.passed) passed++; else failed++; } report["summary"]["passed"] = passed; report["summary"]["failed"] = failed; report["summary"]["total"] = static_cast(results.size()); nlohmann::json tests = nlohmann::json::array(); for (const auto& r : results) { nlohmann::json t; t["name"] = r.name; t["status"] = r.passed ? "passed" : "failed"; t["duration_ms"] = r.duration_ms; if (!r.passed && !r.error_message.empty()) { t["error"] = r.error_message; } tests.push_back(t); } report["tests"] = tests; std::ofstream f(path); f << report.dump(2); } void TestHarness::PrintResults(const std::vector& results) { std::cout << "\n"; std::cout << "========================================\n"; std::cout << " TEST RESULTS\n"; std::cout << "========================================\n\n"; int passed = 0, failed = 0; for (const auto& r : results) { if (r.passed) passed++; else failed++; } std::cout << "Total: " << results.size() << "\n"; std::cout << "Passed: " << passed << "\n"; std::cout << "Failed: " << failed << "\n\n"; if (failed > 0) { std::cout << "FAILED TESTS:\n"; for (const auto& r : results) { if (!r.passed) { std::cout << " - " << r.name << "\n"; std::cout << " " << r.error_message << "\n"; } } std::cout << "\n"; } if (failed == 0) { std::cout << "ALL TESTS PASSED!\n"; } else { std::cout << "SOME TESTS FAILED!\n"; } std::cout << "========================================\n"; }