Skip to content

Commit

Permalink
feat: added ordinalDirection generation function (#992)
Browse files Browse the repository at this point in the history
* Added `ordinalDirection` function

- Implemented random ordinal direction generation function.
- Added testing code for the ordinal direction generation function.

* Fixed code formatting

---------

Co-authored-by: Michał Cieślar <[email protected]>
  • Loading branch information
BAKAJ77 and cieslarmichal authored Nov 23, 2024
1 parent 824cba8 commit 576187d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 21 deletions.
15 changes: 15 additions & 0 deletions include/faker-cxx/location.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,21 @@ FAKER_CXX_EXPORT std::tuple<std::string, std::string> nearbyGPSCoordinate(
*/
FAKER_CXX_EXPORT std::string_view direction();

/**
* @brief Generates a random direction from ordinal directions.
*
* @param abbreviated If `true` this will return abbreviated directions (NW, SE, etc). Otherwise this
* will return the long name. By default, this is set to `false`.
*
* @returns Ordinal direction.
*
* @code
* faker::location::ordinalDirection() // "Southeast"
* faker::location::ordinalDirection(true) // "NW"
* @endcode
*/
FAKER_CXX_EXPORT std::string_view ordinalDirection(bool abbreviated = false);

/**
* @brief Generates a random time zone.
*
Expand Down
6 changes: 6 additions & 0 deletions src/modules/location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ std::string_view direction()
return helper::randomElement(directions);
}

std::string_view ordinalDirection(bool abbreviated)
{
return abbreviated ? helper::randomElement(ordinalDirections).second :
helper::randomElement(ordinalDirections).first;
}

std::string_view timeZone()
{
return helper::randomElement(timeZones);
Expand Down
7 changes: 7 additions & 0 deletions src/modules/location_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,13 @@ const auto directions = std::to_array<std::string_view>({
"West",
});

constexpr auto ordinalDirections = std::to_array<std::pair<std::string_view, std::string_view>>({
{"Northeast", "NE"},
{"Northwest", "NW"},
{"Southeast", "SE"},
{"Southwest", "SW"}
});

const auto timeZones = std::to_array<std::string_view>({
// clang-format off
"Africa/Abidjan",
Expand Down
54 changes: 33 additions & 21 deletions tests/modules/location_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
#include "location_data.h"
#include "person_data.h"
#include "string_data.h"
#include "faker-cxx/location.h"
#include "location_data.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846
Expand Down Expand Up @@ -622,6 +620,22 @@ TEST_F(LocationTest, shouldGenerateDirection)
{ return direction == generatedDirection; }));
}

TEST_F(LocationTest, shouldGenerateOrdinalDirection)
{
const auto generatedOrdinalDirection = ordinalDirection();
const auto generatedOrdinalDirectionAbbreviated = ordinalDirection(true);

ASSERT_TRUE(std::ranges::any_of(
ordinalDirections,
[generatedOrdinalDirection](const std::pair<std::string_view, std::string_view>& ordinalDirection)
{ return ordinalDirection.first == generatedOrdinalDirection; }));

ASSERT_TRUE(std::ranges::any_of(
ordinalDirections,
[generatedOrdinalDirectionAbbreviated](const std::pair<std::string_view, std::string_view>& ordinalDirection)
{ return ordinalDirection.second == generatedOrdinalDirectionAbbreviated; }));
}

TEST_F(LocationTest, shouldGenerateTimeZone)
{
const auto generatedTimeZone = timeZone();
Expand Down Expand Up @@ -1022,7 +1036,6 @@ TEST_F(LocationTest, shouldGenerateSlovakiaStreetAddress)
{ return generatedStreetSuffix.find(streetSuffix) != std::string::npos; }));
}


TEST_F(LocationTest, shouldGeneratePortugalStreet)
{
const auto generatedStreet = street(Locale::pt_PT);
Expand Down Expand Up @@ -1072,7 +1085,6 @@ TEST_F(LocationTest, shouldGenerateIsraelStreet)
const auto& generatedStreetName =
common::join({generatedStreetElements.begin() + 1, generatedStreetElements.end()});


ASSERT_TRUE(std::ranges::any_of(israelStreetPrefixes, [&generatedStreetPrefix](const std::string_view& streetPrefix)
{ return streetPrefix == generatedStreetPrefix; }));
ASSERT_TRUE(std::ranges::any_of(israelStreetNames, [&generatedStreetName](const std::string_view& streetName)
Expand All @@ -1083,31 +1095,32 @@ TEST_F(LocationTest, shouldGenerateIsraelStreetAddress)
{
const auto generatedStreetAddress = streetAddress(Locale::he_IL);
auto generatedAddresses = common::split(generatedStreetAddress, " ");
if (generatedAddresses[generatedAddresses.size() - 2] == "דירה" || generatedAddresses[generatedAddresses.size() - 2] == "חדר")
if (generatedAddresses[generatedAddresses.size() - 2] == "דירה" ||
generatedAddresses[generatedAddresses.size() - 2] == "חדר")
{
const auto& secondaryAddressType = generatedAddresses[generatedAddresses.size() - 2];
const auto& secondaryAddressNumber = generatedAddresses.back();
ASSERT_TRUE(secondaryAddressNumber.size() == 1 || secondaryAddressNumber.size() == 2);
ASSERT_TRUE(checkIfAllCharactersAreNumeric(secondaryAddressNumber));
ASSERT_TRUE(secondaryAddressType == "דירה" || secondaryAddressType == "חדר");
generatedAddresses.pop_back(); // Remove unit number
generatedAddresses.pop_back(); // Remove unit number
generatedAddresses.pop_back();
}
const auto& generatedStreetPrefix = generatedAddresses[0];
auto generatedBuildingNumber = generatedAddresses.back();
generatedAddresses.pop_back();
while (!generatedBuildingNumber.empty() && !checkIfAllCharactersAreNumeric(generatedBuildingNumber)) {
while (!generatedBuildingNumber.empty() && !checkIfAllCharactersAreNumeric(generatedBuildingNumber))
{
generatedBuildingNumber.pop_back(); // Remove the last byte until it's numeric
}
const auto& generatedStreetName =
common::join({generatedAddresses.begin() + 1, generatedAddresses.end()});

ASSERT_TRUE(!generatedBuildingNumber.empty() && generatedBuildingNumber.size() <= 3);
ASSERT_TRUE(checkIfAllCharactersAreNumeric(generatedBuildingNumber));
const auto& generatedStreetName = common::join({generatedAddresses.begin() + 1, generatedAddresses.end()});

ASSERT_TRUE(!generatedBuildingNumber.empty() && generatedBuildingNumber.size() <= 3);
ASSERT_TRUE(checkIfAllCharactersAreNumeric(generatedBuildingNumber));
ASSERT_TRUE(std::ranges::any_of(israelStreetPrefixes, [&generatedStreetPrefix](const std::string_view& streetPrefix)
{ return streetPrefix == generatedStreetPrefix; }));
{ return streetPrefix == generatedStreetPrefix; }));
ASSERT_TRUE(std::ranges::any_of(israelStreetNames, [&generatedStreetName](const std::string_view& streetName)
{ return streetName == generatedStreetName; }));
{ return streetName == generatedStreetName; }));
}

TEST_F(LocationTest, shouldGenerateMexicoStreet)
Expand Down Expand Up @@ -1140,8 +1153,9 @@ TEST_F(LocationTest, shouldGeneratepalestineStreetAddress)
{ return generatedStreetAddress.find(streetName) != std::string::npos; }));
}


class LocationContinentTest : public ::testing::Test {};
class LocationContinentTest : public ::testing::Test
{
};

TEST_F(LocationContinentTest, shouldGenerateCorrectContinentForKnownCountry)
{
Expand All @@ -1158,9 +1172,7 @@ TEST_F(LocationContinentTest, shouldReturnUnknownForUnmappedCountry)

TEST_F(LocationContinentTest, shouldGenerateRandomContinent)
{
const auto generatedContinent = continent();
ASSERT_TRUE(std::ranges::any_of(allContinents, [&generatedContinent](const std::string_view& c) {
return c == generatedContinent;
}));
const auto generatedContinent = continent();
ASSERT_TRUE(std::ranges::any_of(allContinents, [&generatedContinent](const std::string_view& c)
{ return c == generatedContinent; }));
}

0 comments on commit 576187d

Please sign in to comment.