// ===================================================================================================================== // fennec-test, a program to execute unit tests for fennec // Copyright © 2025 Medusa Slockbower // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // ===================================================================================================================== #ifndef FENNEC_TEST_H #define FENNEC_TEST_H #include #include #include #include #include #include #include #include namespace fennec { namespace test { // Helper for printing vectors template inline std::ostream& operator<<(std::ostream& os, const vector& v) { os << "< "; ((os << v[IndicesV] << " "), ...); os << ">"; return os; } // Helper for printing matrices template inline std::ostream& operator<<(std::ostream& os, const matrix& m) { os << "[ "; ((os << m[ColIndicesV] << " "), ...); os << "]"; return os; } // Core test function template inline void __fennec_test_run(const std::string& expression, const ResultT result, const ResultT expected) { // Print out the expression as a string and the resulting value std::cout << std::boolalpha; std::cout << '\t' << expression << " = " << result; bool passed = false; // Check scalar arithmetic values if constexpr(is_arithmetic_v) { passed = result == expected; if constexpr(not is_bool_v) passed |= fennec::abs(expected - result) <= numeric_limits::epsilon(); } // Check non-boolean vector values else if constexpr(is_vector_v) { passed = result == expected; if constexpr(not is_bool_v) passed |= fennec::all(fennec::lessThanEqual(fennec::abs(expected - result), ResultT(numeric_limits::epsilon()))); } // Base Case, simple comparison else { passed = result == expected; } // Print out expected when failed if (not passed) std::cout << ", expected " << expected; std::cout << std::endl; // Assert to halt and get some debug info assert(passed, "Test Failed"); } } } #define fennec_test_run(Expression, Expected) __fennec_test_run(#Expression, Expression, Expected) #define fennec_test_header(Header) std::cout << std::string(80, '=') << std::endl \ << (Header) << std::endl \ << std::string(80, '=') << std::endl #define fennec_test_subheader(Header) std::cout << (Header) << ' ' << std::string(80 - sizeof(Header), '=') << std::endl #define fennec_test_section(Section) std::cout << (Section) << ' ' << std::string(80 - sizeof(Section), '-') << std::endl #define fennec_test_spacer(Count) std::cout << std::string(Count, std::cout.widen('\n')) #endif // FENNEC_TEST_H