| Index: third_party/WebKit/Source/core/editing/state_machines/ForwardGraphemeBoundaryStateMachineTest.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/state_machines/ForwardGraphemeBoundaryStateMachineTest.cpp b/third_party/WebKit/Source/core/editing/state_machines/ForwardGraphemeBoundaryStateMachineTest.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f27ecafce8abd8b3e7aee43e6fc2d2f93110a763
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/core/editing/state_machines/ForwardGraphemeBoundaryStateMachineTest.cpp
|
| @@ -0,0 +1,629 @@
|
| +// Copyright 2016 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 "core/editing/state_machines/ForwardGraphemeBoundaryStateMachine.h"
|
| +
|
| +#include "core/editing/state_machines/StateMachineTestUtil.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "wtf/text/CharacterNames.h"
|
| +
|
| +namespace blink {
|
| +
|
| +// Notations:
|
| +// | indicates inidicates initial offset position.
|
| +// SOT indicates start of text.
|
| +// EOT indicates end of text.
|
| +// [Lead] indicates broken lonely lead surrogate.
|
| +// [Trail] indicates broken lonely trail surrogate.
|
| +// [U] indicates regional indicator symbol U.
|
| +// [S] indicates regional indicator symbol S.
|
| +
|
| +namespace {
|
| +// kWatch kVS16, kEye kVS16 are valid standardized variants.
|
| +const UChar32 kWatch = 0x231A;
|
| +const UChar32 kEye = WTF::Unicode::eyeCharacter;
|
| +const UChar32 kVS16 = 0xFE0F;
|
| +
|
| +// kHanBMP KVS17, kHanSIP kVS17 are valie IVD sequences.
|
| +const UChar32 kHanBMP = 0x845B;
|
| +const UChar32 kHanSIP = 0x20000;
|
| +const UChar32 kVS17 = 0xE0100;
|
| +
|
| +// Following lead/trail values are used for invalid surrogate pairs.
|
| +const UChar kLead = 0xD83D;
|
| +const UChar kTrail = 0xDC66;
|
| +
|
| +// U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U
|
| +const UChar32 kRisU = 0x1F1FA;
|
| +// U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S
|
| +const UChar32 kRisS = 0x1F1F8;
|
| +} // namespace
|
| +
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, DoNothingCase)
|
| +{
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + EXPECT_EQ(0, machine.finalizeAndGetBoundaryOffset());
|
| + EXPECT_EQ(0, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, PrecedingText)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| + // Preceding text should not affect the result except for flags.
|
| + // SOT + | + 'a' + 'a'
|
| + EXPECT_EQ("SRF", processSequenceForward(&machine, kEmpty, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // SOT + [U] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRSRF", processSequenceForward(&machine,
|
| + { kRisU }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // SOT + [U] + [S] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRRSRF", processSequenceForward(&machine,
|
| + { kRisU, kRisS }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + | + 'a' + 'a'
|
| + EXPECT_EQ("SRF", processSequenceForward(&machine, { 'a' }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // 'a' + [U] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRSRF", processSequenceForward(&machine,
|
| + { 'a', kRisU }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // 'a' + [U] + [S] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRRSRF", processSequenceForward(&machine,
|
| + { 'a', kRisU, kRisS }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // U+1F441 + | + 'a' + 'a'
|
| + EXPECT_EQ("RSRF", processSequenceForward(&machine,
|
| + { kEye }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // U+1F441 + [U] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRSRF", processSequenceForward(&machine,
|
| + { kEye, kRisU }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // U+1F441 + [U] + [S] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRRRSRF", processSequenceForward(&machine,
|
| + { kEye, kRisU, kRisS }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // Broken surrogates in preceding text.
|
| +
|
| + // [Lead] + | + 'a' + 'a'
|
| + EXPECT_EQ("SRF", processSequenceForward(&machine,
|
| + { kLead }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // [Lead] + [U] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRSRF", processSequenceForward(&machine,
|
| + { kLead, kRisU }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // [Lead] + [U] + [S] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRRSRF", processSequenceForward(&machine,
|
| + { kLead, kRisU, kRisS }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [Trail] + | + 'a' + 'a'
|
| + EXPECT_EQ("RSRF", processSequenceForward(&machine,
|
| + { 'a', kTrail }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // 'a' + [Trail] + [U] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRSRF", processSequenceForward(&machine,
|
| + { 'a', kTrail, kRisU }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // 'a' + [Trail] + [U] + [S] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRRRSRF", processSequenceForward(&machine,
|
| + { 'a', kTrail, kRisU, kRisS }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Trail] + [Trail] + | + 'a' + 'a'
|
| + EXPECT_EQ("RSRF", processSequenceForward(&machine,
|
| + { kTrail, kTrail }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // [Trail] + [Trail] + [U] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRSRF", processSequenceForward(&machine,
|
| + { kTrail, kTrail, kRisU }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // [Trail] + [Trail] + [U] + [S] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRRRSRF", processSequenceForward(&machine,
|
| + { kTrail, kTrail, kRisU, kRisS }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + [Trail] + | + 'a' + 'a'
|
| + EXPECT_EQ("RSRF", processSequenceForward(&machine,
|
| + { kTrail }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // SOT + [Trail] + [U] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRSRF", processSequenceForward(&machine,
|
| + { kTrail, kRisU }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // SOT + [Trail] + [U] + [S] + | + 'a' + 'a'
|
| + EXPECT_EQ("RRRRRSRF", processSequenceForward(&machine,
|
| + { kTrail, kRisU, kRisS }, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, BrokenSurrogatePair)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| + // SOT + | + [Trail]
|
| + EXPECT_EQ("SF", processSequenceForward(&machine, kEmpty, { kTrail }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // SOT + | + [Lead] + 'a'
|
| + EXPECT_EQ("SRF", processSequenceForward(&machine, kEmpty, { kLead, 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // SOT + | + [Lead] + [Lead]
|
| + EXPECT_EQ("SRF", processSequenceForward(&machine, kEmpty,
|
| + { kLead, kLead }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| + // SOT + | + [Lead] + EOT
|
| + EXPECT_EQ("SR", processSequenceForward(&machine, kEmpty, { kLead }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, BreakImmediately_BMP)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + | + 'a' + 'a'
|
| + EXPECT_EQ("SRF", processSequenceForward(&machine, kEmpty, { 'a', 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + 'a' + U+1F441
|
| + EXPECT_EQ("SRRF", processSequenceForward(&machine, kEmpty, { 'a', kEye }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + 'a' + EOT
|
| + EXPECT_EQ("SR", processSequenceForward(&machine, kEmpty, { 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + 'a' + [Trail]
|
| + EXPECT_EQ("SRF", processSequenceForward(&machine, kEmpty, { 'a', kTrail }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + 'a' + [Lead] + 'a'
|
| + EXPECT_EQ("SRRF", processSequenceForward(&machine, kEmpty,
|
| + { 'a', kLead, 'a' }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + 'a' + [Lead] + [Lead]
|
| + EXPECT_EQ("SRRF", processSequenceForward(&machine, kEmpty,
|
| + { 'a', kLead, kLead }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + 'a' + [Lead] + EOT
|
| + EXPECT_EQ("SRR", processSequenceForward(&machine, kEmpty, { 'a', kLead }));
|
| + EXPECT_EQ(1, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, BreakImmediately_Supplementary)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + | + U+1F441 + 'a'
|
| + EXPECT_EQ("SRRF", processSequenceForward(&machine, kEmpty, { kEye, 'a' }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + U+1F441
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kEye }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + EOT
|
| + EXPECT_EQ("SRR", processSequenceForward(&machine, kEmpty, { kEye }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + [Trail]
|
| + EXPECT_EQ("SRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kTrail }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + [Lead] + 'a'
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kLead, 'a' }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + [Lead] + [Lead]
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kLead, kLead }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + [Lead] + EOT
|
| + EXPECT_EQ("SRRR", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kLead }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, NotBreakImmediatelyAfter_BMP_BMP)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + | + U+231A + U+FE0F + 'a'
|
| + EXPECT_EQ("SRRF", processSequenceForward(&machine, kEmpty,
|
| + { kWatch, kVS16, 'a' }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+231A + U+FE0F + U+1F441
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kWatch, kVS16, kEye }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+231A + U+FE0F + EOT
|
| + EXPECT_EQ("SRR", processSequenceForward(&machine, kEmpty,
|
| + { kWatch, kVS16 }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+231A + U+FE0F + [Trail]
|
| + EXPECT_EQ("SRRF", processSequenceForward(&machine, kEmpty,
|
| + { kWatch, kVS16, kTrail }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+231A + U+FE0F + [Lead] + 'a'
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kWatch, kVS16, kLead, 'a' }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+231A + U+FE0F + [Lead] + [Lead]
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kWatch, kVS16, kLead, kLead }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+231A + U+FE0F + [Lead] + EOT
|
| + EXPECT_EQ("SRRR", processSequenceForward(&machine, kEmpty,
|
| + { kWatch, kVS16, kLead }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest,
|
| + NotBreakImmediatelyAfter_Supplementary_BMP)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + | + U+1F441 + U+FE0F + 'a'
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kVS16, 'a' }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + U+FE0F + U+1F441
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kVS16, kEye }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + U+FE0F + EOT
|
| + EXPECT_EQ("SRRR", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kVS16 }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + U+FE0F + [Trail]
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kVS16, kTrail }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + U+FE0F + [Lead] + 'a'
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kVS16, kLead, 'a' }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + U+FE0F + [Lead] + [Lead]
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kVS16, kLead, kLead }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+1F441 + U+FE0F + [Lead] + EOT
|
| + EXPECT_EQ("SRRRR", processSequenceForward(&machine, kEmpty,
|
| + { kEye, kVS16, kLead }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest,
|
| + NotBreakImmediatelyAfter_BMP_Supplementary)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + | + U+845B + U+E0100 + 'a'
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanBMP, kVS17, 'a' }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+845B + U+E0100 + U+1F441
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanBMP, kVS17, kEye }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+845B + U+E0100 + EOT
|
| + EXPECT_EQ("SRRR", processSequenceForward(&machine, kEmpty,
|
| + { kHanBMP, kVS17 }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+845B + U+E0100 + [Trail]
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanBMP, kVS17, kTrail }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+845B + U+E0100 + [Lead] + 'a'
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanBMP, kVS17, kLead, 'a' }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+845B + U+E0100 + [Lead] + [Lead]
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanBMP, kVS17, kLead, kLead }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+845B + U+E0100 + [Lead] + EOT
|
| + EXPECT_EQ("SRRRR", processSequenceForward(&machine, kEmpty,
|
| + { kHanBMP, kVS17, kLead }));
|
| + EXPECT_EQ(3, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest,
|
| + NotBreakImmediatelyAfter_Supplementary_Supplementary)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + | + U+20000 + U+E0100 + 'a'
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanSIP, kVS17, 'a' }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+20000 + U+E0100 + U+1F441
|
| + EXPECT_EQ("SRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanSIP, kVS17, kEye }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+20000 + U+E0100 + EOT
|
| + EXPECT_EQ("SRRRR", processSequenceForward(&machine, kEmpty,
|
| + { kHanSIP, kVS17 }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+20000 + U+E0100 + [Trail]
|
| + EXPECT_EQ("SRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanSIP, kVS17, kTrail }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+20000 + U+E0100 + [Lead] + 'a'
|
| + EXPECT_EQ("SRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanSIP, kVS17, kLead, 'a' }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+20000 + U+E0100 + [Lead] + [Lead]
|
| + EXPECT_EQ("SRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kHanSIP, kVS17, kLead, kLead }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + U+20000 + U+E0100 + [Lead] + EOT
|
| + EXPECT_EQ("SRRRRR", processSequenceForward(&machine, kEmpty,
|
| + { kHanSIP, kVS17, kLead }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, MuchLongerCase)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + const UChar32 kMan = WTF::Unicode::manCharacter;
|
| + const UChar32 kZwj = WTF::Unicode::zeroWidthJoinerCharacter;
|
| + const UChar32 kHeart = WTF::Unicode::heavyBlackHeartCharacter;
|
| + const UChar32 kKiss = WTF::Unicode::kissMarkCharacter;
|
| +
|
| + // U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 is a valid ZWJ
|
| + // emoji sequence.
|
| + // SOT + | + ZWJ Emoji Sequence + 'a'
|
| + EXPECT_EQ("SRRRRRRRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + ZWJ Emoji Sequence + U+1F441
|
| + EXPECT_EQ("SRRRRRRRRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, kEye }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + ZWJ Emoji Sequence + EOT
|
| + EXPECT_EQ("SRRRRRRRRRRR", processSequenceForward(&machine, kEmpty,
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + ZWJ Emoji Sequence + [Trail]
|
| + EXPECT_EQ("SRRRRRRRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, kTrail }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + ZWJ Emoji Sequence + [Lead] + 'a'
|
| + EXPECT_EQ("SRRRRRRRRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, kLead, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + ZWJ Emoji Sequence + [Lead] + [Lead]
|
| + EXPECT_EQ("SRRRRRRRRRRRRF", processSequenceForward(&machine, kEmpty,
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, kLead, kLead }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("SRRRRRRRRRRRR", processSequenceForward(&machine, kEmpty,
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, kLead }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // Preceding text should not affect the result except for flags.
|
| + // 'a' + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("SRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { 'a' },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // U+1F441 + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("RSRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { kEye },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Lead] + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("SRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { kLead },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [Trail] + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("RSRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { 'a', kTrail },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Trail] + [Trail] + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("RSRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { kTrail, kTrail },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + [Trail] + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("RSRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { kTrail },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [U] + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("RRSRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { 'a', kRisU },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [U] + [S] + | + ZWJ Emoji Sequence + [Lead] + EOT
|
| + EXPECT_EQ("RRRRSRRRRRRRRRRRF", processSequenceForward(&machine,
|
| + { 'a', kRisU, kRisS },
|
| + { kMan, kZwj, kHeart, kVS16, kZwj, kKiss, kZwj, kMan, 'a' }));
|
| + EXPECT_EQ(11, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, singleFlags)
|
| +{
|
| + const std::vector<UChar32> kEmpty;
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + | + [U] + [S]
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine,
|
| + kEmpty, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + | + [U] + [S]
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine,
|
| + { 'a' }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // U+1F441 + | + [U] + [S]
|
| + EXPECT_EQ("RSRRRF", processSequenceForward(&machine,
|
| + { kEye }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Lead] + | + [U] + [S]
|
| + EXPECT_EQ("SRRRF", processSequenceForward(&machine,
|
| + { kLead }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [Trail] + | + [U] + [S]
|
| + EXPECT_EQ("RSRRRF", processSequenceForward(&machine,
|
| + { 'a', kTrail }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Trail] + [Trail] + | + [U] + [S]
|
| + EXPECT_EQ("RSRRRF", processSequenceForward(&machine,
|
| + { kTrail, kTrail }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + [Trail] + | + [U] + [S]
|
| + EXPECT_EQ("RSRRRF", processSequenceForward(&machine,
|
| + { kTrail }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, twoFlags)
|
| +{
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + [U] + [S] + | + [U] + [S]
|
| + EXPECT_EQ("RRRRSRRRF", processSequenceForward(&machine,
|
| + { kRisU, kRisS }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [U] + [S] + | + [U] + [S]
|
| + EXPECT_EQ("RRRRSRRRF", processSequenceForward(&machine,
|
| + { 'a', kRisU, kRisS }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // U+1F441 + [U] + [S] + | + [U] + [S]
|
| + EXPECT_EQ("RRRRRSRRRF", processSequenceForward(&machine,
|
| + { kEye, kRisU, kRisS }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Lead] + [U] + [S] + | + [U] + [S]
|
| + EXPECT_EQ("RRRRSRRRF", processSequenceForward(&machine,
|
| + { kLead, kRisU, kRisS }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [Trail] + [U] + [S] + | + [U] + [S]
|
| + EXPECT_EQ("RRRRRSRRRF", processSequenceForward(&machine,
|
| + { 'a', kTrail, kRisU, kRisS }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Trail] + [Trail] + [U] + [S] + | + [U] + [S]
|
| + EXPECT_EQ("RRRRRSRRRF", processSequenceForward(&machine,
|
| + { kTrail, kTrail, kRisU, kRisS }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + [Trail] + [U] + [S] + | + [U] + [S]
|
| + EXPECT_EQ("RRRRRSRRRF", processSequenceForward(&machine,
|
| + { kTrail, kRisU, kRisS }, { kRisU, kRisS }));
|
| + EXPECT_EQ(4, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +TEST(ForwardGraphemeBoundaryStatemachineTest, oddNumberedFlags)
|
| +{
|
| + ForwardGraphemeBoundaryStateMachine machine;
|
| +
|
| + // SOT + [U] + | + [S] + [S]
|
| + EXPECT_EQ("RRSRRRF", processSequenceForward(&machine,
|
| + { kRisU }, { kRisS, kRisU }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [U] + | + [S] + [S]
|
| + EXPECT_EQ("RRSRRRF", processSequenceForward(&machine,
|
| + { 'a', kRisU }, { kRisS, kRisU }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // U+1F441 + [U] + | + [S] + [S]
|
| + EXPECT_EQ("RRRSRRRF", processSequenceForward(&machine,
|
| + { kEye, kRisU }, { kRisS, kRisU }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Lead] + [U] + | + [S] + [S]
|
| + EXPECT_EQ("RRSRRRF", processSequenceForward(&machine,
|
| + { kLead, kRisU }, { kRisS, kRisU }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // 'a' + [Trail] + [U] + | + [S] + [S]
|
| + EXPECT_EQ("RRRSRRRF", processSequenceForward(&machine,
|
| + { 'a', kTrail, kRisU }, { kRisS, kRisU }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // [Trail] + [Trail] + [U] + | + [S] + [S]
|
| + EXPECT_EQ("RRRSRRRF", processSequenceForward(&machine,
|
| + { kTrail, kTrail, kRisU }, { kRisS, kRisU }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +
|
| + // SOT + [Trail] + [U] + | + [S] + [S]
|
| + EXPECT_EQ("RRRSRRRF", processSequenceForward(&machine,
|
| + { kTrail, kRisU }, { kRisS, kRisU }));
|
| + EXPECT_EQ(2, machine.finalizeAndGetBoundaryOffset());
|
| +}
|
| +
|
| +} // namespace blink
|
|
|