515 lines
15 KiB
C++
515 lines
15 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include "precomp.h"
|
|
#include "WexTestClass.h"
|
|
#include "../../inc/consoletaeftemplates.hpp"
|
|
|
|
#include "../buffer/out/outputCellIterator.hpp"
|
|
|
|
using namespace WEX::Common;
|
|
using namespace WEX::Logging;
|
|
using namespace WEX::TestExecution;
|
|
|
|
static constexpr TextAttribute InvalidTextAttribute{ INVALID_COLOR, INVALID_COLOR };
|
|
|
|
class OutputCellIteratorTests
|
|
{
|
|
CommonState* m_state;
|
|
|
|
TEST_CLASS(OutputCellIteratorTests);
|
|
|
|
TEST_METHOD(CharacterFillDoubleWidth)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const wchar_t wch = L'\x30a2'; // katakana A
|
|
const size_t limit = 5;
|
|
|
|
OutputCellIterator it(wch, limit);
|
|
|
|
OutputCellView expectedLead({ &wch, 1 },
|
|
DbcsAttribute(DbcsAttribute::Attribute::Leading),
|
|
InvalidTextAttribute,
|
|
TextAttributeBehavior::Current);
|
|
|
|
OutputCellView expectedTrail({ &wch, 1 },
|
|
DbcsAttribute(DbcsAttribute::Attribute::Trailing),
|
|
InvalidTextAttribute,
|
|
TextAttributeBehavior::Current);
|
|
|
|
for (size_t i = 0; i < limit; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expectedLead, *it);
|
|
it++;
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expectedTrail, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(CharacterFillLimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const wchar_t wch = L'Q';
|
|
const size_t limit = 5;
|
|
|
|
OutputCellIterator it(wch, limit);
|
|
|
|
OutputCellView expected({ &wch, 1 },
|
|
DbcsAttribute{},
|
|
InvalidTextAttribute,
|
|
TextAttributeBehavior::Current);
|
|
|
|
for (size_t i = 0; i < limit; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(CharacterFillUnlimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const wchar_t wch = L'Q';
|
|
|
|
OutputCellIterator it(wch);
|
|
|
|
OutputCellView expected({ &wch, 1 },
|
|
DbcsAttribute{},
|
|
InvalidTextAttribute,
|
|
TextAttributeBehavior::Current);
|
|
|
|
for (size_t i = 0; i < SHORT_MAX; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
}
|
|
|
|
TEST_METHOD(AttributeFillLimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const TextAttribute attr(FOREGROUND_RED | BACKGROUND_BLUE);
|
|
|
|
const size_t limit = 5;
|
|
|
|
OutputCellIterator it(attr, limit);
|
|
|
|
OutputCellView expected({},
|
|
{},
|
|
attr,
|
|
TextAttributeBehavior::StoredOnly);
|
|
|
|
for (size_t i = 0; i < limit; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(AttributeFillUnlimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const TextAttribute attr(FOREGROUND_RED | BACKGROUND_BLUE);
|
|
|
|
OutputCellIterator it(attr);
|
|
|
|
OutputCellView expected({},
|
|
{},
|
|
attr,
|
|
TextAttributeBehavior::StoredOnly);
|
|
|
|
for (size_t i = 0; i < SHORT_MAX; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
}
|
|
|
|
TEST_METHOD(TextAndAttributeFillLimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const wchar_t wch = L'Q';
|
|
|
|
const TextAttribute attr(FOREGROUND_RED | BACKGROUND_BLUE);
|
|
|
|
const size_t limit = 5;
|
|
|
|
OutputCellIterator it(wch, attr, limit);
|
|
|
|
OutputCellView expected({ &wch, 1 },
|
|
{},
|
|
attr,
|
|
TextAttributeBehavior::Stored);
|
|
|
|
for (size_t i = 0; i < limit; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(TextAndAttributeFillUnlimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const wchar_t wch = L'Q';
|
|
|
|
const TextAttribute attr(FOREGROUND_RED | BACKGROUND_BLUE);
|
|
|
|
OutputCellIterator it(wch, attr);
|
|
|
|
OutputCellView expected({ &wch, 1 },
|
|
{},
|
|
attr,
|
|
TextAttributeBehavior::Stored);
|
|
|
|
for (size_t i = 0; i < SHORT_MAX; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
}
|
|
|
|
TEST_METHOD(CharInfoFillLimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
CHAR_INFO ci;
|
|
ci.Char.UnicodeChar = L'Q';
|
|
ci.Attributes = FOREGROUND_RED | BACKGROUND_BLUE;
|
|
|
|
const size_t limit = 5;
|
|
|
|
OutputCellIterator it(ci, limit);
|
|
|
|
OutputCellView expected({ &ci.Char.UnicodeChar, 1 },
|
|
{},
|
|
TextAttribute(ci.Attributes),
|
|
TextAttributeBehavior::Stored);
|
|
|
|
for (size_t i = 0; i < limit; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(CharInfoFillUnlimited)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
CHAR_INFO ci;
|
|
ci.Char.UnicodeChar = L'Q';
|
|
ci.Attributes = FOREGROUND_RED | BACKGROUND_BLUE;
|
|
|
|
OutputCellIterator it(ci);
|
|
|
|
OutputCellView expected({ &ci.Char.UnicodeChar, 1 },
|
|
{},
|
|
TextAttribute(ci.Attributes),
|
|
TextAttributeBehavior::Stored);
|
|
|
|
for (size_t i = 0; i < SHORT_MAX; i++)
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
}
|
|
|
|
TEST_METHOD(StringData)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const std::wstring testText(L"The quick brown fox jumps over the lazy dog.");
|
|
|
|
OutputCellIterator it(testText);
|
|
|
|
for (const auto& wch : testText)
|
|
{
|
|
OutputCellView expected({ &wch, 1 },
|
|
{},
|
|
InvalidTextAttribute,
|
|
TextAttributeBehavior::Current);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(FullWidthStringData)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const std::wstring testText(L"\x30a2\x30a3\x30a4\x30a5\x30a6");
|
|
|
|
OutputCellIterator it(testText);
|
|
|
|
for (const auto& wch : testText)
|
|
{
|
|
auto expected = OutputCellView({ &wch, 1 },
|
|
DbcsAttribute(DbcsAttribute::Attribute::Leading),
|
|
InvalidTextAttribute,
|
|
TextAttributeBehavior::Current);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
|
|
expected = OutputCellView({ &wch, 1 },
|
|
DbcsAttribute(DbcsAttribute::Attribute::Trailing),
|
|
InvalidTextAttribute,
|
|
TextAttributeBehavior::Current);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(StringDataWithColor)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const std::wstring testText(L"The quick brown fox jumps over the lazy dog.");
|
|
const TextAttribute color(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
|
|
|
OutputCellIterator it(testText, color);
|
|
|
|
for (const auto& wch : testText)
|
|
{
|
|
OutputCellView expected({ &wch, 1 },
|
|
{},
|
|
color,
|
|
TextAttributeBehavior::Stored);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(FullWidthStringDataWithColor)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const std::wstring testText(L"\x30a2\x30a3\x30a4\x30a5\x30a6");
|
|
const TextAttribute color(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
|
|
|
OutputCellIterator it(testText, color);
|
|
|
|
for (const auto& wch : testText)
|
|
{
|
|
auto expected = OutputCellView({ &wch, 1 },
|
|
DbcsAttribute(DbcsAttribute::Attribute::Leading),
|
|
color,
|
|
TextAttributeBehavior::Stored);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
|
|
expected = OutputCellView({ &wch, 1 },
|
|
DbcsAttribute(DbcsAttribute::Attribute::Trailing),
|
|
color,
|
|
TextAttributeBehavior::Stored);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(LegacyColorDataRun)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const std::vector<WORD> colors{ FOREGROUND_GREEN, FOREGROUND_RED | BACKGROUND_BLUE, FOREGROUND_BLUE | FOREGROUND_INTENSITY, BACKGROUND_GREEN };
|
|
const gsl::span<const WORD> view{ colors.data(), colors.size() };
|
|
|
|
OutputCellIterator it(view);
|
|
|
|
for (const auto& color : colors)
|
|
{
|
|
auto expected = OutputCellView({},
|
|
{},
|
|
TextAttribute{ color },
|
|
TextAttributeBehavior::StoredOnly);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(LegacyCharInfoRun)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
std::vector<CHAR_INFO> charInfos;
|
|
|
|
for (auto i = 0; i < 5; i++)
|
|
{
|
|
CHAR_INFO ci;
|
|
ci.Char.UnicodeChar = static_cast<wchar_t>(L'A' + i);
|
|
ci.Attributes = gsl::narrow<WORD>(i);
|
|
|
|
charInfos.push_back(ci);
|
|
}
|
|
|
|
const gsl::span<const CHAR_INFO> view{ charInfos.data(), charInfos.size() };
|
|
|
|
OutputCellIterator it(view);
|
|
|
|
for (const auto& ci : charInfos)
|
|
{
|
|
auto expected = OutputCellView({ &ci.Char.UnicodeChar, 1 },
|
|
{},
|
|
TextAttribute{ ci.Attributes },
|
|
TextAttributeBehavior::Stored);
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(OutputCellRun)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
std::vector<OutputCell> cells;
|
|
|
|
for (auto i = 0; i < 5; i++)
|
|
{
|
|
const std::wstring pair(L"\xd834\xdd1e");
|
|
OutputCell cell(pair, {}, TextAttribute{ gsl::narrow<WORD>(i) });
|
|
cells.push_back(cell);
|
|
}
|
|
|
|
const gsl::span<const OutputCell> view{ cells.data(), cells.size() };
|
|
|
|
OutputCellIterator it(view);
|
|
|
|
for (const auto& cell : cells)
|
|
{
|
|
auto expected = OutputCellView(cell.Chars(),
|
|
cell.DbcsAttr(),
|
|
cell.TextAttr(),
|
|
cell.TextAttrBehavior());
|
|
|
|
VERIFY_IS_TRUE(it);
|
|
VERIFY_ARE_EQUAL(expected, *it);
|
|
it++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
}
|
|
|
|
TEST_METHOD(DistanceStandard)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const std::wstring testText(L"The quick brown fox jumps over the lazy dog.");
|
|
|
|
OutputCellIterator it(testText);
|
|
|
|
const auto original = it;
|
|
|
|
ptrdiff_t expected = 0;
|
|
for (const auto& wch : testText)
|
|
{
|
|
wch; // unused
|
|
VERIFY_IS_TRUE(it);
|
|
it++;
|
|
|
|
expected++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
VERIFY_ARE_EQUAL(expected, it.GetCellDistance(original));
|
|
VERIFY_ARE_EQUAL(expected, it.GetInputDistance(original));
|
|
}
|
|
|
|
TEST_METHOD(DistanceFullWidth)
|
|
{
|
|
SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
|
|
|
|
const std::wstring testText(L"QWER\x30a2\x30a3\x30a4\x30a5\x30a6TYUI");
|
|
|
|
OutputCellIterator it(testText);
|
|
|
|
const auto original = it;
|
|
|
|
ptrdiff_t cellsExpected = 0;
|
|
ptrdiff_t inputExpected = 0;
|
|
for (const auto& wch : testText)
|
|
{
|
|
wch; // unused
|
|
VERIFY_IS_TRUE(it);
|
|
const auto value = *it;
|
|
it++;
|
|
|
|
if (value.DbcsAttr().IsLeading() || value.DbcsAttr().IsTrailing())
|
|
{
|
|
VERIFY_IS_TRUE(it);
|
|
it++;
|
|
cellsExpected++;
|
|
}
|
|
|
|
cellsExpected++;
|
|
inputExpected++;
|
|
}
|
|
|
|
VERIFY_IS_FALSE(it);
|
|
VERIFY_ARE_EQUAL(cellsExpected, it.GetCellDistance(original));
|
|
VERIFY_ARE_EQUAL(inputExpected, it.GetInputDistance(original));
|
|
}
|
|
};
|