Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2021, Andrew Kaster <akaster@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#pragma once
9
10#include <LibTest/Macros.h> // intentionally first -- we redefine VERIFY and friends in here
11
12#include <AK/DeprecatedString.h>
13#include <AK/Function.h>
14#include <AK/NonnullRefPtr.h>
15#include <AK/RefCounted.h>
16
17namespace Test {
18
19using TestFunction = Function<void()>;
20
21class TestCase : public RefCounted<TestCase> {
22public:
23 TestCase(DeprecatedString const& name, TestFunction&& fn, bool is_benchmark)
24 : m_name(name)
25 , m_function(move(fn))
26 , m_is_benchmark(is_benchmark)
27 {
28 }
29
30 bool is_benchmark() const { return m_is_benchmark; }
31 DeprecatedString const& name() const { return m_name; }
32 TestFunction const& func() const { return m_function; }
33
34private:
35 DeprecatedString m_name;
36 TestFunction m_function;
37 bool m_is_benchmark;
38};
39
40// Helper to hide implementation of TestSuite from users
41void add_test_case_to_suite(NonnullRefPtr<TestCase> const& test_case);
42void set_suite_setup_function(Function<void()> setup);
43}
44
45#define TEST_SETUP \
46 static void __setup(); \
47 struct __setup_type { \
48 __setup_type() \
49 { \
50 Test::set_suite_setup_function(__setup); \
51 } \
52 }; \
53 static struct __setup_type __setup_type; \
54 static void __setup()
55
56#define __TESTCASE_FUNC(x) __test_##x
57#define __TESTCASE_TYPE(x) __TestCase_##x
58
59#define TEST_CASE(x) \
60 static void __TESTCASE_FUNC(x)(); \
61 struct __TESTCASE_TYPE(x) { \
62 __TESTCASE_TYPE(x) \
63 () \
64 { \
65 add_test_case_to_suite(adopt_ref(*new ::Test::TestCase(#x, __TESTCASE_FUNC(x), false))); \
66 } \
67 }; \
68 static struct __TESTCASE_TYPE(x) __TESTCASE_TYPE(x); \
69 static void __TESTCASE_FUNC(x)()
70
71#define __BENCHMARK_FUNC(x) __benchmark_##x
72#define __BENCHMARK_TYPE(x) __BenchmarkCase_##x
73
74#define BENCHMARK_CASE(x) \
75 static void __BENCHMARK_FUNC(x)(); \
76 struct __BENCHMARK_TYPE(x) { \
77 __BENCHMARK_TYPE(x) \
78 () \
79 { \
80 add_test_case_to_suite(adopt_ref(*new ::Test::TestCase(#x, __BENCHMARK_FUNC(x), true))); \
81 } \
82 }; \
83 static struct __BENCHMARK_TYPE(x) __BENCHMARK_TYPE(x); \
84 static void __BENCHMARK_FUNC(x)()