Skip to content

Commit

Permalink
test: increase test coverage for word module (#833)
Browse files Browse the repository at this point in the history
* Mv sortedSizeArrayElement definition to word.h, and test in word_test

* Include algorithm header in word.h

* Add word data tests

* Specify namespace and include algorithm header

* Add faker::word::cstd namespace to word_data_test

* Change namespace
  • Loading branch information
jackhwalters authored Jul 28, 2024
1 parent 5fbde12 commit 3d0357a
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 40 deletions.
38 changes: 38 additions & 0 deletions include/faker-cxx/word.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#pragma once

#include <algorithm>
#include <optional>
#include <string>
#include <string_view>
#include "faker-cxx/export.h"

#include "faker-cxx/helper.h"

namespace faker::word
{
/**
Expand Down Expand Up @@ -140,4 +143,39 @@ FAKER_CXX_EXPORT std::string_view preposition(std::optional<unsigned> length = s
* @endcode
*/
FAKER_CXX_EXPORT std::string_view verb(std::optional<unsigned> length = std::nullopt);

template <typename It>
auto sortedSizeArrayElement(std::optional<unsigned int> length, It start, It end) -> decltype(*std::declval<It>())
{
if (!length)
{
return helper::arrayElement(start, end);
}

size_t length_64 = *length;
auto lower_it = ::std::lower_bound(start, end, length_64,
[](const auto& lhs, const auto& value) { return lhs.size() < value; });

if (lower_it == end)
{
return helper::arrayElement(start, end);
}

if (lower_it->size() != length)
{
return helper::arrayElement(start, end);
}

auto upper_it = lower_it;

for (; upper_it != end; upper_it++)
{
if (upper_it->size() != lower_it->size())
{
break;
}
}

return helper::arrayElement(lower_it, upper_it);
}
}
41 changes: 1 addition & 40 deletions src/modules/word.cpp
Original file line number Diff line number Diff line change
@@ -1,52 +1,13 @@
#include "faker-cxx/word.h"

#include <algorithm>
#include <array>
#include <optional>
#include <string>
#include <string_view>

#include "faker-cxx/helper.h"
#include "faker-cxx/word.h"
#include "word_data.h"

namespace faker::word
{
template <typename It>
auto sortedSizeArrayElement(std::optional<unsigned int> length, It start, It end) -> decltype(*std::declval<It>())
{
if (!length)
{
return helper::arrayElement(start, end);
}

size_t length_64 = *length;
auto lower_it = ::std::lower_bound(start, end, length_64,
[](const auto& lhs, const auto& value) { return lhs.size() < value; });

if (lower_it == end)
{
return helper::arrayElement(start, end);
}

if (lower_it->size() != length)
{
return helper::arrayElement(start, end);
}

auto upper_it = lower_it;

for (; upper_it != end; upper_it++)
{
if (upper_it->size() != lower_it->size())
{

break;
}
}

return helper::arrayElement(lower_it, upper_it);
}

std::string_view sample(std::optional<unsigned int> length)
{
return sortedSizeArrayElement(length, _allWords.cbegin(), _allWords.cend());
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ set(FAKER_UT_SOURCES
modules/video_game_test.cpp
modules/weather_test.cpp
modules/word_test.cpp
modules/word_data_test.cpp
)

add_executable(${PROJECT_NAME} ${FAKER_UT_SOURCES})
Expand Down
120 changes: 120 additions & 0 deletions tests/modules/word_data_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#include "gtest/gtest.h"
#include <algorithm>
#include <iterator>
#include <vector>

#include "word_data.h"

using namespace faker::word;
using namespace faker;
using namespace ::testing;

class WordDataTest : public Test
{
public:
};

TEST_F(WordDataTest, shouldIncrementDefault)
{
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin();
auto next_it = next(it);
ASSERT_TRUE(*next_it == 2);
}

TEST_F(WordDataTest, shouldIncrementByN)
{
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin();
auto next_it = next(it, 3);
ASSERT_TRUE(*next_it == 4);
}

TEST_F(WordDataTest, shouldCalculateDistance)
{
std::vector<int> vec = {1, 2, 3, 4, 5};
auto start = vec.begin();
auto end = vec.end();
auto calc_distance = distance(start, end);
ASSERT_TRUE(calc_distance == vec.size());
}

TEST_F(WordDataTest, shouldSwapAdjacentElements)
{
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it1 = vec.begin();
auto it2 = vec.begin() + 1;
iter_swap(it1, it2);
ASSERT_TRUE(*it1 == 2);
ASSERT_TRUE(*it2 == 1);
}

TEST_F(WordDataTest, shouldSwapSameElement)
{
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it1 = vec.begin();
iter_swap(it1, it1);
ASSERT_TRUE(*it1 == 1);
}

TEST_F(WordDataTest, shouldSwapDifferentContainers)
{
std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int> vec2 = {6, 7, 8, 9, 10};
auto it1 = vec.begin();
auto it2 = vec2.begin();
iter_swap(it1, it2);
ASSERT_TRUE(*it1 == 6);
ASSERT_TRUE(*it2 == 1);
}

TEST_F(WordDataTest, shouldPartitionEvenOdd)
{
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto it = cstd::partition(vec.begin(), vec.end(), [](int n) { return n % 2 == 0; });
ASSERT_TRUE(std::all_of(vec.begin(), it, [](int n) { return n % 2 == 0; }));
ASSERT_TRUE(std::all_of(it, vec.end(), [](int n) { return n % 2 != 0; }));
}

TEST_F(WordDataTest, shouldPartitionGreaterThanFive)
{
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto it = cstd::partition(vec.begin(), vec.end(), [](int n) { return n > 5; });
ASSERT_TRUE(std::all_of(vec.begin(), it, [](int n) { return n > 5; }));
ASSERT_TRUE(std::all_of(it, vec.end(), [](int n) { return n <= 5; }));
}

TEST_F(WordDataTest, shouldSortAscending)
{
std::vector<int> vec = {10, 7, 8, 9, 1, 5};
quick_sort(vec.begin(), vec.end());
ASSERT_TRUE(std::is_sorted(vec.begin(), vec.end()));
}

TEST_F(WordDataTest, shouldSortDescending)
{
std::vector<int> vec = {10, 7, 8, 9, 1, 5};
quick_sort(vec.begin(), vec.end(), std::greater<>());
ASSERT_TRUE(std::is_sorted(vec.begin(), vec.end(), std::greater<>()));
}

TEST_F(WordDataTest, shouldSortSingleElement)
{
std::vector<int> single_elem_vec = {1};
quick_sort(single_elem_vec.begin(), single_elem_vec.end());
ASSERT_TRUE(std::is_sorted(single_elem_vec.begin(), single_elem_vec.end()));
}

TEST_F(WordDataTest, shouldSortAlreadySorted)
{
std::vector<int> sorted_vec = {1, 2, 3, 4, 5};
quick_sort(sorted_vec.begin(), sorted_vec.end());
ASSERT_TRUE(std::is_sorted(sorted_vec.begin(), sorted_vec.end()));
}

TEST_F(WordDataTest, shouldSortReverseSorted)
{
std::vector<int> reverse_sorted_vec = {5, 4, 3, 2, 1};
quick_sort(reverse_sorted_vec.begin(), reverse_sorted_vec.end());
ASSERT_TRUE(std::is_sorted(reverse_sorted_vec.begin(), reverse_sorted_vec.end()));
}
10 changes: 10 additions & 0 deletions tests/modules/word_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,14 @@ TEST_F(WordTest, shouldGenerateLargeNumberOfWords)
for (const auto& word : separatedWords) {
ASSERT_TRUE(std::ranges::find(_allWords, word) != _allWords.end());
}
}

TEST_F(WordTest, returnsRandomElementWhenNoLengthMatch)
{
std::vector<std::string> words = {"one", "three", "five"};
std::optional<unsigned int> length = 6;

auto result = sortedSizeArrayElement(length, words.begin(), words.end());

ASSERT_TRUE(result == "one" || result == "three" || result == "five");
}

0 comments on commit 3d0357a

Please sign in to comment.