/*** * ==++== * * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ==--== * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * base64.cpp * * Tests for base64-related utility functions and classes. * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #include "stdafx.h" #if !defined(__GLIBCXX__) #include #endif #include using namespace utility; namespace tests { namespace functional { namespace utils_tests { SUITE(strings) { TEST(usascii_to_utf16) { std::string str_ascii("This is a test"); utf16string str_utf16 = utility::conversions::usascii_to_utf16(str_ascii); for (size_t i = 0; i < str_ascii.size(); ++i) { VERIFY_ARE_EQUAL((utf16char)str_ascii[i], str_utf16[i]); } } #ifdef _WIN32 #define UTF16(x) L ## x #else #define UTF16(x) u ## x #endif TEST(utf16_to_utf8) { #if !defined(__GLIBCXX__) std::wstring_convert, utf16char> conversion; #endif // encodes to single byte character VERIFY_ARE_EQUAL("ABC987", utility::conversions::utf16_to_utf8(UTF16("ABC987"))); utf16string input; input.push_back(0x7F); // last ASCII character auto result = utility::conversions::utf16_to_utf8(input); VERIFY_ARE_EQUAL(0x7F, result[0]); // encodes to 2 byte character input.clear(); input.push_back(0x80); input.push_back(0x14D); input.push_back(0x7FF); result = utility::conversions::utf16_to_utf8(input); #if defined(__GLIBCXX__) VERIFY_ARE_EQUAL(194u, static_cast(result[0])); VERIFY_ARE_EQUAL(128u, static_cast(result[1])); VERIFY_ARE_EQUAL(197u, static_cast(result[2])); VERIFY_ARE_EQUAL(141u, static_cast(result[3])); VERIFY_ARE_EQUAL(223u, static_cast(result[4])); VERIFY_ARE_EQUAL(191u, static_cast(result[5])); #else VERIFY_ARE_EQUAL(conversion.to_bytes(input), result); #endif // encodes to 3 byte character input.clear(); input.push_back(0x800); input.push_back(0x14AB); input.push_back(0xFFFF); result = utility::conversions::utf16_to_utf8(input); #if defined(__GLIBCXX__) VERIFY_ARE_EQUAL(224u, static_cast(result[0])); VERIFY_ARE_EQUAL(160u, static_cast(result[1])); VERIFY_ARE_EQUAL(128u, static_cast(result[2])); VERIFY_ARE_EQUAL(225u, static_cast(result[3])); VERIFY_ARE_EQUAL(146u, static_cast(result[4])); VERIFY_ARE_EQUAL(171u, static_cast(result[5])); VERIFY_ARE_EQUAL(239u, static_cast(result[6])); VERIFY_ARE_EQUAL(191u, static_cast(result[7])); VERIFY_ARE_EQUAL(191u, static_cast(result[8])); #else VERIFY_ARE_EQUAL(conversion.to_bytes(input), result); #endif // surrogate pair - encodes to 4 byte character input.clear(); // U+10000 input.push_back(0xD800); input.push_back(0xDC00); // U+12345 input.push_back(0xD802); input.push_back(0xDD29); // U+10FFFF input.push_back(0xDA3F); input.push_back(0xDFFF); result = utility::conversions::utf16_to_utf8(input); #if defined(__GLIBCXX__) VERIFY_ARE_EQUAL(240u, static_cast(result[0])); VERIFY_ARE_EQUAL(144u, static_cast(result[1])); VERIFY_ARE_EQUAL(128u, static_cast(result[2])); VERIFY_ARE_EQUAL(128u, static_cast(result[3])); VERIFY_ARE_EQUAL(240u, static_cast(result[4])); VERIFY_ARE_EQUAL(144u, static_cast(result[5])); VERIFY_ARE_EQUAL(164u, static_cast(result[6])); VERIFY_ARE_EQUAL(169u, static_cast(result[7])); VERIFY_ARE_EQUAL(242u, static_cast(result[8])); VERIFY_ARE_EQUAL(159u, static_cast(result[9])); VERIFY_ARE_EQUAL(191u, static_cast(result[10])); VERIFY_ARE_EQUAL(191u, static_cast(result[11])); #else VERIFY_ARE_EQUAL(conversion.to_bytes(input), result); #endif } TEST(utf8_to_utf16) { #if !defined(__GLIBCXX__) std::wstring_convert, utf16char> conversion; #endif // single byte character VERIFY_ARE_EQUAL(UTF16("ABC123"), utility::conversions::utf8_to_utf16("ABC123")); std::string input; input.push_back(0x7F); // last ASCII character auto result = utility::conversions::utf8_to_utf16(input); VERIFY_ARE_EQUAL(0x7F, result[0]); // 2 byte character input.clear(); // U+80 input.push_back(208u); // 11010000 input.push_back(128u); // 10000000 // U+7FF input.push_back(223u); // 11011111 input.push_back(191u); // 10111111 result = utility::conversions::utf8_to_utf16(input); #if defined(__GLIBCXX__) VERIFY_ARE_EQUAL(1024, result[0]); VERIFY_ARE_EQUAL(2047, result[1]); #else VERIFY_ARE_EQUAL(conversion.from_bytes(input), result); #endif // 3 byte character input.clear(); // U+800 input.push_back(232u); // 11101000 input.push_back(128u); // 10000000 input.push_back(128u); // 10000000 // U+FFFF input.push_back(239u); // 11101111 input.push_back(191u); // 10111111 input.push_back(191u); // 10111111 result = utility::conversions::utf8_to_utf16(input); #if defined(__GLIBCXX__) VERIFY_ARE_EQUAL(32768, result[0]); VERIFY_ARE_EQUAL(65535, result[1]); #else VERIFY_ARE_EQUAL(conversion.from_bytes(input), result); #endif // 4 byte character input.clear(); // U+10000 input.push_back(244u); // 11110100 input.push_back(128u); // 10000000 input.push_back(128u); // 10000000 input.push_back(128u); // 10000000 // U+10FFFF input.push_back(244u); // 11110100 input.push_back(143u); // 10001111 input.push_back(191u); // 10111111 input.push_back(191u); // 10111111 result = utility::conversions::utf8_to_utf16(input); #if defined(__GLIBCXX__) VERIFY_ARE_EQUAL(56256, result[0]); VERIFY_ARE_EQUAL(56320, result[1]); VERIFY_ARE_EQUAL(56319, result[2]); VERIFY_ARE_EQUAL(57343, result[3]); #else VERIFY_ARE_EQUAL(conversion.from_bytes(input), result); #endif } TEST(utf16_to_utf8_errors) { VERIFY_ARE_EQUAL("ABC987", utility::conversions::utf16_to_utf8(UTF16("ABC987"))); utf16string input; // high surrogate with missing low surrogate. input.push_back(0xD800); input.push_back(0x0); VERIFY_THROWS(utility::conversions::utf16_to_utf8(input), std::range_error); // high surrogate with no more characters input.clear(); input.push_back(0xD800); VERIFY_THROWS(utility::conversions::utf16_to_utf8(input), std::range_error); } TEST(utf8_to_utf16_errors) { // missing second continuation byte std::string input; input.push_back(207u); // 11001111 VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); // missing third continuation byte input.clear(); input.push_back(230u); // 11100110 input.push_back(141u); // 10001101 VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); // missing fourth continuation byte input.clear(); input.push_back(240u); // 11110000 input.push_back(173u); // 10101101 input.push_back(157u); // 10011101 VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); // continuation byte missing leading 10xxxxxx input.clear(); input.push_back(230u); // 11100110 input.push_back(141u); // 00001101 VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); input.clear(); input.push_back(230u); // 11100110 input.push_back(141u); // 11001101 VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); // invalid for a first character to start with 1xxxxxxx input.clear(); input.push_back(128u); // 10000000 input.push_back(128u); // 10000000 VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); input.clear(); input.push_back(191u); // 10111111 input.push_back(128u); // 10000000 VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); } TEST(latin1_to_utf16) { // TODO: find some string that actually uses something unique to the Latin1 code page. std::string str_latin1("This is a test"); utf16string str_utf16 = utility::conversions::latin1_to_utf16(str_latin1); for (size_t i = 0; i < str_latin1.size(); ++i) { VERIFY_ARE_EQUAL((utf16char)str_latin1[i], str_utf16[i]); } } TEST(print_string_locale, "Ignore:Android", "Locale unsupported on Android") { std::locale changedLocale; try { #ifdef _WIN32 changedLocale = std::locale("fr-FR"); #else changedLocale = std::locale("fr_FR.UTF-8"); #endif } catch (const std::exception &) { // Silently pass if locale isn't installed on machine. return; } tests::common::utilities::locale_guard loc(changedLocale); utility::ostringstream_t oss; oss << 1000; VERIFY_ARE_EQUAL(oss.str(), utility::conversions::print_string(1000)); VERIFY_ARE_EQUAL(_XPLATSTR("1000"), utility::conversions::print_string(1000, std::locale::classic())); } TEST(scan_string_locale, "Ignore:Android", "Locale unsupported on Android") { std::locale changedLocale; try { #ifdef _WIN32 changedLocale = std::locale("fr-FR"); #else changedLocale = std::locale("fr_FR.UTF-8"); #endif } catch (const std::exception &) { // Silently pass if locale isn't installed on machine. return; } VERIFY_ARE_EQUAL(_XPLATSTR("1000"), utility::conversions::scan_string(utility::string_t(_XPLATSTR("1000")))); VERIFY_ARE_EQUAL(_XPLATSTR("1,000"), utility::conversions::scan_string(utility::string_t(_XPLATSTR("1,000")))); VERIFY_ARE_EQUAL(_XPLATSTR("1000"), utility::conversions::scan_string(utility::string_t(_XPLATSTR("1000")), changedLocale)); VERIFY_ARE_EQUAL(_XPLATSTR("1,000"), utility::conversions::scan_string(utility::string_t(_XPLATSTR("1,000")), changedLocale)); { tests::common::utilities::locale_guard loc(changedLocale); VERIFY_ARE_EQUAL(_XPLATSTR("1000"), utility::conversions::scan_string(utility::string_t(_XPLATSTR("1000")), std::locale::classic())); VERIFY_ARE_EQUAL(_XPLATSTR("1,000"), utility::conversions::scan_string(utility::string_t(_XPLATSTR("1,000")), std::locale::classic())); } } } }}} //namespaces