From d032b2e5e482220324eacadad357b11be574841d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20M=C3=BCller?= <felix.mueller2@mailbox.tu-dresden.de>
Date: Tue, 6 Mar 2018 15:31:26 +0100
Subject: [PATCH] extended unit tests for /common and /utility

---
 src/amdis/common/TupleUtility.hpp |  1 +
 test/ClonablePtrTest.cpp          | 66 +++++++++++++++++++++++++++++++
 test/ConceptsTest.cpp             | 17 +++++++-
 test/FieldMatVecTest.cpp          | 21 +++++++++-
 test/FilesystemTest.cpp           | 12 ++++++
 test/MultiTypeVectorTest.cpp      | 58 +++++++++++++++++++++------
 test/StringTest.cpp               | 16 ++++++++
 test/TupleUtilityTest.cpp         | 26 ++++++++++++
 8 files changed, 202 insertions(+), 15 deletions(-)
 create mode 100644 test/ClonablePtrTest.cpp
 create mode 100644 test/TupleUtilityTest.cpp

diff --git a/src/amdis/common/TupleUtility.hpp b/src/amdis/common/TupleUtility.hpp
index dcd8ba4b..202622fd 100644
--- a/src/amdis/common/TupleUtility.hpp
+++ b/src/amdis/common/TupleUtility.hpp
@@ -4,6 +4,7 @@
 #include <type_traits>
 
 #include <amdis/common/IndexSeq.hpp>
+#include <amdis/common/Mpl.hpp>
 #include <amdis/common/Utility.hpp>
 
 namespace AMDiS
diff --git a/test/ClonablePtrTest.cpp b/test/ClonablePtrTest.cpp
new file mode 100644
index 00000000..285ad332
--- /dev/null
+++ b/test/ClonablePtrTest.cpp
@@ -0,0 +1,66 @@
+// #include <iostream>
+
+#include <amdis/common/ClonablePtr.hpp>
+
+#include "Tests.hpp"
+
+using namespace AMDiS;
+
+int main()
+{
+  using C = ClonablePtr<int>;
+
+  // constructors
+  C p1; // default constructor
+  AMDIS_TEST( !(p1) );
+  AMDIS_TEST( (p1.get() == nullptr) ); // same as above
+
+  int i = 10;
+  C p2(i); // constructor from reference
+  AMDIS_TEST( (p2.get() != nullptr) );
+  AMDIS_TEST_EQ( *p2 , i );
+
+  p1 = p2; // copy and move assignment
+  AMDIS_TEST( (p1.get() != nullptr) );
+  AMDIS_TEST_EQ( *p1 , i );
+  AMDIS_TEST_EQ( *p1 , *p2 );
+
+  int j = 20;
+  auto u = std::make_unique<int>(j);
+  AMDIS_TEST( (u.get() != nullptr) );
+
+  C p3(u); // constructor from std::unique_ptr
+  AMDIS_TEST( (u.get() == nullptr) ); // unique_ptr is reset to NULL
+  AMDIS_TEST( (p3.get() != nullptr) );
+  AMDIS_TEST_EQ( *p3 , j );
+
+  C p4(p3); // copy constructor
+  AMDIS_TEST( (p3.get() != nullptr) ); // ClonablePtr is not reset
+  AMDIS_TEST( (p4.get() != nullptr) );
+  AMDIS_TEST_EQ( *p4 , j );
+  AMDIS_TEST_EQ( *p3 , *p4 );
+
+  int k = 30;
+  C p5 = C::make(k); // factory method
+  AMDIS_TEST( (p5.get() != nullptr) );
+  AMDIS_TEST_EQ( *p5 , k );
+
+  C p6(*p5); // move constructor
+  AMDIS_TEST( (p6.get() != nullptr) );
+  AMDIS_TEST_EQ( *p6 , k );
+  AMDIS_TEST_EQ( *p5 , *p6 );
+
+/* // Test output
+  std::cout << "*p1:" << *p1 << ", " << p1.get() << "\n"
+            << "*p2:" << *p2 << ", " << p2.get() << "\n"
+            << "*p3:" << *p3 << ", " << p3.get() << "\n"
+            << "*p4:" << *p4 << ", " << p4.get() << "\n"
+            << "*p5:" << *p5 << ", " << p5.get() << "\n"
+            << "*p6:" << *p6 << ", " << p6.get() << "\n"
+            << " u :    " << u.get() << "\n"
+            << " i :" << i << "\n" 
+            << " j :" << j << "\n" 
+            << " k :" << k << "\n" 
+            << "End of Test" << "\n";
+*/
+}
\ No newline at end of file
diff --git a/test/ConceptsTest.cpp b/test/ConceptsTest.cpp
index ee75dfe4..118f25bc 100644
--- a/test/ConceptsTest.cpp
+++ b/test/ConceptsTest.cpp
@@ -15,18 +15,33 @@ int main()
   using M = Dune::FieldMatrix<double,2,2>;
 
   // arithmetic concepts
+  static_assert( Concepts::Addable<double,double>, "" );
   static_assert( Concepts::Addable<V,V>, "" );
   static_assert( Concepts::Addable<M,M>, "" );
 
+  static_assert( Concepts::Subtractable<double,double>, "" );
+  static_assert( Concepts::Subtractable<V,V>, "" );
+  static_assert( Concepts::Subtractable<M,M>, "" );
+
+  static_assert( Concepts::Multiplicable<double,double>, "" );
   static_assert( Concepts::Multiplicable<V,double>, "" );
+  static_assert( Concepts::Multiplicable<V,V>, "" );
   static_assert( Concepts::Multiplicable<M,double>, "" );
-  // static_assert( Concepts::Multiplicable<M,V>, "" );
+//  static_assert( Concepts::Multiplicable<M,V>, "" ); // A*x defined but x*A is not
+
+  static_assert( Concepts::Divisible<double,double>, "" );
+  static_assert( Concepts::Divisible<V,double>, "" );
+  static_assert( Concepts::Divisible<M,double>, "" );
+
+  static_assert( Concepts::LessThanComparable<double,double>, "" );
+  static_assert( Concepts::LessThanComparable<char,char>, "" );
 
   // Concepts::Callable
   auto f = [](V const&) { return 0.0; };
   auto b = [](V const&) { return true; };
 
   static_assert( Concepts::Callable<decltype(f),V>, "" );
+  static_assert( Concepts::Evaluable<decltype(f),V>, "" );
   static_assert( Concepts::Functor<decltype(f),double(V)>, "" );
   static_assert( Concepts::Functor<decltype(b),bool(V)>, "" );
   static_assert( Concepts::Predicate<decltype(b),V>, "" );
diff --git a/test/FieldMatVecTest.cpp b/test/FieldMatVecTest.cpp
index d4573ffb..46fc9300 100644
--- a/test/FieldMatVecTest.cpp
+++ b/test/FieldMatVecTest.cpp
@@ -31,15 +31,28 @@ void test1()
   using V = FieldVector<double, 3>;
   V a{1.0, 2.0, 3.0};
   V b{2.0, 3.0, 4.0};
+  V c{3.0, -5.0, 4.0};
+  V d{-1.0, -2.0, -3.0};
 
   AMDIS_TEST_EQ( unary_dot(a), 14.0 );
   AMDIS_TEST_EQ( dot(a, b), 20.0 );
   AMDIS_TEST_EQ( dot(a, b), dot(b, a) );
 
+  AMDIS_TEST_APPROX( one_norm(a), 6.0 );
   AMDIS_TEST_APPROX( two_norm(a), std::sqrt(14.0) );
+  AMDIS_TEST_APPROX( two_norm(a), p_norm<2>(a) );
+  AMDIS_TEST_APPROX( p_norm<3>(a), std::pow(36.0, 1.0/3) );
   AMDIS_TEST_APPROX( distance(a, b), std::sqrt(3.0) );
 
   AMDIS_TEST_EQ( cross(a, b), (V{-1.0, 2.0, -1.0}) );
+
+  AMDIS_TEST_EQ( sum(c),  2.0 );
+  AMDIS_TEST_EQ( min(b),  2.0 );
+  AMDIS_TEST_EQ( min(c), -5.0 );
+  AMDIS_TEST_EQ( max(c),  4.0 );
+  AMDIS_TEST_EQ( max(d), -1.0 );
+  AMDIS_TEST_EQ( abs_min(c), 3.0 );
+  AMDIS_TEST_EQ( abs_max(c), 5.0 );
 }
 
 // -----------------------------------------------------------------------------
@@ -75,7 +88,7 @@ void test2()
   AMDIS_TEST_EQ( det(A), 1.0 );
   AMDIS_TEST_EQ( det(B), 0.0 );
 
-  // AMDIS_TEST_EQ( det(C*D), det(C)*det(D) );
+  AMDIS_TEST_EQ( det(multiplies(C,D)), det(C)*det(D) );
   AMDIS_TEST_EQ( det(trans(C)), det(C) );
   AMDIS_TEST_EQ( det(2.0*D), Math::pow<3>(2.0)*det(D) );
 
@@ -94,6 +107,12 @@ void test2()
   // test the inverse
   // ----------------
   // AMDIS_TEST_EQ( inv(C), adj(C)/det(C) );
+  AMDIS_TEST_EQ( inv(A), A );
+  AMDIS_TEST_EQ( inv(D), M({ {4.0/5, 1.0/2, -8.0/5}, {4.0/3, 1.0/6, 0.0}, {2.0/15, 1.0/24, 2.0/5} }) );
+
+  V sol;
+  solve(A,sol,a);
+  AMDIS_TEST_EQ( sol, a );
 }
 
 
diff --git a/test/FilesystemTest.cpp b/test/FilesystemTest.cpp
index 4cb0ff25..8d54d868 100644
--- a/test/FilesystemTest.cpp
+++ b/test/FilesystemTest.cpp
@@ -38,13 +38,25 @@ void test0()
   AMDIS_TEST_EQ( path("a/b/./c").string(), "a/b/c" );
   AMDIS_TEST_EQ( path("../a/b/c").string(), "../a/b/c" );
   AMDIS_TEST_EQ( path("./a/b/c").string(), "a/b/c" );
+  AMDIS_TEST_EQ( path("a/b") /= path("c"), path("a/b/c") );
 }
 
 void test1()
 {
   using namespace AMDiS::filesystem;
+#ifdef _WIN32
+
+#else
+  AMDIS_TEST( path("/tmp").is_directory());
+  AMDIS_TEST( !path("/tmp").is_file());
   AMDIS_TEST( exists( path("/tmp") ) );
+  
+  AMDIS_TEST( path("/etc/fstab").is_file() );
+  AMDIS_TEST( !path("/etc/fstab").is_directory() );
   AMDIS_TEST( exists("/etc/fstab") );
+#endif
+
+  // AMDIS_TEST(create_directories( path("testdir") ));
 }
 
 int main()
diff --git a/test/MultiTypeVectorTest.cpp b/test/MultiTypeVectorTest.cpp
index c1ae6a56..77ceea5a 100644
--- a/test/MultiTypeVectorTest.cpp
+++ b/test/MultiTypeVectorTest.cpp
@@ -1,24 +1,58 @@
 #include <amdis/common/FieldMatVec.hpp>
 #include <amdis/common/MultiTypeVector.hpp>
 
+#include "Tests.hpp"
+
 using namespace AMDiS;
+using namespace Dune::Indices;
 
 int main()
 {
-  using V = MultiTypeVector<FieldVector<double,2>, FieldVector<double,3>>;
+  using F2 = FieldVector<double,2>;
+  using F3 = FieldVector<double,3>;
+  using V = MultiTypeVector<F2, F3>;
 
   // constructors
   V v0{}; // default constructor
 
-  FieldVector<double,2> f2 = {1.0, 2.0};
-  FieldVector<double,3> f3 = {1.0, 2.0, 3.0};
+  F2 f2 = {1.0, 2.0};
+  F3 f3 = {1.0, 2.0, 3.0};
+
+//  V tmp = {F2{1.0, 2.0}, F3{1.0, 2.0, 3.0}};
 
   V v1{f2,f3}; // constructor with FV arguments
+  AMDIS_TEST_EQ( v1[_0] , f2 );
+  AMDIS_TEST_EQ( v1[_1] , f3 );
+
   V v2{v1}; // copy constructor
+  AMDIS_TEST_EQ( v2[_0] , f2 );
+  AMDIS_TEST_EQ( v2[_1] , f3 );
+
   v0 = v1; // copy assignment
+  AMDIS_TEST_EQ( v0[_0] , f2 );
+  AMDIS_TEST_EQ( v0[_1] , f3 );
 
   V v3{0.0}; // construction from constant
+  AMDIS_TEST_EQ( v3[_0] , F2({0.0, 0.0}) );
+  AMDIS_TEST_EQ( v3[_1] , F3({0.0, 0.0, 0.0}) );
+
   v3 = 1.0; // assignment of constant
+  AMDIS_TEST_EQ( v3[_0] , F2({1.0, 1.0}) );
+  AMDIS_TEST_EQ( v3[_1] , F3({1.0, 1.0, 1.0}) );
+
+  // compound assignment operators
+  v2 += v1;
+  AMDIS_TEST_EQ( v2[_0] , F2({2.0, 4.0}) );
+  AMDIS_TEST_EQ( v2[_1] , F3({2.0, 4.0, 6.0}) );
+  v2 -= v1;
+
+  v2 *= 1.5;
+  AMDIS_TEST_EQ( v2[_0] , F2({1.5, 3.0}) );
+  AMDIS_TEST_EQ( v2[_1] , F3({1.5, 3.0, 4.5}) );
+  v2 /= 1.5;
+
+  v1[_1] += f3;
+  AMDIS_TEST( v1[_1] == F3({2.0, 4.0, 6.0}) );
 
   {
     V v0_tmp;
@@ -26,27 +60,25 @@ int main()
     v1 = std::move(v1_tmp); // move assignment
   }
 
-  using namespace Dune::Indices;
 
   // element access
   v1[_0] = f2; // mutable block access
-  v1[_0][0] = 2.0; // mutable element access
+  v1[_0][0] = 2.5; // mutable element access
+  AMDIS_TEST( v1[_0][0] == 2.5 && v1[_0][1] == 2.0);
   DUNE_UNUSED auto x = v1[_1][1]; // const access
 
-  // compound assignment operators
-  v1[_1] += f3;
-  v1 += v2;
-
-  v1 *= 2.0;
-  v1 /= 2.0;
-
   // multi-index access
   std::array<std::size_t,2> index{1,1};
   v1[index] = 2.0;
+  AMDIS_TEST( v1[_1][1] == 2.0 );
 
-  using FV = double; //FieldVector<double,1>;
+  using FV = FieldVector<double,1>;
   using W0 = MultiTypeVector<FV,FV>;
   using W = MultiTypeVector<W0,W0>;
   W w;
   w[index] = 3.0;
+  AMDIS_TEST( w[_1][_1] == 3.0 );
+
+  // dimension of the tuple
+  AMDIS_TEST( v1.size() == 2 );
 }
\ No newline at end of file
diff --git a/test/StringTest.cpp b/test/StringTest.cpp
index c73cefdc..d10c8742 100644
--- a/test/StringTest.cpp
+++ b/test/StringTest.cpp
@@ -22,12 +22,15 @@ void test1()
   std::vector<std::string> subs;
   std::string text = "Dies ist ein langer Text";
   split(text.begin(), text.end(), ' ', [&subs](auto it0, auto it1) { subs.push_back(std::string(it0, it1)); });
+// separates text at " " and stores parts in subs
   AMDIS_TEST_EQ( subs.size(), 5 );
   AMDIS_TEST_EQ( subs[0], std::string("Dies") );
+  AMDIS_TEST_EQ( subs[1], std::string("ist") );
 
   int n = 0;
   std::string sep = " x";
   split(text.begin(), text.end(), sep.begin(), sep.end(), [&n](auto,auto) { ++n; });
+// counts occurences of " " or "x"
   AMDIS_TEST_EQ( n, 6 );
 
   n = 0;
@@ -42,11 +45,24 @@ void test1()
   });
 }
 
+// ---------------------------------------------------------------------------------------
+// test the replaceAll() function
+void test2()
+{
+  std::string text = "Hallo Welt!";
+  replaceAll(text, "Welt", "du");
+  AMDIS_TEST_EQ(text,"Hallo du!" );
+  
+  replaceAll(text, "", "Guten Tag");
+  AMDIS_TEST_EQ(text,"Hallo du!" );
+}
+
 
 int main()
 {
   test0();
   test1();
+  test2();
 
   return report_errors();
 }
diff --git a/test/TupleUtilityTest.cpp b/test/TupleUtilityTest.cpp
new file mode 100644
index 00000000..4f40c2c3
--- /dev/null
+++ b/test/TupleUtilityTest.cpp
@@ -0,0 +1,26 @@
+#include <tuple>
+#include <iostream>
+
+#include <amdis/common/TupleUtility.hpp>
+
+#include "Tests.hpp"
+
+using namespace AMDiS;
+
+int main()
+{
+  using Tuple1 = std::tuple<double,int>;
+  using TupleDouble = std::tuple<double,double>;
+  using TupleInt = std::tuple<int,int>;
+  using Tuple2 = std::tuple<TupleDouble,TupleInt>;
+
+  Tuple1 u = {1.3, 2};
+  auto v = constructTuple<Tuple1>(1.5);
+  auto w = foldTuples<Tuple2>(u,v);
+
+  AMDIS_TEST(u == Tuple1({1.3, 2}));
+  AMDIS_TEST(v == Tuple1({1.5, 1}));
+  AMDIS_TEST(w == Tuple2( {{1.3, 1.5}, {2, 1}} ));
+
+  return report_errors();
+}
\ No newline at end of file
-- 
GitLab