json_binder_polymorphic_test.cxx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //
  2. // json_binder_polymorphic.t.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 11/14/18.
  6. // Copyright © 2018 Sam Jaffe. All rights reserved.
  7. //
  8. #include <gmock/gmock.h>
  9. #include "json/json_binder.hpp"
  10. struct Base {
  11. virtual ~Base() = default;
  12. virtual void run() const = 0;
  13. };
  14. struct Left : public Base {
  15. int a;
  16. void run() const override {}
  17. };
  18. struct Right : public Base {
  19. std::string a;
  20. void run() const override {}
  21. };
  22. bool operator==(Left const & lhs, Left const & rhs) {
  23. return lhs.a == rhs.a;
  24. }
  25. bool operator==(Right const & lhs, Right const & rhs) {
  26. return lhs.a == rhs.a;
  27. }
  28. using namespace json::binder;
  29. using namespace json::parser;
  30. class JsonBinderPolymorphicTest : public ::testing::Test {
  31. protected:
  32. using pBase = std::unique_ptr<Base>;
  33. polymorphic_binder<pBase> & GetBinder() {
  34. static polymorphic_binder<pBase> val = polymorphic_binder<pBase>()
  35. ("Left", object_binder<Left>()("a", &Left::a))
  36. ("Right", object_binder<Right>()("a", &Right::a));
  37. return val;
  38. }
  39. };
  40. template <typename T>
  41. bool instanceof(Base * ptr) {
  42. return dynamic_cast<T*>(ptr) != nullptr;
  43. }
  44. using namespace ::testing;
  45. TEST_F(JsonBinderPolymorphicTest, CanHitLeftPolymorph) {
  46. char data[] = "{\"@id\":\"Left\", \"@value\":{\"a\":1}}";
  47. pBase out;
  48. Left expected; expected.a = 1;
  49. EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data));
  50. EXPECT_THAT(out, Not(IsNull()));
  51. EXPECT_PRED1(instanceof<Left>, out.get());
  52. EXPECT_THAT(dynamic_cast<Left&>(*out), expected);
  53. }
  54. TEST_F(JsonBinderPolymorphicTest, CanHitRightPolymorph) {
  55. char data[] = "{\"@id\":\"Right\", \"@value\":{\"a\":\"hello\"}}";
  56. pBase out;
  57. Right expected; expected.a = "hello";
  58. EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data));
  59. EXPECT_THAT(out, Not(IsNull()));
  60. EXPECT_PRED1(instanceof<Right>, out.get());
  61. EXPECT_THAT(dynamic_cast<Right&>(*out), expected);
  62. }