<commit_before>#include <limits>
#include <typeinfo>
#include <type_traits>

#include "gtest/gtest.h"
#include "Exception.hpp"

using But::Exception;

namespace
{

// helper needed, since original c-tor is protected, as class is not to be used as a standalone object
BUT_DEFINE_EXCEPTION(TestEx, Exception, "default");

struct ButException: public testing::Test
{ };


TEST_F(ButException, SomeMessage)
{
  const TestEx ex{"file.hpp", 42u, "func()", "msg"};
  EXPECT_EQ(ex.what(), std::string{"file.hpp:42 default: msg (in func())"});
}


TEST_F(ButException, MaxLineNumber)
{
  constexpr auto max = std::numeric_limits<unsigned>::max();
  const TestEx ex{"file.hpp", max, "func()", "msg"};
  std::stringstream ss;
  ss << "file.hpp:" << max << " default: msg (in func())";
  EXPECT_EQ(ex.what(), ss.str());
}


TEST_F(ButException, DefiningAndThrowing)
{
  BUT_DEFINE_EXCEPTION(Problem, Exception, "holy shit");
  try
  {
    BUT_THROW(Problem, "what the hell is that? " << 52 << "? should be " << 2*21 << "!");
    FAIL() << "no exception has been thrown";
  }
  catch(Exception const& ex)
  {
    EXPECT_EQ( std::string(typeid(ex).name()), typeid(Problem).name() );
    const std::string m = ex.what();
    EXPECT_TRUE( m.find(__FILE__) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find(BOOST_CURRENT_FUNCTION) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find("holy shit: what the hell is that? 52? should be 42!") != std::string::npos ) << "actuall got: " << m;
  }
}


TEST_F(ButException, MultipleDeriving)
{
  BUT_DEFINE_EXCEPTION(Problem, Exception, "base");
  BUT_DEFINE_EXCEPTION(NewProblem, Problem, "derived");
  EXPECT_TRUE( (std::is_base_of<Problem, NewProblem>::value) );
  try
  {
    BUT_THROW(NewProblem, "whatever " << 10);
    FAIL() << "no exception has been thrown";
  }
  catch(NewProblem const& ex)
  {
    EXPECT_EQ( std::string(typeid(ex).name()), typeid(NewProblem).name() );
    const std::string m = ex.what();
    EXPECT_TRUE( m.find(__FILE__) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find(BOOST_CURRENT_FUNCTION) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find("base: derived: whatever 10") != std::string::npos ) << "actuall got: " << m;
  }
}


TEST_F(ButException, DefiningAndThrowingWithEmptyMessage)
{
  BUT_DEFINE_EXCEPTION(Sth, Exception, "holy shit");
  try
  {
    BUT_THROW(Sth, "");
    FAIL() << "no exception has been thrown";
  }
  catch(Sth const&)
  {
  }
}


TEST_F(ButException, DefiningWithEmptyMessage)
{
  BUT_DEFINE_EXCEPTION(Sth, Exception, "");
  try
  {
    BUT_THROW(Sth, "");<commit_msg>added 3 levels of deriving for testing purposes<commit_after>#include <limits>
#include <typeinfo>
#include <type_traits>

#include "gtest/gtest.h"
#include "Exception.hpp"

using But::Exception;

namespace
{

// helper needed, since original c-tor is protected, as class is not to be used as a standalone object
BUT_DEFINE_EXCEPTION(TestEx, Exception, "default");

struct ButException: public testing::Test
{ };


TEST_F(ButException, SomeMessage)
{
  const TestEx ex{"file.hpp", 42u, "func()", "msg"};
  EXPECT_EQ(ex.what(), std::string{"file.hpp:42 default: msg (in func())"});
}


TEST_F(ButException, MaxLineNumber)
{
  constexpr auto max = std::numeric_limits<unsigned>::max();
  const TestEx ex{"file.hpp", max, "func()", "msg"};
  std::stringstream ss;
  ss << "file.hpp:" << max << " default: msg (in func())";
  EXPECT_EQ(ex.what(), ss.str());
}


TEST_F(ButException, DefiningAndThrowing)
{
  BUT_DEFINE_EXCEPTION(Problem, Exception, "holy shit");
  try
  {
    BUT_THROW(Problem, "what the hell is that? " << 52 << "? should be " << 2*21 << "!");
    FAIL() << "no exception has been thrown";
  }
  catch(Exception const& ex)
  {
    EXPECT_EQ( std::string(typeid(ex).name()), typeid(Problem).name() );
    const std::string m = ex.what();
    EXPECT_TRUE( m.find(__FILE__) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find(BOOST_CURRENT_FUNCTION) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find("holy shit: what the hell is that? 52? should be 42!") != std::string::npos ) << "actuall got: " << m;
  }
}


TEST_F(ButException, MultipleDeriving)
{
  BUT_DEFINE_EXCEPTION(Problem, Exception, "base");
  BUT_DEFINE_EXCEPTION(NewProblem, Problem, "derived");
  BUT_DEFINE_EXCEPTION(TopProblem, NewProblem, "last");
  EXPECT_TRUE( (std::is_base_of<Problem, NewProblem>::value) );
  try
  {
    BUT_THROW(TopProblem, "whatever " << 10);
    FAIL() << "no exception has been thrown";
  }
  catch(TopProblem const& ex)
  {
    EXPECT_EQ( std::string(typeid(ex).name()), typeid(TopProblem).name() );
    const std::string m = ex.what();
    EXPECT_TRUE( m.find(__FILE__) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find(BOOST_CURRENT_FUNCTION) != std::string::npos ) << "actuall got: " << m;
    EXPECT_TRUE( m.find("base: derived: last: whatever 10") != std::string::npos ) << "actuall got: " << m;
  }
}


TEST_F(ButException, DefiningAndThrowingWithEmptyMessage)
{
  BUT_DEFINE_EXCEPTION(Sth, Exception, "holy shit");
  try
  {
    BUT_THROW(Sth, "");
    FAIL() << "no exception has been thrown";
  }
  catch(Sth const&)
  {
  }
}


TEST_F(ButException, DefiningWithEmptyMessage)
{
  BUT_DEFINE_EXCEPTION(Sth, Exception, "");
  try
  {
    BUT_THROW(Sth, "");
{'fraction_non_alphanumeric': 0.17596726190476192, 'fraction_numerical': 0.006510416666666667, 'mean_word_length': 4.648109243697479, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4299371', 'n_tokens_mistral': 2012, 'n_tokens_neox': 1921, 'n_words': 431}