summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2025-09-04 22:24:13 +0200
committerJoel Klinghed <the_jk@spawned.biz>2025-09-04 22:24:13 +0200
commit65860e6c873e6e056fe3d1dadd1d309b1bd66e7b (patch)
treecb59ed23c72b841fc2688606d68359b3f6b1e324 /test
parentd75b25d50f4df655d1e69ff900cfeee823039296 (diff)
Add UTF-8, UTF-16 and Modified UTF-8 support
Diffstat (limited to 'test')
-rw-r--r--test/u.cc683
1 files changed, 683 insertions, 0 deletions
diff --git a/test/u.cc b/test/u.cc
new file mode 100644
index 0000000..933a4f2
--- /dev/null
+++ b/test/u.cc
@@ -0,0 +1,683 @@
+#include <gtest/gtest.h>
+
+#include "u8.hh"
+#include "umod8.hh"
+#include "u16.hh"
+
+#include <vector>
+
+TEST(u8, empty) {
+ std::vector<uint8_t> empty;
+ auto it = empty.begin();
+ auto ret = u8::read(it, empty.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::End, ret.error());
+
+ auto ret_replace = u8::read_replace(it, empty.end());
+ ASSERT_FALSE(ret_replace.has_value());
+ EXPECT_EQ(u::ReadErrorReplace::End, ret_replace.error());
+
+ EXPECT_FALSE(u8::write(it, empty.end(), 0x40));
+
+ EXPECT_FALSE(u8::skip(it, empty.end()));
+}
+
+TEST(u8, examples) {
+ {
+ std::vector<uint8_t> literal{0x57};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x57, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u8::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xce, 0x92};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x392, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u8::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xec, 0x9c, 0x84};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0xc704, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u8::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xf0, 0x90, 0x8d, 0x85};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x10345, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0x10345, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u8::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(1, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u8::write(it, literal.end(), 0x57));
+ EXPECT_EQ(0x57, literal[0]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(2, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u8::write(it, literal.end(), 0x392));
+ EXPECT_EQ(0xce, literal[0]);
+ EXPECT_EQ(0x92, literal[1]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(3, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u8::write(it, literal.end(), 0xc704));
+ EXPECT_EQ(0xec, literal[0]);
+ EXPECT_EQ(0x9c, literal[1]);
+ EXPECT_EQ(0x84, literal[2]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(4, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u8::write(it, literal.end(), 0x10345));
+ EXPECT_EQ(0xf0, literal[0]);
+ EXPECT_EQ(0x90, literal[1]);
+ EXPECT_EQ(0x8d, literal[2]);
+ EXPECT_EQ(0x85, literal[3]);
+ EXPECT_EQ(it, literal.end());
+ }
+}
+
+TEST(u8, overlong) {
+ {
+ std::vector<uint8_t> literal{0xc0, 0x80};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ }
+}
+
+TEST(u8, incomplete) {
+ {
+ std::vector<uint8_t> literal{0xce};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xec};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xec, 0x9c};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_FALSE(ret_replace.has_value());
+ EXPECT_EQ(u::ReadErrorReplace::Incomplete, ret_replace.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xf0};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xf0, 0x90};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xf0, 0x90, 0x8d};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+}
+
+TEST(u8, invalid) {
+ {
+ std::vector<uint8_t> literal{0xf0, 0xf0, 0xf0, 0xf0};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xa0};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xce, 0xff};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xec, 0xff, 0x84};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xec, 0x9c, 0xff};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xf0, 0xff, 0x8d, 0x85};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xf0, 0x90, 0xff, 0x85};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xf0, 0x90, 0x8d, 0xff};
+ auto it = literal.begin();
+ auto ret = u8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+}
+
+TEST(umod8, empty) {
+ std::vector<uint8_t> empty;
+ auto it = empty.begin();
+ auto ret = umod8::read(it, empty.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::End, ret.error());
+
+ auto ret_replace = umod8::read_replace(it, empty.end());
+ ASSERT_FALSE(ret_replace.has_value());
+ EXPECT_EQ(u::ReadErrorReplace::End, ret_replace.error());
+
+ EXPECT_FALSE(umod8::write(it, empty.end(), 0x40));
+
+ EXPECT_FALSE(umod8::skip(it, empty.end()));
+}
+
+TEST(umod8, examples) {
+ {
+ std::vector<uint8_t> literal{0x45};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x45, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(umod8::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xc8, 0x85};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x205, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(umod8::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xa0, 0x81, 0xed, 0xb0, 0x80};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x10400, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ auto ret_replace = umod8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0x10400, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(umod8::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xc0, 0x80};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0, *ret);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(1, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(umod8::write(it, literal.end(), 0x45));
+ EXPECT_EQ(0x45, literal[0]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(2, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(umod8::write(it, literal.end(), 0x205));
+ EXPECT_EQ(0xc8, literal[0]);
+ EXPECT_EQ(0x85, literal[1]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(6, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(umod8::write(it, literal.end(), 0x10400));
+ EXPECT_EQ(0xed, literal[0]);
+ EXPECT_EQ(0xa0, literal[1]);
+ EXPECT_EQ(0x81, literal[2]);
+ EXPECT_EQ(0xed, literal[3]);
+ EXPECT_EQ(0xb0, literal[4]);
+ EXPECT_EQ(0x80, literal[5]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal(2, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(umod8::write(it, literal.end(), 0x0));
+ EXPECT_EQ(0xc0, literal[0]);
+ EXPECT_EQ(0x80, literal[1]);
+ EXPECT_EQ(it, literal.end());
+ }
+}
+
+TEST(umod8, overlong) {
+}
+
+TEST(umod8, incomplete) {
+ {
+ std::vector<uint8_t> literal{0xc8};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xed};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xa0};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xa0, 0x81, 0xed};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+
+ it = literal.begin();
+ auto ret_replace = umod8::read_replace(it, literal.end());
+ ASSERT_FALSE(ret_replace.has_value());
+ EXPECT_EQ(u::ReadErrorReplace::Incomplete, ret_replace.error());
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xa0, 0x81, 0xed, 0xb0};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+}
+
+TEST(umod8, invalid) {
+ {
+ std::vector<uint8_t> literal{0xf0, 0xf0, 0xf0, 0xf0};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = umod8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(3, literal.end() - it);
+ }
+ {
+ std::vector<uint8_t> literal{0xa0};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = umod8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xce, 0xff};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = umod8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xec, 0xff, 0x84};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = umod8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xec, 0x9c, 0xff};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = umod8::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xb0, 0x80, 0xed, 0xa0, 0x81};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ EXPECT_EQ(3, literal.end() - it);
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xa0, 0x81};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xa0, 0x81, 0xed, 0xff, 0x80};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ EXPECT_EQ(3, literal.end() - it);
+ }
+ {
+ std::vector<uint8_t> literal{0xed, 0xa0, 0x81, 0xed, 0xb0, 0xff};
+ auto it = literal.begin();
+ auto ret = umod8::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ EXPECT_EQ(3, literal.end() - it);
+ }
+}
+
+TEST(u16, empty) {
+ std::vector<uint16_t> empty;
+ auto it = empty.begin();
+ auto ret = u16::read(it, empty.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::End, ret.error());
+
+ auto ret_replace = u16::read_replace(it, empty.end());
+ ASSERT_FALSE(ret_replace.has_value());
+ EXPECT_EQ(u::ReadErrorReplace::End, ret_replace.error());
+
+ EXPECT_FALSE(u16::write(it, empty.end(), 0x40));
+
+ EXPECT_FALSE(u16::skip(it, empty.end()));
+}
+
+TEST(u16, examples) {
+ {
+ std::vector<uint16_t> literal{0x24};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x24, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u16::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint16_t> literal{0x20ac};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x20ac, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u16::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint16_t> literal{0xd801, 0xdc37};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x10437, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u16::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint16_t> literal{0xd852, 0xdf62};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_TRUE(ret.has_value());
+ EXPECT_EQ(0x24b62, *ret);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ auto ret_replace = u16::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0x24b62, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+
+ it = literal.begin();
+ EXPECT_TRUE(u16::skip(it, literal.end()));
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint16_t> literal(1, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u16::write(it, literal.end(), 0x24));
+ EXPECT_EQ(0x24, literal[0]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint16_t> literal(1, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u16::write(it, literal.end(), 0x20ac));
+ EXPECT_EQ(0x20ac, literal[0]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint16_t> literal(2, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u16::write(it, literal.end(), 0x10437));
+ EXPECT_EQ(0xd801, literal[0]);
+ EXPECT_EQ(0xdc37, literal[1]);
+ EXPECT_EQ(it, literal.end());
+ }
+ {
+ std::vector<uint16_t> literal(2, 0x0);
+ auto it = literal.begin();
+ EXPECT_TRUE(u16::write(it, literal.end(), 0x24b62));
+ EXPECT_EQ(0xd852, literal[0]);
+ EXPECT_EQ(0xdf62, literal[1]);
+ EXPECT_EQ(it, literal.end());
+ }
+}
+
+TEST(u16, incomplete) {
+ {
+ std::vector<uint16_t> literal{0xd801};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+ {
+ std::vector<uint16_t> literal{0xd852};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Incomplete, ret.error());
+ }
+}
+
+TEST(u16, invalid) {
+ {
+ std::vector<uint16_t> literal{0xdc37, 0xd801};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u16::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_NE(it, literal.end());
+ ret_replace = u16::read_replace(it, literal.end());
+ ASSERT_FALSE(ret_replace.has_value());
+ EXPECT_EQ(u::ReadErrorReplace::Incomplete, ret_replace.error());
+ }
+ {
+ std::vector<uint16_t> literal{0xd852, 0xd852};
+ auto it = literal.begin();
+ auto ret = u16::read(it, literal.end());
+ ASSERT_FALSE(ret.has_value());
+ EXPECT_EQ(u::ReadError::Invalid, ret.error());
+ it = literal.begin();
+ auto ret_replace = u16::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_NE(it, literal.end());
+ ret_replace = u16::read_replace(it, literal.end());
+ ASSERT_FALSE(ret_replace.has_value());
+ EXPECT_EQ(u::ReadErrorReplace::Incomplete, ret_replace.error());
+ }
+ {
+ std::vector<uint16_t> literal{0xdc37, 0xdf62};
+ auto it = literal.begin();
+ auto ret_replace = u16::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_NE(it, literal.end());
+ ret_replace = u16::read_replace(it, literal.end());
+ ASSERT_TRUE(ret_replace.has_value());
+ EXPECT_EQ(0xfffd, *ret_replace);
+ EXPECT_EQ(it, literal.end());
+ }
+}