Add CTest coverage reporting
Instrument libakgl in opt-in coverage builds, use CTest fixtures to reset counters and emit Cobertura XML and detailed HTML reports, and upload those reports from Gitea CI. Document the local coverage workflow for contributors. Co-authored-by: Codex (GPT-5) <noreply@openai.com>
This commit is contained in:
@@ -14,7 +14,7 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
cmake doxygen gcc pkg-config \
|
||||
cmake doxygen gcc gcovr pkg-config \
|
||||
libasound2-dev libfreetype-dev libharfbuzz-dev \
|
||||
libpng-dev libtiff-dev libwebp-dev \
|
||||
libudev-dev libx11-dev libxcursor-dev libxext-dev \
|
||||
@@ -22,7 +22,9 @@ jobs:
|
||||
libxss-dev libxtst-dev
|
||||
- name: Configure and build
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
|
||||
cmake -S . -B build \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DAKGL_COVERAGE=ON
|
||||
cmake --build build --parallel
|
||||
- name: Build API documentation
|
||||
run: doxygen Doxyfile
|
||||
@@ -43,6 +45,13 @@ jobs:
|
||||
detailed_summary: true
|
||||
include_passed: true
|
||||
fail_on_failure: 'true'
|
||||
- name: Upload coverage reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: code-coverage
|
||||
path: build/coverage/
|
||||
if-no-files-found: warn
|
||||
|
||||
mutation_test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -28,6 +28,8 @@ Run one test while iterating, for example `ctest --test-dir build -R sprite --ou
|
||||
|
||||
Run mutation testing with `cmake --build build --target mutation`. For a quick smoke run, use `scripts/mutation_test.py --target src/tilemap.c --max-mutants 10`; the harness mutates only a scratch copy and excludes the intentionally failing character test.
|
||||
|
||||
Generate HTML and Cobertura coverage reports with `cmake -S . -B build-coverage -DAKGL_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug`, then build and run CTest. Reports are written to `build-coverage/coverage/`; this mode requires `gcovr` and GCC or Clang.
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
|
||||
Follow the surrounding C style: braces on the next line for function bodies, spaces inside control-flow parentheses, and short, focused functions. Preserve the indentation of the file being edited; older files contain both spaces and tabs. Public symbols use the `akgl_` prefix, public types use `akgl_TypeName`, and constants/macros use `AKGL_UPPER_SNAKE_CASE`. Name matching header/source pairs by feature, such as `include/akgl/sprite.h` and `src/sprite.c`. No repository-wide formatter or linter is configured, so avoid unrelated formatting churn.
|
||||
@@ -39,7 +41,7 @@ Follow the surrounding C style: braces on the next line for function bodies, spa
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
Tests use simple executable return codes and are registered through CTest in `CMakeLists.txt`; there is no declared coverage threshold. Add focused tests as `tests/<feature>.c`, create a matching `test_<feature>` target, and register it with `add_test`. Put reusable fixtures in `tests/assets/` and keep paths compatible with tests launched from the build tree.
|
||||
Tests use simple executable return codes and are registered through CTest in `CMakeLists.txt`; there is no declared coverage threshold. Add focused tests as `tests/<feature>.c`, create a matching `test_<feature>` target, and register it with `add_test`. Put reusable fixtures in `tests/assets/` and keep paths compatible with tests launched from the build tree. Coverage mode wraps the suite in a CTest fixture so counters are reset before tests and reports are generated afterward.
|
||||
|
||||
## Commit & Pull Request Guidelines
|
||||
|
||||
|
||||
@@ -2,6 +2,14 @@ cmake_minimum_required(VERSION 3.10)
|
||||
project(akgl LANGUAGES C)
|
||||
|
||||
include(CTest)
|
||||
option(AKGL_COVERAGE "Instrument libakgl and generate coverage reports with CTest" OFF)
|
||||
|
||||
if(AKGL_COVERAGE)
|
||||
if(NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
|
||||
message(FATAL_ERROR "AKGL_COVERAGE requires GCC or Clang")
|
||||
endif()
|
||||
find_program(GCOVR_EXECUTABLE gcovr REQUIRED)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
|
||||
@@ -141,6 +149,44 @@ target_include_directories(akgl PUBLIC
|
||||
deps/semver/
|
||||
)
|
||||
|
||||
if(AKGL_COVERAGE)
|
||||
target_compile_options(akgl PRIVATE --coverage -O0 -g)
|
||||
target_link_options(akgl PRIVATE --coverage)
|
||||
|
||||
set(AKGL_COVERAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/coverage")
|
||||
file(MAKE_DIRECTORY "${AKGL_COVERAGE_DIR}")
|
||||
|
||||
add_test(
|
||||
NAME coverage_reset
|
||||
COMMAND ${GCOVR_EXECUTABLE}
|
||||
--root "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
--object-directory "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
--delete
|
||||
)
|
||||
set_tests_properties(coverage_reset PROPERTIES FIXTURES_SETUP akgl_coverage)
|
||||
set_tests_properties(
|
||||
actor bitmasks character registry sprite staticstring tilemap util semver_unit
|
||||
PROPERTIES FIXTURES_REQUIRED akgl_coverage
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME coverage_report
|
||||
COMMAND ${GCOVR_EXECUTABLE}
|
||||
--root "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
--object-directory "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
--filter "${CMAKE_CURRENT_SOURCE_DIR}/src/"
|
||||
--xml-pretty
|
||||
--xml "${AKGL_COVERAGE_DIR}/coverage.xml"
|
||||
--html-details "${AKGL_COVERAGE_DIR}/index.html"
|
||||
)
|
||||
set_tests_properties(
|
||||
coverage_report
|
||||
PROPERTIES
|
||||
FIXTURES_CLEANUP akgl_coverage
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(akgl
|
||||
PUBLIC
|
||||
SDL3::SDL3
|
||||
|
||||
Reference in New Issue
Block a user