Skip to content

NexusPHP/assert

Repository files navigation

Nexus Assert

Unit Tests Static Code Analysis

This library provides efficient type assertions for input validation in a chainable, fluent, natural language way. This also provides static analysis support ensuring PHPStan can understand the asserted type.

Installation

composer require nexusphp/assert

Installing the PHPStan extension

You're all set if you are using phpstan/extension-installer.

Manual installation

If you don't want to use phpstan/extension-installer, include extension.neon in your project's PHPStan config:

includes:
    - vendor/nexusphp/assert/extension.neon

Usage

Use the static that() method of Nexus\Assert\Assert to start chaining expectations.

<?php

use Nexus\Assert\Assert;

function test(mixed $a, mixed $b, mixed $c): void
{
    Assert::that($a)->isString();
    // $a is now understood as string

    Assert::that($b)->isString()->isNumeric();
    // $b is now understood as numeric string

    Assert::that($c)->isInt()->not()->isNegativeInt();
    // $c is understood as int<0, max>
}

When an expectation fails, the method call will throw a Nexus\Assert\ExpectationFailedException object with the message formatted depending on the available context. By default, there are two available context:

Name Description
value The exported value of the argument passed to that()
type The exported type of the argument passed to that()

List of Expectations

Methods Available Context
contains(string $needle, ?string $message = null): self value, needle
endsWith(string $needle, ?string $message = null): self value, needle
hasMethod(string $method, ?string $message = null): self value+, method=
hasOffset(int|string $key, ?string $message = null): self value, key=
hasProperty(string $property, ?string $message = null): self value+, property=
isArray(?string $message = null): self value, type
isArrayKey(?string $message = null): self value, type
isBool(?string $message = null): self value, type
isCallable(?string $message = null): self value, type
isCountable(?string $message = null): self value, type
isFalse(?string $message = null): self value, type
isFloat(?string $message = null): self value, type
isIdentical(mixed $other, ?string $message = null): self value, other, type
isInstanceOf(object|string $class, ?string $message = null): self value, class, type
isInt(?string $message = null): self value, type
isIterable(?string $message = null): self value, type
isList(?string $message = null): self value, type
isLowercaseString(?string $message = null): self value, type
isMap(?string $message = null): self value, type
isNaturalInt(?string $message = null): self value, type
isNegativeInt(?string $message = null): self value, type
isNonEmptyString(?string $message = null): self value, type
isNull(?string $message = null): self value, type
isNumeric(?string $message = null): self value, type
isObject(?string $message = null): self value, type
isPositiveInt(?string $message = null): self value, type
isResource(?string $message = null): self value, type
isScalar(?string $message = null): self value, type
isString(?string $message = null): self value, type
isTrue(?string $message = null): self value, type
isUppercaseString(?string $message = null): self value, type
matchesRegularExpression(string $pattern, ?string $message = null): self value, pattern=
startsWith(string $needle, ?string $message = null): self value, needle

Note

  • The value context is always value-exported except when appended by + which means it is type-exported instead.
  • The type context is always type-exported. In negated expectations, this context is omitted.
  • Other context values are value-exported except when appended by = which means it is integrated as-is.

Available Expectation Classes

Nexus\Assert\Assert::that() returns an instance of Nexus\Assert\Expectation which is the base implementation of the Nexus\Assert\Expectable interface.

If you want to have a negated expectation, you can invoke not() on the expectation to return an instance of Nexus\Assert\NegatedExpectation.

<?php

use Nexus\Assert\Assert;

function test(mixed $a): void
{
    Assert::that($a)->isNumeric()->not()->isString();
    // $a is narrowed as either int or float
}

If you want to have a nullable expectation, that is, proceed with the expectation only if the input is not null, then you can invoke nullOr() on the base expectation.

<?php

use Nexus\Assert\Assert;

function test(mixed $a): void
{
    Assert::that($a)->nullOr()->isString();
    // $a is now understood as either string or null
}

Note

Currently, the not() and nullOr() methods can only be invoked on the base Expectation object. It is not yet available on the variant expectations. It can be considered in future versions.

Customising the Exporter

Nexus\Assert\Assert utilises the default implementation of Nexus\Assert\ExporterInterface - Exporter - to nicely export the value and type of the asserted input. If you need to do some customisations for your use case, you can implement your own exporter and let Assert use that.

<?php

use App\Exporter\MyExporter;
use Nexus\Assert\Assert;

Assert::setExporter(new MyExporter());

function foo(mixed $value): void
{
    Assert::that($value)->isBool();
}

Formatting the Exception Message

ExpectationFailedException accepts a templated message and the context when it is instantiated. You can modify the message by passing a template message as last argument to any expectation method. The context values are wrapped in curly braces with no in-between spaces.

<?php

use Nexus\Assert\Assert;

function test(mixed $a): void
{
    $message = 'Value "{value}" is not of type string'.
    Assert::that($a)->isString($message);
    // if this fails, the message would be something like:
    // Value "42" is not of type string.
}

When creating your custom messages, you are not compelled to use all available context. However, adding an unknown context for an expectation method will be useless as that won't be interpolated.

Resources

License

This library is licensed under MIT.

About

Chainable type-safety assertions library.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages