From 35c0a6c54d4e67f0d600044ed8eae0ae5e5adfba Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Sat, 24 Apr 2021 23:53:23 -0600 Subject: [PATCH] AK+Userland: Move AK/TestSuite.h into LibTest and rework Tests' CMake 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. --- AK/TestSuite.h | 319 ------------------ AK/Tests/CMakeLists.txt | 5 +- AK/Tests/TestAllOf.cpp | 4 +- AK/Tests/TestAnyOf.cpp | 4 +- AK/Tests/TestArray.cpp | 4 +- AK/Tests/TestAtomic.cpp | 4 +- AK/Tests/TestBadge.cpp | 4 +- AK/Tests/TestBase64.cpp | 4 +- AK/Tests/TestBinaryHeap.cpp | 4 +- AK/Tests/TestBinarySearch.cpp | 4 +- AK/Tests/TestBitCast.cpp | 4 +- AK/Tests/TestBitmap.cpp | 4 +- AK/Tests/TestByteBuffer.cpp | 4 +- AK/Tests/TestChecked.cpp | 4 +- AK/Tests/TestCircularDeque.cpp | 4 +- AK/Tests/TestCircularDuplexStream.cpp | 4 +- AK/Tests/TestCircularQueue.cpp | 4 +- AK/Tests/TestComplex.cpp | 5 +- AK/Tests/TestDistinctNumeric.cpp | 4 +- AK/Tests/TestDoublyLinkedList.cpp | 4 +- AK/Tests/TestEndian.cpp | 4 +- AK/Tests/TestEnumBits.cpp | 5 +- AK/Tests/TestFind.cpp | 4 +- AK/Tests/TestFormat.cpp | 4 +- AK/Tests/TestGenericLexer.cpp | 4 +- AK/Tests/TestHashFunctions.cpp | 4 +- AK/Tests/TestHashMap.cpp | 4 +- AK/Tests/TestHashTable.cpp | 4 +- AK/Tests/TestHex.cpp | 4 +- AK/Tests/TestIPv4Address.cpp | 4 +- AK/Tests/TestIndexSequence.cpp | 5 +- AK/Tests/TestIntrusiveList.cpp | 5 +- AK/Tests/TestIntrusiveRedBlackTree.cpp | 4 +- AK/Tests/TestJSON.cpp | 4 +- AK/Tests/TestLexicalPath.cpp | 4 +- AK/Tests/TestMACAddress.cpp | 4 +- AK/Tests/TestMemMem.cpp | 4 +- AK/Tests/TestMemoryStream.cpp | 4 +- AK/Tests/TestNeverDestroyed.cpp | 4 +- AK/Tests/TestNonnullRefPtr.cpp | 4 +- AK/Tests/TestNumberFormat.cpp | 4 +- AK/Tests/TestOptional.cpp | 4 +- AK/Tests/TestQueue.cpp | 4 +- AK/Tests/TestQuickSort.cpp | 4 +- AK/Tests/TestRedBlackTree.cpp | 4 +- AK/Tests/TestRefPtr.cpp | 4 +- AK/Tests/TestSinglyLinkedList.cpp | 4 +- AK/Tests/TestSourceGenerator.cpp | 4 +- AK/Tests/TestSourceLocation.cpp | 5 +- AK/Tests/TestSpan.cpp | 4 +- AK/Tests/TestString.cpp | 4 +- AK/Tests/TestStringUtils.cpp | 4 +- AK/Tests/TestStringView.cpp | 4 +- AK/Tests/TestTime.cpp | 4 +- AK/Tests/TestTrie.cpp | 4 +- AK/Tests/TestTypeTraits.cpp | 5 +- AK/Tests/TestTypedTransfer.cpp | 4 +- AK/Tests/TestURL.cpp | 4 +- AK/Tests/TestUtf8.cpp | 4 +- AK/Tests/TestVector.cpp | 4 +- AK/Tests/TestWeakPtr.cpp | 4 +- Meta/CMake/utils.cmake | 16 +- Meta/Lagom/CMakeLists.txt | 22 +- .../Applications/Spreadsheet/CMakeLists.txt | 4 + .../Spreadsheet/Readers/Test/TestXSV.cpp | 4 +- .../Writers/Test/TestXSVWriter.cpp | 4 +- Userland/Libraries/LibC/Tests/CMakeLists.txt | 5 +- .../Libraries/LibC/Tests/TestLibCTime.cpp | 4 +- .../LibCompress/Tests/CMakeLists.txt | 5 +- .../LibCompress/Tests/TestDeflate.cpp | 4 +- .../Libraries/LibCompress/Tests/TestGzip.cpp | 4 +- .../Libraries/LibCompress/Tests/TestZlib.cpp | 4 +- .../Libraries/LibRegex/Tests/Benchmark.cpp | 4 +- .../Libraries/LibRegex/Tests/CMakeLists.txt | 5 +- Userland/Libraries/LibRegex/Tests/Regex.cpp | 4 +- .../Libraries/LibRegex/Tests/RegexLibC.cpp | 4 +- .../Libraries/LibSQL/Tests/CMakeLists.txt | 5 +- .../LibSQL/Tests/TestSqlExpressionParser.cpp | 4 +- .../LibSQL/Tests/TestSqlStatementParser.cpp | 4 +- Userland/Libraries/LibTest/CMakeLists.txt | 7 + Userland/Libraries/LibTest/Macros.h | 87 +++++ Userland/Libraries/LibTest/TestCase.h | 67 ++++ Userland/Libraries/LibTest/TestMain.cpp | 28 ++ Userland/Libraries/LibTest/TestSuite.cpp | 148 ++++++++ Userland/Libraries/LibTest/TestSuite.h | 55 +++ Userland/Tests/Kernel/CMakeLists.txt | 1 + Userland/Tests/LibC/CMakeLists.txt | 6 +- Userland/Tests/LibC/snprintf-correctness.cpp | 4 +- Userland/Tests/LibC/strlcpy-correctness.cpp | 4 +- Userland/Tests/LibGfx/CMakeLists.txt | 8 +- Userland/Tests/LibGfx/painter.cpp | 4 +- Userland/Tests/LibM/CMakeLists.txt | 5 +- Userland/Tests/LibM/test-math.cpp | 4 +- .../Tests/UserspaceEmulator/CMakeLists.txt | 1 + 94 files changed, 522 insertions(+), 579 deletions(-) delete mode 100644 AK/TestSuite.h create mode 100644 Userland/Libraries/LibTest/Macros.h create mode 100644 Userland/Libraries/LibTest/TestCase.h create mode 100644 Userland/Libraries/LibTest/TestMain.cpp create mode 100644 Userland/Libraries/LibTest/TestSuite.cpp create mode 100644 Userland/Libraries/LibTest/TestSuite.h diff --git a/AK/TestSuite.h b/AK/TestSuite.h deleted file mode 100644 index 0f062db9a7..0000000000 --- a/AK/TestSuite.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace AK { - -template -void warnln(CheckedFormatString&& fmtstr, const Parameters&...); - -// Declare a helper so that we can call it from VERIFY in included headers -// before defining TestSuite -inline void current_test_case_did_fail(); - -} - -using AK::warnln; - -#undef VERIFY -#define VERIFY(x) \ - do { \ - if (!(x)) { \ - ::AK::warnln("\033[31;1mFAIL\033[0m: {}:{}: VERIFY({}) failed", __FILE__, __LINE__, #x); \ - 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) - -#include -#include -#include -#include -#include -#include -#include - -namespace AK { - -class TestElapsedTimer { -public: - TestElapsedTimer() { restart(); } - - void restart() { gettimeofday(&m_started, nullptr); } - - u64 elapsed_milliseconds() - { - struct timeval now; - gettimeofday(&now, nullptr); - - struct timeval delta; - timersub(&now, &m_started, &delta); - - return delta.tv_sec * 1000 + delta.tv_usec / 1000; - } - -private: - struct timeval m_started; -}; - -using TestFunction = Function; - -class TestCase : public RefCounted { -public: - TestCase(const String& name, TestFunction&& fn, bool is_benchmark) - : m_name(name) - , m_function(move(fn)) - , m_is_benchmark(is_benchmark) - { - } - - bool is_benchmark() const { return m_is_benchmark; } - const String& name() const { return m_name; } - const TestFunction& func() const { return m_function; } - -private: - String m_name; - TestFunction m_function; - bool m_is_benchmark; -}; - -class TestSuite { -public: - static TestSuite& the() - { - if (s_global == nullptr) - s_global = new TestSuite(); - return *s_global; - } - - static void release() - { - if (s_global) - delete s_global; - s_global = nullptr; - } - - int run(const NonnullRefPtrVector&); - int main(const String& suite_name, int argc, char** argv); - NonnullRefPtrVector find_cases(const String& search, bool find_tests, bool find_benchmarks); - void add_case(const NonnullRefPtr& test_case) - { - m_cases.append(test_case); - } - - void current_test_case_did_fail() { m_current_test_case_passed = false; } - -private: - static TestSuite* s_global; - NonnullRefPtrVector m_cases; - u64 m_testtime = 0; - u64 m_benchtime = 0; - String m_suite_name; - bool m_current_test_case_passed = true; -}; - -inline void current_test_case_did_fail() { TestSuite::the().current_test_case_did_fail(); } - -int TestSuite::main(const String& suite_name, int argc, char** argv) -{ - m_suite_name = suite_name; - - Core::ArgsParser args_parser; - - bool do_tests_only = getenv("TESTS_ONLY") != nullptr; - bool do_benchmarks_only = false; - bool do_list_cases = false; - const char* search_string = "*"; - - args_parser.add_option(do_tests_only, "Only run tests.", "tests", 0); - args_parser.add_option(do_benchmarks_only, "Only run benchmarks.", "bench", 0); - args_parser.add_option(do_list_cases, "List available test cases.", "list", 0); - args_parser.add_positional_argument(search_string, "Only run matching cases.", "pattern", Core::ArgsParser::Required::No); - args_parser.parse(argc, argv); - - const auto& matching_tests = find_cases(search_string, !do_benchmarks_only, !do_tests_only); - - if (do_list_cases) { - outln("Available cases for {}:", suite_name); - for (const auto& test : matching_tests) { - outln(" {}", test.name()); - } - return 0; - } - - outln("Running {} cases out of {}.", matching_tests.size(), m_cases.size()); - - return run(matching_tests); -} - -NonnullRefPtrVector TestSuite::find_cases(const String& search, bool find_tests, bool find_benchmarks) -{ - NonnullRefPtrVector matches; - for (const auto& t : m_cases) { - if (!search.is_empty() && !t.name().matches(search, CaseSensitivity::CaseInsensitive)) { - continue; - } - - if (!find_tests && !t.is_benchmark()) { - continue; - } - if (!find_benchmarks && t.is_benchmark()) { - continue; - } - - matches.append(t); - } - return matches; -} - -int TestSuite::run(const NonnullRefPtrVector& tests) -{ - size_t test_count = 0; - size_t test_failed_count = 0; - size_t benchmark_count = 0; - TestElapsedTimer global_timer; - - for (const auto& t : tests) { - const auto test_type = t.is_benchmark() ? "benchmark" : "test"; - - warnln("Running {} '{}'.", test_type, t.name()); - m_current_test_case_passed = true; - - TestElapsedTimer timer; - t.func()(); - const auto time = timer.elapsed_milliseconds(); - - dbgln("{} {} '{}' in {}ms", m_current_test_case_passed ? "Completed" : "Failed", test_type, t.name(), time); - - if (t.is_benchmark()) { - m_benchtime += time; - benchmark_count++; - } else { - m_testtime += time; - test_count++; - } - - if (!m_current_test_case_passed) { - test_failed_count++; - } - } - - dbgln("Finished {} tests and {} benchmarks in {}ms ({}ms tests, {}ms benchmarks, {}ms other).", - test_count, - benchmark_count, - global_timer.elapsed_milliseconds(), - m_testtime, - m_benchtime, - global_timer.elapsed_milliseconds() - (m_testtime + m_benchtime)); - dbgln("Out of {} tests, {} passed and {} failed.", test_count, test_count - test_failed_count, test_failed_count); - - return (int)test_failed_count; -} - -} - -using AK::current_test_case_did_fail; -using AK::TestCase; -using AK::TestSuite; - -#define __TESTCASE_FUNC(x) __test_##x -#define __TESTCASE_TYPE(x) __TestCase_##x - -#define TEST_CASE(x) \ - static void __TESTCASE_FUNC(x)(); \ - struct __TESTCASE_TYPE(x) { \ - __TESTCASE_TYPE(x) \ - () { TestSuite::the().add_case(adopt_ref(*new TestCase(#x, __TESTCASE_FUNC(x), false))); } \ - }; \ - static struct __TESTCASE_TYPE(x) __TESTCASE_TYPE(x); \ - static void __TESTCASE_FUNC(x)() - -#define __BENCHMARK_FUNC(x) __benchmark_##x -#define __BENCHMARK_TYPE(x) __BenchmarkCase_##x - -#define BENCHMARK_CASE(x) \ - static void __BENCHMARK_FUNC(x)(); \ - struct __BENCHMARK_TYPE(x) { \ - __BENCHMARK_TYPE(x) \ - () { TestSuite::the().add_case(adopt_ref(*new TestCase(#x, __BENCHMARK_FUNC(x), true))); } \ - }; \ - static struct __BENCHMARK_TYPE(x) __BENCHMARK_TYPE(x); \ - static void __BENCHMARK_FUNC(x)() - -#define TEST_MAIN(x) \ - TestSuite* TestSuite::s_global = nullptr; \ - template \ - constexpr size_t compiletime_lenof(const char(&)[N]) \ - { \ - return N - 1; \ - } \ - int main(int argc, char** argv) \ - { \ - static_assert(compiletime_lenof(#x) != 0, "Set SuiteName"); \ - int ret = TestSuite::the().main(#x, argc, argv); \ - TestSuite::release(); \ - return ret; \ - } - -#define EXPECT_EQ(a, b) \ - do { \ - auto lhs = (a); \ - auto rhs = (b); \ - if (lhs != rhs) { \ - warnln("\033[31;1mFAIL\033[0m: {}:{}: EXPECT_EQ({}, {}) failed with lhs={} and rhs={}", __FILE__, __LINE__, #a, #b, FormatIfSupported { lhs }, FormatIfSupported { rhs }); \ - 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) { \ - warnln("\033[31;1mFAIL\033[0m: {}:{}: EXPECT_EQ({}, {}) failed with lhs={} and rhs={}", __FILE__, __LINE__, #a, #b, lhs, rhs); \ - current_test_case_did_fail(); \ - } \ - } while (false) - -#define EXPECT(x) \ - do { \ - if (!(x)) { \ - warnln("\033[31;1mFAIL\033[0m: {}:{}: EXPECT({}) failed", __FILE__, __LINE__, #x); \ - 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(expect_close_lhs) - static_cast(expect_close_rhs); \ - if (fabs(expect_close_diff) > 0.0000005) { \ - 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); \ - current_test_case_did_fail(); \ - } \ - } while (false) diff --git a/AK/Tests/CMakeLists.txt b/AK/Tests/CMakeLists.txt index e2de8f372d..28c7468a94 100644 --- a/AK/Tests/CMakeLists.txt +++ b/AK/Tests/CMakeLists.txt @@ -61,10 +61,7 @@ set(AK_TEST_SOURCES ) foreach(source ${AK_TEST_SOURCES}) - get_filename_component(name ${source} NAME_WE) - add_executable(${name} ${source}) - target_link_libraries(${name} LibCore) - install(TARGETS ${name} RUNTIME DESTINATION usr/Tests/AK) + serenity_test(${source} AK) endforeach() get_filename_component(TEST_FRM_RESOLVED ./test.frm REALPATH) diff --git a/AK/Tests/TestAllOf.cpp b/AK/Tests/TestAllOf.cpp index c953a14468..48f5d0f7aa 100644 --- a/AK/Tests/TestAllOf.cpp +++ b/AK/Tests/TestAllOf.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -19,5 +19,3 @@ TEST_CASE(should_determine_if_predicate_applies_to_all_elements_in_container) EXPECT(all_of(a.begin(), a.end(), [](auto elem) { return elem == 0; })); EXPECT(!all_of(a.begin(), a.end(), [](auto elem) { return elem == 1; })); } - -TEST_MAIN(AllOf) diff --git a/AK/Tests/TestAnyOf.cpp b/AK/Tests/TestAnyOf.cpp index e85c2fb17b..2fcfaf29e6 100644 --- a/AK/Tests/TestAnyOf.cpp +++ b/AK/Tests/TestAnyOf.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -21,5 +21,3 @@ TEST_CASE(should_determine_if_predicate_applies_to_any_element_in_container) EXPECT(any_of(a.begin(), a.end(), [](auto elem) { return elem == 1; })); EXPECT(!any_of(a.begin(), a.end(), [](auto elem) { return elem == 2; })); } - -TEST_MAIN(AllOf) diff --git a/AK/Tests/TestArray.cpp b/AK/Tests/TestArray.cpp index 901dda2ae5..440a9935ae 100644 --- a/AK/Tests/TestArray.cpp +++ b/AK/Tests/TestArray.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -28,5 +28,3 @@ TEST_CASE(compile_time_iterable) constexpr Array array = { 0, 1, 2, 3, 4, 5, 6, 7 }; static_assert(constexpr_sum(array) == 28); } - -TEST_MAIN(Array) diff --git a/AK/Tests/TestAtomic.cpp b/AK/Tests/TestAtomic.cpp index 0b0aa23bfd..eb7a3843ef 100644 --- a/AK/Tests/TestAtomic.cpp +++ b/AK/Tests/TestAtomic.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -340,5 +340,3 @@ TEST_CASE(fetch_xor) a_u8 = 0xe2; EXPECT((a_u8 ^= 0xef) == 0x0d); } - -TEST_MAIN(Atomic) diff --git a/AK/Tests/TestBadge.cpp b/AK/Tests/TestBadge.cpp index cebd3fdd27..8f12b9dcb3 100644 --- a/AK/Tests/TestBadge.cpp +++ b/AK/Tests/TestBadge.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -12,5 +12,3 @@ TEST_CASE(should_provide_underlying_type) { static_assert(IsSame::Type>); } - -TEST_MAIN(Badge) diff --git a/AK/Tests/TestBase64.cpp b/AK/Tests/TestBase64.cpp index 71a2c36588..698a86c354 100644 --- a/AK/Tests/TestBase64.cpp +++ b/AK/Tests/TestBase64.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -44,5 +44,3 @@ TEST_CASE(test_encode) encode_equal("fooba", "Zm9vYmE="); encode_equal("foobar", "Zm9vYmFy"); } - -TEST_MAIN(Base64) diff --git a/AK/Tests/TestBinaryHeap.cpp b/AK/Tests/TestBinaryHeap.cpp index 10865e84b0..dbd4a9a4af 100644 --- a/AK/Tests/TestBinaryHeap.cpp +++ b/AK/Tests/TestBinaryHeap.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -65,5 +65,3 @@ TEST_CASE(large_populate_reverse) EXPECT_EQ(ints.pop_min(), i); } } - -TEST_MAIN(BinaryHeap) diff --git a/AK/Tests/TestBinarySearch.cpp b/AK/Tests/TestBinarySearch.cpp index 6a7098220d..3e5d65c240 100644 --- a/AK/Tests/TestBinarySearch.cpp +++ b/AK/Tests/TestBinarySearch.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -116,5 +116,3 @@ TEST_CASE(unsigned_to_signed_regression) EXPECT_EQ(binary_search(input, 1u, &nearby_index), &input[1]); EXPECT_EQ(nearby_index, 1u); } - -TEST_MAIN(BinarySearch) diff --git a/AK/Tests/TestBitCast.cpp b/AK/Tests/TestBitCast.cpp index e341e79e12..baf270f9b6 100644 --- a/AK/Tests/TestBitCast.cpp +++ b/AK/Tests/TestBitCast.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -21,5 +21,3 @@ TEST_CASE(double_int_conversion) check_cast_both_ways(static_cast(1) << 63, -0.0); check_cast_both_ways(static_cast(0x4172f58bc0000000), 19880124.0); } - -TEST_MAIN(BitCast) diff --git a/AK/Tests/TestBitmap.cpp b/AK/Tests/TestBitmap.cpp index 5271353a79..b4326dcd54 100644 --- a/AK/Tests/TestBitmap.cpp +++ b/AK/Tests/TestBitmap.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -248,5 +248,3 @@ TEST_CASE(count_in_range) test_with_value(true); test_with_value(false); } - -TEST_MAIN(Bitmap) diff --git a/AK/Tests/TestByteBuffer.cpp b/AK/Tests/TestByteBuffer.cpp index 380022184b..a6fabd7085 100644 --- a/AK/Tests/TestByteBuffer.cpp +++ b/AK/Tests/TestByteBuffer.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -49,5 +49,3 @@ TEST_CASE(negative_operator_lt) // error: error: use of deleted function ‘bool AK::ByteBuffer::operator<(const AK::ByteBuffer&) const’ } #endif /* COMPILE_NEGATIVE_TESTS */ - -TEST_MAIN(ByteBuffer) diff --git a/AK/Tests/TestChecked.cpp b/AK/Tests/TestChecked.cpp index ec98872629..a4c932d696 100644 --- a/AK/Tests/TestChecked.cpp +++ b/AK/Tests/TestChecked.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -386,5 +386,3 @@ TEST_CASE(should_constexpr_make_via_factory) { [[maybe_unused]] constexpr auto value = make_checked(42); } - -TEST_MAIN(Checked) diff --git a/AK/Tests/TestCircularDeque.cpp b/AK/Tests/TestCircularDeque.cpp index 06218cb3f5..3fa5189bb8 100644 --- a/AK/Tests/TestCircularDeque.cpp +++ b/AK/Tests/TestCircularDeque.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -61,5 +61,3 @@ TEST_CASE(deque_end) EXPECT_EQ(ints.dequeue_end(), 0); EXPECT(ints.is_empty()); } - -TEST_MAIN(CircularDeque) diff --git a/AK/Tests/TestCircularDuplexStream.cpp b/AK/Tests/TestCircularDuplexStream.cpp index b2f3fa6ab2..62b5534bfb 100644 --- a/AK/Tests/TestCircularDuplexStream.cpp +++ b/AK/Tests/TestCircularDuplexStream.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -61,5 +61,3 @@ TEST_CASE(overwritting_is_well_defined) EXPECT(stream.eof()); } - -TEST_MAIN(CircularDuplexStream) diff --git a/AK/Tests/TestCircularQueue.cpp b/AK/Tests/TestCircularQueue.cpp index edbbd8a98d..edc3cb5184 100644 --- a/AK/Tests/TestCircularQueue.cpp +++ b/AK/Tests/TestCircularQueue.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -66,5 +66,3 @@ TEST_CASE(should_not_call_value_type_constructor_when_created) CircularQueue queue; EXPECT_EQ(0u, ConstructorCounter::s_num_constructor_calls); } - -TEST_MAIN(CircularQueue) diff --git a/AK/Tests/TestComplex.cpp b/AK/Tests/TestComplex.cpp index b3c9b17735..5079569d18 100644 --- a/AK/Tests/TestComplex.cpp +++ b/AK/Tests/TestComplex.cpp @@ -4,8 +4,9 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include + #include -#include TEST_CASE(Complex) { @@ -41,5 +42,3 @@ TEST_CASE(Complex) EXPECT_APPROXIMATE(cexp(Complex(0., 1.) * M_PI).real(), -1.); #endif } - -TEST_MAIN(Complex) diff --git a/AK/Tests/TestDistinctNumeric.cpp b/AK/Tests/TestDistinctNumeric.cpp index 94638c1a23..1ecc740098 100644 --- a/AK/Tests/TestDistinctNumeric.cpp +++ b/AK/Tests/TestDistinctNumeric.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -283,5 +283,3 @@ TEST_CASE(negative_incompatible) // | DistinctNumeric<[...],true,true,true,true,true,[...],[...],64> } #endif /* COMPILE_NEGATIVE_TESTS */ - -TEST_MAIN(DistinctNumeric) diff --git a/AK/Tests/TestDoublyLinkedList.cpp b/AK/Tests/TestDoublyLinkedList.cpp index d663efbc99..407484e443 100644 --- a/AK/Tests/TestDoublyLinkedList.cpp +++ b/AK/Tests/TestDoublyLinkedList.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -41,5 +41,3 @@ TEST_CASE(should_find_const) EXPECT_EQ(sut.end(), sut.find(42)); } - -TEST_MAIN(DoublyLinkedList) diff --git a/AK/Tests/TestEndian.cpp b/AK/Tests/TestEndian.cpp index 104a281ad6..7f7f1a57ff 100644 --- a/AK/Tests/TestEndian.cpp +++ b/AK/Tests/TestEndian.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -15,5 +15,3 @@ static_assert(BigEndian { 42 } == 42, "Big endian values should be value co static_assert(LittleEndian {} == 0, "Little endian values should be default constructed in a constexpr context."); static_assert(LittleEndian { 42 } == 42, "Little endian values should be value constructed in a constexpr context."); - -TEST_MAIN(Endian); diff --git a/AK/Tests/TestEnumBits.cpp b/AK/Tests/TestEnumBits.cpp index 9a357a1667..dc9eadf32d 100644 --- a/AK/Tests/TestEnumBits.cpp +++ b/AK/Tests/TestEnumBits.cpp @@ -4,8 +4,9 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include + #include -#include enum class VideoIntro : u8 { None = 0x0, @@ -66,5 +67,3 @@ TEST_CASE(has_flag) EXPECT(has_flag(intro, VideoIntro::Friends)); EXPECT(!has_flag(intro, VideoIntro::Well)); } - -TEST_MAIN(EnumBits) diff --git a/AK/Tests/TestFind.cpp b/AK/Tests/TestFind.cpp index d7df2bd9c6..26d4ab11fd 100644 --- a/AK/Tests/TestFind.cpp +++ b/AK/Tests/TestFind.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -52,5 +52,3 @@ TEST_CASE(should_return_index_to_first_predicate_matching_value_in_container) EXPECT(4 == AK::find_index(a.begin(), a.end(), 0)); } - -TEST_MAIN(Find) diff --git a/AK/Tests/TestFormat.cpp b/AK/Tests/TestFormat.cpp index cc7b2db8a4..525082b38f 100644 --- a/AK/Tests/TestFormat.cpp +++ b/AK/Tests/TestFormat.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -290,5 +290,3 @@ TEST_CASE(long_long_regression) EXPECT_EQ(builder.string_view(), "81985529216486895"); } - -TEST_MAIN(Format) diff --git a/AK/Tests/TestGenericLexer.cpp b/AK/Tests/TestGenericLexer.cpp index 6b5d09bef2..8b9a08cd1d 100644 --- a/AK/Tests/TestGenericLexer.cpp +++ b/AK/Tests/TestGenericLexer.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -156,5 +156,3 @@ TEST_CASE(should_constexpr_ignore_until_pred) }(); static_assert(sut.peek() == 'c'); } - -TEST_MAIN(GenericLexer) diff --git a/AK/Tests/TestHashFunctions.cpp b/AK/Tests/TestHashFunctions.cpp index 75c284b355..fa8eafae9e 100644 --- a/AK/Tests/TestHashFunctions.cpp +++ b/AK/Tests/TestHashFunctions.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -59,5 +59,3 @@ TEST_CASE(constexpr_ptr_hash) // "ptr_hash" test binds the result. static_assert(ptr_hash(FlatPtr(42))); } - -TEST_MAIN(HashFunctions) diff --git a/AK/Tests/TestHashMap.cpp b/AK/Tests/TestHashMap.cpp index dac0685d36..a057319309 100644 --- a/AK/Tests/TestHashMap.cpp +++ b/AK/Tests/TestHashMap.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -172,5 +172,3 @@ TEST_CASE(basic_contains) EXPECT_EQ(map.remove(1), true); EXPECT_EQ(map.contains(1), false); } - -TEST_MAIN(HashMap) diff --git a/AK/Tests/TestHashTable.cpp b/AK/Tests/TestHashTable.cpp index a0cae5014c..55c297e774 100644 --- a/AK/Tests/TestHashTable.cpp +++ b/AK/Tests/TestHashTable.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -173,5 +173,3 @@ TEST_CASE(basic_contains) EXPECT_EQ(table.remove(1), true); EXPECT_EQ(table.contains(1), false); } - -TEST_MAIN(HashTable) diff --git a/AK/Tests/TestHex.cpp b/AK/Tests/TestHex.cpp index 7bbf0f8e2a..0f94cc03c8 100644 --- a/AK/Tests/TestHex.cpp +++ b/AK/Tests/TestHex.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -59,5 +59,3 @@ TEST_CASE(should_constexpr_decode_hex_digit) static_assert(14u == decode_hex_digit('E')); static_assert(15u == decode_hex_digit('F')); } - -TEST_MAIN(Hex) diff --git a/AK/Tests/TestIPv4Address.cpp b/AK/Tests/TestIPv4Address.cpp index e0a787ded3..b8f07d1e3c 100644 --- a/AK/Tests/TestIPv4Address.cpp +++ b/AK/Tests/TestIPv4Address.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -151,5 +151,3 @@ TEST_CASE(should_compare) EXPECT(addr_a != addr_b); EXPECT(addr_a == addr_a); } - -TEST_MAIN(IPv4Address) diff --git a/AK/Tests/TestIndexSequence.cpp b/AK/Tests/TestIndexSequence.cpp index d7943873f6..31b9401651 100644 --- a/AK/Tests/TestIndexSequence.cpp +++ b/AK/Tests/TestIndexSequence.cpp @@ -4,8 +4,9 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include + #include -#include #include template @@ -46,5 +47,3 @@ TEST_CASE(TypeList) static_assert(IsSame, bool>, ""); static_assert(IsSame, char>, ""); } - -TEST_MAIN(IndexSequence); diff --git a/AK/Tests/TestIntrusiveList.cpp b/AK/Tests/TestIntrusiveList.cpp index 3e3012bc20..f75db9afb7 100644 --- a/AK/Tests/TestIntrusiveList.cpp +++ b/AK/Tests/TestIntrusiveList.cpp @@ -4,10 +4,11 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include + #include #include #include -#include class IntrusiveTestItem { public: @@ -120,5 +121,3 @@ TEST_CASE(intrusive_nonnull_ref_ptr_intrusive) EXPECT(nonnull_ref_list.is_empty()); } - -TEST_MAIN(IntrusiveList) diff --git a/AK/Tests/TestIntrusiveRedBlackTree.cpp b/AK/Tests/TestIntrusiveRedBlackTree.cpp index 0271e4af11..207b026cec 100644 --- a/AK/Tests/TestIntrusiveRedBlackTree.cpp +++ b/AK/Tests/TestIntrusiveRedBlackTree.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -114,5 +114,3 @@ TEST_CASE(clear) test.clear(); EXPECT_EQ(test.size(), 0u); } - -TEST_MAIN(RedBlackTree) diff --git a/AK/Tests/TestJSON.cpp b/AK/Tests/TestJSON.cpp index e0c85e1e03..d85f68c2b5 100644 --- a/AK/Tests/TestJSON.cpp +++ b/AK/Tests/TestJSON.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -121,5 +121,3 @@ TEST_CASE(json_duplicate_keys) json.set("test", "baz"); EXPECT_EQ(json.to_string(), "{\"test\":\"baz\"}"); } - -TEST_MAIN(JSON) diff --git a/AK/Tests/TestLexicalPath.cpp b/AK/Tests/TestLexicalPath.cpp index ac96bf58d6..044f5f157a 100644 --- a/AK/Tests/TestLexicalPath.cpp +++ b/AK/Tests/TestLexicalPath.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -74,5 +74,3 @@ TEST_CASE(relative_path) EXPECT_EQ(LexicalPath::relative_path("/tmp/foo.txt", "tmp"), String {}); EXPECT_EQ(LexicalPath::relative_path("tmp/foo.txt", "/tmp"), String {}); } - -TEST_MAIN(LexicalPath) diff --git a/AK/Tests/TestMACAddress.cpp b/AK/Tests/TestMACAddress.cpp index 7f87967f87..f91ae043a2 100644 --- a/AK/Tests/TestMACAddress.cpp +++ b/AK/Tests/TestMACAddress.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -82,5 +82,3 @@ TEST_CASE(should_string_format) MACAddress sut(1, 2, 3, 4, 5, 6); EXPECT_EQ("01:02:03:04:05:06", sut.to_string()); } - -TEST_MAIN(MACAddress) diff --git a/AK/Tests/TestMemMem.cpp b/AK/Tests/TestMemMem.cpp index 8e1266f5c7..f4dd0a3e52 100644 --- a/AK/Tests/TestMemMem.cpp +++ b/AK/Tests/TestMemMem.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -66,5 +66,3 @@ TEST_CASE(kmp_two_chunks) EXPECT_EQ(result_2.value_or(9), 4u); EXPECT(!result_3.has_value()); } - -TEST_MAIN(MemMem) diff --git a/AK/Tests/TestMemoryStream.cpp b/AK/Tests/TestMemoryStream.cpp index 23d1dfff6d..90512fe456 100644 --- a/AK/Tests/TestMemoryStream.cpp +++ b/AK/Tests/TestMemoryStream.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -220,5 +220,3 @@ TEST_CASE(offset_calculation_error_regression) EXPECT_EQ(input, output); } - -TEST_MAIN(MemoryStream) diff --git a/AK/Tests/TestNeverDestroyed.cpp b/AK/Tests/TestNeverDestroyed.cpp index 29931f2757..7b72d6bae3 100644 --- a/AK/Tests/TestNeverDestroyed.cpp +++ b/AK/Tests/TestNeverDestroyed.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -71,5 +71,3 @@ TEST_CASE(should_provide_basic_getter) AK::NeverDestroyed n {}; EXPECT_EQ(0, n.get().num_destroys); } - -TEST_MAIN(NeverDestroyed) diff --git a/AK/Tests/TestNonnullRefPtr.cpp b/AK/Tests/TestNonnullRefPtr.cpp index 19d43fc2e2..c26adadacc 100644 --- a/AK/Tests/TestNonnullRefPtr.cpp +++ b/AK/Tests/TestNonnullRefPtr.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -59,5 +59,3 @@ TEST_CASE(swap_with_self) swap(object, object); EXPECT_EQ(object->ref_count(), 1u); } - -TEST_MAIN(NonnullRefPtr) diff --git a/AK/Tests/TestNumberFormat.cpp b/AK/Tests/TestNumberFormat.cpp index f4f9d64426..373d3bef98 100644 --- a/AK/Tests/TestNumberFormat.cpp +++ b/AK/Tests/TestNumberFormat.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -125,5 +125,3 @@ TEST_CASE(extremes_8byte) warnln("(Skipping 8-byte-size_t test on 32-bit platform)"); } } - -TEST_MAIN(NumberFormat) diff --git a/AK/Tests/TestOptional.cpp b/AK/Tests/TestOptional.cpp index e14c513d0e..583d11f0eb 100644 --- a/AK/Tests/TestOptional.cpp +++ b/AK/Tests/TestOptional.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -53,5 +53,3 @@ TEST_CASE(short_notation) EXPECT_EQ(value->length(), 3u); EXPECT_EQ(*value, "foo"); } - -TEST_MAIN(Optional) diff --git a/AK/Tests/TestQueue.cpp b/AK/Tests/TestQueue.cpp index 12e240c275..6e11e6e685 100644 --- a/AK/Tests/TestQueue.cpp +++ b/AK/Tests/TestQueue.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -57,5 +57,3 @@ TEST_CASE(order) EXPECT(strings.is_empty()); } - -TEST_MAIN(Queue) diff --git a/AK/Tests/TestQuickSort.cpp b/AK/Tests/TestQuickSort.cpp index 70c8c74edc..23fc7692dc 100644 --- a/AK/Tests/TestQuickSort.cpp +++ b/AK/Tests/TestQuickSort.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -98,5 +98,3 @@ TEST_CASE(maximum_stack_depth) delete[] data; } - -TEST_MAIN(QuickSort) diff --git a/AK/Tests/TestRedBlackTree.cpp b/AK/Tests/TestRedBlackTree.cpp index 9940a968c6..51f9549957 100644 --- a/AK/Tests/TestRedBlackTree.cpp +++ b/AK/Tests/TestRedBlackTree.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -86,5 +86,3 @@ TEST_CASE(clear) test.clear(); EXPECT_EQ(test.size(), 0u); } - -TEST_MAIN(RedBlackTree) diff --git a/AK/Tests/TestRefPtr.cpp b/AK/Tests/TestRefPtr.cpp index f8461183f8..8c85ace774 100644 --- a/AK/Tests/TestRefPtr.cpp +++ b/AK/Tests/TestRefPtr.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -147,5 +147,3 @@ TEST_CASE(self_observers) object->unref(); EXPECT_EQ(SelfAwareObject::num_destroyed, 1u); } - -TEST_MAIN(RefPtr) diff --git a/AK/Tests/TestSinglyLinkedList.cpp b/AK/Tests/TestSinglyLinkedList.cpp index 9d5b51c790..3df43d2cb5 100644 --- a/AK/Tests/TestSinglyLinkedList.cpp +++ b/AK/Tests/TestSinglyLinkedList.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -59,5 +59,3 @@ TEST_CASE(should_find_const_with_predicate) EXPECT_EQ(sut.end(), sut.find_if([](const auto v) { return v == 42; })); } - -TEST_MAIN(SinglyLinkedList) diff --git a/AK/Tests/TestSourceGenerator.cpp b/AK/Tests/TestSourceGenerator.cpp index c6cd3fd6ea..9b8a3b7b6c 100644 --- a/AK/Tests/TestSourceGenerator.cpp +++ b/AK/Tests/TestSourceGenerator.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -69,5 +69,3 @@ TEST_CASE(scoped) EXPECT_EQ(global_generator.as_string_view(), "\nfoo-0 bar-0\nfoo-0 bar-0\nfoo-0 bar-0\nfoo-2 bar-0\nfoo-2 bar-3\nfoo-0 bar-0\nfoo-2 bar-0\n"); } - -TEST_MAIN(SourceGenerator) diff --git a/AK/Tests/TestSourceLocation.cpp b/AK/Tests/TestSourceLocation.cpp index 12f2e16c17..15910062f3 100644 --- a/AK/Tests/TestSourceLocation.cpp +++ b/AK/Tests/TestSourceLocation.cpp @@ -5,9 +5,10 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include + #include #include -#include TEST_CASE(basic_scenario) { @@ -29,5 +30,3 @@ TEST_CASE(default_arg_scenario) EXPECT_EQ(expected_calling_function, actual_calling_function); } - -TEST_MAIN(SourceLocation) diff --git a/AK/Tests/TestSpan.cpp b/AK/Tests/TestSpan.cpp index 1b3587d755..2668133c4e 100644 --- a/AK/Tests/TestSpan.cpp +++ b/AK/Tests/TestSpan.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -123,5 +123,3 @@ TEST_CASE(span_from_c_string) const char* str = "Serenity"; [[maybe_unused]] ReadonlyBytes bytes { str, strlen(str) }; } - -TEST_MAIN(Span) diff --git a/AK/Tests/TestString.cpp b/AK/Tests/TestString.cpp index ab5dde54a6..b61828199e 100644 --- a/AK/Tests/TestString.cpp +++ b/AK/Tests/TestString.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -235,5 +235,3 @@ TEST_CASE(sprintf) EXPECT_EQ(String(buf1), String("+12")); EXPECT_EQ(String(buf2), String("-12")); } - -TEST_MAIN(String) diff --git a/AK/Tests/TestStringUtils.cpp b/AK/Tests/TestStringUtils.cpp index 1f13594468..315c14f1da 100644 --- a/AK/Tests/TestStringUtils.cpp +++ b/AK/Tests/TestStringUtils.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -304,5 +304,3 @@ TEST_CASE(to_snakecase) EXPECT_EQ(AK::StringUtils::to_snakecase("FBar"), "f_bar"); EXPECT_EQ(AK::StringUtils::to_snakecase("FooB"), "foo_b"); } - -TEST_MAIN(StringUtils) diff --git a/AK/Tests/TestStringView.cpp b/AK/Tests/TestStringView.cpp index 28a35a301e..2ffbdf65fd 100644 --- a/AK/Tests/TestStringView.cpp +++ b/AK/Tests/TestStringView.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -177,5 +177,3 @@ TEST_CASE(split_view) EXPECT_EQ(test_string_view.split_view_if(predicate), Vector({ "a", "b", "c", "d" })); EXPECT_EQ(test_string_view.split_view_if(predicate, true), Vector({ "a", "", "b", "c", "d" })); } - -TEST_MAIN(StringView) diff --git a/AK/Tests/TestTime.cpp b/AK/Tests/TestTime.cpp index 732450b75d..61319cd605 100644 --- a/AK/Tests/TestTime.cpp +++ b/AK/Tests/TestTime.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -261,5 +261,3 @@ TEST_CASE(truncation) EXPECT_EQ(TIME(9223372036854, 775'807'000).to_truncated_microseconds(), 0x7fff'ffff'ffff'ffff); EXPECT_EQ(TIME(9223372036854, 775'808'000).to_truncated_microseconds(), 0x7fff'ffff'ffff'ffff); } - -TEST_MAIN(Time) diff --git a/AK/Tests/TestTrie.cpp b/AK/Tests/TestTrie.cpp index 83279d8a2a..50b574cced 100644 --- a/AK/Tests/TestTrie.cpp +++ b/AK/Tests/TestTrie.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -66,5 +66,3 @@ TEST_CASE(iterate) ++i; } } - -TEST_MAIN(Trie) diff --git a/AK/Tests/TestTypeTraits.cpp b/AK/Tests/TestTypeTraits.cpp index 810efa99b7..ecea1bfc15 100644 --- a/AK/Tests/TestTypeTraits.cpp +++ b/AK/Tests/TestTypeTraits.cpp @@ -4,8 +4,9 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include + #include -#include #include #define STATIC_EXPECT_EQ(lhs, rhs) \ @@ -104,5 +105,3 @@ TEST_CASE(UnderlyingType) STATIC_EXPECT_EQ(Type, u8); } - -TEST_MAIN(TypeTraits) diff --git a/AK/Tests/TestTypedTransfer.cpp b/AK/Tests/TestTypedTransfer.cpp index 72380f6a7e..5a0c347092 100644 --- a/AK/Tests/TestTypedTransfer.cpp +++ b/AK/Tests/TestTypedTransfer.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -39,5 +39,3 @@ TEST_CASE(overlapping_source_and_destination_2) for (size_t i = 0; i < 6; ++i) EXPECT_EQ(actual[i].m_value, expected[i].m_value); } - -TEST_MAIN(TypedTransfer) diff --git a/AK/Tests/TestURL.cpp b/AK/Tests/TestURL.cpp index 104dd7c214..c92ee4fc5b 100644 --- a/AK/Tests/TestURL.cpp +++ b/AK/Tests/TestURL.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -200,5 +200,3 @@ TEST_CASE(port_int_overflow_wrap) EXPECT_EQ(url.port(), expected_port); EXPECT_EQ(url.is_valid(), true); } - -TEST_MAIN(URL) diff --git a/AK/Tests/TestUtf8.cpp b/AK/Tests/TestUtf8.cpp index 1336fa3537..4a3f4e8029 100644 --- a/AK/Tests/TestUtf8.cpp +++ b/AK/Tests/TestUtf8.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include @@ -67,5 +67,3 @@ TEST_CASE(validate_invalid_ut8) EXPECT(!utf8_4.validate(valid_bytes)); EXPECT(valid_bytes == 0); } - -TEST_MAIN(UTF8) diff --git a/AK/Tests/TestVector.cpp b/AK/Tests/TestVector.cpp index b81c01ac75..0439a0605f 100644 --- a/AK/Tests/TestVector.cpp +++ b/AK/Tests/TestVector.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -399,5 +399,3 @@ TEST_CASE(should_find_index) EXPECT_EQ(4u, v.find_first_index(0).value()); EXPECT(!v.find_first_index(42).has_value()); } - -TEST_MAIN(Vector) diff --git a/AK/Tests/TestWeakPtr.cpp b/AK/Tests/TestWeakPtr.cpp index 63651204b1..8a573276cd 100644 --- a/AK/Tests/TestWeakPtr.cpp +++ b/AK/Tests/TestWeakPtr.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -64,5 +64,3 @@ TEST_CASE(weakptr_move) EXPECT_EQ(weak2.is_null(), true); } - -TEST_MAIN(WeakPtr) diff --git a/Meta/CMake/utils.cmake b/Meta/CMake/utils.cmake index e3aa4e136e..a57cee686c 100644 --- a/Meta/CMake/utils.cmake +++ b/Meta/CMake/utils.cmake @@ -29,7 +29,6 @@ endfunction() function(serenity_lib target_name fs_name) serenity_install_headers(${target_name}) serenity_install_sources("Userland/Libraries/${target_name}") - #add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES}) add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES}) install(TARGETS ${target_name} DESTINATION usr/lib) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name}) @@ -74,6 +73,21 @@ function(serenity_bin target_name) serenity_generated_sources(${target_name}) endfunction() +function(serenity_test test_src sub_dir) + cmake_parse_arguments(SERENITY_TEST "CUSTOM_MAIN" "" "LIBS" ${ARGN}) + set(TEST_SOURCES ${test_src}) + if (NOT ${SERENITY_TEST_CUSTOM_MAIN}) + list(APPEND TEST_SOURCES "${CMAKE_SOURCE_DIR}/Userland/Libraries/LibTest/TestMain.cpp") + endif() + get_filename_component(test_name ${test_src} NAME_WE) + add_executable(${test_name} ${TEST_SOURCES}) + target_link_libraries(${test_name} LibTest LibCore) + foreach(lib ${SERENITY_TEST_LIBS}) + target_link_libraries(${test_name} ${lib}) + endforeach() + install(TARGETS ${test_name} RUNTIME DESTINATION usr/Tests/${sub_dir}) +endfunction() + function(serenity_app target_name) cmake_parse_arguments(SERENITY_APP "" "ICON" "" ${ARGN}) diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 556345d5ed..ccc4a58915 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -77,9 +77,14 @@ list(FILTER SHELL_SOURCES EXCLUDE REGEX ".*main.cpp$") file(GLOB LIBSQL_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibSQL/*.cpp") file(GLOB LIBSQL_TEST_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibSQL/Tests/*.cpp") +file(GLOB LIBTEST_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibTest/*.cpp") +list(FILTER LIBTEST_SOURCES EXCLUDE REGEX ".*Main.cpp$") +file(GLOB LIBTEST_MAIN CONFIGURE_DEPENDS "../../Userland/Libraries/LibTest/TestMain.cpp") + set(LAGOM_REGEX_SOURCES ${LIBREGEX_LIBC_SOURCES} ${LIBREGEX_SOURCES}) set(LAGOM_CORE_SOURCES ${AK_SOURCES} ${LIBCORE_SOURCES}) set(LAGOM_MORE_SOURCES ${LIBARCHIVE_SOURCES} ${LIBAUDIO_SOURCES} ${LIBELF_SOURCES} ${LIBIPC_SOURCES} ${LIBLINE_SOURCES} ${LIBJS_SOURCES} ${LIBJS_SUBDIR_SOURCES} ${LIBX86_SOURCES} ${LIBCRYPTO_SOURCES} ${LIBCOMPRESS_SOURCES} ${LIBCRYPTO_SUBDIR_SOURCES} ${LIBTLS_SOURCES} ${LIBTTF_SOURCES} ${LIBTEXTCODEC_SOURCES} ${LIBMARKDOWN_SOURCES} ${LIBGEMINI_SOURCES} ${LIBGFX_SOURCES} ${LIBGUI_GML_SOURCES} ${LIBHTTP_SOURCES} ${LAGOM_REGEX_SOURCES} ${SHELL_SOURCES} ${LIBSQL_SOURCES}) +set(LAGOM_TEST_SOURCES ${LIBTEST_SOURCES}) # FIXME: This is a hack, because the lagom stuff can be build individually or # in combination with the system, we generate two Debug.h files. One in @@ -98,6 +103,7 @@ if (BUILD_LAGOM) if (NOT ENABLE_OSS_FUZZ AND NOT ENABLE_FUZZER_SANITIZER) enable_testing() + add_library(LagomTest $ ${LAGOM_TEST_SOURCES}) add_executable(TestApp TestApp.cpp) target_link_libraries(TestApp Lagom) target_link_libraries(TestApp stdc++) @@ -178,8 +184,8 @@ if (BUILD_LAGOM) foreach(source ${AK_TEST_SOURCES}) get_filename_component(name ${source} NAME_WE) - add_executable(${name}_lagom ${source}) - target_link_libraries(${name}_lagom LagomCore) + add_executable(${name}_lagom ${source} ${LIBTEST_MAIN}) + target_link_libraries(${name}_lagom LagomTest) add_test( NAME ${name}_lagom COMMAND ${name}_lagom @@ -190,8 +196,8 @@ if (BUILD_LAGOM) foreach(source ${LIBREGEX_TESTS}) get_filename_component(name ${source} NAME_WE) - add_executable(${name}_lagom ${source} ${LAGOM_REGEX_SOURCES}) - target_link_libraries(${name}_lagom LagomCore) + add_executable(${name}_lagom ${source} ${LAGOM_REGEX_SOURCES} ${LIBTEST_MAIN}) + target_link_libraries(${name}_lagom LagomTest) add_test( NAME ${name}_lagom COMMAND ${name}_lagom @@ -201,8 +207,8 @@ if (BUILD_LAGOM) foreach(source ${LIBCOMPRESS_TESTS}) get_filename_component(name ${source} NAME_WE) - add_executable(${name}_lagom ${source} ${LIBCOMPRESS_SOURCES}) - target_link_libraries(${name}_lagom Lagom) + add_executable(${name}_lagom ${source} ${LIBCOMPRESS_SOURCES} ${LIBTEST_MAIN}) + target_link_libraries(${name}_lagom Lagom LagomTest) add_test( NAME ${name}_lagom COMMAND ${name}_lagom @@ -212,8 +218,8 @@ if (BUILD_LAGOM) foreach(source ${LIBSQL_TEST_SOURCES}) get_filename_component(name ${source} NAME_WE) - add_executable(${name}_lagom ${source} ${LIBSQL_SOURCES}) - target_link_libraries(${name}_lagom LagomCore) + add_executable(${name}_lagom ${source} ${LIBSQL_SOURCES} ${LIBTEST_MAIN}) + target_link_libraries(${name}_lagom LagomTest) add_test( NAME ${name}_lagom COMMAND ${name}_lagom diff --git a/Userland/Applications/Spreadsheet/CMakeLists.txt b/Userland/Applications/Spreadsheet/CMakeLists.txt index 15a9f6c020..73945a9a5f 100644 --- a/Userland/Applications/Spreadsheet/CMakeLists.txt +++ b/Userland/Applications/Spreadsheet/CMakeLists.txt @@ -37,3 +37,7 @@ set(GENERATED_SOURCES serenity_app(Spreadsheet ICON app-spreadsheet) target_link_libraries(Spreadsheet LibGUI LibJS LibWeb) + +# FIXME: build these tests +#serenity_test(Writers/Test/TestXSVWriter.cpp Spreadsheet) +#serenity_test(Readers/Test/TestXSV.cpp Spreadsheet) diff --git a/Userland/Applications/Spreadsheet/Readers/Test/TestXSV.cpp b/Userland/Applications/Spreadsheet/Readers/Test/TestXSV.cpp index 196a496c55..0155912fb2 100644 --- a/Userland/Applications/Spreadsheet/Readers/Test/TestXSV.cpp +++ b/Userland/Applications/Spreadsheet/Readers/Test/TestXSV.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include "../CSV.h" #include "../XSV.h" @@ -86,5 +86,3 @@ BENCHMARK_CASE(fairly_big_data) EXPECT(!csv.has_error()); EXPECT_EQ(csv.size(), 100000u); } - -TEST_MAIN(XSV) diff --git a/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp b/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp index 5dad1dcfdd..8f0348bf8d 100644 --- a/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp +++ b/Userland/Applications/Spreadsheet/Writers/Test/TestXSVWriter.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include "../CSV.h" #include "../XSV.h" @@ -72,5 +72,3 @@ We"ll,"Hello,", Friends EXPECT_EQ(StringView { stream.bytes() }, expected_output); } - -TEST_MAIN(XSV) diff --git a/Userland/Libraries/LibC/Tests/CMakeLists.txt b/Userland/Libraries/LibC/Tests/CMakeLists.txt index 768d984227..5dff11b9a3 100644 --- a/Userland/Libraries/LibC/Tests/CMakeLists.txt +++ b/Userland/Libraries/LibC/Tests/CMakeLists.txt @@ -1,8 +1,5 @@ file(GLOB TEST_SOURCES CONFIGURE_DEPENDS "*.cpp") foreach(source ${TEST_SOURCES}) - get_filename_component(name ${source} NAME_WE) - add_executable(${name} ${source}) - target_link_libraries(${name} LibC LibCore) - install(TARGETS ${name} RUNTIME DESTINATION usr/Tests/LibC) + serenity_test(${source} LibC) endforeach() diff --git a/Userland/Libraries/LibC/Tests/TestLibCTime.cpp b/Userland/Libraries/LibC/Tests/TestLibCTime.cpp index 4e4c3dd303..fcf2327639 100644 --- a/Userland/Libraries/LibC/Tests/TestLibCTime.cpp +++ b/Userland/Libraries/LibC/Tests/TestLibCTime.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include #include const auto expected_epoch = "Thu Jan 1 00:00:00 1970\n"sv; @@ -41,5 +41,3 @@ TEST_CASE(ctime_r) EXPECT_EQ(expected_epoch, StringView(result)); } - -TEST_MAIN(LibCTime) diff --git a/Userland/Libraries/LibCompress/Tests/CMakeLists.txt b/Userland/Libraries/LibCompress/Tests/CMakeLists.txt index 8b15789971..bfd8880d1d 100644 --- a/Userland/Libraries/LibCompress/Tests/CMakeLists.txt +++ b/Userland/Libraries/LibCompress/Tests/CMakeLists.txt @@ -1,8 +1,5 @@ file(GLOB TEST_SOURCES CONFIGURE_DEPENDS "*.cpp") foreach(source ${TEST_SOURCES}) - get_filename_component(name ${source} NAME_WE) - add_executable(${name} ${source}) - target_link_libraries(${name} LibCore LibCompress) - install(TARGETS ${name} RUNTIME DESTINATION usr/Tests/LibCompress) + serenity_test(${source} LibCompress LIBS LibCompress) endforeach() diff --git a/Userland/Libraries/LibCompress/Tests/TestDeflate.cpp b/Userland/Libraries/LibCompress/Tests/TestDeflate.cpp index af88c9f180..7b992d8fee 100644 --- a/Userland/Libraries/LibCompress/Tests/TestDeflate.cpp +++ b/Userland/Libraries/LibCompress/Tests/TestDeflate.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -155,5 +155,3 @@ TEST_CASE(deflate_compress_literals) auto compressed = Compress::DeflateCompressor::compress_all(test, Compress::DeflateCompressor::CompressionLevel::GOOD); EXPECT(compressed.has_value()); } - -TEST_MAIN(Deflate) diff --git a/Userland/Libraries/LibCompress/Tests/TestGzip.cpp b/Userland/Libraries/LibCompress/Tests/TestGzip.cpp index 8d04b238a5..189d5b52c9 100644 --- a/Userland/Libraries/LibCompress/Tests/TestGzip.cpp +++ b/Userland/Libraries/LibCompress/Tests/TestGzip.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -95,5 +95,3 @@ TEST_CASE(gzip_round_trip) EXPECT(uncompressed.has_value()); EXPECT(uncompressed.value() == original); } - -TEST_MAIN(Gzip) diff --git a/Userland/Libraries/LibCompress/Tests/TestZlib.cpp b/Userland/Libraries/LibCompress/Tests/TestZlib.cpp index 1d6b0a0408..8ab5b81a95 100644 --- a/Userland/Libraries/LibCompress/Tests/TestZlib.cpp +++ b/Userland/Libraries/LibCompress/Tests/TestZlib.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -23,5 +23,3 @@ TEST_CASE(zlib_decompress_simple) const auto decompressed = Compress::Zlib::decompress_all(compressed); EXPECT(decompressed.value().bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 })); } - -TEST_MAIN(Zlib) diff --git a/Userland/Libraries/LibRegex/Tests/Benchmark.cpp b/Userland/Libraries/LibRegex/Tests/Benchmark.cpp index 8e13cce111..b51316fdb5 100644 --- a/Userland/Libraries/LibRegex/Tests/Benchmark.cpp +++ b/Userland/Libraries/LibRegex/Tests/Benchmark.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include // import first, to prevent warning of VERIFY* redefinition +#include // import first, to prevent warning of VERIFY* redefinition #include #include @@ -967,5 +967,3 @@ BENCHMARK_CASE(simple_notbol_noteol_benchmark_reference_stdcpp) # endif #endif - -TEST_MAIN(Regex) diff --git a/Userland/Libraries/LibRegex/Tests/CMakeLists.txt b/Userland/Libraries/LibRegex/Tests/CMakeLists.txt index 66478f6ad6..a9ccade427 100644 --- a/Userland/Libraries/LibRegex/Tests/CMakeLists.txt +++ b/Userland/Libraries/LibRegex/Tests/CMakeLists.txt @@ -2,8 +2,5 @@ file(GLOB TEST_SOURCES CONFIGURE_DEPENDS "*.cpp") file(GLOB REGEX_SOURCES CONFIGURE_DEPENDS "../*.cpp" "../C/*.cpp") foreach(source ${TEST_SOURCES}) - get_filename_component(name ${source} NAME_WE) - add_executable(${name} ${source} ${REGEX_SOURCES}) - target_link_libraries(${name} LibCore) - install(TARGETS ${name} RUNTIME DESTINATION usr/Tests/LibRegex) + serenity_test(${source} LibRegex LIBS LibRegex) endforeach() diff --git a/Userland/Libraries/LibRegex/Tests/Regex.cpp b/Userland/Libraries/LibRegex/Tests/Regex.cpp index 5aeb4ccbf8..054c54485b 100644 --- a/Userland/Libraries/LibRegex/Tests/Regex.cpp +++ b/Userland/Libraries/LibRegex/Tests/Regex.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include // import first, to prevent warning of VERIFY* redefinition +#include // import first, to prevent warning of VERIFY* redefinition #include #include @@ -595,5 +595,3 @@ TEST_CASE(replace) EXPECT_EQ(re.replace(test.subject, test.replacement), test.expected); } } - -TEST_MAIN(Regex) diff --git a/Userland/Libraries/LibRegex/Tests/RegexLibC.cpp b/Userland/Libraries/LibRegex/Tests/RegexLibC.cpp index 7e001f4b65..bea5e5984c 100644 --- a/Userland/Libraries/LibRegex/Tests/RegexLibC.cpp +++ b/Userland/Libraries/LibRegex/Tests/RegexLibC.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -1116,5 +1116,3 @@ TEST_CASE(simple_notbol_noteol) regfree(®ex); } - -TEST_MAIN(Regex) diff --git a/Userland/Libraries/LibSQL/Tests/CMakeLists.txt b/Userland/Libraries/LibSQL/Tests/CMakeLists.txt index b028333c61..f002a1e864 100644 --- a/Userland/Libraries/LibSQL/Tests/CMakeLists.txt +++ b/Userland/Libraries/LibSQL/Tests/CMakeLists.txt @@ -1,8 +1,5 @@ file(GLOB TEST_SOURCES CONFIGURE_DEPENDS "*.cpp") foreach(source ${TEST_SOURCES}) - get_filename_component(name ${source} NAME_WE) - add_executable(${name} ${source}) - target_link_libraries(${name} LibSQL) - install(TARGETS ${name} RUNTIME DESTINATION usr/Tests/LibSQL) + serenity_test(${source} LibSQL LIBS LibSQL) endforeach() diff --git a/Userland/Libraries/LibSQL/Tests/TestSqlExpressionParser.cpp b/Userland/Libraries/LibSQL/Tests/TestSqlExpressionParser.cpp index a3d2e6d32f..c2a6b3bfd7 100644 --- a/Userland/Libraries/LibSQL/Tests/TestSqlExpressionParser.cpp +++ b/Userland/Libraries/LibSQL/Tests/TestSqlExpressionParser.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -602,5 +602,3 @@ TEST_CASE(in_selection_expression) validate("15 IN (SELECT * FROM table)", false); validate("15 NOT IN (SELECT * FROM table)", true); } - -TEST_MAIN(SqlExpressionParser) diff --git a/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp b/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp index 7438311bdc..0126a85e4e 100644 --- a/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp +++ b/Userland/Libraries/LibSQL/Tests/TestSqlStatementParser.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -735,5 +735,3 @@ TEST_CASE(common_table_expression) validate("WITH table (column1, column2) AS (SELECT * FROM table) DELETE FROM table;", { false, { { "table", { "column1", "column2" } } } }); validate("WITH RECURSIVE table AS (SELECT * FROM table) DELETE FROM table;", { true, { { "table", {} } } }); } - -TEST_MAIN(SqlStatementParser) diff --git a/Userland/Libraries/LibTest/CMakeLists.txt b/Userland/Libraries/LibTest/CMakeLists.txt index a924ea3e3f..7816fdac71 100644 --- a/Userland/Libraries/LibTest/CMakeLists.txt +++ b/Userland/Libraries/LibTest/CMakeLists.txt @@ -1 +1,8 @@ serenity_install_sources("Userland/Libraries/LibTest") + +set(SOURCES + TestSuite.cpp +) + +serenity_lib(LibTest test) +target_link_libraries(LibTest LibC) diff --git a/Userland/Libraries/LibTest/Macros.h b/Userland/Libraries/LibTest/Macros.h new file mode 100644 index 0000000000..b4704508e2 --- /dev/null +++ b/Userland/Libraries/LibTest/Macros.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace AK { +template +void warnln(CheckedFormatString&& 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(expect_close_lhs) - static_cast(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) diff --git a/Userland/Libraries/LibTest/TestCase.h b/Userland/Libraries/LibTest/TestCase.h new file mode 100644 index 0000000000..d0fb713567 --- /dev/null +++ b/Userland/Libraries/LibTest/TestCase.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include // intentionally first -- we redefine VERIFY and friends in here + +#include +#include +#include +#include + +namespace Test { + +using TestFunction = Function; + +class TestCase : public RefCounted { +public: + TestCase(const String& name, TestFunction&& fn, bool is_benchmark) + : m_name(name) + , m_function(move(fn)) + , m_is_benchmark(is_benchmark) + { + } + + bool is_benchmark() const { return m_is_benchmark; } + const String& name() const { return m_name; } + const TestFunction& func() const { return m_function; } + +private: + String m_name; + TestFunction m_function; + bool m_is_benchmark; +}; + +// Helper to hide implementation of TestSuite from users +void add_test_case_to_suite(const NonnullRefPtr& test_case); + +} + +#define __TESTCASE_FUNC(x) __test_##x +#define __TESTCASE_TYPE(x) __TestCase_##x + +#define TEST_CASE(x) \ + static void __TESTCASE_FUNC(x)(); \ + struct __TESTCASE_TYPE(x) { \ + __TESTCASE_TYPE(x) \ + () { add_test_case_to_suite(adopt_ref(*new ::Test::TestCase(#x, __TESTCASE_FUNC(x), false))); } \ + }; \ + static struct __TESTCASE_TYPE(x) __TESTCASE_TYPE(x); \ + static void __TESTCASE_FUNC(x)() + +#define __BENCHMARK_FUNC(x) __benchmark_##x +#define __BENCHMARK_TYPE(x) __BenchmarkCase_##x + +#define BENCHMARK_CASE(x) \ + static void __BENCHMARK_FUNC(x)(); \ + struct __BENCHMARK_TYPE(x) { \ + __BENCHMARK_TYPE(x) \ + () { add_test_case_to_suite(adopt_ref(*new ::Test::TestCase(#x, __BENCHMARK_FUNC(x), true))); } \ + }; \ + static struct __BENCHMARK_TYPE(x) __BENCHMARK_TYPE(x); \ + static void __BENCHMARK_FUNC(x)() diff --git a/Userland/Libraries/LibTest/TestMain.cpp b/Userland/Libraries/LibTest/TestMain.cpp new file mode 100644 index 0000000000..6a232e1618 --- /dev/null +++ b/Userland/Libraries/LibTest/TestMain.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include + +#ifdef KERNEL +# define TEST_MAIN test_main +#else +# define TEST_MAIN main +#endif + +int TEST_MAIN(int argc, char** argv) +{ + if (argc < 1 || !argv[0] || '\0' == *argv[0]) { + warnln("Test main does not have a valid test name!"); + return 1; + } + int ret = ::Test::TestSuite::the().main(argv[0], argc, argv); + ::Test::TestSuite::release(); + return ret; +} diff --git a/Userland/Libraries/LibTest/TestSuite.cpp b/Userland/Libraries/LibTest/TestSuite.cpp new file mode 100644 index 0000000000..ac2b93b7de --- /dev/null +++ b/Userland/Libraries/LibTest/TestSuite.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include // intentionally first -- we redefine VERIFY and friends in here + +#include +#include +#include +#include + +namespace Test { + +TestSuite* TestSuite::s_global = nullptr; + +class TestElapsedTimer { +public: + TestElapsedTimer() { restart(); } + + void restart() { gettimeofday(&m_started, nullptr); } + + u64 elapsed_milliseconds() + { + struct timeval now = {}; + gettimeofday(&now, nullptr); + + struct timeval delta = {}; + timersub(&now, &m_started, &delta); + + return delta.tv_sec * 1000 + delta.tv_usec / 1000; + } + +private: + struct timeval m_started = {}; +}; + +// Declared in Macros.h +void current_test_case_did_fail() +{ + TestSuite::the().current_test_case_did_fail(); +} + +// Declared in TestCase.h +void add_test_case_to_suite(const NonnullRefPtr& test_case) +{ + TestSuite::the().add_case(test_case); +} + +int TestSuite::main(const String& suite_name, int argc, char** argv) +{ + m_suite_name = suite_name; + + Core::ArgsParser args_parser; + + bool do_tests_only = getenv("TESTS_ONLY") != nullptr; + bool do_benchmarks_only = false; + bool do_list_cases = false; + const char* search_string = "*"; + + args_parser.add_option(do_tests_only, "Only run tests.", "tests", 0); + args_parser.add_option(do_benchmarks_only, "Only run benchmarks.", "bench", 0); + args_parser.add_option(do_list_cases, "List available test cases.", "list", 0); + args_parser.add_positional_argument(search_string, "Only run matching cases.", "pattern", Core::ArgsParser::Required::No); + args_parser.parse(argc, argv); + + const auto& matching_tests = find_cases(search_string, !do_benchmarks_only, !do_tests_only); + + if (do_list_cases) { + outln("Available cases for {}:", suite_name); + for (const auto& test : matching_tests) { + outln(" {}", test.name()); + } + return 0; + } + + outln("Running {} cases out of {}.", matching_tests.size(), m_cases.size()); + + return run(matching_tests); +} + +NonnullRefPtrVector TestSuite::find_cases(const String& search, bool find_tests, bool find_benchmarks) +{ + NonnullRefPtrVector matches; + for (const auto& t : m_cases) { + if (!search.is_empty() && !t.name().matches(search, CaseSensitivity::CaseInsensitive)) { + continue; + } + + if (!find_tests && !t.is_benchmark()) { + continue; + } + if (!find_benchmarks && t.is_benchmark()) { + continue; + } + + matches.append(t); + } + return matches; +} + +int TestSuite::run(const NonnullRefPtrVector& tests) +{ + size_t test_count = 0; + size_t test_failed_count = 0; + size_t benchmark_count = 0; + TestElapsedTimer global_timer; + + for (const auto& t : tests) { + const auto test_type = t.is_benchmark() ? "benchmark" : "test"; + + warnln("Running {} '{}'.", test_type, t.name()); + m_current_test_case_passed = true; + + TestElapsedTimer timer; + t.func()(); + const auto time = timer.elapsed_milliseconds(); + + dbgln("{} {} '{}' in {}ms", m_current_test_case_passed ? "Completed" : "Failed", test_type, t.name(), time); + + if (t.is_benchmark()) { + m_benchtime += time; + benchmark_count++; + } else { + m_testtime += time; + test_count++; + } + + if (!m_current_test_case_passed) { + test_failed_count++; + } + } + + dbgln("Finished {} tests and {} benchmarks in {}ms ({}ms tests, {}ms benchmarks, {}ms other).", + test_count, + benchmark_count, + global_timer.elapsed_milliseconds(), + m_testtime, + m_benchtime, + global_timer.elapsed_milliseconds() - (m_testtime + m_benchtime)); + dbgln("Out of {} tests, {} passed and {} failed.", test_count, test_count - test_failed_count, test_failed_count); + + return (int)test_failed_count; +} + +} diff --git a/Userland/Libraries/LibTest/TestSuite.h b/Userland/Libraries/LibTest/TestSuite.h new file mode 100644 index 0000000000..694b6d1a69 --- /dev/null +++ b/Userland/Libraries/LibTest/TestSuite.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include // intentionally first -- we redefine VERIFY and friends in here + +#include +#include +#include +#include +#include + +namespace Test { + +class TestSuite { +public: + static TestSuite& the() + { + if (s_global == nullptr) + s_global = new TestSuite(); + return *s_global; + } + + static void release() + { + if (s_global) + delete s_global; + s_global = nullptr; + } + + int run(const NonnullRefPtrVector&); + int main(const String& suite_name, int argc, char** argv); + NonnullRefPtrVector find_cases(const String& search, bool find_tests, bool find_benchmarks); + void add_case(const NonnullRefPtr& test_case) + { + m_cases.append(test_case); + } + + void current_test_case_did_fail() { m_current_test_case_passed = false; } + +private: + static TestSuite* s_global; + NonnullRefPtrVector m_cases; + u64 m_testtime = 0; + u64 m_benchtime = 0; + String m_suite_name; + bool m_current_test_case_passed = true; +}; + +} diff --git a/Userland/Tests/Kernel/CMakeLists.txt b/Userland/Tests/Kernel/CMakeLists.txt index cd9438dc4a..408d82163c 100644 --- a/Userland/Tests/Kernel/CMakeLists.txt +++ b/Userland/Tests/Kernel/CMakeLists.txt @@ -1,5 +1,6 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") +# FIXME: These tests do not use LibTest foreach(CMD_SRC ${CMD_SOURCES}) get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) add_executable(${CMD_NAME} ${CMD_SRC}) diff --git a/Userland/Tests/LibC/CMakeLists.txt b/Userland/Tests/LibC/CMakeLists.txt index 799dfa9ff4..a42c42b47e 100644 --- a/Userland/Tests/LibC/CMakeLists.txt +++ b/Userland/Tests/LibC/CMakeLists.txt @@ -1,5 +1,8 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") +list(REMOVE_ITEM CMD_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/snprintf-correctness.cpp) +list(REMOVE_ITEM CMD_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/strlcpy-correctness.cpp) +# FIXME: These tests do not use LibTest foreach(CMD_SRC ${CMD_SOURCES}) get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) add_executable(${CMD_NAME} ${CMD_SRC}) @@ -7,4 +10,5 @@ foreach(CMD_SRC ${CMD_SOURCES}) install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/LibC) endforeach() -#target_link_libraries(foobar LibPthread) +serenity_test(snprintf-correctness.cpp LibC) +serenity_test(strlcpy-correctness.cpp LibC) diff --git a/Userland/Tests/LibC/snprintf-correctness.cpp b/Userland/Tests/LibC/snprintf-correctness.cpp index 5b8200db4f..0df2a5cc30 100644 --- a/Userland/Tests/LibC/snprintf-correctness.cpp +++ b/Userland/Tests/LibC/snprintf-correctness.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -141,5 +141,3 @@ TEST_CASE(special_cases) EXPECT(test_single({ LITERAL("x"), "whf", POISON, 3, LITERAL("\0") })); EXPECT(test_single({ LITERAL("xx"), "whf", POISON, 3, LITERAL("w\0") })); } - -TEST_MAIN(Sprintf) diff --git a/Userland/Tests/LibC/strlcpy-correctness.cpp b/Userland/Tests/LibC/strlcpy-correctness.cpp index c7e4cb0401..e23765cd29 100644 --- a/Userland/Tests/LibC/strlcpy-correctness.cpp +++ b/Userland/Tests/LibC/strlcpy-correctness.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -162,5 +162,3 @@ TEST_CASE(to_nullptr) EXPECT(test_single({ LITERAL("Hello World!\0\0\0"), LITERAL("Hello Friend!"), LITERAL("Hello Friend!\0\0") })); EXPECT(test_single({ LITERAL("aaaaaaaaaa"), LITERAL("whf"), LITERAL("whf\0aaaaaa") })); } - -TEST_MAIN(Sprintf) diff --git a/Userland/Tests/LibGfx/CMakeLists.txt b/Userland/Tests/LibGfx/CMakeLists.txt index 1c2bc2f17e..f0f5cecab9 100644 --- a/Userland/Tests/LibGfx/CMakeLists.txt +++ b/Userland/Tests/LibGfx/CMakeLists.txt @@ -1,12 +1,12 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") +list(REMOVE_ITEM CMD_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/painter.cpp) +# FIXME These tests do not use LibTest foreach(CMD_SRC ${CMD_SOURCES}) get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) add_executable(${CMD_NAME} ${CMD_SRC}) - target_link_libraries(${CMD_NAME} LibCore) + target_link_libraries(${CMD_NAME} LibCore LibGUI) install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/LibGfx) endforeach() -target_link_libraries(font LibGUI LibCore) -target_link_libraries(image-decoder LibGUI LibCore) -target_link_libraries(painter LibGUI LibCore) +serenity_test(painter.cpp LibGfx LIBS LibGUI) diff --git a/Userland/Tests/LibGfx/painter.cpp b/Userland/Tests/LibGfx/painter.cpp index 50210f51a7..ca4fef41cf 100644 --- a/Userland/Tests/LibGfx/painter.cpp +++ b/Userland/Tests/LibGfx/painter.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -51,5 +51,3 @@ BENCHMARK_CASE(fill_with_gradient) painter.fill_rect_with_gradient(bitmap->rect(), Color::Blue, Color::Red); } } - -TEST_MAIN(Painter) diff --git a/Userland/Tests/LibM/CMakeLists.txt b/Userland/Tests/LibM/CMakeLists.txt index de7c217201..bf1c0cc927 100644 --- a/Userland/Tests/LibM/CMakeLists.txt +++ b/Userland/Tests/LibM/CMakeLists.txt @@ -1,8 +1,5 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") foreach(CMD_SRC ${CMD_SOURCES}) - get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) - add_executable(${CMD_NAME} ${CMD_SRC}) - target_link_libraries(${CMD_NAME} LibCore) - install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/LibM) + serenity_test(${CMD_SRC} LibM) endforeach() diff --git a/Userland/Tests/LibM/test-math.cpp b/Userland/Tests/LibM/test-math.cpp index cdc5f35173..e48a5955e2 100644 --- a/Userland/Tests/LibM/test-math.cpp +++ b/Userland/Tests/LibM/test-math.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include @@ -250,5 +250,3 @@ TEST_CASE(fmax_and_fmin) EXPECT(fmin(0, NAN) == 0); EXPECT(isnan(fmin(NAN, NAN))); } - -TEST_MAIN(Math) diff --git a/Userland/Tests/UserspaceEmulator/CMakeLists.txt b/Userland/Tests/UserspaceEmulator/CMakeLists.txt index f39e141ee6..3fbbbc4120 100644 --- a/Userland/Tests/UserspaceEmulator/CMakeLists.txt +++ b/Userland/Tests/UserspaceEmulator/CMakeLists.txt @@ -1,5 +1,6 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") +# FIXME: These tests do not use LibTest foreach(CMD_SRC ${CMD_SOURCES}) get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) add_executable(${CMD_NAME} ${CMD_SRC})