Skip to content

Commit ab84de7

Browse files
ACPT-1360: Automated test to validate _resetState methods cause same state as initially constructed
1 parent 0f6071c commit ab84de7

File tree

3 files changed

+146
-18
lines changed

3 files changed

+146
-18
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\ObjectManager;
7+
8+
use Magento\Framework\App\Utility\Classes;
9+
use Magento\Framework\ObjectManager\FactoryInterface as ObjectManagerFactoryInterface;
10+
use Magento\Framework\ObjectManagerInterface;
11+
use Magento\GraphQl\App\State\Collector;
12+
use Magento\GraphQl\App\State\Comparator;
13+
14+
/**
15+
* Test that verifies that resetState method for classes cause the state to be the same as it was initially constructed
16+
*/
17+
class ResetAfterRequestTest extends \PHPUnit\Framework\TestCase
18+
{
19+
20+
private static $objectManager;
21+
22+
private ?Comparator $comparator;
23+
private ?Collector $collector;
24+
25+
public static function setUpBeforeClass(): void
26+
{
27+
$config = new \Magento\Framework\ObjectManager\Config\Config();
28+
$factory = new Factory\Dynamic\Developer($config);
29+
self::$objectManager = new \Magento\Framework\ObjectManager\ObjectManager($factory, $config);
30+
// self::$objectManager->configure(
31+
// ['preferences' => [self::TEST_INTERFACE => self::TEST_INTERFACE_IMPLEMENTATION]]
32+
// );
33+
$factory->setObjectManager(self::$objectManager);
34+
}
35+
36+
public static function tearDownAfterClass(): void
37+
{
38+
self::$objectManager = null;
39+
}
40+
41+
/**
42+
* @return void
43+
*/
44+
protected function setUp(): void
45+
{
46+
parent::setUp();
47+
$this->comparator = static::$objectManager->create(Comparator::class);
48+
$this->collector = static::$objectManager->create(Collector::class);
49+
}
50+
51+
/**
52+
* Data provider for testNewInstance
53+
*
54+
* Provides list of all classes and virtual classes that implement ResetAfterRequestInterface
55+
*
56+
* @return array
57+
*/
58+
public function resetAfterRequestClassDataProvider()
59+
{
60+
$resetAfterRequestClasses = [];
61+
foreach (Classes::getVirtualClasses() as $name => $type ) {
62+
try {
63+
if (!class_exists($type)) {
64+
continue;
65+
}
66+
if (is_a($type, ObjectManagerInterface::class)) {
67+
continue;
68+
}
69+
if (is_a($type, ObjectManagerFactoryInterface::class)) {
70+
continue;
71+
}
72+
if (is_a($type, ResetAfterRequestInterface::class, true)) {
73+
$resetAfterRequestClasses[] = [$name];
74+
}
75+
} catch (\Error $error) {
76+
continue;
77+
}
78+
}
79+
foreach (array_keys(Classes::collectModuleClasses('[A-Z][a-z\d][A-Za-z\d\\\\]+')) as $type) {
80+
try {
81+
if (!class_exists($type)) {
82+
continue;
83+
}
84+
if (is_a($type, ObjectManagerInterface::class)) {
85+
continue;
86+
}
87+
if (is_a($type, ObjectManagerFactoryInterface::class)) {
88+
continue;
89+
}
90+
if (is_a($type, ResetAfterRequestInterface::class, true)) {
91+
$resetAfterRequestClasses[] = [$type];
92+
}
93+
} catch (\Throwable $throwable) {
94+
continue;
95+
}
96+
}
97+
return $resetAfterRequestClasses;
98+
}
99+
100+
/**
101+
* Verifies that resetState method for classes cause the state to be the same as it was initially constructed
102+
*
103+
* @param string $className
104+
* @dataProvider resetAfterRequestClassDataProvider
105+
*/
106+
public function testResetAfterRequestClasses(string $className)
107+
{
108+
/** @var ResetAfterRequestInterface $object */
109+
$object = self::$objectManager->get($className);
110+
$beforeProperties = $this->collector->getPropertiesFromObject($object);
111+
$object->_resetState();
112+
$afterProperties = $this->collector->getPropertiesFromObject($object);
113+
$differences = [];
114+
foreach ($afterProperties as $propertyName => $propertyValue) {
115+
$result = $this->comparator->checkValues($beforeProperties[$propertyName] ?? null, $propertyValue);
116+
if ($result) {
117+
$differences[$propertyName] = $result;
118+
}
119+
}
120+
$this->assertEmpty($differences, var_export($differences, true));
121+
}
122+
}

dev/tests/integration/testsuite/Magento/GraphQl/App/State/Collector.php

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,27 +73,33 @@ public function getSharedObjects(): array
7373
if ($object instanceof \Magento\Framework\ObjectManagerInterface) {
7474
continue;
7575
}
76-
$objReflection = new \ReflectionObject($object);
77-
$properties = [];
78-
foreach ($objReflection->getProperties() as $property) {
79-
$propName = $property->getName();
80-
$property->setAccessible(true);
81-
$value = $property->getValue($object);
82-
if (is_object($value)) {
83-
$didClone = true;
84-
$properties[$propName] = clone $value;
85-
continue;
86-
} elseif (is_array($value)) {
87-
$didClone = true;
88-
$properties[$propName] = $this->cloneArray($value);
89-
} else {
90-
$properties[$propName] = $value;
91-
}
92-
}
76+
$properties = $this->getPropertiesFromObject($object);
9377
$sharedObjects[$serviceName] = [$object, $properties];
9478
}
9579
// Note: We have to check again because sometimes cloning objects can indirectly cause adding to Object Manager
9680
} while ($didClone);
9781
return $sharedObjects;
9882
}
83+
84+
public function getPropertiesFromObject(object $object): array
85+
{
86+
$objReflection = new \ReflectionObject($object);
87+
$properties = [];
88+
foreach ($objReflection->getProperties() as $property) {
89+
$propName = $property->getName();
90+
$property->setAccessible(true);
91+
$value = $property->getValue($object);
92+
if (is_object($value)) {
93+
$didClone = true;
94+
$properties[$propName] = clone $value;
95+
continue;
96+
} elseif (is_array($value)) {
97+
$didClone = true;
98+
$properties[$propName] = $this->cloneArray($value);
99+
} else {
100+
$properties[$propName] = $value;
101+
}
102+
}
103+
return $properties;
104+
}
99105
}

dev/tests/integration/testsuite/Magento/GraphQl/App/State/Comparator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ private function formatValue($type): array
203203
* @return array
204204
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
205205
*/
206-
private function checkValues($before, $after): array
206+
public function checkValues($before, $after): array
207207
{
208208
$result = [];
209209
$typeBefore = gettype($before);

0 commit comments

Comments
 (0)