#include #include #include #include #include #include #include "String.h" #include /* These unit tests were written using the Google Test framework, * and check everything stated in the specification. Note that * these tests are only used in case GTest is present on the system.*/ /////////////////////////////////////////////////////////////// /// Testing helper classes /// /////////////////////////////////////////////////////////////// using str3 = std::tuple; class AddStringTest : public ::testing::TestWithParam {}; using strcharstr = std::tuple; class AddCharStringTest : public ::testing::TestWithParam {}; class ComparableStringTest : public ::testing::TestWithParam {}; class ResourceSharingStringTest : public ::testing::TestWithParam {}; class StreamStringTest : public ::testing::TestWithParam { public: std::stringstream _stream; }; /////////////////////////////////////////////////////////////// /// Testing data /// /////////////////////////////////////////////////////////////// static const std::vector 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 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") }; static const std::vector testvalues3 = { "cica", "sajt", "sör", "C++11", "suchInitializerList" }; /////////////////////////////////////////////////////////////// /// Tests /// /////////////////////////////////////////////////////////////// // Basic tests TEST(StringTest, defaultConstructible) { EXPECT_TRUE(std::is_default_constructible::value); } 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::value; EXPECT_TRUE(value); } TEST(StringTest, copyConstructible) { EXPECT_TRUE(std::is_copy_constructible::value); } TEST(StringTest, copyAssignable) { EXPECT_TRUE(std::is_copy_assignable::value); } TEST(StringTest, moveConstructible) { EXPECT_TRUE(std::is_move_constructible::value); } TEST(StringTest, moveAssignable) { EXPECT_TRUE(std::is_move_assignable::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); } // add operator tests TEST_P(AddStringTest, addable) { String str1(std::get<0>(GetParam()).c_str()); String str2(std::get<1>(GetParam()).c_str()); EXPECT_STREQ(std::get<2>(GetParam()).c_str(), (str1+str2).c_str()); } TEST_P(AddStringTest, plusEqualsable) { String str1(std::get<0>(GetParam()).c_str()); String str2(std::get<1>(GetParam()).c_str()); str1 += str2; EXPECT_STREQ(std::get<2>(GetParam()).c_str(), str1.c_str()); } INSTANTIATE_TEST_CASE_P(tests, AddStringTest, ::testing::ValuesIn(testvalues1)); TEST_P(AddCharStringTest, addCharable) { String str(std::get<0>(GetParam()).c_str()); EXPECT_STREQ(std::get<2>(GetParam()).c_str(), (str+std::get<1>(GetParam())).c_str()); } TEST_P(AddCharStringTest, plusEqualsCharable) { String str(std::get<0>(GetParam()).c_str()); str+=std::get<1>(GetParam()); EXPECT_STREQ(std::get<2>(GetParam()).c_str(), str.c_str()); } INSTANTIATE_TEST_CASE_P(tests, AddCharStringTest, ::testing::ValuesIn(testvalues2)); // Comparison tests TEST_P(ComparableStringTest, comparable) { String str1(GetParam().c_str()); String str2(GetParam().c_str()); EXPECT_EQ(str1, str2); } INSTANTIATE_TEST_CASE_P(tests, ComparableStringTest, ::testing::ValuesIn(testvalues3)); TEST(StringTest, uninitializedStringCompareThrows) { String str1; String str2; EXPECT_THROW(str1 == str2, std::runtime_error); } // Index operator tests TEST(StringTest, indexOperatorWorks) { String str("cica"); char i = 'i'; EXPECT_EQ(i, str[1]); } TEST(StringTest, indexOperatorWorksWhenUsedWithOtherIndexOperators) { String sajtok = "sajtok"; sajtok[5] = sajtok[0]; EXPECT_STREQ("sajtos", sajtok.c_str()); } 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); } // COW & resource sharing tests TEST(StringTest, copyOnWriteWorks) { String str1("cica"); String str2 = str1; str2[0] = ' '; EXPECT_STRNE(str1.c_str(), str2.c_str()); } TEST_P(ResourceSharingStringTest, resourceSharingWorks) { String str1(GetParam().c_str()); String str2 = String(GetParam().c_str()); EXPECT_EQ(str1.c_str(), str2.c_str()); } // this feature is not implemented yet, therefore needs no testing //INSTANTIATE_TEST_CASE_P(tests, ResourceSharingStringTest, ::testing::ValuesIn(testvalues3)); // Stream tests TEST_P(StreamStringTest, ostreamOperatorWorks) { String str(GetParam().c_str()); _stream << str; EXPECT_STREQ(GetParam().c_str(), _stream.str().c_str()); } TEST_P(StreamStringTest, istreamOperatorWorks) { String str; _stream << GetParam().c_str(); _stream >> str; EXPECT_STREQ(GetParam().c_str(), str.c_str()); } INSTANTIATE_TEST_CASE_P(tests, StreamStringTest, ::testing::ValuesIn(testvalues3)); int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }