Просмотр исходного кода

cleand cmake and added INSTANTIATE_TEST_CASE_P

Teseo Schneider 6 лет назад
Родитель
Сommit
49a74590d4

+ 14 - 14
tests/CMakeLists.txt

@@ -16,10 +16,7 @@ set(IGL_TEST_DATA ${LIBIGL_EXTERNAL}/../tests/data)
 
 
 ### Download Google unit test framework.
 ### Download Google unit test framework.
 igl_download_catch2()
 igl_download_catch2()
-
-SET(TEST_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
 list(APPEND CMAKE_MODULE_PATH ${LIBIGL_EXTERNAL}/Catch2/contrib)
 list(APPEND CMAKE_MODULE_PATH ${LIBIGL_EXTERNAL}/Catch2/contrib)
-INCLUDE_DIRECTORIES(${TEST_ROOT_DIR})
 
 
 
 
 
 
@@ -28,9 +25,12 @@ INCLUDE_DIRECTORIES(${TEST_ROOT_DIR})
 add_library(catch INTERFACE)
 add_library(catch INTERFACE)
 target_include_directories(catch SYSTEM INTERFACE ${LIBIGL_EXTERNAL}/catch2/single_include)
 target_include_directories(catch SYSTEM INTERFACE ${LIBIGL_EXTERNAL}/catch2/single_include)
 
 
+
 # Create test executable
 # Create test executable
 add_executable(libigl_tests main.cpp test_common.h)
 add_executable(libigl_tests main.cpp test_common.h)
 target_link_libraries(libigl_tests PUBLIC igl::core catch)
 target_link_libraries(libigl_tests PUBLIC igl::core catch)
+target_include_directories(libigl_tests PUBLIC ${CMAKE_CURRENT_LIST_DIR})
+
 # Set TEST_DIR definition
 # Set TEST_DIR definition
 set(DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/data/")
 set(DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/data/")
 target_compile_definitions(libigl_tests PUBLIC -DLIBIGL_DATA_DIR="${IGL_TEST_DATA}")
 target_compile_definitions(libigl_tests PUBLIC -DLIBIGL_DATA_DIR="${IGL_TEST_DATA}")
@@ -39,40 +39,40 @@ target_compile_definitions(libigl_tests PUBLIC -DLIBIGL_DATA_DIR="${IGL_TEST_DAT
 # Process code in each subdirectories: add in decreasing order of complexity
 # Process code in each subdirectories: add in decreasing order of complexity
 # (last added will run first and those should be the fastest tests)
 # (last added will run first and those should be the fastest tests)
 IF(LIBIGL_WITH_MOSEK)
 IF(LIBIGL_WITH_MOSEK)
-  file(GLOB TEST_SRC_FILES ${TEST_ROOT_DIR}/include/igl/mosek/*.cpp)
-  file(GLOB TEST_INC_FILES ${TEST_ROOT_DIR}/include/igl/mosek/*.h ${TEST_ROOT_DIR}/include/igl/mosek/*.inl)
+  file(GLOB TEST_SRC_FILES ./include/igl/mosek/*.cpp)
+  file(GLOB TEST_INC_FILES ./include/igl/mosek/*.h ./include/igl/mosek/*.inl)
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
 
 
   target_link_libraries(libigl_tests PUBLIC igl::mosek)
   target_link_libraries(libigl_tests PUBLIC igl::mosek)
 ENDIF()
 ENDIF()
 
 
 IF(LIBIGL_WITH_CGAL)
 IF(LIBIGL_WITH_CGAL)
-  file(GLOB TEST_SRC_FILES ${TEST_ROOT_DIR}/include/igl/copyleft/boolean/*.cpp ${TEST_ROOT_DIR}/include/igl/copyleft/cgal/*.cpp)
-  file(GLOB TEST_INC_FILES ${TEST_ROOT_DIR}/include/igl/copyleft/boolean/*.h ${TEST_ROOT_DIR}/include/igl/copyleft/cgal/*.h ${TEST_ROOT_DIR}/include/igl/copyleft/boolean/*.inl ${TEST_ROOT_DIR}/include/igl/copyleft/cgal/*.inl)
+  file(GLOB TEST_SRC_FILES ./include/igl/copyleft/boolean/*.cpp ./include/igl/copyleft/cgal/*.cpp)
+  file(GLOB TEST_INC_FILES ./include/igl/copyleft/boolean/*.h ./include/igl/copyleft/cgal/*.h ./include/igl/copyleft/boolean/*.inl ./include/igl/copyleft/cgal/*.inl)
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
 
 
-  target_link_libraries(libigl_tests PUBLIC igl::igl::cgal)
+  target_link_libraries(libigl_tests PUBLIC igl::cgal)
 ENDIF()
 ENDIF()
 
 
 IF(LIBIGL_WITH_TETGEN)
 IF(LIBIGL_WITH_TETGEN)
-  file(GLOB TEST_SRC_FILES ${TEST_ROOT_DIR}/include/igl/copyleft/tetgen/*.cpp)
-  file(GLOB TEST_INC_FILES ${TEST_ROOT_DIR}/include/igl/copyleft/tetgen/*.h ${TEST_ROOT_DIR}/include/igl/copyleft/tetgen/*.inl)
+  file(GLOB TEST_SRC_FILES ./include/igl/copyleft/tetgen/*.cpp)
+  file(GLOB TEST_INC_FILES ./include/igl/copyleft/tetgen/*.h ./include/igl/copyleft/tetgen/*.inl)
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
 
 
   target_link_libraries(libigl_tests PUBLIC igl::tetgen)
   target_link_libraries(libigl_tests PUBLIC igl::tetgen)
 ENDIF()
 ENDIF()
 
 
 IF(LIBIGL_WITH_COMISO)
 IF(LIBIGL_WITH_COMISO)
-  file(GLOB TEST_SRC_FILES ${TEST_ROOT_DIR}/include/igl/copyleft/comiso/*.cpp)
-  file(GLOB TEST_INC_FILES ${TEST_ROOT_DIR}/include/igl/copyleft/comiso/*.h ${TEST_ROOT_DIR}/include/igl/copyleft/comiso/*.inl)
+  file(GLOB TEST_SRC_FILES ./include/igl/copyleft/comiso/*.cpp)
+  file(GLOB TEST_INC_FILES ./include/igl/copyleft/comiso/*.h ./include/igl/copyleft/comiso/*.inl)
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
   target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
 
 
   target_link_libraries(libigl_tests PUBLIC igl::comiso)
   target_link_libraries(libigl_tests PUBLIC igl::comiso)
 ENDIF()
 ENDIF()
 
 
 
 
-file(GLOB TEST_SRC_FILES ${TEST_ROOT_DIR}/include/igl/*.cpp)
-file(GLOB TEST_INC_FILES ${TEST_ROOT_DIR}/include/igl/*.h ${TEST_ROOT_DIR}/include/igl/*.inl)
+file(GLOB TEST_SRC_FILES ./include/igl/*.cpp)
+file(GLOB TEST_INC_FILES ./include/igl/*.h ./include/igl/*.inl)
 target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
 target_sources(libigl_tests PRIVATE ${TEST_SRC_FILES} ${TEST_INC_FILES})
 
 
 
 

+ 23 - 27
tests/include/igl/cotmatrix.cpp

@@ -1,33 +1,29 @@
 #include <test_common.h>
 #include <test_common.h>
 #include <igl/cotmatrix.h>
 #include <igl/cotmatrix.h>
 
 
-// class cotmatrix : public ::testing::TestWithParam<std::string> {};
-
-// TEST_P(cotmatrix, constant_in_null_space)
-// {
-//   Eigen::MatrixXd V;
-//   Eigen::MatrixXi F;
-//   Eigen::SparseMatrix<double> L;
-//   // Load example mesh: GetParam() will be name of mesh file
-//   test_common::load_mesh(GetParam(), V, F);
-//   igl::cotmatrix(V,F,L);
-//   REQUIRE (L.rows() == V.rows());
-//   REQUIRE (L.cols() == L.rows());
-//   Eigen::VectorXd C = Eigen::VectorXd::Ones(L.rows());
-//   Eigen::VectorXd Z = Eigen::VectorXd::Zero(L.rows());
-//   REQUIRE (b == a);
-//   REQUIRE (a==b);
-//   // ASSERT_NEAR(a,b,1e-15)
-//   REQUIRE (1e-12 > ((L*C)-(Z)).norm());
-// }
-
-// INSTANTIATE_TEST_CASE_P
-// (
-//  all_meshes,
-//  cotmatrix,
-//  ::testing::ValuesIn(test_common::all_meshes()),
-//  test_common::string_test_name
-// );
+
+TEST_CASE("cotmatrix: constant_in_null_space", "[igl]")
+{
+  const auto test_case = [](const std::string &param)
+  {
+    Eigen::MatrixXd V;
+    Eigen::MatrixXi F;
+    Eigen::SparseMatrix<double> L;
+    // Load example mesh: GetParam() will be name of mesh file
+    test_common::load_mesh(param, V, F);
+    igl::cotmatrix(V,F,L);
+    REQUIRE (L.rows() == V.rows());
+    REQUIRE (L.cols() == L.rows());
+    Eigen::VectorXd C = Eigen::VectorXd::Ones(L.rows());
+    Eigen::VectorXd Z = Eigen::VectorXd::Zero(L.rows());
+    // REQUIRE (b == a);
+    // REQUIRE (a==b);
+    // ASSERT_NEAR(a,b,1e-15)
+    REQUIRE (1e-12 > ((L*C)-(Z)).norm());
+  };
+
+  test_common::run_test_cases(test_common::all_meshes(), test_case);
+}
 
 
 TEST_CASE("cotmatrix: cube", "[igl]")
 TEST_CASE("cotmatrix: cube", "[igl]")
 {
 {

+ 1 - 1
tests/include/igl/cotmatrix_entries.cpp

@@ -70,7 +70,7 @@ TEST_CASE("cotmatrix_entries: simple", "[igl]")
   //All angles still measure 45 or 90 degrees
   //All angles still measure 45 or 90 degrees
   //Their (half)cotangent must value 0.5 or 0.0
   //Their (half)cotangent must value 0.5 or 0.0
   for(int f = 0;f<C1.rows();f++)
   for(int f = 0;f<C1.rows();f++)
-  {    
+  {
 #ifdef IGL_EDGE_LENGTHS_SQUARED_H
 #ifdef IGL_EDGE_LENGTHS_SQUARED_H
       //Hard assert if we have edge_lenght_squared
       //Hard assert if we have edge_lenght_squared
       for(int v = 0;v<3;v++)
       for(int v = 0;v<3;v++)

+ 31 - 34
tests/include/igl/decimate.cpp

@@ -40,38 +40,35 @@ TEST_CASE("decimate: hemisphere", "[igl]")
   test_common::assert_near(D,O,0.02);
   test_common::assert_near(D,O,0.02);
 }
 }
 
 
-// TEST_P(decimate, closed)
-// {
-//   Eigen::MatrixXd V,U;
-//   Eigen::MatrixXi F,G;
-//   Eigen::VectorXi J;
-//   // Load example mesh: GetParam() will be name of mesh file
-//   test_common::load_mesh(GetParam(), V, F);
-//   igl::decimate(V,F,0,U,G,J);
-//   REQUIRE (4 == U.rows());
-//   REQUIRE (4 == G.rows());
-//   {
-//     Eigen::MatrixXi I;
-//     igl::sort(Eigen::MatrixXi(G),2,true,G,I);
-//   }
-//   {
-//     Eigen::VectorXi I;
-//     igl::sortrows(Eigen::MatrixXi(G),true,G,I);
-//   }
-//   // Tet with sorted faces
-//   Eigen::MatrixXi T(4,3);
-//   T<<
-//     0,1,2,
-//     0,1,3,
-//     0,2,3,
-//     1,2,3;
-//   test_common::assert_eq(G,T);
-// }
+TEST_CASE("decimate: closed", "[igl]")
+{
+  const auto test_case = [](const std::string &param)
+  {
+    Eigen::MatrixXd V,U;
+    Eigen::MatrixXi F,G;
+    Eigen::VectorXi J;
+    // Load example mesh: GetParam() will be name of mesh file
+    test_common::load_mesh(param, V, F);
+    igl::decimate(V,F,0,U,G,J);
+    REQUIRE (4 == U.rows());
+    REQUIRE (4 == G.rows());
+    {
+      Eigen::MatrixXi I;
+      igl::sort(Eigen::MatrixXi(G),2,true,G,I);
+    }
+    {
+      Eigen::VectorXi I;
+      igl::sortrows(Eigen::MatrixXi(G),true,G,I);
+    }
+    // Tet with sorted faces
+    Eigen::MatrixXi T(4,3);
+    T<<
+      0,1,2,
+      0,1,3,
+      0,2,3,
+      1,2,3;
+    test_common::assert_eq(G,T);
+  };
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//   closed_genus_0_meshes,
-//   decimate,
-//   ::testing::ValuesIn(test_common::closed_genus_0_meshes()),
-//   test_common::string_test_name
-// );
+  test_common::run_test_cases(test_common::closed_genus_0_meshes(), test_case);
+}

+ 29 - 33
tests/include/igl/doublearea.cpp

@@ -1,39 +1,35 @@
 #include <test_common.h>
 #include <test_common.h>
 #include <igl/doublearea.h>
 #include <igl/doublearea.h>
 
 
-// class doublearea : public ::testing::TestWithParam<std::string> {};
 
 
-// TEST_P(doublearea, VF_vs_ABC )
-// {
-//   Eigen::MatrixXd V;
-//   Eigen::MatrixXi F;
-//   test_common::load_mesh(GetParam(), V, F);
+TEST_CASE("doublearea: VF_vs_ABC", "[igl]")
+{
+    auto test_case = [](const std::string &param)
+    {
+      Eigen::MatrixXd V;
+      Eigen::MatrixXi F;
+      test_common::load_mesh(param, V, F);
 
 
-//   // Check that computing double area with (V,F) is the same as computing
-//   // double area with (V1,V2,V2)
-//   Eigen::VectorXd A1,A2;
-//   igl::doublearea(V,F,A1);
-//   Eigen::MatrixXd A(F.rows(),3);
-//   Eigen::MatrixXd B(F.rows(),3);
-//   Eigen::MatrixXd C(F.rows(),3);
-//   for(int f = 0;f<F.rows();f++)
-//   {
-//     A.row(f) = V.row(F(f,0));
-//     B.row(f) = V.row(F(f,1));
-//     C.row(f) = V.row(F(f,2));
-//   }
-//   igl::doublearea(A,B,C,A2);
-//   REQUIRE (A2.size() == A1.size());
-//   for(int a = 0;a<A1.size();a++)
-//   {
-//     REQUIRE (A2(a) == Approx (A1(a)).margin(1e-15));
-//   }
-// }
+      // Check that computing double area with (V,F) is the same as computing
+      // double area with (V1,V2,V2)
+      Eigen::VectorXd A1,A2;
+      igl::doublearea(V,F,A1);
+      Eigen::MatrixXd A(F.rows(),3);
+      Eigen::MatrixXd B(F.rows(),3);
+      Eigen::MatrixXd C(F.rows(),3);
+      for(int f = 0;f<F.rows();f++)
+      {
+        A.row(f) = V.row(F(f,0));
+        B.row(f) = V.row(F(f,1));
+        C.row(f) = V.row(F(f,2));
+      }
+      igl::doublearea(A,B,C,A2);
+      REQUIRE (A2.size() == A1.size());
+      for(int a = 0;a<A1.size();a++)
+      {
+        REQUIRE (A2(a) == Approx (A1(a)).margin(1e-15));
+      }
+    };
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//  all_meshes,
-//  doublearea,
-//  ::testing::ValuesIn(test_common::all_meshes()),
-//  test_common::string_test_name
-// );
+    test_common::run_test_cases(test_common::all_meshes(), test_case);
+}

+ 36 - 40
tests/include/igl/edge_flaps.cpp

@@ -1,46 +1,42 @@
 #include <test_common.h>
 #include <test_common.h>
 #include <igl/edge_flaps.h>
 #include <igl/edge_flaps.h>
 
 
-// class edge_flaps : public ::testing::TestWithParam<std::string> {};
 
 
-// TEST_P(edge_flaps, verify)
-// {
-//   Eigen::MatrixXd V;
-//   Eigen::MatrixXi F;
-//   test_common::load_mesh(GetParam(), V, F);
+TEST_CASE("edge_flaps: verify", "[igl]")
+{
+	const auto test_case = [](const std::string &param)
+	{
+	  Eigen::MatrixXd V;
+	  Eigen::MatrixXi F;
+	  test_common::load_mesh(param, V, F);
 
 
-//   Eigen::MatrixXi efE,efEF,efEI;
-//   Eigen::VectorXi efEMAP;
-//   igl::edge_flaps(F,efE,efEMAP,efEF,efEI);
-//   REQUIRE (efEF.rows() == efE.rows());
-//   REQUIRE (2 == efE.cols());
-//   REQUIRE (efEF.cols() == efE.cols());
-//   // for each edge, make sure edge appears in face
-//   for(int e = 0;e<efE.rows();e++)
-//   {
-//     for(int fe = 0;fe<2;fe++)
-//     {
-//       const int f = efEF(e,fe);
-//       // index of corner
-//       const int c = efEI(e,fe);
-//       REQUIRE (f<F.rows());
-//       // only check if not on boundary
-//       if(f >= 0)
-//       {
-//         EXPECT_TRUE( 
-//         // Either efE(e,[1 2]) = [i,j] appears after vertex c of face f
-//           ((efE(e,0) == F(f,(c+1)%3)) && (efE(e,1) == F(f,(c+2)%3))) ||
-//         // Or  efE(e,[2 1]) = [j,i] appears after vertex c of face f
-//           ((efE(e,1) == F(f,(c+1)%3)) && (efE(e,0) == F(f,(c+2)%3))));
-//       }
-//     }
-//   }
-// }
+	  Eigen::MatrixXi efE,efEF,efEI;
+	  Eigen::VectorXi efEMAP;
+	  igl::edge_flaps(F,efE,efEMAP,efEF,efEI);
+	  REQUIRE (efEF.rows() == efE.rows());
+	  REQUIRE (2 == efE.cols());
+	  REQUIRE (efEF.cols() == efE.cols());
+	  // for each edge, make sure edge appears in face
+	  for(int e = 0;e<efE.rows();e++)
+	  {
+	    for(int fe = 0;fe<2;fe++)
+	    {
+	      const int f = efEF(e,fe);
+	      // index of corner
+	      const int c = efEI(e,fe);
+	      REQUIRE (f<F.rows());
+	      // only check if not on boundary
+	      if(f >= 0)
+	      {
+	      	// Either efE(e,[1 2]) = [i,j] appears after vertex c of face f
+	      	// Or  efE(e,[2 1]) = [j,i] appears after vertex c of face f
+	        CHECK((
+	          ((efE(e,0) == F(f,(c+1)%3)) && (efE(e,1) == F(f,(c+2)%3))) ||
+	          ((efE(e,1) == F(f,(c+1)%3)) && (efE(e,0) == F(f,(c+2)%3)))));
+	      }
+	    }
+	  }
+	};
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//  all_meshes,
-//  edge_flaps,
-//  ::testing::ValuesIn(test_common::all_meshes()),
-//  test_common::string_test_name
-// );
+	test_common::run_test_cases(test_common::all_meshes(), test_case);
+}

+ 18 - 22
tests/include/igl/guess_extension.cpp

@@ -4,27 +4,23 @@
 #include <igl/pathinfo.h>
 #include <igl/pathinfo.h>
 #include <cstdio>
 #include <cstdio>
 
 
-// class guess_extension : public ::testing::TestWithParam<std::string> {};
 
 
-// TEST_P(guess_extension, all_meshes)
-// {
-//   Eigen::MatrixXd V;
-//   Eigen::MatrixXi F;
-//   std::string path(test_common::data_path(GetParam()));
-//   // Load example mesh: GetParam() will be name of mesh file
-//   std::string d,b,e,f;
-//   igl::pathinfo(path,d,b,e,f);
-//   // Convert extension to lower case
-//   std::transform(e.begin(), e.end(), e.begin(), ::tolower);
-//   FILE * fp = fopen(path.c_str(),"r");
-//   std::string guess = igl::guess_extension(fp);
-//   REQUIRE (e == guess);
-// }
+TEST_CASE("guess_extension: all_meshes", "[igl]")
+{
+	const auto test_case = [](const std::string &param)
+	{
+	  Eigen::MatrixXd V;
+	  Eigen::MatrixXi F;
+	  std::string path(test_common::data_path(param));
+	  // Load example mesh: GetParam() will be name of mesh file
+	  std::string d,b,e,f;
+	  igl::pathinfo(path,d,b,e,f);
+	  // Convert extension to lower case
+	  std::transform(e.begin(), e.end(), e.begin(), ::tolower);
+	  FILE * fp = fopen(path.c_str(),"r");
+	  std::string guess = igl::guess_extension(fp);
+	  REQUIRE (e == guess);
+	};
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//   all_meshes,
-//   guess_extension,
-//   ::testing::ValuesIn(test_common::all_meshes()),
-//   test_common::string_test_name
-// );
+	test_common::run_test_cases(test_common::all_meshes(), test_case);
+}

+ 12 - 16
tests/include/igl/is_edge_manifold.cpp

@@ -1,15 +1,19 @@
 #include <test_common.h>
 #include <test_common.h>
 #include <igl/is_edge_manifold.h>
 #include <igl/is_edge_manifold.h>
 
 
-// class is_edge_manifold : public ::testing::TestWithParam<std::string> {};
 
 
-// TEST_P(is_edge_manifold, positive)
-// {
-//   Eigen::MatrixXd V;
-//   Eigen::MatrixXi F;
-//   test_common::load_mesh(GetParam(), V, F);
-//   REQUIRE ( igl::is_edge_manifold(F) );
-// }
+TEST_CASE("is_edge_manifold: positive", "[igl]")
+{
+	const auto test_case = [](const std::string &param)
+	{
+	  Eigen::MatrixXd V;
+	  Eigen::MatrixXi F;
+	  test_common::load_mesh(param, V, F);
+	  REQUIRE ( igl::is_edge_manifold(F) );
+	};
+
+	test_common::run_test_cases(test_common::manifold_meshes(), test_case);
+}
 
 
 TEST_CASE("is_edge_manifold: negative", "[igl]")
 TEST_CASE("is_edge_manifold: negative", "[igl]")
 {
 {
@@ -19,11 +23,3 @@ TEST_CASE("is_edge_manifold: negative", "[igl]")
   test_common::load_mesh("truck.obj", V, F);
   test_common::load_mesh("truck.obj", V, F);
   REQUIRE (! igl::is_edge_manifold(F) );
   REQUIRE (! igl::is_edge_manifold(F) );
 }
 }
-
-// INSTANTIATE_TEST_CASE_P
-// (
-//  manifold_meshes,
-//  is_edge_manifold,
-//  ::testing::ValuesIn(test_common::manifold_meshes()),
-//  test_common::string_test_name
-// );

+ 44 - 47
tests/include/igl/list_to_matrix.cpp

@@ -3,52 +3,49 @@
 #include <igl/STR.h>
 #include <igl/STR.h>
 #include <tuple>
 #include <tuple>
 
 
-// namespace list_to_matrix
-// {
-//   typedef std::tuple<int/*n*/,int/*m*/> NM;
-//   inline std::string NM_test_name(
-//     const ::testing::TestParamInfo<NM>& info)
-//   {
-//     return STR(
-//       std::get<0>(info.param)<<"x"<<
-//       std::get<1>(info.param)<<"_");
-//   };
-// }
-// class ListToMatrixTest : public ::testing::TestWithParam<list_to_matrix::NM> {};
+namespace list_to_matrix
+{
+  typedef std::tuple<int/*n*/,int/*m*/> NM;
+  // inline std::string NM_test_name(
+  //   const ::testing::TestParamInfo<NM>& info)
+  // {
+  //   return STR(
+  //     std::get<0>(info.param)<<"x"<<
+  //     std::get<1>(info.param)<<"_");
+  // };
+}
 
 
-// TEST_P(ListToMatrixTest,matrix)
-// {
-//   const int n = std::get<0>(GetParam());
-//   const int m = std::get<1>(GetParam());
-//   std::vector<std::vector<double> > vX(n,std::vector<double>(m));
-//   for(int i = 0;i<n;i++)
-//   {
-//     for(int j = 0;j<m;j++)
-//     {
-//       vX[i][j] = i+j*n;
-//     }
-//   }
-//   Eigen::MatrixXd mX;
-//   igl::list_to_matrix(vX,mX);
-//   for(int i = 0;i<n;i++)
-//   {
-//     for(int j = 0;j<m;j++)
-//     {
-//       REQUIRE (mX(i,j) == vX[i][j]);
-//     }
-//   }
-// }
+TEST_CASE("ListToMatrixTest: matrix", "[igl]")
+{
+	const auto test_case = [](const list_to_matrix::NM &param)
+	{
+	  const int n = std::get<0>(param);
+	  const int m = std::get<1>(param);
+	  std::vector<std::vector<double> > vX(n,std::vector<double>(m));
+	  for(int i = 0;i<n;i++)
+	  {
+	    for(int j = 0;j<m;j++)
+	    {
+	      vX[i][j] = i+j*n;
+	    }
+	  }
+	  Eigen::MatrixXd mX;
+	  igl::list_to_matrix(vX,mX);
+	  for(int i = 0;i<n;i++)
+	  {
+	    for(int j = 0;j<m;j++)
+	    {
+	      REQUIRE (mX(i,j) == vX[i][j]);
+	    }
+	  }
+	};
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//   suite,
-//   ListToMatrixTest,
-//   ::testing::ValuesIn<std::vector<list_to_matrix::NM> >(
-//     std::vector<list_to_matrix::NM>{
-//     list_to_matrix::NM{100,4},
-//     list_to_matrix::NM{4,100},
-//     list_to_matrix::NM{100,1},
-//     list_to_matrix::NM{1,100},
-//     }),
-//   list_to_matrix::NM_test_name
-// );
+	std::vector<list_to_matrix::NM> params = {
+	    list_to_matrix::NM{100,4},
+	    list_to_matrix::NM{4,100},
+	    list_to_matrix::NM{100,1},
+	    list_to_matrix::NM{1,100},
+    };
+
+	test_common::run_test_cases(params, test_case);
+}

+ 25 - 32
tests/include/igl/per_face_normals.cpp

@@ -3,36 +3,29 @@
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
 #include <Eigen/Geometry>
 #include <Eigen/Geometry>
 
 
-// class per_face_normals : public ::testing::TestWithParam<std::string> {};
+TEST_CASE("per_face_normals: dot", "[igl]")
+{
+  const auto test_case = [](const std::string &param)
+  {
+	  Eigen::MatrixXd V,N;
+	  Eigen::MatrixXi F;
+	  // Load example mesh: GetParam() will be name of mesh file
+	  test_common::load_mesh(param, V, F);
+	  igl::per_face_normals(V,F,N);
+	  REQUIRE (N.rows() == F.rows());
+	  for(int f = 0;f<N.rows();f++)
+	  {
+	    for(int c = 0;c<3;c++)
+	    {
+	      // Every half-edge dot the normal should be 0
+	      REQUIRE(std::abs((V.row(F(f,c))-V.row(F(f,(c+1)%3))).dot(N.row(f))) < 1e-12);
+	    }
+	  }
+	  // REQUIRE (b == a);
+	  // REQUIRE (a==b);
+	  // ASSERT_NEAR(a,b,1e-15)
+	  // REQUIRE (1e-12 > a);
+  };
 
 
-// TEST_P(per_face_normals, dot)
-// {
-//   Eigen::MatrixXd V,N;
-//   Eigen::MatrixXi F;
-//   // Load example mesh: GetParam() will be name of mesh file
-//   test_common::load_mesh(GetParam(), V, F);
-//   igl::per_face_normals(V,F,N);
-//   REQUIRE (N.rows() == F.rows());
-//   for(int f = 0;f<N.rows();f++)
-//   {
-//     for(int c = 0;c<3;c++)
-//     {
-//       // Every half-edge dot the normal should be 0
-//       ASSERT_LT(
-//         std::abs((V.row(F(f,c))-V.row(F(f,(c+1)%3))).dot(N.row(f))),
-//         1e-12);
-//     }
-//   }
-//   REQUIRE (b == a);
-//   REQUIRE (a==b);
-//   // ASSERT_NEAR(a,b,1e-15)
-//   REQUIRE (1e-12 > a);
-// }
-
-// INSTANTIATE_TEST_CASE_P
-// (
-//   all_meshes,
-//   per_face_normals,
-//   ::testing::ValuesIn(test_common::all_meshes()),
-//   test_common::string_test_name
-// );
+  test_common::run_test_cases(test_common::all_meshes(), test_case);
+}

+ 80 - 84
tests/include/igl/sort.cpp

@@ -3,89 +3,85 @@
 #include <igl/STR.h>
 #include <igl/STR.h>
 #include <tuple>
 #include <tuple>
 
 
-// namespace sort
-// {
-//   typedef std::tuple<int/*n*/,int/*m*/,int/*dim*/,bool/*ascending*/>
-//     NMDimAscending;
-//   inline std::string NMDimAscending_test_name(
-//     const ::testing::TestParamInfo<NMDimAscending>& info)
-//   {
-//     return STR(
-//       std::get<0>(info.param)<<"x"<<
-//       std::get<1>(info.param)<<"_"<<
-//       "dim_"<<std::get<2>(info.param)<<"_"<<
-//       "ascending_"<<(std::get<3>(info.param)?"true":"false"));
-//   };
-// }
-// class SortTest : public ::testing::TestWithParam<sort::NMDimAscending> {};
+namespace sort
+{
+  typedef std::tuple<int/*n*/,int/*m*/,int/*dim*/,bool/*ascending*/> NMDimAscending;
+  // inline std::string NMDimAscending_test_name(
+  //   const ::testing::TestParamInfo<NMDimAscending>& info)
+  // {
+  //   return STR(
+  //     std::get<0>(info.param)<<"x"<<
+  //     std::get<1>(info.param)<<"_"<<
+  //     "dim_"<<std::get<2>(info.param)<<"_"<<
+  //     "ascending_"<<(std::get<3>(info.param)?"true":"false"));
+  // };
+}
 
 
-// TEST_P(SortTest,random)
-// {
-//   const int n = std::get<0>(GetParam());
-//   const int m = std::get<1>(GetParam());
-//   const int dim = std::get<2>(GetParam());
-//   const bool ascending = std::get<3>(GetParam());
-//   Eigen::MatrixXd X = Eigen::MatrixXd::Random(n,m);
-//   // sort ascending
-//   Eigen::MatrixXd Y;
-//   Eigen::MatrixXi IX;
-//   igl::sort(X,dim,ascending,Y,IX);
-//   REQUIRE (Y.rows() == X.rows());
-//   REQUIRE (Y.cols() == X.cols());
-//   REQUIRE (IX.rows() == X.rows());
-//   REQUIRE (IX.cols() == X.cols());
-//   for(int i = 0;i<n;i++)
-//   {
-//     for(int j = 0;j<m;j++)
-//     {
-//       REQUIRE (X(dim==1?IX(i,j):i,dim==2?IX(i,j):j) == Y(i,j));
-//     }
-//   }
-//   for(int i = (dim==1?1:0);i<n;i++) 
-//   {
-//     for(int j = (dim==2?1:0);j<m;j++)
-//     {
-//       if(ascending)
-//       {
-//         REQUIRE (Y(i,j) >= Y(i-(dim==1?1:0),j-(dim==2?1:0)));
-//       }else
-//       {
-//         REQUIRE (Y(i,j) <= Y(i-(dim==1?1:0),j-(dim==2?1:0)));
-//       }
-//     }
-//   }
-// }
+TEST_CASE("SortTest: random", "[igl]")
+{
+	const auto test_case = [](const sort::NMDimAscending &param)
+	{
+		const int n = std::get<0>(param);
+		const int m = std::get<1>(param);
+		const int dim = std::get<2>(param);
+		const bool ascending = std::get<3>(param);
+		Eigen::MatrixXd X = Eigen::MatrixXd::Random(n,m);
+  		// sort ascending
+		Eigen::MatrixXd Y;
+		Eigen::MatrixXi IX;
+		igl::sort(X,dim,ascending,Y,IX);
+		REQUIRE (Y.rows() == X.rows());
+		REQUIRE (Y.cols() == X.cols());
+		REQUIRE (IX.rows() == X.rows());
+		REQUIRE (IX.cols() == X.cols());
+		for(int i = 0;i<n;i++)
+		{
+			for(int j = 0;j<m;j++)
+			{
+				REQUIRE (X(dim==1?IX(i,j):i,dim==2?IX(i,j):j) == Y(i,j));
+			}
+		}
+		for(int i = (dim==1?1:0);i<n;i++)
+		{
+			for(int j = (dim==2?1:0);j<m;j++)
+			{
+				if(ascending)
+				{
+					REQUIRE (Y(i,j) >= Y(i-(dim==1?1:0),j-(dim==2?1:0)));
+				}else
+				{
+					REQUIRE (Y(i,j) <= Y(i-(dim==1?1:0),j-(dim==2?1:0)));
+				}
+			}
+		}
+	};
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//   suite,
-//   SortTest,
-//   ::testing::ValuesIn<std::vector<sort::NMDimAscending> >(
-//     std::vector<sort::NMDimAscending> {
-//     sort::NMDimAscending{100,3,1,true},
-//     sort::NMDimAscending{100,3,2,true},
-//     sort::NMDimAscending{100,3,1,false},
-//     sort::NMDimAscending{100,3,2,false},
-//     sort::NMDimAscending{3,100,1,true},
-//     sort::NMDimAscending{3,100,2,true},
-//     sort::NMDimAscending{3,100,1,false},
-//     sort::NMDimAscending{3,100,2,false},
-//     sort::NMDimAscending{100,2,1,true},
-//     sort::NMDimAscending{100,2,2,true},
-//     sort::NMDimAscending{100,2,1,false},
-//     sort::NMDimAscending{100,2,2,false},
-//     sort::NMDimAscending{2,100,1,true},
-//     sort::NMDimAscending{2,100,2,true},
-//     sort::NMDimAscending{2,100,1,false},
-//     sort::NMDimAscending{2,100,2,false},
-//     sort::NMDimAscending{100,4,1,true},
-//     sort::NMDimAscending{100,4,2,true},
-//     sort::NMDimAscending{100,4,1,false},
-//     sort::NMDimAscending{100,4,2,false},
-//     sort::NMDimAscending{4,100,1,true},
-//     sort::NMDimAscending{4,100,2,true},
-//     sort::NMDimAscending{4,100,1,false},
-//     sort::NMDimAscending{4,100,2,false},
-//     }),
-//   sort::NMDimAscending_test_name
-// );
+	std::vector<sort::NMDimAscending> params = {
+		sort::NMDimAscending{100,3,1,true},
+		sort::NMDimAscending{100,3,2,true},
+		sort::NMDimAscending{100,3,1,false},
+		sort::NMDimAscending{100,3,2,false},
+		sort::NMDimAscending{3,100,1,true},
+		sort::NMDimAscending{3,100,2,true},
+		sort::NMDimAscending{3,100,1,false},
+		sort::NMDimAscending{3,100,2,false},
+		sort::NMDimAscending{100,2,1,true},
+		sort::NMDimAscending{100,2,2,true},
+		sort::NMDimAscending{100,2,1,false},
+		sort::NMDimAscending{100,2,2,false},
+		sort::NMDimAscending{2,100,1,true},
+		sort::NMDimAscending{2,100,2,true},
+		sort::NMDimAscending{2,100,1,false},
+		sort::NMDimAscending{2,100,2,false},
+		sort::NMDimAscending{100,4,1,true},
+		sort::NMDimAscending{100,4,2,true},
+		sort::NMDimAscending{100,4,1,false},
+		sort::NMDimAscending{100,4,2,false},
+		sort::NMDimAscending{4,100,1,true},
+		sort::NMDimAscending{4,100,2,true},
+		sort::NMDimAscending{4,100,1,false},
+		sort::NMDimAscending{4,100,2,false},
+	};
+
+	test_common::run_test_cases(params, test_case);
+}

+ 1 - 1
tests/include/igl/squared_edge_lengths.cpp

@@ -75,7 +75,7 @@ TEST_CASE("squared_edge_lengths: cube", "[igl]")
     //All sides sum exactly side_sq + side_sq + diag_sq
     //All sides sum exactly side_sq + side_sq + diag_sq
     REQUIRE (side_sq + side_sq + diag_sq == L_sq.row(f).sum());
     REQUIRE (side_sq + side_sq + diag_sq == L_sq.row(f).sum());
   }
   }
- 
+
   //Check the equilateral triangles
   //Check the equilateral triangles
   igl::squared_edge_lengths(V_huge,F_tet,L_sq);
   igl::squared_edge_lengths(V_huge,F_tet,L_sq);
   REQUIRE (L_sq.rows() == F_tet.rows());
   REQUIRE (L_sq.rows() == F_tet.rows());

+ 29 - 33
tests/include/igl/tet_tet_adjacency.cpp

@@ -4,38 +4,34 @@
 #include <iostream>
 #include <iostream>
 
 
 
 
-// class tet_tet_adjacency : public ::testing::TestWithParam<std::string> {};
 
 
-// TEST_P(tet_tet_adjacency, dot)
-// {
-//   Eigen::MatrixXd V;
-//   Eigen::MatrixXi F, T, TT,TTi;
-//   // Load example mesh: GetParam() will be name of mesh file
-//   igl::readMESH(test_common::data_path(GetParam()), V, T, F);
-//   igl::tet_tet_adjacency(T, TT, TTi);
-//   REQUIRE (TT.rows() == T.rows());
-//   REQUIRE (TTi.rows() == T.rows());
-//   REQUIRE (TT.cols() == T.cols());
-//   REQUIRE (TTi.cols() == T.cols());
-//   for(int t = 0;t<T.rows();t++)
-//   {
-//     for(int c = 0; c<4 ;c++)
-//     {
-//       if(TT(t, c) >= 0)
-//       {
-//         REQUIRE (T.rows() > TT(t, c));
-//         REQUIRE (0 <= TTi(t, c));
-//         REQUIRE (4 > TTi(t, c));
-//         REQUIRE (t == TT(TT(t, c), TTi(t,c)));
-//       }
-//     }
-//   }
-// }
+TEST_CASE("tet_tet_adjacency: dot", "[igl]")
+{
+  const auto test_case = [](const std::string &param)
+  {
+    Eigen::MatrixXd V;
+    Eigen::MatrixXi F, T, TT,TTi;
+    // Load example mesh: GetParam() will be name of mesh file
+    igl::readMESH(test_common::data_path(param), V, T, F);
+    igl::tet_tet_adjacency(T, TT, TTi);
+    REQUIRE (TT.rows() == T.rows());
+    REQUIRE (TTi.rows() == T.rows());
+    REQUIRE (TT.cols() == T.cols());
+    REQUIRE (TTi.cols() == T.cols());
+    for(int t = 0;t<T.rows();t++)
+    {
+      for(int c = 0; c<4 ;c++)
+      {
+        if(TT(t, c) >= 0)
+        {
+          REQUIRE (T.rows() > TT(t, c));
+          REQUIRE (0 <= TTi(t, c));
+          REQUIRE (4 > TTi(t, c));
+          REQUIRE (t == TT(TT(t, c), TTi(t,c)));
+        }
+      }
+    }
+  };
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//   tet_meshes,
-//   tet_tet_adjacency,
-//   ::testing::ValuesIn(test_common::tet_meshes()),
-//   test_common::string_test_name
-// );
+  test_common::run_test_cases(test_common::tet_meshes(), test_case);
+}

+ 33 - 37
tests/include/igl/triangle_triangle_adjacency.cpp

@@ -3,42 +3,38 @@
 #include <igl/triangle_triangle_adjacency.h>
 #include <igl/triangle_triangle_adjacency.h>
 #include <Eigen/Geometry>
 #include <Eigen/Geometry>
 
 
-// class triangle_triangle_adjacency : public ::testing::TestWithParam<std::string> {};
 
 
-// TEST_P(triangle_triangle_adjacency, dot)
-// {
-//   Eigen::MatrixXd V;
-//   Eigen::MatrixXi F,TT,TTi;
-//   // Load example mesh: GetParam() will be name of mesh file
-//   test_common::load_mesh(GetParam(), V, F);
-//   igl::triangle_triangle_adjacency(F,TT,TTi);
-//   REQUIRE (TT.rows() == F.rows());
-//   REQUIRE (TTi.rows() == F.rows());
-//   REQUIRE (TT.cols() == F.cols());
-//   REQUIRE (TTi.cols() == F.cols());
-//   for(int f = 0;f<F.rows();f++)
-//   {
-//     for(int c = 0;c<3;c++)
-//     {
-//       if(TT(f,c) >= 0)
-//       {
-//         REQUIRE (F.rows() > TT(f,c));
-//         REQUIRE (0 <= TTi(f,c));
-//         REQUIRE (3 > TTi(f,c));
-//         REQUIRE (f == TT(TT(f,c),TTi(f,c)));
-//       }
-//     }
-//   }
-//   REQUIRE (b == a);
-//   REQUIRE (a==b);
-//   // ASSERT_NEAR(a,b,1e-15)
-//   REQUIRE (1e-12 > a);
-// }
+TEST_CASE("triangle_triangle_adjacency: dot", "[igl]")
+{
+  const auto test_case = [](const std::string &param)
+  {
+    Eigen::MatrixXd V;
+    Eigen::MatrixXi F,TT,TTi;
+    // Load example mesh: GetParam() will be name of mesh file
+    test_common::load_mesh(param, V, F);
+    igl::triangle_triangle_adjacency(F,TT,TTi);
+    REQUIRE (TT.rows() == F.rows());
+    REQUIRE (TTi.rows() == F.rows());
+    REQUIRE (TT.cols() == F.cols());
+    REQUIRE (TTi.cols() == F.cols());
+    for(int f = 0;f<F.rows();f++)
+    {
+      for(int c = 0;c<3;c++)
+      {
+        if(TT(f,c) >= 0)
+        {
+          REQUIRE (F.rows() > TT(f,c));
+          REQUIRE (0 <= TTi(f,c));
+          REQUIRE (3 > TTi(f,c));
+          REQUIRE (f == TT(TT(f,c),TTi(f,c)));
+        }
+      }
+    }
+    // REQUIRE (b == a);
+    // REQUIRE (a==b);
+    // REQUIRE(a == Approx(b).margin(1e-15))
+    // REQUIRE (1e-12 > a);
+  };
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//   manifold_meshes,
-//   triangle_triangle_adjacency,
-//   ::testing::ValuesIn(test_common::manifold_meshes()),
-//   test_common::string_test_name
-// );
+  test_common::run_test_cases(test_common::manifold_meshes(), test_case);
+}

+ 23 - 27
tests/include/igl/upsample.cpp

@@ -2,7 +2,6 @@
 #include <test_common.h>
 #include <test_common.h>
 #include <igl/upsample.h>
 #include <igl/upsample.h>
 
 
-// class upsample : public ::testing::TestWithParam<std::string> {};
 
 
 TEST_CASE("upsample: single_triangle", "[igl]")
 TEST_CASE("upsample: single_triangle", "[igl]")
 {
 {
@@ -28,30 +27,27 @@ TEST_CASE("upsample: single_triangle", "[igl]")
   test_common::assert_eq(NV_groundtruth,NV);
   test_common::assert_eq(NV_groundtruth,NV);
 }
 }
 
 
-// TEST_P(upsample, V_comes_first_F_ordering)
-// {
-//   Eigen::MatrixXd V,NV;
-//   Eigen::MatrixXi F,NF;
-//   // Load example mesh: GetParam() will be name of mesh file
-//   test_common::load_mesh(GetParam(), V, F);
-//   igl::upsample(V,F,NV,NF);
-//   REQUIRE (V.rows() <= NV.rows());
-//   REQUIRE (4*F.rows() == NF.rows());
-//   // V should be first part of V
-//   test_common::assert_eq(V,NV.topLeftCorner(V.rows(),V.cols()));
-//   // Expect a particular order 
-//   for(int f = 0;f<F.rows();f++)
-//   {
-//     REQUIRE (NF((f*4)+0,0) == F(f,0));
-//     REQUIRE (NF((f*4)+1,0) == F(f,1));
-//     REQUIRE (NF((f*4)+3,1) == F(f,2));
-//   }
-// }
+TEST_CASE("upsample: V_comes_first_F_ordering", "[igl]")
+{
+  const auto test_case = [](const std::string &param)
+  {
+    Eigen::MatrixXd V,NV;
+    Eigen::MatrixXi F,NF;
+    // Load example mesh: GetParam() will be name of mesh file
+    test_common::load_mesh(param, V, F);
+    igl::upsample(V,F,NV,NF);
+    REQUIRE (V.rows() <= NV.rows());
+    REQUIRE (4*F.rows() == NF.rows());
+    // V should be first part of V
+    test_common::assert_eq(V,NV.topLeftCorner(V.rows(),V.cols()));
+    // Expect a particular order
+    for(int f = 0;f<F.rows();f++)
+    {
+      REQUIRE (NF((f*4)+0,0) == F(f,0));
+      REQUIRE (NF((f*4)+1,0) == F(f,1));
+      REQUIRE (NF((f*4)+3,1) == F(f,2));
+    }
+  };
 
 
-// INSTANTIATE_TEST_CASE_P
-// (
-//   manifold_meshes,
-//   upsample,
-//   ::testing::ValuesIn(test_common::manifold_meshes()),
-//   test_common::string_test_name
-// );
+  test_common::run_test_cases(test_common::manifold_meshes(), test_case);
+}

+ 6 - 0
tests/main.cpp

@@ -0,0 +1,6 @@
+////////////////////////////////////////////////////////////////////////////////
+// Keep this file empty, and implement unit tests in separate compilation units!
+////////////////////////////////////////////////////////////////////////////////
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>

+ 10 - 15
tests/test_common.h

@@ -14,23 +14,18 @@
 #include <algorithm>
 #include <algorithm>
 #include <tuple>
 #include <tuple>
 
 
-namespace test_common 
+namespace test_common
 {
 {
-  // // Input:
-  // //   s  arbitrary string
-  // // Returns s with all non-alphanumeric characters replaced with underscores '_'
-  // inline std::string safe_test_name(std::string s)
-  // {
-  //   std::for_each(s.begin(),s.end(),[](char &c){if(!std::isalnum(c)) c='_';});
-  //   return s;
-  // };
-  // inline std::string string_test_name(const ::testing::TestParamInfo<std::string>& info)
-  // {
-  //   return test_common::safe_test_name(info.param);
-  // };
+  template<typename Param, typename Fun>
+  void run_test_cases(const std::vector<Param> &params,  Fun test_case)
+  {
+    for(const auto &p : params)
+      test_case(p);
+  }
+
   inline std::vector<std::string> closed_genus_0_meshes()
   inline std::vector<std::string> closed_genus_0_meshes()
   {
   {
-    return 
+    return
     {
     {
       "cube.obj",
       "cube.obj",
       "decimated-knight.obj",
       "decimated-knight.obj",
@@ -97,7 +92,7 @@ namespace test_common
   template<typename Derived>
   template<typename Derived>
   void load_matrix(
   void load_matrix(
     const std::string& filename,
     const std::string& filename,
-    Eigen::PlainObjectBase<Derived>& M) 
+    Eigen::PlainObjectBase<Derived>& M)
   {
   {
     igl::readDMAT(data_path(filename), M);
     igl::readDMAT(data_path(filename), M);
   }
   }