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

            Line data    Source code
       1              : #include "catch.hpp"
       2              : #include "Matrix.h"
       3              : 
       4            3 : void validate_identity_matrix(Matrix &m) {
       5           51 :   for (int i = 0; i < NUM_CELLS; ++i) {
       6           48 :     int expected = i % 5 == 0;
       7           48 :     REQUIRE(m.data[i] == expected);
       8           48 :   }
       9            3 : }
      10              : 
      11            4 : void populate_matrix(Matrix &m) {
      12           68 :   for (int i = 0; i < NUM_CELLS; ++i) {
      13           64 :     m.data[i] = i;
      14           64 :   }
      15            4 : }
      16              : 
      17           10 : SCENARIO( "Manipulating a matrix", "[matrix]" ) {
      18           11 :   GIVEN( "A populated matrix" ) {
      19            2 :     Matrix m;
      20              : 
      21              :     // Matrix is defaulted to the identity matrix
      22            2 :     validate_identity_matrix(m);
      23              : 
      24            2 :     populate_matrix(m);
      25              : 
      26            3 :     WHEN( "the matrix is zeroed" ) {
      27            1 :       m.loadZero();
      28              : 
      29            2 :       THEN( "all cells contain 0" ) {
      30           17 :         for (int i = 0; i < NUM_CELLS; ++i) {
      31           16 :           REQUIRE(m.data[i] == 0);
      32           16 :         }
      33            1 :       }
      34            1 :     }
      35              : 
      36            3 :     WHEN( "the identity matrix is loaded" ) {
      37            1 :       m.loadIdentity();
      38              : 
      39            2 :       THEN( "the matrix contains the identify matrix" ) {
      40            1 :         validate_identity_matrix(m);
      41            1 :       }
      42            1 :     }
      43            2 :   }
      44              : 
      45           11 :   GIVEN( "Copy and assignment" ) {
      46            2 :     Matrix a;
      47            2 :     populate_matrix(a);
      48            2 :     Matrix b(a);
      49              : 
      50            3 :     THEN( "copy constructor duplicates data" ) {
      51           17 :       for (int i = 0; i < NUM_CELLS; ++i) {
      52           16 :         REQUIRE(b.data[i] == a.data[i]);
      53           16 :       }
      54            1 :     }
      55              : 
      56            2 :     Matrix c;
      57            2 :     c = a;
      58            3 :     THEN( "assignment duplicates data" ) {
      59           17 :       for (int i = 0; i < NUM_CELLS; ++i) {
      60           16 :         REQUIRE(c.data[i] == a.data[i]);
      61           16 :       }
      62            1 :     }
      63            2 :   }
      64              : 
      65           10 :   GIVEN( "Identity times translation" ) {
      66            1 :     Matrix i;
      67            1 :     Matrix t;
      68            1 :     t.setTranslation(5.0f, -2.0f, 7.0f);
      69            1 :     Matrix r = i * t;
      70              : 
      71            2 :     THEN( "product is the translation matrix" ) {
      72            1 :       REQUIRE(r.data[12] == Approx(5.0f));
      73            1 :       REQUIRE(r.data[13] == Approx(-2.0f));
      74            1 :       REQUIRE(r.data[14] == Approx(7.0f));
      75            1 :       REQUIRE(r.data[0] == Approx(1.0f));
      76            1 :       REQUIRE(r.data[15] == Approx(1.0f));
      77            1 :     }
      78            1 :   }
      79              : 
      80           10 :   GIVEN( "Translation transforms a vertex with perspective divide" ) {
      81            1 :     Matrix t;
      82            1 :     t.setTranslation(1.0f, 2.0f, 3.0f);
      83            1 :     float v[3] = { 0.0f, 0.0f, 0.0f };
      84              :     float out[3];
      85            1 :     t.transformVertex(v, out);
      86              : 
      87            2 :     THEN( "origin maps to translation" ) {
      88            1 :       REQUIRE(out[0] == Approx(1.0f));
      89            1 :       REQUIRE(out[1] == Approx(2.0f));
      90            1 :       REQUIRE(out[2] == Approx(3.0f));
      91            1 :     }
      92            1 :   }
      93              : 
      94              :   // 16-arg ctor: four columns (c11..c41), (c12..c42), … OpenGL column-major data[].
      95           10 :   GIVEN( "Explicit 16-element constructor (four columns: c1x,c2x,c3x,c4x each)" ) {
      96              :     // Matches Matrix(c11,c21,c31,c41, c12,..., c44) -> OpenGL column-major data[].
      97            1 :     Matrix m(
      98            1 :       1.0f, 0.0f, 0.0f, 0.0f,
      99            1 :       0.0f, 2.0f, 0.0f, 0.0f,
     100            1 :       0.0f, 0.0f, 3.0f, 0.0f,
     101            1 :       4.0f, 5.0f, 6.0f, 1.0f
     102              :     );
     103              : 
     104            2 :     THEN( "diagonal and last-column translation match constructor" ) {
     105            1 :       REQUIRE(m.data[0] == Approx(1.0f));
     106            1 :       REQUIRE(m.data[5] == Approx(2.0f));
     107            1 :       REQUIRE(m.data[10] == Approx(3.0f));
     108            1 :       REQUIRE(m.data[3] == Approx(4.0f));
     109            1 :       REQUIRE(m.data[7] == Approx(5.0f));
     110            1 :       REQUIRE(m.data[11] == Approx(6.0f));
     111            1 :       REQUIRE(m.data[15] == Approx(1.0f));
     112            1 :     }
     113            1 :   }
     114              : 
     115           10 :   GIVEN( "Uniform scale matrix" ) {
     116            1 :     Matrix s;
     117            1 :     s.setScale(2.0f, 3.0f, 4.0f);
     118              : 
     119            2 :     THEN( "diagonal holds scale factors" ) {
     120            1 :       REQUIRE(s.data[0] == Approx(2.0f));
     121            1 :       REQUIRE(s.data[5] == Approx(3.0f));
     122            1 :       REQUIRE(s.data[10] == Approx(4.0f));
     123            1 :       REQUIRE(s.data[15] == Approx(1.0f));
     124            1 :     }
     125            1 :   }
     126              : 
     127           10 :   GIVEN( "Scale times translation multiply order" ) {
     128            1 :     Matrix s;
     129            1 :     s.setScale(2.0f, 1.0f, 1.0f);
     130            1 :     Matrix t;
     131            1 :     t.setTranslation(1.0f, 0.0f, 0.0f);
     132            1 :     Matrix a = s * t;
     133            1 :     float v[3] = { 1.0f, 0.0f, 0.0f };
     134              :     float out[3];
     135            1 :     a.transformVertex(v, out);
     136              : 
     137            2 :     THEN( "with A = S*T as implemented, vertex is translated then scaled on X" ) {
     138            1 :       REQUIRE(out[0] == Approx(4.0f));
     139            1 :       REQUIRE(out[1] == Approx(0.0f));
     140            1 :       REQUIRE(out[2] == Approx(0.0f));
     141            1 :     }
     142            1 :   }
     143            9 : }
        

Generated by: LCOV version 2.4-0