Giter VIP home page Giter VIP logo

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

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?

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))

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?

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?

[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?

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.

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.

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

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()

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.

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?

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.

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::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.

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?

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.

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?

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.

[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?

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?

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

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?

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.

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 ๐Ÿ˜ƒ

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)]);

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.

"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.

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.

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?

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 ?

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.

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?

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

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.

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.