class HookOrderTest

@coversDefaultClass \Drupal\Core\Hook\HookOrder

@group Hook

Hierarchy

Expanded class hierarchy of HookOrderTest

File

core/tests/Drupal/Tests/Core/Hook/HookOrderTest.php, line 14

Namespace

Drupal\Tests\Core\Hook
View source
class HookOrderTest extends HookOrderTestBase {
    
    /**
     * The original priorities.
     *
     * @var array
     */
    protected array $originalPriorities = [];
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        // "c" first, "b" second, "a" last.
        $this->setUpContainer(TRUE);
        foreach ([
            'a',
            'b',
            'c',
        ] as $key) {
            $this->originalPriorities[$key] = $this->getPriority($key);
        }
        // The documentation does not clarify the order of arguments, let's do so
        // here to make it easier to develop/debug this test.
        $this->assertGreaterThan(1, 2);
        // According to https://symfony.com/doc/current/event_dispatcher.html
        // the higher the number, the earlier a listener is executed. Accordingly
        // assert that "a" is last, "c" is first, "b" is in the middle. The
        // asserts in methods can be compared to these establishing asserts.
        $this->assertGreaterThan($this->getPriority('a'), $this->getPriority('b'));
        $this->assertGreaterThan($this->getPriority('b'), $this->getPriority('c'));
        // This is unnecessary but asserts are free, and it's easier to compare if
        // this is explicit.
        $this->assertGreaterThan($this->getPriority('a'), $this->getPriority('c'));
    }
    
    /**
     * @covers ::first
     */
    public function testFirst() : void {
        // "c" was first, make "a" the first.
        HookOrder::first($this->container, 'test', 'a::a');
        $this->assertGreaterThan($this->getPriority('c'), $this->getPriority('a'));
        $this->assertGreaterThan($this->getPriority('b'), $this->getPriority('a'));
        // The other two shouldn't change.
        $this->assertNoChange('a');
    }
    
    /**
     * @covers ::last
     */
    public function testLast() : void {
        // "c" was first, make it the last.
        HookOrder::last($this->container, 'test', 'c::c');
        $this->assertGreaterThan($this->getPriority('c'), $this->getPriority('a'));
        $this->assertGreaterThan($this->getPriority('c'), $this->getPriority('b'));
        // The other two shouldn't change.
        $this->assertNoChange('c');
    }
    
    /**
     * @covers ::before
     */
    public function testBefore() : void {
        // "a" was last, move it before "b".
        HookOrder::before($this->container, 'test', 'a::a', 'b::b');
        $this->assertGreaterThan($this->getPriority('b'), $this->getPriority('a'));
        // The relation between these should not change. The actual priority
        // might.
        $this->assertGreaterThan($this->getPriority('b'), $this->getPriority('c'));
        $this->assertGreaterThan($this->getPriority('a'), $this->getPriority('c'));
    }
    
    /**
     * @covers ::after
     */
    public function testAfter() : void {
        // "c" was first, move it after "b".
        HookOrder::after($this->container, 'test', 'c::c', 'b::b');
        $this->assertGreaterThan($this->getPriority('c'), $this->getPriority('b'));
        // The relation between these should not change. The actual priority
        // might.
        $this->assertGreaterThan($this->getPriority('a'), $this->getPriority('b'));
        $this->assertGreaterThan($this->getPriority('a'), $this->getPriority('c'));
    }
    
    /**
     * @covers ::first
     */
    public function testFirstNoChange() : void {
        // "c" was first, making it first should be a no-op.
        HookOrder::first($this->container, 'test', 'c::c');
        $this->assertNoChange();
    }
    
    /**
     * @covers ::last
     */
    public function testLastNoChange() : void {
        // "a" was last, making it last should be a no-op.
        HookOrder::last($this->container, 'test', 'a::a');
        $this->assertNoChange();
    }
    
    /**
     * @covers ::before
     */
    public function testBeforeNoChange() : void {
        // "b" is already firing before "a", this should be a no-op.
        HookOrder::before($this->container, 'test', 'b::b');
        $this->assertNoChange();
    }
    
    /**
     * @covers ::after
     */
    public function testAfterNoChange() : void {
        // "b' is already firing after "c", this should be a no-op.
        HookOrder::after($this->container, 'test', 'b::b');
        $this->assertNoChange();
    }
    
    /**
     * Get the priority for a service.
     */
    protected function getPriority(string $name) : int {
        $definition = $this->container
            ->getDefinition($name);
        return $definition->getTags()['kernel.event_listener'][0]['priority'];
    }
    
    /**
     * Asserts no change has happened.
     *
     * @param string $changed
     *   This one did change. Assert the rest did not change.
     */
    protected function assertNoChange(string $changed = '') : void {
        foreach ($this->originalPriorities as $key => $priority) {
            if ($key !== $changed) {
                $this->assertSame($priority, $this->getPriority($key));
            }
        }
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
ExpectDeprecationTrait::expectDeprecation public function Adds an expected deprecation.
ExpectDeprecationTrait::setUpErrorHandler public function Sets up the test error handler.
ExpectDeprecationTrait::tearDownErrorHandler public function Tears down the test error handler.
HookOrderTest::$originalPriorities protected property The original priorities.
HookOrderTest::assertNoChange protected function Asserts no change has happened.
HookOrderTest::getPriority protected function Get the priority for a service. Overrides HookOrderTestBase::getPriority
HookOrderTest::setUp protected function Overrides UnitTestCase::setUp
HookOrderTest::testAfter public function @covers ::after
HookOrderTest::testAfterNoChange public function @covers ::after
HookOrderTest::testBefore public function @covers ::before
HookOrderTest::testBeforeNoChange public function @covers ::before
HookOrderTest::testFirst public function @covers ::first
HookOrderTest::testFirstNoChange public function @covers ::first
HookOrderTest::testLast public function @covers ::last
HookOrderTest::testLastNoChange public function @covers ::last
HookOrderTestBase::$container protected property The container builder.
HookOrderTestBase::setUpContainer protected function Set up three service listeners, "a", "b" and "c".
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
UnitTestCase::$root protected property The app root.
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setDebugDumpHandler public static function Registers the dumper CLI handler when the DebugDump extension is enabled.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.