feat(dummies): add terminal Any.String().OneOf for explicit value sets - #275
Merged
Conversation
Any.String() had no way to draw from a fixed, closed list of values — the dummy for a domain that is a short enumeration (a currency code, a well-known name) rather than a structural shape. The scalar generators offer a composable OneOf; strings now get a terminal one. OneOf(params string[]) returns AnyStringOneOf, a terminal IAny<string> mirroring StringMatching (ADR-0025): the value set is the whole specification, so it exposes no shape, length or character constraints and rejects being declared after another constraint with a ConflictingAnyConstraintException. Values are deduplicated and drawn uniformly from the seedable source, so a run replays under a seed, and AnyStringOneOf advertises ICardinalityHint<string> so a distinct collection over it is gated eagerly by its cardinality (ADR-0013). Adds unit tests, the package README entry, and ADR-0030 (Proposed, EN and FR). No new dependency: the zero-dependency architecture test and the whole solution build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JxSJGauajxuFBot4NsHdn
The terminal Any.String().OneOf so far took only params string[]. A set held as a sequence — a List, a LINQ result, values loaded at test setup — had to be materialized with ToArray at the call site. Add an IEnumerable<string> overload that delegates to the params one, so all validation, deduplication and the terminal contract stay in a single place. Overload resolution is unambiguous: a string[] argument still binds to the more specific params overload (including OneOf(null!)), so no existing call changes. Covered by tests for the sequence path, its argument validation, and its terminal conflict. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JxSJGauajxuFBot4NsHdn
The maintainer accepted the decision recorded in ADR-0030 (draw arbitrary strings from an explicit, terminal value set). Flip its status from Proposed to Accepted in the English and French records and in the index. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JxSJGauajxuFBot4NsHdn
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
Add
Any.String().OneOf(...), a terminal string generator that draws from an explicit, fixed set of caller-supplied values — the dummy for a value whose domain is a short, closed list (a currency code, a well-known name) rather than a structural shape. It complementsAny.StringMatching, filling the one string-generation gap that previously forced a hand-written array or a foreign library.Type of change
Changes
AnyString.OneOf(params string[])and anIEnumerable<string>overload, returningAnyStringOneOf— a new terminalIAny<string>generator that mirrorsAnyPattern/StringMatching: the value set is the whole specification, so it exposes no shape, length or character constraints, and rejects being declared after another constraint with aConflictingAnyConstraintException.AnyStringOneOfimplements the internalICardinalityHint<string>, so a distinct collection over it (SetOf, dictionary keys) is gated eagerly by its cardinality (ADR-0013).StringSpec.IsUnconstrainedmarker that enforces the terminal contract.Dummies.UnitTests/AnyStringOneOfTests.cs: draw domain, dedup, variety, reproducibility,As/OrNull/SetOfcomposition, terminal conflicts, argument validation, and the sequence overload.Dummiespackage README.Testing
dotnet build FirstClassErrors.sln— 0 warnings, 0 errors (netstandard2.0 + net8.0).dotnet test FirstClassErrors.sln— every project green, 0 failed (Dummies.UnitTests: 253 passed).FirstClassErrors.Analyzers.UnitTests) — 132 passed (untouched, run as part of the solution).Documentation
doc/updateddoc/handwritten/for-users/README.fr.md) updated if user-facing behavior changedNote: the
Dummiespackage ships an English-only package README (there is noREADME.fr.mdfor it); ADR-0030 carries its own French translation per the ADR bilingual convention.Architecture decisions
Proposed: ADR-0030The terminal-vs-composable choice for the string
OneOfmirrors ADR-0025. Drafted asProposed, then accepted by the maintainer (@Reefact) in the originating session, so ADR-0030 is committed asAccepted.Related issues
None.
🤖 Generated with Claude Code
https://claude.ai/code/session_011JxSJGauajxuFBot4NsHdn
Generated by Claude Code