2016-10-23 01:46:48 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <type_traits>
|
2016-10-23 12:14:41 +00:00
|
|
|
#include <stdexcept>
|
2016-10-23 19:05:14 +00:00
|
|
|
#include <tuple>
|
2016-10-24 19:08:01 +00:00
|
|
|
#include <string>
|
2016-10-23 01:46:48 +00:00
|
|
|
#include "String.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
|
2016-10-24 19:34:52 +00:00
|
|
|
|
|
|
|
/* These unit tests were written using the Google Test framework,
|
|
|
|
* and check everything stated in the specification. */
|
2016-10-23 20:17:30 +00:00
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
/// Testing helper classes ///
|
|
|
|
///////////////////////////////////////////////////////////////
|
2016-10-24 19:08:01 +00:00
|
|
|
using str3 = std::tuple<std::string, std::string, std::string>;
|
2016-10-24 19:26:45 +00:00
|
|
|
class AddStringTest : public ::testing::TestWithParam<str3>
|
2016-10-23 20:17:30 +00:00
|
|
|
{};
|
|
|
|
|
2016-10-24 19:08:01 +00:00
|
|
|
using strcharstr = std::tuple<std::string, char, std::string>;
|
2016-10-24 19:26:45 +00:00
|
|
|
class AddCharStringTest : public ::testing::TestWithParam<strcharstr>
|
2016-10-23 20:17:30 +00:00
|
|
|
{};
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
class ComparableStringTest : public ::testing::TestWithParam<std::string> {};
|
|
|
|
|
|
|
|
class ResourceSharingStringTest : public ::testing::TestWithParam<std::string> {};
|
|
|
|
|
|
|
|
class StreamStringTest : public ::testing::TestWithParam<std::string>
|
2016-10-23 20:17:30 +00:00
|
|
|
{
|
2016-10-24 19:26:45 +00:00
|
|
|
public:
|
2016-10-23 20:17:30 +00:00
|
|
|
std::stringstream _stream;
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
/// Testing data ///
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
static const std::vector<str3> testvalues1 =
|
|
|
|
{
|
|
|
|
std::make_tuple("cica", "sajt", "cicasajt"),
|
|
|
|
std::make_tuple("sajtos", " cica", "sajtos cica"),
|
|
|
|
std::make_tuple("szeretem", " a sajtot", "szeretem a sajtot"),
|
|
|
|
std::make_tuple("meg ", "a cicákat", "meg a cicákat"),
|
|
|
|
std::make_tuple("ennyi már ", "elég lesz", "ennyi már elég lesz")
|
|
|
|
};
|
|
|
|
|
|
|
|
static const std::vector<strcharstr> testvalues2 =
|
|
|
|
{
|
|
|
|
std::make_tuple("cicá", 'k', "cicák"),
|
|
|
|
std::make_tuple("sajto", 'k', "sajtok"),
|
|
|
|
std::make_tuple("C++1", '1', "C++11"),
|
|
|
|
std::make_tuple("sö", 'r', "sör"),
|
|
|
|
std::make_tuple("te", 'j', "tej")
|
|
|
|
};
|
2016-10-23 01:46:48 +00:00
|
|
|
|
2016-10-24 19:08:01 +00:00
|
|
|
static const std::vector<std::string> testvalues3 =
|
|
|
|
{ "cica", "sajt", "sör", "C++11", "suchInitializerList" };
|
2016-10-23 21:48:20 +00:00
|
|
|
|
2016-10-23 20:17:30 +00:00
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
/// Tests ///
|
|
|
|
///////////////////////////////////////////////////////////////
|
2016-10-24 19:26:45 +00:00
|
|
|
// Basic tests
|
2016-10-23 01:46:48 +00:00
|
|
|
TEST(StringTest, defaultConstructible)
|
|
|
|
{
|
2016-10-23 12:14:41 +00:00
|
|
|
EXPECT_TRUE(std::is_default_constructible<String>::value);
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, constcharConstructible)
|
|
|
|
{
|
|
|
|
// is_constructible with multiple template params cannot be passed to macro,
|
|
|
|
// TODO: should open an issue at GTest's GitHub
|
|
|
|
auto value = std::is_constructible<String, const char*>::value;
|
2016-10-23 12:14:41 +00:00
|
|
|
EXPECT_TRUE(value);
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, copyConstructible)
|
|
|
|
{
|
2016-10-23 12:14:41 +00:00
|
|
|
EXPECT_TRUE(std::is_copy_constructible<String>::value);
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, copyAssignable)
|
|
|
|
{
|
2016-10-23 12:14:41 +00:00
|
|
|
EXPECT_TRUE(std::is_copy_assignable<String>::value);
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, moveConstructible)
|
|
|
|
{
|
2016-10-23 12:14:41 +00:00
|
|
|
EXPECT_TRUE(std::is_move_constructible<String>::value);
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, moveAssignable)
|
|
|
|
{
|
2016-10-23 12:14:41 +00:00
|
|
|
EXPECT_TRUE(std::is_move_assignable<String>::value);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, cStrMethodWorks)
|
|
|
|
{
|
|
|
|
String str("sajtos cica");
|
|
|
|
|
|
|
|
EXPECT_STREQ("sajtos cica", str.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, uninitializedStringcStrThrows)
|
|
|
|
{
|
|
|
|
String str;
|
|
|
|
|
|
|
|
EXPECT_THROW(str.c_str(), std::runtime_error);
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
|
|
|
|
// add operator tests
|
|
|
|
TEST_P(AddStringTest, addable)
|
2016-10-23 01:46:48 +00:00
|
|
|
{
|
2016-10-24 19:08:01 +00:00
|
|
|
String str1(std::get<0>(GetParam()).c_str());
|
|
|
|
String str2(std::get<1>(GetParam()).c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
|
2016-10-24 19:08:01 +00:00
|
|
|
EXPECT_STREQ(std::get<2>(GetParam()).c_str(), (str1+str2).c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
TEST_P(AddStringTest, plusEqualsable)
|
2016-10-23 01:46:48 +00:00
|
|
|
{
|
2016-10-24 19:08:01 +00:00
|
|
|
String str1(std::get<0>(GetParam()).c_str());
|
|
|
|
String str2(std::get<1>(GetParam()).c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
str1 += str2;
|
|
|
|
|
2016-10-24 19:08:01 +00:00
|
|
|
EXPECT_STREQ(std::get<2>(GetParam()).c_str(), str1.c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
2016-10-24 19:26:45 +00:00
|
|
|
INSTANTIATE_TEST_CASE_P(tests, AddStringTest, ::testing::ValuesIn(testvalues1));
|
2016-10-23 19:05:14 +00:00
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
TEST_P(AddCharStringTest, addCharable)
|
2016-10-23 01:46:48 +00:00
|
|
|
{
|
2016-10-24 19:08:01 +00:00
|
|
|
String str(std::get<0>(GetParam()).c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
|
2016-10-24 19:08:01 +00:00
|
|
|
EXPECT_STREQ(std::get<2>(GetParam()).c_str(), (str+std::get<1>(GetParam())).c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
TEST_P(AddCharStringTest, plusEqualsCharable)
|
2016-10-23 01:46:48 +00:00
|
|
|
{
|
2016-10-24 19:08:01 +00:00
|
|
|
String str(std::get<0>(GetParam()).c_str());
|
2016-10-23 19:05:14 +00:00
|
|
|
str+=std::get<1>(GetParam());
|
2016-10-23 01:46:48 +00:00
|
|
|
|
2016-10-24 19:08:01 +00:00
|
|
|
EXPECT_STREQ(std::get<2>(GetParam()).c_str(), str.c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
2016-10-24 19:26:45 +00:00
|
|
|
INSTANTIATE_TEST_CASE_P(tests, AddCharStringTest, ::testing::ValuesIn(testvalues2));
|
|
|
|
|
2016-10-23 19:05:14 +00:00
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
// Comparison tests
|
|
|
|
TEST_P(ComparableStringTest, comparable)
|
2016-10-23 12:14:41 +00:00
|
|
|
{
|
2016-10-24 19:08:01 +00:00
|
|
|
String str1(GetParam().c_str());
|
|
|
|
String str2(GetParam().c_str());
|
2016-10-23 12:14:41 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(str1, str2);
|
|
|
|
}
|
2016-10-24 19:26:45 +00:00
|
|
|
INSTANTIATE_TEST_CASE_P(tests, ComparableStringTest, ::testing::ValuesIn(testvalues3));
|
2016-10-23 12:14:41 +00:00
|
|
|
|
|
|
|
TEST(StringTest, uninitializedStringCompareThrows)
|
|
|
|
{
|
|
|
|
String str1;
|
|
|
|
String str2;
|
|
|
|
|
|
|
|
EXPECT_THROW(str1 == str2, std::runtime_error);
|
|
|
|
}
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
|
|
|
|
// Index operator tests
|
2016-10-23 01:46:48 +00:00
|
|
|
TEST(StringTest, indexOperatorWorks)
|
|
|
|
{
|
|
|
|
String str("cica");
|
|
|
|
char i = 'i';
|
|
|
|
|
|
|
|
EXPECT_EQ(i, str[1]);
|
|
|
|
}
|
|
|
|
|
2016-10-23 12:14:41 +00:00
|
|
|
TEST(StringTest, indexoperatorBoundCheckWorks)
|
|
|
|
{
|
|
|
|
String str("sajt");
|
|
|
|
|
|
|
|
EXPECT_THROW(str[4], std::out_of_range);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StringTest, uninitializedStringIndexingThrows)
|
|
|
|
{
|
|
|
|
String str;
|
|
|
|
|
|
|
|
EXPECT_THROW(str[0], std::runtime_error);
|
|
|
|
}
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
|
|
|
|
// COW & resource sharing tests
|
2016-10-23 12:14:41 +00:00
|
|
|
TEST(StringTest, copyOnWriteWorks)
|
|
|
|
{
|
|
|
|
String str1("cica");
|
|
|
|
String str2 = str1;
|
|
|
|
str2[0] = ' ';
|
|
|
|
|
|
|
|
EXPECT_STRNE(str1.c_str(), str2.c_str());
|
|
|
|
}
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
TEST_P(ResourceSharingStringTest, resourceSharingWorks)
|
2016-10-23 01:46:48 +00:00
|
|
|
{
|
2016-10-24 19:26:45 +00:00
|
|
|
String str1(GetParam().c_str());
|
|
|
|
String str2 = String(GetParam().c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(str1.c_str(), str2.c_str());
|
|
|
|
}
|
2016-10-26 14:37:18 +00:00
|
|
|
// this feature is not implemented yet, therefore needs no testing
|
|
|
|
//INSTANTIATE_TEST_CASE_P(tests, ResourceSharingStringTest, ::testing::ValuesIn(testvalues3));
|
2016-10-23 01:46:48 +00:00
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
|
|
|
|
// Stream tests
|
|
|
|
TEST_P(StreamStringTest, ostreamOperatorWorks)
|
2016-10-23 01:46:48 +00:00
|
|
|
{
|
2016-10-24 19:26:45 +00:00
|
|
|
String str(GetParam().c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
_stream << str;
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
EXPECT_STREQ(GetParam().c_str(), _stream.str().c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
TEST_P(StreamStringTest, istreamOperatorWorks)
|
2016-10-23 01:46:48 +00:00
|
|
|
{
|
|
|
|
String str;
|
2016-10-24 19:26:45 +00:00
|
|
|
_stream << GetParam().c_str();
|
2016-10-23 01:46:48 +00:00
|
|
|
_stream >> str;
|
|
|
|
|
2016-10-24 19:26:45 +00:00
|
|
|
EXPECT_STREQ(GetParam().c_str(), str.c_str());
|
2016-10-23 01:46:48 +00:00
|
|
|
}
|
2016-10-24 19:26:45 +00:00
|
|
|
INSTANTIATE_TEST_CASE_P(tests, StreamStringTest, ::testing::ValuesIn(testvalues3));
|
2016-10-23 01:46:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
|
|
return RUN_ALL_TESTS();
|
|
|
|
}
|