Skip to content

Commit

Permalink
Add tests data file annotation parser
Browse files Browse the repository at this point in the history
The data files can now be annotated instead of having their conditions
hardcoded in the NodeScopeResolverTest unit test class.

This allows to centralize the maintenance of the data to a single point.
  • Loading branch information
thg2k committed Jun 13, 2024
1 parent d5b2d57 commit 6f69ff2
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/Testing/TypeInferenceTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@
use PHPStan\Type\VerbosityLevel;
use function array_map;
use function array_merge;
use function constant;
use function count;
use function extension_loaded;
use function file_get_contents;
use function in_array;
use function intval;
use function is_string;
use function preg_match;
use function preg_match_all;
use function sprintf;
use function stripos;
use function strtolower;
Expand Down Expand Up @@ -126,12 +132,68 @@ public function assertFileAsserts(
}
}

public static function checkOnlyIfAnnotation(string $file): bool
{
$fileContents = file_get_contents($file);
if ($fileContents === false) {
self::fail(sprintf('Cannot read file %s', $file));
}

if (preg_match_all('{^(?:<\?php\s+)?//\s*onlyif\s+(.+)\s*$}Um', $fileContents, $ma) > 0) {
for ($i = 0; $i < count($ma[0]); $i++) {
$onlyIfCondition = $ma[1][$i];

if (preg_match('/^(PHP_VERSION_ID|PHP_INT_SIZE) (>|>=|<|<=|==) ([0-9]+)$/', $onlyIfCondition, $m) > 0) {
$onlyIfConditionConstant = constant($m[1]);
$onlyIfConditionOperator = $m[2];
$onlyIfConditionValue = intval($m[3]);

switch ($onlyIfConditionOperator) {
case '>':
$onlyIfResult = $onlyIfConditionConstant > $onlyIfConditionValue;
break;
case '>=':
$onlyIfResult = $onlyIfConditionConstant >= $onlyIfConditionValue;
break;
case '<':
$onlyIfResult = $onlyIfConditionConstant < $onlyIfConditionValue;
break;
case '<=':
$onlyIfResult = $onlyIfConditionConstant <= $onlyIfConditionValue;
break;
default:
$onlyIfResult = $onlyIfConditionConstant === $onlyIfConditionValue;
break;
}
} elseif (preg_match('/^extension (\w+)$/', $onlyIfCondition, $m) > 0) {
$onlyIfConditionExtension = $m[1];

$onlyIfResult = extension_loaded($onlyIfConditionExtension);
} elseif (preg_match('/^ignore$/', $onlyIfCondition, $m) > 0) {
$onlyIfResult = false;
} else {
self::fail(sprintf('File %s contains bad onlyif: %s', $file, $onlyIfCondition));
}

if (!$onlyIfResult) {
return false;
}
}
}

return true;
}

/**
* @api
* @return array<string, mixed[]>
*/
public static function gatherAssertTypes(string $file): array
{
if (!self::checkOnlyIfAnnotation($file)) {
return [];
}

$asserts = [];
self::processFile($file, static function (Node $node, Scope $scope) use (&$asserts, $file): void {
if (!$node instanceof Node\Expr\FuncCall) {
Expand Down

0 comments on commit 6f69ff2

Please sign in to comment.