common-test.c++ (19793B)
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #include "common.h" 23 #include "test.h" 24 #include <inttypes.h> 25 #include <kj/compat/gtest.h> 26 27 namespace kj { 28 namespace { 29 30 KJ_TEST("kj::size() on native arrays") { 31 int arr[] = {12, 34, 56, 78}; 32 33 size_t expected = 0; 34 for (size_t i: indices(arr)) { 35 KJ_EXPECT(i == expected++); 36 } 37 KJ_EXPECT(expected == 4u); 38 } 39 40 struct ImplicitToInt { 41 int i; 42 43 operator int() const { 44 return i; 45 } 46 }; 47 48 struct Immovable { 49 Immovable() = default; 50 KJ_DISALLOW_COPY(Immovable); 51 }; 52 53 struct CopyOrMove { 54 // Type that detects the difference between copy and move. 55 CopyOrMove(int i): i(i) {} 56 CopyOrMove(CopyOrMove&& other): i(other.i) { other.i = -1; } 57 CopyOrMove(const CopyOrMove&) = default; 58 59 int i; 60 }; 61 62 TEST(Common, Maybe) { 63 { 64 Maybe<int> m = 123; 65 EXPECT_FALSE(m == nullptr); 66 EXPECT_TRUE(m != nullptr); 67 KJ_IF_MAYBE(v, m) { 68 EXPECT_EQ(123, *v); 69 } else { 70 ADD_FAILURE(); 71 } 72 KJ_IF_MAYBE(v, mv(m)) { 73 EXPECT_EQ(123, *v); 74 } else { 75 ADD_FAILURE(); 76 } 77 EXPECT_EQ(123, m.orDefault(456)); 78 bool ranLazy = false; 79 EXPECT_EQ(123, m.orDefault([&] { 80 ranLazy = true; 81 return 456; 82 })); 83 EXPECT_FALSE(ranLazy); 84 85 KJ_IF_MAYBE(v, m) { 86 int notUsedForRef = 5; 87 const int& ref = m.orDefault([&]() -> int& { return notUsedForRef; }); 88 89 EXPECT_EQ(ref, *v); 90 EXPECT_EQ(&ref, v); 91 92 const int& ref2 = m.orDefault([notUsed = 5]() -> int { return notUsed; }); 93 EXPECT_NE(&ref, &ref2); 94 EXPECT_EQ(ref2, 123); 95 } else { 96 ADD_FAILURE(); 97 } 98 } 99 100 { 101 Maybe<int> empty; 102 int defaultValue = 5; 103 auto& ref1 = empty.orDefault([&defaultValue]() -> int& { 104 return defaultValue; 105 }); 106 EXPECT_EQ(&ref1, &defaultValue); 107 108 auto ref2 = empty.orDefault([&]() -> int { return defaultValue; }); 109 EXPECT_NE(&ref2, &defaultValue); 110 } 111 112 { 113 Maybe<int> m = 0; 114 EXPECT_FALSE(m == nullptr); 115 EXPECT_TRUE(m != nullptr); 116 KJ_IF_MAYBE(v, m) { 117 EXPECT_EQ(0, *v); 118 } else { 119 ADD_FAILURE(); 120 } 121 KJ_IF_MAYBE(v, mv(m)) { 122 EXPECT_EQ(0, *v); 123 } else { 124 ADD_FAILURE(); 125 } 126 EXPECT_EQ(0, m.orDefault(456)); 127 bool ranLazy = false; 128 EXPECT_EQ(0, m.orDefault([&] { 129 ranLazy = true; 130 return 456; 131 })); 132 EXPECT_FALSE(ranLazy); 133 } 134 135 { 136 Maybe<int> m = nullptr; 137 EXPECT_TRUE(m == nullptr); 138 EXPECT_FALSE(m != nullptr); 139 KJ_IF_MAYBE(v, m) { 140 ADD_FAILURE(); 141 EXPECT_EQ(0, *v); // avoid unused warning 142 } 143 KJ_IF_MAYBE(v, mv(m)) { 144 ADD_FAILURE(); 145 EXPECT_EQ(0, *v); // avoid unused warning 146 } 147 EXPECT_EQ(456, m.orDefault(456)); 148 bool ranLazy = false; 149 EXPECT_EQ(456, m.orDefault([&] { 150 ranLazy = true; 151 return 456; 152 })); 153 EXPECT_TRUE(ranLazy); 154 } 155 156 int i = 234; 157 { 158 Maybe<int&> m = i; 159 EXPECT_FALSE(m == nullptr); 160 EXPECT_TRUE(m != nullptr); 161 KJ_IF_MAYBE(v, m) { 162 EXPECT_EQ(&i, v); 163 } else { 164 ADD_FAILURE(); 165 } 166 KJ_IF_MAYBE(v, mv(m)) { 167 EXPECT_EQ(&i, v); 168 } else { 169 ADD_FAILURE(); 170 } 171 EXPECT_EQ(234, m.orDefault(456)); 172 } 173 174 { 175 Maybe<int&> m = nullptr; 176 EXPECT_TRUE(m == nullptr); 177 EXPECT_FALSE(m != nullptr); 178 KJ_IF_MAYBE(v, m) { 179 ADD_FAILURE(); 180 EXPECT_EQ(0, *v); // avoid unused warning 181 } 182 KJ_IF_MAYBE(v, mv(m)) { 183 ADD_FAILURE(); 184 EXPECT_EQ(0, *v); // avoid unused warning 185 } 186 EXPECT_EQ(456, m.orDefault(456)); 187 } 188 189 { 190 Maybe<int&> m = &i; 191 EXPECT_FALSE(m == nullptr); 192 EXPECT_TRUE(m != nullptr); 193 KJ_IF_MAYBE(v, m) { 194 EXPECT_EQ(&i, v); 195 } else { 196 ADD_FAILURE(); 197 } 198 KJ_IF_MAYBE(v, mv(m)) { 199 EXPECT_EQ(&i, v); 200 } else { 201 ADD_FAILURE(); 202 } 203 EXPECT_EQ(234, m.orDefault(456)); 204 } 205 206 { 207 const Maybe<int&> m2 = &i; 208 Maybe<const int&> m = m2; 209 EXPECT_FALSE(m == nullptr); 210 EXPECT_TRUE(m != nullptr); 211 KJ_IF_MAYBE(v, m) { 212 EXPECT_EQ(&i, v); 213 } else { 214 ADD_FAILURE(); 215 } 216 KJ_IF_MAYBE(v, mv(m)) { 217 EXPECT_EQ(&i, v); 218 } else { 219 ADD_FAILURE(); 220 } 221 EXPECT_EQ(234, m.orDefault(456)); 222 } 223 224 { 225 Maybe<int&> m = implicitCast<int*>(nullptr); 226 EXPECT_TRUE(m == nullptr); 227 EXPECT_FALSE(m != nullptr); 228 KJ_IF_MAYBE(v, m) { 229 ADD_FAILURE(); 230 EXPECT_EQ(0, *v); // avoid unused warning 231 } 232 KJ_IF_MAYBE(v, mv(m)) { 233 ADD_FAILURE(); 234 EXPECT_EQ(0, *v); // avoid unused warning 235 } 236 EXPECT_EQ(456, m.orDefault(456)); 237 } 238 239 { 240 Maybe<int> mi = i; 241 Maybe<int&> m = mi; 242 EXPECT_FALSE(m == nullptr); 243 EXPECT_TRUE(m != nullptr); 244 KJ_IF_MAYBE(v, m) { 245 EXPECT_EQ(&KJ_ASSERT_NONNULL(mi), v); 246 } else { 247 ADD_FAILURE(); 248 } 249 KJ_IF_MAYBE(v, mv(m)) { 250 EXPECT_EQ(&KJ_ASSERT_NONNULL(mi), v); 251 } else { 252 ADD_FAILURE(); 253 } 254 EXPECT_EQ(234, m.orDefault(456)); 255 } 256 257 { 258 Maybe<int> mi = nullptr; 259 Maybe<int&> m = mi; 260 EXPECT_TRUE(m == nullptr); 261 KJ_IF_MAYBE(v, m) { 262 KJ_FAIL_EXPECT(*v); 263 } 264 } 265 266 { 267 const Maybe<int> mi = i; 268 Maybe<const int&> m = mi; 269 EXPECT_FALSE(m == nullptr); 270 EXPECT_TRUE(m != nullptr); 271 KJ_IF_MAYBE(v, m) { 272 EXPECT_EQ(&KJ_ASSERT_NONNULL(mi), v); 273 } else { 274 ADD_FAILURE(); 275 } 276 KJ_IF_MAYBE(v, mv(m)) { 277 EXPECT_EQ(&KJ_ASSERT_NONNULL(mi), v); 278 } else { 279 ADD_FAILURE(); 280 } 281 EXPECT_EQ(234, m.orDefault(456)); 282 } 283 284 { 285 const Maybe<int> mi = nullptr; 286 Maybe<const int&> m = mi; 287 EXPECT_TRUE(m == nullptr); 288 KJ_IF_MAYBE(v, m) { 289 KJ_FAIL_EXPECT(*v); 290 } 291 } 292 293 { 294 // Verify orDefault() works with move-only types. 295 Maybe<kj::String> m = nullptr; 296 kj::String s = kj::mv(m).orDefault(kj::str("foo")); 297 EXPECT_EQ("foo", s); 298 EXPECT_EQ("foo", kj::mv(m).orDefault([] { 299 return kj::str("foo"); 300 })); 301 } 302 303 { 304 // Test a case where an implicit conversion didn't used to happen correctly. 305 Maybe<ImplicitToInt> m(ImplicitToInt { 123 }); 306 Maybe<uint> m2(m); 307 Maybe<uint> m3(kj::mv(m)); 308 KJ_IF_MAYBE(v, m2) { 309 EXPECT_EQ(123, *v); 310 } else { 311 ADD_FAILURE(); 312 } 313 KJ_IF_MAYBE(v, m3) { 314 EXPECT_EQ(123, *v); 315 } else { 316 ADD_FAILURE(); 317 } 318 } 319 320 { 321 // Test usage of immovable types. 322 Maybe<Immovable> m; 323 KJ_EXPECT(m == nullptr); 324 m.emplace(); 325 KJ_EXPECT(m != nullptr); 326 m = nullptr; 327 KJ_EXPECT(m == nullptr); 328 } 329 330 { 331 // Test that initializing Maybe<T> from Maybe<T&>&& does a copy, not a move. 332 CopyOrMove x(123); 333 Maybe<CopyOrMove&> m(x); 334 Maybe<CopyOrMove> m2 = kj::mv(m); 335 KJ_EXPECT(m == nullptr); // m is moved out of and cleared 336 KJ_EXPECT(x.i == 123); // but what m *referenced* was not moved out of 337 KJ_EXPECT(KJ_ASSERT_NONNULL(m2).i == 123); // m2 is a copy of what m referenced 338 } 339 340 { 341 // Test that a moved-out-of Maybe<T> is left empty after move constructor. 342 Maybe<int> m = 123; 343 KJ_EXPECT(m != nullptr); 344 345 Maybe<int> n(kj::mv(m)); 346 KJ_EXPECT(m == nullptr); 347 KJ_EXPECT(n != nullptr); 348 } 349 350 { 351 // Test that a moved-out-of Maybe<T> is left empty after move constructor. 352 Maybe<int> m = 123; 353 KJ_EXPECT(m != nullptr); 354 355 Maybe<int> n = kj::mv(m); 356 KJ_EXPECT(m == nullptr); 357 KJ_EXPECT(n != nullptr); 358 } 359 360 { 361 // Test that a moved-out-of Maybe<T&> is left empty when moved to a Maybe<T>. 362 int x = 123; 363 Maybe<int&> m = x; 364 KJ_EXPECT(m != nullptr); 365 366 Maybe<int> n(kj::mv(m)); 367 KJ_EXPECT(m == nullptr); 368 KJ_EXPECT(n != nullptr); 369 } 370 371 { 372 // Test that a moved-out-of Maybe<T&> is left empty when moved to another Maybe<T&>. 373 int x = 123; 374 Maybe<int&> m = x; 375 KJ_EXPECT(m != nullptr); 376 377 Maybe<int&> n(kj::mv(m)); 378 KJ_EXPECT(m == nullptr); 379 KJ_EXPECT(n != nullptr); 380 } 381 382 { 383 Maybe<int> m1 = 123; 384 Maybe<int> m2 = 123; 385 Maybe<int> m3 = 456; 386 Maybe<int> m4 = nullptr; 387 Maybe<int> m5 = nullptr; 388 389 KJ_EXPECT(m1 == m2); 390 KJ_EXPECT(m1 != m3); 391 KJ_EXPECT(m1 != m4); 392 KJ_EXPECT(m4 == m5); 393 KJ_EXPECT(m4 != m1); 394 } 395 } 396 397 TEST(Common, MaybeConstness) { 398 int i; 399 400 Maybe<int&> mi = i; 401 const Maybe<int&> cmi = mi; 402 // const Maybe<int&> cmi2 = cmi; // shouldn't compile! Transitive const violation. 403 404 KJ_IF_MAYBE(i2, cmi) { 405 EXPECT_EQ(&i, i2); 406 } else { 407 ADD_FAILURE(); 408 } 409 410 Maybe<const int&> mci = mi; 411 const Maybe<const int&> cmci = mci; 412 const Maybe<const int&> cmci2 = cmci; 413 414 KJ_IF_MAYBE(i2, cmci2) { 415 EXPECT_EQ(&i, i2); 416 } else { 417 ADD_FAILURE(); 418 } 419 } 420 421 #if __GNUC__ 422 TEST(Common, MaybeUnwrapOrReturn) { 423 { 424 auto func = [](Maybe<int> i) -> int { 425 int& j = KJ_UNWRAP_OR_RETURN(i, -1); 426 KJ_EXPECT(&j == &KJ_ASSERT_NONNULL(i)); 427 return j + 2; 428 }; 429 430 KJ_EXPECT(func(123) == 125); 431 KJ_EXPECT(func(nullptr) == -1); 432 } 433 434 { 435 auto func = [&](Maybe<String> maybe) -> int { 436 String str = KJ_UNWRAP_OR_RETURN(kj::mv(maybe), -1); 437 return str.parseAs<int>(); 438 }; 439 440 KJ_EXPECT(func(kj::str("123")) == 123); 441 KJ_EXPECT(func(nullptr) == -1); 442 } 443 444 // Test void return. 445 { 446 int val = 0; 447 auto func = [&](Maybe<int> i) { 448 val = KJ_UNWRAP_OR_RETURN(i); 449 }; 450 451 func(123); 452 KJ_EXPECT(val == 123); 453 val = 321; 454 func(nullptr); 455 KJ_EXPECT(val == 321); 456 } 457 458 // Test KJ_UNWRAP_OR 459 { 460 bool wasNull = false; 461 auto func = [&](Maybe<int> i) -> int { 462 int& j = KJ_UNWRAP_OR(i, { 463 wasNull = true; 464 return -1; 465 }); 466 KJ_EXPECT(&j == &KJ_ASSERT_NONNULL(i)); 467 return j + 2; 468 }; 469 470 KJ_EXPECT(func(123) == 125); 471 KJ_EXPECT(!wasNull); 472 KJ_EXPECT(func(nullptr) == -1); 473 KJ_EXPECT(wasNull); 474 } 475 476 { 477 bool wasNull = false; 478 auto func = [&](Maybe<String> maybe) -> int { 479 String str = KJ_UNWRAP_OR(kj::mv(maybe), { 480 wasNull = true; 481 return -1; 482 }); 483 return str.parseAs<int>(); 484 }; 485 486 KJ_EXPECT(func(kj::str("123")) == 123); 487 KJ_EXPECT(!wasNull); 488 KJ_EXPECT(func(nullptr) == -1); 489 KJ_EXPECT(wasNull); 490 } 491 492 // Test void return. 493 { 494 int val = 0; 495 auto func = [&](Maybe<int> i) { 496 val = KJ_UNWRAP_OR(i, { 497 return; 498 }); 499 }; 500 501 func(123); 502 KJ_EXPECT(val == 123); 503 val = 321; 504 func(nullptr); 505 KJ_EXPECT(val == 321); 506 } 507 508 } 509 #endif 510 511 class Foo { 512 public: 513 KJ_DISALLOW_COPY(Foo); 514 virtual ~Foo() {} 515 protected: 516 Foo() = default; 517 }; 518 519 class Bar: public Foo { 520 public: 521 Bar() = default; 522 KJ_DISALLOW_COPY(Bar); 523 virtual ~Bar() {} 524 }; 525 526 class Baz: public Foo { 527 public: 528 Baz() = delete; 529 KJ_DISALLOW_COPY(Baz); 530 virtual ~Baz() {} 531 }; 532 533 TEST(Common, Downcast) { 534 Bar bar; 535 Foo& foo = bar; 536 537 EXPECT_EQ(&bar, &downcast<Bar>(foo)); 538 #if defined(KJ_DEBUG) && !KJ_NO_RTTI 539 KJ_EXPECT_THROW_MESSAGE("Value cannot be downcast", downcast<Baz>(foo)); 540 #endif 541 542 #if KJ_NO_RTTI 543 EXPECT_TRUE(dynamicDowncastIfAvailable<Bar>(foo) == nullptr); 544 EXPECT_TRUE(dynamicDowncastIfAvailable<Baz>(foo) == nullptr); 545 #else 546 KJ_IF_MAYBE(m, dynamicDowncastIfAvailable<Bar>(foo)) { 547 EXPECT_EQ(&bar, m); 548 } else { 549 KJ_FAIL_ASSERT("Dynamic downcast returned null."); 550 } 551 EXPECT_TRUE(dynamicDowncastIfAvailable<Baz>(foo) == nullptr); 552 #endif 553 } 554 555 TEST(Common, MinMax) { 556 EXPECT_EQ(5, kj::min(5, 9)); 557 EXPECT_EQ(5, kj::min(9, 5)); 558 EXPECT_EQ(5, kj::min(5, 5)); 559 EXPECT_EQ(9, kj::max(5, 9)); 560 EXPECT_EQ(9, kj::max(9, 5)); 561 EXPECT_EQ(5, kj::min(5, 5)); 562 563 // Hey look, we can handle the types mismatching. Eat your heart out, std. 564 EXPECT_EQ(5, kj::min(5, 'a')); 565 EXPECT_EQ(5, kj::min('a', 5)); 566 EXPECT_EQ('a', kj::max(5, 'a')); 567 EXPECT_EQ('a', kj::max('a', 5)); 568 569 EXPECT_EQ('a', kj::min(1234567890123456789ll, 'a')); 570 EXPECT_EQ('a', kj::min('a', 1234567890123456789ll)); 571 EXPECT_EQ(1234567890123456789ll, kj::max(1234567890123456789ll, 'a')); 572 EXPECT_EQ(1234567890123456789ll, kj::max('a', 1234567890123456789ll)); 573 } 574 575 TEST(Common, MinMaxValue) { 576 EXPECT_EQ(0x7f, int8_t(maxValue)); 577 EXPECT_EQ(0xffu, uint8_t(maxValue)); 578 EXPECT_EQ(0x7fff, int16_t(maxValue)); 579 EXPECT_EQ(0xffffu, uint16_t(maxValue)); 580 EXPECT_EQ(0x7fffffff, int32_t(maxValue)); 581 EXPECT_EQ(0xffffffffu, uint32_t(maxValue)); 582 EXPECT_EQ(0x7fffffffffffffffll, int64_t(maxValue)); 583 EXPECT_EQ(0xffffffffffffffffull, uint64_t(maxValue)); 584 585 EXPECT_EQ(-0x80, int8_t(minValue)); 586 EXPECT_EQ(0, uint8_t(minValue)); 587 EXPECT_EQ(-0x8000, int16_t(minValue)); 588 EXPECT_EQ(0, uint16_t(minValue)); 589 EXPECT_EQ(-0x80000000, int32_t(minValue)); 590 EXPECT_EQ(0, uint32_t(minValue)); 591 EXPECT_EQ(-0x8000000000000000ll, int64_t(minValue)); 592 EXPECT_EQ(0, uint64_t(minValue)); 593 594 double f = inf(); 595 EXPECT_TRUE(f * 2 == f); 596 597 f = nan(); 598 EXPECT_FALSE(f == f); 599 600 // `char`'s signedness is platform-specific. 601 EXPECT_LE(char(minValue), '\0'); 602 EXPECT_GE(char(maxValue), '\x7f'); 603 } 604 605 TEST(Common, Defer) { 606 uint i = 0; 607 uint j = 1; 608 bool k = false; 609 610 { 611 KJ_DEFER(++i); 612 KJ_DEFER(j += 3; k = true); 613 EXPECT_EQ(0u, i); 614 EXPECT_EQ(1u, j); 615 EXPECT_FALSE(k); 616 } 617 618 EXPECT_EQ(1u, i); 619 EXPECT_EQ(4u, j); 620 EXPECT_TRUE(k); 621 } 622 623 TEST(Common, CanConvert) { 624 static_assert(canConvert<long, int>(), "failure"); 625 static_assert(!canConvert<long, void*>(), "failure"); 626 627 struct Super {}; 628 struct Sub: public Super {}; 629 630 static_assert(canConvert<Sub, Super>(), "failure"); 631 static_assert(!canConvert<Super, Sub>(), "failure"); 632 static_assert(canConvert<Sub*, Super*>(), "failure"); 633 static_assert(!canConvert<Super*, Sub*>(), "failure"); 634 635 static_assert(canConvert<void*, const void*>(), "failure"); 636 static_assert(!canConvert<const void*, void*>(), "failure"); 637 } 638 639 TEST(Common, ArrayAsBytes) { 640 uint32_t raw[] = { 0x12345678u, 0x9abcdef0u }; 641 642 ArrayPtr<uint32_t> array = raw; 643 ASSERT_EQ(2, array.size()); 644 EXPECT_EQ(0x12345678u, array[0]); 645 EXPECT_EQ(0x9abcdef0u, array[1]); 646 647 { 648 ArrayPtr<byte> bytes = array.asBytes(); 649 ASSERT_EQ(8, bytes.size()); 650 651 if (bytes[0] == '\x12') { 652 // big-endian 653 EXPECT_EQ(0x12u, bytes[0]); 654 EXPECT_EQ(0x34u, bytes[1]); 655 EXPECT_EQ(0x56u, bytes[2]); 656 EXPECT_EQ(0x78u, bytes[3]); 657 EXPECT_EQ(0x9au, bytes[4]); 658 EXPECT_EQ(0xbcu, bytes[5]); 659 EXPECT_EQ(0xdeu, bytes[6]); 660 EXPECT_EQ(0xf0u, bytes[7]); 661 } else { 662 // little-endian 663 EXPECT_EQ(0x12u, bytes[3]); 664 EXPECT_EQ(0x34u, bytes[2]); 665 EXPECT_EQ(0x56u, bytes[1]); 666 EXPECT_EQ(0x78u, bytes[0]); 667 EXPECT_EQ(0x9au, bytes[7]); 668 EXPECT_EQ(0xbcu, bytes[6]); 669 EXPECT_EQ(0xdeu, bytes[5]); 670 EXPECT_EQ(0xf0u, bytes[4]); 671 } 672 } 673 674 { 675 ArrayPtr<char> chars = array.asChars(); 676 ASSERT_EQ(8, chars.size()); 677 678 if (chars[0] == '\x12') { 679 // big-endian 680 EXPECT_EQ('\x12', chars[0]); 681 EXPECT_EQ('\x34', chars[1]); 682 EXPECT_EQ('\x56', chars[2]); 683 EXPECT_EQ('\x78', chars[3]); 684 EXPECT_EQ('\x9a', chars[4]); 685 EXPECT_EQ('\xbc', chars[5]); 686 EXPECT_EQ('\xde', chars[6]); 687 EXPECT_EQ('\xf0', chars[7]); 688 } else { 689 // little-endian 690 EXPECT_EQ('\x12', chars[3]); 691 EXPECT_EQ('\x34', chars[2]); 692 EXPECT_EQ('\x56', chars[1]); 693 EXPECT_EQ('\x78', chars[0]); 694 EXPECT_EQ('\x9a', chars[7]); 695 EXPECT_EQ('\xbc', chars[6]); 696 EXPECT_EQ('\xde', chars[5]); 697 EXPECT_EQ('\xf0', chars[4]); 698 } 699 } 700 701 ArrayPtr<const uint32_t> constArray = array; 702 703 { 704 ArrayPtr<const byte> bytes = constArray.asBytes(); 705 ASSERT_EQ(8, bytes.size()); 706 707 if (bytes[0] == '\x12') { 708 // big-endian 709 EXPECT_EQ(0x12u, bytes[0]); 710 EXPECT_EQ(0x34u, bytes[1]); 711 EXPECT_EQ(0x56u, bytes[2]); 712 EXPECT_EQ(0x78u, bytes[3]); 713 EXPECT_EQ(0x9au, bytes[4]); 714 EXPECT_EQ(0xbcu, bytes[5]); 715 EXPECT_EQ(0xdeu, bytes[6]); 716 EXPECT_EQ(0xf0u, bytes[7]); 717 } else { 718 // little-endian 719 EXPECT_EQ(0x12u, bytes[3]); 720 EXPECT_EQ(0x34u, bytes[2]); 721 EXPECT_EQ(0x56u, bytes[1]); 722 EXPECT_EQ(0x78u, bytes[0]); 723 EXPECT_EQ(0x9au, bytes[7]); 724 EXPECT_EQ(0xbcu, bytes[6]); 725 EXPECT_EQ(0xdeu, bytes[5]); 726 EXPECT_EQ(0xf0u, bytes[4]); 727 } 728 } 729 730 { 731 ArrayPtr<const char> chars = constArray.asChars(); 732 ASSERT_EQ(8, chars.size()); 733 734 if (chars[0] == '\x12') { 735 // big-endian 736 EXPECT_EQ('\x12', chars[0]); 737 EXPECT_EQ('\x34', chars[1]); 738 EXPECT_EQ('\x56', chars[2]); 739 EXPECT_EQ('\x78', chars[3]); 740 EXPECT_EQ('\x9a', chars[4]); 741 EXPECT_EQ('\xbc', chars[5]); 742 EXPECT_EQ('\xde', chars[6]); 743 EXPECT_EQ('\xf0', chars[7]); 744 } else { 745 // little-endian 746 EXPECT_EQ('\x12', chars[3]); 747 EXPECT_EQ('\x34', chars[2]); 748 EXPECT_EQ('\x56', chars[1]); 749 EXPECT_EQ('\x78', chars[0]); 750 EXPECT_EQ('\x9a', chars[7]); 751 EXPECT_EQ('\xbc', chars[6]); 752 EXPECT_EQ('\xde', chars[5]); 753 EXPECT_EQ('\xf0', chars[4]); 754 } 755 } 756 } 757 758 KJ_TEST("ArrayPtr operator ==") { 759 KJ_EXPECT(ArrayPtr<const int>({123, 456}) == ArrayPtr<const int>({123, 456})); 760 KJ_EXPECT(!(ArrayPtr<const int>({123, 456}) != ArrayPtr<const int>({123, 456}))); 761 KJ_EXPECT(ArrayPtr<const int>({123, 456}) != ArrayPtr<const int>({123, 321})); 762 KJ_EXPECT(ArrayPtr<const int>({123, 456}) != ArrayPtr<const int>({123})); 763 764 KJ_EXPECT(ArrayPtr<const int>({123, 456}) == ArrayPtr<const short>({123, 456})); 765 KJ_EXPECT(!(ArrayPtr<const int>({123, 456}) != ArrayPtr<const short>({123, 456}))); 766 KJ_EXPECT(ArrayPtr<const int>({123, 456}) != ArrayPtr<const short>({123, 321})); 767 KJ_EXPECT(ArrayPtr<const int>({123, 456}) != ArrayPtr<const short>({123})); 768 769 KJ_EXPECT((ArrayPtr<const StringPtr>({"foo", "bar"}) == 770 ArrayPtr<const char* const>({"foo", "bar"}))); 771 KJ_EXPECT(!(ArrayPtr<const StringPtr>({"foo", "bar"}) != 772 ArrayPtr<const char* const>({"foo", "bar"}))); 773 KJ_EXPECT((ArrayPtr<const StringPtr>({"foo", "bar"}) != 774 ArrayPtr<const char* const>({"foo", "baz"}))); 775 KJ_EXPECT((ArrayPtr<const StringPtr>({"foo", "bar"}) != 776 ArrayPtr<const char* const>({"foo"}))); 777 } 778 779 KJ_TEST("kj::range()") { 780 uint expected = 5; 781 for (uint i: range(5, 10)) { 782 KJ_EXPECT(i == expected++); 783 } 784 KJ_EXPECT(expected == 10); 785 786 expected = 0; 787 for (uint i: range(0, 8)) { 788 KJ_EXPECT(i == expected++); 789 } 790 KJ_EXPECT(expected == 8); 791 } 792 793 KJ_TEST("kj::defer()") { 794 bool executed; 795 796 // rvalue reference 797 { 798 executed = false; 799 auto deferred = kj::defer([&executed]() { 800 executed = true; 801 }); 802 KJ_EXPECT(!executed); 803 } 804 805 KJ_EXPECT(executed); 806 807 // lvalue reference 808 auto executor = [&executed]() { 809 executed = true; 810 }; 811 812 { 813 executed = false; 814 auto deferred = kj::defer(executor); 815 KJ_EXPECT(!executed); 816 } 817 818 KJ_EXPECT(executed); 819 } 820 821 } // namespace 822 } // namespace kj