Skip to content

Commit 0daa228

Browse files
authored
Use Faker for unions in type inference (#295)
1 parent 731de42 commit 0daa228

12 files changed

+77
-60
lines changed

phpstan.neon.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ parameters:
1515
-
1616
path: tests/Faker.php
1717
identifier: class.notFound
18-
count: 8
18+
count: 9

tests/Faker.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* @method static \WP_Translations wpTranslations()
3434
* @method static \WP_Query wpQuery()
3535
* @method static \WP_Widget_Factory wpWidgetFactory()
36+
* @method static \wpdb wpdb()
3637
*/
3738
class Faker
3839
{

tests/data/Faker.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,13 @@
4747
assertType('array<mixed>', Faker::union(Faker::array(), Faker::strArray()));
4848
assertType('array<mixed>', Faker::union(Faker::array(), Faker::intArray()));
4949
assertType('string|null', Faker::union(Faker::string(), null));
50+
assertType("'bar'|'foo'", Faker::union('foo', 'bar'));
51+
assertType('string', Faker::union('foo', Faker::string()));
52+
assertType("'foo'|int", Faker::union('foo', Faker::int()));
53+
assertType("array{'baz'}|array{foo: 'bar'}", Faker::union(['foo' => 'bar'], ['baz']));
5054

5155
// Other
56+
assertType('callable(): mixed', Faker::callable());
5257
assertType('resource', Faker::resource());
5358
assertType('object', Faker::object());
5459
assertType('stdClass', Faker::stdClass());
@@ -60,4 +65,5 @@
6065
assertType('WP_Translations', Faker::wpTranslations());
6166
assertType('WP_Query', Faker::wpQuery());
6267
assertType('WP_Widget_Factory', Faker::wpWidgetFactory());
68+
assertType('wpdb', Faker::wpdb());
6369
assertType('mixed', Faker::mixed());

tests/data/_get_list_table.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@
3535
assertType('WP_Privacy_Data_Removal_Requests_List_Table', _get_list_table('WP_Privacy_Data_Removal_Requests_List_Table'));
3636

3737
// Union of core WP_List_Table classes
38-
assertType('WP_Media_List_Table|WP_Posts_List_Table', _get_list_table(isset($_GET['foo']) ? 'WP_Posts_List_Table' : 'WP_Media_List_Table'));
38+
assertType('WP_Media_List_Table|WP_Posts_List_Table', _get_list_table(Faker::union('WP_Posts_List_Table', 'WP_Media_List_Table')));
3939

4040
// Union of core WP_List_Table class and class that is not a subclass of WP_List_Table
41-
assertType('WP_Posts_List_Table|false', _get_list_table(isset($_GET['foo']) ? 'WP_Posts_List_Table' : 'WP_Post'));
41+
assertType('WP_Posts_List_Table|false', _get_list_table(Faker::union('WP_Posts_List_Table', 'WP_Post')));
4242

4343
// WP_Post_Comments_List_Table is generalized WP_Comments_List_Table
44-
assertType('WP_Comments_List_Table', _get_list_table(isset($_GET['foo']) ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table'));
44+
assertType('WP_Comments_List_Table', _get_list_table(Faker::union('WP_Comments_List_Table', 'WP_Post_Comments_List_Table')));
4545

4646
// WP_Theme_Install_List_Table is generalized to WP_Themes_List_Table
47-
assertType('WP_Themes_List_Table', _get_list_table(isset($_GET['foo']) ? 'WP_Themes_List_Table' : 'WP_Theme_Install_List_Table'));
47+
assertType('WP_Themes_List_Table', _get_list_table(Faker::union('WP_Themes_List_Table', 'WP_Theme_Install_List_Table')));
4848

4949
// Unknown string
5050
assertType('WP_Application_Passwords_List_Table|WP_Comments_List_Table|WP_Links_List_Table|WP_Media_List_Table|WP_MS_Sites_List_Table|WP_MS_Themes_List_Table|WP_MS_Users_List_Table|WP_Plugin_Install_List_Table|WP_Plugins_List_Table|WP_Posts_List_Table|WP_Privacy_Data_Export_Requests_List_Table|WP_Privacy_Data_Removal_Requests_List_Table|WP_Terms_List_Table|WP_Themes_List_Table|WP_Users_List_Table|false', _get_list_table(Faker::string()));

tests/data/get_attachment_taxonomies.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
assertType('array<int|string, string|WP_Taxonomy>', get_attachment_taxonomies(Faker::int(), Faker::string()));
2222

2323
// Unions
24-
assertType('array<int|string, string|WP_Taxonomy>', get_attachment_taxonomies(Faker::int(), Faker::bool() ? 'names' : 'objects'));
25-
assertType('array<int|string, string|WP_Taxonomy>', get_attachment_taxonomies(Faker::int(), Faker::bool() ? Faker::string() : 'names'));
26-
assertType('array<int|string, string|WP_Taxonomy>', get_attachment_taxonomies(Faker::int(), Faker::bool() ? Faker::string() : 'objects'));
24+
assertType('array<int|string, string|WP_Taxonomy>', get_attachment_taxonomies(Faker::int(), Faker::union('names', 'objects')));
25+
assertType('array<int|string, string|WP_Taxonomy>', get_attachment_taxonomies(Faker::int(), Faker::union(Faker::string(), 'names')));
26+
assertType('array<int|string, string|WP_Taxonomy>', get_attachment_taxonomies(Faker::int(), Faker::union(Faker::string(), 'objects')));

tests/data/get_object_taxonomies.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', Faker::string()));
2222

2323
// Unions
24-
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', Faker::bool() ? 'names' : 'objects'));
25-
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', Faker::bool() ? Faker::string() : 'names'));
26-
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', Faker::bool() ? Faker::string() : 'objects'));
24+
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', Faker::union('names', 'objects')));
25+
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', Faker::union(Faker::string(), 'names')));
26+
assertType('array<int|string, string|WP_Taxonomy>', get_object_taxonomies('post', Faker::union(Faker::string(), 'objects')));

tests/data/get_post_stati.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@
2222
assertType('array<string, stdClass|string>', get_post_stati([], Faker::string()));
2323

2424
// Unions
25-
assertType('array<string, stdClass|string>', get_post_stati([], Faker::bool() ? 'names' : 'objects'));
26-
assertType('array<string, stdClass|string>', get_post_stati([], Faker::bool() ? Faker::string() : 'names'));
27-
assertType('array<string, stdClass|string>', get_post_stati([], Faker::bool() ? Faker::string() : 'objects'));
25+
assertType('array<string, stdClass|string>', get_post_stati([], Faker::union('names', 'objects')));
26+
assertType('array<string, stdClass|string>', get_post_stati([], Faker::union(Faker::string(), 'names')));
27+
assertType('array<string, stdClass|string>', get_post_stati([], Faker::union(Faker::string(), 'objects')));

tests/data/get_posts.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,50 @@
1818
assertType('array<int, int|WP_Post>', get_posts(Faker::array()));
1919

2020
// Unions
21-
$union = Faker::bool() ? ['key' => 'value'] : ['some' => 'thing'];
21+
$union = Faker::union(['key' => 'value'], ['some' => 'thing']);
2222
assertType('array<int, WP_Post>', get_posts($union));
2323

24-
$union = Faker::bool() ? ['key' => 'value'] : ['fields' => 'ids'];
24+
$union = Faker::union(['key' => 'value'], ['fields' => 'ids']);
2525
assertType('array<int, int|WP_Post>', get_posts($union));
2626

27-
$union = Faker::bool() ? ['key' => 'value'] : ['fields' => ''];
27+
$union = Faker::union(['key' => 'value'], ['fields' => '']);
2828
assertType('array<int, WP_Post>', get_posts($union));
2929

30-
$union = Faker::bool() ? ['key' => 'value'] : ['fields' => 'id=>parent'];
30+
$union = Faker::union(['key' => 'value'], ['fields' => 'id=>parent']);
3131
assertType('array<int, int|WP_Post>', get_posts($union));
3232

33-
$union = Faker::bool() ? ['fields' => ''] : ['fields' => 'ids'];
33+
$union = Faker::union(['fields' => ''], ['fields' => 'ids']);
3434
assertType('array<int, int|WP_Post>', get_posts($union));
3535

36-
$union = Faker::bool() ? ['fields' => ''] : ['fields' => 'id=>parent'];
36+
$union = Faker::union(['fields' => ''], ['fields' => 'id=>parent']);
3737
assertType('array<int, int|WP_Post>', get_posts($union));
3838

39-
$union = Faker::bool() ? ['fields' => 'ids'] : ['fields' => 'id=>parent'];
39+
$union = Faker::union(['fields' => 'ids'], ['fields' => 'id=>parent']);
4040
assertType('array<int, int>', get_posts($union));
4141

42-
$union = Faker::bool() ? Faker::array() : ['fields' => ''];
42+
$union = Faker::union(Faker::array(), ['fields' => '']);
4343
assertType('array<int, int|WP_Post>', get_posts($union));
4444

45-
$union = Faker::bool() ? Faker::array() : ['fields' => 'ids'];
45+
$union = Faker::union(Faker::array(), ['fields' => 'ids']);
4646
assertType('array<int, int|WP_Post>', get_posts($union));
4747

48-
$union = Faker::bool() ? Faker::array() : ['fields' => 'id=>parent'];
48+
$union = Faker::union(Faker::array(), ['fields' => 'id=>parent']);
4949
assertType('array<int, int|WP_Post>', get_posts($union));
5050

51-
$union = Faker::bool() ? Faker::string() : '';
51+
$union = Faker::union(Faker::string(), '');
5252
assertType('array<int, int|WP_Post>', get_posts(['fields' => $union]));
5353

54-
$union = Faker::bool() ? Faker::string() : 'ids';
54+
$union = Faker::union(Faker::string(), 'ids');
5555
assertType('array<int, int|WP_Post>', get_posts(['fields' => $union]));
5656

57-
$union = Faker::bool() ? Faker::string() : 'id=>parent';
57+
$union = Faker::union(Faker::string(), 'id=>parent');
5858
assertType('array<int, int|WP_Post>', get_posts(['fields' => $union]));
5959

60-
$union = Faker::bool() ? Faker::string() : 'fields';
60+
$union = Faker::union(Faker::string(), 'fields');
6161
assertType('array<int, WP_Post>', get_posts([$union => '']));
6262

63-
$union = Faker::bool() ? Faker::string() : 'fields';
63+
$union = Faker::union(Faker::string(), 'fields');
6464
assertType('array<int, int|WP_Post>', get_posts([$union => 'ids']));
6565

66-
$union = Faker::bool() ? Faker::string() : 'fields';
66+
$union = Faker::union(Faker::string(), 'fields');
6767
assertType('array<int, int|WP_Post>', get_posts([$union => 'id=>parent']));

tests/data/get_taxonomies_for_attachments.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
assertType('array<int|string, string|WP_Taxonomy>', get_taxonomies_for_attachments(Faker::string()));
2222

2323
// Unions
24-
assertType('array<int|string, string|WP_Taxonomy>', get_taxonomies_for_attachments(Faker::bool() ? 'names' : 'objects'));
25-
assertType('array<int|string, string|WP_Taxonomy>', get_taxonomies_for_attachments(Faker::bool() ? Faker::string() : 'names'));
26-
assertType('array<int|string, string|WP_Taxonomy>', get_taxonomies_for_attachments(Faker::bool() ? Faker::string() : 'objects'));
24+
assertType('array<int|string, string|WP_Taxonomy>', get_taxonomies_for_attachments(Faker::union('names', 'objects')));
25+
assertType('array<int|string, string|WP_Taxonomy>', get_taxonomies_for_attachments(Faker::union(Faker::string(), 'names')));
26+
assertType('array<int|string, string|WP_Taxonomy>', get_taxonomies_for_attachments(Faker::union(Faker::string(), 'objects')));

tests/data/term_exists.php

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,49 @@
88
use function tag_exists;
99
use function PHPStan\Testing\assertType;
1010

11-
$term = $_GET['term'] ?? 123;
12-
$taxo = $_GET['taxo'] ?? 'category';
11+
$termStr = Faker::string();
12+
$termInt = Faker::int();
13+
$termIntStr = Faker::union(Faker::int(), Faker::string());
1314

1415
// Empty taxonomy
1516
assertType('string|null', term_exists(123));
1617
assertType('string|null', term_exists(123, ''));
17-
assertType('0|string|null', term_exists($term));
18-
assertType('0|string|null', term_exists($term, ''));
18+
assertType('string|null', term_exists($termStr));
19+
assertType('string|null', term_exists($termStr, ''));
20+
assertType('0|string|null', term_exists($termInt));
21+
assertType('0|string|null', term_exists($termInt, ''));
22+
assertType('0|string|null', term_exists($termIntStr));
23+
assertType('0|string|null', term_exists($termIntStr, ''));
1924

2025
// Fixed taxonomy string
2126
assertType('array{term_id: string, term_taxonomy_id: string}|null', term_exists(123, 'category'));
22-
assertType('0|array{term_id: string, term_taxonomy_id: string}|null', term_exists($term, 'category'));
27+
assertType('array{term_id: string, term_taxonomy_id: string}|null', term_exists($termStr, 'category'));
28+
assertType('0|array{term_id: string, term_taxonomy_id: string}|null', term_exists($termInt, 'category'));
29+
assertType('0|array{term_id: string, term_taxonomy_id: string}|null', term_exists($termIntStr, 'category'));
2330

2431
// Unknown taxonomy type
25-
assertType('array{term_id: string, term_taxonomy_id: string}|string|null', term_exists(123, $taxo));
26-
assertType('0|array{term_id: string, term_taxonomy_id: string}|string|null', term_exists($term, $taxo));
27-
assertType('null', term_exists('', $taxo));
32+
$taxonomy = (string)$_GET['taxonomy'] ?? '';
33+
assertType('array{term_id: string, term_taxonomy_id: string}|string|null', term_exists(123, Faker::string()));
34+
assertType('array{term_id: string, term_taxonomy_id: string}|string|null', term_exists($termStr, $taxonomy));
35+
assertType('0|array{term_id: string, term_taxonomy_id: string}|string|null', term_exists($termInt, Faker::string()));
36+
assertType('0|array{term_id: string, term_taxonomy_id: string}|string|null', term_exists($termIntStr, Faker::string()));
2837

2938
// Term 0
3039
assertType('0', term_exists(0));
3140
assertType('0', term_exists(0, ''));
3241
assertType('0', term_exists(0, 'category'));
33-
assertType('0', term_exists(0, $taxo));
42+
assertType('0', term_exists(0, Faker::string()));
3443

3544
// Term empty string
3645
assertType('null', term_exists(''));
3746
assertType('null', term_exists('', ''));
3847
assertType('null', term_exists('', 'category'));
39-
assertType('null', term_exists('', $taxo));
48+
assertType('null', term_exists('', Faker::string()));
4049

4150
// tag_exists()
42-
assertType('array{term_id: string, term_taxonomy_id: string}|null', tag_exists(123));
43-
assertType('0|array{term_id: string, term_taxonomy_id: string}|null', tag_exists($term));
4451
assertType('0', tag_exists(0));
4552
assertType('null', tag_exists(''));
53+
assertType('array{term_id: string, term_taxonomy_id: string}|null', tag_exists(123));
54+
assertType('array{term_id: string, term_taxonomy_id: string}|null', tag_exists($termStr));
55+
assertType('0|array{term_id: string, term_taxonomy_id: string}|null', tag_exists($termInt));
56+
assertType('0|array{term_id: string, term_taxonomy_id: string}|null', tag_exists($termIntStr));

0 commit comments

Comments
 (0)