HART  0.2.0
High level Audio Regression and Testing
Loading...
Searching...
No Matches
hart.hpp
Go to the documentation of this file.
1#pragma once
2
3#if defined (HART_IMPLEMENTATION)
4#define DR_WAV_IMPLEMENTATION // Wav single header library's implementation
5#endif
6
7#include <stdexcept>
8
10#include "dsp/hart_dsp_all.hpp"
12#include "envelopes/hart_envelopes_all.hpp"
15#include "matchers/hart_matchers_all.hpp"
17#include "signals/hart_signals_all.hpp"
18#include "hart_str.hpp"
20#include "hart_units.hpp"
22
23namespace hart
24{
25
26/// @brief Fails a test case unconditionally with a text message
27/// @param message Message to be displayed
28/// @ingroup TestRunner
29#define HART_FAIL_TEST_MSG(message) throw hart::TestAssertException (std::string ("HART_FAIL_TEST_MSG() triggered test fail at line ") + std::to_string (__LINE__) + " with message: \"" + message + '\"')
30
31/// @brief Fails a test case unconditionally
32/// @ingroup TestRunner
33#define HART_FAIL_TEST() throw hart::TestAssertException (std::string ("HART_FAIL_TEST() triggered test fail at line ") + std::to_string (__LINE__))
34
35/// @brief Use to check some condition inside a test case. Failing will abort the test runner.
36/// @details Helpful for free-standing checks (before or after rendering audio)
37/// @param condition A condition or boolean value to be checked. Will be triggered if it evaluates to `false`.
38/// @ingroup TestRunner
39#define HART_ASSERT_TRUE(condition)
40 if (!(condition)) throw hart::TestAssertException (std::string ("HART_ASSERT_TRUE() failed at line ") + std::to_string (__LINE__) + ": \"" #condition "\"");
41
42/// @brief Use to check some condition inside a test case. Failing will not abort the test runner.
43/// @details Helpful for free-standing checks (before or after rendering audio)
44/// @param condition A condition or boolean value to be checked. Will be triggered if it evaluates to `false`.
45/// @ingroup TestRunner
46#define HART_EXPECT_TRUE(condition)
47 if (!(condition)) hart::ExpectationFailureMessages::get().emplace_back (std::string ("HART_EXPECT_TRUE() failed at line ") + std::to_string (__LINE__) + ": \"" #condition "\"");
48
49#define HART_CONCAT_IMPL(x, y) x##y
50#define HART_CONCAT(x, y) HART_CONCAT_IMPL(x, y)
51#define HART_UNIQUE_ID(x) HART_CONCAT(x, __LINE__)
52
53#define HART_ITEM_WITH_TAGS(name, tags, category)
54 static void HART_UNIQUE_ID(HART_RunTask)();
55 namespace {
56 struct HART_UNIQUE_ID(HART_RegistrarType) {
57 HART_UNIQUE_ID(HART_RegistrarType)() {
58 hart::TestRegistry::getInstance().add (name, tags, __FILE__, __LINE__, category, &HART_UNIQUE_ID (HART_RunTask));
59 }
60 };
61 }
62 static HART_UNIQUE_ID(HART_RegistrarType) HART_UNIQUE_ID(HART_registrar);
63 static void HART_UNIQUE_ID(HART_RunTask)()
64
65/// @brief Declares a test case with tags
66/// @warning Tags aren't supported yet
67/// @param name Name for the test case
68/// @param tags Tags like "[my-tag-1][my-tag-2]"
69/// @ingroup TestRunner
70#define HART_TEST_WITH_TAGS(name, tags) HART_ITEM_WITH_TAGS(name, tags, hart::TaskCategory::test)
71
72/// @brief Declares a generator with tags
73/// @details Pretty much the same as a usual test case, but will be called only if the `--run-generators` CLI flag is set
74/// @warning Tags aren't supported yet
75/// @param name Name for the generator
76/// @param tags Tags like "[my-tag-1][my-tag-2]"
77/// @ingroup TestRunner
78#define HART_GENERATE_WITH_TAGS(name, tags) HART_ITEM_WITH_TAGS(name, tags, hart::TaskCategory::generate)
79
80/// @brief Declares a test case
81/// @param name Name for the test case
82/// @ingroup TestRunner
83#define HART_TEST(name) HART_TEST_WITH_TAGS(name, "")
84
85/// @brief Declares a generator
86/// @details Pretty much the same as a usual test case, but will be called only if the `--run-generators` CLI flag is set
87/// @param name Name for generator
88/// @ingroup TestRunner
89#define HART_GENERATE(name) HART_GENERATE_WITH_TAGS(name, "")
90
91#if HART_DO_NOT_THROW_EXCEPTIONS
92/// @brief Put it at the beginning of your tese case if it requires a properly set data path
93/// @details For example, when using relative paths to the wav files. The test will instantly fail is the path is not set.
94/// @ingroup TestRunner
95#define HART_REQUIRES_DATA_PATH_ARG if (hart::CLIConfig::getInstance().getDataRootPath().empty()) { hart::ExpectationFailureMessages::get().emplace_back ("This test requires a data path set by the --data-root-path CLI argument, but it's empty"); return; }
96#else
97/// @brief Put it at the beginning of your tese case if it requires a properly set data path
98/// @details For example, when using relative paths to the wav files. The test will instantly fail is the path is not set.
99/// @ingroup TestRunner
100#define HART_REQUIRES_DATA_PATH_ARG if (hart::CLIConfig::getInstance().getDataRootPath().empty()) { throw hart::ConfigurationError ("This test requires a data path set by the --data-root-path CLI argument, but it's empty"); }
101#endif // HART_DO_NOT_THROW_EXCEPTIONS
102
103/// @brief Runs all tests or generators
104/// @details Place this macro in your `main()` function
105/// @ingroup TestRunner
106#define HART_RUN_ALL_TESTS(argc, argv)
107 do
108 {
109 hart::CLIConfig::getInstance().initCommandLineArgs();
110 CLI11_PARSE (hart::CLIConfig::getInstance().getCLIApp(), argc, argv);
111 return hart::TestRegistry::getInstance().runAll();
112 }
113 while (false);
114
115/// @brief Put it before you test cases to use hart classes without hart:: namespace prefix and explicit `float` template value
116#define HART_DECLARE_ALIASES_FOR_FLOAT using namespace hart::aliases_float
117
118/// @brief Put it before you test cases to use hart classes without hart:: namespace prefix and explicit `double` template value
119#define HART_DECLARE_ALIASES_FOR_DOUBLE using namespace hart::aliases_double
120
121} // namespace hart
#define HART_GENERATE_WITH_TAGS(name, tags)
Declares a generator with tags.
Definition hart.hpp:78
#define HART_TEST_WITH_TAGS(name, tags)
Declares a test case with tags.
Definition hart.hpp:70
#define HART_CONCAT(x, y)
Definition hart.hpp:50
#define HART_UNIQUE_ID(x)
Definition hart.hpp:51
#define HART_CONCAT_IMPL(x, y)
Definition hart.hpp:49
#define HART_ITEM_WITH_TAGS(name, tags, category)
Definition hart.hpp:53