diff options
Diffstat (limited to 'base/i18n/bidi_line_iterator_unittest.cc')
-rw-r--r-- | base/i18n/bidi_line_iterator_unittest.cc | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/base/i18n/bidi_line_iterator_unittest.cc b/base/i18n/bidi_line_iterator_unittest.cc new file mode 100644 index 0000000000..d531313bf1 --- /dev/null +++ b/base/i18n/bidi_line_iterator_unittest.cc @@ -0,0 +1,209 @@ +// Copyright 2017 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 "base/i18n/bidi_line_iterator.h" + +#include "base/macros.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace i18n { +namespace { + +class BiDiLineIteratorTest : public testing::TestWithParam<TextDirection> { + public: + BiDiLineIteratorTest() = default; + + BiDiLineIterator* iterator() { return &iterator_; } + + private: + BiDiLineIterator iterator_; + + DISALLOW_COPY_AND_ASSIGN(BiDiLineIteratorTest); +}; + +TEST_P(BiDiLineIteratorTest, OnlyLTR) { + iterator()->Open(UTF8ToUTF16("abc 馃榿 娴嬭瘯"), GetParam(), + BiDiLineIterator::CustomBehavior::NONE); + ASSERT_EQ(1, iterator()->CountRuns()); + + int start, length; + EXPECT_EQ(UBIDI_LTR, iterator()->GetVisualRun(0, &start, &length)); + EXPECT_EQ(0, start); + EXPECT_EQ(9, length); + + int end; + UBiDiLevel level; + iterator()->GetLogicalRun(0, &end, &level); + EXPECT_EQ(9, end); + if (GetParam() == TextDirection::RIGHT_TO_LEFT) + EXPECT_EQ(2, level); + else + EXPECT_EQ(0, level); +} + +TEST_P(BiDiLineIteratorTest, OnlyRTL) { + iterator()->Open(UTF8ToUTF16("诪讛 讛砖注讛"), GetParam(), + BiDiLineIterator::CustomBehavior::NONE); + ASSERT_EQ(1, iterator()->CountRuns()); + + int start, length; + EXPECT_EQ(UBIDI_RTL, iterator()->GetVisualRun(0, &start, &length)); + EXPECT_EQ(0, start); + EXPECT_EQ(7, length); + + int end; + UBiDiLevel level; + iterator()->GetLogicalRun(0, &end, &level); + EXPECT_EQ(7, end); + EXPECT_EQ(1, level); +} + +TEST_P(BiDiLineIteratorTest, Mixed) { + iterator()->Open(UTF8ToUTF16("讗谞讬 诪砖转诪砖 讘- Chrome 讻讚驻讚驻谉 讛讗讬谞讟专谞讟 砖诇讬"), + GetParam(), BiDiLineIterator::CustomBehavior::NONE); + ASSERT_EQ(3, iterator()->CountRuns()); + + // We'll get completely different results depending on the top-level paragraph + // direction. + if (GetParam() == TextDirection::RIGHT_TO_LEFT) { + // If para direction is RTL, expect the LTR substring "Chrome" to be nested + // within the surrounding RTL text. + int start, length; + EXPECT_EQ(UBIDI_RTL, iterator()->GetVisualRun(0, &start, &length)); + EXPECT_EQ(19, start); + EXPECT_EQ(20, length); + EXPECT_EQ(UBIDI_LTR, iterator()->GetVisualRun(1, &start, &length)); + EXPECT_EQ(13, start); + EXPECT_EQ(6, length); + EXPECT_EQ(UBIDI_RTL, iterator()->GetVisualRun(2, &start, &length)); + EXPECT_EQ(0, start); + EXPECT_EQ(13, length); + + int end; + UBiDiLevel level; + iterator()->GetLogicalRun(0, &end, &level); + EXPECT_EQ(13, end); + EXPECT_EQ(1, level); + iterator()->GetLogicalRun(13, &end, &level); + EXPECT_EQ(19, end); + EXPECT_EQ(2, level); + iterator()->GetLogicalRun(19, &end, &level); + EXPECT_EQ(39, end); + EXPECT_EQ(1, level); + } else { + // If the para direction is LTR, expect the LTR substring "- Chrome " to be + // at the top level, with two nested RTL runs on either side. + int start, length; + EXPECT_EQ(UBIDI_RTL, iterator()->GetVisualRun(0, &start, &length)); + EXPECT_EQ(0, start); + EXPECT_EQ(11, length); + EXPECT_EQ(UBIDI_LTR, iterator()->GetVisualRun(1, &start, &length)); + EXPECT_EQ(11, start); + EXPECT_EQ(9, length); + EXPECT_EQ(UBIDI_RTL, iterator()->GetVisualRun(2, &start, &length)); + EXPECT_EQ(20, start); + EXPECT_EQ(19, length); + + int end; + UBiDiLevel level; + iterator()->GetLogicalRun(0, &end, &level); + EXPECT_EQ(11, end); + EXPECT_EQ(1, level); + iterator()->GetLogicalRun(11, &end, &level); + EXPECT_EQ(20, end); + EXPECT_EQ(0, level); + iterator()->GetLogicalRun(20, &end, &level); + EXPECT_EQ(39, end); + EXPECT_EQ(1, level); + } +} + +TEST_P(BiDiLineIteratorTest, RTLPunctuationNoCustomBehavior) { + // This string features Hebrew characters interleaved with ASCII punctuation. + iterator()->Open(UTF8ToUTF16("讗!讘\"讙#讚$讛%讜&讝'讞(讟)讬*讱+讻,诇-诐.诪/" + "谉:谞;住<注=祝>驻?抓@爪[拽\\专]砖^转_讗`讘{讙|讚}讛~讜"), + GetParam(), BiDiLineIterator::CustomBehavior::NONE); + + // Expect a single RTL run. + ASSERT_EQ(1, iterator()->CountRuns()); + + int start, length; + EXPECT_EQ(UBIDI_RTL, iterator()->GetVisualRun(0, &start, &length)); + EXPECT_EQ(0, start); + EXPECT_EQ(65, length); + + int end; + UBiDiLevel level; + iterator()->GetLogicalRun(0, &end, &level); + EXPECT_EQ(65, end); + EXPECT_EQ(1, level); +} + +TEST_P(BiDiLineIteratorTest, RTLPunctuationAsURL) { + // This string features Hebrew characters interleaved with ASCII punctuation. + iterator()->Open(UTF8ToUTF16("讗!讘\"讙#讚$讛%讜&讝'讞(讟)讬*讱+讻,诇-诐.诪/" + "谉:谞;住<注=祝>驻?抓@爪[拽\\专]砖^转_讗`讘{讙|讚}讛~讜"), + GetParam(), BiDiLineIterator::CustomBehavior::AS_URL); + + const int kStringSize = 65; + + // Expect a primary RTL run, broken up by each of the 8 punctuation marks that + // are considered strong LTR (17 runs total). + struct { + int start; + UBiDiDirection dir; + } expected_runs[] = { + {0, UBIDI_RTL}, {5, UBIDI_LTR}, // '#' + {6, UBIDI_RTL}, {11, UBIDI_LTR}, // '&' + {12, UBIDI_RTL}, {27, UBIDI_LTR}, // '.' + {28, UBIDI_RTL}, {29, UBIDI_LTR}, // '/' + {30, UBIDI_RTL}, {31, UBIDI_LTR}, // ':' + {32, UBIDI_RTL}, {37, UBIDI_LTR}, // '=' + {38, UBIDI_RTL}, {41, UBIDI_LTR}, // '?' + {42, UBIDI_RTL}, {43, UBIDI_LTR}, // '@' + {44, UBIDI_RTL}, + }; + + ASSERT_EQ(arraysize(expected_runs), + static_cast<size_t>(iterator()->CountRuns())); + + for (size_t i = 0; i < arraysize(expected_runs); ++i) { + const auto& expected_run = expected_runs[i]; + int expected_run_end = i >= arraysize(expected_runs) - 1 + ? kStringSize + : expected_runs[i + 1].start; + + size_t visual_index = GetParam() == TextDirection::RIGHT_TO_LEFT + ? arraysize(expected_runs) - 1 - i + : i; + int start, length; + EXPECT_EQ(expected_run.dir, + iterator()->GetVisualRun(visual_index, &start, &length)) + << "(i = " << i << ")"; + EXPECT_EQ(expected_run.start, start) << "(i = " << i << ")"; + EXPECT_EQ(expected_run_end - expected_run.start, length) + << "(i = " << i << ")"; + + int expected_level = + expected_run.dir == UBIDI_RTL + ? 1 + : (GetParam() == TextDirection::RIGHT_TO_LEFT ? 2 : 0); + int end; + UBiDiLevel level; + iterator()->GetLogicalRun(expected_run.start, &end, &level); + EXPECT_EQ(expected_run_end, end) << "(i = " << i << ")"; + EXPECT_EQ(expected_level, level) << "(i = " << i << ")"; + } +} + +INSTANTIATE_TEST_CASE_P(, + BiDiLineIteratorTest, + ::testing::Values(TextDirection::LEFT_TO_RIGHT, + TextDirection::RIGHT_TO_LEFT)); + +} // namespace +} // namespace i18n +} // namespace base |