Composition
Turning several generators into one — through a factory, a tuple, a closed set of choices, or an optional value.
static class
AnyExtensions
Composition over IAny. These extensions are the bridge between constrained primitives and domain types: a generator of raw values becomes a generator of value objects by going through the type's own factory — no reflection, and the domain's validation stays the single gatekeeper.
public static class AnyExtensionsMethods
IAny<TResult?> As<TSource, TResult>(this IAny<TSource?> generator, Func<TSource?, TResult?> factory) | Derives a generator of TResult by passing each generated TSource through factory — typically a value object's own factory method, so the constraints declared upstream express the invariant that factory enforces. |
|---|
sealed class
AnyOneOf<T>
A generator that draws an arbitrary value from an explicit, fixed pool supplied by the caller — the dummy for a value whose domain is a closed set a test does not assert on (one of the currencies a context is configured with, one of the orders already in a fixture, one of a handful of domain states). Unlike the typed builders' OneOf, which narrows within a scalar's own domain, this draws from values the library could never synthesize on its own. It still composes like any other generator — pipe it through As(...) into a value object, make it optional with OrNull(), or fold it into Combine(...) and the collection generators.
public sealed class AnyOneOf<T>- Implements
IAny<T>, IPoolInspection<T>
Constructed via
static AnyOneOf<T?> Any.OneOf<T>(params T?[] values) | Draws an arbitrary value from an explicit pool of caller-supplied values, over the ambient random context — the top-level choice combinator for a value whose domain is a closed set the test does not assert on ("one of the configured currencies", "one of the states in this table"). The pool is the whole shape of the specification — T is opaque, so the returned generator offers no type-specific constraint, only the exclusion pair Except/DifferentFrom every generator carries — and it composes through As(...), OrNull(), Combine(...) and the collection generators like any other. To draw from a pool already held as a collection, use ElementOf. |
|---|---|
static AnyOneOf<T?> Any.ElementOf<T>(IReadOnlyList<T?> values) | Draws an arbitrary value from an explicit pool held as a list — the IReadOnlyList counterpart of OneOf, for a pool already materialized (a configuration list, a fixture, a lookup table of domain objects). Same contract as OneOf: duplicates collapse, the draw is uniform and reproducible under a seed, and Except/DifferentFrom narrow the pool — Any.ElementOf(orders).DifferentFrom(theOneAlreadyUsed) is the idiom this overload exists for. |
static AnyOneOf<T?> Any.ElementOf<T>(IEnumerable<T?> values) | Draws an arbitrary value from an explicit pool held as a sequence — the IEnumerable counterpart of ElementOf (a LINQ result, values loaded at setup). The sequence is materialized once, so a lazy query is never re-enumerated per draw. |
Methods
AnyOneOf<T?> Except(params T?[] values) | Requires the generated value to be none of the supplied values — they are removed from the pool under Default, so the draw stays a single uniform pick over what is left. May be declared several times; the exclusions accumulate. A value that is not in the pool removes nothing. |
|---|---|
AnyOneOf<T?> DifferentFrom(T? value) | Requires the generated value to differ from value — typically a value the test already holds, to exercise an inequality path while still drawing from the pool (Any.ElementOf(orders).DifferentFrom(theOneAlreadyUsed)). Semantically equivalent to Except; the name carries the intent at the call site. |
T? Generate() | Produces one arbitrary value satisfying every constraint declared on this generator. |
static method
Combine
Composes two generators into one through a constructor lambda — the reflection-free way to assemble an object from constrained parts. Each part draws from its own random context when the composed generator generates.
static IAny<TResult?> Any.Combine<T1, T2, TResult>(IAny<T1?> first, IAny<T2?> second, Func<T1?, T2?, TResult?> compose)Methods
static IAny<TResult?> Any.Combine<T1, T2, TResult>(IAny<T1?> first, IAny<T2?> second, Func<T1?, T2?, TResult?> compose) | Composes two generators into one through a constructor lambda — the reflection-free way to assemble an object from constrained parts. Each part draws from its own random context when the composed generator generates. |
|---|---|
static IAny<TResult?> Any.Combine<T1, T2, T3, TResult>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third, Func<T1?, T2?, T3?, TResult?> compose) | Composes three generators into one through a constructor lambda — see Combine. |
static IAny<TResult?> Any.Combine<T1, T2, T3, T4, TResult>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third, IAny<T4?> fourth, Func<T1?, T2?, T3?, T4?, TResult?> compose) | Composes four generators into one through a constructor lambda — see Combine. |
static IAny<TResult?> Any.Combine<T1, T2, T3, T4, T5, TResult>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third, IAny<T4?> fourth, IAny<T5?> fifth, Func<T1?, T2?, T3?, T4?, T5?, TResult?> compose) | Composes five generators into one through a constructor lambda — see Combine. |
static IAny<TResult?> Any.Combine<T1, T2, T3, T4, T5, T6, TResult>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third, IAny<T4?> fourth, IAny<T5?> fifth, IAny<T6?> sixth, Func<T1?, T2?, T3?, T4?, T5?, T6?, TResult?> compose) | Composes six generators into one through a constructor lambda — see Combine. |
static IAny<TResult?> Any.Combine<T1, T2, T3, T4, T5, T6, T7, TResult>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third, IAny<T4?> fourth, IAny<T5?> fifth, IAny<T6?> sixth, IAny<T7?> seventh, Func<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TResult?> compose) | Composes seven generators into one through a constructor lambda — see Combine. |
static IAny<TResult?> Any.Combine<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third, IAny<T4?> fourth, IAny<T5?> fifth, IAny<T6?> sixth, IAny<T7?> seventh, IAny<T8?> eighth, Func<T1?, T2?, T3?, T4?, T5?, T6?, T7?, T8?, TResult?> compose) | Composes eight generators into one through a constructor lambda — see Combine. Eight is the ceiling; a constructor needing more parts is better assembled from intermediate value objects. |
static class
NullableExtensions
The two ways a value-type generator becomes a generator of Nullable, and they are not the same thing. OrNull yields null on an even coin flip and, otherwise, a value satisfying the constraints declared upstream — the dummy for an optional value-type field (int?, DateTime?, Guid?, an enum, ...). AsNullable never yields null: it widens the type and leaves the values alone, for a parameter that is spelled nullable and still has to be given one.
public static class NullableExtensionsMethods
IAny<T?> OrNull<T>(this IAny<T> generator) where T : struct | Derives a generator that yields null about half the time and, otherwise, a value drawn from generator — so a test exercises both the present and the absent case without pinning either. Reproducible under a seed, like every other draw. |
|---|---|
IAny<T?> AsNullable<T>(this IAny<T> generator) where T : struct | Widens generator to Nullable without changing what it draws — the same values, the wider type, and never null. |
static class
NullableReferenceExtensions
Makes a reference-type generator optionally null — the sibling of OrNull for the reference-type case (a nullable string, or an optional value object produced through As). It lives in its own class because a single overloaded OrNull constrained once to struct and once to class would collide.
public static class NullableReferenceExtensionsMethods
IAny<T?> OrNull<T>(this IAny<T> generator) where T : class | Derives a generator that yields null about half the time and, otherwise, a value drawn from generator — the dummy for an optional reference-type field. |
|---|
static method
PairOf
Composes two generators into a generator of the value tuple (T1, T2) — sugar over Combine for the common case of pairing two arbitrary values.
static IAny<ValueTuple<T1?, T2?>> Any.PairOf<T1, T2>(IAny<T1?> first, IAny<T2?> second)Methods
static IAny<ValueTuple<T1?, T2?>> Any.PairOf<T1, T2>(IAny<T1?> first, IAny<T2?> second) | Composes two generators into a generator of the value tuple (T1, T2) — sugar over Combine for the common case of pairing two arbitrary values. |
|---|
static method
TripleOf
Composes three generators into a generator of the value tuple (T1, T2, T3) — sugar over Combine.
static IAny<ValueTuple<T1?, T2?, T3?>> Any.TripleOf<T1, T2, T3>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third)Methods
static IAny<ValueTuple<T1?, T2?, T3?>> Any.TripleOf<T1, T2, T3>(IAny<T1?> first, IAny<T2?> second, IAny<T3?> third) | Composes three generators into a generator of the value tuple (T1, T2, T3) — sugar over Combine. |
|---|