Giter Club home page Giter Club logo

assert's Introduction

Webmozart Assert

Latest Stable Version Total Downloads

This library contains efficient assertions to test the input and output of your methods. With these assertions, you can greatly reduce the amount of coding needed to write a safe implementation.

All assertions in the Assert class throw an Webmozart\Assert\InvalidArgumentException if they fail.

FAQ

What's the difference to beberlei/assert?

This library is heavily inspired by Benjamin Eberlei's wonderful assert package, but fixes a usability issue with error messages that can't be fixed there without breaking backwards compatibility.

This package features usable error messages by default. However, you can also easily write custom error messages:

Assert::string($path, 'The path is expected to be a string. Got: %s');

In beberlei/assert, the ordering of the %s placeholders is different for every assertion. This package, on the contrary, provides consistent placeholder ordering for all assertions:

  • %s: The tested value as string, e.g. "/foo/bar".
  • %2$s, %3$s, ...: Additional assertion-specific values, e.g. the minimum/maximum length, allowed values, etc.

Check the source code of the assertions to find out details about the additional available placeholders.

Installation

Use Composer to install the package:

composer require webmozart/assert

Example

use Webmozart\Assert\Assert;

class Employee
{
    public function __construct($id)
    {
        Assert::integer($id, 'The employee ID must be an integer. Got: %s');
        Assert::greaterThan($id, 0, 'The employee ID must be a positive integer. Got: %s');
    }
}

If you create an employee with an invalid ID, an exception is thrown:

new Employee('foobar');
// => Webmozart\Assert\InvalidArgumentException:
//    The employee ID must be an integer. Got: string

new Employee(-10);
// => Webmozart\Assert\InvalidArgumentException:
//    The employee ID must be a positive integer. Got: -10

Assertions

The Assert class provides the following assertions:

Type Assertions

Method Description
string($value, $message = '') Check that a value is a string
stringNotEmpty($value, $message = '') Check that a value is a non-empty string
integer($value, $message = '') Check that a value is an integer
integerish($value, $message = '') Check that a value casts to an integer
positiveInteger($value, $message = '') Check that a value is a positive (non-zero) integer
float($value, $message = '') Check that a value is a float
numeric($value, $message = '') Check that a value is numeric
natural($value, $message= ''') Check that a value is a non-negative integer
boolean($value, $message = '') Check that a value is a boolean
scalar($value, $message = '') Check that a value is a scalar
object($value, $message = '') Check that a value is an object
resource($value, $type = null, $message = '') Check that a value is a resource
isCallable($value, $message = '') Check that a value is a callable
isArray($value, $message = '') Check that a value is an array
isTraversable($value, $message = '') (deprecated) Check that a value is an array or a \Traversable
isIterable($value, $message = '') Check that a value is an array or a \Traversable
isCountable($value, $message = '') Check that a value is an array or a \Countable
isInstanceOf($value, $class, $message = '') Check that a value is an instanceof a class
isInstanceOfAny($value, array $classes, $message = '') Check that a value is an instanceof at least one class on the array of classes
notInstanceOf($value, $class, $message = '') Check that a value is not an instanceof a class
isAOf($value, $class, $message = '') Check that a value is of the class or has one of its parents
isAnyOf($value, array $classes, $message = '') Check that a value is of at least one of the classes or has one of its parents
isNotA($value, $class, $message = '') Check that a value is not of the class or has not one of its parents
isArrayAccessible($value, $message = '') Check that a value can be accessed as an array
uniqueValues($values, $message = '') Check that the given array contains unique values

Comparison Assertions

Method Description
true($value, $message = '') Check that a value is true
false($value, $message = '') Check that a value is false
notFalse($value, $message = '') Check that a value is not false
null($value, $message = '') Check that a value is null
notNull($value, $message = '') Check that a value is not null
isEmpty($value, $message = '') Check that a value is empty()
notEmpty($value, $message = '') Check that a value is not empty()
eq($value, $value2, $message = '') Check that a value equals another (==)
notEq($value, $value2, $message = '') Check that a value does not equal another (!=)
same($value, $value2, $message = '') Check that a value is identical to another (===)
notSame($value, $value2, $message = '') Check that a value is not identical to another (!==)
greaterThan($value, $value2, $message = '') Check that a value is greater than another
greaterThanEq($value, $value2, $message = '') Check that a value is greater than or equal to another
lessThan($value, $value2, $message = '') Check that a value is less than another
lessThanEq($value, $value2, $message = '') Check that a value is less than or equal to another
range($value, $min, $max, $message = '') Check that a value is within a range
inArray($value, array $values, $message = '') Check that a value is one of a list of values
oneOf($value, array $values, $message = '') Check that a value is one of a list of values (alias of inArray)

String Assertions

You should check that a value is a string with Assert::string() before making any of the following assertions.

Method Description
contains($value, $subString, $message = '') Check that a string contains a substring
notContains($value, $subString, $message = '') Check that a string does not contain a substring
startsWith($value, $prefix, $message = '') Check that a string has a prefix
notStartsWith($value, $prefix, $message = '') Check that a string does not have a prefix
startsWithLetter($value, $message = '') Check that a string starts with a letter
endsWith($value, $suffix, $message = '') Check that a string has a suffix
notEndsWith($value, $suffix, $message = '') Check that a string does not have a suffix
regex($value, $pattern, $message = '') Check that a string matches a regular expression
notRegex($value, $pattern, $message = '') Check that a string does not match a regular expression
unicodeLetters($value, $message = '') Check that a string contains Unicode letters only
alpha($value, $message = '') Check that a string contains letters only
digits($value, $message = '') Check that a string contains digits only
alnum($value, $message = '') Check that a string contains letters and digits only
lower($value, $message = '') Check that a string contains lowercase characters only
upper($value, $message = '') Check that a string contains uppercase characters only
length($value, $length, $message = '') Check that a string has a certain number of characters
minLength($value, $min, $message = '') Check that a string has at least a certain number of characters
maxLength($value, $max, $message = '') Check that a string has at most a certain number of characters
lengthBetween($value, $min, $max, $message = '') Check that a string has a length in the given range
uuid($value, $message = '') Check that a string is a valid UUID
ip($value, $message = '') Check that a string is a valid IP (either IPv4 or IPv6)
ipv4($value, $message = '') Check that a string is a valid IPv4
ipv6($value, $message = '') Check that a string is a valid IPv6
email($value, $message = '') Check that a string is a valid e-mail address
notWhitespaceOnly($value, $message = '') Check that a string contains at least one non-whitespace character

File Assertions

Method Description
fileExists($value, $message = '') Check that a value is an existing path
file($value, $message = '') Check that a value is an existing file
directory($value, $message = '') Check that a value is an existing directory
readable($value, $message = '') Check that a value is a readable path
writable($value, $message = '') Check that a value is a writable path

Object Assertions

Method Description
classExists($value, $message = '') Check that a value is an existing class name
subclassOf($value, $class, $message = '') Check that a class is a subclass of another
interfaceExists($value, $message = '') Check that a value is an existing interface name
implementsInterface($value, $class, $message = '') Check that a class implements an interface
propertyExists($value, $property, $message = '') Check that a property exists in a class/object
propertyNotExists($value, $property, $message = '') Check that a property does not exist in a class/object
methodExists($value, $method, $message = '') Check that a method exists in a class/object
methodNotExists($value, $method, $message = '') Check that a method does not exist in a class/object

Array Assertions

Method Description
keyExists($array, $key, $message = '') Check that a key exists in an array
keyNotExists($array, $key, $message = '') Check that a key does not exist in an array
validArrayKey($key, $message = '') Check that a value is a valid array key (int or string)
count($array, $number, $message = '') Check that an array contains a specific number of elements
minCount($array, $min, $message = '') Check that an array contains at least a certain number of elements
maxCount($array, $max, $message = '') Check that an array contains at most a certain number of elements
countBetween($array, $min, $max, $message = '') Check that an array has a count in the given range
isList($array, $message = '') Check that an array is a non-associative list
isNonEmptyList($array, $message = '') Check that an array is a non-associative list, and not empty
isMap($array, $message = '') Check that an array is associative and has strings as keys
isNonEmptyMap($array, $message = '') Check that an array is associative and has strings as keys, and is not empty

Function Assertions

Method Description
throws($closure, $class, $message = '') Check that a function throws a certain exception. Subclasses of the exception class will be accepted.

Collection Assertions

All of the above assertions can be prefixed with all*() to test the contents of an array or a \Traversable:

Assert::allIsInstanceOf($employees, 'Acme\Employee');

Nullable Assertions

All of the above assertions can be prefixed with nullOr*() to run the assertion only if it the value is not null:

Assert::nullOrString($middleName, 'The middle name must be a string or null. Got: %s');

Extending Assert

The Assert class comes with a few methods, which can be overridden to change the class behaviour. You can also extend it to add your own assertions.

Overriding methods

Overriding the following methods in your assertion class allows you to change the behaviour of the assertions:

  • public static function __callStatic($name, $arguments)
    • This method is used to 'create' the nullOr and all versions of the assertions.
  • protected static function valueToString($value)
    • This method is used for error messages, to convert the value to a string value for displaying. You could use this for representing a value object with a __toString method for example.
  • protected static function typeToString($value)
    • This method is used for error messages, to convert the a value to a string representing its type.
  • protected static function strlen($value)
    • This method is used to calculate string length for relevant methods, using the mb_strlen if available and useful.
  • protected static function reportInvalidArgument($message)
    • This method is called when an assertion fails, with the specified error message. Here you can throw your own exception, or log something.

Static analysis support

Where applicable, assertion functions are annotated to support Psalm's Assertion syntax. A dedicated PHPStan Plugin is required for proper type support.

Authors

Contribute

Contributions to the package are always welcome!

License

All contents of this package are licensed under the MIT license.

assert's People

Contributors

andrew-demb avatar ayesh avatar backendtea avatar bburnichon avatar frontendcoffee avatar grahamcampbell avatar guilliamxavier avatar justblackbird avatar keradus avatar kudashevs avatar localheinz avatar marcosh avatar mathroc avatar mollierobbert avatar mveldman avatar nyholm avatar ocramius avatar phil-davis avatar rmikalkenas avatar rossbearman avatar ruudk avatar sergiy-petrov avatar sfreezer avatar simpod avatar smoench avatar taluu avatar tysonandre avatar vudaltsov avatar webmozart avatar zales0123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

assert's Issues

Add context to exceptions

Hi @webmozart and guys,
Are you interested in adding context to a thrown exception?
E.g.

        Assert::null($error, 'Api request must not return error', [
            'userId' => $currentUser->getId(),
            'apiRequest' => $request,
            'apiResponce' => $response,
            'error' => $error, // why not in the message - it could be too unique message, causing say Sentry to create a lot of duplicates, say usually happens to SQL unique index errors.
        ]);

this is possible to add now to custom exception that support context, thanks to
https://github.com/webmozart/assert/pull/19/files

The context is some payload which is usually useful (when stacktrace is not enough).
Basically, I need to add array $context = [] as 3rd (sometimes 4th) argi to all assert::whatever() methods to then pass it further to throw new InvalidArgumentException($message, 0, null, $context ?: null);

I will draw a PR if this aligns with your thoughts.

[RFC] Return values

Currently if you want to use the result of a given assertion you have to do something like this:

public function returnValue(): int {
    $value = intOrNullFunction();
    Assert::integer($value);
    return $value;
}

What would be nicer is if the assertion on success would return the value:

public function returnValue(): int {
    return Assert::integer(intOrNullFunction());
}

What do you think?

Please add a .gitattributes file

Please add .gitattributes file to exclude the /tests directory and any other files that aren't needed in production (e.g.: README.md, CHANGELOG.md).

Thanks ๐Ÿ˜ƒ

Proposal: array/object property path assertions

I would like to do something like that:

Assert::allKeyPathsExists($collection, [
    'page',
    'pages',
    'total',
    'limit',
    '_embedded.items',
    '_links.self',
    '_links.first',
    '_links.last'
]);

// or 
Assert::keyPathExists($collection, '_links.last.href');

Currently I have something like that:

use Webmozart\Assert\Assert as BaseAssert;

/**
 * Class Assert
 * @package AppBundle\Test
 */
class Assert extends BaseAssert
{
    /**
     * @param array $value
     * @param string $keyPath
     * @param string|null $message
     * @throws
     */
    public static function keyPathExists($value, $keyPath, $message = null)
    {
        $pointer  =& $value;
        $keys     = explode('.', $keyPath);
        $position = [];
        $message  = $message ?: 'expected key-path "%s" to exist. Failed at position "%2$s".';

        foreach ($keys as $key) {
            $position[] = $key;
            static::keyExists($pointer, $key, sprintf($message, $keyPath, implode('.', $position)));
            $pointer =& $pointer[$key];
        }
    }

    /**
     * @param array $value
     * @param array $keyPaths
     * @param string|null $message
     */
    public static function allKeyPathsExists($value, array $keyPaths, $message = null)
    {
        foreach ($keyPaths as $keyPath) {
            static::keyPathExists($value, $keyPath, $message);
        }
    }
}

Which works. I did also a different implementation using __callStatic and adding a prefix apply which could take a subject (value) and apply an assertion with different sets of arguments (and if needed messages).

I'v noticed, what I actually need is the possibilities to also apply such path tests to type-checks like integer or string.

So actually what is needed is some sort of __callStatic to operate over a path of array-keys or object-properties. Without that writing assertions pains. The example above delivered understandable error messages and the customization concept in this project is good, so I think you would not get some super generic (not understandable) messages, if scaled the way I did in the example.

The API could looks like this:

// 1. array subject of test, 2. array keyPaths to test, 3-n. assertion-arguments
Assert::arrayEveryKeyExists(array $subject, array $subjectKeyPaths)
Assert::arrayEveryInteger(array $subject, array $subjectKeyPaths);
Assert::arrayEveryIsInstance(array $subject, array $subjectKeyPaths, SomeClass::class);
// or Assert::arrayAllKeyExists, Assert::arrayAllInteger but the readability is worker here.

String length determined by visual width, not character count

I was looking at the possibility of using this library in a project but stumbled upon the following in the source code: https://github.com/webmozart/assert/blob/4a8bf11547e139e77b651365113fc12850c43d9a/src/Assert.php#L937

My intention was to use the lengthBetween() method which in turn uses the static strlen() method.

I'm curious why mb_strwidth() is used which returns the visual width instead of mb_strlen() which returns the character count?

For example, if you want to set a limit on a method to make sure only a certain amount of characters are passed in so it will fit into a database column it would make more sense to use mb_strlen().

Or is there a particular reason for this choice that I'm missing?
I compared to beberlei/assert which is another potential library I'm considering and it uses mb_strlen()

Thanks for what otherwise looks like an excellent library!

Assert::notOneOf

Hi,

I would like a way to assert that something is NOT in an array. I found how to check that something is in an array, but not the opposite.
Maybe add notOneOf ? Or some sort of magic method that would allow to negate any assertion ?

Token in .composer-auth.json revoked

I'm revoking the OAuth token in .composer-auth.json since that could currently be used to misuse the API rate limits of my account. The token was used to prevent "rate limit exceeded" errors from GitHub during Travis and Appveyor testing when fetching Composer dependencies without authentication.

There are two places in this repository affected by this change:

  • .travis.yml
  • appveyor.yml

In both cases, .composer-auth.json is copied to ~/.composer/auth.json in order to use that token during authentication with GitHub.

I don't know what happens to the builds after the token is revoked, but it could be that they are failing. There are two possible solutions that come to my mind:

  • Remove authentication completely - maybe the rate limit errors are a non-issue nowadays. I don't know how other repositories solve this issue today.
  • Create a new public-read-only token and store it in secret environment variables on Appveyor and Travis and inject those variables into auth.json during the build.

Late static binding

Hi there,

I'm actually working on a "functional tests helper", in a way a wrapper for this very useful library that you made and shared.

To be more flexible, I would like to first extend your Assert class to override some methods, among them valueToString() could use a custom formatter and since it is protected I thought it was an opening for what I'm trying to do.

The problem is that all the static calls in that class use self, so to use an overridden valueToString I have to override all the methods...

Would you accept a PR that changes all the self keyword by static to allow such usage?

If not, may I ask what's the point of having protected static methods instead of private?

Thanks,

Jules

How to use allKeyExists assertion?

Trying this

$data = ['one' => 1, 'two' => 2];

Assert::allKeyExists($data, ['one', 'two']);

//array_key_exists() expects parameter 2 to be array, integer given in Assert.php on line 891
//[internal function]: Webmozart\Assert\Assert::keyExists(1, Array)

and this

$data = ['one' => 1, 'two' => 2];

Assert::allKeyExists(['one', 'two'], $data);

//array_key_exists() expects parameter 2 to be array, string given in Assert.php on line 891
//[internal function]: Webmozart\Assert\Assert::keyExists('one', Array)

I'm one of dumbest man on Earth or this method has a bug?

MinCount and MaxCount assertion

I've faced a use case where I should check length of a \Countable. I see two methods for such checks:

  1. Assert::minCount is like Assert::minLength but for \Countable
  2. Assert::maxCount is like Assert::maxLength but for \Countable

Also an assertion that the passed in argument is a \Countable can be added.

The question is: are the maintainers interested in such methods inside of the library? Is so I could provide a PR with their implementation.

Is the project alive?

It seems that the last commit was made about five months ago. Also there are some PRs that are waiting since then.

So, my question is is the project alive or it's time to move on and choose another assertion library?

Allow multiple values for instanceof

As of now we have:

public static function isInstanceOf($value, $class, $message = '')

It would however be convenient to be able to do:

Assert::isInstanceOf($object, [Foo::class, Bar::class]);

instead of:

Assert::true($object instanceof Foo || $object instanceof Bar);

or another alternative

Custom exceptions

Hi,

I'm looking for a way to raise custom exceptions per assertion..
Looking at the code, it currently seems only possible to override Assert::reportInvalidArgument for all assertions..
The only way I see around this is to add an optional argument to every assertion, allowing to pass a custom exception class.. Would you be open for a PR to support this? Or do you see another way to achieve what I'm after?

Feature request: custom Exception

What do you think about the feature to pass custom exception class, to be able to not invoke InvalidArgument always.
This can be done on config level or/and as an optional argument to assertion.

WDYT?

Assert::interfaceExists($value, $message = '')

As of PHP 5.02 class_exists,

No longer returns TRUE for defined interfaces. Use interface_exists().

Quick Test:

interface MyInterface {}
class MyClass {}
echo PHP_VERSION; // 7.1.12-3+ubuntu14.04.1+deb.sury.org+1
var_dump(interface_exists(MyInterface::class)); // bool(true)
var_dump(class_exists(MyInterface::class)); // bool(false)
var_dump(interface_exists(MyClass::class)); // bool(false)
var_dump(class_exists(MyClass::class)); // bool(true)

interfaceExists() Proposal:

public static function interfaceExists($value, $message = '')
{
    if (!interface_exists($value)) {
        static::reportInvalidArgument(sprintf(
            $message ?: 'Expected an existing interface name. Got: %s',
            static::valueToString($value)
        ));
    }
}

... which is akin to classExists():

https://github.com/webmozart/assert/blob/23bf61bc8a7cc229d7ce8689b1bf818a9e192cac/src/Assert.php#L817-L825

Generically support 'not', 'and', 'or'

I need to assert the following:

Assert::string($value) || Assert::isInstanceOf($value, ClassA::class);

Maybe it's not the kind of problem this lib wants to solve. But it would be really great to have something like an or to chain multiple assertions.

Any opinion about it? Or maybe it's already possible I didn't got it yet?

Something like this would solve it:

try {
    Assert::string($value);
} catch (InvalidArgumentException $e) {
    Assert::isInstanceOf($value, ClassA::class);
}

but that's definitely not the way to go, right? ๐Ÿ˜…

Something like this would be nice:

Assert::isInstanceOfAny($value, [Type::string(), Type::object(ClassA::class)]);

Implements interface throws an exception if used on `null` value

If you want to check if a variable $value implements an interface you need to do two checks:

Assert::notNull($value);
Assert::implementsInterface($value, $className);

Wouldn't it be better if the implementsInterface also checks for null values? Currently I am using the isInstanceOf with an interface class.

Assert::alpha() only works with Latin characters

Because of the reliance on ctype_alpha, in most locales Unicode characters will be rejected, despite being very common in strings that you might want to check only contain letters.

It would be great to see a new assertion that accepts common letters like ร… or ร–. Perhaps using the regex /^\p{L}*$/ would be most appropriate?

\p{L} will match any valid Unicode letters, in either case.

Assertions can generate warnings

Some assertions call functions that may generate a warning if called with incorrect parameters, e.g. preg_match, strlen.

It would be better if they do not generate a warning when called, but either pass the assertion, or throw the exception.

This can be solved in one of two ways:

  • Silence errors using @ where possible
  • Assert the input is of the correct type, and throw an exception when it is not.

The issue with the second type is that it is a theoretical BC break. For example, the user may input an object that can be cast to a string, in which case most functions will do so, in which case it may pass the assertion.

Silencing the errors will however not save us from the TypeErrors that php 8.0 will start throwing: https://wiki.php.net/rfc/consistent_type_errors.

There is also the current issue of all the count related assertions, which do not check if the passed value is countable. So before php 7.2 everything is fine, but after that an warning is generated.

Personally i'm fine with the theoretical BC break, as it isn't really intended behaviour, as it is dependent on the implementation.

Assert::positiveInteger

Aas far as I understand, at the moment to assert that a variable contains a positive integer I need to use two assertions

Assert::integer($a, '...');
Assert::greaterThanEq($a, 0, '...');

Would it make sense to create a new assertion to condense these two in a single call? It could be called something like Assert::natural()

Assert integer or string - safe array keys

Hello,

PHP Documentation says:

The key can either be an integer or a string. The value can be of any type.
Additionally the following key casts will occur: (...)

I want to propose a new assertion that will make sure that a value can be safely used as a key in an array. By safely I mean that there will be no key casts and therefore no unexpected key collisions.

I'm not sure how to name it. Be more indicative of the intention or the implementation?

Assert::safeArrayKey()
Assert::allSafeArrayKey()

vs.

Assert::integerOrString()
Assert::allIntegerOrString()

Any comments? I'm happy to make a pull request.

Add a `oneOf` assertion

As we have all* assertions, having oneOf* assertions could be useful, as in detecting if one element in the collection can be asserted to the given assert.

WDYT ? I'd be glad to make a PR for that.

Add doc. comments to methods?

I really like this assertion library you've made (thanks!). However, it would be really nice if there were documenting comments (/** ... */) that my IDE could pick up as I'm using your library (for things like helping me figure out which parameter should be which for the contains(...) method).

For example, a helpful doc. comment for the contains(...) method might be...

/**
 * Assert that the given $value contains the given $subString.
 *
 * @param string $value The string to search (the haystack).
 * @param string $subString The string to search for (the needle).
 * @param string $message (Optional:) A custom error message if the
 *     assertion fails.
 */
public static function contains($value, $subString, $message = '')
{
    // ...
}

Have you considered adding those?

"Assert::assertIp" method

I believe that the library is missing the following assertions:

  • assertIp
  • assertIpv4
  • assertIpv6

Although such assertions can be easily implemented via assertTrue + filter_val I believe that addition them to the library could increase readability of client's code.


If the maintainers are interested in it, I could provide a PR.

Tag release 1.1.0

When will 1.1.0 be tagged? I've reviewed the changes since 1.0.2.

I believe we should merge #8 & #10 before tagging a release.

What do you think?

Flip expected/actual arguments?

Currently, when one is used to assertions in PHPUnit (first argument "expected", second "actual"), it's easy to get the assertions in this library wrong (first argument "actual", second "expected"). What do you think about flipping the arguments and releasing a 2.0?

Proposal: Custom exception class

It would be useful if the assert can throw instance of custom exception class not only \InvalidArgumentException.

In my usecase every module throws exceptions implementing one extra interface (let's say \Acme\Foo\DomainExceptionInterface). This helps to catch only exception of exact module if it's needed. With current implementation of the library I cannot achieve it.

If the maintainer is interested in resolving this I could provide a PR.

[feature proposal] How about introduce a static class `Valid` ?

I think it would be very useful to have a static class Valid that would have the same methods of Assert, but instead of throwing an exception when the condition is invalid it would return false.

if (!Valid:uuid('test')) {
    return new Response('', 404);
}

Many times I want to integrate this library in contexts - taking advantage of its working validation code - where throwing an exception is not desired.

Do you think would that be useful? Or even pertinent to this library scope?

String comparison with regular expression

Hi everyone,

I'm doing a lot of Behat testing for API stuff lately and I feel like I'm implementing the same assertion over and over again. The use case is the following:

Think of having a huge JSON response that contains a random value, such as a UUID. In fact, I want to compare the whole response as a string but because of that one value, this is not that easy and packing it all into one big regex is just not really working.

{
    "@context": "\/contexts\/Foobar",
    "@id": "I-am-a-generated-UUID",
    "_comment": "and a lot more content I want to compare 1:1+"
}

Or think of an e-mail body that contains a long text and just one simple part of it contains e.g. a link to a generated resource. How do you assert this?

Hello,

Welcome to platform x. 

Here is a lot of introduction and superb text I just want to compare 1:1.
Link to your profile: https://www.domain.com/and-this-here-is-generated

Best regards,
Platform

What do you guys think about implementing a special assertion in this library that searches for special regex handlers and then asserts all the rest.
I imagine it like this:

Assert::sameConsideringRegexes($given, $expected, 'The strings do not match.');

The $expected could then be written like so:

Hello,

Welcome to platform x. 

Here is a lot of introduction and superb text I just want to compare 1:1.
Link to your profile: https://www.domain.com/<regex>@^.{2}-\\d{4}-\\d{2}-[0-9A-Z]{4}-[0-9A-Z]{4}-.{1}$@</regex>

Best regards,
Platform

So in HTML style with opening <regex> and closing </regex>. But I'm very open for alternatives.
What do you guys think? Would that be useful to you? Would that fit this library? Do you have better naming ideas or overall improvements to the concept?

Why not PHP's assert()?

Hello.

I was wondering, why is this package not using PHP's native assert()? That way we could have much more control over it.

Suggestion to Assert some ISO standards

Would it be an idea to assert some ISO standards, like:

  • 639-2 (2 letter language code)
  • 639-1 (3 letter language code)
  • 3166-1 (country codes)

Or would this be out-of-scope of this library?

Add PHPDoc method hints for allNullOrIs*

E.g. I used a Assert::allNullOrIsInstanceOf(...) in a __construct(), it's a valid function, but without a method PHPDoc. Is this intentional or should it be added?

Uninformative message when failing to assert that an object and a string are equal

We have lots of Assert::eq("EUR", $currency); where $currency implements __toString().

The comparison works well, but in case of inequality the error message is really unclear: Expected a value equal to Money\Currency. Got: "EUR"

It would be great \Webmozart\Assert\Assert::valueToString() would check on this.

If you agree, I can provide a PR.

Assert unique values in array

One more proposition - allow to assert that all values in an array are unique e.g.

Assert::uniqueValues($array)
Assert::allUnique($array)
Assert::noDuplicates($array)

I would follow semantics of array_unique() so probably the assertion would look like:
count($array) === count(array_unique($array))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.