blob: fe01532716b021b9553171137a3e5afd763e6930 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h"
#include <unicode/unistr.h>
#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/text/character.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
namespace blink {
TEST(UTF16RagelIteratorTest, CharacterClasses) {
UChar32 class_examples_codepoints[] = {
kCombiningEnclosingKeycapCharacter,
kCombiningEnclosingCircleBackslashCharacter,
kZeroWidthJoinerCharacter,
kVariationSelector15Character,
kVariationSelector16Character,
0x1f3f4,
0xE0030,
kCancelTag,
0x261D,
0x1F3FB,
0x1F1E6,
0x0030,
0x231A,
0x00A9};
icu::UnicodeString class_examples_unicode_string =
icu::UnicodeString::fromUTF32(class_examples_codepoints,
base::size(class_examples_codepoints));
char categories[] = {UTF16RagelIterator::COMBINING_ENCLOSING_KEYCAP,
UTF16RagelIterator::COMBINING_ENCLOSING_CIRCLE_BACKSLASH,
UTF16RagelIterator::ZWJ,
UTF16RagelIterator::VS15,
UTF16RagelIterator::VS16,
UTF16RagelIterator::TAG_BASE,
UTF16RagelIterator::TAG_SEQUENCE,
UTF16RagelIterator::TAG_TERM,
UTF16RagelIterator::EMOJI_MODIFIER_BASE,
UTF16RagelIterator::EMOJI_MODIFIER,
UTF16RagelIterator::REGIONAL_INDICATOR,
UTF16RagelIterator::KEYCAP_BASE,
UTF16RagelIterator::EMOJI_EMOJI_PRESENTATION,
UTF16RagelIterator::EMOJI_TEXT_PRESENTATION};
UTF16RagelIterator ragel_iterator(
reinterpret_cast<const UChar*>(class_examples_unicode_string.getBuffer()),
class_examples_unicode_string.length());
for (char& category : categories) {
CHECK_EQ(category, *ragel_iterator);
ragel_iterator++;
}
UTF16RagelIterator reverse_ragel_iterator(
reinterpret_cast<const UChar*>(class_examples_unicode_string.getBuffer()),
class_examples_unicode_string.length(),
class_examples_unicode_string.length() - 1);
size_t i = base::size(categories) - 1;
while (reverse_ragel_iterator.Cursor() > 0) {
CHECK_EQ(categories[i], *reverse_ragel_iterator);
i--;
reverse_ragel_iterator--;
};
}
TEST(UTF16RagelIteratorTest, ArithmeticOperators) {
UChar32 class_examples_codepoints[] = {
kVariationSelector15Character, kVariationSelector15Character,
kVariationSelector15Character, kVariationSelector16Character,
kVariationSelector16Character, kVariationSelector16Character,
};
icu::UnicodeString class_examples_unicode_string =
icu::UnicodeString::fromUTF32(class_examples_codepoints,
base::size(class_examples_codepoints));
UTF16RagelIterator ragel_iterator(
reinterpret_cast<const UChar*>(class_examples_unicode_string.getBuffer()),
class_examples_unicode_string.length());
CHECK_EQ(*ragel_iterator, UTF16RagelIterator::VS15);
CHECK_EQ(*(ragel_iterator + 2), UTF16RagelIterator::VS15);
CHECK_EQ(*(ragel_iterator + 3), UTF16RagelIterator::VS16);
CHECK_EQ(*(ragel_iterator + 5), UTF16RagelIterator::VS16);
CHECK_EQ(*(ragel_iterator += 3), UTF16RagelIterator::VS16);
CHECK_EQ(*(ragel_iterator += 2), UTF16RagelIterator::VS16);
CHECK_EQ(*(ragel_iterator -= 4), UTF16RagelIterator::VS15);
CHECK_EQ(*(ragel_iterator += 1), UTF16RagelIterator::VS15);
ragel_iterator += 3;
UTF16RagelIterator ragel_iterator_begin = ragel_iterator - 5;
CHECK(ragel_iterator != ragel_iterator_begin);
CHECK(ragel_iterator == ragel_iterator.end() - 1);
CHECK_EQ(*ragel_iterator, UTF16RagelIterator::VS16);
CHECK_EQ(*(ragel_iterator - 2), UTF16RagelIterator::VS16);
CHECK_EQ(*(ragel_iterator - 3), UTF16RagelIterator::VS15);
CHECK_EQ(*(ragel_iterator - 5), UTF16RagelIterator::VS15);
}
TEST(UTF16RagelIteratorTest, InvalidOperationOnEmpty) {
UTF16RagelIterator ragel_iterator;
CHECK_EQ(ragel_iterator.Cursor(), 0u);
#if DCHECK_IS_ON()
EXPECT_DEATH_IF_SUPPORTED(ragel_iterator++, "");
EXPECT_DEATH_IF_SUPPORTED(ragel_iterator--, "");
EXPECT_DEATH_IF_SUPPORTED(*ragel_iterator, "");
#endif
}
TEST(UTF16RagelIteratorTest, CursorPositioning) {
UChar32 flags_codepoints[] = {0x1F99E, 0x1F99E, 0x1F99E,
kLeftSpeechBubbleCharacter};
icu::UnicodeString flags_unicode_string = icu::UnicodeString::fromUTF32(
flags_codepoints, base::size(flags_codepoints));
UTF16RagelIterator ragel_iterator(
reinterpret_cast<const UChar*>(flags_unicode_string.getBuffer()),
flags_unicode_string.length());
CHECK_EQ(ragel_iterator.end().Cursor(), 8u);
CHECK_EQ(*ragel_iterator, UTF16RagelIterator::EMOJI_EMOJI_PRESENTATION);
CHECK_EQ(*(ragel_iterator.SetCursor(4)),
UTF16RagelIterator::EMOJI_EMOJI_PRESENTATION);
CHECK_EQ(*(ragel_iterator.SetCursor(6)),
UTF16RagelIterator::EMOJI_TEXT_PRESENTATION);
#if DCHECK_IS_ON()
EXPECT_DEATH_IF_SUPPORTED(ragel_iterator.SetCursor(-1), "");
EXPECT_DEATH_IF_SUPPORTED(
ragel_iterator.SetCursor(ragel_iterator.end().Cursor()), "");
#endif
}
} // namespace blink