Skip to content

Commit

Permalink
feature: Implemented Helper::setElement() (#310)
Browse files Browse the repository at this point in the history
* feature: Implemented `Helper::setElement()`

This helper function can be used to get random items from a std::set
of objects.

* refactor: Use `Helper::setElement()`

Use helper function instead of rewriting code

* tests: Added tests for `Helper::setElement()`
  • Loading branch information
braw-lee authored Nov 21, 2023
1 parent bc2f7c8 commit 1728c38
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
28 changes: 28 additions & 0 deletions include/faker-cxx/Helper.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma once

#include <algorithm>
#include <functional>
#include <numeric>
#include <set>
#include <span>
#include <string>

Expand Down Expand Up @@ -67,6 +69,32 @@ class Helper
return data[index];
}

/**
* @brief Get a random element from a std::set.
*
* @tparam T an element type of the std::set.
*
* @param std::set of elements.
*
* @return T a random element from the std::set.
*
* @code
* std::set<char> chars{'a', 'b', 'c', 'd', 'e'};
* Helper::setElement(chars) // 'd'
* @endcode
*/
template <class T>
static T setElement(const std::set<T>& data)
{
if (data.empty())
{
throw std::invalid_argument{"Data is empty."};
}
T item;
std::sample(data.begin(), data.end(), &item, 1, pseudoRandomGenerator);
return item;
}

template <class T>
struct WeightedElement
{
Expand Down
19 changes: 19 additions & 0 deletions src/modules/helper/HelperTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <regex>
#include <stdexcept>
#include <unordered_map>
#include <vector>

#include "gtest/gtest.h"

Expand All @@ -18,6 +19,24 @@ class HelperTest : public Test
namespace
{

TEST_F(HelperTest, SetElement)
{
std::set<char> chars{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'l', 'm'};
std::vector<char> randomChars;
for (int i = 0; i < 30; ++i)
{
randomChars.push_back(Helper::setElement(chars));
}
for (auto character : randomChars)
{
ASSERT_TRUE(chars.find(character) != chars.end());
}
}
TEST_F(HelperTest, SetElementEmptyData)
{
std::set<char> chars{};
ASSERT_THROW(Helper::setElement<char>(chars), std::invalid_argument);
}
TEST_F(HelperTest, ReplaceSymbolWithNumber)
{
std::string input = "123#456!";
Expand Down
3 changes: 1 addition & 2 deletions src/modules/string/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,7 @@ std::string String::binary(GuaranteeMap&& guarantee, unsigned int length)
while (true)
{
// pick random char from targetCharacters
std::mt19937 gen(std::random_device{}());
std::sample(targetCharacters.begin(), targetCharacters.end(), &generatedChar, 1, gen);
generatedChar = Helper::setElement(targetCharacters);

auto it = guarantee.find(generatedChar);
// if no constraint on generated char, break out of loop
Expand Down

0 comments on commit 1728c38

Please sign in to comment.