A fluent API for enforcing design contracts with automatic message generation:
✔️ Easy to use
✔️ Fast
✔️ Production-ready
To get started, add this dependency:
npm install --save @cowwoc/[email protected]
or pnpm:
pnpm add @cowwoc/[email protected]
import {requireThatString} from "@cowwoc/requirements";
class Cake
{
private bitesTaken = 0;
private piecesLeft;
public constructor(piecesLeft: number)
{
requireThat(piecesLeft, "piecesLeft").isPositive();
this.piecesLeft = piecesLeft;
}
public eat(): number
{
++bitesTaken;
assertThat(bitesTaken, "bitesTaken").isNotNegative().elseThrow();
piecesLeft -= ThreadLocalRandom.current().nextInt(5);
assertThat(piecesLeft, "piecesLeft").isNotNegative().elseThrow();
return piecesLeft;
}
public getFailures(): String[]
{
return checkIf(bitesTaken, "bitesTaken").isNotNegative().
and(checkIf(piecesLeft, "piecesLeft").isGreaterThan(3)).
elseGetMessages();
}
}
If you violate a precondition:
const cake = new Cake(-1000);
You'll get:
RangeError: "piecesLeft" must be positive.
actual: -1000
If you violate a class invariant:
const cake = new Cake(1_000_000);
while (true)
cake.eat();
You'll get:
lang.AssertionError: "bitesTaken" may not be negative.
actual: -128
If you violate a postcondition:
const cake = new Cake(100);
while (true)
cake.eat();
You'll get:
AssertionError: "piecesLeft" may not be negative.
actual: -4
If you violate multiple conditions at once:
const cake = new Cake(1);
cake.bitesTaken = -1;
cake.piecesLeft = 2;
const failures = [];
for (const failure of cake.getFailures())
failures.add(failure);
console.log(failures.join("\n\n"));
You'll get:
"bitesTaken" may not be negative.
actual: -1
"piecesLeft" must be greater than 3.
actual: 2
This library offers the following features:
- Automatic message generation for validation failures
- Diffs provided whenever possible to highlight the differences between expected and actual values
- Zero overhead when assertions are disabled for better performance
- Multiple validation failures that report all the errors at once
- Nested validations that allow you to validate complex objects
- String diff that shows the differences between two strings
Designed for discovery using your favorite IDE's auto-complete feature. The main entry points are:
requireThat(value, name)
for method preconditions.assertThat(value, name)
for class invariants, method postconditions and private methods.checkIf(value, name)
for multiple failures and customized error handling.
See the API documentation for more details.
- Use
checkIf().elseGetMessages()
to return failure messages without throwing an exception. This is the fastest validation approach, ideal for web services. - To enhance the clarity of failure messages, you should provide parameter names, even when they are optional.
In other words, favor
assert that(value, name)
overassert that(value)
.
Code licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
Icons made by Flat Icons from www.flaticon.com is licensed by CC 3.0 BY