Skip to content

Commit

Permalink
#135 rewrote AnnotationRegistry tests to prevent reflection reads
Browse files Browse the repository at this point in the history
  • Loading branch information
Ocramius committed Jul 22, 2017
1 parent 0a1b8d7 commit 8750460
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 18 deletions.
5 changes: 1 addition & 4 deletions lib/Doctrine/Common/Annotations/AnnotationRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,8 @@ static public function registerAutoloadNamespaces(array $namespaces)
*
* @throws \InvalidArgumentException
*/
static public function registerLoader($callable)
static public function registerLoader(callable $callable)
{
if (!is_callable($callable)) {
throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader().");
}
// Reset our static cache now that we have a new loader to work with
self::$failedToAutoload = array();
self::$loaders[] = $callable;
Expand Down
88 changes: 74 additions & 14 deletions tests/Doctrine/Tests/Common/Annotations/AnnotationRegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ public function testReset()

self::assertEmpty($this->getStaticField($this->class, 'autoloadNamespaces'));
self::assertEmpty($this->getStaticField($this->class, 'loaders'));
self::assertEmpty($this->getStaticField($this->class, 'loaded'));
self::assertEmpty($this->getStaticField($this->class, 'unloadable'));
}

/**
Expand Down Expand Up @@ -68,7 +66,10 @@ protected function getStaticField($class, $field)
return $reflection->getValue();
}

public function testStopCallingLoadersIfClassIsNotFound()
/**
* @runInSeparateProcess
*/
public function testStopCallingLoadersIfClassIsNotFound() : void
{
AnnotationRegistry::reset();
$i = 0;
Expand All @@ -83,29 +84,88 @@ public function testStopCallingLoadersIfClassIsNotFound()
$this->assertEquals(1, $i, 'Autoloader should only be called once');
}

public function testStopCallingLoadersAfterClassIsFound()
/**
* @runInSeparateProcess
*/
public function testStopCallingLoadersAfterClassIsFound() : void
{
$className = 'autoloadedClass' . random_int(10, 100000);
AnnotationRegistry::reset();
$i = 0;
$autoLoader = function($annotation) use (&$i) {
$autoLoader = function($annotation) use (&$i, $className) {
eval('class ' . $className . ' {}');
$i++;
return true;
};
AnnotationRegistry::registerLoader($autoLoader);
AnnotationRegistry::loadAnnotationClass(self::class);
AnnotationRegistry::loadAnnotationClass(self::class);
AnnotationRegistry::loadAnnotationClass(self::class);
AnnotationRegistry::loadAnnotationClass($className);
AnnotationRegistry::loadAnnotationClass($className);
AnnotationRegistry::loadAnnotationClass($className);
$this->assertEquals(1, $i, 'Autoloader should only be called once');
}

public function testAddingANewLoaderClearsTheCache()
/**
* @runInSeparateProcess
*/
public function testAddingANewLoaderClearsTheCache() : void
{
$failures = 0;
$failingLoader = function (string $annotation) use (& $failures) : bool {
$failures += 1;

return false;
};

AnnotationRegistry::reset();
AnnotationRegistry::registerLoader($failingLoader);

self::assertSame(0, $failures);

AnnotationRegistry::loadAnnotationClass('unloadableClass');

self::assertSame(1, $failures);

AnnotationRegistry::loadAnnotationClass('unloadableClass');

self::assertSame(1, $failures);

AnnotationRegistry::registerLoader(function () {
return false;
});
AnnotationRegistry::loadAnnotationClass('unloadableClass');

self::assertSame(2, $failures);
}

/**
* @runInSeparateProcess
*/
public function testResetClearsRegisteredAutoloaderFailures() : void
{
$failures = 0;
$failingLoader = function (string $annotation) use (& $failures) : bool {
$failures += 1;

return false;
};

AnnotationRegistry::reset();
AnnotationRegistry::registerLoader('class_exists');
AnnotationRegistry::loadAnnotationClass(self::class);
AnnotationRegistry::registerLoader($failingLoader);

self::assertSame(0, $failures);

AnnotationRegistry::loadAnnotationClass('unloadableClass');

self::assertSame(1, $failures);

AnnotationRegistry::loadAnnotationClass('unloadableClass');
AnnotationRegistry::registerLoader('class_exists');
self::assertEmpty($this->getStaticField($this->class, 'loaded'));
self::assertEmpty($this->getStaticField($this->class, 'unloadable'));

self::assertSame(1, $failures);

AnnotationRegistry::reset();
AnnotationRegistry::registerLoader($failingLoader);
AnnotationRegistry::loadAnnotationClass('unloadableClass');

self::assertSame(2, $failures);
}
}

0 comments on commit 8750460

Please sign in to comment.