Serenity Operating System
at master 253 lines 7.1 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/DeprecatedString.h> 10#include <AK/HashMap.h> 11#include <AK/OwnPtr.h> 12#include <AK/String.h> 13 14TEST_CASE(construct) 15{ 16 using IntIntMap = HashMap<int, int>; 17 EXPECT(IntIntMap().is_empty()); 18 EXPECT_EQ(IntIntMap().size(), 0u); 19} 20 21TEST_CASE(construct_from_initializer_list) 22{ 23 HashMap<int, DeprecatedString> number_to_string { 24 { 1, "One" }, 25 { 2, "Two" }, 26 { 3, "Three" }, 27 }; 28 EXPECT_EQ(number_to_string.is_empty(), false); 29 EXPECT_EQ(number_to_string.size(), 3u); 30} 31 32TEST_CASE(populate) 33{ 34 HashMap<int, DeprecatedString> number_to_string; 35 number_to_string.set(1, "One"); 36 number_to_string.set(2, "Two"); 37 number_to_string.set(3, "Three"); 38 39 EXPECT_EQ(number_to_string.is_empty(), false); 40 EXPECT_EQ(number_to_string.size(), 3u); 41} 42 43TEST_CASE(range_loop) 44{ 45 HashMap<int, DeprecatedString> number_to_string; 46 EXPECT_EQ(number_to_string.set(1, "One"), AK::HashSetResult::InsertedNewEntry); 47 EXPECT_EQ(number_to_string.set(2, "Two"), AK::HashSetResult::InsertedNewEntry); 48 EXPECT_EQ(number_to_string.set(3, "Three"), AK::HashSetResult::InsertedNewEntry); 49 50 int loop_counter = 0; 51 for (auto& it : number_to_string) { 52 EXPECT_EQ(it.value.is_null(), false); 53 ++loop_counter; 54 } 55 EXPECT_EQ(loop_counter, 3); 56} 57 58TEST_CASE(map_remove) 59{ 60 HashMap<int, DeprecatedString> number_to_string; 61 EXPECT_EQ(number_to_string.set(1, "One"), AK::HashSetResult::InsertedNewEntry); 62 EXPECT_EQ(number_to_string.set(2, "Two"), AK::HashSetResult::InsertedNewEntry); 63 EXPECT_EQ(number_to_string.set(3, "Three"), AK::HashSetResult::InsertedNewEntry); 64 65 EXPECT_EQ(number_to_string.remove(1), true); 66 EXPECT_EQ(number_to_string.size(), 2u); 67 EXPECT(number_to_string.find(1) == number_to_string.end()); 68 69 EXPECT_EQ(number_to_string.remove(3), true); 70 EXPECT_EQ(number_to_string.size(), 1u); 71 EXPECT(number_to_string.find(3) == number_to_string.end()); 72 EXPECT(number_to_string.find(2) != number_to_string.end()); 73} 74 75TEST_CASE(remove_all_matching) 76{ 77 HashMap<int, DeprecatedString> map; 78 79 map.set(1, "One"); 80 map.set(2, "Two"); 81 map.set(3, "Three"); 82 map.set(4, "Four"); 83 84 EXPECT_EQ(map.size(), 4u); 85 86 EXPECT_EQ(map.remove_all_matching([&](int key, DeprecatedString const& value) { return key == 1 || value == "Two"; }), true); 87 EXPECT_EQ(map.size(), 2u); 88 89 EXPECT_EQ(map.remove_all_matching([&](int, DeprecatedString const&) { return false; }), false); 90 EXPECT_EQ(map.size(), 2u); 91 92 EXPECT(map.contains(3)); 93 EXPECT(map.contains(4)); 94 95 EXPECT_EQ(map.remove_all_matching([&](int, DeprecatedString const&) { return true; }), true); 96 EXPECT_EQ(map.remove_all_matching([&](int, DeprecatedString const&) { return false; }), false); 97 98 EXPECT(map.is_empty()); 99 100 EXPECT_EQ(map.remove_all_matching([&](int, DeprecatedString const&) { return true; }), false); 101} 102 103TEST_CASE(case_insensitive) 104{ 105 HashMap<DeprecatedString, int, CaseInsensitiveStringTraits> casemap; 106 EXPECT_EQ(DeprecatedString("nickserv").to_lowercase(), DeprecatedString("NickServ").to_lowercase()); 107 EXPECT_EQ(casemap.set("nickserv", 3), AK::HashSetResult::InsertedNewEntry); 108 EXPECT_EQ(casemap.set("NickServ", 3), AK::HashSetResult::ReplacedExistingEntry); 109 EXPECT_EQ(casemap.size(), 1u); 110} 111 112TEST_CASE(case_insensitive_stringview) 113{ 114 HashMap<StringView, int, CaseInsensitiveStringViewTraits> casemap; 115 EXPECT_EQ(casemap.set("nickserv"sv, 3), AK::HashSetResult::InsertedNewEntry); 116 EXPECT_EQ(casemap.set("NickServ"sv, 3), AK::HashSetResult::ReplacedExistingEntry); 117 EXPECT_EQ(casemap.size(), 1u); 118} 119 120TEST_CASE(hashmap_of_nonnullownptr_get) 121{ 122 struct Object { 123 Object(DeprecatedString const& s) 124 : string(s) 125 { 126 } 127 DeprecatedString string; 128 }; 129 130 HashMap<int, NonnullOwnPtr<Object>> objects; 131 objects.set(1, make<Object>("One")); 132 objects.set(2, make<Object>("Two")); 133 objects.set(3, make<Object>("Three")); 134 135 { 136 auto x = objects.get(2); 137 EXPECT_EQ(x.has_value(), true); 138 EXPECT_EQ(x.value()->string, "Two"); 139 } 140 141 { 142 // Do it again to make sure that peeking into the map above didn't 143 // remove the value from the map. 144 auto x = objects.get(2); 145 EXPECT_EQ(x.has_value(), true); 146 EXPECT_EQ(x.value()->string, "Two"); 147 } 148 149 EXPECT_EQ(objects.size(), 3u); 150} 151 152TEST_CASE(many_strings) 153{ 154 HashMap<DeprecatedString, int> strings; 155 for (int i = 0; i < 999; ++i) { 156 EXPECT_EQ(strings.set(DeprecatedString::number(i), i), AK::HashSetResult::InsertedNewEntry); 157 } 158 EXPECT_EQ(strings.size(), 999u); 159 for (auto& it : strings) { 160 EXPECT_EQ(it.key.to_int().value(), it.value); 161 } 162 for (int i = 0; i < 999; ++i) { 163 EXPECT_EQ(strings.remove(DeprecatedString::number(i)), true); 164 } 165 EXPECT_EQ(strings.is_empty(), true); 166} 167 168TEST_CASE(basic_remove) 169{ 170 HashMap<int, int> map; 171 map.set(1, 10); 172 map.set(2, 20); 173 map.set(3, 30); 174 175 EXPECT_EQ(map.remove(3), true); 176 EXPECT_EQ(map.remove(3), false); 177 EXPECT_EQ(map.size(), 2u); 178 179 EXPECT_EQ(map.remove(1), true); 180 EXPECT_EQ(map.remove(1), false); 181 EXPECT_EQ(map.size(), 1u); 182 183 EXPECT_EQ(map.remove(2), true); 184 EXPECT_EQ(map.remove(2), false); 185 EXPECT_EQ(map.size(), 0u); 186} 187 188TEST_CASE(basic_contains) 189{ 190 HashMap<int, int> map; 191 map.set(1, 10); 192 map.set(2, 20); 193 map.set(3, 30); 194 195 EXPECT_EQ(map.contains(1), true); 196 EXPECT_EQ(map.contains(2), true); 197 EXPECT_EQ(map.contains(3), true); 198 EXPECT_EQ(map.contains(4), false); 199 200 EXPECT_EQ(map.remove(3), true); 201 EXPECT_EQ(map.contains(3), false); 202 EXPECT_EQ(map.contains(1), true); 203 EXPECT_EQ(map.contains(2), true); 204 205 EXPECT_EQ(map.remove(2), true); 206 EXPECT_EQ(map.contains(2), false); 207 EXPECT_EQ(map.contains(3), false); 208 EXPECT_EQ(map.contains(1), true); 209 210 EXPECT_EQ(map.remove(1), true); 211 EXPECT_EQ(map.contains(1), false); 212} 213 214TEST_CASE(in_place_rehashing_ordered_loop_bug) 215{ 216 OrderedHashMap<DeprecatedString, DeprecatedString> map; 217 map.set("yt.innertube::nextId", ""); 218 map.set("yt.innertube::requests", ""); 219 map.remove("yt.innertube::nextId"); 220 map.set("yt.innertube::nextId", ""); 221 VERIFY(map.keys().size() == 2); 222} 223 224TEST_CASE(take) 225{ 226 HashMap<String, int> map; 227 228 EXPECT(!map.take("foo"sv).has_value()); 229 EXPECT(!map.take("bar"sv).has_value()); 230 EXPECT(!map.take("baz"_short_string).has_value()); 231 232 map.set("foo"_short_string, 1); 233 map.set("bar"_short_string, 2); 234 map.set("baz"_short_string, 3); 235 236 auto foo = map.take("foo"sv); 237 EXPECT_EQ(foo, 1); 238 239 foo = map.take("foo"sv); 240 EXPECT(!foo.has_value()); 241 242 auto bar = map.take("bar"sv); 243 EXPECT_EQ(bar, 2); 244 245 bar = map.take("bar"sv); 246 EXPECT(!bar.has_value()); 247 248 auto baz = map.take("baz"_short_string); 249 EXPECT_EQ(baz, 3); 250 251 baz = map.take("baz"_short_string); 252 EXPECT(!baz.has_value()); 253}