// Lösungen zu "Richard Kaiser: C++ mit dem Borland C++Builder 2007", ISBN: 978-3-540-69575-2
// Copyright Richard Kaiser, 2007. http://www.rkaiser.de. All rights reserved.
// Diese Quelltexte dürfen in eigenen Programmen verwendet werden, wenn sie einen Hinweis auf die Quelle (die ersten beiden Zeilen) enthalten. In keinem Fall wird eine Haftung für direkte, indirekte, zufällige oder Folgeschäden übernommen, die sich aus der Nutzung ergeben.
// It is permitted to use this source text in programs of your own, provided that it contains a reference to the source (the first two lines above). All liabilities for use of the code are disclaimed.

#ifndef TESTUTILS_H__
#define TESTUTILS_H__


#include "NearlyEqual.h"


// Einfach: Alle Definitionen in einer h-Datei, keine cpp-Datei. 
// Zur Aufteilung der Definitionen und Deklarationen in eine cpp-Datei 
// und eine h-Datei: Siehe Abschnitt 3.23 und 3.23.5.


bool log_Testcases=false;

// Die folgenden Funktionen sind so geschrieben, dass man sie einfach
// in einer Klasse zusammenfassen kann, indem man sie zwischen
// class { ... } einfügt.  


int TestUtilsPassCount=0,TestUtilsFailCount=0;

void initTestUtils()
{
TestUtilsPassCount=0;
TestUtilsFailCount=0;
}

#include <vcl.h>

bool assertTrue(bool condition, AnsiString msg, 
                TCustomMemo* Memo=Form1->Memo1)
{ // base routine to display one test case
if (!condition)
  {
    Memo->Lines->Add("Test failed: "+msg);
    ++TestUtilsFailCount;
  }
else
  {
    if (log_Testcases)
      Memo->Lines->Add("Test passed: "+msg);
    ++TestUtilsPassCount;
  }
return condition;
}

bool assertEqual_int(int f, int s, AnsiString  msg, 
                     TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertTrue(f==s,msg+"=="+IntToStr(f)+", expected: "+IntToStr(s), 
                  Memo);
}

AnsiString BoolToString(bool b)
{
if (b) return "true";
else return "false";
}

bool assertEqual_bool(bool f, bool s, AnsiString msg, 
                      TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertTrue(f==s, msg+"=="+BoolToString(f)+", expected: "+
                  BoolToString(s));
}

bool assertEqual_double(double f, double s, AnsiString msg, 
                TCustomMemo* Memo=Form1->Memo1, int digits=10)
{ // tests one test case
return assertTrue(NearlyEqual2(f,s,digits),msg+"=="+FloatToStr(f)+
                  ", expected: "+FloatToStr(s));
}

bool assertNotEqual_double(double f, double s, AnsiString msg, 
                   TCustomMemo* Memo=Form1->Memo1, int digits=10)
{ // tests one test case
return assertTrue(!NearlyEqual2(f,s,digits),msg+"=="+FloatToStr(f)+
                          ", expected: "+FloatToStr(s));
}

bool assertEqual_AnsiString(AnsiString f, AnsiString s, AnsiString msg, 
                                          TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertTrue(f==s,msg+"=="+f+", expected: "+s);
}

bool assertEqual_Pointer(void* f, void* s, AnsiString msg, 
                                          TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertTrue(f==s,msg+"=="+IntToStr(f)+", expected: "+IntToStr(s));
}

bool assertEqual_Currency(Currency f, Currency s, AnsiString  msg, 
                                          TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertTrue(f==s,msg+"=="+IntToStr(f)+", expected: "+IntToStr(s), 
                  Memo);
}

#include <string>
bool assertEqual_string(std::string f, std::string s, AnsiString  msg, 
                                          TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertTrue(f==s,msg+"=="+AnsiString(f.c_str())+", expected: "+
                                          AnsiString(s.c_str()), Memo);
}


// Die überladenden Funktionen lassen sich einfacher aufrufen:

bool assertEqual(bool f, bool s, AnsiString msg, 
                 TCustomMemo* Memo=Form1->Memo1)
{
return assertEqual_bool(f, s, msg, Memo);
}

bool assertEqual(int f, int s, AnsiString msg, 
                 TCustomMemo* Memo=Form1->Memo1)
{
return assertEqual_int(f, s, msg, Memo);
}

bool assertEqual(double f, double s, AnsiString msg, 
                 TCustomMemo* Memo=Form1->Memo1, int digits=10)
{ // tests one test case
return assertEqual_double(f, s, msg, Memo, digits);
}

bool assertEqual(AnsiString f, AnsiString s, AnsiString msg,  
                 TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertEqual_AnsiString(f, s, msg, Memo);
}

bool assertEqual(std::string f, std::string s, AnsiString msg, 
                 TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertEqual_string(f, s, msg, Memo);
}

bool assertEqual(void* f, void* s, AnsiString msg, 
                 TCustomMemo* Memo=Form1->Memo1)
{ // tests one test case
return assertEqual_Pointer(f, s, msg, Memo);
}

bool assertEqual(Currency f, Currency s, AnsiString msg, 
                 TCustomMemo* Memo=Form1->Memo1)
{
return assertEqual_Currency(f, s, msg, Memo);
}

void testUtilsSummary(TMemo* Memo, bool result)
{
if (result)
  Memo->Lines->Add("All tests passed (total: "+
                   IntToStr(TestUtilsPassCount)+")");
else
  Memo->Lines->Add(IntToStr(TestUtilsFailCount)+
    " Tests failed from "+ IntToStr(TestUtilsFailCount+
    TestUtilsPassCount) );
}


#endif // TESTUTILS_H__
