From 0f2ac0c4311e4429bfa4ede1d96ce467b5dceb5b Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Thu, 5 Jan 2023 10:37:41 +0100 Subject: Added tests --- Makefile | 10 ++++- common.mk | 13 +++++- debian/libreichwein-dev.install | 2 +- stringhelper.cpp | 66 +++++++++++++++++++++++++++++++ stringhelper.h | 17 ++++++++ stringutil.cpp | 66 ------------------------------- stringutil.h | 17 -------- tests/Makefile | 87 +++++++++++++++++++++++++++++++++++++++++ tests/test-base64.cpp | 23 +++++++++++ tests/test-file.cpp | 56 +++++++++++++++++++++++++- tests/test-mime.cpp | 23 +++++++++++ tests/test-os.cpp | 22 +++++++++++ tests/test-stringhelper.cpp | 23 +++++++++++ tests/test-tempfile.cpp | 23 +++++++++++ tests/test-url.cpp | 22 +++++++++++ 15 files changed, 381 insertions(+), 89 deletions(-) create mode 100644 stringhelper.cpp create mode 100644 stringhelper.h delete mode 100644 stringutil.cpp delete mode 100644 stringutil.h create mode 100644 tests/Makefile create mode 100644 tests/test-base64.cpp create mode 100644 tests/test-mime.cpp create mode 100644 tests/test-os.cpp create mode 100644 tests/test-stringhelper.cpp create mode 100644 tests/test-tempfile.cpp create mode 100644 tests/test-url.cpp diff --git a/Makefile b/Makefile index 18725c8..391c626 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ PROGSRC=\ file.cpp \ mime.cpp \ os.cpp \ - stringutil.cpp \ + stringhelper.cpp \ tempfile.cpp \ url.cpp @@ -50,6 +50,8 @@ install: $(PROJECTNAME).a: $(SRC:.cpp=.o) ar rcs $@ $^ +dep: $(SRC:.cpp=.d) + %.d: %.cpp $(CXX) $(CXXFLAGS) -MM -MP -MF $@ -c $< @@ -68,6 +70,9 @@ $(DISTROS): deb-src sudo pbuilder build --basetgz /var/cache/pbuilder/$@.tgz --buildresult result/$@ ../libreichwein_$(VERSION).dsc -debsign result/$@/libreichwein_$(VERSION)_amd64.changes +test: + $(MAKE) -C tests + # dependencies ADD_DEP=Makefile @@ -75,7 +80,8 @@ ADD_DEP=Makefile # misc --------------------------------------------------- clean: -rm -f *.o *.a *.d $(SONAME1) $(SONAME2) $(SONAME3) + $(MAKE) -C tests clean -.PHONY: clean all install +.PHONY: clean all install test -include $(wildcard $(SRC:.cpp=.d)) diff --git a/common.mk b/common.mk index 9ec95e7..aa68033 100644 --- a/common.mk +++ b/common.mk @@ -47,20 +47,31 @@ endif # -fprofile-instr-generate -fcoverage-mapping # gcc:--coverage -CXXFLAGS+=-Wall -I. +CXXFLAGS+=-Wall CXXFLAGS+=-Wpedantic -gdwarf-4 CXXFLAGS+=-fexceptions -Iexternal ifeq ($(CXX),clang++-11) CXXFLAGS+=-std=c++20 #-stdlib=libc++ +CXXTYPE=clang++ +LLVMPROFDATA=llvm-profdata-11 +LLVMCOV=llvm-cov-11 else ifeq ($(CXX),clang++-14) CXXFLAGS+=-std=c++20 #-stdlib=libc++ +CXXTYPE=clang++ +LLVMPROFDATA=llvm-profdata-14 +LLVMCOV=llvm-cov-14 else ifeq ($(CXX),clang++-13) CXXFLAGS+=-std=c++20 #-stdlib=libc++ +CXXTYPE=clang++ +LLVMPROFDATA=llvm-profdata-13 +LLVMCOV=llvm-cov-13 else ifeq ($(CXX),g++-11) CXXFLAGS+=-std=c++20 #-stdlib=libc++ +CXXTYPE=g++ else CXXFLAGS+=-std=c++17 +CXXTYPE=g++ endif ifeq ($(CXX),clang++-11) diff --git a/debian/libreichwein-dev.install b/debian/libreichwein-dev.install index 6cb6588..38b90c8 100644 --- a/debian/libreichwein-dev.install +++ b/debian/libreichwein-dev.install @@ -2,7 +2,7 @@ usr/include/libreichwein/base64.h usr/include/libreichwein/file.h usr/include/libreichwein/mime.h usr/include/libreichwein/os.h -usr/include/libreichwein/stringutil.h +usr/include/libreichwein/stringhelper.h usr/include/libreichwein/tempfile.h usr/include/libreichwein/url.h usr/lib/libreichwein.so diff --git a/stringhelper.cpp b/stringhelper.cpp new file mode 100644 index 0000000..af37499 --- /dev/null +++ b/stringhelper.cpp @@ -0,0 +1,66 @@ +#include "stringhelper.h" + +#include +#include + +#include + +std::string Reichwein::Stringhelper::strfmt(const char* fmt, ...) +{ + va_list args; + + va_start(args, fmt); + int size = std::vsnprintf(nullptr, 0, fmt, args); + va_end(args); + + std::string result(size, ' '); + + va_start(args, fmt); + std::vsnprintf(result.data(), size + 1, fmt, args); + va_end(args); + + return result; +} + +std::vector Reichwein::Stringhelper::split(std::string value, const std::string separators) +{ + std::vector result; + + size_t pos0 = 0; + size_t pos1 = 0; + while (pos0 < value.size()) { + pos1 = value.find_first_of(separators, pos0); + if (pos1 == std::string::npos) + pos1 = value.size(); + std::string part = value.substr(pos0, pos1 - pos0); + //std::cout << "DEBUG: " << part << std::endl << std::flush; + if (part != "") + result.push_back(part); + pos0 = value.find_first_not_of(separators, pos1); + if (pos0 == std::string::npos) + pos0 = value.size(); + } + + return result; +} + +std::string Reichwein::Stringhelper::join(std::vector vs, std::string separator) +{ + std::string s; + for (const auto& line : vs) { + if (s.size() > 0) + s += separator; + s += line; + } + + return s; +} + +bool Reichwein::Stringhelper::startsWithAnyOfLower(const std::string &s, const std::vector &list) { + for (const std::string& element : list) { + if (boost::algorithm::starts_with(boost::algorithm::to_lower_copy(s), boost::algorithm::to_lower_copy(element))) + return true; + } + return false; +} + diff --git a/stringhelper.h b/stringhelper.h new file mode 100644 index 0000000..7b27a02 --- /dev/null +++ b/stringhelper.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +#define EXPORT __attribute__((visibility("default"))) + +namespace Reichwein::Stringhelper { + +[[deprecated("Better use libfmt or std::format[C++20]")]] +EXPORT std::string strfmt(const char* fmt, ...); + +EXPORT std::vector split(std::string value, const std::string separators = "\r\n "); +EXPORT std::string join(std::vector vs, std::string separator = "\n"); +EXPORT bool startsWithAnyOfLower(const std::string &s, const std::vector &list); + +} // namespace diff --git a/stringutil.cpp b/stringutil.cpp deleted file mode 100644 index 6eb2899..0000000 --- a/stringutil.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "stringutil.h" - -#include -#include - -#include - -std::string Reichwein::Stringutil::strfmt(const char* fmt, ...) -{ - va_list args; - - va_start(args, fmt); - int size = std::vsnprintf(nullptr, 0, fmt, args); - va_end(args); - - std::string result(size, ' '); - - va_start(args, fmt); - std::vsnprintf(result.data(), size + 1, fmt, args); - va_end(args); - - return result; -} - -std::vector Reichwein::Stringutil::split(std::string value, const std::string separators) -{ - std::vector result; - - size_t pos0 = 0; - size_t pos1 = 0; - while (pos0 < value.size()) { - pos1 = value.find_first_of(separators, pos0); - if (pos1 == std::string::npos) - pos1 = value.size(); - std::string part = value.substr(pos0, pos1 - pos0); - //std::cout << "DEBUG: " << part << std::endl << std::flush; - if (part != "") - result.push_back(part); - pos0 = value.find_first_not_of(separators, pos1); - if (pos0 == std::string::npos) - pos0 = value.size(); - } - - return result; -} - -std::string Reichwein::Stringutil::join(std::vector vs, std::string separator) -{ - std::string s; - for (const auto& line : vs) { - if (s.size() > 0) - s += separator; - s += line; - } - - return s; -} - -bool Reichwein::Stringutil::startsWithAnyOfLower(const std::string &s, const std::vector &list) { - for (const std::string& element : list) { - if (boost::algorithm::starts_with(boost::algorithm::to_lower_copy(s), boost::algorithm::to_lower_copy(element))) - return true; - } - return false; -} - diff --git a/stringutil.h b/stringutil.h deleted file mode 100644 index 510d2fd..0000000 --- a/stringutil.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -#define EXPORT __attribute__((visibility("default"))) - -namespace Reichwein::Stringutil { - -[[deprecated("Better use libfmt or std::format[C++20]")]] -EXPORT std::string strfmt(const char* fmt, ...); - -EXPORT std::vector split(std::string value, const std::string separators = "\r\n "); -EXPORT std::string join(std::vector vs, std::string separator = "\n"); -EXPORT bool startsWithAnyOfLower(const std::string &s, const std::vector &list); - -} // namespace diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..44f50dc --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,87 @@ +CXXFLAGS=-g -O0 + +include ../common.mk + +ifeq ($(CXXTYPE),clang++) +CXXFLAGS+=-fprofile-instr-generate -fcoverage-mapping +LDFLAGS+=-fprofile-instr-generate -fcoverage-mapping +else +# GCC +CXXFLAGS+=--coverage +LDFLAGS+=--coverage +endif + +UNITS=\ + base64.cpp \ + file.cpp \ + mime.cpp \ + os.cpp \ + stringhelper.cpp \ + tempfile.cpp \ + url.cpp + +UNITTESTS=\ + test-base64.cpp \ + test-file.cpp \ + test-mime.cpp \ + test-os.cpp \ + test-stringhelper.cpp \ + test-tempfile.cpp \ + test-url.cpp + +CXXFLAGS+=\ + -I/usr/src/googletest/googletest/include \ + -I/usr/src/googletest/googlemock/include \ + -I/usr/src/googletest/googletest \ + -I/usr/src/googletest/googlemock \ + -I.. + +test: unittests + # https://clang.llvm.org/docs/SourceBasedCodeCoverage.html +ifeq ($(CXXTYPE),clang++) + LLVM_PROFILE_FILE="unittests.profraw" ./unittests + $(LLVMPROFDATA) merge -sparse unittests.profraw -o unittests.profdata + $(LLVMCOV) report --ignore-filename-regex='google' --ignore-filename-regex='test-' --ignore-filename-regex='Magick' --show-region-summary=0 -instr-profile unittests.profdata unittests +else + ./unittests + gcovr -r .. +endif + +coverage: + $(LLVMCOV) show -instr-profile unittests.profdata $(UNITS:.cpp=.o) + +unittests: libgmock.a $(UNITTESTS:.cpp=.o) $(UNITS:.cpp=.o) + $(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@ + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +base64.o: ../base64.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +file.o: ../file.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +mime.o: ../mime.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +os.o: ../os.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +stringhelper.o: ../stringhelper.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +tempfile.o: ../tempfile.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +url.o: ../url.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +libgmock.a: + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googletest/src/gtest-all.cc + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googlemock/src/gmock-all.cc + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googlemock/src/gmock_main.cc + ar -rv libgmock.a gmock-all.o gtest-all.o gmock_main.o + +clean: + -rm -f *.o *.a unittests *.gcda *.gcno *.profraw *.profdata *.gcov diff --git a/tests/test-base64.cpp b/tests/test-base64.cpp new file mode 100644 index 0000000..03648d4 --- /dev/null +++ b/tests/test-base64.cpp @@ -0,0 +1,23 @@ +#include + +#include "file.h" + +class Base64Test: public ::testing::Test +{ +protected: + Base64Test(){ + } + + ~Base64Test() override{ + } + + void SetUp() override + { + } + + void TearDown() override + { + } + +}; + diff --git a/tests/test-file.cpp b/tests/test-file.cpp index 13d0ded..7c3b752 100644 --- a/tests/test-file.cpp +++ b/tests/test-file.cpp @@ -1,3 +1,55 @@ -getFile +#include -getFile /proc +#include "file.h" + +#include +#include +#include + +namespace fs = std::filesystem; + +namespace { + const fs::path testFilename{"testfile.txt"}; +} // namespace + +class FileTest: public ::testing::Test +{ +protected: + FileTest(){ + } + + ~FileTest() override{ + } + + void SetUp() override + { + std::error_code ec; + fs::remove(testFilename, ec); + } + + void TearDown() override + { + std::error_code ec; + fs::remove(testFilename, ec); + } + +}; + +TEST_F(FileTest, getFile) +{ + { + std::ofstream of(testFilename, std::ios::binary); + of << "abc"; + } + + std::string s{Reichwein::File::getFile(testFilename)}; + + EXPECT_EQ(s, "abc"); +} + +TEST_F(FileTest, getFile_proc) +{ + std::string s{Reichwein::File::getFile("/proc/cmdline")}; + + EXPECT_GT(s.size(), 0); +} diff --git a/tests/test-mime.cpp b/tests/test-mime.cpp new file mode 100644 index 0000000..2d28a36 --- /dev/null +++ b/tests/test-mime.cpp @@ -0,0 +1,23 @@ +#include + +#include "file.h" + +class MimeTest: public ::testing::Test +{ +protected: + MimeTest(){ + } + + ~MimeTest() override{ + } + + void SetUp() override + { + } + + void TearDown() override + { + } + +}; + diff --git a/tests/test-os.cpp b/tests/test-os.cpp new file mode 100644 index 0000000..6177bfa --- /dev/null +++ b/tests/test-os.cpp @@ -0,0 +1,22 @@ +#include + +#include "file.h" + +class OsTest: public ::testing::Test +{ +protected: + OsTest(){ + } + + ~OsTest() override{ + } + + void SetUp() override + { + } + + void TearDown() override + { + } + +}; diff --git a/tests/test-stringhelper.cpp b/tests/test-stringhelper.cpp new file mode 100644 index 0000000..3ece784 --- /dev/null +++ b/tests/test-stringhelper.cpp @@ -0,0 +1,23 @@ +#include + +#include "file.h" + +class StringhelperTest: public ::testing::Test +{ +protected: + StringhelperTest(){ + } + + ~StringhelperTest() override{ + } + + void SetUp() override + { + } + + void TearDown() override + { + } + +}; + diff --git a/tests/test-tempfile.cpp b/tests/test-tempfile.cpp new file mode 100644 index 0000000..b9bef05 --- /dev/null +++ b/tests/test-tempfile.cpp @@ -0,0 +1,23 @@ +#include + +#include "file.h" + +class TempfileTest: public ::testing::Test +{ +protected: + TempfileTest(){ + } + + ~TempfileTest() override{ + } + + void SetUp() override + { + } + + void TearDown() override + { + } + +}; + diff --git a/tests/test-url.cpp b/tests/test-url.cpp new file mode 100644 index 0000000..2f5075a --- /dev/null +++ b/tests/test-url.cpp @@ -0,0 +1,22 @@ +#include + +#include "file.h" + +class URLTest: public ::testing::Test +{ +protected: + URLTest(){ + } + + ~URLTest() override{ + } + + void SetUp() override + { + } + + void TearDown() override + { + } + +}; -- cgit v1.2.3