Add WIP UnitTests for TSLQueue

This commit is contained in:
Stephen Seo 2019-10-24 20:25:41 +09:00
parent aa132fbf12
commit 78862dc29d
3 changed files with 196 additions and 18 deletions

View file

@ -56,6 +56,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug")
set(UDPC_UnitTest_SOURCES
src/test/UDPC_UnitTest.cpp
src/test/TestTSQueue.cpp
src/test/TestTSLQueue.cpp
src/test/TestUDPC.cpp
)
add_executable(UnitTest ${UDPC_UnitTest_SOURCES})

View file

@ -42,7 +42,7 @@ class TSLQueue {
TSLQIterWrapper(
std::conditional_t<isConst, const std::list<T>, std::list<T>> *container,
std::weak_ptr<void> iterValid,
std::shared_ptr<void> iterWrapperCount
std::shared_ptr<char> iterWrapperCount
);
bool isValid() const;
@ -54,6 +54,8 @@ class TSLQueue {
TSLQIterWrapper<isConst, isRev>& operator++();
TSLQIterWrapper<isConst, isRev>& operator--();
bool set(T &&newValue);
private:
std::conditional_t<isConst, const std::list<T>, std::list<T>>
*containerPtr;
@ -67,7 +69,7 @@ class TSLQueue {
iter;
std::weak_ptr<void> iterValid;
std::shared_ptr<void> iterWrapperCount;
std::shared_ptr<char> iterWrapperCount;
};
TSLQIterWrapper<false, false> iter();
@ -76,8 +78,8 @@ class TSLQueue {
TSLQIterWrapper<true, true> criter();
private:
std::shared_ptr<void> iterValid;
std::shared_ptr<void> iterWrapperCount;
std::shared_ptr<char> iterValid;
std::shared_ptr<char> iterWrapperCount;
std::mutex mutex;
std::list<T> container;
};
@ -86,8 +88,8 @@ class TSLQueue {
template <typename T>
TSLQueue<T>::TSLQueue() :
iterValid(std::make_shared<void>()),
iterWrapperCount(std::make_shared<void>())
iterValid(std::make_shared<char>()),
iterWrapperCount(std::make_shared<char>())
{
}
@ -97,8 +99,8 @@ TSLQueue<T>::~TSLQueue() {
template <typename T>
TSLQueue<T>::TSLQueue(TSLQueue &&other) :
iterValid(std::make_shared<void>()),
iterWrapperCount(std::make_shared<void>())
iterValid(std::make_shared<char>()),
iterWrapperCount(std::make_shared<char>())
{
std::lock_guard lock(other.mutex);
container = std::move(other.container);
@ -169,8 +171,8 @@ bool TSLQueue<T>::pop() {
return false;
} else {
container.pop_front();
iterValid = std::make_shared<void>();
iterWrapperCount = std::make_shared<void>();
iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<char>();
return true;
}
}
@ -185,8 +187,8 @@ std::optional<T> TSLQueue<T>::top_and_pop() {
if(!container.empty()) {
ret = container.front();
container.pop_front();
iterValid = std::make_shared<void>();
iterWrapperCount = std::make_shared<void>();
iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<char>();
}
return ret;
}
@ -205,8 +207,8 @@ std::optional<T> TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
} else {
ret = container.front();
container.pop_front();
iterValid = std::make_shared<void>();
iterWrapperCount = std::make_shared<void>();
iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<char>();
if(isEmpty) {
*isEmpty = container.empty();
}
@ -221,8 +223,8 @@ void TSLQueue<T>::clear() {
}
std::lock_guard lock(mutex);
container.clear();
iterValid = std::make_shared<void>();
iterWrapperCount = std::make_shared<void>();
iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<char>();
}
template <typename T>
@ -239,7 +241,7 @@ template <bool isConst, bool isRev>
TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::TSLQIterWrapper(
std::conditional_t<isConst, const std::list<T>, std::list<T>> *container,
std::weak_ptr<void> iterValid,
std::shared_ptr<void> iterWrapperCount) :
std::shared_ptr<char> iterWrapperCount) :
containerPtr(container),
iterValid(iterValid),
iterWrapperCount(iterWrapperCount) {
@ -277,6 +279,9 @@ bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::next() {
return false;
} else {
++iter;
if(containerPtr->rend() == iter) {
return false;
}
}
} else {
if(containerPtr->end() == iter) {
@ -284,6 +289,9 @@ bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::next() {
return false;
} else {
++iter;
if(containerPtr->end() == iter) {
return false;
}
}
}
@ -332,7 +340,6 @@ std::optional<T> TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::current() {
}
}
}
return *iter;
}
@ -350,23 +357,41 @@ typename TSLQueue<T>::template TSLQIterWrapper<isConst, isRev>& TSLQueue<T>::TSL
return *this;
}
template <typename T>
template <bool isConst, bool isRev>
bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::set(T &&newValue) {
if constexpr(isConst) {
return false;
} else {
if(!isValid()) {
return false;
}
*iter = std::forward<T>(newValue);
return true;
}
}
template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<false, false> TSLQueue<T>::iter() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<false, false>(&container, iterValid, iterWrapperCount);
}
template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<false, true> TSLQueue<T>::riter() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<false, true>(&container, iterValid, iterWrapperCount);
}
template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<true, false> TSLQueue<T>::citer() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<true, false>(&container, iterValid, iterWrapperCount);
}
template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<true, true> TSLQueue<T>::criter() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<true, true>(&container, iterValid, iterWrapperCount);
}

View file

@ -0,0 +1,152 @@
#include <gtest/gtest.h>
#include <iostream>
#include "TSLQueue.hpp"
TEST(TSLQueue, Usage) {
TSLQueue<int> q;
bool isEmpty;
std::optional<int> opt;
// init
EXPECT_FALSE(q.pop());
opt = q.top_and_pop();
EXPECT_FALSE(opt.has_value());
opt = q.top_and_pop_and_empty(&isEmpty);
EXPECT_FALSE(opt.has_value());
EXPECT_TRUE(isEmpty);
EXPECT_TRUE(q.empty());
// push 1, 2, 3
q.push(1);
EXPECT_FALSE(q.empty());
opt = q.top();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 1);
q.push_nb(2);
EXPECT_FALSE(q.empty());
opt = q.top_nb();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 1);
q.push(3);
EXPECT_FALSE(q.empty());
opt = q.top();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 1);
// iterators
{
auto citer = q.citer();
opt = citer.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 1);
EXPECT_FALSE(citer.set(111));
EXPECT_TRUE(citer.next());
opt = citer.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 2);
EXPECT_TRUE(citer.next());
opt = citer.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 3);
EXPECT_FALSE(citer.next());
opt = citer.current();
EXPECT_FALSE(opt.has_value());
EXPECT_TRUE(citer.isValid());
EXPECT_FALSE(citer.next());
EXPECT_FALSE(citer.isValid());
}
{
auto criter = q.criter();
opt = criter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 3);
EXPECT_FALSE(criter.set(333));
EXPECT_TRUE(criter.next());
opt = criter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 2);
EXPECT_TRUE(criter.next());
opt = criter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 1);
EXPECT_FALSE(criter.next());
opt = criter.current();
EXPECT_FALSE(opt.has_value());
}
{
// values changed to 10, 20, 30
auto iter = q.iter();
opt = iter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 1);
EXPECT_TRUE(iter.set(10));
opt = iter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 10);
EXPECT_TRUE(iter.next());
opt = iter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 2);
EXPECT_TRUE(iter.set(20));
opt = iter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 20);
EXPECT_TRUE(iter.next());
opt = iter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 3);
EXPECT_TRUE(iter.set(30));
opt = iter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 30);
EXPECT_FALSE(iter.next());
opt = iter.current();
EXPECT_FALSE(opt.has_value());
}
{
// values changed to 1, 2, 3
auto riter = q.riter();
opt = riter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 30);
EXPECT_TRUE(riter.set(3));
opt = riter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 3);
EXPECT_TRUE(riter.next());
opt = riter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 20);
EXPECT_TRUE(riter.set(2));
opt = riter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 2);
EXPECT_TRUE(riter.next());
opt = riter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 10);
EXPECT_TRUE(riter.set(1));
opt = riter.current();
ASSERT_TRUE(opt.has_value());
EXPECT_EQ(opt.value(), 1);
}
}