Skip to content

Commit ceabc90

Browse files
herndlmIanDelMarszepeviktor
authored
Add TypeInferenceTest for current_time() (#76)
* Add TypeInferenceTest for `current_time()` * Simplify to most important test cases Co-authored-by: IanDelMar <[email protected]> * Add tests for mysql2date() * Fix has_filter()/has_action() return type and add tests up * Fix get_object_taxonomies() return type and add tests * Add tests for get_taxonomies() * Fix CS Co-authored-by: Viktor Szépe <[email protected]> * Use vendor+package style namespace * Update .travis.yml * Add tests for get_comment() * Avoid introducing a new variable --------- Co-authored-by: IanDelMar <[email protected]> Co-authored-by: Viktor Szépe <[email protected]>
1 parent ac44bd7 commit ceabc90

16 files changed

+212
-13
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
/.phpunit.result.cache
12
/vendor/
23
/composer.lock

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ script:
5151
- "git diff --exit-code"
5252
# Execute stubs
5353
- "php -f wordpress-stubs.php"
54-
# Analyse our code
55-
- "composer exec -- phpstan"
54+
# Run all tests
55+
- "composer run test"

composer.json

+14-2
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@
1313
"nikic/php-parser": "< 4.12.0",
1414
"php-stubs/generator": "^0.8.3",
1515
"phpdocumentor/reflection-docblock": "^5.3",
16-
"phpstan/phpstan": "^1.9"
16+
"phpstan/phpstan": "^1.9",
17+
"phpunit/phpunit": "^9.5"
1718
},
1819
"suggest": {
1920
"paragonie/sodium_compat": "Pure PHP implementation of libsodium",
2021
"symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
2122
"szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
2223
},
24+
"autoload-dev": {
25+
"classmap": [
26+
"tests/"
27+
]
28+
},
2329
"minimum-stability": "stable",
2430
"config": {
2531
"allow-plugins": {
@@ -29,7 +35,13 @@
2935
"scripts": {
3036
"post-install-cmd": "@composer --working-dir=source/ update --no-interaction",
3137
"post-update-cmd": "@composer --working-dir=source/ update --no-interaction",
32-
"cleanup": "git status --short --ignored | sed -n -e 's#^!! ##p' | xargs -r rm -vrf"
38+
"cleanup": "git status --short --ignored | sed -n -e 's#^!! ##p' | xargs -r rm -vrf",
39+
"test": [
40+
"@test:phpstan",
41+
"@test:phpunit"
42+
],
43+
"test:phpstan": "phpstan analyze",
44+
"test:phpunit": "phpunit"
3345
},
3446
"scripts-descriptions": {
3547
"cleanup": "Remove all ignored files."

functionMap.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@
7979
'mysql2date' => ["(\$format is 'G'|'U' ? int|false : string|false)"],
8080
'get_post_types' => ["(\$output is 'names' ? array<int, string> : array<int, \WP_Post_Type>)"],
8181
'get_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<int, \WP_Taxonomy>)"],
82-
'get_object_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<int, \WP_Taxonomy>)"],
82+
'get_object_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<string, \WP_Taxonomy>)"],
8383
'get_comment' => ["(\$output is 'ARRAY_A' ? array<string, mixed>|null : (\$output is 'ARRAY_N' ? array<int, mixed>|null : \WP_Comment|null))"],
8484
'get_post' => ["(\$output is 'ARRAY_A' ? array<string, mixed>|null : (\$output is 'ARRAY_N' ? array<int, mixed>|null : \WP_Post|null))"],
8585
'get_page_by_path' => ["(\$output is 'ARRAY_A' ? array<string, mixed>|null : (\$output is 'ARRAY_N' ? array<int, mixed>|null : \WP_Post|null))"],
86-
'has_action' => ['($callback is false ? bool : bool|int)'],
87-
'has_filter' => ['($callback is false ? bool : bool|int)'],
86+
'has_action' => ['($callback is false ? bool : false|int)'],
87+
'has_filter' => ['($callback is false ? bool : false|int)'],
8888
];

functionMap62.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@
7979
'mysql2date' => ["(\$format is 'G'|'U' ? int|false : string|false)"],
8080
'get_post_types' => ["(\$output is 'names' ? array<int, string> : array<int, \WP_Post_Type>)"],
8181
'get_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<int, \WP_Taxonomy>)"],
82-
'get_object_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<int, \WP_Taxonomy>)"],
82+
'get_object_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<string, \WP_Taxonomy>)"],
8383
'get_comment' => ["(\$output is 'ARRAY_A' ? array<string, mixed>|null : (\$output is 'ARRAY_N' ? array<int, mixed>|null : \WP_Comment|null))"],
8484
'get_post' => ["(\$output is 'ARRAY_A' ? array<string, mixed>|null : (\$output is 'ARRAY_N' ? array<int, mixed>|null : \WP_Post|null))"],
8585
'get_page_by_path' => ["(\$output is 'ARRAY_A' ? array<string, mixed>|null : (\$output is 'ARRAY_N' ? array<int, mixed>|null : \WP_Post|null))"],
86-
'has_action' => ['($callback is false ? bool : bool|int)'],
87-
'has_filter' => ['($callback is false ? bool : bool|int)'],
86+
'has_action' => ['($callback is false ? bool : false|int)'],
87+
'has_filter' => ['($callback is false ? bool : false|int)'],
8888
];

phpstan.neon

+3
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ parameters:
33
paths:
44
- finder.php
55
- visitor.php
6+
- tests/
7+
excludePaths:
8+
- tests/data/

phpunit.xml.dist

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
5+
colors="true"
6+
failOnRisky="true"
7+
failOnWarning="true"
8+
>
9+
<testsuites>
10+
<testsuite name="main">
11+
<directory>./tests/</directory>
12+
</testsuite>
13+
</testsuites>
14+
</phpunit>

tests/TypeInferenceTest.php

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStubs\WordPress\Core\Tests;
6+
7+
class TypeInferenceTest extends \PHPStan\Testing\TypeInferenceTestCase
8+
{
9+
/** @return iterable<mixed> */
10+
public function dataFileAsserts(): iterable
11+
{
12+
yield from $this->gatherAssertTypes(__DIR__ . '/data/current_time.php');
13+
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_object_taxonomies.php');
14+
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_taxonomies.php');
15+
yield from $this->gatherAssertTypes(__DIR__ . '/data/has_filter.php');
16+
yield from $this->gatherAssertTypes(__DIR__ . '/data/mysql2date.php');
17+
}
18+
19+
/**
20+
* @dataProvider dataFileAsserts
21+
* @param array<string> ...$args
22+
*/
23+
public function testFileAsserts(string $assertType, string $file, ...$args): void
24+
{
25+
$this->assertFileAsserts($assertType, $file, ...$args);
26+
}
27+
28+
public static function getAdditionalConfigFiles(): array
29+
{
30+
return [__DIR__ . '/phpstan.neon'];
31+
}
32+
}

tests/data/current_time.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStubs\WordPress\Core\Tests;
6+
7+
use function current_time;
8+
use function PHPStan\Testing\assertType;
9+
10+
// Integer types
11+
assertType('int', current_time('timestamp'));
12+
assertType('int', current_time('U'));
13+
14+
// String types
15+
assertType('string', current_time('mysql'));
16+
assertType('string', current_time('Hello'));
17+
18+
// Unknown string
19+
assertType('int|string', current_time((string)$_GET['unknown_string']));

tests/data/get_comment.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStubs\WordPress\Core\Tests;
6+
7+
use function get_comment;
8+
use function PHPStan\Testing\assertType;
9+
10+
/** @var \WP_Comment|int $comment */
11+
$comment = $comment;
12+
13+
// Default output
14+
assertType('WP_Comment|null', get_comment());
15+
assertType('WP_Comment|null', get_comment($comment));
16+
assertType('WP_Comment|null', get_comment($comment, OBJECT));
17+
18+
// Unexpected output
19+
assertType('WP_Comment|null', get_comment($comment, 'Hello'));
20+
21+
// Unknown output
22+
assertType('array|WP_Comment|null', get_comment($comment, $_GET['foo']));
23+
24+
// Associative array output
25+
assertType('array<string, mixed>|null', get_comment($comment, ARRAY_A));
26+
27+
// Numeric array output
28+
assertType('array<int, mixed>|null', get_comment($comment, ARRAY_N));

tests/data/get_object_taxonomies.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStubs\WordPress\Core\Tests;
6+
7+
use function get_object_taxonomies;
8+
use function PHPStan\Testing\assertType;
9+
10+
// Default output
11+
assertType('array<int, string>', get_object_taxonomies('post'));
12+
assertType('array<int, string>', get_object_taxonomies('post', 'names'));
13+
14+
// Objects output
15+
assertType('array<string, WP_Taxonomy>', get_object_taxonomies('post', 'objects'));
16+
17+
// Unexpected output
18+
assertType('array<string, WP_Taxonomy>', get_object_taxonomies('post', 'Hello'));
19+
20+
// Unknown string
21+
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', (string)$_GET['unknown_string']));

tests/data/get_taxonomies.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStubs\WordPress\Core\Tests;
6+
7+
use function get_object_taxonomies;
8+
use function PHPStan\Testing\assertType;
9+
10+
// Default output
11+
assertType('array<int, string>', get_taxonomies([]));
12+
assertType('array<int, string>', get_object_taxonomies([], 'names'));
13+
14+
// Objects output
15+
assertType('array<string, WP_Taxonomy>', get_object_taxonomies([], 'objects'));
16+
17+
// Unexpected output
18+
assertType('array<string, WP_Taxonomy>', get_object_taxonomies([], 'Hello'));
19+
20+
// Unknown string
21+
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies([], (string)$_GET['unknown_string']));

tests/data/has_filter.php

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStubs\WordPress\Core\Tests;
6+
7+
use function has_action;
8+
use function has_filter;
9+
use function PHPStan\Testing\assertType;
10+
11+
// Default callback of false
12+
assertType('bool', has_filter(''));
13+
assertType('bool', has_action(''));
14+
15+
// Explicit callback of false
16+
assertType('bool', has_filter('', false));
17+
assertType('bool', has_action('', false));
18+
19+
// Explicit callback
20+
assertType('int|false', has_filter('', 'intval'));
21+
assertType('int|false', has_action('', 'intval'));
22+
23+
// Maybe false callback
24+
/** @var callable|string|array|false $callback */
25+
$callback = $_GET['callback'];
26+
assertType('bool|int', has_filter('', $callback));
27+
assertType('bool|int', has_action('', $callback));

tests/data/mysql2date.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStubs\WordPress\Core\Tests;
6+
7+
use function mysql2date;
8+
use function PHPStan\Testing\assertType;
9+
10+
$time = '1970-01-01 00:00:00';
11+
12+
// Constant strings
13+
assertType('int|false', mysql2date('G', $time));
14+
assertType('int|false', mysql2date('U', $time));
15+
assertType('string|false', mysql2date('Y-m-d H:i:s', $time));
16+
17+
// Unknown string
18+
assertType('int|string|false', mysql2date((string)$_GET['unknown_string'], $time));

tests/phpstan.neon

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
parameters:
2+
bootstrapFiles:
3+
- ../wordpress-stubs.php

wordpress-stubs.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -118472,7 +118472,7 @@ function apply_filters_ref_array($hook_name, $args)
118472118472
* @return bool|int If `$callback` is omitted, returns boolean for whether the hook has
118473118473
* anything registered. When checking a specific function, the priority
118474118474
* of that hook is returned, or false if the function is not attached.
118475-
* @phpstan-return ($callback is false ? bool : bool|int)
118475+
* @phpstan-return ($callback is false ? bool : false|int)
118476118476
*/
118477118477
function has_filter($hook_name, $callback = \false)
118478118478
{
@@ -118664,7 +118664,7 @@ function do_action_ref_array($hook_name, $args)
118664118664
* @return bool|int If `$callback` is omitted, returns boolean for whether the hook has
118665118665
* anything registered. When checking a specific function, the priority
118666118666
* of that hook is returned, or false if the function is not attached.
118667-
* @phpstan-return ($callback is false ? bool : bool|int)
118667+
* @phpstan-return ($callback is false ? bool : false|int)
118668118668
*/
118669118669
function has_action($hook_name, $callback = \false)
118670118670
{
@@ -126823,7 +126823,7 @@ function get_taxonomies($args = array(), $output = 'names', $operator = 'and')
126823126823
* @param string $output Optional. The type of output to return in the array. Accepts either
126824126824
* 'names' or 'objects'. Default 'names'.
126825126825
* @return string[]|WP_Taxonomy[] The names or objects of all taxonomies of `$object_type`.
126826-
* @phpstan-return ($output is 'names' ? array<int, string> : array<int, \WP_Taxonomy>)
126826+
* @phpstan-return ($output is 'names' ? array<int, string> : array<string, \WP_Taxonomy>)
126827126827
*/
126828126828
function get_object_taxonomies($object_type, $output = 'names')
126829126829
{

0 commit comments

Comments
 (0)