/**
* This test loops through the DataProvider (which provides a list of public
* methods from ReflectionClass), ensures the method exists in ReflectionObject
* and that when the method is called on ReflectionObject, the method of the
* same name on ReflectionClass is also called.
*
* @param string $methodName
* @dataProvider reflectionClassMethodProvider
*/
public function testReflectionObjectOverridesAllMethodsInReflectionClass($methodName)
{
// First, ensure the expected method even exists
$publicObjectMethods = get_class_methods(ReflectionObject::class);
$this->assertContains($methodName, $publicObjectMethods);
// Create a mock that will be used to assert that the named method will
// be called when we call the same method on ReflectionObject
$mockReflectionClass = $this->getMockBuilder(ReflectionClass::class)->disableOriginalConstructor()->setMethods([$methodName])->getMock();
$mockReflectionClass->expects($this->atLeastOnce())->method($methodName);
// Force inject node and locatedSource properties on our ReflectionClass
// mock so that methods will not fail when they are accessed
$mockReflectionClassReflection = new \ReflectionClass(ReflectionClass::class);
$php = '<?php class stdClass {}';
$mockReflectionClassNodeReflection = $mockReflectionClassReflection->getProperty('locatedSource');
$mockReflectionClassNodeReflection->setAccessible(true);
$mockReflectionClassNodeReflection->setValue($mockReflectionClass, new EvaledLocatedSource($php));
$mockReflectionClassNodeReflection = $mockReflectionClassReflection->getProperty('node');
$mockReflectionClassNodeReflection->setAccessible(true);
$mockReflectionClassNodeReflection->setValue($mockReflectionClass, $this->getPhpParser()->parse($php)[0]);
// Create the ReflectionObject from a dummy class
$reflectionObject = ReflectionObject::createFromInstance(new \stdClass());
// Override the reflectionClass property on the ReflectionObject to use
// the mocked reflectionclass above
$reflectionObjectReflection = new \ReflectionObject($reflectionObject);
$reflectionObjectReflectionClassPropertyReflection = $reflectionObjectReflection->getProperty('reflectionClass');
$reflectionObjectReflectionClassPropertyReflection->setAccessible(true);
$reflectionObjectReflectionClassPropertyReflection->setValue($reflectionObject, $mockReflectionClass);
// Finally, call the method name with some dummy parameters. This should
// ensure that the method of the same name gets called on the
// $mockReflectionClass mock (as we expect $methodName to be called)
$reflectionObject->{$methodName}('foo', 'bar', 'baz');
}