Ejemplo n.º 1
0
TEST(WTF_Expected, UnexpectedType)
{
    {
        auto u = UnexpectedType<int>(42);
        EXPECT_EQ(u.value(), 42);
        constexpr auto c = makeUnexpected(42);
        EXPECT_EQ(c.value(), 42);
        EXPECT_EQ(u, c);
        EXPECT_FALSE(u != c);
        EXPECT_FALSE(u < c);
        EXPECT_FALSE(u > c);
        EXPECT_LE(u, c);
        EXPECT_GE(u, c);
    }
    {
        auto c = makeUnexpected(oops);
        EXPECT_EQ(c.value(), oops);
    }
    {
        auto s = makeUnexpected(std::string(oops));
        EXPECT_EQ(s.value(), oops);
    }
    {
        constexpr auto s0 = makeUnexpected(oops);
        constexpr auto s1(s0);
        EXPECT_EQ(s0, s1);
    }
}
Ejemplo n.º 2
0
TEST(WTF_Expected, hash_void)
{
    typedef Expected<void, const char*> E;
    std::unordered_map<E, int> m;
    m.insert({ E(), 42 });
    m.insert({ E(makeUnexpected(oops)), 5 });
    m.insert({ E(makeUnexpected(foof)), 0xf00f });
    EXPECT_EQ(m[E()], 42);
    EXPECT_EQ(m[E(makeUnexpected(oops))], 5);
    EXPECT_EQ(m[E(makeUnexpected(foof))], 0xf00f);
}
Ejemplo n.º 3
0
TEST(WTF_Expected, hash)
{
    typedef Expected<int, const char*> E;
    std::unordered_map<E, int> m;
    m.insert({ E(42), 42 });
    m.insert({ E(makeUnexpected(oops)), 5 });
    m.insert({ E(1024), 1024 });
    m.insert({ E(makeUnexpected(foof)), 0xf00f });
    EXPECT_EQ(m[E(42)], 42);
    EXPECT_EQ(m[E(1024)], 1024);
    EXPECT_EQ(m[E(makeUnexpected(oops))], 5);
    EXPECT_EQ(m[E(makeUnexpected(foof))], 0xf00f);
}
Ejemplo n.º 4
0
Expected<IPAddress, IPAddressFormatError> IPAddress::tryFromBinary(
    ByteRange bytes) noexcept {
  // Check IPv6 first since it's our main protocol.
  if (bytes.size() == 16) {
    return IPAddressV6::tryFromBinary(bytes);
  } else if (bytes.size() == 4) {
    return IPAddressV4::tryFromBinary(bytes);
  } else {
    return makeUnexpected(IPAddressFormatError::UNSUPPORTED_ADDR_FAMILY);
  }
}
Ejemplo n.º 5
0
Expected<IPAddress, IPAddressFormatError> IPAddress::tryFromString(
    StringPiece str) noexcept {
  // need to check for V4 address second, since IPv4-mapped IPv6 addresses may
  // contain a period
  if (str.find(':') != string::npos) {
    return IPAddressV6::tryFromString(str);
  } else if (str.find('.') != string::npos) {
    return IPAddressV4::tryFromString(str);
  } else {
    return makeUnexpected(IPAddressFormatError::UNSUPPORTED_ADDR_FAMILY);
  }
}
Ejemplo n.º 6
0
TEST(WTF_Expected, destructors)
{
    typedef Expected<NonTrivialDtor, const char*> NT;
    typedef Expected<const char*, NonTrivialDtor> TN;
    typedef Expected<NonTrivialDtor, NonTrivialDtor> NN;
    typedef Expected<void, NonTrivialDtor> VN;
    EXPECT_EQ(NonTrivialDtor::count, 0);
    { NT nt; }
    EXPECT_EQ(NonTrivialDtor::count, 1);
    { NT nt = makeUnexpected(oops); }
    EXPECT_EQ(NonTrivialDtor::count, 1);
    { TN tn; }
    EXPECT_EQ(NonTrivialDtor::count, 1);
    { TN tn = makeUnexpected(NonTrivialDtor()); }
    EXPECT_EQ(NonTrivialDtor::count, 4);
    { NN nn; }
    EXPECT_EQ(NonTrivialDtor::count, 5);
    { NN nn = makeUnexpected(NonTrivialDtor()); }
    EXPECT_EQ(NonTrivialDtor::count, 8);
    { VN vn; }
    EXPECT_EQ(NonTrivialDtor::count, 8);
    { VN vn = makeUnexpected(NonTrivialDtor()); }
    EXPECT_EQ(NonTrivialDtor::count, 11);
}
Ejemplo n.º 7
0
// static
Expected<json_patch, json_patch::parse_error> json_patch::try_parse(
    dynamic const& obj) noexcept {
  using err_code = parse_error_code;

  json_patch patch;
  if (!obj.isArray()) {
    return makeUnexpected(parse_error{err_code::invalid_shape, &obj});
  }
  for (auto const& elem : obj) {
    if (!elem.isObject()) {
      return makeUnexpected(parse_error{err_code::invalid_shape, &elem});
    }
    auto const* op_ptr = elem.get_ptr(kOpTag);
    if (!op_ptr) {
      return makeUnexpected(parse_error{err_code::missing_op, &elem});
    }
    if (!op_ptr->isString()) {
      return makeUnexpected(parse_error{err_code::malformed_op, &elem});
    }
    auto const op_str = op_ptr->asString();
    patch_operation op;

    // extract 'from' attribute
    {
      auto const* from_ptr = elem.get_ptr(kFromTag);
      if (from_ptr) {
        if (!from_ptr->isString()) {
          return makeUnexpected(parse_error{err_code::invalid_shape, &elem});
        }
        auto json_ptr = json_pointer::try_parse(from_ptr->asString());
        if (!json_ptr.hasValue()) {
          return makeUnexpected(
              parse_error{err_code::malformed_from_attr, &elem});
        }
        op.from = json_ptr.value();
      }
    }

    // extract 'path' attribute
    {
      auto const* path_ptr = elem.get_ptr(kPathTag);
      if (!path_ptr) {
        return makeUnexpected(parse_error{err_code::missing_path_attr, &elem});
      }
      if (!path_ptr->isString()) {
        return makeUnexpected(
            parse_error{err_code::malformed_path_attr, &elem});
      }
      auto const json_ptr = json_pointer::try_parse(path_ptr->asString());
      if (!json_ptr.hasValue()) {
        return makeUnexpected(
            parse_error{err_code::malformed_path_attr, &elem});
      }
      op.path = json_ptr.value();
    }

    // extract 'value' attribute
    {
      auto const* val_ptr = elem.get_ptr(kValueTag);
      if (val_ptr) {
        op.value = *val_ptr;
      }
    }

    // check mandatory attributes - different per operation
    // NOTE: per RFC, the surplus attributes (e.g. 'from' with 'add')
    // should be simply ignored

    using op_code = patch_operation_code;

    if (op_str == kOperationTest) {
      if (!op.value) {
        return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
      }
      op.op_code = op_code::test;
    } else if (op_str == kOperationRemove) {
      op.op_code = op_code::remove;
    } else if (op_str == kOperationAdd) {
      if (!op.value) {
        return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
      }
      op.op_code = op_code::add;
    } else if (op_str == kOperationReplace) {
      if (!op.value) {
        return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
      }
      op.op_code = op_code::replace;
    } else if (op_str == kOperationMove) {
      if (!op.from) {
        return makeUnexpected(parse_error{err_code::missing_from_attr, &elem});
      }
      // is from a proper prefix to path?
      if (op.from->is_prefix_of(op.path)) {
        return makeUnexpected(
            parse_error{err_code::overlapping_pointers, &elem});
      }
      op.op_code = op_code::move;
    } else if (op_str == kOperationCopy) {
      if (!op.from) {
        return makeUnexpected(parse_error{err_code::missing_from_attr, &elem});
      }
      op.op_code = op_code::copy;
    }

    if (op.op_code != op_code::invalid) {
      patch.ops_.emplace_back(std::move(op));
    } else {
      return makeUnexpected(parse_error{err_code::unknown_op, &elem});
    }
  }
  return patch;
}
Ejemplo n.º 8
0
// clang-format off
Expected<Unit, json_patch::patch_application_error>
// clang-format on
json_patch::apply(dynamic& obj) {
  using op_code = patch_operation_code;
  using error_code = patch_application_error_code;
  using error = patch_application_error;

  for (auto&& it : enumerate(ops_)) {
    auto const index = it.index;
    auto const& op = *it;
    auto resolved_path = obj.try_get_ptr(op.path);

    switch (op.op_code) {
      case op_code::test:
        if (!resolved_path.hasValue()) {
          return folly::makeUnexpected(
              error{error_code::path_not_found, index});
        }
        if (*resolved_path->value != *op.value) {
          return folly::makeUnexpected(error{error_code::test_failed, index});
        }
        break;
      case op_code::remove: {
        auto ret = do_remove(resolved_path);
        if (ret.hasError()) {
          return makeUnexpected(error{ret.error(), index});
        }
        break;
      }
      case op_code::add: {
        DCHECK(op.value.hasValue());
        auto ret = do_add(resolved_path, *op.value, op.path.tokens().back());
        if (ret.hasError()) {
          return makeUnexpected(error{ret.error(), index});
        }
        break;
      }
      case op_code::replace: {
        if (resolved_path.hasValue()) {
          *resolved_path->value = *op.value;
        } else {
          return folly::makeUnexpected(
              error{error_code::path_not_found, index});
        }
        break;
      }
      case op_code::move: {
        DCHECK(op.from.hasValue());
        auto resolved_from = obj.try_get_ptr(*op.from);
        if (!resolved_from.hasValue()) {
          return makeUnexpected(error{error_code::from_not_found, index});
        }
        {
          auto ret = do_add(
              resolved_path, *resolved_from->value, op.path.tokens().back());
          if (ret.hasError()) {
            return makeUnexpected(error{ret.error(), index});
          }
        }
        {
          auto ret = do_remove(resolved_from);
          if (ret.hasError()) {
            return makeUnexpected(error{ret.error(), index});
          }
        }
        break;
      }
      case op_code::copy: {
        DCHECK(op.from.hasValue());
        auto const resolved_from = obj.try_get_ptr(*op.from);
        if (!resolved_from.hasValue()) {
          return makeUnexpected(error{error_code::from_not_found, index});
        }
        {
          DCHECK(!op.path.tokens().empty());
          auto ret = do_add(
              resolved_path, *resolved_from->value, op.path.tokens().back());
          if (ret.hasError()) {
            return makeUnexpected(error{ret.error(), index});
          }
        }
        break;
      }
      case op_code::invalid: {
        DCHECK(false);
        return makeUnexpected(error{error_code::other, index});
      }
    }
  }
  return unit;
}
Ejemplo n.º 9
0
TEST(WTF_Expected, comparison)
{
    typedef Expected<int, const char*> Ex;
    typedef Expected<int, int> Er;

    // Two Expected, no errors.
    EXPECT_EQ(Ex(42), Ex(42));
    EXPECT_NE(Ex(42), Ex(1024));
    EXPECT_LT(Ex(42), Ex(1024));
    EXPECT_GT(Ex(1024), Ex(42));
    EXPECT_LE(Ex(42), Ex(42));
    EXPECT_GE(Ex(42), Ex(42));
    EXPECT_LE(Ex(42), Ex(1024));
    EXPECT_GE(Ex(1024), Ex(42));

    EXPECT_FALSE(Ex(42) == Ex(1024));
    EXPECT_FALSE(Ex(42) != Ex(42));
    EXPECT_FALSE(Ex(1024) < Ex(42));
    EXPECT_FALSE(Ex(42) > Ex(1024));
    EXPECT_FALSE(Ex(1024) < Ex(42));
    EXPECT_FALSE(Ex(42) >= Ex(1024));

    // Two Expected, half errors.
    EXPECT_FALSE(Ex(42) == Ex(makeUnexpected(oops)));
    EXPECT_NE(Ex(42), Ex(makeUnexpected(oops)));
    EXPECT_LT(Ex(42), Ex(makeUnexpected(oops)));
    EXPECT_FALSE(Ex(42) > Ex(makeUnexpected(oops)));
    EXPECT_LE(Ex(42), Ex(makeUnexpected(oops)));
    EXPECT_FALSE(Ex(42) >= Ex(makeUnexpected(oops)));

    EXPECT_FALSE(Ex(makeUnexpected(oops)) == Ex(42));
    EXPECT_NE(Ex(makeUnexpected(oops)), Ex(42));
    EXPECT_FALSE(Ex(makeUnexpected(oops)) < Ex(42));
    EXPECT_GT(Ex(makeUnexpected(oops)), Ex(42));
    EXPECT_FALSE(Ex(makeUnexpected(oops)) <= Ex(42));
    EXPECT_GE(Ex(makeUnexpected(oops)), Ex(42));

    // Two Expected, all errors.
    EXPECT_EQ(Er(42), Er(42));
    EXPECT_NE(Er(42), Er(1024));
    EXPECT_LT(Er(42), Er(1024));
    EXPECT_GT(Er(1024), Er(42));
    EXPECT_LE(Er(42), Er(42));
    EXPECT_GE(Er(42), Er(42));
    EXPECT_LE(Er(42), Er(1024));
    EXPECT_GE(Er(1024), Er(42));

    EXPECT_FALSE(Er(42) == Er(1024));
    EXPECT_FALSE(Er(42) != Er(42));
    EXPECT_FALSE(Er(1024) < Er(42));
    EXPECT_FALSE(Er(42) > Er(1024));
    EXPECT_FALSE(Er(1024) <= Er(42));
    EXPECT_FALSE(Er(42) >= Er(1024));

    // One Expected, one value.
    EXPECT_EQ(Ex(42), 42);
    EXPECT_NE(Ex(42), 0);
    EXPECT_LT(Ex(42), 1024);
    EXPECT_GT(Ex(1024), 42);
    EXPECT_LE(Ex(42), 42);
    EXPECT_GE(Ex(42), 42);
    EXPECT_LE(Ex(42), 1024);
    EXPECT_GE(Ex(1024), 42);

    EXPECT_FALSE(Ex(42) == 0);
    EXPECT_FALSE(Ex(42) != 42);
    EXPECT_FALSE(Ex(1024) < 42);
    EXPECT_FALSE(Ex(42) > 1024);
    EXPECT_FALSE(Ex(1024) < 42);
    EXPECT_FALSE(Ex(42) >= 1024);

    EXPECT_EQ(42, Ex(42));
    EXPECT_NE(42, Ex(1024));
    EXPECT_LT(42, Ex(1024));
    EXPECT_GT(1024, Ex(42));
    EXPECT_LE(42, Ex(42));
    EXPECT_GE(42, Ex(42));
    EXPECT_LE(42, Ex(1024));
    EXPECT_GE(1024, Ex(42));

    EXPECT_FALSE(42 == Ex(1024));
    EXPECT_FALSE(42 != Ex(42));
    EXPECT_FALSE(1024 < Ex(42));
    EXPECT_FALSE(42 > Ex(1024));
    EXPECT_FALSE(1024 <= Ex(42));
    EXPECT_FALSE(42 >= Ex(1024));

    // One Expected, one unexpected.
    EXPECT_FALSE(Ex(42) == makeUnexpected(oops));
    EXPECT_NE(Ex(42), makeUnexpected(oops));
    EXPECT_LT(Ex(42), makeUnexpected(oops));
    EXPECT_FALSE(Ex(42) > makeUnexpected(oops));
    EXPECT_LE(Ex(42), makeUnexpected(oops));
    EXPECT_FALSE(Ex(42) >= makeUnexpected(oops));

    EXPECT_FALSE(makeUnexpected(oops) == Ex(42));
    EXPECT_NE(makeUnexpected(oops), Ex(42));
    EXPECT_FALSE(makeUnexpected(oops) < Ex(42));
    EXPECT_GT(makeUnexpected(oops), Ex(42));
    EXPECT_FALSE(makeUnexpected(oops) <= Ex(42));
    EXPECT_GE(makeUnexpected(oops), Ex(42));
}
Ejemplo n.º 10
0
TEST(WTF_Expected, Expected_void)
{
    typedef Expected<void, const char*> E;
    typedef Expected<void, const void*> EV;
    typedef Expected<void, std::string> String;
    {
        auto e = E();
        EXPECT_TRUE(e.hasValue());
        const auto e2(e);
        EXPECT_TRUE(e2.hasValue());
        EXPECT_EQ(e, e2);
        E e3;
        e3 = e2;
        EXPECT_TRUE(e3.hasValue());
        EXPECT_EQ(e, e3);
    }
    {
        constexpr E c;
        EXPECT_TRUE(c.hasValue());
        constexpr const auto c2(c);
        EXPECT_TRUE(c2.hasValue());
        EXPECT_EQ(c, c2);
    }
    {
        auto u = E(makeUnexpected(oops));
        EXPECT_FALSE(u.hasValue());
        EXPECT_EQ(u.error(), oops);
        EXPECT_EQ(u.getUnexpected().value(), oops);
    }
    {
        auto uv = EV(makeUnexpected(oops));
        EXPECT_FALSE(uv.hasValue());
        EXPECT_EQ(uv.error(), oops);
        EXPECT_EQ(uv.getUnexpected().value(), oops);
    }
    {
        E e = makeUnexpected(oops);
        EXPECT_FALSE(e.hasValue());
        EXPECT_EQ(e.error(), oops);
        EXPECT_EQ(e.getUnexpected().value(), oops);
    }
    {
        auto e = makeExpectedFromError<void, const char*>(oops);
        EXPECT_FALSE(e.hasValue());
        EXPECT_EQ(e.error(), oops);
        EXPECT_EQ(e.getUnexpected().value(), oops);
    }
    {
        auto e = makeExpectedFromError<void, const void*>(oops);
        EXPECT_FALSE(e.hasValue());
        EXPECT_EQ(e.error(), oops);
        EXPECT_EQ(e.getUnexpected().value(), oops);
    }
    {
        auto e0 = E();
        auto e1 = E();
        swap(e0, e1);
        EXPECT_EQ(e0, e1);
    }
    {
        auto e0 = E(makeUnexpected(oops));
        auto e1 = E(makeUnexpected(foof));
        swap(e0, e1);
        EXPECT_EQ(e0.error(), foof);
        EXPECT_EQ(e1.error(), oops);
    }
    {
        const char* message = "very long failure string, for very bad failure cases";
        String e0(makeUnexpected<std::string>(message));
        String e1(makeUnexpected<std::string>(message));
        String e2(makeUnexpected<std::string>(std::string()));
        EXPECT_EQ(e0.error(), std::string(message));
        EXPECT_EQ(e0, e1);
        EXPECT_NE(e0, e2);
        String* e4 = new String(makeUnexpected<std::string>(message));
        String* e5 = new String(*e4);
        EXPECT_EQ(e0, *e4);
        delete e4;
        EXPECT_EQ(e0, *e5);
        delete e5;
    }
}
Ejemplo n.º 11
0
TEST(WTF_Expected, expected)
{
    typedef Expected<int, const char*> E;
    typedef Expected<int, const void*> EV;
    typedef Expected<foo, const char*> FooChar;
    typedef Expected<foo, std::string> FooString;
    {
        auto e = E();
        EXPECT_TRUE(e.hasValue());
        EXPECT_EQ(e.value(), 0);
        EXPECT_EQ(e.valueOr(3.14), 0);
    }
    {
        constexpr E e;
        EXPECT_TRUE(e.hasValue());
        EXPECT_EQ(e.value(), 0);
        EXPECT_EQ(e.valueOr(3.14), 0);
    }
    {
        auto e = E(42);
        EXPECT_TRUE(e.hasValue());
        EXPECT_EQ(e.value(), 42);
        EXPECT_EQ(e.valueOr(3.14), 42);
        const auto e2(e);
        EXPECT_TRUE(e2.hasValue());
        EXPECT_EQ(e2.value(), 42);
        EXPECT_EQ(e2.valueOr(3.14), 42);
        E e3;
        e3 = e2;
        EXPECT_TRUE(e3.hasValue());
        EXPECT_EQ(e3.value(), 42);
        EXPECT_EQ(e3.valueOr(3.14), 42);
        const E e4 = e2;
        EXPECT_TRUE(e4.hasValue());
        EXPECT_EQ(e4.value(), 42);
        EXPECT_EQ(e4.valueOr(3.14), 42);
    }
    {
        constexpr E c(42);
        EXPECT_TRUE(c.hasValue());
        EXPECT_EQ(c.value(), 42);
        EXPECT_EQ(c.valueOr(3.14), 42);
        constexpr const auto c2(c);
        EXPECT_TRUE(c2.hasValue());
        EXPECT_EQ(c2.value(), 42);
        EXPECT_EQ(c2.valueOr(3.14), 42);
    }
    {
        auto u = E(makeUnexpected(oops));
        EXPECT_FALSE(u.hasValue());
        EXPECT_EQ(u.error(), oops);
        EXPECT_EQ(u.getUnexpected().value(), oops);
        EXPECT_EQ(u.valueOr(3.14), 3);
    }
    {
        auto uv = EV(makeUnexpected(oops));
        EXPECT_FALSE(uv.hasValue());
        EXPECT_EQ(uv.error(), oops);
        EXPECT_EQ(uv.getUnexpected().value(), oops);
        EXPECT_EQ(uv.valueOr(3.14), 3);
    }
    {
        E e = makeUnexpected(oops);
        EXPECT_FALSE(e.hasValue());
        EXPECT_EQ(e.error(), oops);
        EXPECT_EQ(e.getUnexpected().value(), oops);
        EXPECT_EQ(e.valueOr(3.14), 3);
    }
    {
        auto e = makeExpectedFromError<int, const char*>(oops);
        EXPECT_FALSE(e.hasValue());
        EXPECT_EQ(e.error(), oops);
        EXPECT_EQ(e.getUnexpected().value(), oops);
        EXPECT_EQ(e.valueOr(3.14), 3);
    }
    {
        auto e = makeExpectedFromError<int, const void*>(oops);
        EXPECT_FALSE(e.hasValue());
        EXPECT_EQ(e.error(), oops);
        EXPECT_EQ(e.getUnexpected().value(), oops);
        EXPECT_EQ(e.valueOr(3.14), 3);
    }
    {
        auto e = FooChar(42);
        EXPECT_EQ(e->v, 42);
        EXPECT_EQ((*e).v, 42);
    }
    {
        auto e0 = E(42);
        auto e1 = E(1024);
        swap(e0, e1);
        EXPECT_EQ(e0.value(), 1024);
        EXPECT_EQ(e1.value(), 42);
    }
    {
        auto e0 = E(makeUnexpected(oops));
        auto e1 = E(makeUnexpected(foof));
        swap(e0, e1);
        EXPECT_EQ(e0.error(), foof);
        EXPECT_EQ(e1.error(), oops);
    }
    {
        FooChar c(foo(42));
        EXPECT_EQ(c->v, 42);
        EXPECT_EQ((*c).v, 42);
    }
    {
        FooString s(foo(42));
        EXPECT_EQ(s->v, 42);
        EXPECT_EQ((*s).v, 42);
        const char* message = "very long failure string, for very bad failure cases";
        FooString e0(makeUnexpected<std::string>(message));
        FooString e1(makeUnexpected<std::string>(message));
        FooString e2(makeUnexpected<std::string>(std::string()));
        EXPECT_EQ(e0.error(), std::string(message));
        EXPECT_EQ(e0, e1);
        EXPECT_NE(e0, e2);
        FooString* e4 = new FooString(makeUnexpected<std::string>(message));
        FooString* e5 = new FooString(*e4);
        EXPECT_EQ(e0, *e4);
        delete e4;
        EXPECT_EQ(e0, *e5);
        delete e5;
    }
}