| Index: Source/core/html/HTMLTextFormControlElementTest.cpp | 
| diff --git a/Source/core/html/HTMLTextFormControlElementTest.cpp b/Source/core/html/HTMLTextFormControlElementTest.cpp | 
| index 1134854814f50e622791d248eed837aa2d9c7b0b..5d8e8951edf8ec56c7e6a153903a5301c2eaa9da 100644 | 
| --- a/Source/core/html/HTMLTextFormControlElementTest.cpp | 
| +++ b/Source/core/html/HTMLTextFormControlElementTest.cpp | 
| @@ -5,12 +5,20 @@ | 
| #include "config.h" | 
| #include "core/html/HTMLTextFormControlElement.h" | 
|  | 
| +#include "core/dom/Position.h" | 
| +#include "core/dom/Text.h" | 
| +#include "core/editing/FrameSelection.h" | 
| +#include "core/editing/VisibleSelection.h" | 
| +#include "core/editing/VisibleUnits.h" | 
| #include "core/frame/FrameView.h" | 
| +#include "core/html/HTMLBRElement.h" | 
| #include "core/html/HTMLDocument.h" | 
| +#include "core/rendering/RenderTreeAsText.h" | 
| #include "core/testing/DummyPageHolder.h" | 
| #include "wtf/OwnPtr.h" | 
| #include <gtest/gtest.h> | 
|  | 
| +using namespace blink; | 
| using namespace WebCore; | 
|  | 
| namespace { | 
| @@ -19,21 +27,23 @@ class HTMLTextFormControlElementTest : public ::testing::Test { | 
| protected: | 
| virtual void SetUp() OVERRIDE; | 
|  | 
| +    HTMLDocument& document() const { return *m_document; } | 
| HTMLTextFormControlElement& textControl() const { return *m_textControl; } | 
|  | 
| private: | 
| OwnPtr<DummyPageHolder> m_dummyPageHolder; | 
|  | 
| +    RefPtrWillBePersistent<HTMLDocument> m_document; | 
| RefPtrWillBePersistent<HTMLTextFormControlElement> m_textControl; | 
| }; | 
|  | 
| void HTMLTextFormControlElementTest::SetUp() | 
| { | 
| m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); | 
| -    HTMLDocument& document = toHTMLDocument(m_dummyPageHolder->document()); | 
| -    document.documentElement()->setInnerHTML("<body><textarea id=textarea></textarea></body>", ASSERT_NO_EXCEPTION); | 
| -    document.view()->updateLayoutAndStyleIfNeededRecursive(); | 
| -    m_textControl = toHTMLTextFormControlElement(document.getElementById("textarea")); | 
| +    m_document = toHTMLDocument(&m_dummyPageHolder->document()); | 
| +    m_document->documentElement()->setInnerHTML("<body><textarea id=textarea></textarea></body>", ASSERT_NO_EXCEPTION); | 
| +    m_document->view()->updateLayoutAndStyleIfNeededRecursive(); | 
| +    m_textControl = toHTMLTextFormControlElement(m_document->getElementById("textarea")); | 
| m_textControl->focus(); | 
| } | 
|  | 
| @@ -51,4 +61,70 @@ TEST_F(HTMLTextFormControlElementTest, SetSelectionRange) | 
| EXPECT_EQ(3, textControl().selectionEnd()); | 
| } | 
|  | 
| +typedef Position (*PositionFunction)(const Position&); | 
| +typedef VisiblePosition(*VisblePositionFunction)(const VisiblePosition&); | 
| + | 
| +void testFunctionEquality(const Position& position, PositionFunction positionFunction, VisblePositionFunction visibleFunction) | 
| +{ | 
| +    VisiblePosition visiblePosition(position); | 
| +    VisiblePosition expected = visibleFunction(visiblePosition); | 
| +    VisiblePosition actual = VisiblePosition(positionFunction(position)); | 
| +    EXPECT_EQ(expected, actual); | 
| +} | 
| + | 
| +static VisiblePosition startOfWord(const VisiblePosition& position) | 
| +{ | 
| +    return startOfWord(position, LeftWordIfOnBoundary); | 
| +} | 
| + | 
| +static VisiblePosition endOfWord(const VisiblePosition& position) | 
| +{ | 
| +    return endOfWord(position, RightWordIfOnBoundary); | 
| +} | 
| + | 
| +TEST_F(HTMLTextFormControlElementTest, WordAndSentenceBoundary) | 
| +{ | 
| +    HTMLElement* innerText = textControl().innerEditorElement(); | 
| +    // We have: | 
| +    // innerText(shadow root) | 
| +    // --#Text "Hello, text form." | 
| +    // --BR | 
| +    // --BR | 
| +    // --#TEXT "" | 
| +    // --#TEXT "\n\n" | 
| +    // --#TEXT "\n" | 
| +    // --#Text "Hel\nlo, te" | 
| +    // --#TEXT "xt form." | 
| +    innerText->appendChild(Text::create(document(), "Hello, text form.")); | 
| +    innerText->appendChild(HTMLBRElement::create(document())); | 
| +    innerText->appendChild(HTMLBRElement::create(document())); | 
| +    innerText->appendChild(Text::create(document(), "")); | 
| +    innerText->appendChild(Text::create(document(), "\n\n")); | 
| +    innerText->appendChild(Text::create(document(), "\n")); | 
| +    innerText->appendChild(Text::create(document(), "Hel\nlo, te")); | 
| +    innerText->appendChild(Text::create(document(), "xt form.")); | 
| + | 
| +    for (unsigned i = 0; i < textControl().innerEditorValue().length(); i++) { | 
| +        textControl().setSelectionRange(i, i); | 
| +        Position pos = document().frame()->selection().start(); | 
| +        SCOPED_TRACE(testing::Message() << "offset " << pos.deprecatedEditingOffset() << " of " << nodePosition(pos.deprecatedNode()).ascii().data()); | 
| +        { | 
| +            SCOPED_TRACE("HTMLTextFormControlElement::startOfWord"); | 
| +            testFunctionEquality(pos, HTMLTextFormControlElement::startOfWord, startOfWord); | 
| +        } | 
| +        { | 
| +            SCOPED_TRACE("HTMLTextFormControlElement::endOfWord"); | 
| +            testFunctionEquality(pos, HTMLTextFormControlElement::endOfWord, endOfWord); | 
| +        } | 
| +        { | 
| +            SCOPED_TRACE("HTMLTextFormControlElement::startOfSentence"); | 
| +            testFunctionEquality(pos, HTMLTextFormControlElement::startOfSentence, startOfSentence); | 
| +        } | 
| +        { | 
| +            SCOPED_TRACE("HTMLTextFormControlElement::endOfSentence"); | 
| +            testFunctionEquality(pos, HTMLTextFormControlElement::endOfSentence, endOfSentence); | 
| +        } | 
| +    } | 
| +} | 
| + | 
| } | 
|  |