d09fdd61cb
Many include statements use forward slashes, while others use backwards slashes. This is inconsistent formatting. For this reason, I changed the backward slashes to forward slashes since that is the standard.
102 lines
3.4 KiB
C++
102 lines
3.4 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include "precomp.h"
|
|
#include "WexTestClass.h"
|
|
#include "../../inc/consoletaeftemplates.hpp"
|
|
#include "CommonState.hpp"
|
|
|
|
#include "../types/inc/CodepointWidthDetector.hpp"
|
|
|
|
using namespace WEX::Logging;
|
|
|
|
static constexpr std::wstring_view emoji = L"\xD83E\xDD22"; // U+1F922 nauseated face
|
|
|
|
static constexpr std::wstring_view ambiguous = L"\x414"; // U+0414 cyrillic capital de
|
|
|
|
// codepoint and utf16 encoded string
|
|
static const std::vector<std::tuple<unsigned int, std::wstring, CodepointWidth>> testData = {
|
|
{ 0x7, L"\a", CodepointWidth::Narrow }, // BEL
|
|
{ 0x20, L" ", CodepointWidth::Narrow },
|
|
{ 0x39, L"9", CodepointWidth::Narrow },
|
|
{ 0x414, L"\x414", CodepointWidth::Ambiguous }, // U+0414 cyrillic capital de
|
|
{ 0x1104, L"\x1104", CodepointWidth::Wide }, // U+1104 hangul choseong ssangtikeut
|
|
{ 0x306A, L"\x306A", CodepointWidth::Wide }, // U+306A hiragana na
|
|
{ 0x30CA, L"\x30CA", CodepointWidth::Wide }, // U+30CA katakana na
|
|
{ 0x72D7, L"\x72D7", CodepointWidth::Wide }, // U+72D7
|
|
{ 0x1F47E, L"\xD83D\xDC7E", CodepointWidth::Wide }, // U+1F47E alien monster
|
|
{ 0x1F51C, L"\xD83D\xDD1C", CodepointWidth::Wide } // U+1F51C SOON
|
|
};
|
|
|
|
class CodepointWidthDetectorTests
|
|
{
|
|
TEST_CLASS(CodepointWidthDetectorTests);
|
|
|
|
TEST_METHOD(CanLookUpEmoji)
|
|
{
|
|
CodepointWidthDetector widthDetector;
|
|
VERIFY_IS_TRUE(widthDetector.IsWide(emoji));
|
|
}
|
|
|
|
TEST_METHOD(CanExtractCodepoint)
|
|
{
|
|
CodepointWidthDetector widthDetector;
|
|
for (const auto& data : testData)
|
|
{
|
|
const auto& expected = std::get<0>(data);
|
|
const auto& wstr = std::get<1>(data);
|
|
const auto result = widthDetector._extractCodepoint({ wstr.c_str(), wstr.size() });
|
|
VERIFY_ARE_EQUAL(result, expected);
|
|
}
|
|
}
|
|
|
|
TEST_METHOD(CanGetWidths)
|
|
{
|
|
CodepointWidthDetector widthDetector;
|
|
for (const auto& data : testData)
|
|
{
|
|
const auto& expected = std::get<2>(data);
|
|
const auto& wstr = std::get<1>(data);
|
|
const auto result = widthDetector.GetWidth({ wstr.c_str(), wstr.size() });
|
|
VERIFY_ARE_EQUAL(result, expected);
|
|
}
|
|
}
|
|
|
|
static bool FallbackMethod(const std::wstring_view glyph)
|
|
{
|
|
if (glyph.size() < 1)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return (glyph.at(0) % 2) == 1;
|
|
}
|
|
}
|
|
|
|
TEST_METHOD(AmbiguousCache)
|
|
{
|
|
// Set up a detector with fallback.
|
|
CodepointWidthDetector widthDetector;
|
|
widthDetector.SetFallbackMethod(std::bind(&FallbackMethod, std::placeholders::_1));
|
|
|
|
// Ensure fallback cache is empty.
|
|
VERIFY_ARE_EQUAL(0u, widthDetector._fallbackCache.size());
|
|
|
|
// Lookup ambiguous width character.
|
|
widthDetector.IsWide(ambiguous);
|
|
|
|
// Cache should hold it.
|
|
VERIFY_ARE_EQUAL(1u, widthDetector._fallbackCache.size());
|
|
|
|
// Cached item should match what we expect
|
|
const auto it = widthDetector._fallbackCache.begin();
|
|
VERIFY_ARE_EQUAL(ambiguous, it->first);
|
|
VERIFY_ARE_EQUAL(FallbackMethod(ambiguous), it->second);
|
|
|
|
// Cache should empty when font changes.
|
|
widthDetector.NotifyFontChanged();
|
|
VERIFY_ARE_EQUAL(0u, widthDetector._fallbackCache.size());
|
|
}
|
|
};
|