capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

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