Test coverage + GitHub Actions CI (x64 & ARM64), fix blank hostname error#132
Merged
Merged
Conversation
…stname error Raise HostsFileEditor.Core coverage from ~75% to ~88% line / ~84% branch / ~95% method by driving the previously-untested code paths: - Exercise the headless CLI (HostsCli.Run) end-to-end — list/apply/enable/ disable/import/merge plus the top-level catch branches — against the HostsFile.Instance singleton, bound to a temp file via the sanctioned HFE_HOSTS_PATH override in an [AssemblyInitialize] (TestAssemblyInit) so no test ever touches the real hosts file. - Cover the small classes (exceptions, PrivilegedFileOperations helper selection, FileOpener registered-app resolution, NativeMethods, Resources, ConsoleAttach early-return) and the remaining HostsFile / HostsEntry / HostsEntryList / HostsArchive branches. - The uncovered remainder is deliberately left: the runas UAC escalation, native comdlg32 dialogs, process spawn/kill, and the one-time archive migration — all side-effectful and unsafe to unit-test. Add HostsFileEditor.WinForm.Tests covering the classic edition's HostsFilter (the modern edition's logic is covered by its build gate; a WinUI unit-test project was infeasible — the WinAppSDK testhost won't launch). Add .github/workflows/ci.yml gating every PR (and pushes to master) on a build + full test run across x64 (windows-latest) and ARM64 (windows-11-arm). Fix #131: add the missing InvalidHostnames key to Core's Resources.resx so an invalid hostname surfaces a real IDataErrorInfo message instead of a blank one (the strongly-typed getter previously resolved to null). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rdening - Fix cross-test flakiness: HostsEntry.Ping() is fire-and-forget and mutates the process-global ping counter / PingActivityChanged on a thread-pool continuation. Ping-starting test classes now drain in-flight pings in cleanup so they can't leak into (and flake) the ping-activity assertions here or in the pre-existing PingActivity_RaisesOnZeroBoundaryOnly. - CI: pass an explicit RuntimeIdentifier (win-arm64 on the arm64 leg) to the WinForm/WinUI builds — both projects default RID to win-x64 regardless of Platform, so the arm64 leg was silently building x64 and never validating arm64. - ConsoleAttach test: snapshot/restore Console.Out/Error so the rare attach-and-rebind path can't corrupt another test's output capture. - Elevation-helper stub test: defensively clear a leftover stub so the no-helper case is order-independent. - Replace a tautological HostsFilter test (compared the method to its own body) with concrete expected values that actually catch a wiring bug. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
scottlerch
marked this pull request as ready for review
July 14, 2026 20:10
scottlerch
added a commit
that referenced
this pull request
Jul 14, 2026
) The strongly-typed Resources.InvalidHostnames getter existed but Core's Resources.resx had no matching <data name="InvalidHostnames"> entry, so it resolved to null. HostsEntry.ValidateHostnames does `SetError(nameof(HostNames), !_hostnamesValid ? Resources.InvalidHostnames : null)` and SetError treats null as "clear the error", so an invalid hostname surfaced a BLANK IDataErrorInfo message in both the classic and modern editions instead of "Invalid host names". Add the key ("Invalid host names", matching the WinForm resource) plus a regression test asserting the invalid-hostname error message is the non-empty resource string. Split out of the larger CI/coverage PR #132 so the user-facing fix can land on its own. Closes #131 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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
Raises unit-test coverage for the shared core and headless CLI, adds a GitHub Actions CI workflow that gates PRs on both x64 and ARM64, and fixes a latent resource bug found along the way.
Coverage (
HostsFileEditor.Core)192 → 286 Core tests. Highlights:
HostsCli51.6% → 98.8%,HostsFile70% → 92%,HostsEntry78% → 95%,HostsEntryList→ 100%, and several classes to 100%.The enabling piece is
TestAssemblyInit: an[AssemblyInitialize]binds theHostsFile.Instancesingleton to a temp file via the sanctionedHFE_HOSTS_PATHoverride before anything touches it, so the fullapply/enable/disable/import/mergeflow (andRun's catch branches, via a throwingIPrivilegedFileOperations) is exercised without ever touching the real hosts file.The uncovered remainder is deliberate — all side-effectful and unsafe/impractical to unit-test: the
runasUAC escalation helper, nativecomdlg32file dialogs, the process-spawning file opener,ShowFirstInstance(kills the process), and the one-time legacy-archive migration.UI tests
New
HostsFileEditor.WinForm.Testscovers the classic edition'sHostsFilter(delegates the three filter rules to Core's canonicalMatchesFilter). A WinUI unit-test project was attempted forSelectionStateServicebut dropped — the WinAppSDK testhost won't launch (self-contained testhost, missinghostpolicy.dll); the modern edition is covered by its compile gate, and shared logic already lives in Core.CI —
.github/workflows/ci.ymlRuns on every PR and on pushes to
master. Matrix over x64 (windows-latest) and ARM64 (windows-11-arm): builds Core/CLI/Elevate/WinForm + WinUI (-p:Platform=<arch>), runs the full test suite with OpenCover coverage, posts a coverage summary to the job summary, and uploads results. WinForm UI tests run on the x64 leg only (the project pins RIDwin-x64).Bug fix — closes #131
Resources.InvalidHostnames(Core) had no matching key inResources.resx, so the strongly-typed getter resolved to null — an invalid hostname surfaced a blankIDataErrorInfomessage in both editions. Added the key ("Invalid host names", matching the WinForm value) plus regression coverage.Test plan
dotnet test HostsFileEditor.Core.Tests— 286 passing (Release)dotnet test HostsFileEditor.WinForm.Tests— 5 passing (Release)🤖 Generated with Claude Code