diff --git a/include/faker-cxx/String.h b/include/faker-cxx/String.h index b0c840bd5..1edc9a027 100644 --- a/include/faker-cxx/String.h +++ b/include/faker-cxx/String.h @@ -225,6 +225,19 @@ class String static std::string hexadecimal(unsigned length = 1, HexCasing casing = HexCasing::Lower, HexPrefix prefix = HexPrefix::ZeroX); + /** + * @brief Generates a binary string. + * + * @param length The number of digits to generate. Defaults to `1`. + * + * @returns Binary string. + * + * @code + * String::binary(8) // "0b01110101" + * @endcode + */ + static std::string binary(unsigned length = 1); + /** * @brief Generates a binary string. * @@ -234,10 +247,23 @@ class String * @returns Binary string. * * @code - * String::binary({}, 8) // "0b01110101" + * String::binary({'1',{7,8}}, 8) // "0b11110111" + * @endcode + */ + static std::string binary(GuaranteeMap&& guarantee, unsigned length = 1); + + /** + * @brief Generates an octal string. + * + * @param length The number of digits to generate. Defaults to `1`. + * + * @returns Octal string. + * + * @code + * String::octal(8) // "0o52561721" * @endcode */ - static std::string binary(GuaranteeMap&& guarantee = {}, unsigned length = 1); + static std::string octal(unsigned length = 1); /** * @brief Generates an octal string. @@ -248,9 +274,9 @@ class String * @returns Octal string. * * @code - * String::octal({}, 8) // "0o52561721" + * String::octal({'4',{4,5}}, 8) // "0o42444041" * @endcode */ - static std::string octal(GuaranteeMap&& guarantee = {}, unsigned length = 1); + static std::string octal(GuaranteeMap&& guarantee, unsigned length = 1); }; } diff --git a/src/modules/string/String.cpp b/src/modules/string/String.cpp index 1a2e2e6cd..42478a5dd 100644 --- a/src/modules/string/String.cpp +++ b/src/modules/string/String.cpp @@ -206,6 +206,16 @@ std::string String::hexadecimal(unsigned int length, HexCasing casing, HexPrefix return hexadecimal; } +std::string String::binary(unsigned int length) +{ + std::string binaryNumber; + for (unsigned int i = 0; i < length; ++i) + { + binaryNumber += static_cast(Number::integer(1)); + } + return "0b" + binaryNumber; +} + std::string String::binary(GuaranteeMap&& guarantee, unsigned int length) { // numbers used by binary representation @@ -219,6 +229,15 @@ std::string String::binary(GuaranteeMap&& guarantee, unsigned int length) return "0b" + generateStringWithGuarantee(guarantee, targetCharacters, length); } +std::string String::octal(unsigned int length) +{ + std::string octalNumber; + for (unsigned int i = 0; i < length; ++i) + { + octalNumber += static_cast(Number::integer(7)); + } + return "0o" + octalNumber; +} std::string String::octal(GuaranteeMap&& guarantee, unsigned int length) { // numbers used by octal representation diff --git a/src/modules/string/StringTest.cpp b/src/modules/string/StringTest.cpp index 797162ee0..79b20f1a3 100644 --- a/src/modules/string/StringTest.cpp +++ b/src/modules/string/StringTest.cpp @@ -355,7 +355,7 @@ TEST_F(StringTest, shouldGenerateBinary) { const auto binaryLength = 8; - const auto binary = String::binary({}, binaryLength); + const auto binary = String::binary(binaryLength); const auto prefix = binary.substr(0, 2); const auto binaryNumber = binary.substr(2); @@ -373,19 +373,25 @@ TEST_F(StringTest, shouldGenerateBinaryWithGuarantee1) // atleast 3 '0' and 2 '1' // atmost 7 '0' and 7 '1' faker::GuaranteeMap guarantee{{'0', {3, 7}}, {'1', {2, 7}}}; - const auto binary = String::binary(std::move(guarantee), binaryLength); + // it is a random function so lets test for 20 random generations + for (int i = 0; i < 20; ++i) + { + auto copyGuarantee = guarantee; + const auto binary = String::binary(std::move(copyGuarantee), binaryLength); - const auto prefix = binary.substr(0, 2); - const auto binaryNumber = binary.substr(2); + const auto prefix = binary.substr(0, 2); + const auto binaryNumber = binary.substr(2); - ASSERT_EQ(binaryNumber.size(), binaryLength); - ASSERT_EQ(prefix, "0b"); - ASSERT_TRUE(std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) - { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); - auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); - auto count_1 = std::count(binaryNumber.begin(), binaryNumber.end(), '1'); - ASSERT_TRUE(count_0 >= 3 && count_0 <= 7); - ASSERT_TRUE(count_1 >= 2 && count_1 <= 7); + ASSERT_EQ(binaryNumber.size(), binaryLength); + ASSERT_EQ(prefix, "0b"); + ASSERT_TRUE( + std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) + { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); + auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); + auto count_1 = std::count(binaryNumber.begin(), binaryNumber.end(), '1'); + ASSERT_TRUE(count_0 >= 3 && count_0 <= 7); + ASSERT_TRUE(count_1 >= 2 && count_1 <= 7); + } } TEST_F(StringTest, shouldGenerateBinaryWithGuarantee2) { @@ -393,19 +399,25 @@ TEST_F(StringTest, shouldGenerateBinaryWithGuarantee2) // exactly 8 '0' and 2 '1' faker::GuaranteeMap guarantee{{'0', {8, 8}}, {'1', {2, 2}}}; - const auto binary = String::binary(std::move(guarantee), binaryLength); + // it is a random function so lets test for 20 random generations + for (int i = 0; i < 20; ++i) + { + auto copyGuarantee = guarantee; + const auto binary = String::binary(std::move(copyGuarantee), binaryLength); - const auto prefix = binary.substr(0, 2); - const auto binaryNumber = binary.substr(2); + const auto prefix = binary.substr(0, 2); + const auto binaryNumber = binary.substr(2); - ASSERT_EQ(binaryNumber.size(), binaryLength); - ASSERT_EQ(prefix, "0b"); - ASSERT_TRUE(std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) - { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); - auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); - auto count_1 = std::count(binaryNumber.begin(), binaryNumber.end(), '1'); - ASSERT_TRUE(count_0 == 8); - ASSERT_TRUE(count_1 == 2); + ASSERT_EQ(binaryNumber.size(), binaryLength); + ASSERT_EQ(prefix, "0b"); + ASSERT_TRUE( + std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) + { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); + auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); + auto count_1 = std::count(binaryNumber.begin(), binaryNumber.end(), '1'); + ASSERT_TRUE(count_0 == 8); + ASSERT_TRUE(count_1 == 2); + } } TEST_F(StringTest, shouldGenerateBinaryWithGuarantee3) { @@ -413,17 +425,23 @@ TEST_F(StringTest, shouldGenerateBinaryWithGuarantee3) // atleast 10 '0' faker::GuaranteeMap guarantee{{'0', {10}}}; - const auto binary = String::binary(std::move(guarantee), binaryLength); + // it is a random function so lets test for 20 random generations + for (int i = 0; i < 20; ++i) + { + auto copyGuarantee = guarantee; + const auto binary = String::binary(std::move(copyGuarantee), binaryLength); - const auto prefix = binary.substr(0, 2); - const auto binaryNumber = binary.substr(2); + const auto prefix = binary.substr(0, 2); + const auto binaryNumber = binary.substr(2); - ASSERT_EQ(binaryNumber.size(), binaryLength); - ASSERT_EQ(prefix, "0b"); - ASSERT_TRUE(std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) - { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); - auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); - ASSERT_TRUE(count_0 == 10); + ASSERT_EQ(binaryNumber.size(), binaryLength); + ASSERT_EQ(prefix, "0b"); + ASSERT_TRUE( + std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) + { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); + auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); + ASSERT_TRUE(count_0 == 10); + } } TEST_F(StringTest, shouldGenerateBinaryWithGuarantee4) @@ -432,17 +450,23 @@ TEST_F(StringTest, shouldGenerateBinaryWithGuarantee4) // atmost 0 '0' faker::GuaranteeMap guarantee{{'0', {0, 0}}}; - const auto binary = String::binary(std::move(guarantee), binaryLength); + // it is a random function so lets test for 20 random generations + for (int i = 0; i < 20; ++i) + { + auto copyGuarantee = guarantee; + const auto binary = String::binary(std::move(copyGuarantee), binaryLength); - const auto prefix = binary.substr(0, 2); - const auto binaryNumber = binary.substr(2); + const auto prefix = binary.substr(0, 2); + const auto binaryNumber = binary.substr(2); - ASSERT_EQ(binaryNumber.size(), binaryLength); - ASSERT_EQ(prefix, "0b"); - ASSERT_TRUE(std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) - { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); - auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); - ASSERT_TRUE(count_0 == 0); + ASSERT_EQ(binaryNumber.size(), binaryLength); + ASSERT_EQ(prefix, "0b"); + ASSERT_TRUE( + std::ranges::any_of(binaryNumber, [](char binaryNumberCharacter) + { return std::string("01").find(binaryNumberCharacter) != std::string::npos; })); + auto count_0 = std::count(binaryNumber.begin(), binaryNumber.end(), '0'); + ASSERT_TRUE(count_0 == 0); + } } TEST_F(StringTest, invalidGuaranteeForBinary1) @@ -477,7 +501,7 @@ TEST_F(StringTest, shouldGenerateOctalWithPrefix) { const auto octalLength = 8; - const auto octal = String::octal({}, octalLength); + const auto octal = String::octal(octalLength); const auto prefix = octal.substr(0, 2); const auto octalNumber = octal.substr(2); @@ -499,7 +523,8 @@ TEST_F(StringTest, shouldGenerateOctalWithGuarantee1) // it is a random function so lets test for 20 random generations for (int i = 0; i < 20; ++i) { - const auto octal = String::octal(std::move(guarantee), octalLength); + auto copyGuarantee = guarantee; + const auto octal = String::octal(std::move(copyGuarantee), octalLength); const auto prefix = octal.substr(0, 2); const auto octalNumber = octal.substr(2); @@ -532,7 +557,8 @@ TEST_F(StringTest, shouldGenerateOctalWithGuarantee2) // it is a random function so lets test for 20 random generations for (int i = 0; i < 20; ++i) { - const auto octal = String::octal(std::move(guarantee), octalLength); + auto copyGuarantee = guarantee; + const auto octal = String::octal(std::move(copyGuarantee), octalLength); const auto prefix = octal.substr(0, 2); const auto octalNumber = octal.substr(2);