1#ifndef TEST_GENERATORS_HPP
2#define TEST_GENERATORS_HPP
4#pragma GCC diagnostic push
5#pragma GCC diagnostic ignored "-Wconversion"
7#include <rapidcheck/gtest.h>
9#pragma GCC diagnostic pop
42 static_assert(N > 0,
"N must be greater than 0");
45 gen::container<std::array<bool, N>>(gen::arbitrary<bool>()),
46 [](
const auto &booleans)
48 return std::any_of(booleans.begin(), booleans.end(), [](
const bool b)
78 return gen::container<std::array<bool, N>>(gen::just(
true));
80 return atLeastOneFalse<N>();
96inline auto IPv4Octet(
const bool valid =
true) -> Gen<int>
98 static constexpr int min_ipv4_octet = 0;
99 static constexpr int max_ipv4_octet = 255;
103 return gen::inRange(min_ipv4_octet, max_ipv4_octet + 1);
105 return gen::suchThat(gen::arbitrary<int>(), [](
const auto &i)
106 {
return i < min_ipv4_octet || i > max_ipv4_octet; });
125inline auto IPv4Address(
const bool valid =
true) -> Gen<std::string>
127 static constexpr int octets_number = 4;
128 static constexpr std::array<bool, octets_number> all_true = {
true,
true,
true,
true};
129 const auto octet_validity = valid ? all_true : *atLeastOneFalse<octets_number>().as(
"first,second,third,fourth octet valid");
136 [](
const auto &octets)
138 return std::to_string(std::get<0>(octets)) +
"." + std::to_string(std::get<1>(octets)) +
"."
139 + std::to_string(std::get<2>(octets)) +
"." + std::to_string(std::get<3>(octets));
157 static constexpr int ASCII_range_start_code = 32;
158 static constexpr int ASCII_range_end_code = 127;
159 static constexpr int ASCII_percent_sign_code = 37;
163 return gen::distinctFrom(gen::inRange(ASCII_range_start_code, ASCII_range_end_code), ASCII_percent_sign_code);
181inline auto hexChar(
const bool valid =
true) -> Gen<std::string>
185 const auto alphapositives = gen::elementOf(std::string(
"abcdefABCDEF123456789"));
187 static constexpr int probability_weight_of_0 = 23;
188 static constexpr int probability_weight_of_alphapositives = 1;
191 return gen::map(gen::weightedOneOf<char>({{probability_weight_of_0, gen::just<char>(
'0')},
192 {probability_weight_of_alphapositives, alphapositives}}),
195 return std::string{
static_cast<char>(c)};
201 {
return isxdigit(c) == 0; }),
204 return std::string{
static_cast<char>(c)};
224 static constexpr int hexchars_number = 4;
225 static constexpr std::array<bool, hexchars_number> all_true = {
true,
true,
true,
true};
226 const auto hexchar_validity = valid ? all_true : *atLeastOneFalse<hexchars_number>().as(
"first,second,third,fourth hexchar in hextet valid");
229 gen::tuple(
hexChar(hexchar_validity[0]),
233 [](
const auto &hexchars)
235 const auto &[first_hexchar, second_hexchar, third_hexchar, fourth_hexchar] = hexchars;
236 return first_hexchar + second_hexchar + third_hexchar + fourth_hexchar;
249 const auto first_nonzero = hextet.find_first_not_of(
'0');
250 return first_nonzero == std::string::npos ?
"0" : hextet.substr(first_nonzero);
276 for (
auto longest_zero_sequence = hextets.size(); longest_zero_sequence > 1; --longest_zero_sequence)
278 auto position = std::search_n(hextets.begin(), hextets.end(), longest_zero_sequence, std::string{
"0"});
279 if (position != hextets.end())
281 const auto it = hextets.insert(position,
"::");
282 hextets.erase(it + 1, std::next(it + 1, longest_zero_sequence));
301 for (
size_t i = 0; i < hextets.size(); ++i)
303 if (i > 0 && hextets[i] !=
"::" && hextets[i - 1] !=
"::")
307 result += hextets[i];
345inline auto IPv6Address(
const bool valid =
true) -> Gen<std::string>
347 static constexpr int number_of_hextets = 8;
348 static constexpr std::array<bool, number_of_hextets> all_true = {
true,
true,
true,
true,
true,
true,
true,
true};
349 const auto hextet_validity = valid ? all_true : *atLeastOneFalse<number_of_hextets>().as(
"first,second,third,fourth,fifth,sixth,seventh,eighth hextet valid");
351 auto convert_hextets_to_compressed_address = [](std::string first_hextet,
352 std::string second_hextet,
353 std::string third_hextet,
354 std::string fourth_hextet,
355 std::string fifth_hextet,
356 std::string sixth_hextet,
357 std::string seventh_hextet,
358 std::string eighth_hextet)
361 std::move(second_hextet),
362 std::move(third_hextet),
363 std::move(fourth_hextet),
364 std::move(fifth_hextet),
365 std::move(sixth_hextet),
366 std::move(seventh_hextet),
367 std::move(eighth_hextet)});
372 return gen::apply(convert_hextets_to_compressed_address,
382 return gen::map(gen::tuple(
391 [](
const auto &hextets)
393 const auto [first_hextet, second_hextet, third_hextet, fourth_hextet, fifth_hextet, sixth_hextet, seventh_hextet, eighth_hextet] = hextets;
394 return first_hextet +
":" + second_hextet +
":" + third_hextet +
":" + fourth_hextet +
":" + fifth_hextet +
":" + sixth_hextet +
":" + seventh_hextet +
":" + eighth_hextet;
417 static constexpr int number_of_flags = 9;
419 gen::container<std::vector<int>>(gen::inRange(0, number_of_flags + 1)),
420 [](
const auto &bit_positions)
423 for (
const auto &pos : bit_positions)
447 static auto arbitrary() -> Gen<openvpn::TunBuilderCapture::RouteBase>
470 static auto arbitrary() -> Gen<openvpn::TunBuilderCapture::Route>
490 static auto arbitrary() -> Gen<openvpn::TunBuilderCapture::RouteAddress>
515template <
typename T,
typename... Ts>
516struct Arbitrary<std::variant<T, Ts...>>
529 gen::cast<std::variant<T, Ts...>>(gen::arbitrary<T>()),
530 gen::cast<std::variant<T, Ts...>>(gen::arbitrary<Ts>())...);
534static const std::string
ALPHA_CHARACTERS =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
535static const std::string
DIGITS =
"1234567890";
552inline auto alpha(
const bool valid =
true) -> Gen<char>
558 return gen::suchThat(gen::character<char>(),
559 [](
const char character)
560 {
return !std::isalpha(character); });
577inline auto from_allowed_chars(
const std::string_view &allowed_chars,
const bool valid =
true) -> Gen<char>
581 return gen::elementOf(allowed_chars);
583 return gen::suchThat(gen::character<char>(),
584 [allowed_chars](
const char character)
585 {
return allowed_chars.find(character) == std::string::npos; });
611 return gen::suchThat(gen::string<std::string>(), [allowed_chars](
const auto &
string)
612 {
return std::any_of(
string.begin(),
string.end(), [allowed_chars](
const auto &character)
613 {
return allowed_chars.find(character) == std::string::npos; }); });
626inline auto port(
const bool valid =
true) -> Gen<int>
628 static constexpr int port_upper_bound = 65535;
629 static constexpr int port_lower_bound = 0;
631 return gen::inRange(port_lower_bound, port_upper_bound + 1);
632 return gen::suchThat<int>(
633 [](
const auto port_number)
634 {
return port_number < port_lower_bound || port_number > port_upper_bound; });
656 std::array<unsigned int, 4> addressParts{};
657 std::istringstream addressStream(ipAddress);
659 size_t partIndex = 0;
661 while (std::getline(addressStream, part,
'.'))
663 addressParts[partIndex++] = std::stoi(part);
666 const uint32_t addressInteger = (addressParts[0] << 24) | (addressParts[1] << 16) | (addressParts[2] << 8) | addressParts[3];
668 auto minimumPrefix = 32;
669 for (
auto bitPosition = 0; bitPosition < 32; ++bitPosition)
671 if (addressInteger & (1U << bitPosition))
673 minimumPrefix = 32 - bitPosition;
Route address class that may use non-canonical form.
Base class for route-related functionality representing a network route.
Route class that must use canonical form.
auto calculateIPPrefixRange(const std::string &ipAddress) -> std::tuple< int, int >
Calculates the valid IP prefix range for a given IP address.
auto string_from_allowed_chars(const std::string_view &allowed_chars, const bool valid=true) -> Gen< std::string >
Generates strings based on allowed characters.
auto from_allowed_chars(const std::string_view &allowed_chars, const bool valid=true) -> Gen< char >
Generates characters based on an allowed character set.
std::string stringifyHextetsToAddressWithColons(const std::vector< std::string > &hextets)
Converts a vector of hextets to an IPv6 address string with colons.
auto IPv4Octet(const bool valid=true) -> Gen< int >
Generates a valid or invalid IPv4 octet value.
void replaceSequenceOfZerosWithDoubleColon(std::vector< std::string > &hextets)
Replaces the longest sequence of consecutive "0" strings in a vector with "::".
std::variant< openvpn::TunBuilderCapture::Route, openvpn::TunBuilderCapture::RouteAddress, openvpn::TunBuilderCapture::RouteBase > RouteBased
Alias representing a route-based variant type.
std::string compressIPv6Address(std::vector< std::string > hextets)
Compress an IPv6 address by simplifying its representation.
static const std::string ALPHA_CHARACTERS
std::string removeLeadingZerosFromHextet(const std::string &hextet)
Removes leading zeros from a hextet (IPv6 segment).
static const std::string DIGITS
void removeLeadingZerosFromHextets(std::vector< std::string > &hextets)
Removes leading zeros from a vector of hextets.
auto hexChar(const bool valid=true) -> Gen< std::string >
Generates a valid or invalid hexadecimal character.
auto atLeastOneFalse() -> Gen< std::array< bool, N > >
Generates an array of booleans that contains at least one false.
auto asciiPrintableCode() -> Gen< int >
Generates a random printable ASCII character code.
auto generateValidityFlags(const bool all_valid=true) -> Gen< std::array< bool, N > >
Generates an array of validity flags for component testing.
auto IPv6HextetValue(const bool valid=true) -> Gen< std::string >
Generates a hextet value of an IPv6 address.
auto IPv4Address(const bool valid=true) -> Gen< std::string >
Generates a random IPv4 address.
auto IPv6Address(const bool valid=true) -> Gen< std::string >
Generates a random IPv6 address.
auto alpha(const bool valid=true) -> Gen< char >
Generates alphabetic or non-alphabetic characters.
static Gen< RedirectGatewayFlagsValues > arbitrary()
Generates an arbitrary RedirectGatewayFlagsValues.
static auto arbitrary() -> Gen< openvpn::TunBuilderCapture::RouteAddress >
Generates an arbitrary RouteAddress instance.
static auto arbitrary() -> Gen< openvpn::TunBuilderCapture::RouteBase >
Generates a value of type RouteBase.
static auto arbitrary() -> Gen< openvpn::TunBuilderCapture::Route >
Generates an arbitrary instance of TunBuilderCapture::Route.
static auto arbitrary() -> Gen< std::variant< T, Ts... > >
Generates an arbitrary std::variant containing one of the specified types.