Skip to content

Extract RuntimeVersion for upgrade testing#85

Closed
jpasichnyk wants to merge 8 commits into
Cleric-K:masterfrom
jpasichnyk:extract-runtime-version-for-upgrade-testing
Closed

Extract RuntimeVersion for upgrade testing#85
jpasichnyk wants to merge 8 commits into
Cleric-K:masterfrom
jpasichnyk:extract-runtime-version-for-upgrade-testing

Conversation

@jpasichnyk
Copy link
Copy Markdown
Contributor

@jpasichnyk jpasichnyk commented Mar 25, 2026

Summary

  • Extract Configuration.RuntimeVersion behind a virtual property to enable DoUpgrade unit testing
  • Add root-level solution file with all projects
  • Add ConfigurationUpgradeTests (339 lines)
  • Fix build for modern MSBuild (SDK 9.0+) with old-style csproj: ship System.Resources.Extensions + transitive deps in Lib/
  • Fix crash on startup when ScpVBus driver is not installed

Test plan

  • CI passes (build + 205+ tests on windows-latest)
  • App launches in Rider without errors
  • vJoy joystick enumeration works without ScpVBus driver

🤖 Generated with Claude Code

jpasichnyk and others added 8 commits March 19, 2026 11:01
* Add test project with axis mapping and configuration tests

- Add vJoySerialFeeder.Tests project (NUnit, SDK-style, targeting net48)
- Add AxisParametersTests: 11 tests covering linear mapping, clamping,
  invert, symmetric mode, deadband, expo curves, and invalid parameters
- Add ConfigurationTests: 11 tests covering JSON round-trip for profiles
  with all mapping types, serial parameters, global options, profile
  CRUD, merge with conflict resolution, and ProfilesEqual
- Add Directory.Build.props for cross-platform .NET Framework reference
  assemblies
- Update CI workflow to run tests after build
- Update CLAUDE.md and AGENTS.md with test documentation

Tests build and run on Windows only (CI) due to WinForms project
dependency. This constraint goes away after the UI/logic decoupling work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add .gitignore and remove tracked obj/ files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix Configuration tests failing in test runner context

Assembly.GetEntryAssembly() returns null under test hosts (NUnit),
causing NullReferenceException in Configuration constructor. Add null
guard with fallback to version 0.0.0.0. Also remove duplicate
Microsoft.NETFramework.ReferenceAssemblies from test csproj (already
provided by Directory.Build.props).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add test project with axis mapping and configuration tests

- Add vJoySerialFeeder.Tests project (NUnit, SDK-style, targeting net48)
- Add AxisParametersTests: 11 tests covering linear mapping, clamping,
  invert, symmetric mode, deadband, expo curves, and invalid parameters
- Add ConfigurationTests: 11 tests covering JSON round-trip for profiles
  with all mapping types, serial parameters, global options, profile
  CRUD, merge with conflict resolution, and ProfilesEqual
- Add Directory.Build.props for cross-platform .NET Framework reference
  assemblies
- Update CI workflow to run tests after build
- Update CLAUDE.md and AGENTS.md with test documentation

Tests build and run on Windows only (CI) due to WinForms project
dependency. This constraint goes away after the UI/logic decoupling work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add .gitignore and remove tracked obj/ files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix Configuration tests failing in test runner context

Assembly.GetEntryAssembly() returns null under test hosts (NUnit),
causing NullReferenceException in Configuration constructor. Add null
guard with fallback to version 0.0.0.0. Also remove duplicate
Microsoft.NETFramework.ReferenceAssemblies from test csproj (already
provided by Directory.Build.props).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add ButtonParameters and CRC-8 tests with Docker test runner

Add tests for ButtonMapping.ButtonParameters.Transform() covering
single/dual threshold, invert, trigger flag interaction, and edge
cases. Add tests for Crc8 class covering CRC-8/DVB-S2 standard
vectors, reset behavior, determinism, and polynomial correctness.

Add Dockerfile.tests for local test execution on Linux via Mono +
.NET SDK, and .dockerignore to reduce build context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add test coverage expansion plan (no refactoring)

Plan covers ~87 new tests across 6 chunks: mapping clamp/copy/failsafe,
protocol reader properties, VJoyNone, and configuration edge cases.
All testable without modifying application source code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add comprehensive test coverage for mappings, protocols, and config

New test files:
- MappingClampTests: Output clamping for Axis/Button/ButtonBitmap (17 tests)
- MappingCopyTests: Copy() field preservation and independence (10 tests)
- MappingFailsafeTests: Failsafe behavior for all mapping types (14 tests)
- ProtocolReaderPropertiesTests: Serial params, names, configurable
  for all 9 protocol readers (27 tests)
- VJoyNoneTests: Null-object joystick no-op verification (8 tests)

Extended ConfigurationTests with ButtonBitmapMapping round-trip,
mixed mapping types, edge cases, and default value assertions (12 tests).

Total: 157 tests (was 69), all passing. Zero application code changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add behavior-pinning tests for edge cases and implicit behaviors

AxisParametersBehaviorTests: deadband ignored without Symmetric,
deadband=100 nearly all center, negative deadband ignored, asymmetric
center scaling, expo at boundaries, expo+deadband interaction,
invert+symmetric keeps center at 0.5, Min==Max returns zero.

MappingPipelineTests: Input→Output pipeline through actual Mapping
classes, ButtonBitmapMapping bit-level Invert via Transform, disabled
bits pass through unchanged, Copy() does not carry Input/Output/Removed.

ConfigurationBehaviorTests: null/empty/wrong-shape JSON handling
(including DataContract returning null Profiles on array input),
unknown fields ignored, Unicode round-trip, Upgrade() always returns
false in test context with various version strings, merge edge cases,
ProfilesEqual order-sensitivity, Version field serialization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DataContractJsonSerializer bypasses field initializers, so deserializing
JSON without a Profiles key (e.g. "[]" or "{}") left Profiles as null.
Add an [OnDeserialized] callback to default Profiles to an empty dictionary.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Expose internal methods for testing via InternalsVisibleTo

Add InternalsVisibleTo attribute and change private → internal on
parseConfig/buildConfig (6 readers), CrsfReader.map, and
DjiControllerReader.remap. Add 53 new tests covering config parsing
round-trips and range mapping math, bringing total to 258.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix CLAUDE.md brace style (K&R → Allman) and add Sbus/Fport edge case tests

The codebase uses Allman braces throughout; CLAUDE.md incorrectly said
K&R. Also add missing "unknown tokens ignored", "reversed order
normalization", and "only unknown tokens" tests for SbusConfigTests and
FportConfigTests to match IbusConfigTests parity (6 new tests, 264 total).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix CS0108 warnings: add 'new' to FportReader.parseConfig/buildConfig

FportReader inherits from SbusReader. Now that both have internal
parseConfig/buildConfig, the compiler warns about hiding. Adding 'new'
makes the intentional hiding explicit and eliminates the warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce ITimeProvider interface so TriggerState can receive a time
source via constructor injection instead of calling MainForm.Now
directly. This enables precise time control in tests without changing
any runtime behavior — the parameterless constructor still delegates
to MainForm.Instance.

- Add ITimeProvider interface (double Now property)
- Make MainForm implement ITimeProvider via explicit interface member
- Add ITimeProvider constructor to TriggerState, keep parameterless
  constructor for backward compatibility
- Add ITimeProvider.cs to both Windows and Linux csproj files
- Add TestTimeProvider mock and 17 TriggerState tests covering edge
  detection, pulse duration, duration=0, timer reset, and re-trigger

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace per-worktree AGENTS.workstream.md references with STACKMUX.md
header in AGENTS.md and CLAUDE.md. Add StackMux generated files to
.gitignore.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Feature:
- Extract Configuration.RuntimeVersion behind a virtual property to
  enable DoUpgrade unit testing
- Add root-level solution file with all projects
- Add ConfigurationUpgradeTests (339 lines)

Build fixes for modern MSBuild (SDK 9.0+) with old-style csproj:
- Add System.Resources.Extensions + 8 transitive deps to Lib/ for
  .resx non-string resource serialization
- Add binding redirects in app.config for assembly version mismatches
- Scope PackageReference in Directory.Build.props to SDK-style projects

Bug fix:
- Handle missing ScpVBus driver gracefully in VJoyVXBox.GetJoysticks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jpasichnyk
Copy link
Copy Markdown
Contributor Author

sorry, this was supposed to be against my fork for now...

@jpasichnyk jpasichnyk closed this Mar 25, 2026
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