test: unit cover audio peak helpers and path_info module#8
Merged
Conversation
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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the testing gap left by the four refactor PRs (#3 / #4 / #6 / #7) — each extracted a module from
cli_args_debugger.cppbut 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 insideaudio_capture.cppare promoted into theaudio_capture::detailnamespace so the test TU can link against them. No behaviour change:AudioCapture::ComputePeakstill calls them unqualified via a function-scopedusing namespace audio_capture::detail;.tests/audio_peak_tests.cpp— 22 testsPeakFloat32/PeakPcm16/PeakPcm24/PeakPcm32— positive peaks, full-scale negatives (INT*_MIN→1.0), silence, and the 24-bit sign-extension edge case that used to live buried inside the CCN-50PollMicrophonebody.PeakForFormat— dispatch correctness plus the "unsupported format degrades to 0" contract (8-bit PCM, A-law).ResolveFormat— plainWAVEFORMATEXpassthrough,WAVEFORMATEXTENSIBLEunwrapping for bothIEEE_FLOATandPCM, preference forwValidBitsPerSampleon pro audio devices, zero-channel-count fallback to mono.tests/path_info_tests.cpp— 11 smoke testsLive 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 ofCollect()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 undercli_args_tests.exe.Memory Safety Tests(ASan) — confirms no leaks in the new test helpers.