Skip to content

Commit

Permalink
Add Bio function to Person Module (#373)
Browse files Browse the repository at this point in the history
* Add bioPart std::vector

* Adjust bio vector

* Add bio() method to the Person class

* Add bioSupporter and bioFormats vector

* Add bio() method implementation

* Add test for the Person bio

* Add BioHelper to check if the bio generated is valid

* Add method to the Internet class to check if an emoji is valid

* Implement BioHelper::checkTokenFormat()

* Add missing includes

* Adjust regex expressions

* Add comment to checkIfEmojiIsValid() method

* Adjust regex matching

* Delete useless std::cout

* Format code
  • Loading branch information
MikelKokoshi authored Dec 4, 2023
1 parent 99171ea commit 1003827
Show file tree
Hide file tree
Showing 13 changed files with 279 additions and 25 deletions.
21 changes: 11 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

option(BUILD_FAKER_TESTS DEFAULT ON)

if (MSVC)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++20 /permissive- /bigobj")
else ()
else()
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wconversion -Wformat -Werror"
)
endif ()
)
endif()

set(LIBRARY_NAME faker-cxx)

Expand All @@ -38,6 +38,7 @@ set(FAKER_SOURCES
src/modules/string/String.cpp
src/modules/word/Word.cpp
src/modules/phone/Phone.cpp
src/common/BioHelper.cpp
src/common/StringHelper.cpp
src/common/FormatHelper.cpp
src/common/LuhnCheck.cpp
Expand All @@ -55,7 +56,7 @@ set(FAKER_SOURCES
src/common/WeatherHelper.cpp
src/modules/airline/Airline.cpp
src/modules/image/Image.cpp
src/modules/crypto/Crypto.cpp
src/modules/crypto/Crypto.cpp
src/modules/computer/Computer.cpp)

set(FAKER_UT_SOURCES
Expand Down Expand Up @@ -94,7 +95,7 @@ set(FAKER_UT_SOURCES
src/common/WeatherHelperTest.cpp
src/modules/airline/AirlineTest.cpp
src/modules/image/ImageTest.cpp
src/modules/crypto/CryptoTest.cpp
src/modules/crypto/CryptoTest.cpp
src/modules/computer/ComputerTest.cpp)

add_library(${LIBRARY_NAME} ${FAKER_SOURCES})
Expand All @@ -110,7 +111,7 @@ set(FMT_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/fmt/include")

target_link_libraries(${LIBRARY_NAME} PRIVATE fmt)

if (BUILD_FAKER_TESTS)
if(BUILD_FAKER_TESTS)
add_subdirectory(externals/googletest)

set(GTEST_INCLUDE_DIR
Expand All @@ -129,17 +130,17 @@ if (BUILD_FAKER_TESTS)
add_executable(${LIBRARY_NAME}-UT ${FAKER_UT_SOURCES})

target_link_libraries(${LIBRARY_NAME}-UT PRIVATE gtest_main gmock_main
faker-cxx)
faker-cxx)

target_include_directories(
${LIBRARY_NAME}-UT
PRIVATE ${FMT_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR}
${CMAKE_CURRENT_LIST_DIR})
${CMAKE_CURRENT_LIST_DIR})

add_test(
NAME ${LIBRARY_NAME}-UT
COMMAND ${LIBRARY_NAME}-UT
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})

target_code_coverage(${LIBRARY_NAME}-UT ALL)
endif ()
endif()
16 changes: 7 additions & 9 deletions include/faker-cxx/Computer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@

#include <string>


namespace faker
{
class Computer
{
public:
/*
* @brief Returns a random computer type.
*
* @returns computer type
*
* @code
* Computer::type() // Laptop
*/
* @brief Returns a random computer type.
*
* @returns computer type
*
* @code
* Computer::type() // Laptop
*/
static std::string type();
/*
* @brief Returns a random computer manufacture name.
Expand Down Expand Up @@ -89,7 +88,6 @@ class Computer
* Computer::gpuModel() // NVIDIA GeForce RTX 3080
*/
static std::string gpuModel();

};

}
16 changes: 15 additions & 1 deletion include/faker-cxx/Internet.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ enum class IPv4Class
C
};

struct PasswordOptions {
struct PasswordOptions
{
bool upperLetters = true;
bool lowerLetters = true;
bool numbers = true;
Expand Down Expand Up @@ -123,6 +124,19 @@ class Internet
*/
static std::string emoji(std::optional<EmojiType> type = std::nullopt);

/**
* @brief Verify that a given emoji is valid.
*
* @param emojiToCheck the emoji to check.
*
* @returns true if emojiToCheck is found in one of the vectors, false otherwise.
*
* @code
* Internet::checkIfEmojiIsValid("👑") // true
* @endcode
*/
static bool checkIfEmojiIsValid(const std::string& emojiToCheck);

/**
* @brief Returns a random web protocol. Either `http` or `https`.
*
Expand Down
11 changes: 11 additions & 0 deletions include/faker-cxx/Person.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ class Person
*/
static std::string suffix();

/**
* @brief Returns a random bio.
*
* @returns Bio.
*
* @code
* Person::bio() //"Developer"
* @endcode
*/
static std::string bio();

/**
* @brief Returns a sex.
*
Expand Down
102 changes: 102 additions & 0 deletions src/common/BioHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "BioHelper.h"

#include "../../include/faker-cxx/Internet.h"
#include "../../src/modules/person/data/Bio.h"
#include "../../src/modules/word/data/Nouns.h"

namespace faker
{
bool BioHelper::checkTokenFormat(const std::string& bio)
{

const std::regex firstRegex{R"(^[a-zA-Z0-9_]+$)"};
const std::regex secondRegex{R"(^(\w+\s?\w+), (\w+\s?\w+)$)"};
const std::regex thirdRegex{R"(^(\w+\s?\w+), (\w+\s?\w+), (\w+\s?\w+)$)"};
const std::regex fourthRegex{R"(^(\w+\s?\w+), (\w+\s?\w+), (\w+\s?\w+), (\S+)$)"};
const std::regex fifthRegex{R"(^(\w+) (\w+)$)"};
const std::regex sixthRegex{R"(^(\w+) (\w+) (\S+)$)"};
const std::regex seventhRegex{R"(^(\w+) (\w+), (\w+\s?\w+)$)"};
const std::regex eigthRegex{R"(^(\w+) (\w+), (\w+\s?\w+) (\S+)$)"};

std::smatch matches;
//
if (std::regex_match(bio, matches, firstRegex))
{
// In this case the bio is in the format {bio_part} so check that the value is present in the bio_part vector.
if (std::find(bioPart.begin(), bioPart.end(), matches[0]) != bioPart.end())
return true;
}

if (std::regex_match(bio, matches, secondRegex))
{
// In this case the bio is in the format {bio_part}, {bio_part} so check that the value is present in the
// bio_part vector.
if (std::find(bioPart.begin(), bioPart.end(), matches[1]) != bioPart.end() &&
std::find(bioPart.begin(), bioPart.end(), matches[2]) != bioPart.end())
return true;
}

if (std::regex_match(bio, matches, thirdRegex))
{
// In this case the bio is in the format {bio_part}, {bio_part}, {bio_part} so check that the value is present
// in the bio_part vector.
if (std::find(bioPart.begin(), bioPart.end(), matches[1]) != bioPart.end() &&
std::find(bioPart.begin(), bioPart.end(), matches[2]) != bioPart.end() &&
std::find(bioPart.begin(), bioPart.end(), matches[3]) != bioPart.end())
return true;
}

if (std::regex_match(bio, matches, fourthRegex))
{
// In this case the bio is in the format {bio_part}, {bio_part}, {bio_part}, {emoji} so check that the value is
// present in the bio_part vector.
if (std::find(bioPart.begin(), bioPart.end(), matches[1]) != bioPart.end() &&
std::find(bioPart.begin(), bioPart.end(), matches[2]) != bioPart.end() &&
std::find(bioPart.begin(), bioPart.end(), matches[3]) != bioPart.end() &&
Internet::checkIfEmojiIsValid(matches[4]))
return true;
}

if (std::regex_match(bio, matches, fifthRegex))
{
// In this case the bio is in the format {noun} {bio_supporter} so check that the value is present
// in the bio_part vector.
if (std::find(nouns.begin(), nouns.end(), matches[1]) != nouns.end() &&
std::find(bioSupporter.begin(), bioSupporter.end(), matches[2]) != bioSupporter.end())
return true;
}

if (std::regex_match(bio, matches, sixthRegex))
{
// In this case the bio is in the format {noun} {bio_supporter} {emoji} so check that the value is present
// in the bio_part vector.
if (std::find(nouns.begin(), nouns.end(), matches[1]) != nouns.end() &&
std::find(bioSupporter.begin(), bioSupporter.end(), matches[2]) != bioSupporter.end() &&
Internet::checkIfEmojiIsValid(matches[3]))
return true;
}

if (std::regex_match(bio, matches, seventhRegex))
{
// In this case the bio is in the format {noun} {bio_supporter}, {bio_part} so check that the value is present
// in the bio_part vector.
if (std::find(nouns.begin(), nouns.end(), matches[1]) != nouns.end() &&
std::find(bioSupporter.begin(), bioSupporter.end(), matches[2]) != bioSupporter.end() &&
std::find(bioPart.begin(), bioPart.end(), matches[3]) != bioPart.end())
return true;
}

if (std::regex_match(bio, matches, eigthRegex))
{
// In this case the bio is in the format {noun} {bio_supporter}, {bio_part} {emoji} so check that the value is
// present in the bio_part vector.
if (std::find(nouns.begin(), nouns.end(), matches[1]) != nouns.end() &&
std::find(bioSupporter.begin(), bioSupporter.end(), matches[2]) != bioSupporter.end() &&
std::find(bioPart.begin(), bioPart.end(), matches[3]) != bioPart.end() &&
Internet::checkIfEmojiIsValid(matches[4]))
return true;
}

return false;
}
}
16 changes: 16 additions & 0 deletions src/common/BioHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <functional>
#include <map>
#include <regex>
#include <string>
#include <vector>

namespace faker
{
class BioHelper
{
public:
static bool checkTokenFormat(const std::string& bio);
};
}
5 changes: 2 additions & 3 deletions src/common/StringHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

#include <algorithm>
#include <cctype>
#include <sstream>
#include <locale>
#include <codecvt>

#include <locale>
#include <sstream>

namespace faker
{
Expand Down
1 change: 0 additions & 1 deletion src/common/StringHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@ class StringHelper
static std::string toLower(const std::string& data);
static bool isPunctuation(char c);
static std::string removePunctuation(const std::string& word);

};
}
1 change: 0 additions & 1 deletion src/common/StringHelperTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,3 @@ TEST_F(StringHelperTest, RemovePunctuation)
std::string result = StringHelper::removePunctuation(input);
EXPECT_EQ(result, "Hello World");
}

14 changes: 14 additions & 0 deletions src/modules/internet/Internet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ std::string Internet::emoji(std::optional<EmojiType> type)
return Helper::arrayElement<std::string>(emojis);
}


bool Internet::checkIfEmojiIsValid(const std::string& emojiToCheck)
{
for (const auto& vector : {smileyEmojis, bodyEmojis, personEmojis, natureEmojis, foodEmojis, travelEmojis, activityEmojis, objectEmojis, symbolEmojis, flagEmojis})
{
if(std::find(vector.begin(), vector.end(), emojiToCheck) != vector.end()){
return true;
}
}

return false;
}


std::string Internet::protocol()
{
return Helper::arrayElement<std::string>(webProtocols);
Expand Down
18 changes: 18 additions & 0 deletions src/modules/person/Person.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "data/austria/AustrianPeopleNames.h"
#include "data/belarus/BelarusianPeopleNames.h"
#include "data/belgium/BelgianPeopleNames.h"
#include "data/Bio.h"
#include "data/brazil/BrazilianPeopleNames.h"
#include "data/canada/CanadianPeopleNames.h"
#include "data/china/ChinesePeopleNames.h"
Expand Down Expand Up @@ -55,6 +56,8 @@
#include "data/ukraine/UkrainianPeopleNames.h"
#include "data/usa/UsaPeopleNames.h"
#include "data/ZodiacSigns.h"
#include "faker-cxx/Word.h"
#include "faker-cxx/Internet.h"
#include "faker-cxx/Helper.h"
#include "fmt/format.h"

Expand Down Expand Up @@ -264,6 +267,21 @@ std::string Person::prefix(std::optional<Sex> sex)
return Helper::arrayElement<std::string>(allPrefixes);
}


std::string Person::bio()
{
const auto randomBioFormat = Helper::arrayElement<std::string>(bioFormats);


const auto dataGeneratorsMapping = std::map<std::string, std::function<std::string()>>{
{"bio_part", []() { return Helper::arrayElement(bioPart);}},
{"bio_supporter", []() { return Helper::arrayElement(bioSupporter); }},
{"noun", []() { return Word::noun();}},
{"emoji", []() { return Internet::emoji();}}};

return FormatHelper::fillTokenValues(randomBioFormat, dataGeneratorsMapping);
}

std::string Person::suffix()
{
std::vector<std::string> allSuffixes;
Expand Down
9 changes: 9 additions & 0 deletions src/modules/person/PersonTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "gtest/gtest.h"


#include "../../common/BioHelper.h"
#include "../../common/StringHelper.h"
#include "data/albania/AlbanianPeopleNames.h"
#include "data/argentina/ArgentinianPeopleNames.h"
Expand Down Expand Up @@ -432,6 +434,13 @@ TEST_F(PersonTest, shouldGenerateHobby)
std::ranges::any_of(hobbies, [generatedHobby](const std::string& hobby) { return hobby == generatedHobby; }));
}

TEST_F(PersonTest, shouldGenerateBio)
{
const auto generatedBio = Person::bio();

ASSERT_TRUE(BioHelper::checkTokenFormat(generatedBio));
}

TEST_F(PersonTest, shouldGenerateLanguage)
{
const auto generatedLanguage = Person::language();
Expand Down
Loading

0 comments on commit 1003827

Please sign in to comment.