Skip to content

feat(dummies): add OrNull for optional value and reference generators - #176

Merged
Reefact merged 1 commit into
mainfrom
claude/dummies-nullable
Jul 18, 2026
Merged

feat(dummies): add OrNull for optional value and reference generators#176
Reefact merged 1 commit into
mainfrom
claude/dummies-nullable

Conversation

@Reefact

@Reefact Reefact commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

Adds .OrNull() to the Dummies DSL: it turns any generator into one that yields null about half the time and otherwise a value satisfying the upstream constraints — the dummy for an optional field.

Type of change

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

Changes

  • .OrNull() extension over IAny<T>, in two overloads: value types (where T : struct, returning IAny<T?> over Nullable<T>) and reference types (where T : class). They live in separate classes (NullableExtensions, NullableReferenceExtensions) because a single OrNull constrained once to struct and once to class would collide; at a call site exactly one applies, so .OrNull() reads uniformly on any generator.
  • The null-versus-value decision is an even coin flip drawn from the wrapped generator's own random context, so a run stays reproducible under a seed and a null draw does not consume a value from the wrapped generator.
  • Chaining .OrNull() twice is a compile-time error by construction — a Nullable<T> is neither a struct nor a class, so neither overload applies.
  • Tests: new AnyNullableTests (both overloads yield both cases and honour the inner constraints, composition with As for an optional value object, seed reproducibility, argument validation); the seed reproducibility batch gains a nullable draw.
  • Docs: NuGet readme gains an "optional values" bullet.

Testing

  • dotnet build FirstClassErrors.sln — succeeded, 0 warnings (both netstandard2.0 and net8.0 legs).
  • dotnet test FirstClassErrors.sln — all green (Dummies 150; FCE 423; Analyzers 85; GenDoc 155; PropertyTests 21; Binder 76; Cli 64).
  • Analyzer tests pass (FirstClassErrors.Analyzers.UnitTests) — ran as part of the full suite above.

Documentation

  • Public API / error documentation updated — full XML docs on the two overloads.
  • README / doc/ updated — Dummies/README.nuget.md.
  • French translation (doc/handwritten/for-users/README.fr.md) updated if user-facing behavior changed
  • No documentation change required

The handwritten EN/FR user guides stay deferred until the V1 surface stabilizes (ADR-0011 follow-up); only the packaged NuGet readme is kept current here.

Architecture decisions

  • No architectural decision in this pull request
  • 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-____

The 50/50 null rate is a deliberate, realism-free default (the library surfaces hidden dependencies rather than modelling how often a field is present); a probability-tuning overload was considered and intentionally left out to keep the API free of randomness knobs — addable later, non-breaking, if a concrete need appears.

🤖 Generated with Claude Code


Generated by Claude Code

.OrNull() wraps any IAny<T> into a generator that yields null about half
the time and otherwise a value satisfying the upstream constraints — the
dummy for an optional field. Two overloads cover value types (returning
IAny<T?> over Nullable<T>) and reference types; they live in separate
classes because a single OrNull constrained once to struct and once to
class would collide. The null-versus-value decision draws from the
wrapped generator's own random context, so a run stays reproducible and
a null draw does not consume a value.

Tests cover both cases, composition with As (an optional value object),
seed reproducibility, and argument validation; the reproducibility batch
gains a nullable draw. README notes the feature. Full suite green on
both target legs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhPrBqngpiSwdsF4DWvNPw
@Reefact
Reefact merged commit 038e76c into main Jul 18, 2026
13 checks passed
@Reefact
Reefact deleted the claude/dummies-nullable branch July 18, 2026 10:47
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.

2 participants