Make WordPress Core

Changeset 57257


Ignore:
Timestamp:
01/09/2024 04:32:14 PM (12 months ago)
Author:
hellofromTonya
Message:

Tests: Add hook priority call order tests.

Adds happy (integer) and unhappy (non-integer) tests for validating the priority call order for:

  • do_action()
  • WP_Hook::do_action()
  • apply_filters()
  • WP_Hook::apply_filters()

As each of these functions have differing code, the tests are added to each to ensure expected results and protect against future regressions.

Follow-up to [53804], [52010], [25002], [25/tests], [62/tests].

Props hellofromTonya, mukesh27, dd32, valendesigns, drrobotnik.
Fixes #60193.

Location:
trunk/tests/phpunit/tests
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/actions.php

    r56559 r57257  
    230230    }
    231231
    232     public function test_action_priority() {
    233         $a         = new MockAction();
    234         $hook_name = __FUNCTION__;
    235 
    236         add_action( $hook_name, array( &$a, 'action' ), 10 );
    237         add_action( $hook_name, array( &$a, 'action2' ), 9 );
     232    /**
     233     * @ticket 60193
     234     *
     235     * @dataProvider data_priority_callback_order_with_integers
     236     * @dataProvider data_priority_callback_order_with_unhappy_path_nonintegers
     237     *
     238     * @covers ::do_action
     239     *
     240     * @param array $priorities {
     241     *     Indexed array of the priorities for the MockAction callbacks.
     242     *
     243     *     @type mixed $0 Priority for 'action' callback.
     244     *     @type mixed $1 Priority for 'action2' callback.
     245     * }
     246     * @param array  $expected_call_order  An array of callback names in expected call order.
     247     * @param string $expected_deprecation Optional. Deprecation message. Default ''.
     248     */
     249    public function test_priority_callback_order( $priorities, $expected_call_order, $expected_deprecation = '' ) {
     250        $mock      = new MockAction();
     251        $hook_name = __FUNCTION__;
     252
     253        if ( $expected_deprecation && PHP_VERSION_ID >= 80100 ) {
     254            $this->expectDeprecation();
     255            $this->expectDeprecationMessage( $expected_deprecation );
     256        }
     257
     258        add_action( $hook_name, array( $mock, 'action' ), $priorities[0] );
     259        add_action( $hook_name, array( $mock, 'action2' ), $priorities[1] );
    238260        do_action( $hook_name );
    239261
    240         // Two events, one per action.
    241         $this->assertSame( 2, $a->get_call_count() );
    242 
    243         $expected = array(
    244             // 'action2' is called first because it has priority 9.
    245             array(
    246                 'action'    => 'action2',
    247                 'hook_name' => $hook_name,
    248                 'tag'       => $hook_name, // Back compat.
    249                 'args'      => array( '' ),
    250             ),
    251             // 'action' is called second.
    252             array(
    253                 'action'    => 'action',
    254                 'hook_name' => $hook_name,
    255                 'tag'       => $hook_name, // Back compat.
    256                 'args'      => array( '' ),
     262        $this->assertSame( 2, $mock->get_call_count(), 'The number of call counts does not match' );
     263
     264        $actual_call_order = wp_list_pluck( $mock->get_events(), 'action' );
     265        $this->assertSame( $expected_call_order, $actual_call_order, 'The action callback order does not match the expected order' );
     266    }
     267
     268    /**
     269     * Happy path data provider.
     270     *
     271     * @return array[]
     272     */
     273    public function data_priority_callback_order_with_integers() {
     274        return array(
     275            'int DESC' => array(
     276                'priorities'          => array( 10, 9 ),
     277                'expected_call_order' => array( 'action2', 'action' ),
     278            ),
     279            'int ASC'  => array(
     280                'priorities'          => array( 9, 10 ),
     281                'expected_call_order' => array( 'action', 'action2' ),
    257282            ),
    258283        );
    259 
    260         $this->assertSame( $expected, $a->get_events() );
     284    }
     285
     286    /**
     287     * Unhappy path data provider.
     288     *
     289     * @return array[]
     290     */
     291    public function data_priority_callback_order_with_unhappy_path_nonintegers() {
     292        return array(
     293            // Numbers as strings and floats.
     294            'int as string DESC'               => array(
     295                'priorities'          => array( '10', '9' ),
     296                'expected_call_order' => array( 'action2', 'action' ),
     297            ),
     298            'int as string ASC'                => array(
     299                'priorities'          => array( '9', '10' ),
     300                'expected_call_order' => array( 'action', 'action2' ),
     301            ),
     302            'float DESC'                       => array(
     303                'priorities'           => array( 10.0, 9.5 ),
     304                'expected_call_order'  => array( 'action2', 'action' ),
     305                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     306            ),
     307            'float ASC'                        => array(
     308                'priorities'           => array( 9.5, 10.0 ),
     309                'expected_call_order'  => array( 'action', 'action2' ),
     310                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     311            ),
     312            'float as string DESC'             => array(
     313                'priorities'          => array( '10.0', '9.5' ),
     314                'expected_call_order' => array( 'action2', 'action' ),
     315            ),
     316            'float as string ASC'              => array(
     317                'priorities'          => array( '9.5', '10.0' ),
     318                'expected_call_order' => array( 'action', 'action2' ),
     319            ),
     320
     321            // Non-numeric.
     322            'null'                             => array(
     323                'priorities'          => array( null, null ),
     324                'expected_call_order' => array( 'action', 'action2' ),
     325            ),
     326            'bool DESC'                        => array(
     327                'priorities'          => array( true, false ),
     328                'expected_call_order' => array( 'action2', 'action' ),
     329            ),
     330            'bool ASC'                         => array(
     331                'priorities'          => array( false, true ),
     332                'expected_call_order' => array( 'action', 'action2' ),
     333            ),
     334            'non-numerical string DESC'        => array(
     335                'priorities'          => array( 'test1', 'test2' ),
     336                'expected_call_order' => array( 'action', 'action2' ),
     337            ),
     338            'non-numerical string ASC'         => array(
     339                'priorities'          => array( 'test1', 'test2' ),
     340                'expected_call_order' => array( 'action', 'action2' ),
     341            ),
     342            'int, non-numerical string DESC'   => array(
     343                'priorities'          => array( 10, 'test' ),
     344                'expected_call_order' => array( 'action2', 'action' ),
     345            ),
     346            'int, non-numerical string ASC'    => array(
     347                'priorities'          => array( 'test', 10 ),
     348                'expected_call_order' => array( 'action', 'action2' ),
     349            ),
     350            'float, non-numerical string DESC' => array(
     351                'priorities'          => array( 10.0, 'test' ),
     352                'expected_call_order' => array( 'action2', 'action' ),
     353            ),
     354            'float, non-numerical string ASC'  => array(
     355                'priorities'          => array( 'test', 10.0 ),
     356                'expected_call_order' => array( 'action', 'action2' ),
     357            ),
     358        );
    261359    }
    262360
  • trunk/tests/phpunit/tests/filters.php

    r56548 r57257  
    119119    }
    120120
    121     public function test_filter_priority() {
    122         $a         = new MockAction();
    123         $hook_name = __FUNCTION__;
    124         $val       = __FUNCTION__ . '_val';
    125 
    126         // Make two filters with different priorities.
    127         add_filter( $hook_name, array( $a, 'filter' ), 10 );
    128         add_filter( $hook_name, array( $a, 'filter2' ), 9 );
    129         $this->assertSame( $val, apply_filters( $hook_name, $val ) );
    130 
    131         // There should be two events, one per filter.
    132         $this->assertSame( 2, $a->get_call_count() );
    133 
    134         $expected = array(
    135             // 'filter2' is called first because it has priority 9.
    136             array(
    137                 'filter'    => 'filter2',
    138                 'hook_name' => $hook_name,
    139                 'tag'       => $hook_name, // Back compat.
    140                 'args'      => array( $val ),
    141             ),
    142             // 'filter' is called second.
    143             array(
    144                 'filter'    => 'filter',
    145                 'hook_name' => $hook_name,
    146                 'tag'       => $hook_name, // Back compat.
    147                 'args'      => array( $val ),
     121    /**
     122     * @ticket 60193
     123     *
     124     * @dataProvider data_priority_callback_order_with_integers
     125     * @dataProvider data_priority_callback_order_with_unhappy_path_nonintegers
     126     *
     127     * @covers ::apply_filters
     128     *
     129     * @param array $priorities {
     130     *     Indexed array of the priorities for the MockAction callbacks.
     131     *
     132     *     @type mixed $0 Priority for 'action' callback.
     133     *     @type mixed $1 Priority for 'action2' callback.
     134     * }
     135     * @param array  $expected_call_order  An array of callback names in expected call order.
     136     * @param string $expected_deprecation Optional. Deprecation message. Default ''.
     137     */
     138    public function test_priority_callback_order( $priorities, $expected_call_order, $expected_deprecation = '' ) {
     139        $mock      = new MockAction();
     140        $hook_name = __FUNCTION__;
     141
     142        if ( $expected_deprecation && PHP_VERSION_ID >= 80100 ) {
     143            $this->expectDeprecation();
     144            $this->expectDeprecationMessage( $expected_deprecation );
     145        }
     146
     147        add_filter( $hook_name, array( $mock, 'filter' ), $priorities[0] );
     148        add_filter( $hook_name, array( $mock, 'filter2' ), $priorities[1] );
     149        apply_filters( $hook_name, __FUNCTION__ . '_val' );
     150
     151        $this->assertSame( 2, $mock->get_call_count(), 'The number of call counts does not match' );
     152
     153        $actual_call_order = wp_list_pluck( $mock->get_events(), 'filter' );
     154        $this->assertSame( $expected_call_order, $actual_call_order, 'The filter callback order does not match the expected order' );
     155    }
     156
     157    /**
     158     * Happy path data provider.
     159     *
     160     * @return array[]
     161     */
     162    public function data_priority_callback_order_with_integers() {
     163        return array(
     164            'int DESC' => array(
     165                'priorities'          => array( 10, 9 ),
     166                'expected_call_order' => array( 'filter2', 'filter' ),
     167            ),
     168            'int ASC'  => array(
     169                'priorities'          => array( 9, 10 ),
     170                'expected_call_order' => array( 'filter', 'filter2' ),
    148171            ),
    149172        );
    150 
    151         $this->assertSame( $expected, $a->get_events() );
     173    }
     174
     175    /**
     176     * Unhappy path data provider.
     177     *
     178     * @return array[]
     179     */
     180    public function data_priority_callback_order_with_unhappy_path_nonintegers() {
     181        return array(
     182            // Numbers as strings and floats.
     183            'int as string DESC'               => array(
     184                'priorities'          => array( '10', '9' ),
     185                'expected_call_order' => array( 'filter2', 'filter' ),
     186            ),
     187            'int as string ASC'                => array(
     188                'priorities'          => array( '9', '10' ),
     189                'expected_call_order' => array( 'filter', 'filter2' ),
     190            ),
     191            'float DESC'                       => array(
     192                'priorities'           => array( 10.0, 9.5 ),
     193                'expected_call_order'  => array( 'filter2', 'filter' ),
     194                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     195            ),
     196            'float ASC'                        => array(
     197                'priorities'           => array( 9.5, 10.0 ),
     198                'expected_call_order'  => array( 'filter', 'filter2' ),
     199                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     200            ),
     201            'float as string DESC'             => array(
     202                'priorities'          => array( '10.0', '9.5' ),
     203                'expected_call_order' => array( 'filter2', 'filter' ),
     204            ),
     205            'float as string ASC'              => array(
     206                'priorities'          => array( '9.5', '10.0' ),
     207                'expected_call_order' => array( 'filter', 'filter2' ),
     208            ),
     209
     210            // Non-numeric.
     211            'null'                             => array(
     212                'priorities'          => array( null, null ),
     213                'expected_call_order' => array( 'filter', 'filter2' ),
     214            ),
     215            'bool DESC'                        => array(
     216                'priorities'          => array( true, false ),
     217                'expected_call_order' => array( 'filter2', 'filter' ),
     218            ),
     219            'bool ASC'                         => array(
     220                'priorities'          => array( false, true ),
     221                'expected_call_order' => array( 'filter', 'filter2' ),
     222            ),
     223            'non-numerical string DESC'        => array(
     224                'priorities'          => array( 'test1', 'test2' ),
     225                'expected_call_order' => array( 'filter', 'filter2' ),
     226            ),
     227            'non-numerical string ASC'         => array(
     228                'priorities'          => array( 'test1', 'test2' ),
     229                'expected_call_order' => array( 'filter', 'filter2' ),
     230            ),
     231            'int, non-numerical string DESC'   => array(
     232                'priorities'          => array( 10, 'test' ),
     233                'expected_call_order' => array( 'filter2', 'filter' ),
     234            ),
     235            'int, non-numerical string ASC'    => array(
     236                'priorities'          => array( 'test', 10 ),
     237                'expected_call_order' => array( 'filter', 'filter2' ),
     238            ),
     239            'float, non-numerical string DESC' => array(
     240                'priorities'          => array( 10.0, 'test' ),
     241                'expected_call_order' => array( 'filter2', 'filter' ),
     242            ),
     243            'float, non-numerical string ASC'  => array(
     244                'priorities'          => array( 'test', 10.0 ),
     245                'expected_call_order' => array( 'filter', 'filter2' ),
     246            ),
     247        );
    152248    }
    153249
  • trunk/tests/phpunit/tests/hooks/applyFilters.php

    r56547 r57257  
    4343        $this->assertSame( 2, $a->get_call_count() );
    4444    }
     45
     46    /**
     47     * @ticket 60193
     48     *
     49     * @dataProvider data_priority_callback_order_with_integers
     50     * @dataProvider data_priority_callback_order_with_unhappy_path_nonintegers
     51     *
     52     * @param array $priorities {
     53     *     Indexed array of the priorities for the MockAction callbacks.
     54     *
     55     *     @type mixed $0 Priority for 'action' callback.
     56     *     @type mixed $1 Priority for 'action2' callback.
     57     * }
     58     * @param array  $expected_call_order  An array of callback names in expected call order.
     59     * @param string $expected_deprecation Optional. Deprecation message. Default ''.
     60     */
     61    public function test_priority_callback_order( $priorities, $expected_call_order, $expected_deprecation = '' ) {
     62        $mock      = new MockAction();
     63        $hook      = new WP_Hook();
     64        $hook_name = __FUNCTION__;
     65
     66        if ( $expected_deprecation && PHP_VERSION_ID >= 80100 ) {
     67            $this->expectDeprecation();
     68            $this->expectDeprecationMessage( $expected_deprecation );
     69        }
     70
     71        $hook->add_filter( $hook_name, array( $mock, 'filter' ), $priorities[0], 1 );
     72        $hook->add_filter( $hook_name, array( $mock, 'filter2' ), $priorities[1], 1 );
     73        $hook->apply_filters( __FUNCTION__ . '_val', array( '' ) );
     74
     75        $this->assertSame( 2, $mock->get_call_count(), 'The number of call counts does not match' );
     76
     77        $actual_call_order = wp_list_pluck( $mock->get_events(), 'filter' );
     78        $this->assertSame( $expected_call_order, $actual_call_order, 'The filter callback order does not match the expected order' );
     79    }
     80
     81    /**
     82     * Happy path data provider.
     83     *
     84     * @return array[]
     85     */
     86    public function data_priority_callback_order_with_integers() {
     87        return array(
     88            'int DESC' => array(
     89                'priorities'          => array( 10, 9 ),
     90                'expected_call_order' => array( 'filter2', 'filter' ),
     91            ),
     92            'int ASC'  => array(
     93                'priorities'          => array( 9, 10 ),
     94                'expected_call_order' => array( 'filter', 'filter2' ),
     95            ),
     96        );
     97    }
     98
     99    /**
     100     * Unhappy path data provider.
     101     *
     102     * @return array[]
     103     */
     104    public function data_priority_callback_order_with_unhappy_path_nonintegers() {
     105        return array(
     106            // Numbers as strings and floats.
     107            'int as string DESC'               => array(
     108                'priorities'          => array( '10', '9' ),
     109                'expected_call_order' => array( 'filter2', 'filter' ),
     110            ),
     111            'int as string ASC'                => array(
     112                'priorities'          => array( '9', '10' ),
     113                'expected_call_order' => array( 'filter', 'filter2' ),
     114            ),
     115            'float DESC'                       => array(
     116                'priorities'           => array( 10.0, 9.5 ),
     117                'expected_call_order'  => array( 'filter2', 'filter' ),
     118                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     119            ),
     120            'float ASC'                        => array(
     121                'priorities'           => array( 9.5, 10.0 ),
     122                'expected_call_order'  => array( 'filter', 'filter2' ),
     123                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     124            ),
     125            'float as string DESC'             => array(
     126                'priorities'          => array( '10.0', '9.5' ),
     127                'expected_call_order' => array( 'filter2', 'filter' ),
     128            ),
     129            'float as string ASC'              => array(
     130                'priorities'          => array( '9.5', '10.0' ),
     131                'expected_call_order' => array( 'filter', 'filter2' ),
     132            ),
     133
     134            // Non-numeric.
     135            'null'                             => array(
     136                'priorities'          => array( null, null ),
     137                'expected_call_order' => array( 'filter', 'filter2' ),
     138            ),
     139            'bool DESC'                        => array(
     140                'priorities'          => array( true, false ),
     141                'expected_call_order' => array( 'filter2', 'filter' ),
     142            ),
     143            'bool ASC'                         => array(
     144                'priorities'          => array( false, true ),
     145                'expected_call_order' => array( 'filter', 'filter2' ),
     146            ),
     147            'non-numerical string DESC'        => array(
     148                'priorities'          => array( 'test1', 'test2' ),
     149                'expected_call_order' => array( 'filter', 'filter2' ),
     150            ),
     151            'non-numerical string ASC'         => array(
     152                'priorities'          => array( 'test1', 'test2' ),
     153                'expected_call_order' => array( 'filter', 'filter2' ),
     154            ),
     155            'int, non-numerical string DESC'   => array(
     156                'priorities'          => array( 10, 'test' ),
     157                'expected_call_order' => array( 'filter2', 'filter' ),
     158            ),
     159            'int, non-numerical string ASC'    => array(
     160                'priorities'          => array( 'test', 10 ),
     161                'expected_call_order' => array( 'filter', 'filter2' ),
     162            ),
     163            'float, non-numerical string DESC' => array(
     164                'priorities'          => array( 10.0, 'test' ),
     165                'expected_call_order' => array( 'filter2', 'filter' ),
     166            ),
     167            'float, non-numerical string ASC'  => array(
     168                'priorities'          => array( 'test', 10.0 ),
     169                'expected_call_order' => array( 'filter', 'filter2' ),
     170            ),
     171        );
     172    }
    45173}
  • trunk/tests/phpunit/tests/hooks/doAction.php

    r53804 r57257  
    8686    }
    8787
     88    /**
     89     * @ticket 60193
     90     *
     91     * @dataProvider data_priority_callback_order_with_integers
     92     * @dataProvider data_priority_callback_order_with_unhappy_path_nonintegers
     93     *
     94     * @param array $priorities {
     95     *     Indexed array of the priorities for the MockAction callbacks.
     96     *
     97     *     @type mixed $0 Priority for 'action' callback.
     98     *     @type mixed $1 Priority for 'action2' callback.
     99     * }
     100     * @param array  $expected_call_order  An array of callback names in expected call order.
     101     * @param string $expected_deprecation Optional. Deprecation message. Default ''.
     102     */
     103    public function test_priority_callback_order( $priorities, $expected_call_order, $expected_deprecation = '' ) {
     104        $mock      = new MockAction();
     105        $hook      = new WP_Hook();
     106        $hook_name = __FUNCTION__;
     107
     108        if ( $expected_deprecation && PHP_VERSION_ID >= 80100 ) {
     109            $this->expectDeprecation();
     110            $this->expectDeprecationMessage( $expected_deprecation );
     111        }
     112
     113        $hook->add_filter( $hook_name, array( $mock, 'action' ), $priorities[0], 1 );
     114        $hook->add_filter( $hook_name, array( $mock, 'action2' ), $priorities[1], 1 );
     115        $hook->do_action( array( '' ) );
     116
     117        $this->assertSame( 2, $mock->get_call_count(), 'The number of call counts does not match' );
     118
     119        $actual_call_order = wp_list_pluck( $mock->get_events(), 'action' );
     120        $this->assertSame( $expected_call_order, $actual_call_order, 'The action callback order does not match the expected order' );
     121    }
     122
     123    /**
     124     * Happy path data provider.
     125     *
     126     * @return array[]
     127     */
     128    public function data_priority_callback_order_with_integers() {
     129        return array(
     130            'int DESC' => array(
     131                'priorities'          => array( 10, 9 ),
     132                'expected_call_order' => array( 'action2', 'action' ),
     133            ),
     134            'int ASC'  => array(
     135                'priorities'          => array( 9, 10 ),
     136                'expected_call_order' => array( 'action', 'action2' ),
     137            ),
     138        );
     139    }
     140
     141    /**
     142     * Unhappy path data provider.
     143     *
     144     * @return array[]
     145     */
     146    public function data_priority_callback_order_with_unhappy_path_nonintegers() {
     147        return array(
     148            // Numbers as strings and floats.
     149            'int as string DESC'               => array(
     150                'priorities'          => array( '10', '9' ),
     151                'expected_call_order' => array( 'action2', 'action' ),
     152            ),
     153            'int as string ASC'                => array(
     154                'priorities'          => array( '9', '10' ),
     155                'expected_call_order' => array( 'action', 'action2' ),
     156            ),
     157            'float DESC'                       => array(
     158                'priorities'           => array( 10.0, 9.5 ),
     159                'expected_call_order'  => array( 'action2', 'action' ),
     160                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     161            ),
     162            'float ASC'                        => array(
     163                'priorities'           => array( 9.5, 10.0 ),
     164                'expected_call_order'  => array( 'action', 'action2' ),
     165                'expected_deprecation' => 'Implicit conversion from float 9.5 to int loses precision',
     166            ),
     167            'float as string DESC'             => array(
     168                'priorities'          => array( '10.0', '9.5' ),
     169                'expected_call_order' => array( 'action2', 'action' ),
     170            ),
     171            'float as string ASC'              => array(
     172                'priorities'          => array( '9.5', '10.0' ),
     173                'expected_call_order' => array( 'action', 'action2' ),
     174            ),
     175
     176            // Non-numeric.
     177            'null'                             => array(
     178                'priorities'          => array( null, null ),
     179                'expected_call_order' => array( 'action', 'action2' ),
     180            ),
     181            'bool DESC'                        => array(
     182                'priorities'          => array( true, false ),
     183                'expected_call_order' => array( 'action2', 'action' ),
     184            ),
     185            'bool ASC'                         => array(
     186                'priorities'          => array( false, true ),
     187                'expected_call_order' => array( 'action', 'action2' ),
     188            ),
     189            'non-numerical string DESC'        => array(
     190                'priorities'          => array( 'test1', 'test2' ),
     191                'expected_call_order' => array( 'action', 'action2' ),
     192            ),
     193            'non-numerical string ASC'         => array(
     194                'priorities'          => array( 'test1', 'test2' ),
     195                'expected_call_order' => array( 'action', 'action2' ),
     196            ),
     197            'int, non-numerical string DESC'   => array(
     198                'priorities'          => array( 10, 'test' ),
     199                'expected_call_order' => array( 'action2', 'action' ),
     200            ),
     201            'int, non-numerical string ASC'    => array(
     202                'priorities'          => array( 'test', 10 ),
     203                'expected_call_order' => array( 'action', 'action2' ),
     204            ),
     205            'float, non-numerical string DESC' => array(
     206                'priorities'          => array( 10.0, 'test' ),
     207                'expected_call_order' => array( 'action2', 'action' ),
     208            ),
     209            'float, non-numerical string ASC'  => array(
     210                'priorities'          => array( 'test', 10.0 ),
     211                'expected_call_order' => array( 'action', 'action2' ),
     212            ),
     213        );
     214    }
     215
    88216    public function test_do_action_with_no_accepted_args() {
    89217        $callback      = array( $this, '_action_callback' );
Note: See TracChangeset for help on using the changeset viewer.