diff --git a/CMakeLists.txt b/CMakeLists.txt index 82d7f86b..4b304db9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ set(FAKER_SOURCES src/modules/weather/Weather.cpp src/common/WeatherHelper.cpp src/modules/airline/Airline.cpp + src/modules/image/Image.cpp ) set(FAKER_UT_SOURCES @@ -84,6 +85,7 @@ set(FAKER_UT_SOURCES src/modules/weather/WeatherTest.cpp src/common/WeatherHelperTest.cpp src/modules/airline/AirlineTest.cpp + src/modules/image/ImageTest.cpp ) add_library(${LIBRARY_NAME} ${FAKER_SOURCES}) @@ -94,7 +96,7 @@ target_include_directories(${LIBRARY_NAME} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/include" ${FMT_INCLUDE_DIR} - ) +) add_subdirectory(externals/fmt) diff --git a/README.md b/README.md index 55174135..5590c3e1 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,8 @@ target_link_libraries(main faker-cxx) - 📁 Git - branch names, commit messages, commit hash - 👨‍💻 Hacker - hacker words - ✋ Helper - random element from container -- 🌐 Internet - emails, usernames, passwords, images urls, IP, HTTP +- 🌐 Internet - emails, usernames, passwords, IP, HTTP +- 🖼️ Image - images urls, github avatar urls, image dimensions - 🌍 Location - countries, cities, zip codes, street addresses - 📚 Lorem - lorem words, sentences, paragraphs - 🏥 Medicine - conditions, medical tests, specialties diff --git a/include/faker-cxx/Image.h b/include/faker-cxx/Image.h new file mode 100644 index 00000000..e0a12794 --- /dev/null +++ b/include/faker-cxx/Image.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include + +#include "types/ImageCategory.h" + +namespace +{ +std::map imageCategoryString = { + {faker::ImageCategory::animals, "animals"}, {faker::ImageCategory::business, "business"}, + {faker::ImageCategory::cats, "cats"}, {faker::ImageCategory::city, "city"}, + {faker::ImageCategory::food, "food"}, {faker::ImageCategory::nightlife, "nightlife"}, + {faker::ImageCategory::fashion, "fashion"}, {faker::ImageCategory::people, "people"}, + {faker::ImageCategory::nature, "nature"}, {faker::ImageCategory::sports, "sports"}, + {faker::ImageCategory::technics, "technics"}, {faker::ImageCategory::transport, "transport"}, +}; +} + +namespace faker +{ +class Image +{ +public: + /** + * @brief Generates a real image url with `https://loremflickr.com/`. + * + * @param width The width of the image. Defaults to `640`. + * @param height The height of the image. Defaults to `480`. + * @param category The optional category of generated real image. + * + * @returns Random real image url from external service. + * + * @code + * Internet::imageUrl() // "https://loremflickr.com/640/480" + * Internet::imageUrl(800, 600) // "https://loremflickr.com/800/600" + * Internet::imageUrl(800, 600, ImageCategory::animals) // "https://loremflickr.com/800/600/animals" + * @endcode + */ + static std::string imageUrl(unsigned width = 640, unsigned height = 480, + std::optional category = std::nullopt); + + /** + * @brief Generates a random avatar from GitHub. + * + * @returns Url to github avatar. + * + * @code + * Internet::githubAvatarUrl() // "https://avatars.githubusercontent.com/u/9716558" + * @endcode + */ + static std::string githubAvatarUrl(); + + /** + * @brief Generates a random image dimensions. + * + * @returns Random image dimensions. + * + * @code + * Internet::dimensions() // "1920x1080" + * @endcode + */ + static std::string dimensions(); +}; +} \ No newline at end of file diff --git a/include/faker-cxx/Internet.h b/include/faker-cxx/Internet.h index cee447e2..cbe08dcf 100644 --- a/include/faker-cxx/Internet.h +++ b/include/faker-cxx/Internet.h @@ -96,32 +96,6 @@ class Internet */ static std::string password(int length = 15); - /** - * @brief Generates a real image url with `https://source.unsplash.com/`. - * - * @param width The width of the image. Defaults to `640`. - * @param height The height of the image. Defaults to `480`. - * - * @returns Random real image url from external service. - * - * @code - * Internet::imageUrl() // "https://source.unsplash.com/640x480" - * Internet::imageUrl(800, 600) // "https://source.unsplash.com/800x600" - * @endcode - */ - static std::string imageUrl(unsigned width = 640, unsigned height = 480); - - /** - * @brief Generates a random avatar from GitHub. - * - * @returns Url to github avatar. - * - * @code - * Internet::githubAvatarUrl() // "https://avatars.githubusercontent.com/u/9716558" - * @endcode - */ - static std::string githubAvatarUrl(); - /** * @brief Returns a random emoji. * diff --git a/include/faker-cxx/types/ImageCategory.h b/include/faker-cxx/types/ImageCategory.h new file mode 100644 index 00000000..db425c35 --- /dev/null +++ b/include/faker-cxx/types/ImageCategory.h @@ -0,0 +1,20 @@ +#pragma once + +namespace faker +{ +enum class ImageCategory +{ + animals, + business, + cats, + city, + food, + nightlife, + fashion, + people, + nature, + sports, + technics, + transport +}; +} \ No newline at end of file diff --git a/src/modules/image/Image.cpp b/src/modules/image/Image.cpp new file mode 100644 index 00000000..2383d8d8 --- /dev/null +++ b/src/modules/image/Image.cpp @@ -0,0 +1,26 @@ +#include "faker-cxx/Image.h" + +#include "faker-cxx/Number.h" +#include "fmt/format.h" + +namespace faker +{ + +std::string Image::imageUrl(unsigned int width, unsigned int height, std::optional category) +{ + const std::string image_category = + category.has_value() ? fmt::format("/{}", imageCategoryString.at(category.value())) : ""; + return fmt::format("https://loremflickr.com/{}/{}{}", width, height, image_category); +} + +std::string Image::githubAvatarUrl() +{ + return fmt::format("https://avatars.githubusercontent.com/u/{}", Number::integer(100000000)); +} + +std::string Image::dimensions() +{ + return fmt::format("{}x{}", Number::integer(1, 32720), Number::integer(1, 17280)); +} + +} diff --git a/src/modules/image/ImageTest.cpp b/src/modules/image/ImageTest.cpp new file mode 100644 index 00000000..5442736d --- /dev/null +++ b/src/modules/image/ImageTest.cpp @@ -0,0 +1,68 @@ +#include "faker-cxx/Image.h" + +#include + +#include "gtest/gtest.h" + +#include "../src/common/StringHelper.h" + +using namespace ::testing; +using namespace faker; + +class ImageTest : public Test +{ +public: +}; + +TEST_F(ImageTest, shouldGenerateImageUrlDefault) +{ + const auto imageUrl = Image::imageUrl(); + + ASSERT_EQ(imageUrl, "https://loremflickr.com/640/480"); +} + +TEST_F(ImageTest, shouldGenerateImageUrl) +{ + const auto width = 800; + const auto height = 600; + + const auto imageUrl = Image::imageUrl(width, height); + + ASSERT_EQ(imageUrl, "https://loremflickr.com/800/600"); +} + +TEST_F(ImageTest, shouldGenerateImageUrlCategory) +{ + const auto width = 800; + const auto height = 600; + const ImageCategory category = ImageCategory::fashion; + + const auto imageUrl = Image::imageUrl(width, height, category); + + ASSERT_EQ(imageUrl, "https://loremflickr.com/800/600/fashion"); +} + +TEST_F(ImageTest, shouldGenerateGithubAvatarUrl) +{ + const auto githubAvatarUrl = Image::githubAvatarUrl(); + + const std::string expectedGithubAvatarPrefix = "https://avatars.githubusercontent.com/u/"; + + const auto userNumber = std::stoi(githubAvatarUrl.substr(expectedGithubAvatarPrefix.size())); + + ASSERT_TRUE(githubAvatarUrl.starts_with(expectedGithubAvatarPrefix)); + ASSERT_TRUE(userNumber >= 0 && userNumber <= 100000000); +} + +TEST_F(ImageTest, shouldGenerateDimensions) +{ + const auto dimensions = Image::dimensions(); + + std::vector split_dimensions = StringHelper::split(dimensions, "x"); + + auto width_dimension = std::stoi(split_dimensions[0]); + ASSERT_TRUE(width_dimension >= 1 && width_dimension <= 32720); + + auto height_dimension = std::stoi(split_dimensions[1]); + ASSERT_TRUE(height_dimension >= 1 && height_dimension <= 17280); +} \ No newline at end of file diff --git a/src/modules/internet/Internet.cpp b/src/modules/internet/Internet.cpp index cbdf7d77..f5689c53 100644 --- a/src/modules/internet/Internet.cpp +++ b/src/modules/internet/Internet.cpp @@ -104,16 +104,6 @@ std::string Internet::password(int length) return password; } -std::string Internet::imageUrl(unsigned int width, unsigned int height) -{ - return fmt::format("https://source.unsplash.com/{}x{}", width, height); -} - -std::string Internet::githubAvatarUrl() -{ - return fmt::format("https://avatars.githubusercontent.com/u/{}", Number::integer(100000000)); -} - std::string Internet::emoji(std::optional type) { if (type) diff --git a/src/modules/internet/InternetTest.cpp b/src/modules/internet/InternetTest.cpp index 43ce43cc..28af5f06 100644 --- a/src/modules/internet/InternetTest.cpp +++ b/src/modules/internet/InternetTest.cpp @@ -381,28 +381,6 @@ TEST_F(InternetTest, shouldGeneratePasswordWithSpecifiedLength) { return passwordCharacters.find(passwordCharacter) != std::string::npos; })); } -TEST_F(InternetTest, shouldGenerateImageUrl) -{ - const auto width = 800; - const auto height = 600; - - const auto imageUrl = Internet::imageUrl(width, height); - - ASSERT_EQ(imageUrl, "https://source.unsplash.com/800x600"); -} - -TEST_F(InternetTest, shouldGenerateGithubAvatarUrl) -{ - const auto githubAvatarUrl = Internet::githubAvatarUrl(); - - const std::string expectedGithubAvatarPrefix = "https://avatars.githubusercontent.com/u/"; - - const auto userNumber = std::stoi(githubAvatarUrl.substr(expectedGithubAvatarPrefix.size())); - - ASSERT_TRUE(githubAvatarUrl.starts_with(expectedGithubAvatarPrefix)); - ASSERT_TRUE(userNumber >= 0 && userNumber <= 100000000); -} - TEST_F(InternetTest, shouldGenerateEmoji) { const auto generatedEmoji = Internet::emoji();