LCOV - code coverage report
Current view: top level - test - engine.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 76 76
Test Date: 2026-04-03 02:26:39 Functions: 100.0 % 2 2

            Line data    Source code
       1              : #include "catch.hpp"
       2              : #include "Engine.h"
       3              : #include "KeyState.h"
       4              : 
       5              : // gameCycle, initGL, initAL, loadGame, loadLevel, and renderText require a live
       6              : // GL/audio environment and are not exercised here.
       7              : 
       8           14 : SCENARIO( "Engine", "[Engine]" ) {
       9           26 :   GIVEN( "A game engine instance" ) {
      10           13 :     Engine e;
      11              : 
      12           18 :     WHEN( "first constructed" ) {
      13            6 :       THEN( "engine is running" ) {
      14            1 :         REQUIRE(e.getIsRunning() == true);
      15            1 :       }
      16              : 
      17            6 :       THEN( "key state pointers are valid (addresses of member structs)" ) {
      18            1 :         REQUIRE(e.getKeyState() != NULL);
      19            1 :         REQUIRE(e.getSpecialKeyState() != NULL);
      20            1 :       }
      21              : 
      22            6 :       THEN( "fps starts at zero" ) {
      23            1 :         REQUIRE(e.getFps() == Approx(0.0f));
      24            1 :       }
      25              : 
      26            6 :       THEN( "no level is loaded" ) {
      27            1 :         REQUIRE(e.getCurrentLevel() == NULL);
      28            1 :       }
      29              : 
      30            6 :       THEN( "mouse position starts at origin" ) {
      31            1 :         REQUIRE(e.getMouseX() == Approx(0.0f));
      32            1 :         REQUIRE(e.getMouseY() == Approx(0.0f));
      33            1 :       }
      34            5 :     }
      35              : 
      36           14 :     WHEN( "a normal key is pressed" ) {
      37            1 :       e.processNormalKeyDown('a');
      38              : 
      39            2 :       THEN( "keyState records it as pressed" ) {
      40            1 :         REQUIRE(e.getKeyState()->keys['a'] == KEY_STATE_PRESSED);
      41            1 :       }
      42            1 :     }
      43              : 
      44           14 :     WHEN( "a normal key is released" ) {
      45            1 :       e.processNormalKeyDown('a');
      46            1 :       e.processNormalKeyUp('a');
      47              : 
      48            2 :       THEN( "keyState records it as released" ) {
      49            1 :         REQUIRE(e.getKeyState()->keys['a'] == KEY_STATE_RELEASED);
      50            1 :       }
      51            1 :     }
      52              : 
      53           14 :     WHEN( "a special key is pressed" ) {
      54            1 :       e.processKeyDown(1);
      55              : 
      56            2 :       THEN( "specialKeyState records it as pressed" ) {
      57            1 :         REQUIRE(e.getSpecialKeyState()->keys[1] == KEY_STATE_PRESSED);
      58            1 :       }
      59            1 :     }
      60              : 
      61           14 :     WHEN( "a special key is released" ) {
      62            1 :       e.processKeyDown(1);
      63            1 :       e.processKeyUp(1);
      64              : 
      65            2 :       THEN( "specialKeyState records it as released" ) {
      66            1 :         REQUIRE(e.getSpecialKeyState()->keys[1] == KEY_STATE_RELEASED);
      67            1 :       }
      68            1 :     }
      69              : 
      70              :     // processCommands resets both key states to KEY_STATE_INIT each frame
      71              :     // (called at the start of gameCycle via updateGame).
      72           14 :     WHEN( "processCommands is called after a key is pressed" ) {
      73            1 :       e.processNormalKeyDown('a');
      74            1 :       e.processKeyDown(1);
      75            1 :       e.processCommands();
      76              : 
      77            2 :       THEN( "all key states are reset to KEY_STATE_INIT" ) {
      78            1 :         REQUIRE(e.getKeyState()->keys['a'] == KEY_STATE_INIT);
      79            1 :         REQUIRE(e.getSpecialKeyState()->keys[1] == KEY_STATE_INIT);
      80            1 :       }
      81            1 :     }
      82              : 
      83           14 :     WHEN( "processMouseMove is called" ) {
      84            1 :       e.processMouseMove(100, 200);
      85              : 
      86            2 :       THEN( "mouse position is updated" ) {
      87            1 :         REQUIRE(e.getMouseX() == Approx(100.0f));
      88            1 :         REQUIRE(e.getMouseY() == Approx(200.0f));
      89            1 :       }
      90            1 :     }
      91              : 
      92              :     // pause() toggles isPaused_ but there is no public getter; not testable here.
      93           15 :     WHEN( "shutdown is called" ) {
      94            2 :       e.shutdown();
      95              : 
      96            3 :       THEN( "engine is no longer running" ) {
      97            1 :         REQUIRE(e.getIsRunning() == false);
      98            1 :       }
      99              : 
     100              :       // shutdown() only sets isRunning_ = false — it does not close Lua, OpenAL,
     101              :       // or delete levels. Key state structs are Engine members and remain valid
     102              :       // until the Engine object is destroyed.
     103            3 :       THEN( "key state pointers remain valid" ) {
     104            1 :         REQUIRE(e.getKeyState() != NULL);
     105            1 :         REQUIRE(e.getSpecialKeyState() != NULL);
     106            1 :       }
     107            2 :     }
     108           13 :   }
     109           13 : }
        

Generated by: LCOV version 2.4-0