From 52acdd8337b87028e31aa8ed1d08e984892c63fd Mon Sep 17 00:00:00 2001 From: "Peter Doak (epd)" <doakpw@ornl.gov> Date: Thu, 30 Jan 2025 10:55:09 -0500 Subject: [PATCH] adding unit tests --- src/Utilities/for_testing/checkVector.hpp | 21 +++--- .../tests/for_testing/CMakeLists.txt | 4 +- .../test_NativeInitializerPrint.cpp | 61 +++++++++++++++ .../tests/for_testing/test_checkVector.cpp | 74 +++++++++++++++++++ 4 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 src/Utilities/tests/for_testing/test_NativeInitializerPrint.cpp create mode 100644 src/Utilities/tests/for_testing/test_checkVector.cpp diff --git a/src/Utilities/for_testing/checkVector.hpp b/src/Utilities/for_testing/checkVector.hpp index b405a9ed6c..f31ce89948 100644 --- a/src/Utilities/for_testing/checkVector.hpp +++ b/src/Utilities/for_testing/checkVector.hpp @@ -29,7 +29,7 @@ struct CheckVectorResult std::string result_message; }; - /** This function checks equality a_vec and b_vec elements +/** This function checks equality a_vec and b_vec elements * M1, M2 need to have their element type declared M1::value_type * and have an operator(i,j) accessor. * I leave the c++14 template meta programming to insure @@ -53,21 +53,20 @@ CheckVectorResult checkVector(M1& a_vec, return {false, "b_vec is too small for a_vec to be a checkable segment"}; std::stringstream error_msg; auto vectorElementError = [&error_msg](int i, auto& a_vec, auto& b_vec) { - error_msg << "checkVector found bad element at " << i << " " << a_vec[i] << " != " << b_vec[i] - << '\n'; + error_msg << "checkVector found bad element at " << i << " " << a_vec[i] << " != " << b_vec[i] << '\n'; }; bool all_elements_match = true; for (int i = 0; i < a_vec.size(); i++) + { + bool approx_equality = approxEquality<typename M1::value_type>(a_vec[i], b_vec[i], eps); + if (!approx_equality) { - bool approx_equality = approxEquality<typename M1::value_type>(a_vec[i], b_vec[i], eps); - if (!approx_equality) - { - vectorElementError(i, a_vec, b_vec); - all_elements_match = false; - if (!check_all) - return {false, error_msg.str()}; - } + vectorElementError(i, a_vec, b_vec); + all_elements_match = false; + if (!check_all) + return {false, error_msg.str()}; } + } return {all_elements_match, error_msg.str()}; } } // namespace qmcplusplus diff --git a/src/Utilities/tests/for_testing/CMakeLists.txt b/src/Utilities/tests/for_testing/CMakeLists.txt index 6d593fa9d3..e5f2e5a842 100644 --- a/src/Utilities/tests/for_testing/CMakeLists.txt +++ b/src/Utilities/tests/for_testing/CMakeLists.txt @@ -2,7 +2,7 @@ #// This file is distributed under the University of Illinois/NCSA Open Source License. #// See LICENSE file in top directory for details. #// -#// Copyright (c) 2021 QMCPACK developers. +#// Copyright (c) 2025 QMCPACK developers. #// #// File developed by: Peter Doak, , doakpw@ornl.gov, Oak Ridge National Laboratory #////////////////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ set(TEST_NAME utilities_for_testing) set(UTEST_EXE test_${TEST_NAME}) set(UTEST_NAME deterministic-unit_test_${TEST_NAME}) -add_executable(${UTEST_EXE} test_checkMatrix.cpp test_RandomForTest.cpp) +add_executable(${UTEST_EXE} test_checkMatrix.cpp test_checkVector.cpp test_RandomForTest.cpp test_NativeInitializerPrint.cpp) target_link_libraries(${UTEST_EXE} catch_main_no_mpi utilities_for_test containers) target_include_directories(${UTEST_EXE} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/src/Utilities/tests/for_testing/test_NativeInitializerPrint.cpp b/src/Utilities/tests/for_testing/test_NativeInitializerPrint.cpp new file mode 100644 index 0000000000..04d9a0190c --- /dev/null +++ b/src/Utilities/tests/for_testing/test_NativeInitializerPrint.cpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source License. +// See LICENSE file in top directory for details. +// +// Copyright (c) 2025 QMCPACK developers. +// +// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +////////////////////////////////////////////////////////////////////////////////////// + +#include "catch.hpp" +#include <iostream> +#include <string> +#include <array> +#include <unordered_map> +#include <strstream> +#include "NativeInitializerPrint.hpp" + +/** \file + * Tests NativeInitializerPrint more strictly than necessary, what it really needs to produce + * is a text representation that can be pasted into test programs and produce the same + * Native representation as the object that was written out. That would require a second pass + * of compilation as part of the test program which I'd be impressed if someone could + * figure out how to integrate with our unite testing. + */ +namespace qmcplusplus +{ + +TEST_CASE("NativePrint::array", "[utilities][for_testing]") +{ + std::ostringstream oss; + std::array<double, 4> test_array{1.1, 2.2, 3.3, 4.4}; + oss << NativePrint(test_array); + CHECK(std::string("{ 1.1, 2.2, 3.3, 4.4, }") == oss.str()); + std::array<double, 4> test_array2{1.11111111111111, 2.2222222222222, 3.333333333333333, 4.44444444444444}; + std::ostringstream oss2; + oss2 << NativePrint(test_array2); + CHECK(std::string("{ 1.111111111, 2.222222222, 3.333333333, 4.444444444, }") == oss2.str()); +} + +TEST_CASE("NativePrint::unordered_map<std::string, std::vector<Vector<T>>>", "[utilities][for_testing]") +{ + std::ostringstream oss; + std::unordered_map<std::string, std::vector<Vector<double>>> test_map{{"alpha", {{0.0, 1.1}, {2.2}}}, + {"beta", {{3.3}, {4.4}}}, + {"lambda", {{6.5, 3.6}, {3.2, 3.3}}}}; + oss << NativePrint(test_map); + CHECK(std::string("{{{\"lambda\"}, {{6.5, 3.6, },{3.2, 3.3, }, }},\n{{\"beta\"}, {{3.3, },{4.4, }, " + "}},\n{{\"alpha\"}, {{0, 1.1, },{2.2, }, }},\n};") == oss.str()); + + std::ostringstream oss2; + std::unordered_map<std::string, std::vector<Vector<int>>> test_map2{{"alpha", {{0, 1}, {2}}}, + {"beta", {{3}, {4}}}, + {"lambda", {{6, 3}, {3, 3}}}}; + oss2 << NativePrint(test_map2); + CHECK(std::string("{{{\"lambda\"}, {{6, 3, },{3, 3, }, }},\n{{\"beta\"}, {{3, },{4, }, " + "}},\n{{\"alpha\"}, {{0, 1, },{2, }, }},\n};") == oss2.str()); + +} +} // namespace qmcplusplus diff --git a/src/Utilities/tests/for_testing/test_checkVector.cpp b/src/Utilities/tests/for_testing/test_checkVector.cpp new file mode 100644 index 0000000000..e37f6eb559 --- /dev/null +++ b/src/Utilities/tests/for_testing/test_checkVector.cpp @@ -0,0 +1,74 @@ +////////////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source License. +// See LICENSE file in top directory for details. +// +// Copyright (c) 2025 QMCPACK developers. +// +// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +////////////////////////////////////////////////////////////////////////////////////// + +#include "catch.hpp" +#include "checkVector.hpp" +#include <iostream> +#include <string> +#include "OhmmsPETE/OhmmsVector.h" + +/** \file + * Tests checkVector + */ +namespace qmcplusplus +{ + +TEST_CASE("checkVector_OhmmsVector_real", "[utilities][for_testing]") +{ + Vector<double> a_vec; + a_vec.resize(3); + a_vec[0] = 2.3; + a_vec[1] = 4.5; + a_vec[2] = 2.6; + + Vector<double> b_vec; + b_vec.resize(3); + b_vec[0] = 2.3; + b_vec[1] = 4.5; + b_vec[2] = 2.6; + + auto check_vector_result = checkVector(a_vec, b_vec); + // This would be how you would fail and print the information about what element failed. + CHECKED_ELSE(check_vector_result.result) { FAIL(check_vector_result.result_message); } + + //check with epsilon + b_vec[2] = 2.6005; + check_vector_result = checkVector(a_vec, b_vec, false, 1e-4); + REQUIRE(check_vector_result.result == false); + check_vector_result = checkVector(a_vec, b_vec, false, 1e-3); + REQUIRE(check_vector_result.result == true); + + b_vec.resize(4); + b_vec[0] = 2.3; + b_vec[1] = 4.5; + b_vec[2] = 2.6; + + check_vector_result = checkVector(a_vec, b_vec); + CHECKED_ELSE(check_vector_result.result) { FAIL(check_vector_result.result_message); } + + b_vec[0] = 1.0; + b_vec[1] = 3.6; + check_vector_result = checkVector(a_vec, b_vec, true); + std::string::size_type pos = 0; + int lines = 0; + while (true) + { + pos = check_vector_result.result_message.find("\n", pos); + if (pos == std::string::npos) + break; + ++pos; + ++lines; + } + CHECK(lines == 2); + REQUIRE(check_vector_result.result == false); +} + +} // namespace qmcplusplus