Skip to content

Commit

Permalink
Regression tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jul 26, 2022
1 parent c968ca1 commit 5d7a1a5
Show file tree
Hide file tree
Showing 25 changed files with 898 additions and 0 deletions.
11 changes: 11 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,17 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7621-1.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7621-2.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7621-3.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-7511.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7224.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6556.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-4708.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4708.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-2911.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-7156.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6728.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-6364.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-5758.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-3931.php');
}

/**
Expand Down
139 changes: 139 additions & 0 deletions tests/PHPStan/Analyser/data/bug-2911.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php declare(strict_types=1);

namespace Bug2911;

use Exception;
use function PHPStan\Testing\assertType;

class MutatorConfig
{
/**
* @return array<mixed>
*/
public function getMutatorSettings(): array
{
return [];
}
}

final class ArrayItemRemoval
{
private const DEFAULT_SETTINGS = [
'remove' => 'first',
'limit' => PHP_INT_MAX,
];

/**
* @var string first|last|all
*/
private $remove;

/**
* @var int
*/
private $limit;

public function __construct(MutatorConfig $config)
{
$settings = $this->getResultSettings($config->getMutatorSettings());

$this->remove = $settings['remove'];
$this->limit = $settings['limit'];
}

/**
* @param array<string, mixed> $settings
*
* @return array{remove: string, limit: int}
*/
private function getResultSettings(array $settings): array
{
$settings = array_merge(self::DEFAULT_SETTINGS, $settings);
assertType('non-empty-array<string, mixed>', $settings);

if (!is_string($settings['remove'])) {
throw $this->configException($settings, 'remove');
}

assertType("non-empty-array<string, mixed>&hasOffsetValue('remove', string)", $settings);

$settings['remove'] = strtolower($settings['remove']);

assertType("non-empty-array<string, mixed>&hasOffsetValue('remove', string)", $settings);

if (!in_array($settings['remove'], ['first', 'last', 'all'], true)) {
throw $this->configException($settings, 'remove');
}

assertType("non-empty-array<string, mixed>&hasOffsetValue('remove', 'all'|'first'|'last')", $settings);

if (!is_numeric($settings['limit']) || $settings['limit'] < 1) {
throw $this->configException($settings, 'limit');
}
assertType("non-empty-array<string, mixed>&hasOffsetValue('limit', float|int<1, max>|numeric-string)&hasOffsetValue('remove', 'all'|'first'|'last')", $settings);

$settings['limit'] = (int) $settings['limit'];

assertType("non-empty-array<string, mixed>&hasOffsetValue('limit', float|int<1, max>|numeric-string)&hasOffsetValue('limit', int)&hasOffsetValue('remove', 'all'|'first'|'last')", $settings);

return $settings;
}

/**
* @param array<string, mixed> $settings
*/
private function configException(array $settings, string $property): Exception
{
$value = $settings[$property];

return new Exception(sprintf(
'Invalid configuration of ArrayItemRemoval mutator. Setting `%s` is invalid (%s)',
$property,
is_scalar($value) ? $value : '<' . strtoupper(gettype($value)) . '>'
));
}
}

final class ArrayItemRemoval2
{
private const DEFAULT_SETTINGS = [
'remove' => 'first',
'limit' => PHP_INT_MAX,
];

/**
* @param array<string, mixed> $settings
*
* @return array{remove: string, limit: int}
*/
private function getResultSettings(array $settings): array
{
$settings = array_merge(self::DEFAULT_SETTINGS, $settings);

assertType('non-empty-array<string, mixed>', $settings);

if (!is_string($settings['remove'])) {
throw new Exception();
}

assertType("non-empty-array<string, mixed>&hasOffsetValue('remove', string)", $settings);

if (!is_int($settings['limit'])) {
throw new Exception();
}

assertType("non-empty-array<string, mixed>&hasOffsetValue('limit', int)&hasOffsetValue('remove', string)", $settings);

return $settings;
}


/**
* @param array<mixed> $array
*/
function foo(array $array): void {
$array['bar'] = 'string';

assertType("hasOffsetValue('bar', 'string')&non-empty-array", $array);
}
}
92 changes: 92 additions & 0 deletions tests/PHPStan/Analyser/data/bug-4708.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Bug4708Two;

use function PHPStan\Testing\assertType;

/**
* @param string[] $columns
*
* @return string[]|false
*/

function GenerateData($columns)
{
$res = [];

if (!empty($columns))
{
foreach ($columns as $col)
{
$res[$col] = $col;
}
}
else
{
$res = false;
}

return $res;
}

/**
* Get a bunch of configurational fields about an ASC.
*
* @return array
*/

function GetASCConfig()
{
$columns = ['bsw', 'bew', 'utc', 'ssi'];

$result = GenerateData($columns);

if ($result === FALSE)
{
$result = ['result' => FALSE,
'dberror' => 'xyz'];
}
else
{
assertType('array<string>', $result);
if (!isset($result['bsw']))
{
assertType('array<string>', $result);
$result['bsw'] = 1;
assertType("non-empty-array<1|string>&hasOffsetValue('bsw', 1)", $result);
}
else
{
assertType("array<string>&hasOffsetValue('bsw', string)", $result);
$result['bsw'] = (int) $result['bsw'];
assertType('*NEVER*', $result); // should be non-empty-array<string|int>&hasOffsetValue('bsw', int)
}

assertType("non-empty-array<1|string>&hasOffsetValue('bsw', 1)", $result); // should be non-empty-array<1|string>&hasOffsetValue('bsw', int)

if (!isset($result['bew']))
{
$result['bew'] = 5;
}
else
{
$result['bew'] = (int) $result['bew'];
}

assertType("non-empty-array<int|string>&hasOffsetValue('bsw', 1)", $result); // should be non-empty-array<int|string>&hasOffsetValue('bsw', int)&hasOffsetValue('bew', int)

foreach (['utc', 'ssi'] as $field)
{
if (array_key_exists($field, $result))
{
$result[$field] = (int) $result[$field];
}
}

assertType("non-empty-array<int|string>&hasOffsetValue('bsw', 1)", $result); // should be non-empty-array<int|string>&hasOffsetValue('bsw', int)&hasOffsetValue('bew', int)
}

assertType('non-empty-array<int|string|false>', $result);

return $result;
}
42 changes: 42 additions & 0 deletions tests/PHPStan/Analyser/data/bug-6556.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php declare(strict_types = 1);

namespace Bug6556;

use function PHPStan\Testing\assertType;

/**
* @phpstan-type Test array{
* test1?: string,
* test2?: string,
* test3?: array{title: string, details: string}
* }
*/
class TestClass {
/**
* @param Test $testArg
*/
function testFunc(array $testArg): void {
assertType('array{test1?: string, test2?: string, test3?: array{title: string, details: string}}', $testArg);
$testKeys = [
'test1',
'test2'
];

$result = '';

foreach ($testKeys as $option) {
if (\array_key_exists($option, $testArg)) {
$result .= '<p>' . $testArg[$option] . '</p>';
}
}

assertType('array{test1?: string, test2?: string, test3?: array{title: string, details: string}}', $testArg);

if (\array_key_exists('test3', $testArg)) {
$result .= '<p>';
$result .= '<b>' . $testArg['test3']['title'] . '</b><br>';
$result .= $testArg['test3']['details'];
$result .= '</p>';
}
}
}
32 changes: 32 additions & 0 deletions tests/PHPStan/Analyser/data/bug-6728.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Bug6728;

use function PHPStan\Testing\assertType;

class HelloWorld
{
/** @return array{success: false, errorReason: string}|array{success: true, id: int} */
public function sayHello(): array
{
if (date('d') === '01') {
return ['success' => false, 'errorReason' => 'Test'];
}

return ['success' => true, 'id' => 1];
}

public function test(): void
{
$retArr = $this->sayHello();
assertType('array{success: false, errorReason: string}|array{success: true, id: int}', $retArr);
if ($retArr['success'] === true) {
assertType('array{success: true, id: int}', $retArr);
assertType('true', isset($retArr['id']));
assertType('int', $retArr['id']);
} else {
assertType('array{success: false, errorReason: string}', $retArr);
assertType('string', $retArr['errorReason']);
}
}
}
61 changes: 61 additions & 0 deletions tests/PHPStan/Analyser/data/bug-7224.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Bug7224;


use function PHPStan\Testing\assertType;

/**
* @param array{id: string, name?: string, team_name?: string|null} $roleUpdates
*/
function processUpdates(array $roleUpdates): void {
assertType('array{id: string, name?: string, team_name?: string|null}', $roleUpdates);
if (!isset($roleUpdates['team_name']) && !isset($roleUpdates['name'])) {
return;
}

assertType('array{id: string, name?: string, team_name?: string|null}', $roleUpdates);

$fieldUpdates = ['updated_at' => new \DateTime()];

if (\array_key_exists('team_name', $roleUpdates)) {
$fieldUpdates['team_name'] = $roleUpdates['team_name'];
}

if (isset($roleUpdates['name'])) {
$fieldUpdates['name'] = $roleUpdates['name'];
}

saveUpdates($roleUpdates['id'], $fieldUpdates);
}

/**
* @param array{id: string, name?: string, team_name?: string|null} $roleUpdates
*/
function processUpdates2(array $roleUpdates): void {
assertType('array{id: string, name?: string, team_name?: string|null}', $roleUpdates);
if (!isset($roleUpdates['team_name'])) {

}

assertType('array{id: string, name?: string, team_name?: string|null}', $roleUpdates);

$fieldUpdates = ['updated_at' => new \DateTime()];

if (\array_key_exists('team_name', $roleUpdates)) {
$fieldUpdates['team_name'] = $roleUpdates['team_name'];
}

if (isset($roleUpdates['name'])) {
$fieldUpdates['name'] = $roleUpdates['name'];
}

saveUpdates($roleUpdates['id'], $fieldUpdates);
}

/**
* @param array<string, mixed> $updatedFields
*/
function saveUpdates(string $id, array $updatedFields): void {
// ...
}

0 comments on commit 5d7a1a5

Please sign in to comment.