Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "core/editing/EphemeralRange.h" | |
| 6 | |
| 7 #include "core/dom/Range.h" | |
| 8 #include "core/editing/EditingTestBase.h" | |
| 9 #include <sstream> | |
| 10 | |
| 11 namespace blink { | |
| 12 | |
| 13 namespace { | |
|
yosin_UTC9
2016/08/18 02:11:09
We don't need to have anonymous namespace for test
Andrey Kraynov
2016/08/18 10:16:33
Done.
| |
| 14 | |
| 15 class EphemeralRangeTest : public EditingTestBase { | |
| 16 protected: | |
| 17 template <typename Traversal> | |
| 18 std::string traverseRange(Range*) const; | |
| 19 | |
| 20 template <typename Strategy> | |
| 21 std::string traverseRange(const EphemeralRangeTemplate<Strategy>&) const; | |
| 22 | |
| 23 Range* getBodyRange() const; | |
| 24 }; | |
| 25 | |
| 26 template <typename Traversal = NodeTraversal> | |
| 27 std::string EphemeralRangeTest::traverseRange(Range* range) const | |
| 28 { | |
| 29 std::stringstream nodesContent; | |
| 30 for (Node* node = range->firstNode(); node != range->pastLastNode(); node = Traversal::next(*node)) { | |
| 31 nodesContent << "[" << *node << "]"; | |
| 32 } | |
| 33 | |
| 34 return nodesContent.str(); | |
| 35 } | |
| 36 | |
| 37 template <typename Strategy> | |
| 38 std::string EphemeralRangeTest::traverseRange(const EphemeralRangeTemplate<Strat egy>& range) const | |
| 39 { | |
| 40 std::stringstream nodesContent; | |
| 41 for (Node& node : range.nodes()) { | |
|
yosin_UTC9
2016/08/18 02:11:09
nit: s/Node&/const Node&/
nit: No need to have |{}
Andrey Kraynov
2016/08/18 10:16:33
Done.
| |
| 42 nodesContent << "[" << node << "]"; | |
| 43 } | |
| 44 | |
| 45 return nodesContent.str(); | |
| 46 } | |
| 47 | |
| 48 Range* EphemeralRangeTest::getBodyRange() const | |
| 49 { | |
| 50 Range* range = Range::create(document()); | |
| 51 range->selectNode(document().body()); | |
| 52 return range; | |
| 53 } | |
| 54 | |
| 55 } // namespace | |
| 56 | |
| 57 // Tests that |EphemeralRange::nodes()| will traverse the whole range exactly as | |
| 58 // |for (Node* n = firstNode(); n != pastLastNode(); n = Traversal::next(*n))| | |
| 59 // does. | |
| 60 TEST_F(EphemeralRangeTest, rangeTraversal) | |
| 61 { | |
| 62 const char* bodyContent = "<p id='host'><b id='one'></b><b id='two'>22</b></ p>"; | |
| 63 setBodyContent(bodyContent); | |
| 64 | |
| 65 const std::string expectedNodes("[BODY][P id=\"host\"][B id=\"one\"][B id=\" two\"][#text \"22\"]"); | |
| 66 | |
| 67 // Check two ways to traverse. | |
| 68 EXPECT_EQ(expectedNodes, traverseRange<>(getBodyRange())); | |
| 69 EXPECT_EQ(traverseRange<>(getBodyRange()), traverseRange(EphemeralRange(getB odyRange()))); | |
| 70 | |
| 71 // The same with FlatTree traversing. | |
| 72 EXPECT_EQ(expectedNodes, traverseRange<FlatTreeTraversal>(getBodyRange())); | |
| 73 EXPECT_EQ( | |
| 74 traverseRange<FlatTreeTraversal>(getBodyRange()), | |
| 75 traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); | |
| 76 } | |
| 77 | |
| 78 // Tests that |inRange| helper will traverse the whole range with shadow DOM. | |
| 79 TEST_F(EphemeralRangeTest, rangeShadowTraversal) | |
| 80 { | |
| 81 const char* bodyContent = "<p id='host'><b id='one'></b><input type='text' v alue='some'></p>"; | |
| 82 setBodyContent(bodyContent); | |
| 83 | |
| 84 EXPECT_EQ( | |
| 85 "[BODY][P id=\"host\"][B id=\"one\"][INPUT]", | |
| 86 traverseRange<>(getBodyRange())); | |
| 87 EXPECT_EQ(traverseRange<>(getBodyRange()), traverseRange(EphemeralRange(getB odyRange()))); | |
| 88 | |
| 89 // In this case FlatTree traverse should differs from DOM tree traverse. | |
| 90 EXPECT_EQ( | |
| 91 "[BODY][P id=\"host\"][B id=\"one\"][INPUT][DIV id=\"inner-editor\"][#te xt \"some\"]", | |
| 92 traverseRange<FlatTreeTraversal>(getBodyRange())); | |
| 93 EXPECT_EQ( | |
| 94 traverseRange<FlatTreeTraversal>(getBodyRange()), | |
| 95 traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); | |
| 96 } | |
| 97 | |
| 98 // Limit a range and check that it will be traversed correctly. | |
| 99 TEST_F(EphemeralRangeTest, rangeTraversalLimited) | |
| 100 { | |
| 101 const char* bodyContent = "<p id='host'><b id='one'></b><input type='text' v alue='some'><span id='two'></p>"; | |
| 102 setBodyContent(bodyContent); | |
| 103 | |
| 104 // Get a limited range from <body> to <b> nodes. | |
| 105 Range* untilB = getBodyRange(); | |
| 106 untilB->setEnd(document().getElementById("one"), 0, IGNORE_EXCEPTION); | |
| 107 EXPECT_EQ( | |
| 108 "[BODY][P id=\"host\"][B id=\"one\"]", | |
| 109 traverseRange<>(untilB)); | |
| 110 | |
| 111 EXPECT_EQ(traverseRange<>(untilB), traverseRange(EphemeralRange(untilB))); | |
| 112 | |
| 113 EXPECT_EQ( | |
| 114 "[BODY][P id=\"host\"][B id=\"one\"]", | |
| 115 traverseRange<FlatTreeTraversal>(untilB)); | |
| 116 EXPECT_EQ( | |
| 117 traverseRange<FlatTreeTraversal>(untilB), | |
| 118 traverseRange(EphemeralRangeInFlatTree(untilB))); | |
| 119 | |
| 120 // Get a limited range from <b> to <span> nodes. | |
| 121 Range* fromBToSpan = getBodyRange(); | |
| 122 fromBToSpan->setStart(document().getElementById("one"), 0, IGNORE_EXCEPTION) ; | |
| 123 fromBToSpan->setEnd(document().getElementById("two"), 0, IGNORE_EXCEPTION); | |
| 124 | |
| 125 EXPECT_EQ( | |
| 126 "[B id=\"one\"][INPUT][SPAN id=\"two\"]", | |
| 127 traverseRange<>(fromBToSpan)); | |
| 128 EXPECT_EQ(traverseRange<>(fromBToSpan), traverseRange(EphemeralRange(fromBTo Span))); | |
| 129 | |
| 130 EXPECT_EQ( | |
| 131 "[B id=\"one\"][INPUT][DIV id=\"inner-editor\"][#text \"some\"][SPAN id= \"two\"]", | |
| 132 traverseRange<FlatTreeTraversal>(fromBToSpan)); | |
| 133 EXPECT_EQ( | |
| 134 traverseRange<FlatTreeTraversal>(fromBToSpan), | |
| 135 traverseRange(EphemeralRangeInFlatTree(fromBToSpan))); | |
| 136 } | |
| 137 | |
| 138 TEST_F(EphemeralRangeTest, traversalEmptyRanges) | |
| 139 { | |
| 140 const char* bodyContent = "<p id='host'><b id='one'></b></p>"; | |
| 141 setBodyContent(bodyContent); | |
| 142 | |
| 143 // Expect no iterations in loop for an empty EphemeralRange. | |
| 144 EXPECT_EQ(std::string(), traverseRange(EphemeralRange())); | |
| 145 | |
| 146 auto iterable = EphemeralRange().nodes(); | |
| 147 // Tree iterators have only |operator !=| ATM. | |
| 148 EXPECT_FALSE(iterable.begin() != iterable.end()); | |
| 149 | |
| 150 const EphemeralRange singlePositionRange(getBodyRange()->startPosition()); | |
| 151 EXPECT_FALSE(singlePositionRange.isNull()); | |
| 152 EXPECT_EQ(std::string(), traverseRange(singlePositionRange)); | |
| 153 EXPECT_EQ( | |
| 154 singlePositionRange.startPosition().nodeAsRangeFirstNode(), | |
| 155 singlePositionRange.endPosition().nodeAsRangePastLastNode()); | |
| 156 } | |
| 157 | |
| 158 } // namespace blink | |
| OLD | NEW |