Skip to content

feat(dummies): add ContainingEntry to pin a dictionary entry's value#290

Merged
Reefact merged 1 commit into
mainfrom
claude/issue-288-containing-entry
Jul 22, 2026
Merged

feat(dummies): add ContainingEntry to pin a dictionary entry's value#290
Reefact merged 1 commit into
mainfrom
claude/issue-288-containing-entry

Conversation

@Reefact

@Reefact Reefact commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

AnyDictionary.ContainingKey(TKey) forces a key into the generated dictionary, but its value was still drawn arbitrarily from the value generator — so a test could not pin a specific key/value pair. This adds ContainingEntry(TKey, TValue), which pins the value for a required key while leaving the other entries arbitrary.

Closes #288. The method name (ContainingEntry, over Containing(TKey, TValue) or a chained ContainingKey(...).WithValue(...)) was chosen with the maintainer.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Analyzer / diagnostic change
  • Tests
  • Documentation
  • Build / CI / tooling

Changes

  • Add AnyDictionary.ContainingEntry(TKey key, TValue value): it forces the key in exactly as ContainingKey does (so it inherits the out-of-domain cardinality credit) and records key → value in an immutable, comparer-aware map that Generate() consults before falling back to the value generator. With(...) carries the map across later constraints, keeping the recipe immutable.
  • Conflict semantics reuse the existing machinery, no new rule: dictionary keys are distinct, so pinning the same key twice — or an entry and a plain ContainingKey for the same key — fails eagerly with ConflictingAnyConstraintException through the key-distinctness validation already in CollectionState.
  • The factory keeps its three-argument constructor (now delegating to a private four-argument one), so Any.DictionaryOf is untouched.
  • Declare the new member in both per-TFM PublicAPI.Unshipped.txt baselines (netstandard2.0 and net8.0).
  • Add tests: the pinned value surfacing with an out-of-domain key (value proven pinned because it lies outside the value generator's domain), and the duplicate-key conflict (both the two-entry and the entry-plus-ContainingKey forms).

Testing

  • dotnet build FirstClassErrors.sln — Build succeeded, 0 Warning(s), 0 Error(s) (both the netstandard2.0 and net8.0 legs of Dummies; the PublicAPI analyzer is clean).
  • dotnet test FirstClassErrors.sln — full suite not run locally; ran dotnet test Dummies.UnitTests instead: 453 passed (2 new), 0 failed, 0 skipped.
  • Analyzer tests pass (FirstClassErrors.Analyzers.UnitTests) — not run; no analyzer change in this PR.

Documentation

  • Public API / error documentation updated — the new member is declared in the per-TFM PublicAPI.*.txt baselines.
  • README / doc/ updated
  • French translation (doc/handwritten/for-users/README.fr.md) updated if user-facing behavior changed
  • No documentation change required

Architecture decisions

  • No architectural decision in this pull request — an additive method reusing the existing key-containment / cardinality-credit machinery (ADR-0013) and the distinct-key conflict path unchanged.
  • New decision recorded — ADR drafted as Proposed: ADR-____
  • Supersedes an existing ADR — successor proposed, status not flipped: ADR-____
  • ⚠️ Conflicts with an existing ADR — flagged for the maintainer: ADR-____

Related issues

Closes #288.

ContainingKey(TKey) forces a key in, but its value was still drawn
arbitrarily from the value generator, so a test could not pin a specific
key/value pair. Unlike the other containment methods this needed new state:
keys flow through CollectionState, whereas values are generated per key.

Add ContainingEntry(TKey, TValue): it forces the key in exactly as
ContainingKey does (inheriting the out-of-domain cardinality credit) and
records key -> value in an immutable, comparer-aware map that Generate
consults before falling back to the value generator; With carries the map
across later constraints. A duplicate key — two entries, or an entry and a
ContainingKey for the same key — conflicts eagerly through the existing
distinct-key validation, so no new conflict rule is introduced. The factory
keeps its three-argument constructor, which now delegates to a private
four-argument one, so Any.DictionaryOf is untouched.

Declare it in both per-TFM PublicAPI baselines and cover it with tests: the
pinned value surfacing with an out-of-domain key, and the duplicate-key
conflict.

Refs: #288

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RduXUaM3V6tk6MuKxzVzJ
@Reefact
Reefact force-pushed the claude/issue-288-containing-entry branch from b16abc7 to 7003330 Compare July 22, 2026 15:32
@Reefact
Reefact merged commit 40ebd93 into main Jul 22, 2026
16 checks passed
@Reefact
Reefact deleted the claude/issue-288-containing-entry branch July 22, 2026 16:22
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.

Dummies: let AnyDictionary pin the value for a required key

2 participants