OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 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 <set> | |
6 | |
7 #include "testing/gtest/include/gtest/gtest.h" | |
8 #include "ui/gfx/geometry/r_tree.h" | |
9 #include "ui/gfx/geometry/rect.h" | |
10 | |
11 namespace gfx { | |
piman
2014/04/21 23:59:31
I think we want to add several tests around all th
luken
2014/04/28 01:33:34
Done.
| |
12 | |
13 // Adds count squares stacked around the point (0,0) with key equal to width. | |
14 void AddStackedSquares(RTree* rt, int count) { | |
15 for (int i = 1; i <= count; ++i) { | |
16 rt->Insert(Rect(0, 0, i, i), reinterpret_cast<void*>(i)); | |
17 EXPECT_TRUE(rt->Validate()); | |
18 } | |
19 } | |
20 | |
21 // Given an unordered list of matching keys, verify that it contains all values | |
22 // [1..length] for the length of that list. | |
23 void VerifyAllKeys(const std::set<void*>& keys) { | |
24 // Verify that each key was uniquely identified. | |
25 int c = 1; | |
26 for (std::set<void*>::const_iterator it = keys.begin(); | |
27 it != keys.end(); | |
28 it++) { | |
29 // Verify that the keys are in values [1,count]. | |
30 EXPECT_EQ(c, reinterpret_cast<int>((*it))); | |
piman
2014/04/21 23:59:31
nit: extra () around *it
luken
2014/04/28 01:33:34
Done.
| |
31 ++c; | |
32 } | |
33 } | |
34 | |
35 // An empty RTree should never return Query results, and RTrees should be empty | |
36 // upon construction. | |
37 TEST(RTreeTest, QueryEmptyTree) { | |
38 RTree rt(2, 10); | |
39 EXPECT_TRUE(rt.Validate()); | |
40 std::set<void*> results; | |
41 Rect test_rect(25, 25); | |
42 rt.Query(test_rect, &results); | |
43 EXPECT_EQ(results.size(), 0U); | |
44 EXPECT_TRUE(rt.Validate()); | |
45 } | |
46 | |
47 // Clear should empty the tree, meaning that all queries should not return | |
48 // results after. | |
49 TEST(RTreeTest, ClearEmptiesTreeOfSingleNode) { | |
50 RTree rt(2, 5); | |
51 rt.Insert(Rect(0, 0, 100, 100), reinterpret_cast<void*>(1)); | |
52 rt.Clear(); | |
53 std::set<void*> results; | |
54 Rect test_rect(1, 1); | |
55 rt.Query(test_rect, &results); | |
56 EXPECT_EQ(results.size(), 0U); | |
57 } | |
58 | |
59 // Even with a complex internal structure, clear should empty the tree, meaning | |
60 // that all queries should not return results after. | |
61 TEST(RTreeTest, ClearEmptiesTreeOfManyNodes) { | |
62 RTree rt(2, 5); | |
63 AddStackedSquares(&rt, 100); | |
64 rt.Clear(); | |
65 EXPECT_TRUE(rt.Validate()); | |
66 std::set<void*> results; | |
67 Rect test_rect(1, 1); | |
68 rt.Query(test_rect, &results); | |
69 EXPECT_EQ(results.size(), 0U); | |
70 } | |
71 | |
72 // Duplicate inserts should overwrite previous inserts. | |
73 TEST(RTreeTest, DuplicateInsertsOverwrite) { | |
74 RTree rt(2, 5); | |
75 // Add 100 stacked squares, but always with duplicate key of 1. | |
76 for (int i = 1; i <= 100; ++i) { | |
77 rt.Insert(Rect(0, 0, i, i), reinterpret_cast<void*>(1)); | |
78 EXPECT_TRUE(rt.Validate()); | |
79 } | |
80 std::set<void*> results; | |
81 Rect test_rect(1, 1); | |
82 rt.Query(test_rect, &results); | |
83 EXPECT_EQ(results.size(), 1U); | |
84 EXPECT_EQ(reinterpret_cast<int>(*(results.begin())), 1); | |
85 } | |
86 | |
87 // Call Remove() once on something that's been inserted repeatedly. | |
88 TEST(RTreeTest, DuplicateInsertRemove) { | |
89 RTree rt(3, 9); | |
90 AddStackedSquares(&rt, 25); | |
91 for (int i = 1; i <= 100; ++i) { | |
92 rt.Insert(Rect(0, 0, i, i), reinterpret_cast<void*>(26)); | |
93 EXPECT_TRUE(rt.Validate()); | |
94 } | |
95 rt.Remove(reinterpret_cast<void*>(26)); | |
96 std::set<void*> results; | |
97 Rect test_rect(1, 1); | |
98 rt.Query(test_rect, &results); | |
99 EXPECT_EQ(results.size(), 25U); | |
100 VerifyAllKeys(results); | |
101 } | |
102 | |
103 // Call Remove() repeatedly on something that's been inserted once. | |
104 TEST(RTreeTest, InsertDuplicateRemove) { | |
105 RTree rt(7, 15); | |
106 AddStackedSquares(&rt, 101); | |
107 for (int i = 0; i < 100; ++i) { | |
108 rt.Remove(reinterpret_cast<void*>(101)); | |
109 EXPECT_TRUE(rt.Validate()); | |
110 } | |
111 std::set<void*> results; | |
112 Rect test_rect(1, 1); | |
113 rt.Query(test_rect, &results); | |
114 EXPECT_EQ(results.size(), 100U); | |
115 VerifyAllKeys(results); | |
116 } | |
117 | |
118 // Stacked rects should meet all matching queries regardless of nesting. | |
119 TEST(RTreeTest, QueryStackedSquaresNestedHit) { | |
120 RTree rt(2, 5); | |
121 AddStackedSquares(&rt, 100); | |
122 std::set<void*> results; | |
123 Rect test_rect(1, 1); | |
124 rt.Query(test_rect, &results); | |
125 EXPECT_EQ(results.size(), 100U); | |
126 VerifyAllKeys(results); | |
127 } | |
128 | |
129 // Stacked rects should meet all matching queries when contained completely by | |
130 // the query rectangle. | |
131 TEST(RTreeTest, QueryStackedSquaresContainedHit) { | |
132 RTree rt(2, 10); | |
133 AddStackedSquares(&rt, 100); | |
134 std::set<void*> results; | |
135 Rect test_rect(0, 0, 100, 100); | |
136 rt.Query(test_rect, &results); | |
137 EXPECT_EQ(results.size(), 100U); | |
138 VerifyAllKeys(results); | |
139 } | |
140 | |
141 // Stacked rects should miss a missing query when the query has no intersection | |
142 // with the rects. | |
143 TEST(RTreeTest, QueryStackedSquaresCompleteMiss) { | |
144 RTree rt(2, 7); | |
145 AddStackedSquares(&rt, 100); | |
146 std::set<void*> results; | |
147 Rect test_rect(150, 150, 100, 100); | |
148 rt.Query(test_rect, &results); | |
149 EXPECT_EQ(results.size(), 0U); | |
150 } | |
151 | |
152 // Removing half the nodes after insertion should still result in a valid tree. | |
153 TEST(RTreeTest, RemoveHalfStackedRects) { | |
154 RTree rt(2, 11); | |
155 AddStackedSquares(&rt, 200); | |
156 for (int i = 101; i <= 200; ++i) { | |
157 rt.Remove(reinterpret_cast<void*>(i)); | |
158 EXPECT_TRUE(rt.Validate()); | |
159 } | |
160 std::set<void*> results; | |
161 Rect test_rect(1, 1); | |
162 rt.Query(test_rect, &results); | |
163 EXPECT_EQ(results.size(), 100U); | |
164 VerifyAllKeys(results); | |
165 // Add the nodes back in. | |
166 for (int i = 101; i <= 200; ++i) { | |
167 rt.Insert(Rect(0, 0, i, i), reinterpret_cast<void*>(i)); | |
168 EXPECT_TRUE(rt.Validate()); | |
169 } | |
170 results.clear(); | |
171 rt.Query(test_rect, &results); | |
172 EXPECT_EQ(results.size(), 200U); | |
173 VerifyAllKeys(results); | |
174 } | |
175 | |
176 TEST(RTreeTest, InsertNegativeCoordsRect) { | |
177 RTree rt(5, 11); | |
178 for (int i = 1; i <= 100; ++i) { | |
179 rt.Insert(Rect(-i, -i, i, i), reinterpret_cast<void*>((i * 2) - 1)); | |
180 EXPECT_TRUE(rt.Validate()); | |
181 rt.Insert(Rect(0, 0, i, i), reinterpret_cast<void*>(i * 2)); | |
182 EXPECT_TRUE(rt.Validate()); | |
183 } | |
184 std::set<void*> results; | |
185 Rect test_rect(-1, -1, 2, 2); | |
186 rt.Query(test_rect, &results); | |
187 EXPECT_EQ(results.size(), 200U); | |
188 VerifyAllKeys(results); | |
189 } | |
190 | |
191 TEST(RTreeTest, RemoveNegativeCoordsRect) { | |
192 RTree rt(7, 21); | |
193 // Add 100 positive stacked squares. | |
194 AddStackedSquares(&rt, 100); | |
195 // Now add 100 negative stacked squares. | |
196 for (int i = 101; i <= 200; ++i) { | |
197 rt.Insert(Rect(100 - i, 100 - i, i - 100, i - 100), | |
198 reinterpret_cast<void*>(301 - i)); | |
199 EXPECT_TRUE(rt.Validate()); | |
200 } | |
201 // Now remove half of the negative squares. | |
202 for (int i = 101; i <= 150; ++i) { | |
203 rt.Remove(reinterpret_cast<void*>(301 - i)); | |
204 EXPECT_TRUE(rt.Validate()); | |
205 } | |
206 // Queries should return 100 positive and 50 negative stacked squares. | |
207 std::set<void*> results; | |
208 Rect test_rect(-1, -1, 2, 2); | |
209 rt.Query(test_rect, &results); | |
210 EXPECT_EQ(results.size(), 150U); | |
211 VerifyAllKeys(results); | |
212 } | |
213 | |
214 } // namespace gfx | |
OLD | NEW |