webmozarts / assert

Assertions to validate method input/output with nice error messages.
MIT License
7.56k stars 145 forks source link

Assert::upper() correct usage #299

Open bpastukh opened 8 months ago

bpastukh commented 8 months ago

Hello I'm trying to use Assert::upper() method, but psalm assert * @psalm-assert !lowercase-string $value link confuses me - how the string can be upper if we assert it is lowercase?

So following code does not pass psalm check:

        $string = $data['someKey'];
        Assert::upper($string);

The error is:

ERROR: DocblockTypeContradiction - src/Event/AbstractEvent.php:28:17 - Docblock-defined type string for $string is always lowercase-string (see https://psalm.dev/155)
        Assert::upper($string);

So what is correct usage of upper assertion?

zerkms commented 8 months ago

how the string can be upper if we assert it is lowercase?

Assertion is for !lowercase-string, exclamation mark ! means negation.

The error is:

How exactly is typed $string? Show /** @psalm-trace $string */;

bpastukh commented 8 months ago

It is not typed, it's $data is a dynamic array

        #[OA\Property(property: 'data', description: 'An array of data dependent on event type', type: 'object')]
        #[Assert\NotBlank]
        #[Assert\Type('array')]
        public array $data = [],
bpastukh commented 8 months ago

I'm able to reproduce it this way:

        $array = ['someKey' => random_bytes(10)];
        $string = $array['someKey'];
        Assert::upper($string);

So $array is not typed (it is defined on the first line of the example) and i'm still getting

ERROR: TypeDoesNotContainType - src/Event/AbstractEvent.php:25:17 - Type non-empty-string for $string is always !lowercase-string (see https://psalm.dev/056)
        Assert::upper($string);

As a workaround for now i've used Assert::true

        Assert::true(
            ctype_upper($string),
            sprintf('Expected a value to contain uppercase characters only. Got: "%s"', $string),
        );
zerkms commented 8 months ago

Indeed, I could reproduce it on the psalm.dev:

https://psalm.dev/r/7f0799fc21

shadowhand commented 3 weeks ago

What would the correct type assertion be? Or does it even need one?