LCOV - code coverage report
Current view: top level - libs/mem/tests/src - test_libmem_0011.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 63 63
Test Date: 2026-07-12 01:01:34 Functions: 100.0 % 3 3
Branches: 100.0 % 4 4

             Branch data     Line data    Source code
       1                 :             : #include "test_libmem_all.h"
       2                 :             : 
       3                 :             : /**
       4                 :             :  * @brief Verify that typed and raw accessors expose the same descriptor storage
       5                 :             :  *
       6                 :             :  * Seeds a point descriptor through m_data, then obtains writable raw,
       7                 :             :  * read-only raw, and read-only typed views. For a valid descriptor all
       8                 :             :  * those views must point at the same backing allocation. A mutation
       9                 :             :  * through the raw writable view must be visible through both read-only
      10                 :             :  * views, proving that the raw helpers expose the live descriptor
      11                 :             :  * storage rather than a detached buffer
      12                 :             :  *
      13                 :             :  * @return Return describing success or failure
      14                 :             :  */
      15                 :           1 : static Return test_libmem_0011_1(void)
      16                 :             : {
      17                 :           1 :         INITTEST;
      18                 :             : 
      19                 :           1 :         m_create(point,points);
      20                 :             : 
      21                 :             :         /* Seed the working descriptor through the typed write helper with a predictable per-index pattern */
      22                 :           1 :         ASSERT(SUCCESS == m_resize(points,5));
      23                 :           1 :         ASSERT(SUCCESS == fill_points(points));
      24                 :             : 
      25                 :           1 :         point *typed_points = m_data(point,points);
      26                 :           1 :         point *raw_points = (point *)m_raw_data(points);
      27                 :           1 :         const point *readonly_raw_points = (const point *)m_raw_data_ro(points);
      28                 :           1 :         const point *readonly_typed_points = m_data_ro(point,points);
      29                 :             : 
      30                 :           1 :         ASSERT(typed_points != NULL);
      31                 :           1 :         ASSERT(raw_points != NULL);
      32                 :           1 :         ASSERT(readonly_raw_points != NULL);
      33                 :           1 :         ASSERT(readonly_typed_points != NULL);
      34                 :             : 
      35                 :           1 :         IF(typed_points != NULL &&
      36                 :             :                 raw_points != NULL &&
      37                 :             :                 readonly_raw_points != NULL &&
      38                 :             :                 readonly_typed_points != NULL)
      39                 :             :         {
      40                 :             :                 /* All accessor families expose the same live allocation for a valid descriptor */
      41                 :           1 :                 ASSERT((const void *)typed_points == (const void *)raw_points);
      42                 :           1 :                 ASSERT((const void *)typed_points == (const void *)readonly_raw_points);
      43                 :           1 :                 ASSERT((const void *)typed_points == (const void *)readonly_typed_points);
      44                 :             : 
      45                 :             :                 /* The asymmetric mutation makes detached views or wrong point-field interpretation visible on read-back */
      46                 :           1 :                 raw_points[0].x += 100;
      47                 :           1 :                 raw_points[0].y += 200;
      48                 :             : 
      49                 :           1 :                 ASSERT(readonly_raw_points[0].x == 101);
      50                 :           1 :                 ASSERT(readonly_raw_points[0].y == 202);
      51                 :           1 :                 ASSERT(readonly_typed_points[0].x == 101);
      52                 :           1 :                 ASSERT(readonly_typed_points[0].y == 202);
      53                 :             :         }
      54                 :             : 
      55                 :           1 :         ASSERT(points->string_length == 0);
      56                 :           1 :         ASSERT(points->is_string == false);
      57                 :           1 :         call(m_del(points));
      58                 :             : 
      59                 :           1 :         RETURN_STATUS;
      60                 :             : }
      61                 :             : 
      62                 :             : /**
      63                 :             :  * @brief Verify that m_copy duplicates every typed point element
      64                 :             :  *
      65                 :             :  * Copies a populated point descriptor into an empty mirror descriptor.
      66                 :             :  * The source first receives a raw-side mutation at index zero so the
      67                 :             :  * copied payload includes both the deterministic fill_points pattern
      68                 :             :  * and a later raw write. The mirror is then checked element by element,
      69                 :             :  * which catches implementations that copy metadata or only a prefix of
      70                 :             :  * the payload
      71                 :             :  *
      72                 :             :  * @return Return describing success or failure
      73                 :             :  */
      74                 :           1 : static Return test_libmem_0011_2(void)
      75                 :             : {
      76                 :           1 :         INITTEST;
      77                 :             : 
      78                 :           1 :         m_create(point,points);
      79                 :           1 :         m_create(point,mirror);
      80                 :             : 
      81                 :           1 :         ASSERT(SUCCESS == m_resize(points,5));
      82                 :           1 :         ASSERT(SUCCESS == fill_points(points));
      83                 :             : 
      84                 :           1 :         point *raw_points = (point *)m_raw_data(points);
      85                 :           1 :         ASSERT(raw_points != NULL);
      86                 :             : 
      87                 :           1 :         IF(raw_points != NULL)
      88                 :             :         {
      89                 :           1 :                 raw_points[0].x += 100;
      90                 :           1 :                 raw_points[0].y += 200;
      91                 :             :         }
      92                 :             : 
      93                 :           1 :         ASSERT(SUCCESS == m_copy(mirror,points));
      94                 :             : 
      95                 :             :         /* Typed read-only view on the mirror confirms the copy carried length and every point element */
      96                 :           1 :         const point *mirror_points = m_data_ro(point,mirror);
      97                 :           1 :         ASSERT(mirror_points != NULL);
      98                 :             : 
      99                 :           1 :         IF(mirror_points != NULL)
     100                 :             :         {
     101                 :           1 :                 ASSERT(mirror->length == 5);
     102                 :             : 
     103         [ +  + ]:           6 :                 for(size_t point_index = 0; point_index < mirror->length; point_index++)
     104                 :             :                 {
     105                 :           5 :                         int expected_x = (int)(point_index * 2 + 1);
     106                 :           5 :                         int expected_y = (int)(point_index * 2 + 2);
     107                 :             : 
     108         [ +  + ]:           5 :                         if(point_index == 0)
     109                 :             :                         {
     110                 :           1 :                                 expected_x += 100;
     111                 :           1 :                                 expected_y += 200;
     112                 :             :                         }
     113                 :             : 
     114                 :           5 :                         ASSERT(mirror_points[point_index].x == expected_x);
     115                 :           5 :                         ASSERT(mirror_points[point_index].y == expected_y);
     116                 :             :                 }
     117                 :             :         }
     118                 :             : 
     119                 :           1 :         ASSERT(points->string_length == 0);
     120                 :           1 :         ASSERT(points->is_string == false);
     121                 :           1 :         ASSERT(mirror->string_length == 0);
     122                 :           1 :         ASSERT(mirror->is_string == false);
     123                 :           1 :         call(m_del(points));
     124                 :           1 :         call(m_del(mirror));
     125                 :             : 
     126                 :           1 :         RETURN_STATUS;
     127                 :             : }
     128                 :             : 
     129                 :             : /**
     130                 :             :  * @brief Verify raw pointer access and descriptor copying for typed point arrays
     131                 :             :  *
     132                 :             :  * Groups tests for the direct access contract of m_data, m_data_ro,
     133                 :             :  * m_raw_data, and m_raw_data_ro, plus data-mode descriptor copying
     134                 :             :  * through m_copy
     135                 :             :  *
     136                 :             :  * @return Return describing success or failure
     137                 :             :  */
     138                 :           1 : Return test_libmem_0011(void)
     139                 :             : {
     140                 :           1 :         INITTEST;
     141                 :             : 
     142                 :           1 :         TEST(test_libmem_0011_1,"Typed and raw point accessors share descriptor storage");
     143                 :           1 :         TEST(test_libmem_0011_2,"m_copy duplicates every typed point element");
     144                 :             : 
     145                 :           1 :         RETURN_STATUS;
     146                 :             : }
        

Generated by: LCOV version 2.0-1