#pragma once

/**
 * \file Test.h
 * \brief Contient une assertion utilisable avec les optimisations
 */

#include <iostream>
#include <stdexcept>

/**
 * \def TEST_SUCCESSFUL
 * \brief Indique que le test a été passé
 */
#define TEST_SUCCESSFUL 0

/**
 * \def TEST_FAILED
 * \brief Indique que le test a échoué
 */
#define TEST_FAILED 1

#ifndef __FUNCTION_NAME__
#ifdef _WIN32
#define __FUNCTION_NAME__ __FUNCTION__
#else
#define __FUNCTION_NAME__ __PRETTY_FUNCTION__
#endif
#endif

/**
 * \def test_assert
 * \param ... L'expression à évaluer
 * \brief Evalue une expression et arrête le programme si elle n'est pas valide
 * \note Cette macro équivaut à assert() mais fonctionne également avec les optimisations activées
 */
#define test_assert(...)                                                                                                              \
	if (!static_cast<bool>(__VA_ARGS__)) {                                                                                            \
		std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << ": Assertion failed !\n";                            \
		std::cout << "    " << __LINE__ << "  |\t" << #__VA_ARGS__ << std::endl;                                                      \
		throw std::runtime_error("Assertion failed !");                                                                               \
	}
