Serenity Operating System
at master 404 lines 11 kB view raw
1/* 2 * Copyright (c) 2020, Ben Wiederhake <BenWiederhake.GitHub@gmx.de> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/Checked.h> 10#include <AK/NumericLimits.h> 11 12// These tests only check whether the usual operator semantics work. 13// TODO: Add tests about the actual `Check`ing itself! 14 15TEST_CASE(address_identity) 16{ 17 Checked<int> a = 4; 18 Checked<int> b = 5; 19 EXPECT_EQ(&a == &a, true); 20 EXPECT_EQ(&a == &b, false); 21 EXPECT_EQ(&a != &a, false); 22 EXPECT_EQ(&a != &b, true); 23} 24 25TEST_CASE(operator_identity) 26{ 27 Checked<int> a = 4; 28 EXPECT_EQ(a == 4, true); 29 EXPECT_EQ(a == 5, false); 30 EXPECT_EQ(a != 4, false); 31 EXPECT_EQ(a != 5, true); 32} 33 34TEST_CASE(operator_incr) 35{ 36 Checked<int> a = 4; 37 EXPECT_EQ(++a, 5); 38 EXPECT_EQ(++a, 6); 39 EXPECT_EQ(++a, 7); 40 EXPECT_EQ(a++, 7); 41 EXPECT_EQ(a++, 8); 42 EXPECT_EQ(a++, 9); 43 EXPECT_EQ(a, 10); 44} 45 46TEST_CASE(operator_decr) 47{ 48 Checked<u32> a = 5; 49 EXPECT_EQ(--a, 4u); 50 EXPECT_EQ(--a, 3u); 51 EXPECT_EQ(a--, 3u); 52 EXPECT_EQ(a--, 2u); 53 EXPECT_EQ(a--, 1u); 54 EXPECT_EQ(a, 0u); 55 EXPECT(!a.has_overflow()); 56 a--; 57 EXPECT(a.has_overflow()); 58} 59 60TEST_CASE(operator_cmp) 61{ 62 Checked<int> a = 4; 63 EXPECT_EQ(a > 3, true); 64 EXPECT_EQ(a < 3, false); 65 EXPECT_EQ(a >= 3, true); 66 EXPECT_EQ(a <= 3, false); 67 EXPECT_EQ(a > 4, false); 68 EXPECT_EQ(a < 4, false); 69 EXPECT_EQ(a >= 4, true); 70 EXPECT_EQ(a <= 4, true); 71 EXPECT_EQ(a > 5, false); 72 EXPECT_EQ(a < 5, true); 73 EXPECT_EQ(a >= 5, false); 74 EXPECT_EQ(a <= 5, true); 75} 76 77TEST_CASE(operator_arith) 78{ 79 Checked<int> a = 12; 80 Checked<int> b = 345; 81 EXPECT_EQ(a + b, 357); 82 EXPECT_EQ(b + a, 357); 83 EXPECT_EQ(a - b, -333); 84 EXPECT_EQ(b - a, 333); 85 EXPECT_EQ(a * b, 4140); 86 EXPECT_EQ(b * a, 4140); 87 EXPECT_EQ(a / b, 0); 88 EXPECT_EQ(b / a, 28); 89} 90 91TEST_CASE(detects_signed_overflow) 92{ 93 EXPECT(!(Checked<int>(0x40000000) + Checked<int>(0x3fffffff)).has_overflow()); 94 EXPECT((Checked<int>(0x40000000) + Checked<int>(0x40000000)).has_overflow()); 95 EXPECT(!(Checked<int>(-0x40000000) + Checked<int>(-0x40000000)).has_overflow()); 96 EXPECT((Checked<int>(-0x40000001) + Checked<int>(-0x40000000)).has_overflow()); 97 98 EXPECT(!(Checked<int>(0x40000000) - Checked<int>(-0x3fffffff)).has_overflow()); 99 EXPECT((Checked<int>(0x40000000) - Checked<int>(-0x40000000)).has_overflow()); 100 EXPECT(!(Checked<int>(-0x40000000) - Checked<int>(0x40000000)).has_overflow()); 101 EXPECT((Checked<int>(-0x40000000) - Checked<int>(0x40000001)).has_overflow()); 102 103 EXPECT(!(Checked<i64>(0x4000000000000000) + Checked<i64>(0x3fffffffffffffff)).has_overflow()); 104 EXPECT((Checked<i64>(0x4000000000000000) + Checked<i64>(0x4000000000000000)).has_overflow()); 105 EXPECT(!(Checked<i64>(-0x4000000000000000) + Checked<i64>(-0x4000000000000000)).has_overflow()); 106 EXPECT((Checked<i64>(-0x4000000000000001) + Checked<i64>(-0x4000000000000000)).has_overflow()); 107 108 EXPECT(!(Checked<i64>(0x4000000000000000) - Checked<i64>(-0x3fffffffffffffff)).has_overflow()); 109 EXPECT((Checked<i64>(0x4000000000000000) - Checked<i64>(-0x4000000000000000)).has_overflow()); 110 EXPECT(!(Checked<i64>(-0x4000000000000000) - Checked<i64>(0x4000000000000000)).has_overflow()); 111 EXPECT((Checked<i64>(-0x4000000000000000) - Checked<i64>(0x4000000000000001)).has_overflow()); 112 113 EXPECT((Checked<i32>(0x80000000) / Checked<i32>(-1)).has_overflow()); 114 EXPECT((Checked<i64>(0x8000000000000000) / Checked<i64>(-1)).has_overflow()); 115} 116 117TEST_CASE(detects_unsigned_overflow) 118{ 119 EXPECT(!(Checked<u32>(0x40000000) + Checked<u32>(0x3fffffff)).has_overflow()); 120 EXPECT(!(Checked<u32>(0x40000000) + Checked<u32>(0x40000000)).has_overflow()); 121 EXPECT(!(Checked<u32>(0xf0000000) + Checked<u32>(0x0fffffff)).has_overflow()); 122 EXPECT((Checked<u32>(0xf0000000) + Checked<u32>(0x10000000)).has_overflow()); 123 124 EXPECT(!(Checked<u32>(0x40000000) - Checked<u32>(0x3fffffff)).has_overflow()); 125 EXPECT(!(Checked<u32>(0x40000000) - Checked<u32>(0x40000000)).has_overflow()); 126 EXPECT((Checked<u32>(0x40000000) - Checked<u32>(0x40000001)).has_overflow()); 127 128 EXPECT(!(Checked<u64>(0x4000000000000000) + Checked<u64>(0x3fffffffffffffff)).has_overflow()); 129 EXPECT(!(Checked<u64>(0x4000000000000000) + Checked<u64>(0x4000000000000000)).has_overflow()); 130 EXPECT(!(Checked<u64>(0xf000000000000000) + Checked<u64>(0x0fffffffffffffff)).has_overflow()); 131 EXPECT((Checked<u64>(0xf000000000000000) + Checked<u64>(0x1000000000000000)).has_overflow()); 132 133 EXPECT(!(Checked<u64>(0x4000000000000000) - Checked<u64>(0x3fffffffffffffff)).has_overflow()); 134 EXPECT(!(Checked<u64>(0x4000000000000000) - Checked<u64>(0x4000000000000000)).has_overflow()); 135 EXPECT((Checked<u64>(0x4000000000000000) - Checked<u64>(0x4000000000000001)).has_overflow()); 136} 137 138TEST_CASE(should_constexpr_default_construct) 139{ 140 constexpr Checked<int> checked_value {}; 141 static_assert(!checked_value.has_overflow()); 142 static_assert(checked_value == int {}); 143} 144 145TEST_CASE(should_constexpr_value_construct) 146{ 147 constexpr Checked<int> checked_value { 42 }; 148 static_assert(!checked_value.has_overflow()); 149 static_assert(checked_value == 42); 150} 151 152TEST_CASE(should_constexpr_convert_construct) 153{ 154 constexpr Checked<int> checked_value { 42u }; 155 static_assert(!checked_value.has_overflow()); 156 static_assert(checked_value == 42); 157} 158 159TEST_CASE(should_constexpr_copy_construct) 160{ 161 constexpr auto checked_value = [] { 162 const Checked<int> old_value { 42 }; 163 Checked<int> value(old_value); 164 return value; 165 }(); 166 static_assert(!checked_value.has_overflow()); 167 static_assert(checked_value == 42); 168} 169 170TEST_CASE(should_constexpr_move_construct) 171{ 172 constexpr auto checked_value = [] { 173 Checked<int> value(Checked<int> { 42 }); 174 return value; 175 }(); 176 static_assert(!checked_value.has_overflow()); 177 static_assert(checked_value == 42); 178} 179 180TEST_CASE(should_constexpr_copy_assign) 181{ 182 constexpr auto checked_value = [] { 183 const Checked<int> old_value { 42 }; 184 Checked<int> value {}; 185 value = old_value; 186 return value; 187 }(); 188 static_assert(!checked_value.has_overflow()); 189 static_assert(checked_value == 42); 190} 191 192TEST_CASE(should_constexpr_move_assign) 193{ 194 constexpr auto checked_value = [] { 195 Checked<int> value {}; 196 value = Checked<int> { 42 }; 197 return value; 198 }(); 199 static_assert(!checked_value.has_overflow()); 200 static_assert(checked_value == 42); 201} 202 203TEST_CASE(should_constexpr_convert_and_assign) 204{ 205 constexpr auto checked_value = [] { 206 Checked<int> value {}; 207 value = 42; 208 return value; 209 }(); 210 static_assert(!checked_value.has_overflow()); 211 static_assert(checked_value == 42); 212} 213 214TEST_CASE(should_constexpr_not_operator) 215{ 216 constexpr Checked<int> value {}; 217 static_assert(!value); 218} 219 220TEST_CASE(should_constexpr_value_accessor) 221{ 222 constexpr Checked<int> value { 42 }; 223 static_assert(value.value() == 42); 224} 225 226TEST_CASE(should_constexpr_add) 227{ 228 constexpr auto checked_value = [] { 229 Checked<int> value { 42 }; 230 value.add(3); 231 return value; 232 }(); 233 static_assert(checked_value == 45); 234} 235 236TEST_CASE(should_constexpr_sub) 237{ 238 constexpr auto checked_value = [] { 239 Checked<int> value { 42 }; 240 value.sub(3); 241 return value; 242 }(); 243 static_assert(checked_value == 39); 244} 245 246TEST_CASE(should_constexpr_mul) 247{ 248 constexpr auto checked_value = [] { 249 Checked<int> value { 42 }; 250 value.mul(2); 251 return value; 252 }(); 253 static_assert(checked_value == 84); 254} 255 256TEST_CASE(should_constexpr_div) 257{ 258 constexpr auto checked_value = [] { 259 Checked<int> value { 42 }; 260 value.div(3); 261 return value; 262 }(); 263 static_assert(checked_value == 14); 264} 265 266TEST_CASE(should_constexpr_assignment_by_sum) 267{ 268 constexpr auto checked_value = [] { 269 Checked<int> value { 42 }; 270 value += 3; 271 return value; 272 }(); 273 static_assert(checked_value == 45); 274} 275 276TEST_CASE(should_constexpr_assignment_by_diff) 277{ 278 constexpr auto checked_value = [] { 279 Checked<int> value { 42 }; 280 value -= 3; 281 return value; 282 }(); 283 static_assert(checked_value == 39); 284} 285 286TEST_CASE(should_constexpr_assignment_by_product) 287{ 288 constexpr auto checked_value = [] { 289 Checked<int> value { 42 }; 290 value *= 2; 291 return value; 292 }(); 293 static_assert(checked_value == 84); 294} 295 296TEST_CASE(should_constexpr_assignment_by_quotient) 297{ 298 constexpr auto checked_value = [] { 299 Checked<int> value { 42 }; 300 value /= 3; 301 return value; 302 }(); 303 static_assert(checked_value == 14); 304} 305 306TEST_CASE(should_constexpr_prefix_increment) 307{ 308 constexpr auto checked_value = [] { 309 Checked<int> value { 42 }; 310 ++value; 311 return value; 312 }(); 313 static_assert(checked_value == 43); 314} 315 316TEST_CASE(should_constexpr_postfix_increment) 317{ 318 constexpr auto checked_value = [] { 319 Checked<int> value { 42 }; 320 value++; 321 return value; 322 }(); 323 static_assert(checked_value == 43); 324} 325 326TEST_CASE(should_constexpr_check_for_overflow_addition) 327{ 328 static_assert(Checked<int>::addition_would_overflow(NumericLimits<int>::max(), 1)); 329} 330 331TEST_CASE(should_constexpr_check_for_overflow_multiplication) 332{ 333 static_assert(Checked<int>::multiplication_would_overflow(NumericLimits<int>::max(), 2)); 334 static_assert(Checked<int>::multiplication_would_overflow(NumericLimits<int>::max(), 1, 2)); 335} 336 337TEST_CASE(should_constexpr_add_checked_values) 338{ 339 constexpr Checked<int> a { 42 }; 340 constexpr Checked<int> b { 17 }; 341 constexpr Checked<int> expected { 59 }; 342 static_assert(expected == (a + b).value()); 343} 344 345TEST_CASE(should_constexpr_subtract_checked_values) 346{ 347 constexpr Checked<int> a { 42 }; 348 constexpr Checked<int> b { 17 }; 349 constexpr Checked<int> expected { 25 }; 350 static_assert(expected == (a - b).value()); 351} 352 353TEST_CASE(should_constexpr_multiply_checked_values) 354{ 355 constexpr Checked<int> a { 3 }; 356 constexpr Checked<int> b { 5 }; 357 constexpr Checked<int> expected { 15 }; 358 static_assert(expected == (a * b).value()); 359} 360 361TEST_CASE(should_constexpr_divide_checked_values) 362{ 363 constexpr Checked<int> a { 10 }; 364 constexpr Checked<int> b { 2 }; 365 constexpr Checked<int> expected { 5 }; 366 static_assert(expected == (a / b).value()); 367} 368 369TEST_CASE(should_constexpr_compare_checked_values_lhs) 370{ 371 constexpr Checked<int> a { 10 }; 372 373 static_assert(a > 5); 374 static_assert(a >= 10); 375 static_assert(a >= 5); 376 377 static_assert(a < 20); 378 static_assert(a <= 30); 379 static_assert(a <= 20); 380 381 static_assert(a == 10); 382 static_assert(a != 20); 383} 384 385TEST_CASE(should_constexpr_compare_checked_values_rhs) 386{ 387 constexpr Checked<int> a { 10 }; 388 389 static_assert(5 < a); 390 static_assert(10 <= a); 391 static_assert(5 <= a); 392 393 static_assert(20 > a); 394 static_assert(30 >= a); 395 static_assert(30 >= a); 396 397 static_assert(10 == a); 398 static_assert(20 != a); 399} 400 401TEST_CASE(should_constexpr_make_via_factory) 402{ 403 [[maybe_unused]] constexpr auto value = make_checked(42); 404}