1d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// found in the LICENSE file.
4d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
5d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "config.h"
6d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/editing/VisibleSelection.h"
7d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
8d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/dom/Document.h"
9d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/dom/Range.h"
10d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/dom/Text.h"
11d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/html/HTMLElement.h"
12d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/testing/DummyPageHolder.h"
13d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include <gtest/gtest.h>
14d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
15d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#define LOREM_IPSUM \
16d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " \
17d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " \
18d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " \
19d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." \
20d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " \
21d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    "mollit anim id est laborum."
22d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
23c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
24d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
25d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)class VisibleSelectionTest : public ::testing::Test {
26d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)protected:
27d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    virtual void SetUp() OVERRIDE;
28d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
29f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    // Oilpan: wrapper object needed to be able to trace VisibleSelection.
30f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    class VisibleSelectionWrapper : public NoBaseWillBeGarbageCollectedFinalized<VisibleSelectionWrapper> {
31f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    public:
32f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        void trace(Visitor* visitor)
33f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        {
34f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            visitor->trace(m_selection);
35f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        }
36f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
37f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        VisibleSelection m_selection;
38f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    };
39f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
40d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Document& document() const { return m_dummyPageHolder->document(); }
41d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Text* textNode() const { return m_textNode.get(); }
42f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    VisibleSelection& selection() { return m_wrap->m_selection; }
43d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
44d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Helper function to set the VisibleSelection base/extent.
45d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void setSelection(int base) { setSelection(base, base); }
46d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
47d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Helper function to set the VisibleSelection base/extent.
48d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void setSelection(int base, int extend)
49d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
50f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_wrap->m_selection.setBase(Position(textNode(), base));
51f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_wrap->m_selection.setExtent(Position(textNode(), extend));
52d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
53d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
54d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)private:
55d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    OwnPtr<DummyPageHolder> m_dummyPageHolder;
56f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBePersistent<Text> m_textNode;
57f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    OwnPtrWillBePersistent<VisibleSelectionWrapper> m_wrap;
58d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)};
59d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void blink::VisibleSelectionTest::SetUp()
61d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
62d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
63d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_textNode = document().createTextNode(LOREM_IPSUM);
64f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_wrap = adoptPtrWillBeNoop(new VisibleSelectionWrapper());
65d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    document().body()->appendChild(m_textNode.get());
66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
67d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
69d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
70d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)namespace {
71d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
72c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink;
73d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
74d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)TEST_F(VisibleSelectionTest, Initialisation)
75d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
76d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    setSelection(0);
77d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
78d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EXPECT_FALSE(selection().isNone());
79d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EXPECT_TRUE(selection().isCaret());
80d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
81d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<Range> range = selection().firstRange();
82d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EXPECT_EQ(0, range->startOffset());
83d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EXPECT_EQ(0, range->endOffset());
84d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EXPECT_EQ("", range->text());
85d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
86d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
87d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)TEST_F(VisibleSelectionTest, WordGranularity)
88d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Beginning of a word.
90d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
91d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        setSelection(0);
92d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        selection().expandUsingGranularity(WordGranularity);
93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
94d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Range> range = selection().firstRange();
95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(0, range->startOffset());
96d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(5, range->endOffset());
97d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ("Lorem", range->text());
98d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
99d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
100d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Middle of a word.
101d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
102d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        setSelection(8);
103d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        selection().expandUsingGranularity(WordGranularity);
104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
105d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Range> range = selection().firstRange();
106d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(6, range->startOffset());
107d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(11, range->endOffset());
108d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ("ipsum", range->text());
109d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
110d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
111d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // End of a word.
112d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // FIXME: that sounds buggy, we might want to select the word _before_ instead
113d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // of the space...
114d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
115d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        setSelection(5);
116d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        selection().expandUsingGranularity(WordGranularity);
117d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
118d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Range> range = selection().firstRange();
119d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(5, range->startOffset());
120d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(6, range->endOffset());
121d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(" ", range->text());
122d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
123d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
124d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Before comma.
125d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // FIXME: that sounds buggy, we might want to select the word _before_ instead
126d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // of the comma.
127d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
128d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        setSelection(26);
129d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        selection().expandUsingGranularity(WordGranularity);
130d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
131d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Range> range = selection().firstRange();
132d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(26, range->startOffset());
133d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(27, range->endOffset());
134d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(",", range->text());
135d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
136d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
137d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // After comma.
138d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
139d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        setSelection(27);
140d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        selection().expandUsingGranularity(WordGranularity);
141d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
142d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Range> range = selection().firstRange();
143d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(27, range->startOffset());
144d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(28, range->endOffset());
145d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(" ", range->text());
146d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
147d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
148d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // When selecting part of a word.
149d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
150d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        setSelection(0, 1);
151d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        selection().expandUsingGranularity(WordGranularity);
152d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
153d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Range> range = selection().firstRange();
154d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(0, range->startOffset());
155d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(5, range->endOffset());
156d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ("Lorem", range->text());
157d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
158d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
159d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // When selecting part of two words.
160d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
161d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        setSelection(2, 8);
162d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        selection().expandUsingGranularity(WordGranularity);
163d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
164d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Range> range = selection().firstRange();
165d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(0, range->startOffset());
166d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ(11, range->endOffset());
167d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        EXPECT_EQ("Lorem ipsum", range->text());
168d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
169d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
170d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
171c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
172