Skip to main content
Version: 0.3.x (0.3.0)

Class ValueObjectSampler

Namespace: AdCodicem.ValueObjects.Testing.Data
Assembly: AdCodicem.ValueObjects.Testing.Data.dll

Draws value objects their own rules accept, from the schema they declare: test data that never restates a rule the type already holds.

public sealed class ValueObjectSampler

Inheritance​

object ← ValueObjectSampler

Inherited Members​

object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.ReferenceEquals(object?, object?), object.ToString()

Remarks​

A candidate comes from TSelf.Schema. A closed value set gives one of its known values, an open one gives a known value part of the time (). A string gets a length between MinLength and MaxLength; without a maximum, at most characters beyond the shortest it can be, its MinLength, the shortest match of its pattern, or one character when it declares neither. The pattern the type declares fills it: drawn from the pattern when it is inside the subset the built-in sampler reads, padded at an end no anchor holds when its matches are too short, and otherwise drawn by rejection sampling, from the pattern read without its lookarounds and with its categories reduced to printable ASCII, or from ASCII letters and digits, and kept only once the pattern matches. A number, a date, a time or a duration gets a value between Minimum and Maximum, or across the type's own range on a side left open; a character keeps to printable ASCII there, unless the bound declared on the other side lies beyond it, where the open side runs to the type's own extreme. A and a are drawn as they are. A generator registered with replaces all of that for its type.

Each candidate then goes through TSelf.TryCreate, so the normalizer and the validators apply and nothing the type refuses comes out. After candidates, the sampler falls back on the example the type declares, and failing that throws a that shows the registration to add, or names the registered generator whose values the type refused. A rule no schema carries, a checksum for one, makes most candidates fail: the example then comes out most of the time, which a generator registered for the type avoids.

A sampler is as thread-safe as the it draws from: is, a created with a seed is not, and replays the same values given the same calls. The typed members read TSelf.Schema and never the registry.

Constructors​

ValueObjectSampler(Random, ValueObjectSamplerOptions?)​

Initializes a new instance of the class.

public ValueObjectSampler(Random random, ValueObjectSamplerOptions? options = null)

Parameters​

random Random

The source of randomness: , or a created with a seed to replay a run.

options ValueObjectSamplerOptions?

How it draws, or null for the defaults.

Exceptions​

ArgumentNullException

random is null.

Methods​

Boundaries<TSelf, TValue>()​

Gets the accepted values at the edges the schema declares: its Minimum and Maximum, a string of its MinLength (the empty string without one) and of its MaxLength, and each known value, each once its rules accept it, normalized and without repeats.

public IEnumerable<TValue> Boundaries<TSelf, TValue>() where TSelf : struct, IValueObject<TSelf, TValue>

Returns​

IEnumerable<TValue>

The values, in that order; none for a schema that declares no edge.

Type Parameters​

TSelf

The value object.

TValue

Its underlying type.

Remarks​

A property over a wide type lands on its edges by chance once in a blue moon: draw these as well.

Next<TSelf, TValue>()​

Draws a value the type accepts: a candidate built from its schema, kept only once its rules accept it, or the example it declares once no candidate passed.

public TSelf Next<TSelf, TValue>() where TSelf : struct, IValueObject<TSelf, TValue>

Returns​

TSelf

The value object.

Type Parameters​

TSelf

The value object.

TValue

Its underlying type.

Exceptions​

ValueObjectSamplingException

No candidate, drawn from the schema or from the generator registered for the type, passed its rules, and it declares no example they accept.

Next(ValueObjectDescriptor)​

Draws a value of a value object known only by its descriptor, as draws it, closed over the descriptor's type arguments through its visitor.

public object Next(ValueObjectDescriptor descriptor)

Parameters​

descriptor ValueObjectDescriptor

The descriptor, as ValueObjectRegistry holds it.

Returns​

object

The value object, boxed.

Exceptions​

ArgumentNullException

descriptor is null.

ValueObjectSamplingException

No candidate, drawn from the schema or from the generator registered for the type, passed its rules, and it declares no example they accept.

RejectedValues<TSelf, TValue>()​

Gets values the schema rules out, each with the rule it breaks: a string one character shorter than its MinLength and the empty string, one character longer than its MaxLength, a value one step below its Minimum and one above its Maximum, and a value outside its closed value set.

public IEnumerable<SchemaViolation<TValue>> RejectedValues<TSelf, TValue>() where TSelf : struct, IValueObject<TSelf, TValue>

Returns​

IEnumerable<SchemaViolation<TValue>>

The values; none for a schema that rules nothing out.

Type Parameters​

TSelf

The value object.

TValue

Its underlying type.

Remarks​

A string of the wrong length is otherwise drawn as the pattern asks, so that its length alone breaks a rule, and drawn again while the type's normalizer brings it back to a right length, a trimmed space for one. The empty string is derived only beside a MinLength of 2 or more, since the schema does not say whether a type without one accepts it. A step is one unit of the bound's last written digit for a , one unit in the last place for a binary floating-point number, one tick for a date, a time or a duration, and one day for a ; no step is taken past the type's own extremes. A value outside a closed set is drawn from the rest of the schema, and compared with the known values once normalized, ignoring case for a string.

A type whose normalizer clamps a value into its rules, rather than its validator refusing it, accepts some of these: a number past a bound, or a string its normalizer cuts or pads to its lengths whatever the draw.

Shrink<TSelf, TValue>(TSelf, Func<TValue, IEnumerable<TValue>>?)​

Proposes simpler values the type accepts than one it holds, for a property-based testing library to shrink a counterexample to: the values its schema declares, its Minimum, its first known value and its example, then the shrinks of the underlying value the type accepts as they are.

public static IEnumerable<TSelf> Shrink<TSelf, TValue>(TSelf value, Func<TValue, IEnumerable<TValue>>? shrinkUnderlying = null) where TSelf : struct, IValueObject<TSelf, TValue>

Parameters​

value TSelf

The value to shrink.

shrinkUnderlying Func<TValue, IEnumerable<TValue>>?

The shrinker of the underlying type, or null to propose the declared values alone.

Returns​

IEnumerable<TSelf>

The proposals, none equal to the value or to one another.

Type Parameters​

TSelf

The value object.

TValue

Its underlying type.

Remarks​

A shrink of the underlying value is proposed only when the type accepts it and its normalizer leaves it unchanged: a normalizer maps a shrink to a value that may be no simpler, as upper-casing maps the 'b' a character shrinks to back to 'B', and two values would then shrink to each other until the library gives up.

The declared values are ranked in that order, and from one of them only those ranked before it are proposed, and no shrink of its underlying value: every chain of shrinks ends wherever the chains of the underlying shrinker end.

TryNext<TSelf, TValue>(out TSelf, out ValidationResult)​

Draws a value the type accepts, or reports why none could be drawn: the refusal of the last candidate, or no refusal when the schema gave no candidate at all.

public bool TryNext<TSelf, TValue>(out TSelf value, out ValidationResult refusal) where TSelf : struct, IValueObject<TSelf, TValue>

Parameters​

value TSelf

The value object, or default when none could be drawn.

refusal ValidationResult

when a value was drawn; otherwise the refusal of the last candidate, or again when the schema gave none.

Returns​

bool

true when a value was drawn.

Type Parameters​

TSelf

The value object.

TValue

Its underlying type.