src: Add tests for ImmutableString and StringRef

This commit is contained in:
Tatsuhiro Tsujikawa 2016-01-17 16:32:55 +09:00
parent 7b2d4b6ae6
commit 39c0a71065
5 changed files with 215 additions and 5 deletions

View File

@ -174,7 +174,8 @@ nghttpx_unittest_SOURCES = shrpx-unittest.cc \
nghttp2_gzip_test.c nghttp2_gzip_test.h \ nghttp2_gzip_test.c nghttp2_gzip_test.h \
nghttp2_gzip.c nghttp2_gzip.h \ nghttp2_gzip.c nghttp2_gzip.h \
buffer_test.cc buffer_test.h \ buffer_test.cc buffer_test.h \
memchunk_test.cc memchunk_test.h memchunk_test.cc memchunk_test.h \
template_test.cc template_test.h
nghttpx_unittest_CPPFLAGS = ${AM_CPPFLAGS} \ nghttpx_unittest_CPPFLAGS = ${AM_CPPFLAGS} \
-DNGHTTP2_TESTS_DIR=\"$(top_srcdir)/tests\" -DNGHTTP2_TESTS_DIR=\"$(top_srcdir)/tests\"
nghttpx_unittest_LDADD = libnghttpx.a ${LDADD} @CUNIT_LIBS@ @TESTLDADD@ nghttpx_unittest_LDADD = libnghttpx.a ${LDADD} @CUNIT_LIBS@ @TESTLDADD@

View File

@ -38,6 +38,7 @@
#include "nghttp2_gzip_test.h" #include "nghttp2_gzip_test.h"
#include "buffer_test.h" #include "buffer_test.h"
#include "memchunk_test.h" #include "memchunk_test.h"
#include "template_test.h"
#include "shrpx_config.h" #include "shrpx_config.h"
#include "ssl.h" #include "ssl.h"
@ -178,7 +179,11 @@ int main(int argc, char *argv[]) {
!CU_add_test(pSuite, "peek_memchunk_disable_peek_no_drain", !CU_add_test(pSuite, "peek_memchunk_disable_peek_no_drain",
nghttp2::test_peek_memchunks_disable_peek_no_drain) || nghttp2::test_peek_memchunks_disable_peek_no_drain) ||
!CU_add_test(pSuite, "peek_memchunk_reset", !CU_add_test(pSuite, "peek_memchunk_reset",
nghttp2::test_peek_memchunks_reset)) { nghttp2::test_peek_memchunks_reset) ||
!CU_add_test(pSuite, "template_immutable_string",
nghttp2::test_template_immutable_string) ||
!CU_add_test(pSuite, "template_string_ref",
nghttp2::test_template_string_ref)) {
CU_cleanup_registry(); CU_cleanup_registry();
return CU_get_error(); return CU_get_error();
} }

View File

@ -215,7 +215,10 @@ inline std::unique_ptr<char[]> strcopy(const std::unique_ptr<char[]> &val,
// std::string. It has c_str() and size() functions to mimic // std::string. It has c_str() and size() functions to mimic
// std::string. It manages buffer by itself. Just like std::string, // std::string. It manages buffer by itself. Just like std::string,
// c_str() returns NULL-terminated string, but NULL character may // c_str() returns NULL-terminated string, but NULL character may
// appear before the final terminal NULL. // appear before the final terminal NULL. The crucial difference
// between this and std::string is that when ImmutableString is
// default constructed, c_str() returns nullptr, whereas std::string
// will return non nullptr. Both size() returns 0.
class ImmutableString { class ImmutableString {
public: public:
using traits_type = std::char_traits<char>; using traits_type = std::char_traits<char>;
@ -232,13 +235,22 @@ public:
ImmutableString(const char *s, size_t slen) ImmutableString(const char *s, size_t slen)
: len(slen), base(strcopy(s, len)) {} : len(slen), base(strcopy(s, len)) {}
ImmutableString(const char *s) : len(strlen(s)), base(strcopy(s, len)) {} ImmutableString(const char *s) : len(strlen(s)), base(strcopy(s, len)) {}
ImmutableString(std::unique_ptr<char[]> s)
: len(strlen(s.get())), base(std::move(s)) {}
ImmutableString(std::unique_ptr<char[]> s, size_t slen)
: len(slen), base(std::move(s)) {}
ImmutableString(const std::string &s) : len(s.size()), base(strcopy(s)) {} ImmutableString(const std::string &s) : len(s.size()), base(strcopy(s)) {}
template <typename InputIt> template <typename InputIt>
ImmutableString(InputIt first, InputIt last) ImmutableString(InputIt first, InputIt last)
: len(std::distance(first, last)), base(strcopy(first, last)) {} : len(std::distance(first, last)), base(strcopy(first, last)) {}
ImmutableString(const ImmutableString &other) ImmutableString(const ImmutableString &other)
: len(other.len), base(strcopy(other.base, other.len)) {} : len(other.len), base(strcopy(other.base, other.len)) {}
ImmutableString(ImmutableString &&) = default; ImmutableString(ImmutableString &&other) noexcept
: len(other.len),
base(std::move(other.base)) {
other.len = 0;
}
ImmutableString &operator=(const ImmutableString &other) { ImmutableString &operator=(const ImmutableString &other) {
if (this == &other) { if (this == &other) {
return *this; return *this;
@ -247,7 +259,15 @@ public:
base = strcopy(other.base, other.len); base = strcopy(other.base, other.len);
return *this; return *this;
} }
ImmutableString &operator=(ImmutableString &&other) = default; ImmutableString &operator=(ImmutableString &&other) noexcept {
if (this == &other) {
return *this;
}
len = other.len;
base = std::move(other.base);
other.len = 0;
return *this;
}
template <size_t N> static ImmutableString from_lit(const char(&s)[N]) { template <size_t N> static ImmutableString from_lit(const char(&s)[N]) {
return ImmutableString(s, N - 1); return ImmutableString(s, N - 1);
@ -313,6 +333,15 @@ inline bool operator==(const std::string &lhs, const StringRef &rhs) {
return rhs == lhs; return rhs == lhs;
} }
inline bool operator==(const StringRef &lhs, const char *rhs) {
return lhs.size() == strlen(rhs) &&
std::equal(std::begin(lhs), std::end(lhs), rhs);
}
inline bool operator==(const char *lhs, const StringRef &rhs) {
return rhs == lhs;
}
inline int run_app(std::function<int(int, char **)> app, int argc, inline int run_app(std::function<int(int, char **)> app, int argc,
char **argv) { char **argv) {
try { try {

136
src/template_test.cc Normal file
View File

@ -0,0 +1,136 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2016 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "template_test.h"
#include <cstring>
#include <iostream>
#include <CUnit/CUnit.h>
#include "template.h"
namespace nghttp2 {
void test_template_immutable_string(void) {
ImmutableString null;
CU_ASSERT(nullptr == null.c_str());
CU_ASSERT(0 == null.size());
ImmutableString from_cstr("alpha");
CU_ASSERT(0 == strcmp("alpha", from_cstr.c_str()));
CU_ASSERT(5 == from_cstr.size());
CU_ASSERT("alpha" == from_cstr);
CU_ASSERT(from_cstr == "alpha");
CU_ASSERT(std::string("alpha") == from_cstr);
CU_ASSERT(from_cstr == std::string("alpha"));
ImmutableString from_uniq(strcopy("charlie"));
CU_ASSERT("charlie" == from_uniq);
CU_ASSERT(7 == from_uniq.size());
// copy constructor
ImmutableString copy = from_uniq;
CU_ASSERT("charlie" == copy);
CU_ASSERT(7 == copy.size());
// copy assignment
ImmutableString copy2;
copy2 = from_uniq;
CU_ASSERT("charlie" == copy2);
CU_ASSERT(7 == copy2.size());
// move constructor
ImmutableString move = std::move(copy);
CU_ASSERT("charlie" == move);
CU_ASSERT(7 == move.size());
CU_ASSERT(nullptr == copy.c_str());
CU_ASSERT(0 == copy.size());
// move assignment
move = std::move(from_cstr);
CU_ASSERT("alpha" == move);
CU_ASSERT(5 == move.size());
CU_ASSERT(nullptr == from_cstr.c_str());
CU_ASSERT(0 == from_cstr.size());
// from string literal
auto from_lit = StringRef::from_lit("bravo");
CU_ASSERT("bravo" == from_lit);
CU_ASSERT(5 == from_lit.size());
}
void test_template_string_ref(void) {
StringRef empty;
CU_ASSERT("" == empty);
CU_ASSERT(0 == empty.size());
// from std::string
std::string alpha = "alpha";
StringRef ref(alpha);
CU_ASSERT("alpha" == ref);
CU_ASSERT(ref == "alpha");
CU_ASSERT(alpha == ref);
CU_ASSERT(ref == alpha);
CU_ASSERT(5 == ref.size());
// from string literal
auto from_lit = StringRef::from_lit("alpha");
CU_ASSERT("alpha" == from_lit);
CU_ASSERT(5 == from_lit.size());
// from ImmutableString
ImmutableString im = "bravo";
StringRef imref(im);
CU_ASSERT("bravo" == imref);
CU_ASSERT(5 == imref.size());
// from C-string
StringRef cstrref("charlie");
CU_ASSERT("charlie" == cstrref);
CU_ASSERT(7 == cstrref.size());
// from C-string and its length
StringRef cstrnref("delta", 5);
CU_ASSERT("delta" == cstrnref);
CU_ASSERT(5 == cstrnref.size());
}
} // namespace nghttp2

39
src/template_test.h Normal file
View File

@ -0,0 +1,39 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2016 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef TEMPLATE_TEST_H
#define TEMPLATE_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace nghttp2 {
void test_template_immutable_string(void);
void test_template_string_ref(void);
} // namespace nghttp2
#endif // TEMPLATE_TEST_H