Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/update UUID function to take optional random generator #243

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion include/faker-cxx/String.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#pragma once

#include <iostream>
#include <random>
#include <sstream>
#include <string>

#include "types/Hex.h"
#include "types/RandomGenerator.hpp"

namespace faker
{
Expand All @@ -21,11 +25,55 @@ class String
*
* @returns UUIDv4.
*
* @param gen A random number generator (type RandomGenerator)
* @code
* String::uuid() // "27666229-cedb-4a45-8018-98b1e1d921e2"
* @endcode
*/
static std::string uuid();
template <typename T = std::mt19937>
static std::string uuid(RandomGenerator<T> gen = RandomGenerator<std::mt19937>{})
{
static std::uniform_int_distribution<> dist(0, 15);
static std::uniform_int_distribution<> dist2(8, 11);

std::stringstream ss;
ss << std::hex;

for (int i = 0; i < 8; i++)
{
ss << gen(dist);
}

ss << "-";
for (int i = 0; i < 4; i++)
{
ss << gen(dist);
}

ss << "-4";
for (int i = 0; i < 3; i++)
{
ss << gen(dist);
}

ss << "-";

ss << gen(dist2);

for (int i = 0; i < 3; i++)
{
ss << gen(dist);
}

ss << "-";

for (int i = 0; i < 12; i++)
{
ss << gen(dist);
};

return ss.str();
}

/**
* @brief Returns a string containing UTF-16 chars between 33 and 125 (`!` to `}`).
Expand Down
24 changes: 24 additions & 0 deletions include/faker-cxx/types/RandomGenerator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once
#include <random>

template <typename T>
requires std::uniform_random_bit_generator<T>
class RandomGenerator
{
public:
RandomGenerator() : generator_{T(std::random_device{}())} {}
~RandomGenerator() = default;

RandomGenerator(const RandomGenerator&) = default;
RandomGenerator(RandomGenerator&&) = default;
RandomGenerator& operator=(const RandomGenerator&) = default;
RandomGenerator& operator=(RandomGenerator&&) = default;

int operator()(std::uniform_int_distribution<>& dist)
{
return dist(generator_);
}

private:
T generator_;
};
46 changes: 0 additions & 46 deletions src/modules/string/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,52 +32,6 @@ const std::map<HexPrefix, std::string> hexPrefixToStringMapping{
};
}

std::string String::uuid()
{
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<> dist(0, 15);
static std::uniform_int_distribution<> dist2(8, 11);

std::stringstream ss;
ss << std::hex;

for (int i = 0; i < 8; i++)
{
ss << dist(gen);
}

ss << "-";
for (int i = 0; i < 4; i++)
{
ss << dist(gen);
}

ss << "-4";
for (int i = 0; i < 3; i++)
{
ss << dist(gen);
}

ss << "-";

ss << dist2(gen);

for (int i = 0; i < 3; i++)
{
ss << dist(gen);
}

ss << "-";

for (int i = 0; i < 12; i++)
{
ss << dist(gen);
};

return ss.str();
}

std::string String::sample(unsigned int length)
{
std::string sample;
Expand Down
95 changes: 95 additions & 0 deletions src/modules/string/StringTest.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "faker-cxx/String.h"

#include <algorithm>
#include <random>

#include "gtest/gtest.h"

#include "data/Characters.h"
#include "faker-cxx/types/RandomGenerator.hpp"

using namespace ::testing;
using namespace faker;
Expand All @@ -14,6 +16,99 @@ class StringTest : public Test
public:
};

TEST_F(StringTest, shouldUseCustomRandomGeneratorForUuid4)
{
RandomGenerator<std::mt19937> gen1{};
const auto uuid1 = String::uuid(gen1);

ASSERT_EQ(uuid1[8], '-');
ASSERT_EQ(uuid1[13], '-');
ASSERT_EQ(uuid1[14], '4');
ASSERT_EQ(uuid1[18], '-');
ASSERT_EQ(uuid1[23], '-');

RandomGenerator<std::mt19937_64> gen2{};
const auto uuid2 = String::uuid(gen2);

ASSERT_EQ(uuid2[8], '-');
ASSERT_EQ(uuid2[13], '-');
ASSERT_EQ(uuid2[14], '4');
ASSERT_EQ(uuid2[18], '-');
ASSERT_EQ(uuid2[23], '-');

RandomGenerator<std::minstd_rand0> gen3{};
const auto uuid3 = String::uuid(gen3);

ASSERT_EQ(uuid3[8], '-');
ASSERT_EQ(uuid3[13], '-');
ASSERT_EQ(uuid3[14], '4');
ASSERT_EQ(uuid3[18], '-');
ASSERT_EQ(uuid3[23], '-');

RandomGenerator<std::minstd_rand> gen4{};
const auto uuid4 = String::uuid(gen4);

ASSERT_EQ(uuid4[8], '-');
ASSERT_EQ(uuid4[13], '-');
ASSERT_EQ(uuid4[14], '4');
ASSERT_EQ(uuid4[18], '-');
ASSERT_EQ(uuid4[23], '-');

RandomGenerator<std::ranlux24_base> gen5{};
const auto uuid5 = String::uuid(gen5);

ASSERT_EQ(uuid5[8], '-');
ASSERT_EQ(uuid5[13], '-');
ASSERT_EQ(uuid5[14], '4');
ASSERT_EQ(uuid5[18], '-');
ASSERT_EQ(uuid5[23], '-');

RandomGenerator<std::ranlux24> gen6{};
const auto uuid6 = String::uuid(gen6);

ASSERT_EQ(uuid6[8], '-');
ASSERT_EQ(uuid6[13], '-');
ASSERT_EQ(uuid6[14], '4');
ASSERT_EQ(uuid6[18], '-');
ASSERT_EQ(uuid6[23], '-');

RandomGenerator<std::ranlux48_base> gen7{};
const auto uuid7 = String::uuid(gen7);

ASSERT_EQ(uuid7[8], '-');
ASSERT_EQ(uuid7[13], '-');
ASSERT_EQ(uuid7[14], '4');
ASSERT_EQ(uuid7[18], '-');
ASSERT_EQ(uuid7[23], '-');

RandomGenerator<std::ranlux48> gen8{};
const auto uuid8 = String::uuid(gen8);

ASSERT_EQ(uuid8[8], '-');
ASSERT_EQ(uuid8[13], '-');
ASSERT_EQ(uuid8[14], '4');
ASSERT_EQ(uuid8[18], '-');
ASSERT_EQ(uuid8[23], '-');

RandomGenerator<std::knuth_b> gen9{};
const auto uuid9 = String::uuid(gen9);

ASSERT_EQ(uuid9[8], '-');
ASSERT_EQ(uuid9[13], '-');
ASSERT_EQ(uuid9[14], '4');
ASSERT_EQ(uuid9[18], '-');
ASSERT_EQ(uuid9[23], '-');

RandomGenerator<std::default_random_engine> gen10{};
const auto uuid10 = String::uuid(gen10);

ASSERT_EQ(uuid10[8], '-');
ASSERT_EQ(uuid10[13], '-');
ASSERT_EQ(uuid10[14], '4');
ASSERT_EQ(uuid10[18], '-');
ASSERT_EQ(uuid10[23], '-');
}

TEST_F(StringTest, shouldGenerateUuid4)
{
const auto uuid = String::uuid();
Expand Down