Start work on basic tests
This commit is contained in:
parent
0f6866e982
commit
710ea2a8bf
@ -12,6 +12,7 @@ set(LIBREXY_LIBFLAGS "-lrexy")
|
|||||||
|
|
||||||
option(ENABLE_SHARED "Build shared library" ON)
|
option(ENABLE_SHARED "Build shared library" ON)
|
||||||
option(ENABLE_PROFILING "Enable asan" OFF)
|
option(ENABLE_PROFILING "Enable asan" OFF)
|
||||||
|
option(BUILD_TESTS "Enable testing" OFF)
|
||||||
mark_as_advanced(ENABLE_PROFILING)
|
mark_as_advanced(ENABLE_PROFILING)
|
||||||
|
|
||||||
set(SOURCE_LIST "src/filerd.cpp" "src/string.cpp" "src/binary.cpp" "src/static_string.cpp")
|
set(SOURCE_LIST "src/filerd.cpp" "src/string.cpp" "src/binary.cpp" "src/static_string.cpp")
|
||||||
@ -28,8 +29,12 @@ if(ENABLE_PROFILING)
|
|||||||
target_compile_options(rexy PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
|
target_compile_options(rexy PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
|
||||||
target_link_options(rexy PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
|
target_link_options(rexy PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
|
||||||
endif()
|
endif()
|
||||||
|
if(BUILD_TESTS)
|
||||||
|
enable_testing()
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(LIBREXY_PUBLIC_HEADERS "include/rexy/traits.hpp" "include/rexy/steal.hpp" "include/rexy/binary.hpp" "include/rexy/expression.hpp" "include/rexy/binary_base.hpp" "include/rexy/binary_base.tpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp")
|
set(LIBREXY_PUBLIC_HEADERS "include/rexy/traits.hpp" "include/rexy/steal.hpp" "include/rexy/binary.hpp" "include/rexy/expression.hpp" "include/rexy/binary_base.hpp" "include/rexy/binary_base.tpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp" "include/rexy/allocator.hpp")
|
||||||
target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++17)
|
target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++17)
|
||||||
|
|
||||||
install(TARGETS rexy
|
install(TARGETS rexy
|
||||||
|
|||||||
16
tests/CMakeLists.txt
Normal file
16
tests/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0.2)
|
||||||
|
project(rexylib_tests)
|
||||||
|
set(INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
||||||
|
include_directories("${INCLUDE_PATH}")
|
||||||
|
add_compile_options(-Wall -Wextra -pedantic -std=c++17)
|
||||||
|
link_libraries(rexy)
|
||||||
|
|
||||||
|
if(ENABLE_PROFILING)
|
||||||
|
add_compile_options(-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
|
||||||
|
add_link_options(-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(basic_string "basic_string.cpp")
|
||||||
|
set_target_properties(basic_string PROPERTIES OUTPUT_NAME basic_string)
|
||||||
|
|
||||||
|
add_test(NAME basic_string-test COMMAND basic_string)
|
||||||
249
tests/basic_string.cpp
Normal file
249
tests/basic_string.cpp
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
#include "rexy/string.hpp"
|
||||||
|
#include "rexy/allocator.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
[[noreturn]] void error(const char* str){
|
||||||
|
fprintf(stderr, "%s", str);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
using test_str = rexy::basic_string<char,rexy::allocator<char>>;
|
||||||
|
|
||||||
|
void check_empty_construction(){
|
||||||
|
test_str str1;
|
||||||
|
if(str1.length() != 0)
|
||||||
|
error("length() should return 0 on default init\n");
|
||||||
|
if(test_str::uses_sso()){
|
||||||
|
if(str1.get()[0] != 0)
|
||||||
|
error("get() should return an empty, zero length string\n");
|
||||||
|
}else{
|
||||||
|
if(str1.get() != nullptr)
|
||||||
|
error("get() should return a null string\n");
|
||||||
|
}
|
||||||
|
if(str1.valid())
|
||||||
|
error("valid() should return false on empty string\n");
|
||||||
|
if(str1.get() != str1.c_str())
|
||||||
|
error("c_str() should be a synonymn of get()\n");
|
||||||
|
if(char* c = str1;c != str1.get())
|
||||||
|
error("conversion to pointer type should be synonymous with get()\n");
|
||||||
|
|
||||||
|
test_str str2(str1);
|
||||||
|
if(str2.length() != str1.length())
|
||||||
|
error("copy construction on empty string should give equivalent length()\n");
|
||||||
|
if(str2.capacity() != str1.capacity())
|
||||||
|
error("copy construction on empty string should give equivalent capacity()\n");
|
||||||
|
if(test_str::uses_sso()){
|
||||||
|
if(str2.get()[0] != str1.get()[0])
|
||||||
|
error("copy construction on empty string should give equivalent get()\n");
|
||||||
|
}else{
|
||||||
|
if(str2.get() != str1.get())
|
||||||
|
error("copy construction on empty string should give equivalent get()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
test_str str3(std::move(str2));
|
||||||
|
if(str3.length() != str1.length())
|
||||||
|
error("move construction on empty string should give equivalent length()\n");
|
||||||
|
if(str3.capacity() != str1.capacity())
|
||||||
|
error("move construction on empty string should give equivalent capacity()\n");
|
||||||
|
if(test_str::uses_sso()){
|
||||||
|
if(str3.get()[0] != str1.get()[0])
|
||||||
|
error("move construction on empty string should give equivalent get()\n");
|
||||||
|
}else{
|
||||||
|
if(str3.get() != str1.get())
|
||||||
|
error("move construction on empty string should give equivalent get()\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_short_construction(){
|
||||||
|
if(!test_str::uses_sso())
|
||||||
|
return;
|
||||||
|
|
||||||
|
test_str::size_type cap = test_str::short_string_size();
|
||||||
|
test_str str1("a");
|
||||||
|
if(str1.length() != 1)
|
||||||
|
error("short constructed string 'a' should be length() == 1\n");
|
||||||
|
if(str1.capacity() != cap)
|
||||||
|
error("short constructed string 'a' should be capacity() == short_string_size()\n");
|
||||||
|
if(strcmp(str1.get(), "a"))
|
||||||
|
error("short constructed string 'a' should be !strcmp(get(), \"a\")\n");
|
||||||
|
|
||||||
|
test_str str2(str1);
|
||||||
|
if(str2.length() != str1.length())
|
||||||
|
error("short copy constructed string should have equal length()\n");
|
||||||
|
if(str2.capacity() != str1.capacity())
|
||||||
|
error("short copy constructed string should have equal capacity()\n");
|
||||||
|
if(strcmp(str2.get(), str1.get()))
|
||||||
|
error("short copy constructed string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str3(std::move(str2));
|
||||||
|
if(str3.length() != str1.length())
|
||||||
|
error("short move constructed string should have equal length()\n");
|
||||||
|
if(str3.capacity() != str1.capacity())
|
||||||
|
error("short move constructed string should have equal capacity()\n");
|
||||||
|
if(strcmp(str3.get(), str1.get()))
|
||||||
|
error("short move constructed string should have equivalent get()\n");
|
||||||
|
}
|
||||||
|
void check_long_construction(){
|
||||||
|
const char* data = "this is a really long string that should ensure that it makes a dynamic allocation even if it has a big buffer.";
|
||||||
|
size_t len = strlen(data);
|
||||||
|
test_str str1(data);
|
||||||
|
if(str1.length() != len)
|
||||||
|
error("long constructed string should be length() == strlen(data)\n");
|
||||||
|
if(str1.capacity() < len)
|
||||||
|
error("long constructed string should be capacity() >= strlen(data)\n");
|
||||||
|
if(strcmp(str1.get(), data))
|
||||||
|
error("long constructed string should be !strcmp(get(), data)\n");
|
||||||
|
|
||||||
|
test_str str2(str1);
|
||||||
|
if(str2.length() != str1.length())
|
||||||
|
error("long copy constructed string should have equal length()\n");
|
||||||
|
if(str2.capacity() != str1.capacity())
|
||||||
|
error("long copy constructed string should have equal capacity()\n");
|
||||||
|
if(strcmp(str2.get(), str1.get()))
|
||||||
|
error("long copy constructed string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str3(std::move(str2));
|
||||||
|
if(str3.length() != str1.length())
|
||||||
|
error("long move constructed string should have equal length()\n");
|
||||||
|
if(str3.capacity() != str1.capacity())
|
||||||
|
error("long move constructed string should have equal capacity()\n");
|
||||||
|
if(strcmp(str3.get(), str1.get()))
|
||||||
|
error("long move constructed string should have equivalent get()\n");
|
||||||
|
}
|
||||||
|
void check_short_assignment(){
|
||||||
|
if(!test_str::uses_sso())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* longstartdata = "this is another really long string that should ensure that it makes some sort of dyn alloc for big buf";
|
||||||
|
|
||||||
|
test_str::size_type cap = test_str::short_string_size();
|
||||||
|
test_str str1("zy");
|
||||||
|
str1 = "a";
|
||||||
|
if(str1.length() != 1)
|
||||||
|
error("short assigned string 'a' should be length() == 1\n");
|
||||||
|
if(str1.capacity() != cap)
|
||||||
|
error("short assigned string 'a' should be capacity() == short_string_size()\n");
|
||||||
|
if(strcmp(str1.get(), "a"))
|
||||||
|
error("short assigned string 'a' should be !strcmp(get(), \"a\")\n");
|
||||||
|
|
||||||
|
test_str str2("ba");
|
||||||
|
str2 = str1;
|
||||||
|
if(str2.length() != str1.length())
|
||||||
|
error("short copy assigned string should have equal length()\n");
|
||||||
|
if(str2.capacity() != str1.capacity())
|
||||||
|
error("short copy assigned string should have equal capacity()\n");
|
||||||
|
if(strcmp(str2.get(), str1.get()))
|
||||||
|
error("short copy assigned string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str3("cb");
|
||||||
|
str3 = std::move(str2);
|
||||||
|
if(str3.length() != str1.length())
|
||||||
|
error("short move assigned string should have equal length()\n");
|
||||||
|
if(str3.capacity() != str1.capacity())
|
||||||
|
error("short move assigned string should have equal capacity()\n");
|
||||||
|
if(strcmp(str3.get(), str1.get()))
|
||||||
|
error("short move assigned string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str4(longstartdata);
|
||||||
|
str4 = str1;
|
||||||
|
if(str4.length() != str1.length())
|
||||||
|
error("long->short copy assigned string should have equal length()\n");
|
||||||
|
if(str4.capacity() < str1.capacity())
|
||||||
|
error("long->short copy assigned string should have equal or greater capacity()\n");
|
||||||
|
if(strcmp(str4.get(), str1.get()))
|
||||||
|
error("long->short copy assigned string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str5(longstartdata);
|
||||||
|
str5 = std::move(str4);
|
||||||
|
if(str5.length() != str1.length())
|
||||||
|
error("long->short move assigned string should have equal length()\n");
|
||||||
|
if(str5.capacity() < str1.capacity())
|
||||||
|
error("long->short move assigned string should have equal or greater capacity()\n");
|
||||||
|
if(strcmp(str5.get(), str1.get()))
|
||||||
|
error("long->short move assigned string should have equivalent get()\n");
|
||||||
|
}
|
||||||
|
void check_long_assignment(){
|
||||||
|
const char* startdata1 = "this is another really long string that should ensure that it makes some sort of dyn alloc for big buf";
|
||||||
|
const char* startdata2 = "zy";
|
||||||
|
const char* data = "this is a really long string that should ensure that it makes a dynamic allocation even if it has a big buffer.";
|
||||||
|
size_t len = strlen(data);
|
||||||
|
test_str str1(startdata1);
|
||||||
|
str1 = data;
|
||||||
|
if(str1.length() != len)
|
||||||
|
error("long assigned string should be length() == strlen(data)\n");
|
||||||
|
if(str1.capacity() < len)
|
||||||
|
error("long assigned string should be capacity() >= strlen(data)\n");
|
||||||
|
if(strcmp(str1.get(), data))
|
||||||
|
error("long assigned string should be !strcmp(get(), data)\n");
|
||||||
|
|
||||||
|
test_str str2(startdata1);
|
||||||
|
str2 = str1;
|
||||||
|
if(str2.length() != str1.length())
|
||||||
|
error("long copy assigned string should have equal length()\n");
|
||||||
|
if(str2.capacity() != str1.capacity())
|
||||||
|
error("long copy assigned string should have equal capacity()\n");
|
||||||
|
if(strcmp(str2.get(), str1.get()))
|
||||||
|
error("long copy assigned string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str3(startdata1);
|
||||||
|
str3 = std::move(str2);
|
||||||
|
if(str3.length() != str1.length())
|
||||||
|
error("long move assigned string should have equal length()\n");
|
||||||
|
if(str3.capacity() != str1.capacity())
|
||||||
|
error("long move assigned string should have equal capacity()\n");
|
||||||
|
if(strcmp(str3.get(), str1.get()))
|
||||||
|
error("long move assigned string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str4(startdata2);
|
||||||
|
str4 = str1;
|
||||||
|
if(str4.length() != str1.length())
|
||||||
|
error("short->long copy assigned string should have equal length()\n");
|
||||||
|
if(str4.capacity() != str1.capacity())
|
||||||
|
error("short->long copy assigned string should have equal capacity()\n");
|
||||||
|
if(strcmp(str4.get(), str1.get()))
|
||||||
|
error("short->long copy assigned string should have equivalent get()\n");
|
||||||
|
|
||||||
|
test_str str5(startdata2);
|
||||||
|
str5 = std::move(str4);
|
||||||
|
if(str5.length() != str1.length())
|
||||||
|
error("short->long move assigned string should have equal length()\n");
|
||||||
|
if(str5.capacity() != str1.capacity())
|
||||||
|
error("short->long move assigned string should have equal capacity()\n");
|
||||||
|
if(strcmp(str5.get(), str1.get()))
|
||||||
|
error("short->long move assigned string should have equivalent get()\n");
|
||||||
|
}
|
||||||
|
void check_short_append(){
|
||||||
|
test_str str1;
|
||||||
|
test_str str2("bc");
|
||||||
|
test_str str3("really long string that should trigger a short to long conversion in the string");
|
||||||
|
str1.append("a");
|
||||||
|
str1.append("b");
|
||||||
|
str1.append(str2);
|
||||||
|
if(strcmp(str1.get(), "abbc"))
|
||||||
|
error("short append should have resulted in abbc\n");
|
||||||
|
str1.append(str3);
|
||||||
|
if(strcmp(str1, "abbcreally long string that should trigger a short to long conversion in the string"))
|
||||||
|
error("short->long append should have resulted in abbcreally long string that should trigger a short to long conversion in the string\n");
|
||||||
|
}
|
||||||
|
void check_long_append(){
|
||||||
|
const char* startdata1 = "this is another really long string that should ensure that it makes some sort of dyn alloc for big buf";
|
||||||
|
const char* appendeddata = "this is another really long string that should ensure that it makes some sort of dyn alloc for big bufstuff";
|
||||||
|
test_str str1(startdata1);
|
||||||
|
str1.append("stuff");
|
||||||
|
if(strcmp(str1.get(), appendeddata))
|
||||||
|
error("long append should have resulted in this is another really long string that should ensure that it makes some sort of dyn alloc for big bufstuff");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
check_empty_construction();
|
||||||
|
check_short_construction();
|
||||||
|
check_long_construction();
|
||||||
|
check_short_assignment();
|
||||||
|
check_long_assignment();
|
||||||
|
check_short_append();
|
||||||
|
check_long_append();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user