AssertValue

Since v1.2016052101

Description

AssertValue is a Requirement. It throws a ContractFailed exception if an expression does not evaluate to true.

Public Interface

AssertValue has the following public interface:

// AssertValue lives in this namespace
namespace GanbaroDigital\Contracts\V1\Contracts;

// our base classes and interfaces
use GanbaroDigital\Defensive\V1\Interfaces\Requirement;

// our exceptions
use GanbaroDigital\Contracts\V1\Exceptions\ContractFailed;

/**
 * check that an expression is true ... and if it is not, throw an exception
 */
class AssertValue implements Requirement
{
    /**
     * create a composable requirement
     *
     * @param  boolean $expr
     *         the expression we use to check $value
     * @param  string $reason
     *         the reason why $expr must be true
     * @return Requirement
     *         a requirement that can be enforced
     */
    public static function apply($expr, $reason = "see source code for details");

    /**
     * constructor
     *
     * @param  boolean $expr
     *         the expression we are checking
     * @param  string $reason
     *         the reason why $expr must be true
     */
    public function __construct($expr, $reason);

    /**
     * check that an expression is true ... and if it is not, throw an
     * exception
     *
     * @param  mixed $data
     *         the value check we are checking
     * @param  string $fieldOrVarName
     *         the name of the field we are checking
     * @return boolean
     *         TRUE on success
     */
    public function __invoke($data, $fieldOrVarName = 'value');

    /**
     * check that an expression is true ... and if it is not, throw an
     * exception
     *
     * @param  mixed $data
     *         the value check we are checking
     * @param  string $fieldOrVarName
     *         the name of the field we are checking
     * @return boolean
     *         TRUE on success
     */
    public function to($data, $fieldOrVarName = 'value');
}

How To Use

Enforcing A Contract

Use the ::apply()->to() pattern to check a value:

use GanbaroDigital\Contracts\V1\Contracts\AssertValue;

$data = 10;
AssertValue::apply($data > 4)->to($data);

If the expression does not evaluates to true, an exception is thrown:

use GanbaroDigital\Contracts\V1\Contracts\AssertValue;

// throws a ContractFailed exception
$data = 2;
AssertValue::apply($data > 4)->to($data);

You can supply a string to explain the contract. This will be included in the ContractFailed exception, and should appear in your app's logs.

use GanbaroDigital\Contracts\V1\Contracts\AssertValue;

// throws a ContractFailed exception
$data = 2;
AssertValue::apply($data > 4, "must be greater than 4")->to($data, '$data');

Class Contract

Here is the contract for this class:

GanbaroDigitalTest\Contracts\V1\Contracts\AssertValue
 [x] Can instantiate
 [x] is Requirement
 [x] Returns true if expression is true
 [x] Throws exception if expression is not true
 [x] Failed assert provides location of broken contract
 [x] Failed assert provides contract terms
 [x] Failed assert falls back to default contract terms
 [x] Failed assert provides rejected value

Class contracts are built from this class's unit tests.

Future releases of this class will not break this contract.

Future releases of this class may add to this contract. New additions may include:

  • clarifying existing behaviour (e.g. stricter contract around input or return types)
  • add new behaviours (e.g. extra class methods)

When you use this class, you can only rely on the behaviours documented by this contract.

If you:

  • find other ways to use this class,
  • or depend on behaviours that are not covered by a unit test,
  • or depend on undocumented internal states of this class,

... your code may not work in the future.

Notes

Combining AssertValue With PHP's assert()

PHP 5 and PHP 7 have assert() functions that behave differently:

Both PHP 5 and PHP 7 support disabling assert() to increase performance in Production.

AssertValue can be combined with PHP's assert() safely:

$data = 10;
assert(AssertValue::apply($data > 5)->to($data));

That will work on PHP 5 and PHP 7, and bring you these benefits:

  1. Ease of use: can pass any PHP expression, no need to pass it as as string
  2. Stricter: the expression has to evaluate to true, anything else is treated as a failure
  3. Modern error flow: AssertValue throws an exception, no need to deal with PHP's legacy error system
  4. Better error information: the ContractFailed exception contains $data's value and type

On PHP 5, switching off assertions will not improve the speed of your code. AssertValue will still run, and it will still throw an exception if the expression isn't true.

See Also