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