Skip to content

Commit 6e40d3f

Browse files
Refacto queryResultTypeWalkerTest
1 parent 6116afd commit 6e40d3f

File tree

3 files changed

+350
-309
lines changed

3 files changed

+350
-309
lines changed

Diff for: phpunit.xml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
<testsuites>
3434
<testsuite name="PHPStan for Doctrine">
35+
<directory suffix="TestCase.php">tests</directory>
3536
<directory suffix="Test.php">tests</directory>
3637
</testsuite>
3738
</testsuites>

Diff for: tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php renamed to tests/Type/Doctrine/Query/PDOQueryResultTypeWalkerTest.php

+3-309
Original file line numberDiff line numberDiff line change
@@ -6,232 +6,35 @@
66
use Composer\Semver\VersionParser;
77
use DateTime;
88
use DateTimeImmutable;
9-
use Doctrine\Common\Collections\ArrayCollection;
10-
use Doctrine\ORM\EntityManagerInterface;
119
use Doctrine\ORM\Mapping\Column;
12-
use Doctrine\ORM\Query\AST\TypedExpression;
13-
use Doctrine\ORM\Tools\SchemaTool;
14-
use PHPStan\Testing\PHPStanTestCase;
15-
use PHPStan\Type\Accessory\AccessoryNumericStringType;
16-
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
1710
use PHPStan\Type\Constant\ConstantIntegerType;
1811
use PHPStan\Type\Constant\ConstantStringType;
19-
use PHPStan\Type\ConstantTypeHelper;
20-
use PHPStan\Type\Doctrine\DescriptorRegistry;
2112
use PHPStan\Type\FloatType;
22-
use PHPStan\Type\IntegerRangeType;
2313
use PHPStan\Type\IntegerType;
24-
use PHPStan\Type\IntersectionType;
2514
use PHPStan\Type\MixedType;
2615
use PHPStan\Type\NullType;
2716
use PHPStan\Type\ObjectType;
2817
use PHPStan\Type\StringType;
2918
use PHPStan\Type\Type;
3019
use PHPStan\Type\TypeCombinator;
31-
use PHPStan\Type\UnionType;
32-
use PHPStan\Type\VerbosityLevel;
33-
use QueryResult\Entities\Embedded;
34-
use QueryResult\Entities\JoinedChild;
3520
use QueryResult\Entities\Many;
3621
use QueryResult\Entities\ManyId;
37-
use QueryResult\Entities\NestedEmbedded;
3822
use QueryResult\Entities\One;
3923
use QueryResult\Entities\OneId;
40-
use QueryResult\Entities\SingleTableChild;
41-
use QueryResult\EntitiesEnum\EntityWithEnum;
4224
use QueryResult\EntitiesEnum\IntEnum;
4325
use QueryResult\EntitiesEnum\StringEnum;
44-
use Throwable;
45-
use function array_merge;
46-
use function array_shift;
4726
use function assert;
4827
use function class_exists;
49-
use function count;
5028
use function property_exists;
51-
use function sprintf;
5229
use function strpos;
53-
use function version_compare;
5430
use const PHP_VERSION_ID;
5531

56-
final class QueryResultTypeWalkerTest extends PHPStanTestCase
32+
final class PDOQueryResultTypeWalkerTest extends QueryResultTypeWalkerTestCase
5733
{
5834

59-
/** @var EntityManagerInterface */
60-
private static $em;
61-
62-
/** @var DescriptorRegistry */
63-
private $descriptorRegistry;
64-
65-
public static function getAdditionalConfigFiles(): array
66-
{
67-
return [
68-
__DIR__ . '/../data/QueryResult/config.neon',
69-
];
70-
}
71-
72-
public static function setUpBeforeClass(): void
73-
{
74-
$em = require __DIR__ . '/../data/QueryResult/entity-manager.php';
75-
self::$em = $em;
76-
77-
$schemaTool = new SchemaTool($em);
78-
$classes = $em->getMetadataFactory()->getAllMetadata();
79-
$schemaTool->createSchema($classes);
80-
81-
$dataOne = [
82-
'intColumn' => [1, 2],
83-
'stringColumn' => ['A', 'B'],
84-
'stringNullColumn' => ['A', null],
85-
];
86-
87-
$dataMany = [
88-
'intColumn' => [1, 2],
89-
'stringColumn' => ['A', 'B'],
90-
'stringNullColumn' => ['A', null],
91-
];
92-
93-
$dataJoinedInheritance = [
94-
'parentColumn' => [1, 2],
95-
'parentNullColumn' => [1, null],
96-
'childColumn' => [1, 2],
97-
'childNullColumn' => [1, null],
98-
];
99-
100-
$dataSingleTableInheritance = [
101-
'parentColumn' => [1, 2],
102-
'parentNullColumn' => [1, null],
103-
'childNullColumn' => [1, null],
104-
];
105-
106-
$id = 1;
107-
108-
foreach (self::combinations($dataOne) as $combination) {
109-
[$intColumn, $stringColumn, $stringNullColumn] = $combination;
110-
$one = new One();
111-
$one->id = (string) $id++;
112-
$one->intColumn = $intColumn;
113-
$one->stringColumn = $stringColumn;
114-
$one->stringNullColumn = $stringNullColumn;
115-
$embedded = new Embedded();
116-
$embedded->intColumn = $intColumn;
117-
$embedded->stringColumn = $stringColumn;
118-
$embedded->stringNullColumn = $stringNullColumn;
119-
$nestedEmbedded = new NestedEmbedded();
120-
$nestedEmbedded->intColumn = $intColumn;
121-
$nestedEmbedded->stringColumn = $stringColumn;
122-
$nestedEmbedded->stringNullColumn = $stringNullColumn;
123-
$embedded->nestedEmbedded = $nestedEmbedded;
124-
$one->embedded = $embedded;
125-
$one->manies = new ArrayCollection();
126-
127-
foreach (self::combinations($dataMany) as $combinationMany) {
128-
[$intColumnMany, $stringColumnMany, $stringNullColumnMany] = $combinationMany;
129-
$many = new Many();
130-
$many->id = (string) $id++;
131-
$many->intColumn = $intColumnMany;
132-
$many->stringColumn = $stringColumnMany;
133-
$many->stringNullColumn = $stringNullColumnMany;
134-
$many->datetimeColumn = new DateTime('2001-01-01 00:00:00');
135-
$many->datetimeImmutableColumn = new DateTimeImmutable('2001-01-01 00:00:00');
136-
$many->simpleArrayColumn = ['foo'];
137-
$many->one = $one;
138-
$one->manies->add($many);
139-
$em->persist($many);
140-
}
141-
142-
$em->persist($one);
143-
}
144-
145-
foreach (self::combinations($dataJoinedInheritance) as $combination) {
146-
[$parentColumn, $parentNullColumn, $childColumn, $childNullColumn] = $combination;
147-
$child = new JoinedChild();
148-
$child->id = (string) $id++;
149-
$child->parentColumn = $parentColumn;
150-
$child->parentNullColumn = $parentNullColumn;
151-
$child->childColumn = $childColumn;
152-
$child->childNullColumn = $childNullColumn;
153-
$em->persist($child);
154-
}
155-
156-
foreach (self::combinations($dataSingleTableInheritance) as $combination) {
157-
[$parentColumn, $parentNullColumn, $childNullColumn] = $combination;
158-
$child = new SingleTableChild();
159-
$child->id = (string) $id++;
160-
$child->parentColumn = $parentColumn;
161-
$child->parentNullColumn = $parentNullColumn;
162-
$child->childNullColumn = $childNullColumn;
163-
$em->persist($child);
164-
}
165-
166-
if (property_exists(Column::class, 'enumType') && PHP_VERSION_ID >= 80100) {
167-
assert(class_exists(StringEnum::class));
168-
assert(class_exists(IntEnum::class));
169-
170-
$entityWithEnum = new EntityWithEnum();
171-
$entityWithEnum->id = '1';
172-
$entityWithEnum->stringEnumColumn = StringEnum::A;
173-
$entityWithEnum->intEnumColumn = IntEnum::A;
174-
$entityWithEnum->intEnumOnStringColumn = IntEnum::A;
175-
$em->persist($entityWithEnum);
176-
}
177-
178-
$em->flush();
179-
}
180-
181-
public static function tearDownAfterClass(): void
182-
{
183-
self::$em->clear();
184-
}
185-
186-
public function setUp(): void
35+
protected static function getEntityManagerPath(): string
18736
{
188-
$this->descriptorRegistry = self::getContainer()->getByType(DescriptorRegistry::class);
189-
}
190-
191-
/** @dataProvider getTestData */
192-
public function test(Type $expectedType, string $dql, ?string $expectedExceptionMessage = null, ?string $expectedDeprecationMessage = null): void
193-
{
194-
$em = self::$em;
195-
196-
$query = $em->createQuery($dql);
197-
198-
$typeBuilder = new QueryResultTypeBuilder();
199-
200-
if ($expectedExceptionMessage !== null) {
201-
$this->expectException(Throwable::class);
202-
$this->expectExceptionMessage($expectedExceptionMessage);
203-
} elseif ($expectedDeprecationMessage !== null) {
204-
$this->expectDeprecation();
205-
$this->expectDeprecationMessage($expectedDeprecationMessage);
206-
}
207-
208-
QueryResultTypeWalker::walk($query, $typeBuilder, $this->descriptorRegistry);
209-
210-
$type = $typeBuilder->getResultType();
211-
212-
self::assertSame(
213-
$expectedType->describe(VerbosityLevel::precise()),
214-
$type->describe(VerbosityLevel::precise())
215-
);
216-
217-
// Double-check our expectations
218-
219-
$query = $em->createQuery($dql);
220-
221-
$result = $query->getResult();
222-
self::assertGreaterThan(0, count($result));
223-
224-
foreach ($result as $row) {
225-
$rowType = ConstantTypeHelper::getTypeFromValue($row);
226-
self::assertTrue(
227-
$type->accepts($rowType, true)->yes(),
228-
sprintf(
229-
"The inferred type\n%s\nshould accept actual type\n%s",
230-
$type->describe(VerbosityLevel::precise()),
231-
$rowType->describe(VerbosityLevel::precise())
232-
)
233-
);
234-
}
37+
return __DIR__ . '/../data/QueryResult/entity-manager.php';
23538
}
23639

23740
/**
@@ -1591,113 +1394,4 @@ public function getTestData(): iterable
15911394
];
15921395
}
15931396

1594-
/**
1595-
* @param array<int,array{0: ConstantIntegerType|ConstantStringType, 1: Type, 2?: bool}> $elements
1596-
*/
1597-
private function constantArray(array $elements): Type
1598-
{
1599-
$builder = ConstantArrayTypeBuilder::createEmpty();
1600-
1601-
foreach ($elements as $element) {
1602-
$offsetType = $element[0];
1603-
$valueType = $element[1];
1604-
$optional = $element[2] ?? false;
1605-
$builder->setOffsetValueType($offsetType, $valueType, $optional);
1606-
}
1607-
1608-
return $builder->getArray();
1609-
}
1610-
1611-
private function numericStringOrInt(): Type
1612-
{
1613-
return new UnionType([
1614-
new IntegerType(),
1615-
new IntersectionType([
1616-
new StringType(),
1617-
new AccessoryNumericStringType(),
1618-
]),
1619-
]);
1620-
}
1621-
1622-
private function numericString(): Type
1623-
{
1624-
return new IntersectionType([
1625-
new StringType(),
1626-
new AccessoryNumericStringType(),
1627-
]);
1628-
}
1629-
1630-
private function uint(): Type
1631-
{
1632-
return IntegerRangeType::fromInterval(0, null);
1633-
}
1634-
1635-
private function intStringified(): Type
1636-
{
1637-
return TypeCombinator::union(
1638-
new IntegerType(),
1639-
$this->numericString()
1640-
);
1641-
}
1642-
private function uintStringified(): Type
1643-
{
1644-
return TypeCombinator::union(
1645-
$this->uint(),
1646-
$this->numericString()
1647-
);
1648-
}
1649-
1650-
private function numericStringified(): Type
1651-
{
1652-
return TypeCombinator::union(
1653-
new FloatType(),
1654-
new IntegerType(),
1655-
$this->numericString()
1656-
);
1657-
}
1658-
1659-
private function unumericStringified(): Type
1660-
{
1661-
return TypeCombinator::union(
1662-
new FloatType(),
1663-
IntegerRangeType::fromInterval(0, null),
1664-
$this->numericString()
1665-
);
1666-
}
1667-
1668-
private function hasTypedExpressions(): bool
1669-
{
1670-
return class_exists(TypedExpression::class);
1671-
}
1672-
1673-
/**
1674-
* @param array<mixed[]> $arrays
1675-
*
1676-
* @return iterable<mixed[]>
1677-
*/
1678-
private static function combinations(array $arrays): iterable
1679-
{
1680-
if ($arrays === []) {
1681-
yield [];
1682-
return;
1683-
}
1684-
1685-
$head = array_shift($arrays);
1686-
1687-
foreach ($head as $elem) {
1688-
foreach (self::combinations($arrays) as $combination) {
1689-
yield array_merge([$elem], $combination);
1690-
}
1691-
}
1692-
}
1693-
1694-
private function isDoctrine211(): bool
1695-
{
1696-
$version = InstalledVersions::getVersion('doctrine/orm');
1697-
1698-
return $version !== null
1699-
&& version_compare($version, '2.11', '>=')
1700-
&& version_compare($version, '2.12', '<');
1701-
}
1702-
17031397
}

0 commit comments

Comments
 (0)