Sequoia
Loading...
Searching...
No Matches
FreeTestCore.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2020. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
20
24
25#include <memory>
26#include <chrono>
27
28namespace sequoia::testing
29{
30 class [[nodiscard]] timer
31 {
32 public:
33 timer();
34
35 [[nodiscard]]
36 std::chrono::nanoseconds time_elapsed() const;
37 private:
38 using time_point = std::chrono::steady_clock::time_point;
39
40 time_point m_Start;
41 };
42
49 {
50 public:
51 explicit test_base(std::string name) : m_Name{std::move(name)} {}
52
53 test_base(std::string name, test_mode mode, std::string_view suiteName, const normal_path& srcFile, project_paths projPaths, individual_materials_paths materials, const std::optional<std::string>& outputDiscriminator, const std::optional<std::string>& summaryDiscriminator)
54 : m_Name{std::move(name)}
55 , m_ProjectPaths{std::move(projPaths)}
56 , m_Materials{std::move(materials)}
57 , m_Diagnostics{get_project_paths().project_root(), suiteName, srcFile, mode, outputDiscriminator}
58 , m_SummaryFile{srcFile, m_ProjectPaths, summaryDiscriminator}
59 {
60 std::filesystem::create_directories(m_Diagnostics.false_positive_or_negative_file_path().parent_path());
61 }
62
63 test_base(const test_base&) = delete;
64 test_base& operator=(const test_base&) = delete;
65
66 [[nodiscard]]
67 const std::string& name() const noexcept
68 {
69 return m_Name;
70 }
71
72 [[nodiscard]]
73 std::filesystem::path working_materials() const
74 {
75 return m_Materials.working();
76 }
77
78 [[nodiscard]]
79 std::filesystem::path predictive_materials() const
80 {
81 return m_Materials.prediction();
82 }
83
84 [[nodiscard]]
85 std::filesystem::path auxiliary_materials() const
86 {
87 return m_Materials.auxiliary();
88 }
89
90 [[nodiscard]]
91 const project_paths& get_project_paths() const noexcept
92 {
93 return m_ProjectPaths;
94 }
95
96 [[nodiscard]]
97 const individual_diagnostics_paths& diagnostics_file_paths() const noexcept
98 {
99 return m_Diagnostics;
100 }
101
102 [[nodiscard]]
103 const test_summary_path& summary_file_path() const noexcept
104 {
105 return m_SummaryFile;
106 }
107
108 [[nodiscard]]
109 std::string report(const reporter& rep) const
110 {
111 return rep.location() ? testing::report_line(rep.message(), m_ProjectPaths.tests().repo(), rep.location().value()) : rep.message();
112 }
113 protected:
114 ~test_base() = default;
115
116 test_base(test_base&&) noexcept = default;
117 test_base& operator=(test_base&&) noexcept = default;
118
119 void write_instability_analysis_output(const normal_path& srcFile, std::optional<std::size_t> index, const failure_output& output) const;
120 private:
121 std::string m_Name{};
122 project_paths m_ProjectPaths{};
123 individual_materials_paths m_Materials{};
124 individual_diagnostics_paths m_Diagnostics{};
125 test_summary_path m_SummaryFile{};
126 };
127
142 template<test_mode Mode, class Extender>
143 class basic_test : public test_base, public checker<Mode, Extender>
144 {
145 public:
147 constexpr static test_mode mode{Mode};
148
149 explicit basic_test(std::string name) : test_base{std::move(name)} {}
150
151 basic_test(std::string name, std::string_view suiteName, const normal_path& srcFile, const project_paths& projPaths, individual_materials_paths materials, active_recovery_files files, const std::optional<std::string>& outputDiscriminator, const std::optional<std::string>& summaryDiscriminator)
152 : test_base{std::move(name), Mode, suiteName, srcFile, projPaths, std::move(materials), outputDiscriminator, summaryDiscriminator}
153 , checker<Mode, Extender>{std::move(files)}
154 {}
155
156 basic_test(const basic_test&) = delete;
157 basic_test& operator=(const basic_test&) = delete;
158
159 using checker_type::reset_results;
160 protected:
161 using duration = std::chrono::steady_clock::duration;
162
163 ~basic_test() = default;
164
165 basic_test(basic_test&&) noexcept = default;
166 basic_test& operator=(basic_test&&) noexcept = default;
167
168 [[nodiscard]]
169 log_summary summarize(duration delta) const
170 {
171 return checker_type::summary(name(), delta);
172 }
173 private:
174 friend class test_vessel;
175
176 void log_critical_failure(const normal_path& srcFile, std::string_view tag, std::string_view what)
177 {
178 auto sentry{checker_type::make_sentinel("")};
179 sentry.log_critical_failure(exception_message(tag, srcFile, checker_type::exceptions_detected_by_sentinel(), what));
180 }
181
182 void write_instability_analysis_output(const normal_path& srcFile, std::optional<std::size_t> index) const
183 {
184 test_base::write_instability_analysis_output(srcFile, index, checker_type::failure_messages());
185 }
186 };
187
188 template<class T>
190 requires (T& test){
191 { test.run_tests() };
192 { test.source_file() } -> std::convertible_to<std::filesystem::path>;
193 { test.reset_results() };
194 }
195 && std::derived_from<T, test_base> && std::movable<T> && std::destructible<T>;
196
197 template<concrete_test T>
198 inline constexpr bool has_discriminated_output_v{
199 requires(const T& t){
200 { t.output_discriminator() } -> std::convertible_to<std::string>;
201 }
202 };
203
204 template<concrete_test T>
205 inline constexpr bool has_discriminated_summary_v{
206 requires(const T & t){
207 { t.summary_discriminator() } -> std::convertible_to<std::string>;
208 }
209 };
210
213 {
214 public:
215 trivial_extender() = default;
216 protected:
217 ~trivial_extender() = default;
218
219 trivial_extender(trivial_extender&&) noexcept = default;
220 trivial_extender& operator=(trivial_extender&&) noexcept = default;
221 };
222
223 template<test_mode Mode>
225
230
231 template<class T>
232 inline constexpr bool has_parallelizable_type{
233 requires {
234 typename T::parallelizable_type;
235 requires std::is_convertible_v<typename T::parallelizable_type, std::true_type> || std::is_convertible_v<typename T::parallelizable_type, std::false_type>;
236 }
237 };
238
240 template<class T>
242
243 template<class T>
244 using is_parallelizable_t = typename is_parallelizable<T>::type;
245
246 template<class T>
247 inline constexpr bool is_parallelizable_v{is_parallelizable<T>::value};
248
249 template<concrete_test T>
250 struct is_parallelizable<T> : std::true_type {};
251
252 template<concrete_test T>
253 requires has_parallelizable_type<T>
254 struct is_parallelizable<T> : T::parallelizable_type {};
255
256}
Concepts which are sufficiently general to appear in the sequoia namespace.
Useful specializations for the class template value_tester.
Extensions to the std::filesystem library.
File paths pertaining to individual tests.
A collection of functions for making substitutions within text.
Definition: FileSystem.hpp:20
class template from which all concrete tests should derive.
Definition: FreeTestCore.hpp:144
Exposes elementary check methods, with the option to plug in arbitrary Extenders to compose functiona...
Definition: FreeCheckers.hpp:708
Definition: IndividualTestPaths.hpp:64
Definition: IndividualTestPaths.hpp:20
Summaries data generated by the logger, for the purposes of reporting.
Definition: TestLogger.hpp:299
Paths used by the project.
Definition: ProjectPaths.hpp:469
Definition: Output.hpp:186
class from which all tests ultimately derive
Definition: FreeTestCore.hpp:49
Definition: IndividualTestPaths.hpp:90
Definition: TestRunner.hpp:59
Definition: FreeTestCore.hpp:31
Temporary workaround while waiting for variadic friends.
Definition: FreeTestCore.hpp:213
Definition: FreeTestCore.hpp:189
Holds paths to files where recovery information will be written if the path is not empty.
Definition: TestLogger.hpp:36
Definition: FreeTestCore.hpp:241