mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:48:10 +00:00

As many macros as possible are moved to Macros.h, while the macros to create a test case are moved to TestCase.h. TestCase is now the only user-facing header for creating a test case. TestSuite and its helpers have moved into a .cpp file. Instead of requiring a TEST_MAIN macro to be instantiated into the test file, a TestMain.cpp file is provided instead that will be linked against each test. This has the side effect that, if we wanted to have test cases split across multiple files, it's as simple as adding them all to the same executable. The test main should be portable to kernel mode as well, so if there's a set of tests that should be run in self-test mode in kernel space, we can accomodate that. A new serenity_test CMake function streamlines adding a new test with arguments for the test source file, subdirectory under /usr/Tests to install the test application and an optional list of libraries to link against the test application. To accomodate future test where the provided TestMain.cpp is not suitable (e.g. test-js), a CUSTOM_MAIN parameter can be passed to the function to not link against the boilerplate main function.
87 lines
6.7 KiB
C++
87 lines
6.7 KiB
C++
/*
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
|
* Copyright (c) 2021, Andrew Kaster <akaster@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Assertions.h>
|
|
#include <AK/CheckedFormatString.h>
|
|
|
|
namespace AK {
|
|
template<typename... Parameters>
|
|
void warnln(CheckedFormatString<Parameters...>&& fmtstr, const Parameters&...);
|
|
}
|
|
|
|
namespace Test {
|
|
// Declare a helper so that we can call it from VERIFY in included headers
|
|
void current_test_case_did_fail();
|
|
}
|
|
|
|
#undef VERIFY
|
|
#define VERIFY(x) \
|
|
do { \
|
|
if (!(x)) { \
|
|
::AK::warnln("\033[31;1mFAIL\033[0m: {}:{}: VERIFY({}) failed", __FILE__, __LINE__, #x); \
|
|
::Test::current_test_case_did_fail(); \
|
|
} \
|
|
} while (false)
|
|
|
|
#undef VERIFY_NOT_REACHED
|
|
#define VERIFY_NOT_REACHED() \
|
|
do { \
|
|
::AK::warnln("\033[31;1mFAIL\033[0m: {}:{}: VERIFY_NOT_REACHED() called", __FILE__, __LINE__); \
|
|
::abort(); \
|
|
} while (false)
|
|
|
|
#undef TODO
|
|
#define TODO() \
|
|
do { \
|
|
::AK::warnln(stderr, "\033[31;1mFAIL\033[0m: {}:{}: TODO() called", __FILE__, __LINE__); \
|
|
::abort(); \
|
|
} while (false)
|
|
|
|
#define EXPECT_EQ(a, b) \
|
|
do { \
|
|
auto lhs = (a); \
|
|
auto rhs = (b); \
|
|
if (lhs != rhs) { \
|
|
::AK::warnln("\033[31;1mFAIL\033[0m: {}:{}: EXPECT_EQ({}, {}) failed with lhs={} and rhs={}", __FILE__, __LINE__, #a, #b, FormatIfSupported { lhs }, FormatIfSupported { rhs }); \
|
|
::Test::current_test_case_did_fail(); \
|
|
} \
|
|
} while (false)
|
|
|
|
// If you're stuck and `EXPECT_EQ` seems to refuse to print anything useful,
|
|
// try this: It'll spit out a nice compiler error telling you why it doesn't print.
|
|
#define EXPECT_EQ_FORCE(a, b) \
|
|
do { \
|
|
auto lhs = (a); \
|
|
auto rhs = (b); \
|
|
if (lhs != rhs) { \
|
|
::AK::warnln("\033[31;1mFAIL\033[0m: {}:{}: EXPECT_EQ({}, {}) failed with lhs={} and rhs={}", __FILE__, __LINE__, #a, #b, lhs, rhs); \
|
|
::Test::current_test_case_did_fail(); \
|
|
} \
|
|
} while (false)
|
|
|
|
#define EXPECT(x) \
|
|
do { \
|
|
if (!(x)) { \
|
|
::AK::warnln("\033[31;1mFAIL\033[0m: {}:{}: EXPECT({}) failed", __FILE__, __LINE__, #x); \
|
|
::Test::current_test_case_did_fail(); \
|
|
} \
|
|
} while (false)
|
|
|
|
#define EXPECT_APPROXIMATE(a, b) \
|
|
do { \
|
|
auto expect_close_lhs = a; \
|
|
auto expect_close_rhs = b; \
|
|
auto expect_close_diff = static_cast<double>(expect_close_lhs) - static_cast<double>(expect_close_rhs); \
|
|
if (fabs(expect_close_diff) > 0.0000005) { \
|
|
::AK::warnln("\033[31;1mFAIL\033[0m: {}:{}: EXPECT_APPROXIMATE({}, {})" \
|
|
" failed with lhs={}, rhs={}, (lhs-rhs)={}", \
|
|
__FILE__, __LINE__, #a, #b, expect_close_lhs, expect_close_rhs, expect_close_diff); \
|
|
::Test::current_test_case_did_fail(); \
|
|
} \
|
|
} while (false)
|