74#include <gmock/gmock.h>
75#include <gtest/gtest.h>
85template <
class T,
class G >
95template <
class T,
class G>
109 = std::same_as<T, short> || std::same_as<T, unsigned short> || std::same_as<T, int> || std::same_as<T, unsigned int> || std::same_as<T, long>
110 || std::same_as<T, unsigned long> || std::same_as<T, long long> || std::same_as<T, unsigned long long>;
118 using T = std::remove_reference_t<
decltype(t)>;
119 t = std::uniform_int_distribution<T>(std::numeric_limits<T>::min())(gen);
126static inline void random_init(std::uniform_random_bit_generator
auto& gen, std::floating_point
auto& t)
128 t = std::normal_distribution<std::remove_reference_t<
decltype(t)>>{}(gen);
135static inline void random_init(std::uniform_random_bit_generator
auto& gen, std::ranges::input_range
auto& t)
137 std::for_each(std::begin(t), std::end(t), [&](std::ranges::range_value_t<
decltype(t)>& v) { random_init(gen, v); });
144static inline void random_init(std::uniform_random_bit_generator
auto& gen,
initializable_from<
decltype(gen)>
auto& t)
153template <
typename T, std::uniform_random_bit_generator G>
155static inline void random_init(G& gen, T& t)
163template <
typename T, std::uniform_random_bit_generator G>
165static inline T make_random(G& gen)
173template <
typename T, std::uniform_random_bit_generator G>
175static inline T make_random(G& gen)
178 random_init(gen, result);
192 std::filesystem::path m_workdir;
195 std::filesystem::path m_tmpdir;
198 PC_tree_t m_conf = {PC_NODE_NOT_FOUND,
nullptr,
nullptr};
201 std::mt19937_64 m_random_generator;
204 static void s_pdi_errhandler(
PDI_status_t status,
const char* message,
void* context)
206 static_cast<PdiTest*
>(context)->PdiError(status, message);
216 template <
typename T>
219 return ::PDI::make_random<T>(m_random_generator);
226 inline void with_file(std::filesystem::path file) { std::filesystem::create_symlink((m_workdir / file), (m_tmpdir / file.filename())); }
235 inline void InitPdi(PC_tree_t tree);
247 : m_workdir(
std::filesystem::canonical(
std::filesystem::current_path()))
249 static thread_local auto random_generator([]() {
250 if (
int gseed = ::testing::UnitTest::GetInstance()->random_seed()) {
251 return std::mt19937_64(gseed);
253 std::random_device source;
254 std::array<unsigned, std::mt19937_64::state_size> random_seed_data;
255 std::generate(std::begin(random_seed_data), std::end(random_seed_data), std::ref(source));
256 std::seed_seq seed(std::begin(random_seed_data), std::end(random_seed_data));
257 return std::mt19937_64(seed);
260 auto const filename = [&]() {
261 static constexpr char const VALID_FILE_CHARS[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
263 std::uniform_int_distribution<size_t> random(0, std::ranges::size(VALID_FILE_CHARS) - 2);
264 std::string filename(16,
'\0');
265 std::generate(filename.begin(), filename.end(), [&]() { return VALID_FILE_CHARS[random(random_generator)]; });
266 auto&& test_info = *::testing::UnitTest::GetInstance()->current_test_info();
267 return std::string(
"pdi_tst_dir.") + test_info.test_suite_name() +
"." + test_info.name() +
"." + filename;
269 m_tmpdir = m_workdir / filename;
270 std::filesystem::create_directory(m_tmpdir);
271 std::filesystem::current_path(m_tmpdir);
272 EXPECT_CALL(*
this, PdiError(testing::_, testing::_)).Times(0);
278 ASSERT_EQ(PC_OK, PC_status(tree));
287 if (!PC_status(m_conf)) {
289 EXPECT_EQ(PC_OK, PC_tree_destroy(&m_conf));
290 m_conf = {PC_NODE_NOT_FOUND,
nullptr,
nullptr};
297 std::filesystem::current_path(m_workdir);
298 std::filesystem::remove_all(m_tmpdir);
void with_file(std::filesystem::path file)
Requires a file from the original working-directory to be present on the effective working-directory.
Definition testing.h:226
void InitPdi(PC_tree_t tree)
Initialize PDI with the provided PC_tree.
Definition testing.h:275
PdiTest()
Definition testing.h:246
MOCK_METHOD(void, PdiError,(PDI_status_t, char const *),(const))
T make_a()
make a new repeatably randomly initialized object
Definition testing.h:217
void FinalizePdi()
Finalize PDI.
Definition testing.h:285
~PdiTest()
Definition testing.h:294
An object is buildable_from<G> if it can be constructed using the init_from member function from a re...
Definition testing.h:96
Bridge the gap between integral and IntType, by disabling bool and char.
Definition testing.h:109
An object is initializable_from<G> if it can be initalized using the init_from member function from a...
Definition testing.h:86
PDI_errhandler_t PDI_errhandler(PDI_errhandler_t handler)
Sets the error handler to use.
PDI_status_t
Error codes of PDI.
Definition pdi.h:80
@ PDI_OK
everything went well
Definition pdi.h:82
PDI_status_t PDI_init(PC_tree_t conf)
Initializes PDI.
PDI_status_t PDI_finalize(void)
Finalizes PDI.
Definition array_datatype.h:38