Repository: fmtlib/fmt
File: test/base-test.cc (C++)

Code before:
  CHECK_ARG(char, cstr, str);

  auto sv = fmt::string_view(str);
  CHECK_ARG(char, sv, std::string(str));
}

TEST(arg_test, pointer_arg) {
  void* p = nullptr;
  const void* cp = nullptr;
  CHECK_ARG(char, cp, p);
  CHECK_ARG_SIMPLE(cp);
}

TEST(arg_test, volatile_pointer_arg) {
  auto check = [](const int val) {
    CHECK_ARG(
        char, reinterpret_cast<const void*>(val),
        static_cast<volatile void*>(reinterpret_cast<volatile int*>(val)));
    CHECK_ARG(char, reinterpret_cast<const void*>(val),
              static_cast<const volatile void*>(
                  reinterpret_cast<const volatile int*>(val)));
  };
  check(0);
  check(1);
  check(2);
  check(0xbeef);
}

struct check_custom {
  auto operator()(fmt::basic_format_arg<fmt::format_context>::handle h) const
      -> test_result {
    struct test_buffer final : fmt::detail::buffer<char> {
      char data[10];
      test_buffer()
          : fmt::detail::buffer<char>([](buffer<char>&, size_t) {}, data, 0,
                                      10) {}
    } buffer;
    auto parse_ctx = fmt::format_parse_context("");
    auto ctx = fmt::format_context(fmt::appender(buffer), fmt::format_args());
    h.format(parse_ctx, ctx);
    EXPECT_EQ("test", std::string(buffer.data, buffer.size()));
    return test_result();
  }
};

TEST(arg_test, custom_arg) {
  auto test = test_struct();
  using visitor =
      mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>;
  auto&& v = testing::StrictMock<visitor>();
  EXPECT_CALL(v, visit(_)).WillOnce(Invoke(check_custom()));

Review comment (bug):
I don't think we need to check various values here, let's get rid of the lambda and just check nullptr.

Code after:
  CHECK_ARG(char, cstr, str);

  auto sv = fmt::string_view(str);
  CHECK_ARG(char, sv, std::string(str));
}

TEST(arg_test, pointer_arg) {
  void* p = nullptr;
  const void* cp = nullptr;
  CHECK_ARG(char, cp, p);
  CHECK_ARG_SIMPLE(cp);
}

TEST(arg_test, volatile_pointer_arg) {
  const void* p = nullptr;
  volatile int* vip = nullptr;
  const volatile int* cvip = nullptr;
  CHECK_ARG(char, p, static_cast<volatile void*>(vip));
  CHECK_ARG(char, p, static_cast<const volatile void*>(cvip));
}

struct check_custom {
  auto operator()(fmt::basic_format_arg<fmt::format_context>::handle h) const
      -> test_result {
    struct test_buffer final : fmt::detail::buffer<char> {
      char data[10];
      test_buffer()
          : fmt::detail::buffer<char>([](buffer<char>&, size_t) {}, data, 0,
                                      10) {}
    } buffer;
    auto parse_ctx = fmt::format_parse_context("");
    auto ctx = fmt::format_context(fmt::appender(buffer), fmt::format_args());
    h.format(parse_ctx, ctx);
    EXPECT_EQ("test", std::string(buffer.data, buffer.size()));
    return test_result();
  }
};

TEST(arg_test, custom_arg) {
  auto test = test_struct();
  using visitor =
      mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>;
  auto&& v = testing::StrictMock<visitor>();
  EXPECT_CALL(v, visit(_)).WillOnce(Invoke(check_custom()));
  fmt::detail::make_arg<fmt::format_context>(test).visit(v);
}

TEST(arg_test, visit_invalid_arg) {
  auto&& visitor = testing::StrictMock<mock_visitor<fmt::monostate>>();
  EXPECT_CALL(visitor, visit(_));
  fmt::basic_format_arg<fmt::format_context>().visit(visitor);