manager_test.cxx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // manager_test.cxx
  3. // graphics
  4. //
  5. // Created by Sam Jaffe on 6/6/19.
  6. // Copyright © 2019 Sam Jaffe. All rights reserved.
  7. //
  8. #include <gmock/gmock.h>
  9. #include "../src/helper.hpp"
  10. #include "game/graphics/manager.hpp"
  11. #include "game/graphics/material.hpp"
  12. #include "game/graphics/shader.hpp"
  13. #include "game/graphics/shader_program.hpp"
  14. #include "game/graphics/texture.hpp"
  15. using testing::AllOf;
  16. using testing::AnyNumber;
  17. using testing::Eq;
  18. using testing::Ge;
  19. using testing::Le;
  20. using testing::Ne;
  21. using testing::SizeIs;
  22. using testing::_;
  23. struct mock_manager_impl : graphics::manager {
  24. using shader = graphics::shader;
  25. using shader_program = graphics::shader_program;
  26. using texture = graphics::texture;
  27. MOCK_CONST_METHOD2(compile_shader,
  28. shader(graphics::shaders::type, std::string const &));
  29. MOCK_CONST_METHOD2(compile_program,
  30. shader_program(identity<shader>, identity<shader>));
  31. shader compile(graphics::shaders::type t, std::string const & s) const {
  32. return compile_shader(t, s);
  33. }
  34. shader_program compile(identity<shader> f, identity<shader> v) const {
  35. return compile_program(f, v);
  36. }
  37. MOCK_CONST_METHOD3(compile, texture(graphics::textures::format, math::vec2i,
  38. void const *));
  39. };
  40. template <typename T> identity<T> cast(unsigned int id) {
  41. return *reinterpret_cast<identity<T> *>(&id);
  42. }
  43. auto cast_p(unsigned int id) { return cast<graphics::shader_program>(id); }
  44. class ManagerTest : public testing::Test {
  45. public:
  46. void SetUp() override;
  47. mock_manager_impl mock;
  48. private:
  49. struct {
  50. graphics::texture operator()(math::vec2i const & sz) { return {++i, sz}; }
  51. unsigned int i{0};
  52. } next_tex;
  53. };
  54. void ManagerTest::SetUp() {
  55. using testing::Invoke;
  56. using testing::WithArg;
  57. // Start with a new set of IDs
  58. ON_CALL(mock, compile(_, _, _))
  59. .WillByDefault(WithArg<1>(Invoke(std::ref(next_tex))));
  60. }
  61. TEST_F(ManagerTest, DoesNotGreedilyCompile) {
  62. EXPECT_CALL(mock, compile(_, _, _)).Times(0);
  63. EXPECT_CALL(mock, compile_shader(_, _)).Times(0);
  64. EXPECT_CALL(mock, compile_program(_, _)).Times(0);
  65. }
  66. using MaterialTest = ManagerTest;
  67. // TEST_F(MaterialTest, ThrowsExceptionIfNoTexOrUniform) {
  68. // EXPECT_CALL(mock, compile(_, _, _)).Times(AnyNumber());
  69. // // TODO (sjaffe): Throw a specific exception here, since throw; kills us
  70. // EXPECT_ANY_THROW(mock.get(cast_p(1), "", ""));
  71. //}
  72. TEST_F(MaterialTest, GeneratesUniformTexturesIfNoTexFile) {
  73. using graphics::materials::uniform;
  74. EXPECT_CALL(mock, compile(_, make_vector(1, 1), _)).Times(3);
  75. EXPECT_NO_THROW(mock.get(cast_p(1), "", "u_normalMap"));
  76. }
  77. TEST_F(MaterialTest, CreatedMaterialCanBeRefetched) {
  78. using graphics::materials::uniform;
  79. EXPECT_CALL(mock, compile(_, make_vector(1, 1), _)).Times(3);
  80. auto material_id = mock.get(cast_p(1), "", "u_normalMap");
  81. auto material = mock.get(material_id);
  82. // Ensure that the material is the 'same one' i.e.
  83. // mock.get(mock.get(id)) == mock.get(id)
  84. EXPECT_THAT(material, Eq(material_id));
  85. }
  86. TEST_F(MaterialTest, UniformMaterialIsOneByOne) {
  87. using graphics::materials::uniform;
  88. EXPECT_CALL(mock, compile(_, make_vector(1, 1), _)).Times(3);
  89. auto material = mock.get(mock.get(cast_p(1), "", "u_normalMap"));
  90. // Uniforms are always sized 1x1
  91. EXPECT_THAT(material.size, Eq(make_vector(1, 1)));
  92. }
  93. TEST_F(MaterialTest, UniformMaterialHasDataBindingToNormalTex) {
  94. using graphics::materials::uniform;
  95. EXPECT_CALL(mock, compile(_, make_vector(1, 1), _)).Times(3);
  96. auto material = mock.get(mock.get(cast_p(1), "", "u_normalMap"));
  97. EXPECT_THAT(material.uniforms, SizeIs(1));
  98. // Because we never initialize any textures, we are within the first three
  99. // texture ID units.
  100. EXPECT_THAT(material.uniforms[0].texture.id, AllOf(Ge(1), Le(3)));
  101. // Test the mapping from "u_normalMap" to uniform::NORMAL
  102. EXPECT_THAT(material.uniforms[0].uniform_id, Eq(uniform::NORMAL));
  103. }
  104. TEST_F(MaterialTest, DifferentProgramMakesDifferentMaterial) {
  105. using graphics::materials::uniform;
  106. EXPECT_CALL(mock, compile(_, make_vector(1, 1), _)).Times(3);
  107. auto id_1 = mock.get(cast_p(1), "", "u_normalMap");
  108. auto id_2 = mock.get(cast_p(2), "", "u_normalMap");
  109. EXPECT_THAT(id_1, Ne(id_2));
  110. }
  111. TEST_F(MaterialTest, DifferentProgramDoesntChangeUniformId) {
  112. using graphics::materials::uniform;
  113. EXPECT_CALL(mock, compile(_, make_vector(1, 1), _)).Times(3);
  114. auto mat_1 = mock.get(mock.get(cast_p(1), "", "u_normalMap"));
  115. auto mat_2 = mock.get(mock.get(cast_p(2), "", "u_normalMap"));
  116. EXPECT_THAT(mat_1.uniforms[0].texture, Eq(mat_2.uniforms[0].texture));
  117. }