Skip to content

feat: document and enforce eager validation of named options (#310)#314

Open
seabbs-bot wants to merge 1 commit into
mainfrom
fix/310-eager-option-validation
Open

feat: document and enforce eager validation of named options (#310)#314
seabbs-bot wants to merge 1 commit into
mainfrom
fix/310-eager-option-validation

Conversation

@seabbs-bot

Copy link
Copy Markdown
Collaborator

Summary

Fixes #310. Part of the #307 shared-quality-tooling epic.

Any function that accepts a set of named options -- keyword arguments,
a scenario/backend registry, a set of sweep axes -- should validate
them eagerly and, on an unrecognised name, raise an error naming every
offending key and listing the valid set. A silently-ignored option name
is a latent bug: a caller believes they set a value when they did not,
and the mistake only surfaces (if at all) as a wrong result far from
its cause. The worst case is a sweep axis, where a mistyped name can
send a whole run down the wrong path and only become visible deep
inside it.

The practice already existed here as an exemplar (scaffold's
SUPPORTED_LICENSES check) but was undocumented and unenforced
elsewhere.

What changed

  • test_option_validation(f, valid; n = 50, rng = Random.default_rng())
    (src/quality.jl): fuzzes a validating function f with n random
    names outside valid and asserts each call throws, with a message
    naming the rejected value and listing every entry of valid. A
    package points it at each option-accepting entry point, e.g.
    test_option_validation(k -> configure(; Dict(k => true)...), VALID_KEYS),
    rather than auditing by hand.
  • Extracted the exemplar into a named, directly testable helper
    (_validate_license, src/scaffold.jl, behaviour-preserving) so
    test/qa.jl dogfoods the fuzz helper against the kit's own real
    check, not just a synthetic one.
  • Documented the convention on the
    test-infrastructure docs page,
    citing the exemplar and the new helper, and noting it is wired in
    per-entry-point rather than being part of the generic quality.jl
    testset.
  • Random becomes a new dependency of the main package and the test
    environment (the fuzz helper's default rng).

Test plan

  • task test: full suite green (2524 pass / 8 broken(xfail) / 0 fail)
  • New test_option_validation testset in test/qa.jl: a
    conforming validator passes; a silent-accept validator, a
    message-omits-the-key validator, and a message-omits-a-valid-entry
    validator each correctly fail; a String-flavoured valid set works;
    the real _validate_license/SUPPORTED_LICENSES exemplar passes
  • JuliaFormatter clean
  • Independent pre-PR-checks subagent re-verification: format,
    isolated formatting env, full suite (matches exactly), and quality
    gates (Aqua/ExplicitImports/JET/doctests/docstrings/README/extension
    ambiguities) all pass

This was opened by a bot. Please ping @seabbs for any questions.

Any function that accepts a set of named options -- keyword arguments,
a scenario/backend registry, a set of sweep axes -- should validate
them eagerly and, on an unrecognised name, raise an error naming every
offending key and listing the valid set. A silently-ignored option name
is a latent bug: a caller believes they set a value when they did not,
and the mistake only surfaces (if at all) as a wrong result far from
its cause. The practice already existed here as an exemplar (scaffold's
SUPPORTED_LICENSES check) but was undocumented and unenforced.

Add `test_option_validation(f, valid; n, rng)` (src/quality.jl): fuzzes
a validating function `f` with random names outside `valid` and asserts
each call throws, naming the rejected value and listing every valid
entry. A package points it at each option-accepting entry point (e.g.
`test_option_validation(k -> configure(; Dict(k => true)...),
VALID_KEYS)`) instead of auditing by hand.

Extract the exemplar into a named, directly testable helper
(`_validate_license`, src/scaffold.jl) so `test/qa.jl` can dogfood the
fuzz helper against the kit's own real check, not just a synthetic
one. Document the convention on the test-infrastructure docs page,
citing the exemplar and the new helper.

`Random` becomes a new dependency of the main package and test
environment (the fuzz helper's default `rng`).

Co-authored-by: Sam Abbott <contact@samabbott.co.uk>
@github-actions

Copy link
Copy Markdown
Contributor

Try this Pull Request!

Option 1: Julia Package Manager

Open Julia and type:

import Pkg
Pkg.activate(temp=true)
Pkg.add(url="https://github.com/EpiAware/EpiAwarePackageTools.jl", rev="fix/310-eager-option-validation")
using EpiAwarePackageTools

Option 2: Local Checkout

If you have the repo locally:

git checkout fix/310-eager-option-validation
julia --project=. -e "using Pkg; Pkg.instantiate()"

@github-actions

Copy link
Copy Markdown
Contributor

📖 Documentation preview is ready!

View the docs for this PR at: https://EpiAware.github.io/EpiAwarePackageTools.jl/previews/PR314/

This preview will be updated automatically when you push new commits.

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.10345% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/quality.jl 92.00% 2 Missing ⚠️
Flag Coverage Δ
unit 94.79% <93.10%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/EpiAwarePackageTools.jl 100.00% <ø> (ø)
src/scaffold.jl 99.44% <100.00%> (+<0.01%) ⬆️
src/quality.jl 92.07% <92.00%> (-0.02%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

Document and auto-enforce eager validation of named options

1 participant