Skip to content

test(cpp): add tests for pure utilities#55

Merged
alandtse merged 2 commits into
devfrom
test/cpp-tier1-pure-utils
May 29, 2026
Merged

test(cpp): add tests for pure utilities#55
alandtse merged 2 commits into
devfrom
test/cpp-tier1-pure-utils

Conversation

@alandtse
Copy link
Copy Markdown
Owner

@alandtse alandtse commented May 29, 2026

Summary

First batch of the cpp-test expansion — the Tier-1 units that are directly unit-testable (compile straight into the Catch2 binary, no plugin DLL / CommonLibSSE / D3D / ImGui runtime). Tier-2 (extraction-required units like FormulaHelper, ISL math, LLF clamp) is a planned fast-follow.

New suites (139 new assertions; 161 total with the existing Subrect + BootSnapshot suites)

  • SphericalHarmonics — band-0/1 basis constants, Dot symmetry + the 1/π unit-direction self-dot identity, Add/Scale algebra, Unproject of a DC-only SH.
  • PerfUtilsCalcFrameTime/CalcFPS guards, Mean/Median (empty/odd/even/unsorted), QPC clock monotonicity.
  • RestartSettingsUTIL_RESTART_FIELD offset/size, FindRestartField hit/miss/case-sensitivity/empty-span.
  • Input — device+key packing & 16-bit key truncation, IsValid, equality/ordering, ToString/IsValidDevice, JSON round-trip (scalar + vector).

Harness changes

  • test_prelude.h (force-included via /FI) supplies the float2/3/4 = DirectX::SimpleMath::* aliases the plugin PCH normally provides, so SphericalHarmonics.cpp compiles without dragging in the RE/SKSE PCH.
  • Links DirectXTK (SimpleMath) and magic_enum to the test target.

Local-build fix (BootSnapshot)

cpp_tests didn't build on the VS2026 / MSVC 14.50 toolchain: test_bootsnapshot's SettingsWithString (a std::string member) tripped BootSnapshot's is_standard_layout static-assert, because std::string isn't standard-layout under MSVC's current STL. (CI's windows-2025/older STL accepted it, so the gate stayed green and earlier incremental builds masked it via a stale .obj.)

The assert was overly strict — detail::MemberOffset uses layout-agnostic pointer subtraction and offsetof is conditionally-supported (MSVC computes correct offsets for the scalar registered fields). Relaxed it to reject only polymorphic Settings (genuinely unstable offsets). Runtime behavior unchanged; compile-time guard only. cpp_tests now builds and passes locally on MSVC 14.50.

Scope notes

  • FileSystem reclassified to Tier 2. SanitizeFileName calls Util::IEquals, declared in Format.h but defined in Format.cpp (which #includes Globals.h), so FileSystem.cpp can't compile standalone. Moves to the Tier-2 follow-up once IEquals is decoupled.
  • Input::MatchesKeyboardCombo is intentionally not tested — it reads live key state via GetAsyncKeyState.

Validation

Full suite builds and passes locally (MSVC 14.50) and is gated in CI (windows-2025): 161 assertions / 43 cases.

Cover the engine-free utility units that compile directly into the Catch2
binary (no plugin DLL, no CommonLibSSE/D3D/ImGui runtime):

- SphericalHarmonics: band-0/1 basis constants, Dot symmetry + 1/pi
  self-dot identity, Add/Scale algebra, Unproject of a DC-only SH.
- PerfUtils: CalcFrameTime / CalcFPS guards, Mean/Median edge cases, QPC.
- RestartSettings: UTIL_RESTART_FIELD offset/size, FindRestartField
  hit/miss/case-sensitivity/empty.
- Input: device+key packing & 16-bit truncation, IsValid, equality/order,
  ToString/IsValidDevice, JSON round-trip (scalar + vector).

Adds test_prelude.h (force-included) to supply the float2/3/4 =
DirectX::SimpleMath aliases the plugin PCH normally provides, and links
DirectXTK + magic_enum to the test target.

FileSystem was reclassified out of Tier 1: SanitizeFileName calls
Util::IEquals, which is defined in Format.cpp (includes Globals.h), so the
TU can't compile standalone. It moves to the Tier-2 follow-up.

139 assertions / 39 cases pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 29, 2026 00:28
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Warning

Review limit reached

@alandtse, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 35 minutes and 48 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9ae1c695-3ce5-41e0-9d32-0a945979b807

📥 Commits

Reviewing files that changed from the base of the PR and between 37b5159 and 6a5743e.

📒 Files selected for processing (7)
  • src/Utils/BootSnapshot.h
  • tests/cpp/CMakeLists.txt
  • tests/cpp/test_input.cpp
  • tests/cpp/test_perfutils.cpp
  • tests/cpp/test_prelude.h
  • tests/cpp/test_restartsettings.cpp
  • tests/cpp/test_sphericalharmonics.cpp
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/cpp-tier1-pure-utils

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

No actionable suggestions for changed features.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the first batch ("Tier-1") of Catch2 unit tests for pure-utility code that does not depend on the plugin DLL, CommonLibSSE, D3D, or ImGui. A small force-included prelude supplies the float2/3/4 SimpleMath aliases that the plugin PCH normally provides, so headers like SphericalHarmonics.h compile inside the standalone test binary.

Changes:

  • New Catch2 test suites for SphericalHarmonics, PerfUtils, RestartSettings, and Input (combo packing, validation, equality/ordering, JSON round-trip).
  • New test_prelude.h force-included into cpp_tests to provide the SimpleMath floatN/float4x4 aliases without dragging in the engine PCH.
  • tests/cpp/CMakeLists.txt registers the new sources, force-includes the prelude, adds directxtk + magic_enum dependencies, and compiles Utils/SphericalHarmonics.cpp directly into the test binary.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/cpp/test_sphericalharmonics.cpp Band-0/1 basis constants, Dot symmetry, Add/Scale algebra, DC-only Unproject.
tests/cpp/test_perfutils.cpp CalcFrameTime/CalcFPS guards, Mean/Median edge cases, QPC monotonicity.
tests/cpp/test_restartsettings.cpp UTIL_RESTART_FIELD offset/size and FindRestartField hit/miss/case-sensitivity/empty-span.
tests/cpp/test_input.cpp Device+key packing, 16-bit key truncation, IsValid, ordering, ToString/IsValidDevice, JSON round-trip.
tests/cpp/test_prelude.h Force-included aliases (float2/3/4, float4x4) for SimpleMath types.
tests/cpp/CMakeLists.txt Registers new sources, prelude force-include, DirectXTK + magic_enum deps.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 29, 2026

✅ A pre-release build is available for this PR:
Download

@alandtse alandtse changed the title test(cpp): add Tier-1 unit tests for pure utilities test(cpp): add Tier-1 tests for pure utilities May 29, 2026
The constructor required std::is_standard_layout_v<SettingsT>, but that
rejects Settings carrying a std::string (std::string is not standard-layout
under MSVC's STL) -- which broke cpp_tests' SettingsWithString deep-copy case
on the VS2026/MSVC 14.50 toolchain (CI's older windows-2025 STL happened to
accept it). The requirement is overly strict: detail::MemberOffset uses
layout-agnostic pointer subtraction, and offsetof in UTIL_RESTART_FIELD is
conditionally-supported on non-standard-layout types (MSVC computes correct
offsets for the scalar registered fields). Reject only polymorphic types,
where a vtable makes member offsets genuinely unstable. Runtime behavior
unchanged; this only relaxes a compile-time guard.

cpp_tests now builds and passes locally on MSVC 14.50 (161 assertions).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 29, 2026 03:31
@alandtse alandtse force-pushed the test/cpp-tier1-pure-utils branch from 13b55da to 6a5743e Compare May 29, 2026 03:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@alandtse alandtse changed the title test(cpp): add Tier-1 tests for pure utilities test(cpp): add tests for pure utilities May 29, 2026
@alandtse alandtse merged commit 61725ff into dev May 29, 2026
21 checks passed
@alandtse alandtse deleted the test/cpp-tier1-pure-utils branch May 29, 2026 05:02
Copilot AI pushed a commit that referenced this pull request May 30, 2026
Move InverseSquareLighting's radius/attenuation constants and the
CalculateRadius / GetAttenuation / SmoothStep math into a new pure header
(Features/InverseSquareLighting/RadiusMath.h, namespace ISLMath). The
functions take only plain floats, so the header compiles standalone into the
cpp_tests binary with no game/RE runtime. The class's static methods now
delegate to it -- call sites (incl. LightEditor) are unchanged. Adds
test_isl_radiusmath.cpp (13 assertions): SmoothStep ramp/clamp,
CalculateRadius closed-form + shadow/override branches + NaN->1 guard,
GetAttenuation peak/vanish/monotonic. Validated: cpp suite + plugin build.

Phase 2 (Tier 2) of the cpp-test expansion; follows #55.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
alandtse added a commit that referenced this pull request May 30, 2026
Move InverseSquareLighting's radius/attenuation constants and the
CalculateRadius / GetAttenuation / SmoothStep math into a new pure header
(Features/InverseSquareLighting/RadiusMath.h, namespace ISLMath). The
functions take only plain floats, so the header compiles standalone into the
cpp_tests binary with no game/RE runtime. The class's static methods now
delegate to it -- call sites (incl. LightEditor) are unchanged. Adds
test_isl_radiusmath.cpp (13 assertions): SmoothStep ramp/clamp,
CalculateRadius closed-form + shadow/override branches + NaN->1 guard,
GetAttenuation peak/vanish/monotonic. Validated: cpp suite + plugin build.

Phase 2 (Tier 2) of the cpp-test expansion; follows #55.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants