diff options
author | Alexis Hildebrandt <afh@surryhill.net> | 2023-12-07 16:43:46 +0100 |
---|---|---|
committer | Alexis Hildebrandt <afh@surryhill.net> | 2023-12-10 19:01:27 +0100 |
commit | f017686dd4720bac373e8fcd5b779777a83162ec (patch) | |
tree | 408f1a27aa999bce0646f21c76330e3f252e1c76 /lib/utfcpp/v4/tests | |
parent | 3cfad2570d7fe8aa5d88de3797797d695d4fbe06 (diff) | |
download | fork-ledger-f017686dd4720bac373e8fcd5b779777a83162ec.tar.gz fork-ledger-f017686dd4720bac373e8fcd5b779777a83162ec.tar.bz2 fork-ledger-f017686dd4720bac373e8fcd5b779777a83162ec.zip |
utfcpp: Update to 4.0.4
Diffstat (limited to 'lib/utfcpp/v4/tests')
-rw-r--r-- | lib/utfcpp/v4/tests/CMakeLists.txt | 56 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/apitests.cpp | 6 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/docker/Dockerfile | 5 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/negative.cpp | 59 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/noexceptionstests.cpp | 4 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/test_checked_api.h | 233 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/test_checked_iterator.h | 35 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/test_cpp11.cpp | 122 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/test_cpp17.cpp | 88 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/test_cpp20.cpp | 77 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/test_data/utf8_invalid.txt | bin | 0 -> 20010 bytes | |||
-rw-r--r-- | lib/utfcpp/v4/tests/test_unchecked_api.h | 198 | ||||
-rw-r--r-- | lib/utfcpp/v4/tests/test_unchecked_iterator.h | 36 |
13 files changed, 919 insertions, 0 deletions
diff --git a/lib/utfcpp/v4/tests/CMakeLists.txt b/lib/utfcpp/v4/tests/CMakeLists.txt new file mode 100644 index 00000000..8a00a6a0 --- /dev/null +++ b/lib/utfcpp/v4/tests/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required (VERSION 3.5) +project(utfcpptests LANGUAGES CXX) +enable_testing() + +add_library(${PROJECT_NAME} INTERFACE) + +include_directories("${PROJECT_SOURCE_DIR}/../source") + +add_executable(negative negative.cpp) +add_executable(cpp11 test_cpp11.cpp) +add_executable(cpp17 test_cpp17.cpp) +add_executable(cpp20 test_cpp20.cpp) +add_executable(apitests apitests.cpp) + +add_executable(noexceptionstests noexceptionstests.cpp) + + + +target_compile_options(${PROJECT_NAME} INTERFACE + $<$<CXX_COMPILER_ID:MSVC>:/W4> + $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic -Wconversion>) + +target_compile_options(noexceptionstests PUBLIC -fno-exceptions) + +set_target_properties(negative apitests noexceptionstests + PROPERTIES + CXX_STANDARD 98 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + +set_target_properties(cpp11 + PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + +set_target_properties(cpp17 + PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + +set_target_properties(cpp20 + PROPERTIES + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + + +add_test(negative_test negative ${PROJECT_SOURCE_DIR}/test_data/utf8_invalid.txt) +add_test(cpp11_test cpp11) +add_test(cpp17_test cpp17) +add_test(cpp20_test cpp20) +add_test(api_test apitests) +add_test(noexceptions_test noexceptionstests) + diff --git a/lib/utfcpp/v4/tests/apitests.cpp b/lib/utfcpp/v4/tests/apitests.cpp new file mode 100644 index 00000000..083266d7 --- /dev/null +++ b/lib/utfcpp/v4/tests/apitests.cpp @@ -0,0 +1,6 @@ +#include "../extern/ftest/ftest.h" + +#include "test_checked_api.h" +#include "test_checked_iterator.h" +#include "test_unchecked_api.h" +#include "test_unchecked_iterator.h" diff --git a/lib/utfcpp/v4/tests/docker/Dockerfile b/lib/utfcpp/v4/tests/docker/Dockerfile new file mode 100644 index 00000000..dcdd47d1 --- /dev/null +++ b/lib/utfcpp/v4/tests/docker/Dockerfile @@ -0,0 +1,5 @@ +FROM gcc:12.2 + +RUN apt-get update \ + && apt-get install -y make g++ cmake git \ + && rm -rf /var/lib/apt/lists/* diff --git a/lib/utfcpp/v4/tests/negative.cpp b/lib/utfcpp/v4/tests/negative.cpp new file mode 100644 index 00000000..f1bcc993 --- /dev/null +++ b/lib/utfcpp/v4/tests/negative.cpp @@ -0,0 +1,59 @@ +#include "utf8.h" +using namespace utf8; + +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +using namespace std; + +const unsigned INVALID_LINES[] = { 75, 76, 83, 84, 85, 93, 102, 103, 105, 106, 107, 108, 109, 110, 114, 115, 116, 117, 124, 125, 130, 135, 140, 145, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 169, 175, 176, 177, 207, 208, 209, 210, 211, 220, 221, 222, 223, 224, 232, 233, 234, 235, 236, 247, 248, 249, 250, 251, 252, 253, 257, 258, 259, 260, 261, 262, 263, 264}; +const unsigned* INVALID_LINES_END = INVALID_LINES + sizeof(INVALID_LINES)/sizeof(unsigned); + +int main(int argc, char** argv) +{ + string test_file_path; + if (argc == 2) + test_file_path = argv[1]; + else { + cout << "Wrong number of arguments" << endl; + return 1; + } + // Open the test file + ifstream fs8(test_file_path.c_str()); + if (!fs8.is_open()) { + cout << "Could not open " << test_file_path << endl; + return 1; + } + + // Read it line by line + unsigned int line_count = 0; + char byte; + while (!fs8.eof()) { + string line; + while ((byte = static_cast<char>(fs8.get())) != '\n' && !fs8.eof()) + line.push_back(byte); + + line_count++; + bool expected_valid = (find(INVALID_LINES, INVALID_LINES_END, line_count) == INVALID_LINES_END); + // Print out lines that contain unexpected invalid UTF-8 + if (!is_valid(line.begin(), line.end())) { + if (expected_valid) { + cout << "Unexpected invalid utf-8 at line " << line_count << '\n'; + return 1; + } + + // try fixing it: + string fixed_line; + replace_invalid(line.begin(), line.end(), back_inserter(fixed_line)); + if (!is_valid(fixed_line.begin(), fixed_line.end())) { + cout << "replace_invalid() resulted in an invalid utf-8 at line " << line_count << '\n'; + return 1; + } + } + else if (!expected_valid) { + cout << "Invalid utf-8 NOT detected at line " << line_count << '\n'; + return 1; + } + } +} diff --git a/lib/utfcpp/v4/tests/noexceptionstests.cpp b/lib/utfcpp/v4/tests/noexceptionstests.cpp new file mode 100644 index 00000000..108ee750 --- /dev/null +++ b/lib/utfcpp/v4/tests/noexceptionstests.cpp @@ -0,0 +1,4 @@ +#include "../extern/ftest/ftest.h" + +#include "test_unchecked_api.h" +#include "test_unchecked_iterator.h" diff --git a/lib/utfcpp/v4/tests/test_checked_api.h b/lib/utfcpp/v4/tests/test_checked_api.h new file mode 100644 index 00000000..54e9cf8f --- /dev/null +++ b/lib/utfcpp/v4/tests/test_checked_api.h @@ -0,0 +1,233 @@ +#ifndef UTF8_FOR_CPP_TEST_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8.h" + +#include <string> +#include <vector> +using namespace utf8; +using namespace std; + + +TEST(CheckedAPITests, test_append) +{ + unsigned char u[5] = {0,0,0,0,0}; + append(0x0448, u); + EXPECT_EQ (u[0], 0xd1); + EXPECT_EQ (u[1], 0x88); + EXPECT_EQ (u[2], 0); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + append(0x65e5, u); + EXPECT_EQ (u[0], 0xe6); + EXPECT_EQ (u[1], 0x97); + EXPECT_EQ (u[2], 0xa5); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + append(0x3044, u); + EXPECT_EQ (u[0], 0xe3); + EXPECT_EQ (u[1], 0x81); + EXPECT_EQ (u[2], 0x84); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + append(0x10346, u); + EXPECT_EQ (u[0], 0xf0); + EXPECT_EQ (u[1], 0x90); + EXPECT_EQ (u[2], 0x8d); + EXPECT_EQ (u[3], 0x86); + EXPECT_EQ (u[4], 0); + + // Ensure no warnings with plain char + char c[2] = {0,0}; + append('a', c); + EXPECT_EQ (c[0], 'a'); + EXPECT_EQ (c[1], 0); +} + +TEST(CheckedAPITests, test_append16) +{ + utfchar16_t u[5] = {0,0}; + append16(0x0448, u); + EXPECT_EQ (u[0], 0x0448); + EXPECT_EQ (u[1], 0x0000); + + append16(0x65e5, u); + EXPECT_EQ (u[0], 0x65e5); + EXPECT_EQ (u[1], 0x0000); + + append16(0x10346, u); + EXPECT_EQ (u[0], 0xd800); + EXPECT_EQ (u[1], 0xdf46); +} + +TEST(CheckedAPITests, test_next) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars; + unsigned int cp = next(w, twochars + 6); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars + 3); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars; + + cp = next(w, threechars + 9); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars + 4); + + cp = next(w, threechars + 9); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 7); + + cp = next(w, threechars + 9); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 9); +} + +TEST(CheckedAPITests, test_next16) +{ + const utfchar16_t u[3] = {0x65e5, 0xd800, 0xdf46}; + const utfchar16_t* w = u; + utf8::utfchar32_t cp = next16(w, w + 3); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, u + 1); + + cp = next16(w, w + 2); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, u + 3); +} + +TEST(CheckedAPITests, test_peek_next) +{ + const char* const cw = "\xe6\x97\xa5\xd1\x88"; + unsigned int cp = peek_next(cw, cw + 6); + EXPECT_EQ (cp, 0x65e5); +} + +TEST(CheckedAPITests, test_prior) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars + 3; + unsigned int cp = prior (w, twochars); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars + 9; + cp = prior(w, threechars); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 7); + cp = prior(w, threechars); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 4); + cp = prior(w, threechars); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars); +} + +TEST(CheckedAPITests, test_advance) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + const char* w = threechars; + advance(w, 2, threechars + 9); + EXPECT_EQ(w, threechars + 7); + advance(w, -2, threechars); + EXPECT_EQ(w, threechars); + advance(w, 3, threechars + 9); + EXPECT_EQ(w, threechars + 9); + advance(w, -2, threechars); + EXPECT_EQ(w, threechars + 4); + advance(w, -1, threechars); + EXPECT_EQ(w, threechars); +} + +TEST(CheckedAPITests, test_distance) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + size_t dist = static_cast<size_t>(utf8::distance(twochars, twochars + 5)); + EXPECT_EQ (dist, 2); +} + +TEST(CheckedAPITests, test_utf32to8) +{ + unsigned int utf32string[] = {0x448, 0x65E5, 0x10346, 0}; + string utf8result; + utf32to8(utf32string, utf32string + 3, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CheckedAPITests, test_utf8to32) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + vector<unsigned int> utf32result; + utf8to32(twochars, twochars + 5, back_inserter(utf32result)); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CheckedAPITests, test_utf16to8) +{ + unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + string utf8result; + utf16to8(utf16string, utf16string + 5, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 10); +} + +TEST(CheckedAPITests, test_utf8to16) +{ + char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + vector <unsigned short> utf16result; + utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result)); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(CheckedAPITests, test_replace_invalid) +{ + char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + vector<char> replace_invalid_result; + replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), std::back_inserter(replace_invalid_result), '?'); + bool bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end()); + EXPECT_TRUE (bvalid); + const char fixed_invalid_sequence[] = "a????z"; + EXPECT_EQ (sizeof(fixed_invalid_sequence), replace_invalid_result.size()); + EXPECT_TRUE (std::equal(replace_invalid_result.begin(), replace_invalid_result.begin() + sizeof(fixed_invalid_sequence), fixed_invalid_sequence)); +} + +TEST(CheckedAPITests, test_find_invalid) +{ + char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; + const char* invalid = find_invalid(utf_invalid, utf_invalid + 6); + EXPECT_EQ (invalid, utf_invalid + 5); + invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, utf_invalid + 5); +} + +TEST(CheckedAPITests, test_is_valid) +{ + char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid, utf_invalid + 6); + EXPECT_FALSE (bvalid); + bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates, utf8_with_surrogates + 9); + EXPECT_TRUE (bvalid); + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CheckedAPITests, test_starts_with_bom) +{ + unsigned char byte_order_mark[] = {0xef, 0xbb, 0xbf}; + bool bbom = starts_with_bom(byte_order_mark, byte_order_mark + sizeof(byte_order_mark)); + EXPECT_TRUE (bbom); + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars, threechars + sizeof(threechars)); + EXPECT_FALSE (no_bbom); +} + +#endif diff --git a/lib/utfcpp/v4/tests/test_checked_iterator.h b/lib/utfcpp/v4/tests/test_checked_iterator.h new file mode 100644 index 00000000..2829a734 --- /dev/null +++ b/lib/utfcpp/v4/tests/test_checked_iterator.h @@ -0,0 +1,35 @@ +#ifndef UTF8_FOR_CPP_TEST_CHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_CHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8.h" + +using namespace utf8; + + +TEST(CheckedIteratrTests, test_increment) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::iterator<const char*> it(threechars, threechars, threechars + 9); + utf8::iterator<const char*> it2 = it; + EXPECT_EQ (it2, it); + EXPECT_EQ (*it, 0x10346); + EXPECT_EQ (*(++it), 0x65e5); + EXPECT_EQ ((*it++), 0x65e5); + EXPECT_EQ (*it, 0x0448); + EXPECT_NE (it, it2); + utf8::iterator<const char*> endit (threechars + 9, threechars, threechars + 9); + EXPECT_EQ (++it, endit); +} + +TEST(CheckedIteratrTests, test_decrement) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::iterator<const char*> it(threechars+9, threechars, threechars + 9); + EXPECT_EQ (*(--it), 0x0448); + EXPECT_EQ ((*it--), 0x0448); + EXPECT_EQ (*it, 0x65e5); + EXPECT_EQ (--it, utf8::iterator<const char*>(threechars, threechars, threechars + 9)); + EXPECT_EQ (*it, 0x10346); +} + +#endif diff --git a/lib/utfcpp/v4/tests/test_cpp11.cpp b/lib/utfcpp/v4/tests/test_cpp11.cpp new file mode 100644 index 00000000..e5219668 --- /dev/null +++ b/lib/utfcpp/v4/tests/test_cpp11.cpp @@ -0,0 +1,122 @@ +#include "../extern/ftest/ftest.h" +#include "utf8.h" +#include <string> +using namespace utf8; +using namespace std; + +#if __cplusplus >= 201103L // C++ 11 or later + +TEST(CPP11APITests, test_append) +{ + string u; + append(0x0448, u); + EXPECT_EQ (u[0], char(0xd1)); + EXPECT_EQ (u[1], char(0x88)); + EXPECT_EQ (u.length(), 2); + + u.clear(); + append(0x65e5, u); + EXPECT_EQ (u[0], char(0xe6)); + EXPECT_EQ (u[1], char(0x97)); + EXPECT_EQ (u[2], char(0xa5)); + EXPECT_EQ (u.length(), 3); + + u.clear(); + append(0x3044, u); + EXPECT_EQ (u[0], char(0xe3)); + EXPECT_EQ (u[1], char(0x81)); + EXPECT_EQ (u[2], char(0x84)); + EXPECT_EQ (u.length(), 3); + + u.clear(); + append(0x10346, u); + EXPECT_EQ (u[0], char(0xf0)); + EXPECT_EQ (u[1], char(0x90)); + EXPECT_EQ (u[2], char(0x8d)); + EXPECT_EQ (u[3], char(0x86)); + EXPECT_EQ (u.length(), 4); +} + +TEST(CPP11APITests, test_append16) +{ + u16string u; + append16(0x0448, u); + EXPECT_EQ (u[0], char16_t(0x0448)); + EXPECT_EQ (u.length(), 1); +} + +TEST(CPP11APITests, test_utf16to8) +{ + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + string u = utf16to8(utf16string); + EXPECT_EQ (u.size(), 10); + + u16string h16 = u"h!"; + string h8; + utf8::unchecked::utf16to8(h16.begin(), h16.end(), std::back_inserter(h8)); + EXPECT_EQ (h8, "h!"); +} + +TEST(CPP11APITests, test_utf8to16) +{ + string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + u16string utf16result = utf8to16(utf8_with_surrogates); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); + // Just to make sure it compiles with string literals + utf8to16(u8"simple"); + utf8to16("simple"); +} + +TEST(CPP11APITests, test_utf32to8) +{ + u32string utf32string = {0x448, 0x65E5, 0x10346}; + string utf8result = utf32to8(utf32string); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CPP11APITests, test_utf8to32) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + u32string utf32result = utf8to32(twochars); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CPP11APITests, test_find_invalid) +{ + string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + auto invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, 5); +} + +TEST(CPP11APITests, test_is_valid) +{ + string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CPP11APITests, test_replace_invalid) +{ + string invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + string replace_invalid_result = replace_invalid(invalid_sequence, '?'); + bool bvalid = is_valid(replace_invalid_result); + EXPECT_TRUE (bvalid); + const string fixed_invalid_sequence = "a????z"; + EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result); +} + +TEST(CPP11APITests, test_starts_with_bom) +{ + string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)}; + bool bbom = starts_with_bom(byte_order_mark); + EXPECT_TRUE (bbom); + string threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars); + EXPECT_FALSE (no_bbom); +} +#endif // C++ 11 or later diff --git a/lib/utfcpp/v4/tests/test_cpp17.cpp b/lib/utfcpp/v4/tests/test_cpp17.cpp new file mode 100644 index 00000000..a38e6f71 --- /dev/null +++ b/lib/utfcpp/v4/tests/test_cpp17.cpp @@ -0,0 +1,88 @@ +#include "../extern/ftest/ftest.h" +#include "utf8.h" +#include <string> +using namespace utf8; +using namespace std; + +#if __cplusplus >= 201703L // C++ 17 or later + + +TEST(CPP17APITests, test_utf16to8) +{ + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + u16string_view utf16stringview(utf16string); + string u = utf16to8(utf16stringview); + EXPECT_EQ (u.size(), 10); +} + +TEST(CPP17APITests, test_utf8to16) +{ + string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + u16string utf16result = utf8to16(utf8_with_surrogates); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(CPP17APITests, test_utf32to8) +{ + u32string utf32string = {0x448, 0x65E5, 0x10346}; + u32string_view utf32stringview(utf32string); + string utf8result = utf32to8(utf32stringview); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CPP17APITests, test_utf8to32) +{ + string_view twochars = "\xe6\x97\xa5\xd1\x88"; + u32string utf32result = utf8to32(twochars); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CPP17APITests, test_find_invalid) +{ + string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + auto invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, 5); +} + +TEST(CPP17APITests, test_is_valid) +{ + string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CPP17APITests, test_replace_invalid) +{ + string_view invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + string replace_invalid_result = replace_invalid(invalid_sequence, '?'); + bool bvalid = is_valid(replace_invalid_result); + EXPECT_TRUE (bvalid); + const string fixed_invalid_sequence = "a????z"; + EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result); +} + +TEST(CPP17APITests, test_starts_with_bom) +{ + string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)}; + string_view byte_order_mark_view(byte_order_mark); + bool bbom = starts_with_bom(byte_order_mark_view); + EXPECT_TRUE (bbom); + string_view threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars); + EXPECT_FALSE (no_bbom); +} + +TEST(CPP17APITests, string_class_and_literals) +{ + const char* twochars = u8"ab"; + EXPECT_TRUE (is_valid(twochars)); + const string two_chars_string(twochars); + EXPECT_TRUE (is_valid(two_chars_string)); +} + +#endif // C++ 11 or later diff --git a/lib/utfcpp/v4/tests/test_cpp20.cpp b/lib/utfcpp/v4/tests/test_cpp20.cpp new file mode 100644 index 00000000..50dbe30a --- /dev/null +++ b/lib/utfcpp/v4/tests/test_cpp20.cpp @@ -0,0 +1,77 @@ +#include "../extern/ftest/ftest.h" +#define UTF_CPP_CPLUSPLUS 202002L +#include "utf8.h" +#include <string> +using namespace utf8; +using namespace std; + +TEST(CPP20APITests, test_utf16tou8) +{ + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + u16string_view utf16stringview{utf16string}; + u8string u = utf16tou8(utf16string); + EXPECT_EQ (u.size(), 10); + u = utf16tou8(utf16stringview); + EXPECT_EQ (u.size(), 10); +} + +TEST(CPP20APITests, tes20t_utf8to16) +{ + u8string utf8_with_surrogates{u8"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"}; + u16string utf16result = utf8to16(utf8_with_surrogates); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(CPP20APITests, test_utf32tou8) +{ + u32string utf32string = {0x448, 0x65E5, 0x10346}; + u32string_view utf32stringview{utf32string}; + u8string utf8result = utf32tou8(utf32stringview); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CPP20APITests, test_utf8to32) +{ + u8string twochars = u8"\xe6\x97\xa5\xd1\x88"; + u32string utf32result = utf8to32(twochars); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CPP20APITests, test_find_invalid) +{ + u8string utf_invalid = u8"\xe6\x97\xa5\xd1\x88\xfa"; + auto invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, 5); +} + +TEST(CPP20APITests, test_is_valid) +{ + u8string utf_invalid = u8"\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + u8string utf8_with_surrogates = u8"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CPP20APITests, test_replace_invalid) +{ + u8string invalid_sequence = u8"a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + u8string replace_invalid_result = replace_invalid(invalid_sequence, u8'?'); + bool bvalid = is_valid(replace_invalid_result); + EXPECT_TRUE (bvalid); + const u8string fixed_invalid_sequence = u8"a????z"; + EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result); +} + +TEST(CPP20APITests, test_starts_with_bom) +{ + u8string byte_order_mark = u8"\xef\xbb\xbf"; + bool bbom = starts_with_bom(byte_order_mark); + EXPECT_TRUE (bbom); + u8string threechars = u8"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars); + EXPECT_FALSE (no_bbom); +} diff --git a/lib/utfcpp/v4/tests/test_data/utf8_invalid.txt b/lib/utfcpp/v4/tests/test_data/utf8_invalid.txt Binary files differnew file mode 100644 index 00000000..ae831593 --- /dev/null +++ b/lib/utfcpp/v4/tests/test_data/utf8_invalid.txt diff --git a/lib/utfcpp/v4/tests/test_unchecked_api.h b/lib/utfcpp/v4/tests/test_unchecked_api.h new file mode 100644 index 00000000..aa0cf697 --- /dev/null +++ b/lib/utfcpp/v4/tests/test_unchecked_api.h @@ -0,0 +1,198 @@ +#ifndef UTF8_FOR_CPP_TEST_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/unchecked.h" + +#include <string> +#include <vector> + +using namespace std; + +TEST(UnCheckedAPITests, test_append) +{ + unsigned char u[5] = {0,0,0,0,0}; + utf8::unchecked::append(0x0448, u); + EXPECT_EQ (u[0], 0xd1); + EXPECT_EQ (u[1], 0x88); + EXPECT_EQ (u[2], 0); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + utf8::unchecked::append(0x65e5, u); + EXPECT_EQ (u[0], 0xe6); + EXPECT_EQ (u[1], 0x97); + EXPECT_EQ (u[2], 0xa5); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + utf8::unchecked::append(0x3044, u); + EXPECT_EQ (u[0], 0xe3); + EXPECT_EQ (u[1], 0x81); + EXPECT_EQ (u[2], 0x84); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + utf8::unchecked::append(0x10346, u); + EXPECT_EQ (u[0], 0xf0); + EXPECT_EQ (u[1], 0x90); + EXPECT_EQ (u[2], 0x8d); + EXPECT_EQ (u[3], 0x86); + EXPECT_EQ (u[4], 0); +} + +TEST(UnCheckedAPITests, test_append16) +{ + unsigned short u[5] = {0,0}; + utf8::unchecked::append16(0x0448, u); + EXPECT_EQ (u[0], 0x0448); + EXPECT_EQ (u[1], 0x0000); + + utf8::unchecked::append16(0x65e5, u); + EXPECT_EQ (u[0], 0x65e5); + EXPECT_EQ (u[1], 0x0000); + + utf8::unchecked::append16(0x10346, u); + EXPECT_EQ (u[0], 0xd800); + EXPECT_EQ (u[1], 0xdf46); +} + +TEST(UnCheckedAPITests, test_next) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars; + unsigned int cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars + 3); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars; + + cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars + 4); + + cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 7); + + cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 9); +} + +TEST(UnCheckedAPITests, test_next16) +{ + const utf8::utfchar16_t u[3] = {0x65e5, 0xd800, 0xdf46}; + const utf8::utfchar16_t* w = u; + utf8::utfchar32_t cp = utf8::unchecked::next16(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, u + 1); + + cp = utf8::unchecked::next16(w); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, u + 3); +} + +TEST(UnCheckedAPITests, test_peek_next) +{ + const char* const cw = "\xe6\x97\xa5\xd1\x88"; + unsigned int cp = utf8::unchecked::peek_next(cw); + EXPECT_EQ (cp, 0x65e5); +} + +TEST(UnCheckedAPITests, test_prior) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars + 3; + unsigned int cp = utf8::unchecked::prior (w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars + 9; + cp = utf8::unchecked::prior(w); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 7); + cp = utf8::unchecked::prior(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 4); + cp = utf8::unchecked::prior(w); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars); +} + +TEST(UnCheckedAPITests, test_advance) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + const char* w = threechars; + utf8::unchecked::advance(w, 2); + EXPECT_EQ(w, threechars + 7); + utf8::unchecked::advance(w, -2); + EXPECT_EQ(w, threechars); + utf8::unchecked::advance(w, 3); + EXPECT_EQ(w, threechars + 9); + utf8::unchecked::advance(w, -2); + EXPECT_EQ(w, threechars + 4); + utf8::unchecked::advance(w, -1); + EXPECT_EQ(w, threechars); +} + +TEST(UnCheckedAPITests, test_distance) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + size_t dist = static_cast<size_t>(utf8::unchecked::distance(twochars, twochars + 5)); + EXPECT_EQ (dist, 2); +} + +TEST(UnCheckedAPITests, test_utf32to8) +{ + unsigned int utf32string[] = {0x448, 0x65E5, 0x10346, 0}; + string utf8result; + utf8::unchecked::utf32to8(utf32string, utf32string + 3, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(UnCheckedAPITests, test_utf8to32) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + vector<unsigned int> utf32result; + utf8::unchecked::utf8to32(twochars, twochars + 5, back_inserter(utf32result)); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(UnCheckedAPITests, test_utf16to8) +{ + unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + string utf8result; + utf8::unchecked::utf16to8(utf16string, utf16string + 5, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 10); + + utf8result.clear(); + unsigned short highsurrogateonly[] = {0xd800}; + utf8::unchecked::utf16to8(highsurrogateonly, highsurrogateonly + 1, back_inserter(utf8result)); + EXPECT_TRUE(true); // we didn't crash +} + +TEST(UnCheckedAPITests, test_utf8to16) +{ + char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + vector <unsigned short> utf16result; + utf8::unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result)); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(UnCheckedAPITests, test_replace_invalid) +{ + char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + vector<char> replace_invalid_result; + utf8::unchecked::replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), std::back_inserter(replace_invalid_result), '?'); + bool bvalid = utf8::is_valid(replace_invalid_result.begin(), replace_invalid_result.end()); + EXPECT_TRUE (bvalid); + const char fixed_invalid_sequence[] = "a????z"; + EXPECT_EQ (sizeof(fixed_invalid_sequence), replace_invalid_result.size()); + EXPECT_TRUE (std::equal(replace_invalid_result.begin(), replace_invalid_result.begin() + sizeof(fixed_invalid_sequence), fixed_invalid_sequence)); +} + +#endif diff --git a/lib/utfcpp/v4/tests/test_unchecked_iterator.h b/lib/utfcpp/v4/tests/test_unchecked_iterator.h new file mode 100644 index 00000000..4294232d --- /dev/null +++ b/lib/utfcpp/v4/tests/test_unchecked_iterator.h @@ -0,0 +1,36 @@ +#ifndef UTF8_FOR_CPP_TEST_UNCHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_UNCHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/unchecked.h" + +using namespace utf8::unchecked; + + +TEST(UnCheckedIteratrTests, test_increment) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::unchecked::iterator<const char*> it(threechars); + utf8::unchecked::iterator<const char*> it2 = it; + EXPECT_EQ (it2, it); + EXPECT_EQ (*it, 0x10346); + EXPECT_EQ (*(++it), 0x65e5); + EXPECT_EQ ((*it++), 0x65e5); + EXPECT_EQ (*it, 0x0448); + EXPECT_NE (it, it2); + utf8::unchecked::iterator<const char*> endit (threechars + 9); + EXPECT_EQ (++it, endit); +} + +TEST(UnCheckedIteratrTests, test_decrement) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::unchecked::iterator<const char*> it(threechars+9); + EXPECT_EQ (*(--it), 0x0448); + EXPECT_EQ ((*it--), 0x0448); + EXPECT_EQ (*it, 0x65e5); + EXPECT_EQ (--it, utf8::unchecked::iterator<const char*>(threechars)); + EXPECT_EQ (*it, 0x10346); + +} + +#endif |