/*
 *  Copyright (c) 2011 Cyrille Berger <cberger@cberger.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; see the file COPYING.RUNTIME.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * The file COPYING.RUNTIME.EXCEPTION contains an exception that allow
 * to use this file with other open source license
 */

#include <string>

namespace std
{
  template<typename _T_>
  class complex;
}

namespace Cauchy
{
  namespace xUnit
  {
    void assertTrue(bool v, const std::string& msg, int line);
    void assertFilesEqual(const std::string& file1, const std::string& file2, const std::string& msg, int line);
    void assertElementsAlmostEqual(double x, double y, double t, const std::string& msg, int line);
    void assertElementsAlmostEqual(const std::complex<double>& x, const std::complex<double>& y, double t, const std::string& msg, int line);
    void assertElementsAlmostEqual(int x, int y, double t, const std::string& msg, int line);
    inline void assertElementsAlmostEqual(double x, int y, double t, const std::string& msg, int line)
    {
      assertElementsAlmostEqual(x, (double)y, t, msg, line);
    }
    inline void assertElementsAlmostEqual(int x, double y, double t, const std::string& msg, int line)
    {
      assertElementsAlmostEqual((double)x, y, t, msg, line);
    }
  }
}

#define CAUCHY_ASSERT_TRUE(x) \
  Cauchy::xUnit::assertTrue(x, #x, __LINE__)

#define CAUCHY_ASSERT_TRUE_X(x, msg) \
  Cauchy::xUnit::assertTrue(x, msg, __LINE__)

#define CAUCHY_ASSERT_FALSE(x) \
  Cauchy::xUnit::assertTrue(!(x), #x, __LINE__)

#define CAUCHY_ASSERT_FALSE_X(x, msg) \
  Cauchy::xUnit::assertTrue(!(x), msg, __LINE__)

#define CAUCHY_ASSERT_EQUAL(x, y) \
  Cauchy::xUnit::assertTrue(x == y, #x " == " #y, __LINE__  )

#define CAUCHY_ASSERT_EQUAL_X(x, y, msg) \
  Cauchy::xUnit::assertTrue(x == y, msg, __LINE__)

#define CAUCHY_ASSERT_FILES_EQUAL(x, y) \
  Cauchy::xUnit::assertFilesEqual(x, y, " are different files.", __LINE__ )

#define CAUCHY_ASSERT_FILES_EQUAL_X(x, y, msg) \
  Cauchy::xUnit::assertFilesEqual(x, y, msg, __LINE__)

#define CAUCHY_ASSERT_ELEMENTS_ALMOST_EQUAL(x, y) \
  Cauchy::xUnit::assertElementsAlmostEqual(x, y, Cauchy::eps, #x " is almost equal to " #y , __LINE__)

#define CAUCHY_ASSERT_ELEMENTS_ALMOST_EQUAL_T(x, y, t) \
  Cauchy::xUnit::assertElementsAlmostEqual(x, y, t, #x " is almost equal to " #y , __LINE__)

#define CAUCHY_ASSERT_ELEMENTS_ALMOST_EQUAL_X(x, y, msg) \
  Cauchy::xUnit::assertElementsAlmostEqual(x, y, msg, __LINE__)

#define CAUCHY_ASSERT_VECTORS_ALMOST_EQUAL(x, y) \
  Cauchy::xUnit::assertVectorsAlmostEqual(x, y, #x " is almost equal to " #y , __LINE__)

#define CAUCHY_ASSERT_VECTORS_ALMOST_EQUAL_X(x, y, msg) \
  Cauchy::xUnit::assertVectorsAlmostEqual(x, y, msg, __LINE__)

