Skip to content

Commit

Permalink
refactor: Overloaded String::binary() and String::octal() (#322)
Browse files Browse the repository at this point in the history
* refactor: Overloaded `String::octal()`

Overloaded `String::octal()` so to optimize string generation if user
does not want to use string guarantees

* refactor: Overloaded `String::binary()`

Overloaded `String::binary()` to optimize string generation if user
does not use string guarantees
  • Loading branch information
braw-lee authored Nov 23, 2023
1 parent 023d80f commit ff061eb
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 48 deletions.
34 changes: 30 additions & 4 deletions include/faker-cxx/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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.
Expand All @@ -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);
};
}
19 changes: 19 additions & 0 deletions src/modules/string/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<char>(Number::integer(1));
}
return "0b" + binaryNumber;
}

std::string String::binary(GuaranteeMap&& guarantee, unsigned int length)
{
// numbers used by binary representation
Expand All @@ -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<char>(Number::integer(7));
}
return "0o" + octalNumber;
}
std::string String::octal(GuaranteeMap&& guarantee, unsigned int length)
{
// numbers used by octal representation
Expand Down
114 changes: 70 additions & 44 deletions src/modules/string/StringTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -373,57 +373,75 @@ 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)
{
const auto binaryLength = 10;

// 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)
{
const auto binaryLength = 10;

// 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)
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit ff061eb

Please sign in to comment.