Serenity Operating System
at hosted 316 lines 7.8 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <AK/TestSuite.h> 28 29#include <AK/String.h> 30#include <AK/NonnullOwnPtrVector.h> 31#include <AK/OwnPtr.h> 32#include <AK/Vector.h> 33 34TEST_CASE(construct) 35{ 36 EXPECT(Vector<int>().is_empty()); 37 EXPECT(Vector<int>().size() == 0); 38} 39 40TEST_CASE(ints) 41{ 42 Vector<int> ints; 43 ints.append(1); 44 ints.append(2); 45 ints.append(3); 46 EXPECT_EQ(ints.size(), 3u); 47 EXPECT_EQ(ints.take_last(), 3); 48 EXPECT_EQ(ints.size(), 2u); 49 EXPECT_EQ(ints.take_last(), 2); 50 EXPECT_EQ(ints.size(), 1u); 51 EXPECT_EQ(ints.take_last(), 1); 52 EXPECT_EQ(ints.size(), 0u); 53 54 ints.clear(); 55 EXPECT_EQ(ints.size(), 0u); 56} 57 58TEST_CASE(strings) 59{ 60 Vector<String> strings; 61 strings.append("ABC"); 62 strings.append("DEF"); 63 64 int loop_counter = 0; 65 for (const String& string : strings) { 66 EXPECT(!string.is_null()); 67 EXPECT(!string.is_empty()); 68 ++loop_counter; 69 } 70 71 loop_counter = 0; 72 for (auto& string : (const_cast<const Vector<String>&>(strings))) { 73 EXPECT(!string.is_null()); 74 EXPECT(!string.is_empty()); 75 ++loop_counter; 76 } 77 EXPECT_EQ(loop_counter, 2); 78} 79 80TEST_CASE(strings_insert_ordered) 81{ 82 Vector<String> strings; 83 strings.append("abc"); 84 strings.append("def"); 85 strings.append("ghi"); 86 87 strings.insert_before_matching("f-g", [](auto& entry) { 88 return "f-g" < entry; 89 }); 90 91 EXPECT_EQ(strings[0], "abc"); 92 EXPECT_EQ(strings[1], "def"); 93 EXPECT_EQ(strings[2], "f-g"); 94 EXPECT_EQ(strings[3], "ghi"); 95} 96 97TEST_CASE(prepend_vector) 98{ 99 Vector<int> ints; 100 ints.append(1); 101 ints.append(2); 102 ints.append(3); 103 104 Vector<int> more_ints; 105 more_ints.append(4); 106 more_ints.append(5); 107 more_ints.append(6); 108 109 ints.prepend(move(more_ints)); 110 111 EXPECT_EQ(ints.size(), 6u); 112 EXPECT_EQ(more_ints.size(), 0u); 113 114 EXPECT_EQ(ints[0], 4); 115 EXPECT_EQ(ints[1], 5); 116 EXPECT_EQ(ints[2], 6); 117 EXPECT_EQ(ints[3], 1); 118 EXPECT_EQ(ints[4], 2); 119 EXPECT_EQ(ints[5], 3); 120 121 ints.prepend(move(more_ints)); 122 EXPECT_EQ(ints.size(), 6u); 123 EXPECT_EQ(more_ints.size(), 0u); 124 125 more_ints.prepend(move(ints)); 126 EXPECT_EQ(more_ints.size(), 6u); 127 EXPECT_EQ(ints.size(), 0u); 128} 129 130TEST_CASE(prepend_vector_object) 131{ 132 struct SubObject { 133 SubObject(int v) 134 : value(v) 135 { 136 } 137 int value { 0 }; 138 }; 139 struct Object { 140 Object(NonnullOwnPtr<SubObject>&& a_subobject) 141 : subobject(move(a_subobject)) 142 { 143 } 144 OwnPtr<SubObject> subobject; 145 }; 146 147 Vector<Object> objects; 148 objects.empend(make<SubObject>(1)); 149 objects.empend(make<SubObject>(2)); 150 objects.empend(make<SubObject>(3)); 151 152 EXPECT_EQ(objects.size(), 3u); 153 154 Vector<Object> more_objects; 155 more_objects.empend(make<SubObject>(4)); 156 more_objects.empend(make<SubObject>(5)); 157 more_objects.empend(make<SubObject>(6)); 158 EXPECT_EQ(more_objects.size(), 3u); 159 160 objects.prepend(move(more_objects)); 161 EXPECT_EQ(more_objects.size(), 0u); 162 EXPECT_EQ(objects.size(), 6u); 163 164 EXPECT_EQ(objects[0].subobject->value, 4); 165 EXPECT_EQ(objects[1].subobject->value, 5); 166 EXPECT_EQ(objects[2].subobject->value, 6); 167 EXPECT_EQ(objects[3].subobject->value, 1); 168 EXPECT_EQ(objects[4].subobject->value, 2); 169 EXPECT_EQ(objects[5].subobject->value, 3); 170} 171 172TEST_CASE(vector_compare) 173{ 174 Vector<int> ints; 175 Vector<int> same_ints; 176 177 for (int i = 0; i < 1000; ++i) { 178 ints.append(i); 179 same_ints.append(i); 180 } 181 182 EXPECT_EQ(ints.size(), 1000u); 183 EXPECT_EQ(ints, same_ints); 184 185 Vector<String> strings; 186 Vector<String> same_strings; 187 188 for (int i = 0; i < 1000; ++i) { 189 strings.append(String::number(i)); 190 same_strings.append(String::number(i)); 191 } 192 193 EXPECT_EQ(strings.size(), 1000u); 194 EXPECT_EQ(strings, same_strings); 195} 196 197TEST_CASE(grow_past_inline_capacity) 198{ 199 auto make_vector = [] { 200 Vector<String, 16> strings; 201 for (int i = 0; i < 32; ++i) { 202 strings.append(String::number(i)); 203 } 204 return strings; 205 }; 206 207 auto strings = make_vector(); 208 209 EXPECT_EQ(strings.size(), 32u); 210 EXPECT_EQ(strings[31], "31"); 211 212 strings.clear(); 213 EXPECT_EQ(strings.size(), 0u); 214 EXPECT_EQ(strings.capacity(), 16u); 215 216 strings = make_vector(); 217 218 strings.clear_with_capacity(); 219 EXPECT_EQ(strings.size(), 0u); 220 EXPECT(strings.capacity() >= 32u); 221} 222 223BENCHMARK_CASE(vector_append_trivial) 224{ 225 // This should be super fast thanks to Vector using memmove. 226 Vector<int> ints; 227 for (int i = 0; i < 1000000; ++i) { 228 ints.append(i); 229 } 230 for (int i = 0; i < 100; ++i) { 231 Vector<int> tmp; 232 tmp.append(ints); 233 EXPECT_EQ(tmp.size(), 1000000u); 234 } 235} 236 237BENCHMARK_CASE(vector_remove_trivial) 238{ 239 // This should be super fast thanks to Vector using memmove. 240 Vector<int> ints; 241 for (int i = 0; i < 10000; ++i) { 242 ints.append(i); 243 } 244 while (!ints.is_empty()) { 245 ints.remove(0); 246 } 247 EXPECT_EQ(ints.size(), 0u); 248} 249 250TEST_CASE(vector_remove) 251{ 252 Vector<int> ints; 253 ints.append(1); 254 ints.append(2); 255 ints.append(3); 256 ints.append(4); 257 ints.append(5); 258 259 ints.remove(1); 260 EXPECT_EQ(ints.size(), 4u); 261 EXPECT_EQ(ints[0], 1); 262 EXPECT_EQ(ints[1], 3); 263 EXPECT_EQ(ints[2], 4); 264 EXPECT_EQ(ints[3], 5); 265 266 ints.remove(0); 267 EXPECT_EQ(ints.size(), 3u); 268 EXPECT_EQ(ints[0], 3); 269 EXPECT_EQ(ints[1], 4); 270 EXPECT_EQ(ints[2], 5); 271 272 ints.take_last(); 273 EXPECT_EQ(ints.size(), 2u); 274 EXPECT_EQ(ints[0], 3); 275 EXPECT_EQ(ints[1], 4); 276 277 ints.take_first(); 278 EXPECT_EQ(ints.size(), 1u); 279 EXPECT_EQ(ints[0], 4); 280} 281 282TEST_CASE(nonnullownptrvector) 283{ 284 struct Object { 285 String string; 286 }; 287 NonnullOwnPtrVector<Object> objects; 288 289 objects.append(make<Object>()); 290 EXPECT_EQ(objects.size(), 1u); 291 292 OwnPtr<Object> o = make<Object>(); 293 objects.append(o.release_nonnull()); 294 EXPECT(o == nullptr); 295 EXPECT_EQ(objects.size(), 2u); 296} 297 298TEST_CASE(insert_trivial) 299{ 300 Vector<int> ints; 301 ints.append(0); 302 ints.append(10); 303 ints.append(20); 304 ints.append(30); 305 ints.append(40); 306 ints.insert(2, 15); 307 EXPECT_EQ(ints.size(), 6u); 308 EXPECT_EQ(ints[0], 0); 309 EXPECT_EQ(ints[1], 10); 310 EXPECT_EQ(ints[2], 15); 311 EXPECT_EQ(ints[3], 20); 312 EXPECT_EQ(ints[4], 30); 313 EXPECT_EQ(ints[5], 40); 314} 315 316TEST_MAIN(Vector)