Skip to content

test: unit cover audio peak helpers and path_info module#8

Merged
kryuchenko merged 3 commits into
mainfrom
tests/cover-extracted-modules
Apr 18, 2026
Merged

test: unit cover audio peak helpers and path_info module#8
kryuchenko merged 3 commits into
mainfrom
tests/cover-extracted-modules

Conversation

@kryuchenko
Copy link
Copy Markdown
Owner

Summary

Closes the testing gap left by the four refactor PRs (#3 / #4 / #6 / #7) — each extracted a module from cli_args_debugger.cpp but none added tests for the newly-extracted code. This PR covers the two modules with non-trivial pure logic:

audio_capture::detail — the anonymous-namespace peak helpers inside audio_capture.cpp are promoted into the audio_capture::detail namespace so the test TU can link against them. No behaviour change: AudioCapture::ComputePeak still calls them unqualified via a function-scoped using namespace audio_capture::detail;.

tests/audio_peak_tests.cpp — 22 tests

  • PeakFloat32 / PeakPcm16 / PeakPcm24 / PeakPcm32 — positive peaks, full-scale negatives (INT*_MIN1.0), silence, and the 24-bit sign-extension edge case that used to live buried inside the CCN-50 PollMicrophone body.
  • PeakForFormat — dispatch correctness plus the "unsupported format degrades to 0" contract (8-bit PCM, A-law).
  • ResolveFormat — plain WAVEFORMATEX passthrough, WAVEFORMATEXTENSIBLE unwrapping for both IEEE_FLOAT and PCM, preference for wValidBitsPerSample on pro audio devices, zero-channel-count fallback to mono.

tests/path_info_tests.cpp — 11 smoke tests

Live Win32 smoke coverage for each helper plus Collect(). Validates that the growing-buffer / queried-size patterns don't truncate (the whole point of the PathInfo refactor), and pins the label order of Collect() so an accidental reorder in the UI becomes a test failure.

Test plan

  • build / windows-build — audio_capture TU still links correctly with the namespace move.
  • test (CTest) — 33 new test cases execute under cli_args_tests.exe.
  • Memory Safety Tests (ASan) — confirms no leaks in the new test helpers.

Andrey Kryuchenko added 3 commits April 18, 2026 21:25
The four refactor PRs (LogManager / PathInfo / AudioCapture / Renderer
split) shipped without adding tests for the newly-extracted code. This
closes that gap for the two modules with meaningful pure logic.

audio_capture::detail — the anonymous-namespace peak helpers are
promoted into audio_capture::detail so the test TU can link against
them. No behaviour change — AudioCapture::ComputePeak still calls
them unqualified via a function-scoped `using`.

tests/audio_peak_tests.cpp (22 tests):
 - PeakFloat32 / PeakPcm16 / PeakPcm24 / PeakPcm32: positive peaks,
   full-scale negatives (INT*_MIN → 1.0), silence, and the 24-bit
   sign-extension edge case that used to be buried in the CCN-50
   PollMicrophone body.
 - PeakForFormat: dispatch correctness plus the "unsupported format
   degrades to 0" contract (8-bit PCM, A-law).
 - ResolveFormat: plain WAVEFORMATEX passthrough, WAVEFORMATEXTENSIBLE
   unwrapping for IEEE_FLOAT and PCM, wValidBitsPerSample preference,
   zero-channel-count fallback to mono.

tests/path_info_tests.cpp (11 smoke tests): live Win32 smoke coverage
for each helper plus Collect(). Validates the growing-buffer /
queried-size patterns don't truncate (the whole point of that
refactor), and pins the label order of Collect() so an accidental
reorder in the UI becomes a test failure.
Two compile errors surfaced under MSVC / C++20 for the newly added
tests — both noticed only via CI because neither is reproducible on
non-Windows:

1. <ksmedia.h> has a hard `#error "KS.H must be included before
   KSMEDIA.H"` guard. audio_peak_tests.cpp was pulling only ksmedia.h
   (for the KSDATAFORMAT_SUBTYPE_* GUIDs used by the WAVEFORMATEXTENSIBLE
   tests). Add <ks.h> above it and lock the order with clang-format
   off/on so a future auto-sort doesn't re-break it.

2. `std::towlower` is not declared in MSVC's <cctype> — only the C
   function `towlower` (from <cwctype>) reliably exists. Swap the
   header to <cwctype> and call `::towlower`, keeping the wchar_t
   round-trip explicit.
<windows.h> defines bare `min(a,b)` and `max(a,b)` macros that rewrite
`std::numeric_limits<int16_t>::min()` into a malformed expression
under MSVC:

    error C2589: '(': illegal token on right side of '::'
    error C2059: syntax error: ')'

Defining NOMINMAX before the Windows headers suppresses those macros.
The tests use the standard `std::min/std::max` path (via
`std::numeric_limits`), not Windows' macros, so this is a pure
no-op everywhere else.
@kryuchenko kryuchenko merged commit d7568e7 into main Apr 18, 2026
4 checks passed
@kryuchenko kryuchenko deleted the tests/cover-extracted-modules branch April 18, 2026 19:44
kryuchenko pushed a commit that referenced this pull request Apr 18, 2026
…ests

Splits the 2101-line monolithic cli_args_debugger.cpp into a thin window
class plus four composable modules, and fills the test gap along the way.
End state: cli_args_debugger.cpp down to ~1270 lines, zero functions over
the static-analysis CCN threshold, and 33 new unit tests covering the
extracted pure logic.

Modules extracted
-----------------

log_manager.{hpp,cpp}
  Owns g_log_file / g_logPath, InitLogger / Log / LogSEH / CloseLogger.
  Collapses the duplicated cleanup that was inlined in both branches of
  wWinMain. Keeps the extern globals so tests/logging_tests.cpp links
  unchanged.

path_info.{hpp,cpp}  (namespace path_info)
  Hosts ExecutablePath / CurrentWorkingDirectory / TempDirectory /
  WindowsDirectory / SystemDirectory / OsVersionString /
  WineOrProtonVersion / SaveFilePath / Collect. While moving the code:
    - MAX_PATH truncation fixed in five Win32 helpers via growing-retry
      / queried-size patterns.
    - C-style casts on GetProcAddress → reinterpret_cast.
    - exeDir = exeDir.substr(0, slash) → in-place erase.
    - Wrapped under a namespace so Windows.h macros like
      GetWindowsDirectory don't rewrite the function names.

audio_capture.{hpp,cpp}  (class AudioCapture)
  Pulls the entire WASAPI pipeline out of ArgumentDebuggerWindow: the
  11 audio data members, InitializeMicrophone, PollMicrophone (CCN 50,
  the worst function in the codebase), the capture thread entry, and
  the audio slice of OnDestroy/Cleanup. The seh_wrapper TU now casts
  its LPVOID straight to AudioCapture* and calls ThreadMain, so the
  main class no longer leaks into it. PollMicrophone is split into
  ResolveFormat + four per-format peak helpers + a dispatch; highest
  resulting CCN is 16.

RenderFrame split in place
  The CCN-21, 289-line RenderFrame is replaced by a ~20-line orchestrator
  plus ten private section methods (UpdateFrameTiming, RenderCube,
  RenderTextHud, RenderLoadedDataPanel, RenderPathsPanel,
  RenderInputPrompt, RenderQrBitmap, RenderVolumeMeter, EndOverlay,
  PresentFrame). No behaviour change — each helper draws the same
  region in the same order; EndOverlay's bool return mirrors the
  original device-lost early return.

Build system
------------
CMAKE_CXX_STANDARD 20 (required, extensions off) is set in both
CMakeLists.txt files, aligning the CMake/CTest builds with the
/std:c++20 flag already used by the raw-cl path in build.yml. Prior to
this, CMakeLists.txt left the standard unset (MSVC default ≈ C++14)
and tests/CMakeLists.txt pinned C++17, which is why
std::wstring::data() appeared to work for the main exe but broke
CTest compilation.

Tests
-----
tests/audio_peak_tests.cpp — 22 GoogleTest cases covering PeakFloat32,
PeakPcm16, PeakPcm24, PeakPcm32, PeakForFormat dispatch, ResolveFormat
for plain WAVEFORMATEX and WAVEFORMATEXTENSIBLE unwrapping. Includes
the 24-bit sign-extension edge case that used to be buried in
PollMicrophone, the "unsupported format degrades to 0" contract, and
the zero-channel-count fallback.

tests/path_info_tests.cpp — 11 smoke tests covering every path_info::
helper plus Collect(). Validates the growing-buffer / queried-size
patterns don't truncate, and pins Collect()'s label order so a future
accidental reorder surfaces as a test failure.

To keep these helpers testable without a live microphone, the
anonymous-namespace peak helpers in audio_capture.cpp are promoted
into audio_capture::detail.

Numbers
-------
                         before   after
cli_args_debugger.cpp    2101    ~1270   (-40 %)
functions with CCN > 15     2       0
average CCN (main file)   6.4     3.4
highest CCN (main file)    50       7   (WindowProc)
test suites                12      14

Squash of PRs #3, #4, #5, #6, #7, #8.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant