scene_test.cxx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //
  2. // scene_test.cxx
  3. // engine-test
  4. //
  5. // Created by Sam Jaffe on 7/12/19.
  6. // Copyright © 2019 Sam Jaffe. All rights reserved.
  7. //
  8. #include <gmock/gmock.h>
  9. #include "game/engine/entity.hpp"
  10. #include "game/engine/game_dispatch.hpp"
  11. #include "game/engine/scene.hpp"
  12. #include "mock_renderer.h"
  13. struct test_scene : engine::scene {
  14. using engine::scene::scene;
  15. void update(float) override { check_collisions(); }
  16. void render(graphics::renderer &) override {}
  17. void handle_key_event(engine::event::key_event) override {}
  18. void handle_mouse_event(engine::event::mouse_event) override {}
  19. void add_with(engine::collision_t t, engine::collidable & c) {
  20. colliders[t].push_back(&c);
  21. }
  22. void add_as(engine::collision_t t, engine::collidable & c) {
  23. collidables[t].push_back(&c);
  24. }
  25. };
  26. struct mock_collidable : engine::collidable {
  27. mock_collidable(math::dim2::rectangle bounds)
  28. : engine::collidable({bounds, bounds, cast<graphics::material>(1), {}}) {}
  29. MOCK_METHOD1(collide, void(engine::collidable const &));
  30. };
  31. class SceneTest : public testing::Test {
  32. protected:
  33. void SetUp() override;
  34. void TearDown() override;
  35. test_scene & scene() const { return *scene_; }
  36. engine::game_dispatch & game() const { return *dispatch_; }
  37. std::shared_ptr<stub_renderer> renderer_;
  38. std::shared_ptr<engine::game_dispatch> dispatch_;
  39. std::shared_ptr<test_scene> scene_;
  40. };
  41. void SceneTest::SetUp() {
  42. renderer_.reset(new stub_renderer);
  43. dispatch_.reset(new engine::game_dispatch(renderer_));
  44. scene_.reset(new test_scene("test", dispatch_));
  45. }
  46. void SceneTest::TearDown() {
  47. scene_.reset();
  48. dispatch_.reset();
  49. renderer_.reset();
  50. }
  51. using testing::Ref;
  52. TEST_F(SceneTest, WillCollideOverlappingObjects) {
  53. math::dim2::rectangle bnds{{{0.f, 0.f}}, {{1.f, 1.f}}};
  54. mock_collidable one{bnds}, two{bnds};
  55. scene().add_with(1, one);
  56. scene().add_as(1, two);
  57. EXPECT_CALL(one, collide(Ref(two))).Times(1);
  58. scene().update(0.f);
  59. }
  60. TEST_F(SceneTest, NonOverlappingDontCollide) {
  61. mock_collidable one{{{{0.f, 0.f}}, {{1.f, 1.f}}}};
  62. mock_collidable two{{{{2.f, 2.f}}, {{1.f, 1.f}}}};
  63. scene().add_with(1, one);
  64. scene().add_as(1, two);
  65. EXPECT_CALL(one, collide(Ref(two))).Times(0);
  66. scene().update(0.f);
  67. }
  68. TEST_F(SceneTest, CollisionIsOneWay) {
  69. math::dim2::rectangle bnds{{{0.f, 0.f}}, {{1.f, 1.f}}};
  70. mock_collidable one{bnds}, two{bnds};
  71. scene().add_with(1, one);
  72. scene().add_as(1, two);
  73. EXPECT_CALL(one, collide(Ref(two))).Times(1);
  74. EXPECT_CALL(two, collide(Ref(one))).Times(0);
  75. scene().update(0.f);
  76. }
  77. TEST_F(SceneTest, ObjectCannotCollideSelf) {
  78. math::dim2::rectangle bnds{{{0.f, 0.f}}, {{1.f, 1.f}}};
  79. mock_collidable one{bnds};
  80. scene().add_with(1, one);
  81. scene().add_as(1, one);
  82. EXPECT_CALL(one, collide(Ref(one))).Times(0);
  83. scene().update(0.f);
  84. }
  85. TEST_F(SceneTest, CollisionMatchesAsWithKeys) {
  86. math::dim2::rectangle bnds{{{0.f, 0.f}}, {{1.f, 1.f}}};
  87. mock_collidable one{bnds}, two{bnds}, three{bnds};
  88. scene().add_with(2, one);
  89. scene().add_as(1, two);
  90. scene().add_as(2, three);
  91. EXPECT_CALL(one, collide(Ref(two))).Times(0);
  92. EXPECT_CALL(one, collide(Ref(three))).Times(1);
  93. scene().update(0.f);
  94. }
  95. TEST_F(SceneTest, ObjectCanBeInMultipleCollidesWithGroups) {
  96. math::dim2::rectangle bnds{{{0.f, 0.f}}, {{1.f, 1.f}}};
  97. mock_collidable one{bnds}, two{bnds}, three{bnds};
  98. scene().add_with(1, one);
  99. scene().add_with(2, one);
  100. scene().add_as(1, two);
  101. scene().add_as(2, three);
  102. EXPECT_CALL(one, collide(Ref(two))).Times(1);
  103. EXPECT_CALL(one, collide(Ref(three))).Times(1);
  104. scene().update(0.f);
  105. }
  106. TEST_F(SceneTest, ObjectCanBeInMultipleCollidableAsGroups) {
  107. math::dim2::rectangle bnds{{{0.f, 0.f}}, {{1.f, 1.f}}};
  108. mock_collidable one{bnds}, two{bnds}, three{bnds};
  109. scene().add_with(1, one);
  110. scene().add_with(2, three);
  111. scene().add_as(1, two);
  112. scene().add_as(2, two);
  113. EXPECT_CALL(one, collide(Ref(two))).Times(1);
  114. EXPECT_CALL(three, collide(Ref(two))).Times(1);
  115. scene().update(0.f);
  116. }
  117. TEST_F(SceneTest, DoubleCollisionCanOccur) {
  118. math::dim2::rectangle bnds{{{0.f, 0.f}}, {{1.f, 1.f}}};
  119. mock_collidable one{bnds}, two{bnds};
  120. scene().add_with(1, one);
  121. scene().add_with(2, one);
  122. scene().add_as(1, two);
  123. scene().add_as(2, two);
  124. EXPECT_CALL(one, collide(Ref(two))).Times(1);
  125. scene().update(0.f);
  126. }