Skip to content

Nullean.Entities 0.1.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 17:05
d5fcf02

Nullean.Entities 0.1.0

Types say what a thing is. Nothing says what it must do.

Nullean.Entities makes business rules first-class: a rule is a named value, declared once next to the type, and that one declaration validates a value, is tested automatically on generated data, and can watch live events. This is the first release. Docs: https://entities.nullean.net/getting-started/

What you get

  • Rules as named values. Constraint<T> and ConstraintSet<T>, with Always, When/Requires, Transitions, Idempotent, Monotonic, Conserves, OrderIndependent, Unique, References and deadline and liveness rules for event streams. [Constraints] gathers the rules on a type into one generated set, so a rule you add cannot be forgotten.
  • Tests you do not write. AutoTest.For(rules, ...) runs one test per axis the rules declare, on nine axes: invariants, idempotency, monotonicity, conservation, absence, deadlines, liveness, order independence, and a check that the tests reached the rules at all (a test that never exercised a rule fails as vacuous).
  • Records, services and mutable classes. The same AutoTest runs on immutable records and on services changed in place (Mutate / MutateAsync), awaits async operations, and never blocks on a task.
  • Failures that read like an incident report. The rule that broke, the operation, the state before and after, the law and what it costs, and a seed that replays the smallest case found.
  • Relations declared once. Relation.Reference and Relation.Unique build the rule and tell the data generator which members it relates, so the two cannot drift apart.
  • Adopt gradually. A rule can start as a warning and become an error on a date you choose.

Packages

Package For
Nullean.Entities The rules, Result<T>, state machines and the [Constraints] source generator (bundled). No dependency on a test library or on Rx.
Nullean.Entities.Reactive Temporal and structural rules over IObservable<TEvent> streams
Nullean.Entities.FileSystem File rules over System.IO.Abstractions
Nullean.Entities.Extensions.DependencyInjection Constraint sets in Microsoft.Extensions.DependencyInjection
Nullean.Entities.AspNetCore A 400 ValidationProblem keyed by member, from violations
Nullean.Entities.Argh Validate the options a Nullean.Argh command receives
Nullean.Entities.CsCheck The generated tests, on CsCheck. Tests only.
Nullean.Entities.CsCheck.Reactive Rx scheduler terminals for the CsCheck package (opt-in)
Nullean.Entities.CsCheck.FileSystem A mock file system in generated data
Nullean.Entities.CsCheck.AutoBogus Bogus and AutoBogus generators that route their draws through CsCheck so seeds replay

All target net10.0 and net11.0. The core, Reactive, FileSystem, DependencyInjection, AspNetCore and Argh packages are trim and native-AOT clean (CI publishes a native AOT smoke app on Linux, macOS and Windows); the CsCheck packages rely on reflection and are for tests only.

Start here

[Constraints]
public static partial class OrderConstraints
{
    public static readonly Constraint<Order> TotalNeverNegative = Constraints<Order>.Always(o => o.Total >= 0, "An order total is never negative.");
    public static readonly Constraint<Order> CancelIsRepeatable = Constraints<Order>.Idempotent(o => o.Cancel());
    public static readonly Constraint<Order> VersionNeverGoesBack = Constraints<Order>.Monotonic(o => o.Version, MonotonicDirection.NonDecreasing);
}

await AutoTest.For(OrderConstraints.Instance, orders).RunAsync();

Getting started · The nine axes · Services and mutable classes · Rolling out a rule

Good to know

  • Versions are 0.x: the API can still change between minor versions.
  • 0.1.0-preview.1 was published without the source generator, so [Constraints] did nothing; use 0.1.0-preview.2 or later.
  • MIT licensed.