From 8d37101b5c32d05c7767b4ac68875eafa37d0137 Mon Sep 17 00:00:00 2001 From: Eric Floyd <101071809+eric-bodhi@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:02:45 -0400 Subject: [PATCH] added passport to person (#524) * added passport to person * separated tests and fixed documentation --- include/faker-cxx/Person.h | 12 ++++ include/faker-cxx/types/PassportType.h | 24 +++++++ src/modules/person/Person.cpp | 22 +++++++ src/modules/person/PersonTest.cpp | 87 +++++++++++++++++++++++--- 4 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 include/faker-cxx/types/PassportType.h diff --git a/include/faker-cxx/Person.h b/include/faker-cxx/Person.h index 153f4013d..cc0872720 100644 --- a/include/faker-cxx/Person.h +++ b/include/faker-cxx/Person.h @@ -4,6 +4,7 @@ #include #include "faker-cxx/types/Country.h" +#include "faker-cxx/types/PassportType.h" #include "faker-cxx/types/Sex.h" #include "faker-cxx/types/SsnCountry.h" @@ -242,5 +243,16 @@ class Person * @endcode */ static std::string chineseZodiac(); + + /** + * @brief Returns a random passport number from a given country + * + * @returns Passport + * + * @code + * Person::passport(PassportCountry::Romania) // "12345678" + * @endcode + */ + static std::string passport(PassportCountry country = PassportCountry::Usa); }; } diff --git a/include/faker-cxx/types/PassportType.h b/include/faker-cxx/types/PassportType.h new file mode 100644 index 000000000..08b239992 --- /dev/null +++ b/include/faker-cxx/types/PassportType.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +namespace faker +{ + +enum class PassportCountry +{ + Usa, + Poland, + France, + Romania, +}; + +const std::map passportFormats{ + {PassportCountry::Usa, "AA0000000"}, + {PassportCountry::Poland, "AA0000000"}, + {PassportCountry::France, "00AA00000"}, + {PassportCountry::Romania, "00000000"}, +}; + +} diff --git a/src/modules/person/Person.cpp b/src/modules/person/Person.cpp index 4370a08e9..4c2b3586c 100644 --- a/src/modules/person/Person.cpp +++ b/src/modules/person/Person.cpp @@ -77,6 +77,7 @@ #include "faker-cxx/Helper.h" #include "faker-cxx/Internet.h" #include "faker-cxx/String.h" +#include "faker-cxx/types/PassportType.h" #include "faker-cxx/Word.h" namespace faker @@ -455,6 +456,27 @@ std::string Person::chineseZodiac() return Helper::arrayElement(chineseZodiacs); } +std::string Person::passport(PassportCountry country) +{ + std::string passportFormat = passportFormats.at(country); + std::string passportNumber; + + for (const char& c : passportFormat) + { + if (c == 'A') + { + passportNumber += String::alpha(1, StringCasing::Upper); + } + + else if (c == '0') + { + passportNumber += String::numeric(1); + } + } + + return passportNumber; +} + namespace { std::string middleNameForCountry(Country country, std::optional sex) diff --git a/src/modules/person/PersonTest.cpp b/src/modules/person/PersonTest.cpp index 2b2e831a2..97b4895fd 100644 --- a/src/modules/person/PersonTest.cpp +++ b/src/modules/person/PersonTest.cpp @@ -76,6 +76,7 @@ #include "data/vietnam/VietnamesePeopleNames.h" #include "data/ZodiacSigns.h" #include "faker-cxx/Internet.h" +#include "faker-cxx/types/PassportType.h" using namespace ::testing; using namespace faker; @@ -646,6 +647,73 @@ INSTANTIATE_TEST_SUITE_P(TestPersonSsn, PersonSsnSuite, testing::ValuesIn(suppor [](const testing::TestParamInfo& info) { return "shouldGenerate" + toString(info.param) + "Ssn"; }); +class PersonPassportTest : public Test +{ +public: +}; + +TEST_F(PersonPassportTest, shouldGenerateUsaPassport) +{ + const auto passportNumber = Person::passport(PassportCountry::Usa); + + ASSERT_EQ(passportNumber.size(), 9); + ASSERT_TRUE(std::isalpha(passportNumber[0])); + ASSERT_TRUE(std::isalpha(passportNumber[1])); + ASSERT_TRUE(std::isdigit(passportNumber[2])); + ASSERT_TRUE(std::isdigit(passportNumber[3])); + ASSERT_TRUE(std::isdigit(passportNumber[4])); + ASSERT_TRUE(std::isdigit(passportNumber[5])); + ASSERT_TRUE(std::isdigit(passportNumber[6])); + ASSERT_TRUE(std::isdigit(passportNumber[7])); + ASSERT_TRUE(std::isdigit(passportNumber[8])); +}; + +TEST_F(PersonPassportTest, shouldGeneratePolandPassport) +{ + const auto passportNumber = Person::passport(PassportCountry::Poland); + + ASSERT_EQ(passportNumber.size(), 9); + ASSERT_TRUE(std::isalpha(passportNumber[0])); + ASSERT_TRUE(std::isalpha(passportNumber[1])); + ASSERT_TRUE(std::isdigit(passportNumber[2])); + ASSERT_TRUE(std::isdigit(passportNumber[3])); + ASSERT_TRUE(std::isdigit(passportNumber[4])); + ASSERT_TRUE(std::isdigit(passportNumber[5])); + ASSERT_TRUE(std::isdigit(passportNumber[6])); + ASSERT_TRUE(std::isdigit(passportNumber[7])); + ASSERT_TRUE(std::isdigit(passportNumber[8])); +}; + +TEST_F(PersonPassportTest, shouldGenerateFrenchPassport) +{ + const auto passportNumber = Person::passport(PassportCountry::France); + + ASSERT_EQ(passportNumber.size(), 9); + ASSERT_TRUE(std::isdigit(passportNumber[0])); + ASSERT_TRUE(std::isdigit(passportNumber[1])); + ASSERT_TRUE(std::isalpha(passportNumber[2])); + ASSERT_TRUE(std::isalpha(passportNumber[3])); + ASSERT_TRUE(std::isdigit(passportNumber[4])); + ASSERT_TRUE(std::isdigit(passportNumber[5])); + ASSERT_TRUE(std::isdigit(passportNumber[6])); + ASSERT_TRUE(std::isdigit(passportNumber[7])); + ASSERT_TRUE(std::isdigit(passportNumber[8])); +}; + +TEST_F(PersonPassportTest, shouldGenerateRomanianPassport) +{ + const auto passportNumber = Person::passport(PassportCountry::Romania); + ASSERT_EQ(passportNumber.size(), 8); + ASSERT_TRUE(std::isdigit(passportNumber[0])); + ASSERT_TRUE(std::isdigit(passportNumber[1])); + ASSERT_TRUE(std::isdigit(passportNumber[2])); + ASSERT_TRUE(std::isdigit(passportNumber[3])); + ASSERT_TRUE(std::isdigit(passportNumber[4])); + ASSERT_TRUE(std::isdigit(passportNumber[5])); + ASSERT_TRUE(std::isdigit(passportNumber[6])); + ASSERT_TRUE(std::isdigit(passportNumber[7])); +}; + bool checkTokenFormat(const std::string& bio) { const std::regex firstRegex{R"(^(\w+\s?\w+)$)"}; @@ -661,7 +729,8 @@ bool checkTokenFormat(const std::string& bio) // 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. + // 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; } @@ -677,8 +746,8 @@ bool checkTokenFormat(const std::string& bio) 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. + // 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()) @@ -687,8 +756,8 @@ bool checkTokenFormat(const std::string& bio) 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. + // 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() && @@ -717,8 +786,8 @@ bool checkTokenFormat(const std::string& bio) 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. + // 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()) @@ -727,8 +796,8 @@ bool checkTokenFormat(const std::string& bio) 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. + // 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() &&