Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / PODIntervalTreeTest.cpp
blobdc98641459d439f493e943e78187a36f73e658b0
1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // Tests for the interval tree class.
28 #include "config.h"
29 #include "platform/PODIntervalTree.h"
31 #include "platform/Logging.h"
32 #include "platform/testing/TreeTestHelpers.h"
33 #include "wtf/Vector.h"
34 #include "wtf/text/WTFString.h"
36 #include <gtest/gtest.h>
38 namespace blink {
40 using TreeTestHelpers::initRandom;
41 using TreeTestHelpers::nextRandom;
43 #ifndef NDEBUG
44 template<>
45 struct ValueToString<float> {
46 static String string(const float& value) { return String::number(value); }
49 template<>
50 struct ValueToString<void*> {
51 static String string(void* const& value)
53 return String::format("0x%p", value);
56 #endif
58 TEST(PODIntervalTreeTest, TestInsertion)
60 PODIntervalTree<float> tree;
61 tree.add(PODInterval<float>(2, 4));
62 ASSERT_TRUE(tree.checkInvariants());
65 TEST(PODIntervalTreeTest, TestInsertionAndQuery)
67 PODIntervalTree<float> tree;
68 tree.add(PODInterval<float>(2, 4));
69 ASSERT_TRUE(tree.checkInvariants());
70 Vector<PODInterval<float>> result = tree.allOverlaps(PODInterval<float>(1, 3));
71 EXPECT_EQ(1U, result.size());
72 EXPECT_EQ(2, result[0].low());
73 EXPECT_EQ(4, result[0].high());
76 TEST(PODIntervalTreeTest, TestQueryAgainstZeroSizeInterval)
78 PODIntervalTree<float> tree;
79 tree.add(PODInterval<float>(1, 2.5));
80 tree.add(PODInterval<float>(3.5, 5));
81 tree.add(PODInterval<float>(2, 4));
82 ASSERT_TRUE(tree.checkInvariants());
83 Vector<PODInterval<float>> result = tree.allOverlaps(PODInterval<float>(3, 3));
84 EXPECT_EQ(1U, result.size());
85 EXPECT_EQ(2, result[0].low());
86 EXPECT_EQ(4, result[0].high());
89 #ifndef NDEBUG
90 template<>
91 struct ValueToString<int*> {
92 static String string(int* const& value)
94 return String::format("0x%p", value);
97 #endif
99 TEST(PODIntervalTreeTest, TestDuplicateElementInsertion)
101 PODIntervalTree<float, int*> tree;
102 int tmp1 = 1;
103 int tmp2 = 2;
104 typedef PODIntervalTree<float, int*>::IntervalType IntervalType;
105 IntervalType interval1(1, 3, &tmp1);
106 IntervalType interval2(1, 3, &tmp2);
107 tree.add(interval1);
108 tree.add(interval2);
109 ASSERT_TRUE(tree.checkInvariants());
110 EXPECT_TRUE(tree.contains(interval1));
111 EXPECT_TRUE(tree.contains(interval2));
112 EXPECT_TRUE(tree.remove(interval1));
113 EXPECT_TRUE(tree.contains(interval2));
114 EXPECT_FALSE(tree.contains(interval1));
115 EXPECT_TRUE(tree.remove(interval2));
116 EXPECT_EQ(0, tree.size());
119 namespace {
121 struct UserData1 {
122 public:
123 UserData1()
124 : a(0), b(1) { }
126 float a;
127 int b;
130 } // anonymous namespace
132 #ifndef NDEBUG
133 template<>
134 struct ValueToString<UserData1> {
135 static String string(const UserData1& value)
137 return String("[UserData1 a=") + String::number(value.a) + " b=" + String::number(value.b) + "]";
140 #endif
142 TEST(PODIntervalTreeTest, TestInsertionOfComplexUserData)
144 PODIntervalTree<float, UserData1> tree;
145 UserData1 data1;
146 data1.a = 5;
147 data1.b = 6;
148 tree.add(tree.createInterval(2, 4, data1));
149 ASSERT_TRUE(tree.checkInvariants());
152 TEST(PODIntervalTreeTest, TestQueryingOfComplexUserData)
154 PODIntervalTree<float, UserData1> tree;
155 UserData1 data1;
156 data1.a = 5;
157 data1.b = 6;
158 tree.add(tree.createInterval(2, 4, data1));
159 ASSERT_TRUE(tree.checkInvariants());
160 Vector<PODInterval<float, UserData1>> overlaps = tree.allOverlaps(tree.createInterval(3, 5, data1));
161 EXPECT_EQ(1U, overlaps.size());
162 EXPECT_EQ(5, overlaps[0].data().a);
163 EXPECT_EQ(6, overlaps[0].data().b);
166 namespace {
168 class EndpointType1 {
169 public:
170 explicit EndpointType1(int value)
171 : m_value(value) { }
173 int value() const { return m_value; }
175 bool operator<(const EndpointType1& other) const { return m_value < other.m_value; }
176 bool operator==(const EndpointType1& other) const { return m_value == other.m_value; }
178 private:
179 int m_value;
180 // These operators should not be called by the interval tree.
181 bool operator>(const EndpointType1& other);
182 bool operator<=(const EndpointType1& other);
183 bool operator>=(const EndpointType1& other);
184 bool operator!=(const EndpointType1& other);
187 } // anonymous namespace
189 #ifndef NDEBUG
190 template<>
191 struct ValueToString<EndpointType1> {
192 static String string(const EndpointType1& value)
194 return String("[EndpointType1 value=") + String::number(value.value()) + "]";
197 #endif
199 TEST(PODIntervalTreeTest, TestTreeDoesNotRequireMostOperators)
201 PODIntervalTree<EndpointType1> tree;
202 tree.add(tree.createInterval(EndpointType1(1), EndpointType1(2)));
203 ASSERT_TRUE(tree.checkInvariants());
206 // Uncomment to debug a failure of the insertion and deletion test. Won't work
207 // in release builds.
208 // #define DEBUG_INSERTION_AND_DELETION_TEST
210 #ifndef NDEBUG
211 template<>
212 struct ValueToString<int> {
213 static String string(const int& value) { return String::number(value); }
215 #endif
217 namespace {
219 void InsertionAndDeletionTest(int32_t seed, int treeSize)
221 initRandom(seed);
222 int maximumValue = treeSize;
223 // Build the tree
224 PODIntervalTree<int> tree;
225 Vector<PODInterval<int>> addedElements;
226 Vector<PODInterval<int>> removedElements;
227 for (int i = 0; i < treeSize; i++) {
228 int left = nextRandom(maximumValue);
229 int length = nextRandom(maximumValue);
230 PODInterval<int> interval(left, left + length);
231 tree.add(interval);
232 #ifdef DEBUG_INSERTION_AND_DELETION_TEST
233 WTF_LOG_ERROR("*** Adding element %s", ValueToString<PODInterval<int>>::string(interval).ascii().data());
234 #endif
235 addedElements.append(interval);
237 // Churn the tree's contents.
238 // First remove half of the elements in random order.
239 for (int i = 0; i < treeSize / 2; i++) {
240 int index = nextRandom(addedElements.size());
241 #ifdef DEBUG_INSERTION_AND_DELETION_TEST
242 WTF_LOG_ERROR("*** Removing element %s", ValueToString<PODInterval<int>>::string(addedElements[index]).ascii().data());
243 #endif
244 ASSERT_TRUE(tree.contains(addedElements[index])) << "Test failed for seed " << seed;
245 tree.remove(addedElements[index]);
246 removedElements.append(addedElements[index]);
247 addedElements.remove(index);
248 ASSERT_TRUE(tree.checkInvariants()) << "Test failed for seed " << seed;
250 // Now randomly add or remove elements.
251 for (int i = 0; i < 2 * treeSize; i++) {
252 bool add = false;
253 if (!addedElements.size())
254 add = true;
255 else if (!removedElements.size())
256 add = false;
257 else
258 add = (nextRandom(2) == 1);
259 if (add) {
260 int index = nextRandom(removedElements.size());
261 #ifdef DEBUG_INSERTION_AND_DELETION_TEST
262 WTF_LOG_ERROR("*** Adding element %s", ValueToString<PODInterval<int>>::string(removedElements[index]).ascii().data());
263 #endif
264 tree.add(removedElements[index]);
265 addedElements.append(removedElements[index]);
266 removedElements.remove(index);
267 } else {
268 int index = nextRandom(addedElements.size());
269 #ifdef DEBUG_INSERTION_AND_DELETION_TEST
270 WTF_LOG_ERROR("*** Removing element %s", ValueToString<PODInterval<int>>::string(addedElements[index]).ascii().data());
271 #endif
272 ASSERT_TRUE(tree.contains(addedElements[index])) << "Test failed for seed " << seed;
273 ASSERT_TRUE(tree.remove(addedElements[index])) << "Test failed for seed " << seed;
274 removedElements.append(addedElements[index]);
275 addedElements.remove(index);
277 ASSERT_TRUE(tree.checkInvariants()) << "Test failed for seed " << seed;
281 } // anonymous namespace
283 TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest1)
285 InsertionAndDeletionTest(13972, 100);
288 TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest2)
290 InsertionAndDeletionTest(1283382113, 10);
293 TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest3)
295 // This is the sequence of insertions and deletions that triggered
296 // the failure in RandomDeletionAndInsertionRegressionTest2.
297 PODIntervalTree<int> tree;
298 tree.add(tree.createInterval(0, 5));
299 ASSERT_TRUE(tree.checkInvariants());
300 tree.add(tree.createInterval(4, 5));
301 ASSERT_TRUE(tree.checkInvariants());
302 tree.add(tree.createInterval(8, 9));
303 ASSERT_TRUE(tree.checkInvariants());
304 tree.add(tree.createInterval(1, 4));
305 ASSERT_TRUE(tree.checkInvariants());
306 tree.add(tree.createInterval(3, 5));
307 ASSERT_TRUE(tree.checkInvariants());
308 tree.add(tree.createInterval(4, 12));
309 ASSERT_TRUE(tree.checkInvariants());
310 tree.add(tree.createInterval(0, 2));
311 ASSERT_TRUE(tree.checkInvariants());
312 tree.add(tree.createInterval(0, 2));
313 ASSERT_TRUE(tree.checkInvariants());
314 tree.add(tree.createInterval(9, 13));
315 ASSERT_TRUE(tree.checkInvariants());
316 tree.add(tree.createInterval(0, 1));
317 ASSERT_TRUE(tree.checkInvariants());
318 tree.remove(tree.createInterval(0, 2));
319 ASSERT_TRUE(tree.checkInvariants());
320 tree.remove(tree.createInterval(9, 13));
321 ASSERT_TRUE(tree.checkInvariants());
322 tree.remove(tree.createInterval(0, 2));
323 ASSERT_TRUE(tree.checkInvariants());
324 tree.remove(tree.createInterval(0, 1));
325 ASSERT_TRUE(tree.checkInvariants());
326 tree.remove(tree.createInterval(4, 5));
327 ASSERT_TRUE(tree.checkInvariants());
328 tree.remove(tree.createInterval(4, 12));
329 ASSERT_TRUE(tree.checkInvariants());
332 TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest4)
334 // Even further reduced test case for RandomDeletionAndInsertionRegressionTest3.
335 PODIntervalTree<int> tree;
336 tree.add(tree.createInterval(0, 5));
337 ASSERT_TRUE(tree.checkInvariants());
338 tree.add(tree.createInterval(8, 9));
339 ASSERT_TRUE(tree.checkInvariants());
340 tree.add(tree.createInterval(1, 4));
341 ASSERT_TRUE(tree.checkInvariants());
342 tree.add(tree.createInterval(3, 5));
343 ASSERT_TRUE(tree.checkInvariants());
344 tree.add(tree.createInterval(4, 12));
345 ASSERT_TRUE(tree.checkInvariants());
346 tree.remove(tree.createInterval(4, 12));
347 ASSERT_TRUE(tree.checkInvariants());
350 } // namespace blink