207 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
 | 
						|
#include <concepts>
 | 
						|
#include <format>
 | 
						|
#include <source_location>
 | 
						|
 | 
						|
namespace lt::test {
 | 
						|
 | 
						|
template<typename T>
 | 
						|
concept Printable = requires(std::ostream &stream, T value) {
 | 
						|
	{ stream << value } -> std::same_as<std::ostream &>;
 | 
						|
} || requires(std::ostream &stream, T value) {
 | 
						|
	{ stream << std::to_underlying<T>(value) } -> std::same_as<std::ostream &>;
 | 
						|
};
 | 
						|
 | 
						|
template<typename T>
 | 
						|
concept Testable = Printable<T> && std::equality_comparable<T>;
 | 
						|
 | 
						|
constexpr void expect_unreachable(
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	throw std::runtime_error {
 | 
						|
		std::format(
 | 
						|
		    "Failed unreachable expectation:\n"
 | 
						|
		    "\tlocation: {}:{}",
 | 
						|
		    source_location.file_name(),
 | 
						|
		    source_location.line()
 | 
						|
		),
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
constexpr void expect_throw(
 | 
						|
    std::invocable auto invocable,
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	try
 | 
						|
	{
 | 
						|
		invocable();
 | 
						|
	}
 | 
						|
	catch (const std::exception &exp)
 | 
						|
	{
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	throw std::runtime_error {
 | 
						|
		std::format(
 | 
						|
		    "Failed throwing expectation:\n"
 | 
						|
		    "\tlocation: {}:{}",
 | 
						|
		    source_location.file_name(),
 | 
						|
		    source_location.line()
 | 
						|
		),
 | 
						|
	};
 | 
						|
}
 | 
						|
 | 
						|
constexpr void expect_eq(
 | 
						|
    Testable auto lhs,
 | 
						|
    Testable auto rhs,
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	if constexpr (std::is_enum_v<decltype(lhs)>)
 | 
						|
	{
 | 
						|
		if (lhs != rhs)
 | 
						|
		{
 | 
						|
			throw std::runtime_error {
 | 
						|
				std::format(
 | 
						|
				    "Failed equality expectation:\n"
 | 
						|
				    "\tactual: {}\n"
 | 
						|
				    "\texpected: {}\n"
 | 
						|
				    "\tlocation: {}:{}",
 | 
						|
				    std::to_underlying<decltype(lhs)>(lhs),
 | 
						|
				    std::to_underlying<decltype(rhs)>(rhs),
 | 
						|
				    source_location.file_name(),
 | 
						|
				    source_location.line()
 | 
						|
				),
 | 
						|
			};
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else if (lhs != rhs)
 | 
						|
	{
 | 
						|
		throw std::runtime_error {
 | 
						|
			std::format(
 | 
						|
			    "Failed equality expectation:\n"
 | 
						|
			    "\tactual: {}\n"
 | 
						|
			    "\texpected: {}\n"
 | 
						|
			    "\tlocation: {}:{}",
 | 
						|
			    lhs,
 | 
						|
			    rhs,
 | 
						|
			    source_location.file_name(),
 | 
						|
			    source_location.line()
 | 
						|
			),
 | 
						|
		};
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
constexpr void expect_ne(
 | 
						|
    Testable auto lhs,
 | 
						|
    Testable auto rhs,
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	if (lhs == rhs)
 | 
						|
	{
 | 
						|
		throw std::runtime_error {
 | 
						|
			std::format(
 | 
						|
			    "Failed un-equality expectation:\n"
 | 
						|
			    "\tactual: {}\n"
 | 
						|
			    "\texpected: {}\n"
 | 
						|
			    "\tlocation: {}:{}",
 | 
						|
			    lhs,
 | 
						|
			    rhs,
 | 
						|
			    source_location.file_name(),
 | 
						|
			    source_location.line()
 | 
						|
			),
 | 
						|
		};
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
constexpr void expect_true(
 | 
						|
    bool expression,
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	if (!expression)
 | 
						|
	{
 | 
						|
		throw std::runtime_error {
 | 
						|
			std::format(
 | 
						|
			    "Failed true expectation:\n"
 | 
						|
			    "\tactual: {}\n"
 | 
						|
			    "\texpected: true\n"
 | 
						|
			    "\tlocation: {}:{}",
 | 
						|
			    expression,
 | 
						|
			    source_location.file_name(),
 | 
						|
			    source_location.line()
 | 
						|
			),
 | 
						|
		};
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
constexpr void expect_false(
 | 
						|
    bool expression,
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	if (expression)
 | 
						|
	{
 | 
						|
		throw std::runtime_error {
 | 
						|
			std::format(
 | 
						|
			    "Failed false expectation:\n"
 | 
						|
			    "\tactual: {}\n"
 | 
						|
			    "\texpected: true\n"
 | 
						|
			    "\tlocation: {}:{}",
 | 
						|
			    expression,
 | 
						|
			    source_location.file_name(),
 | 
						|
			    source_location.line()
 | 
						|
			),
 | 
						|
		};
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
constexpr void expect_not_nullptr(
 | 
						|
    auto *pointer,
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	if (pointer == nullptr)
 | 
						|
	{
 | 
						|
		throw std::runtime_error {
 | 
						|
			std::format(
 | 
						|
			    "Failed true expectation:\n"
 | 
						|
			    "\tactual: nullptr\n"
 | 
						|
			    "\texpected: not nullptr\n"
 | 
						|
			    "\tlocation: {}:{}",
 | 
						|
			    source_location.file_name(),
 | 
						|
			    source_location.line()
 | 
						|
			),
 | 
						|
		};
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
constexpr void expect_le(
 | 
						|
    Testable auto lhs,
 | 
						|
    Testable auto rhs,
 | 
						|
    std::source_location source_location = std::source_location::current()
 | 
						|
)
 | 
						|
{
 | 
						|
	if (lhs > rhs)
 | 
						|
	{
 | 
						|
		throw std::runtime_error {
 | 
						|
			std::format(
 | 
						|
			    "Failed false expectation:\n"
 | 
						|
			    "\tactual: {}\n"
 | 
						|
			    "\texpected: >= {}\n"
 | 
						|
			    "\tlocation: {}:{}",
 | 
						|
			    lhs,
 | 
						|
			    rhs,
 | 
						|
			    source_location.file_name(),
 | 
						|
			    source_location.line()
 | 
						|
			),
 | 
						|
		};
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
} // namespace lt::test
 |