Skip to content

Commit

Permalink
Assert: added PHP 8 typehints
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Mar 2, 2023
1 parent e6e826a commit 8cbcd04
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 129 deletions.
140 changes: 52 additions & 88 deletions src/Framework/Assert.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Assert
/**
* Asserts that two values are equal and have the same type and identity of objects.
*/
public static function same($expected, $actual, ?string $description = null): void
public static function same(mixed $expected, mixed $actual, ?string $description = null): void
{
self::$counter++;
if ($actual !== $expected) {
Expand All @@ -63,7 +63,7 @@ public static function same($expected, $actual, ?string $description = null): vo
/**
* Asserts that two values are not equal or do not have the same type and identity of objects.
*/
public static function notSame($expected, $actual, ?string $description = null): void
public static function notSame(mixed $expected, mixed $actual, ?string $description = null): void
{
self::$counter++;
if ($actual === $expected) {
Expand All @@ -76,7 +76,7 @@ public static function notSame($expected, $actual, ?string $description = null):
* Asserts that two values are equal and checks expectations. The identity of objects,
* the order of keys in the arrays and marginally different floats are ignored.
*/
public static function equal($expected, $actual, ?string $description = null): void
public static function equal(mixed $expected, mixed $actual, ?string $description = null): void
{
self::$counter++;
if (!self::isEqual($expected, $actual)) {
Expand All @@ -89,7 +89,7 @@ public static function equal($expected, $actual, ?string $description = null): v
* Asserts that two values are not equal and checks expectations. The identity of objects,
* the order of keys in the arrays and marginally different floats are ignored.
*/
public static function notEqual($expected, $actual, ?string $description = null): void
public static function notEqual(mixed $expected, mixed $actual, ?string $description = null): void
{
self::$counter++;
try {
Expand All @@ -105,91 +105,70 @@ public static function notEqual($expected, $actual, ?string $description = null)

/**
* Asserts that a haystack (string or array) contains an expected needle.
* @param mixed $needle
* @param array|string $actual
*/
public static function contains($needle, $actual, ?string $description = null): void
public static function contains(mixed $needle, array|string $actual, ?string $description = null): void
{
self::$counter++;
if (is_array($actual)) {
if (!in_array($needle, $actual, true)) {
self::fail(self::describe('%1 should contain %2', $description), $actual, $needle);
}
} elseif (is_string($actual)) {
if (!is_string($needle)) {
self::fail(self::describe('Needle %1 should be string'), $needle);
} elseif (!is_string($needle)) {
self::fail(self::describe('Needle %1 should be string'), $needle);

} elseif ($needle !== '' && !str_contains($actual, $needle)) {
self::fail(self::describe('%1 should contain %2', $description), $actual, $needle);
}
} else {
self::fail(self::describe('%1 should be string or array', $description), $actual);
} elseif ($needle !== '' && !str_contains($actual, $needle)) {
self::fail(self::describe('%1 should contain %2', $description), $actual, $needle);
}
}


/**
* Asserts that a haystack (string or array) does not contain an expected needle.
* @param mixed $needle
* @param array|string $actual
*/
public static function notContains($needle, $actual, ?string $description = null): void
public static function notContains(mixed $needle, array|string $actual, ?string $description = null): void
{
self::$counter++;
if (is_array($actual)) {
if (in_array($needle, $actual, true)) {
self::fail(self::describe('%1 should not contain %2', $description), $actual, $needle);
}
} elseif (is_string($actual)) {
if (!is_string($needle)) {
self::fail(self::describe('Needle %1 should be string'), $needle);
} elseif (!is_string($needle)) {
self::fail(self::describe('Needle %1 should be string'), $needle);

} elseif ($needle === '' || str_contains($actual, $needle)) {
self::fail(self::describe('%1 should not contain %2', $description), $actual, $needle);
}
} else {
self::fail(self::describe('%1 should be string or array', $description), $actual);
} elseif ($needle === '' || str_contains($actual, $needle)) {
self::fail(self::describe('%1 should not contain %2', $description), $actual, $needle);
}
}


/**
* Asserts that a haystack has an expected key.
* @param string|int $key
*/
public static function hasKey($key, array $actual, ?string $description = null): void
public static function hasKey(string|int $key, array $actual, ?string $description = null): void
{
self::$counter++;
if (!is_int($key) && !is_string($key)) {
self::fail(self::describe('Key %1 should be string or integer'), $key);

} elseif (!array_key_exists($key, $actual)) {
if (!array_key_exists($key, $actual)) {
self::fail(self::describe('%1 should contain key %2', $description), $actual, $key);
}
}


/**
* Asserts that a haystack doesn't have an expected key.
* @param string|int $key
*/
public static function hasNotKey($key, array $actual, ?string $description = null): void
public static function hasNotKey(string|int $key, array $actual, ?string $description = null): void
{
self::$counter++;
if (!is_int($key) && !is_string($key)) {
self::fail(self::describe('Key %1 should be string or integer'), $key);

} elseif (array_key_exists($key, $actual)) {
if (array_key_exists($key, $actual)) {
self::fail(self::describe('%1 should not contain key %2', $description), $actual, $key);
}
}


/**
* Asserts that a value is true.
* @param mixed $actual
*/
public static function true($actual, ?string $description = null): void
public static function true(mixed $actual, ?string $description = null): void
{
self::$counter++;
if ($actual !== true) {
Expand All @@ -200,9 +179,8 @@ public static function true($actual, ?string $description = null): void

/**
* Asserts that a value is false.
* @param mixed $actual
*/
public static function false($actual, ?string $description = null): void
public static function false(mixed $actual, ?string $description = null): void
{
self::$counter++;
if ($actual !== false) {
Expand All @@ -213,9 +191,8 @@ public static function false($actual, ?string $description = null): void

/**
* Asserts that a value is null.
* @param mixed $actual
*/
public static function null($actual, ?string $description = null): void
public static function null(mixed $actual, ?string $description = null): void
{
self::$counter++;
if ($actual !== null) {
Expand All @@ -226,9 +203,8 @@ public static function null($actual, ?string $description = null): void

/**
* Asserts that a value is not null.
* @param mixed $actual
*/
public static function notNull($actual, ?string $description = null): void
public static function notNull(mixed $actual, ?string $description = null): void
{
self::$counter++;
if ($actual === null) {
Expand All @@ -239,9 +215,8 @@ public static function notNull($actual, ?string $description = null): void

/**
* Asserts that a value is Not a Number.
* @param mixed $actual
*/
public static function nan($actual, ?string $description = null): void
public static function nan(mixed $actual, ?string $description = null): void
{
self::$counter++;
if (!is_float($actual) || !is_nan($actual)) {
Expand All @@ -252,9 +227,8 @@ public static function nan($actual, ?string $description = null): void

/**
* Asserts that a value is truthy.
* @param mixed $actual
*/
public static function truthy($actual, ?string $description = null): void
public static function truthy(mixed $actual, ?string $description = null): void
{
self::$counter++;
if (!$actual) {
Expand All @@ -265,9 +239,8 @@ public static function truthy($actual, ?string $description = null): void

/**
* Asserts that a value is falsey.
* @param mixed $actual
*/
public static function falsey($actual, ?string $description = null): void
public static function falsey(mixed $actual, ?string $description = null): void
{
self::$counter++;
if ($actual) {
Expand All @@ -278,32 +251,23 @@ public static function falsey($actual, ?string $description = null): void

/**
* Asserts the number of items in an array or Countable.
* @param array|\Countable $value
*/
public static function count(int $count, $value, ?string $description = null): void
public static function count(int $count, array|\Countable $value, ?string $description = null): void
{
self::$counter++;
if (!$value instanceof \Countable && !is_array($value)) {
self::fail(self::describe('%1 should be array or countable object', $description), $value);

} elseif (count($value) !== $count) {
if (count($value) !== $count) {
self::fail(self::describe('Count %1 should be %2', $description), count($value), $count);
}
}


/**
* Asserts that a value is of given class, interface or built-in type.
* @param string|object $type
* @param mixed $value
*/
public static function type($type, $value, ?string $description = null): void
public static function type(string|object $type, mixed $value, ?string $description = null): void
{
self::$counter++;
if (!is_object($type) && !is_string($type)) {
throw new \Exception('Type must be a object or a string.');

} elseif ($type === 'list') {
if ($type === 'list') {
if (!is_array($value) || ($value && array_keys($value) !== range(0, count($value) - 1))) {
self::fail(self::describe("%1 should be $type", $description), $value);
}
Expand Down Expand Up @@ -358,20 +322,26 @@ public static function exception(
/**
* Asserts that a function throws exception of given type and its message matches given pattern. Alias for exception().
*/
public static function throws(callable $function, string $class, ?string $message = null, $code = null): ?\Throwable
public static function throws(
callable $function,
string $class,
?string $message = null,
mixed $code = null
): ?\Throwable
{
return self::exception($function, $class, $message, $code);
}


/**
* Asserts that a function generates one or more PHP errors or throws exceptions.
* @param int|string|array $expectedType
* @param string $expectedMessage message
* @throws \Exception
* @throws \Exception
*/
public static function error(callable $function, $expectedType, ?string $expectedMessage = null): ?\Throwable
public static function error(
callable $function,
int|string|array $expectedType,
?string $expectedMessage = null
): ?\Throwable
{
if (is_string($expectedType) && !preg_match('#^E_[A-Z_]+$#D', $expectedType)) {
return static::exception($function, $expectedType, $expectedMessage);
Expand Down Expand Up @@ -457,13 +427,10 @@ public static function noError(callable $function): void
* %h% one or more HEX digits
* @param string $pattern mask|regexp; only delimiters ~ and # are supported for regexp
*/
public static function match(string $pattern, $actual, ?string $description = null): void
public static function match(string $pattern, string $actual, ?string $description = null): void
{
self::$counter++;
if (!is_scalar($actual)) {
self::fail(self::describe('%1 should match %2', $description), $actual, $pattern);

} elseif (!self::isMatching($pattern, $actual)) {
if (!self::isMatching($pattern, $actual)) {
if (self::$expandPatterns) {
[$pattern, $actual] = self::expandMatchingPatterns($pattern, $actual);
}
Expand All @@ -476,16 +443,13 @@ public static function match(string $pattern, $actual, ?string $description = nu
/**
* Asserts that a string matches a given pattern stored in file.
*/
public static function matchFile(string $file, $actual, ?string $description = null): void
public static function matchFile(string $file, string $actual, ?string $description = null): void
{
self::$counter++;
$pattern = @file_get_contents($file); // @ is escalated to exception
if ($pattern === false) {
throw new \Exception("Unable to read file '$file'.");

} elseif (!is_scalar($actual)) {
self::fail(self::describe('%1 should match %2', $description), $actual, $pattern, null, basename($file));

} elseif (!self::isMatching($pattern, $actual)) {
if (self::$expandPatterns) {
[$pattern, $actual] = self::expandMatchingPatterns($pattern, $actual);
Expand Down Expand Up @@ -525,9 +489,8 @@ private static function describe(string $reason, ?string $description = null): s

/**
* Executes function that can access private and protected members of given object via $this.
* @param object|string $obj
*/
public static function with($objectOrClass, \Closure $closure)
public static function with(object|string $objectOrClass, \Closure $closure): mixed
{
return $closure->bindTo(is_object($objectOrClass) ? $objectOrClass : null, $objectOrClass)();
}
Expand All @@ -540,12 +503,8 @@ public static function with($objectOrClass, \Closure $closure)
* Compares using mask.
* @internal
*/
public static function isMatching(string $pattern, $actual, bool $strict = false): bool
public static function isMatching(string $pattern, string $actual, bool $strict = false): bool
{
if (!is_scalar($actual)) {
throw new \Exception('Value must be strings.');
}

$old = ini_set('pcre.backtrack_limit', '10000000');

if (!self::isPcre($pattern)) {
Expand Down Expand Up @@ -579,7 +538,7 @@ public static function isMatching(string $pattern, $actual, bool $strict = false
/**
* @internal
*/
public static function expandMatchingPatterns(string $pattern, $actual): array
public static function expandMatchingPatterns(string $pattern, string $actual): array
{
if (self::isPcre($pattern)) {
return [$pattern, $actual];
Expand Down Expand Up @@ -640,7 +599,12 @@ public static function expandMatchingPatterns(string $pattern, $actual): array
* Compares two structures and checks expectations. The identity of objects, the order of keys
* in the arrays and marginally different floats are ignored.
*/
private static function isEqual($expected, $actual, int $level = 0, $objects = null): bool
private static function isEqual(
mixed $expected,
mixed $actual,
int $level = 0,
?\SplObjectStorage $objects = null
): bool
{
switch (true) {
case $level > 10:
Expand Down
8 changes: 0 additions & 8 deletions tests/Framework/Assert.contains.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,10 @@ foreach ($notContains as [$expected, $value]) {
}


Assert::exception(function () {
Assert::contains(1, 1);
}, Tester\AssertException::class, '1 should be string or array');

Assert::exception(function () {
Assert::contains(1, '1');
}, Tester\AssertException::class, 'Needle 1 should be string');

Assert::exception(function () {
Assert::notContains(1, 1);
}, Tester\AssertException::class, '1 should be string or array');

Assert::exception(function () {
Assert::notContains(1, '1');
}, Tester\AssertException::class, 'Needle 1 should be string');
Expand Down
Loading

0 comments on commit 8cbcd04

Please sign in to comment.