<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[51852] trunk/tests/phpunit/tests: Build/Test Tools: Splits and improves `compat` tests.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/51852">51852</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/51852","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>hellofromTonya</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-09-22 23:05:59 +0000 (Wed, 22 Sep 2021)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Build/Test Tools: Splits and improves `compat` tests.

Splits the tests in the `tests/phpunit/tests/compat.php` file up into individual test classes for each function being tested.

Improvements to individual test cases:
* Adds `@covers` tags.
* Adds visibility modifiers to all methods.
* Adds function availability test.
* Where relevant, fixes the assertion parameter order.
* Data provider:
   * Where relevant, reworks a test to use a data provider.
   * Where relevant, renames data provider methods to have a more obvious link to the test it applies to.
   * Makes the data provider more readable by adding keys within the data sets.
   * Moves the data provider below its associated tests.
   * Adds/removes data sets in data providers.
* Makes the actual test code more readable by using descriptive variables and multi-line function calls.
* Adds the `$message` parameter to all assertions when a test method contains more than one assertion.

Specifically for the `_mb_substr()` tests:
* Splits the `test_mb_substr_phpcore()` method into two test methods based on the PHP Core test files they are emulating.
* Makes the actual test code within the `test_mb_substr_phpcore_basic()` method more readable by using descriptive variables and multi-line function calls.
* Splits the data used for the second part of the `test_mb_substr_phpcore()` function, now `test_mb_substr_phpcore_input_type_handling()`, off into a separate data provider with named data sets.
* Removes duplicate data sets from the `data_mb_substr_phpcore_input_type_handling()`. 
   * Why? The PHP native tests test against upper/lowercase `false`, `true`, `null` and some other text string single quote/double quote variations. As things were, those differentiations had been undone when the coding standards were put in place, so in effect those weren't being tested anymore. And as this is userland code, there's no point in adding these differentiations back as they will be handled the same by PHP anyway (and that is safeguarded via the PHP native tests).
* Removes the "undefined variable" and "unset variable" test cases as, while those are relevant to the C code in which PHP is written, they are not relevant for testing userland code and will behave the same as the test passing `null`.

Follow-to <a href="https://core.trac.wordpress.org/changeset/25002">[25002]</a>, <a href="https://core.trac.wordpress.org/changeset/32364">[32364]</a>, <a href="https://core.trac.wordpress.org/changeset/42228">[42228]</a>, <a href="https://core.trac.wordpress.org/changeset/42343">[42343]</a>, <a href="https://core.trac.wordpress.org/changeset/43034">[43034]</a>, <a href="https://core.trac.wordpress.org/changeset/43036">[43036]</a>, <a href="https://core.trac.wordpress.org/changeset/43220">[43220]</a>, <a href="https://core.trac.wordpress.org/changeset/43571">[43571]</a>, <a href="https://core.trac.wordpress.org/changeset/45607">[45607]</a>, <a href="https://core.trac.wordpress.org/changeset/47122">[47122]</a>, <a href="https://core.trac.wordpress.org/changeset/47198">[47198]</a>, <a href="https://core.trac.wordpress.org/changeset/48937">[48937]</a>, <a href="https://core.trac.wordpress.org/changeset/48996">[48996]</a>, <a href="https://core.trac.wordpress.org/changeset/51415">[51415]
 </a>, <a href="https://core.trac.wordpress.org/changeset/51563">[51563]</a>, <a href="https://core.trac.wordpress.org/changeset/51594">[51594]</a>.

Props jrf, hellofromTonya.
See <a href="https://core.trac.wordpress.org/ticket/39265">#39265</a>, <a href="https://core.trac.wordpress.org/ticket/53363">#53363</a>.</pre>

<h3>Added Paths</h3>
<ul>
<li>trunk/tests/phpunit/tests/compat/</li>
<li><a href="#trunktestsphpunittestscompathashHmacphp">trunk/tests/phpunit/tests/compat/hashHmac.php</a></li>
<li><a href="#trunktestsphpunittestscompatisCountablephp">trunk/tests/phpunit/tests/compat/isCountable.php</a></li>
<li><a href="#trunktestsphpunittestscompatisIterablephp">trunk/tests/phpunit/tests/compat/isIterable.php</a></li>
<li><a href="#trunktestsphpunittestscompatjsonEncodeDecodephp">trunk/tests/phpunit/tests/compat/jsonEncodeDecode.php</a></li>
<li><a href="#trunktestsphpunittestscompatmbStrlenphp">trunk/tests/phpunit/tests/compat/mbStrlen.php</a></li>
<li><a href="#trunktestsphpunittestscompatmbSubstrphp">trunk/tests/phpunit/tests/compat/mbSubstr.php</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestscompatphp">trunk/tests/phpunit/tests/compat.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunktestsphpunittestscompathashHmacphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/compat/hashHmac.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/compat/hashHmac.php                             (rev 0)
+++ trunk/tests/phpunit/tests/compat/hashHmac.php       2021-09-22 23:05:59 UTC (rev 51852)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,65 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group compat
+ *
+ * @covers ::hash_hmac
+ * @covers ::_hash_hmac
+ */
+class Tests_Compat_hashHmac extends WP_UnitTestCase {
+
+       /**
+        * Test that hash_hmac() is always available (either from PHP or WP).
+        */
+       public function test_hash_hmac_availability() {
+               $this->assertTrue( function_exists( 'hash_hmac' ) );
+       }
+
+       public function test_hash_hmac_simple() {
+               $data = 'simple';
+               $key  = 'key';
+
+               $this->assertSame(
+                       '140d1cb79fa12e2a31f32d35ad0a2723',
+                       _hash_hmac( 'md5', $data, $key ),
+                       'MD5 hash does not match'
+               );
+               $this->assertSame(
+                       '993003b95758e0ac2eba451a4c5877eb1bb7b92a',
+                       _hash_hmac( 'sha1', $data, $key ),
+                       'sha1 hash does not match'
+               );
+       }
+
+       public function test_hash_hmac_padding() {
+               $data = 'simple';
+               $key  = '65 character key 65 character key 65 character key 65 character k';
+
+               $this->assertSame(
+                       '3c1399103807cf12ec38228614416a8c',
+                       _hash_hmac( 'md5', $data, $key ),
+                       'MD5 hash does not match'
+               );
+               $this->assertSame(
+                       '4428826d20003e309d6c2a6515891370daf184ea',
+                       _hash_hmac( 'sha1', $data, $key ),
+                       'sha1 hash does not match'
+               );
+       }
+
+       public function test_hash_hmac_output() {
+               $data = 'simple';
+               $key  = 'key';
+
+               $this->assertSame(
+                       array( 1 => '140d1cb79fa12e2a31f32d35ad0a2723' ),
+                       unpack( 'H32', _hash_hmac( 'md5', $data, $key, true ) ),
+                       'unpacked MD5 hash does not match'
+               );
+               $this->assertSame(
+                       array( 1 => '993003b95758e0ac2eba451a4c5877eb1bb7b92a' ),
+                       unpack( 'H40', _hash_hmac( 'sha1', $data, $key, true ) ),
+                       'unpacked sha1 hash does not match'
+               );
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/compat/hashHmac.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktestsphpunittestscompatisCountablephp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/compat/isCountable.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/compat/isCountable.php                          (rev 0)
+++ trunk/tests/phpunit/tests/compat/isCountable.php    2021-09-22 23:05:59 UTC (rev 51852)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,117 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group compat
+ *
+ * @covers ::is_countable
+ */
+class Tests_Compat_isCountable extends WP_UnitTestCase {
+
+       /**
+        * Test that is_countable() is always available (either from PHP or WP).
+        *
+        * @ticket 43583
+        */
+       public function test_is_countable_availability() {
+               $this->assertTrue( function_exists( 'is_countable' ) );
+       }
+
+       /**
+        * Test is_countable() polyfill.
+        *
+        * @ticket 43583
+        *
+        * @dataProvider data_is_countable_functionality
+        *
+        * @param mixed $variable     Variable to check.
+        * @param bool  $is_countable The expected return value of PHP 7.3 is_countable() function.
+        */
+       public function test_is_countable_functionality( $variable, $is_countable ) {
+               $this->assertSame( $is_countable, is_countable( $variable ) );
+       }
+
+       /**
+        * Data provider for test_is_countable_functionality().
+        *
+        * @ticket 43583
+        *
+        * @return array {
+        *     @type array {
+        *         @type mixed $variable     Variable to check.
+        *         @type bool  $is_countable The expected return value of PHP 7.3 is_countable() function.
+        *     }
+        * }
+        */
+       public function data_is_countable_functionality() {
+               return array(
+                       'boolean true'                     => array(
+                               'variable'     => true,
+                               'is_countable' => false,
+                       ),
+                       'plain stdClass object'            => array(
+                               'variable'     => new stdClass(),
+                               'is_countable' => false,
+                       ),
+                       'Array iterator object'            => array(
+                               'variable'     => new ArrayIteratorFakeForIsCountable(),
+                               'is_countable' => true,
+                       ),
+                       'Countable object'                 => array(
+                               'variable'     => new CountableFakeForIsCountable(),
+                               'is_countable' => true,
+                       ),
+                       'integer 16'                       => array(
+                               'variable'     => 16,
+                               'is_countable' => false,
+                       ),
+                       'null'                             => array(
+                               'variable'     => null,
+                               'is_countable' => false,
+                       ),
+                       'non-empty array, 3 items'         => array(
+                               'variable'     => array( 1, 2, 3 ),
+                               'is_countable' => true,
+                       ),
+                       'non-empty array, 1 item via cast' => array(
+                               'variable'     => (array) 1,
+                               'is_countable' => true,
+                       ),
+                       'array cast to object'             => array(
+                               'variable'     => (object) array( 'foo', 'bar', 'baz' ),
+                               'is_countable' => false,
+                       ),
+               );
+       }
+
+       /**
+        * Test is_countable() polyfill for ResourceBundle.
+        *
+        * @ticket 43583
+        *
+        * @requires extension intl
+        */
+       public function test_is_countable_ResourceBundle() {
+               $this->assertTrue( is_countable( new ResourceBundle( 'en', null ) ) );
+       }
+
+       /**
+        * Test is_countable() polyfill for SimpleXMLElement.
+        *
+        * @ticket 43583
+        *
+        * @requires extension simplexml
+        */
+       public function test_is_countable_SimpleXMLElement() {
+               $this->assertTrue( is_countable( new SimpleXMLElement( '<xml><tag>1</tag><tag>2</tag></xml>' ) ) );
+       }
+}
+
+class ArrayIteratorFakeForIsCountable extends ArrayIterator {
+}
+
+class CountableFakeForIsCountable implements Countable {
+       #[ReturnTypeWillChange]
+       public function count() {
+               return 16;
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/compat/isCountable.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktestsphpunittestscompatisIterablephp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/compat/isIterable.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/compat/isIterable.php                           (rev 0)
+++ trunk/tests/phpunit/tests/compat/isIterable.php     2021-09-22 23:05:59 UTC (rev 51852)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,77 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group compat
+ *
+ * @covers ::is_iterable
+ */
+class Tests_Compat_isIterable extends WP_UnitTestCase {
+
+       /**
+        * Test that is_iterable() is always available (either from PHP or WP).
+        *
+        * @ticket 43619
+        */
+       public function test_is_iterable_availability() {
+               $this->assertTrue( function_exists( 'is_iterable' ) );
+       }
+
+       /**
+        * Test is_iterable() polyfill.
+        *
+        * @ticket 43619
+        *
+        * @dataProvider data_is_iterable_functionality
+        *
+        * @param mixed $variable    Variable to check.
+        * @param bool  $is_iterable The expected return value of PHP 7.1 is_iterable() function.
+        */
+       public function test_is_iterable_functionality( $variable, $is_iterable ) {
+               $this->assertSame( $is_iterable, is_iterable( $variable ) );
+       }
+
+       /**
+        * Data provider for test_is_iterable_functionality().
+        *
+        * @ticket 43619
+        *
+        * @return array {
+        *     @type array {
+        *         @type mixed $variable    Variable to check.
+        *         @type bool  $is_iterable The expected return value of PHP 7.1 is_iterable() function.
+        *     }
+        * }
+        */
+       public function data_is_iterable_functionality() {
+               return array(
+                       'empty array'           => array(
+                               'variable'    => array(),
+                               'is_iterable' => true,
+                       ),
+                       'non-empty array'       => array(
+                               'variable'    => array( 1, 2, 3 ),
+                               'is_iterable' => true,
+                       ),
+                       'Iterator object'       => array(
+                               'variable'    => new ArrayIterator( array( 1, 2, 3 ) ),
+                               'is_iterable' => true,
+                       ),
+                       'null'                  => array(
+                               'variable'    => null,
+                               'is_iterable' => false,
+                       ),
+                       'integer 1'             => array(
+                               'variable'    => 1,
+                               'is_iterable' => false,
+                       ),
+                       'float 3.14'            => array(
+                               'variable'    => 3.14,
+                               'is_iterable' => false,
+                       ),
+                       'plain stdClass object' => array(
+                               'variable'    => new stdClass(),
+                               'is_iterable' => false,
+                       ),
+               );
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/compat/isIterable.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktestsphpunittestscompatjsonEncodeDecodephp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/compat/jsonEncodeDecode.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/compat/jsonEncodeDecode.php                             (rev 0)
+++ trunk/tests/phpunit/tests/compat/jsonEncodeDecode.php       2021-09-22 23:05:59 UTC (rev 51852)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,28 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group compat
+ *
+ * @covers Services_JSON
+ */
+class Tests_Compat_jsonEncodeDecode extends WP_UnitTestCase {
+
+       public function test_json_encode_decode() {
+               $this->expectDeprecation();
+
+               require_once ABSPATH . WPINC . '/class-json.php';
+               $json = new Services_JSON();
+
+               // Super basic test to verify Services_JSON is intact and working.
+               $this->assertSame(
+                       '["foo"]',
+                       $json->encodeUnsafe( array( 'foo' ) ),
+                       'encodeUnsafe() did not return expected output'
+               );
+               $this->assertSame(
+                       array( 'foo' ),
+                       $json->decode( '["foo"]' ),
+                       'decode() did not return expected output'
+               );
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/compat/jsonEncodeDecode.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktestsphpunittestscompatmbStrlenphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/compat/mbStrlen.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/compat/mbStrlen.php                             (rev 0)
+++ trunk/tests/phpunit/tests/compat/mbStrlen.php       2021-09-22 23:05:59 UTC (rev 51852)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,91 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group compat
+ * @group security-153
+ *
+ * @covers ::mb_strlen
+ * @covers ::_mb_strlen
+ */
+class Tests_Compat_mbStrlen extends WP_UnitTestCase {
+
+       /**
+        * Test that mb_strlen() is always available (either from PHP or WP).
+        */
+       public function test_mb_strlen_availability() {
+               $this->assertTrue( function_exists( 'mb_strlen' ) );
+       }
+
+       /**
+        * @dataProvider utf8_string_lengths
+        */
+       public function test_mb_strlen( $string, $expected_character_length ) {
+               $this->assertSame( $expected_character_length, _mb_strlen( $string, 'UTF-8' ) );
+       }
+
+       /**
+        * @dataProvider utf8_string_lengths
+        */
+       public function test_mb_strlen_via_regex( $string, $expected_character_length ) {
+               _wp_can_use_pcre_u( false );
+               $this->assertSame( $expected_character_length, _mb_strlen( $string, 'UTF-8' ) );
+               _wp_can_use_pcre_u( 'reset' );
+       }
+
+       /**
+        * @dataProvider utf8_string_lengths
+        */
+       public function test_8bit_mb_strlen( $string, $expected_character_length, $expected_byte_length ) {
+               $this->assertSame( $expected_byte_length, _mb_strlen( $string, '8bit' ) );
+       }
+
+       /**
+        * Data provider.
+        *
+        * @return array
+        */
+       public function utf8_string_lengths() {
+               return array(
+                       array(
+                               'string'                    => 'баба',
+                               'expected_character_length' => 4,
+                               'expected_byte_length'      => 8,
+                       ),
+                       array(
+                               'string'                    => 'баб',
+                               'expected_character_length' => 3,
+                               'expected_byte_length'      => 6,
+                       ),
+                       array(
+                               'string'                    => 'I am your б',
+                               'expected_character_length' => 11,
+                               'expected_byte_length'      => 12,
+                       ),
+                       array(
+                               'string'                    => '1111111111',
+                               'expected_character_length' => 10,
+                               'expected_byte_length'      => 10,
+                       ),
+                       array(
+                               'string'                    => '²²²²²²²²²²',
+                               'expected_character_length' => 10,
+                               'expected_byte_length'      => 20,
+                       ),
+                       array(
+                               'string'                    => '3333333333',
+                               'expected_character_length' => 10,
+                               'expected_byte_length'      => 30,
+                       ),
+                       array(
+                               'string'                    => '𝟜𝟜𝟜𝟜𝟜𝟜𝟜𝟜𝟜𝟜',
+                               'expected_character_length' => 10,
+                               'expected_byte_length'      => 40,
+                       ),
+                       array(
+                               'string'                    => '1²3𝟜1²3𝟜1²3𝟜',
+                               'expected_character_length' => 12,
+                               'expected_byte_length'      => 30,
+                       ),
+               );
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/compat/mbStrlen.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktestsphpunittestscompatmbSubstrphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/compat/mbSubstr.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/compat/mbSubstr.php                             (rev 0)
+++ trunk/tests/phpunit/tests/compat/mbSubstr.php       2021-09-22 23:05:59 UTC (rev 51852)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,241 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group compat
+ * @group security-153
+ *
+ * @covers ::mb_substr
+ * @covers ::_mb_substr
+ */
+class Tests_Compat_mbSubstr extends WP_UnitTestCase {
+
+       /**
+        * Test that mb_substr() is always available (either from PHP or WP).
+        */
+       public function test_mb_substr_availability() {
+               $this->assertTrue( function_exists( 'mb_substr' ) );
+       }
+
+       /**
+        * @dataProvider utf8_substrings
+        */
+       public function test_mb_substr( $string, $start, $length, $expected_character_substring ) {
+               $this->assertSame( $expected_character_substring, _mb_substr( $string, $start, $length, 'UTF-8' ) );
+       }
+
+       /**
+        * @dataProvider utf8_substrings
+        */
+       public function test_mb_substr_via_regex( $string, $start, $length, $expected_character_substring ) {
+               _wp_can_use_pcre_u( false );
+               $this->assertSame( $expected_character_substring, _mb_substr( $string, $start, $length, 'UTF-8' ) );
+               _wp_can_use_pcre_u( 'reset' );
+       }
+
+       /**
+        * @dataProvider utf8_substrings
+        */
+       public function test_8bit_mb_substr( $string, $start, $length, $expected_character_substring, $expected_byte_substring ) {
+               $this->assertSame( $expected_byte_substring, _mb_substr( $string, $start, $length, '8bit' ) );
+       }
+
+       /**
+        * Data provider.
+        *
+        * @return array
+        */
+       public function utf8_substrings() {
+               return array(
+                       array(
+                               'string'                       => 'баба',
+                               'start'                        => 0,
+                               'length'                       => 3,
+                               'expected_character_substring' => 'баб',
+                               'expected_byte_substring'      => "б\xD0",
+                       ),
+                       array(
+                               'string'                       => 'баба',
+                               'start'                        => 0,
+                               'length'                       => -1,
+                               'expected_character_substring' => 'баб',
+                               'expected_byte_substring'      => "баб\xD0",
+                       ),
+                       array(
+                               'string'                       => 'баба',
+                               'start'                        => 1,
+                               'length'                       => null,
+                               'expected_character_substring' => 'аба',
+                               'expected_byte_substring'      => "\xB1аба",
+                       ),
+                       array(
+                               'string'                       => 'баба',
+                               'start'                        => -3,
+                               'length'                       => null,
+                               'expected_character_substring' => 'аба',
+                               'expected_byte_substring'      => "\xB1а",
+                       ),
+                       array(
+                               'string'                       => 'баба',
+                               'start'                        => -3,
+                               'length'                       => 2,
+                               'expected_character_substring' => 'аб',
+                               'expected_byte_substring'      => "\xB1\xD0",
+                       ),
+                       array(
+                               'string'                       => 'баба',
+                               'start'                        => -1,
+                               'length'                       => 2,
+                               'expected_character_substring' => 'а',
+                               'expected_byte_substring'      => "\xB0",
+                       ),
+                       array(
+                               'string'                       => 'I am your баба',
+                               'start'                        => 0,
+                               'length'                       => 11,
+                               'expected_character_substring' => 'I am your б',
+                               'expected_byte_substring'      => "I am your \xD0",
+                       ),
+               );
+       }
+
+       /**
+        * @link https://github.com/php/php-src/blob/php-5.6.8/ext/mbstring/tests/mb_substr_basic.phpt
+        */
+       public function test_mb_substr_phpcore_basic() {
+               $string_ascii = 'ABCDEF';
+               $string_mb    = base64_decode( '5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=' );
+
+               $this->assertSame(
+                       'DEF',
+                       _mb_substr( $string_ascii, 3 ),
+                       'Substring does not match expected for offset 3'
+               );
+               $this->assertSame(
+                       'DEF',
+                       _mb_substr( $string_ascii, 3, 5, 'ISO-8859-1' ),
+                       'Substring does not match expected for offset 3, length 5, with iso charset'
+               );
+
+               // Specific latin-1 as that is the default the core PHP test operates under.
+               $this->assertSame(
+                       'peacrOiqng==',
+                       base64_encode( _mb_substr( $string_mb, 2, 7, 'latin-1' ) ),
+                       'Substring does not match expected for offset 2, length 7, with latin-1 charset'
+               );
+               $this->assertSame(
+                       '6Kqe44OG44Kt44K544OI44Gn44GZ',
+                       base64_encode( _mb_substr( $string_mb, 2, 7, 'utf-8' ) ),
+                       'Substring does not match expected for offset 2, length 7, with utf-8 charset'
+               );
+       }
+
+       /**
+        * @link https://github.com/php/php-src/blob/php-5.6.8/ext/mbstring/tests/mb_substr_variation1.phpt
+        *
+        * @dataProvider data_mb_substr_phpcore_input_type_handling
+        *
+        * @param mixed  $input    Input to pass to the function.
+        * @param string $expected Expected function output.
+        */
+       public function test_mb_substr_phpcore_input_type_handling( $input, $expected ) {
+               $start  = 0;
+               $length = 5;
+
+               $this->assertSame( $expected, _mb_substr( $input, $start, $length ) );
+       }
+
+       /**
+        * Data provider.
+        *
+        * @return array
+        */
+       public function data_mb_substr_phpcore_input_type_handling() {
+               $heredoc = <<<EOT
+hello world
+EOT;
+
+               return array(
+                       'integer zero'                   => array(
+                               'input'    => 0,
+                               'expected' => '0',
+                       ),
+                       'integer 1'                      => array(
+                               'input'    => 1,
+                               'expected' => '1',
+                       ),
+                       'positive integer'               => array(
+                               'input'    => 12345,
+                               'expected' => '12345',
+                       ),
+                       'negative integer'               => array(
+                               'input'    => -2345,
+                               'expected' => '-2345',
+                       ),
+                       // Float data.
+                       'positive float with fraction'   => array(
+                               'input'    => 10.5,
+                               'expected' => '10.5',
+                       ),
+                       'negative float with fraction'   => array(
+                               'input'    => -10.5,
+                               'expected' => '-10.5',
+                       ),
+                       'float scientific whole number'  => array(
+                               'input'    => 12.3456789000e10,
+                               'expected' => '12345',
+                       ),
+                       'float scientific with fraction' => array(
+                               'input'    => 12.3456789000E-10,
+                               'expected' => '1.234',
+                       ),
+                       'float, fraction only'           => array(
+                               'input'    => .5,
+                               'expected' => '0.5',
+                       ),
+                       // Null data.
+                       'null'                           => array(
+                               'input'    => null,
+                               'expected' => '',
+                       ),
+                       // Boolean data.
+                       'boolean true'                   => array(
+                               'input'    => true,
+                               'expected' => '1',
+                       ),
+                       'boolean false'                  => array(
+                               'input'    => false,
+                               'expected' => '',
+                       ),
+                       // Empty data.
+                       'empty string'                   => array(
+                               'input'    => '',
+                               'expected' => '',
+                       ),
+                       // String data.
+                       'double quoted string'           => array(
+                               'input'    => "string'",
+                               'expected' => 'strin',
+                       ),
+                       'single quoted string'           => array(
+                               'input'    => 'string',
+                               'expected' => 'strin',
+                       ),
+                       'heredoc string'                 => array(
+                               'input'    => $heredoc,
+                               'expected' => 'hello',
+                       ),
+                       // Object data.
+                       'object with __toString method'  => array(
+                               'input'    => new ClassWithToStringForMbSubstr(),
+                               'expected' => 'Class',
+                       ),
+               );
+       }
+}
+
+/* used in data_mb_substr_phpcore_input_type_handling() */
+class ClassWithToStringForMbSubstr {
+       public function __toString() {
+               return 'Class object';
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/compat/mbSubstr.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktestsphpunittestscompatphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/compat.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/compat.php      2021-09-22 21:21:40 UTC (rev 51851)
+++ trunk/tests/phpunit/tests/compat.php        2021-09-22 23:05:59 UTC (rev 51852)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,325 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-/**
- * @group compat
- * @group security-153
- */
-class Tests_Compat extends WP_UnitTestCase {
-       function utf8_string_lengths() {
-               return array(
-                       // String, character_length, byte_length.
-                       array( 'баба', 4, 8 ),
-                       array( 'баб', 3, 6 ),
-                       array( 'I am your б', 11, 12 ),
-                       array( '1111111111', 10, 10 ),
-                       array( '²²²²²²²²²²', 10, 20 ),
-                       array( '3333333333', 10, 30 ),
-                       array( '𝟜𝟜𝟜𝟜𝟜𝟜𝟜𝟜𝟜𝟜', 10, 40 ),
-                       array( '1²3𝟜1²3𝟜1²3𝟜', 12, 30 ),
-               );
-       }
-
-       function utf8_substrings() {
-               return array(
-                       // String, start, length, character_substring, byte_substring.
-                       array( 'баба', 0, 3, 'баб', "б\xD0" ),
-                       array( 'баба', 0, -1, 'баб', "баб\xD0" ),
-                       array( 'баба', 1, null, 'аба', "\xB1аба" ),
-                       array( 'баба', -3, null, 'аба', "\xB1а" ),
-                       array( 'баба', -3, 2, 'аб', "\xB1\xD0" ),
-                       array( 'баба', -1, 2, 'а', "\xB0" ),
-                       array( 'I am your баба', 0, 11, 'I am your б', "I am your \xD0" ),
-               );
-       }
-
-       /**
-        * @dataProvider utf8_string_lengths
-        */
-       function test_mb_strlen( $string, $expected_character_length ) {
-               $this->assertSame( $expected_character_length, _mb_strlen( $string, 'UTF-8' ) );
-       }
-
-       /**
-        * @dataProvider utf8_string_lengths
-        */
-       function test_mb_strlen_via_regex( $string, $expected_character_length ) {
-               _wp_can_use_pcre_u( false );
-               $this->assertSame( $expected_character_length, _mb_strlen( $string, 'UTF-8' ) );
-               _wp_can_use_pcre_u( 'reset' );
-       }
-
-       /**
-        * @dataProvider utf8_string_lengths
-        */
-       function test_8bit_mb_strlen( $string, $expected_character_length, $expected_byte_length ) {
-               $this->assertSame( $expected_byte_length, _mb_strlen( $string, '8bit' ) );
-       }
-
-       /**
-        * @dataProvider utf8_substrings
-        */
-       function test_mb_substr( $string, $start, $length, $expected_character_substring ) {
-               $this->assertSame( $expected_character_substring, _mb_substr( $string, $start, $length, 'UTF-8' ) );
-       }
-
-       /**
-        * @dataProvider utf8_substrings
-        */
-       function test_mb_substr_via_regex( $string, $start, $length, $expected_character_substring ) {
-               _wp_can_use_pcre_u( false );
-               $this->assertSame( $expected_character_substring, _mb_substr( $string, $start, $length, 'UTF-8' ) );
-               _wp_can_use_pcre_u( 'reset' );
-       }
-
-       /**
-        * @dataProvider utf8_substrings
-        */
-       function test_8bit_mb_substr( $string, $start, $length, $expected_character_substring, $expected_byte_substring ) {
-               $this->assertSame( $expected_byte_substring, _mb_substr( $string, $start, $length, '8bit' ) );
-       }
-
-       function test_mb_substr_phpcore() {
-               /* https://github.com/php/php-src/blob/php-5.6.8/ext/mbstring/tests/mb_substr_basic.phpt */
-               $string_ascii = 'ABCDEF';
-               $string_mb    = base64_decode( '5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=' );
-
-               $this->assertSame( 'DEF', _mb_substr( $string_ascii, 3 ) );
-               $this->assertSame( 'DEF', _mb_substr( $string_ascii, 3, 5, 'ISO-8859-1' ) );
-
-               // Specific latin-1 as that is the default the core PHP test operates under.
-               $this->assertSame( 'peacrOiqng==', base64_encode( _mb_substr( $string_mb, 2, 7, 'latin-1' ) ) );
-               $this->assertSame( '6Kqe44OG44Kt44K544OI44Gn44GZ', base64_encode( _mb_substr( $string_mb, 2, 7, 'utf-8' ) ) );
-
-               /* https://github.com/php/php-src/blob/php-5.6.8/ext/mbstring/tests/mb_substr_variation1.phpt */
-               $start     = 0;
-               $length    = 5;
-               $unset_var = 10;
-               unset( $unset_var );
-               $heredoc  = <<<EOT
-hello world
-EOT;
-               $inputs   = array(
-                       0,
-                       1,
-                       12345,
-                       -2345,
-                       // Float data.
-                       10.5,
-                       -10.5,
-                       12.3456789000e10,
-                       12.3456789000E-10,
-                       .5,
-                       // Null data.
-                       null,
-                       null,
-                       // Boolean data.
-                       true,
-                       false,
-                       true,
-                       false,
-                       // Empty data.
-                       '',
-                       '',
-                       // String data.
-                       'string',
-                       'string',
-                       $heredoc,
-                       // Object data.
-                       new ClassA(),
-                       // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- intentionally undefined data
-                       @$undefined_var,
-                       // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- intentionally unset data
-                       @$unset_var,
-               );
-               $outputs  = array(
-                       '0',
-                       '1',
-                       '12345',
-                       '-2345',
-                       '10.5',
-                       '-10.5',
-                       '12345',
-                       '1.234',
-                       '0.5',
-                       '',
-                       '',
-                       '1',
-                       '',
-                       '1',
-                       '',
-                       '',
-                       '',
-                       'strin',
-                       'strin',
-                       'hello',
-                       'Class',
-                       '',
-                       '',
-               );
-               $iterator = 0;
-               foreach ( $inputs as $input ) {
-                       $this->assertSame( $outputs[ $iterator ], _mb_substr( $input, $start, $length ) );
-                       $iterator++;
-               }
-
-       }
-
-       function test_hash_hmac_simple() {
-               $this->assertSame( '140d1cb79fa12e2a31f32d35ad0a2723', _hash_hmac( 'md5', 'simple', 'key' ) );
-               $this->assertSame( '993003b95758e0ac2eba451a4c5877eb1bb7b92a', _hash_hmac( 'sha1', 'simple', 'key' ) );
-       }
-
-       function test_hash_hmac_padding() {
-               $this->assertSame( '3c1399103807cf12ec38228614416a8c', _hash_hmac( 'md5', 'simple', '65 character key 65 character key 65 character key 65 character k' ) );
-               $this->assertSame( '4428826d20003e309d6c2a6515891370daf184ea', _hash_hmac( 'sha1', 'simple', '65 character key 65 character key 65 character key 65 character k' ) );
-       }
-
-       function test_hash_hmac_output() {
-               $this->assertSame( array( 1 => '140d1cb79fa12e2a31f32d35ad0a2723' ), unpack( 'H32', _hash_hmac( 'md5', 'simple', 'key', true ) ) );
-               $this->assertSame( array( 1 => '993003b95758e0ac2eba451a4c5877eb1bb7b92a' ), unpack( 'H40', _hash_hmac( 'sha1', 'simple', 'key', true ) ) );
-       }
-
-       function test_json_encode_decode() {
-               $this->expectDeprecation();
-
-               require_once ABSPATH . WPINC . '/class-json.php';
-               $json = new Services_JSON();
-               // Super basic test to verify Services_JSON is intact and working.
-               $this->assertSame( '["foo"]', $json->encodeUnsafe( array( 'foo' ) ) );
-               $this->assertSame( array( 'foo' ), $json->decode( '["foo"]' ) );
-       }
-
-       /**
-        * Test that is_countable() is always available (either from PHP or WP).
-        *
-        * @ticket 43583
-        */
-       function test_is_countable_availability() {
-               $this->assertTrue( function_exists( 'is_countable' ) );
-       }
-
-       /**
-        * Test is_countable() polyfill.
-        *
-        * @ticket 43583
-        *
-        * @dataProvider countable_variable_test_data
-        *
-        * @param mixed $variable     Variable to check.
-        * @param bool  $is_countable The expected return value of PHP 7.3 is_countable() function.
-        */
-       function test_is_countable_functionality( $variable, $is_countable ) {
-               $this->assertSame( is_countable( $variable ), $is_countable );
-       }
-
-       /**
-        * Data provider for test_is_countable_functionality().
-        *
-        * @ticket 43583
-        *
-        * @return array {
-        *     @type array {
-        *         @type mixed $variable     Variable to check.
-        *         @type bool  $is_countable The expected return value of PHP 7.3 is_countable() function.
-        *     }
-        * }
-        */
-       public function countable_variable_test_data() {
-               return array(
-                       array( true, false ),
-                       array( new stdClass(), false ),
-                       array( new ArrayIteratorFake(), true ),
-                       array( new CountableFake(), true ),
-                       array( 16, false ),
-                       array( null, false ),
-                       array( array( 1, 2, 3 ), true ),
-                       array( (array) 1, true ),
-                       array( (object) array( 'foo', 'bar', 'baz' ), false ),
-               );
-       }
-
-       /**
-        * Test is_countable() polyfill for ResourceBundle.
-        *
-        * @ticket 43583
-        *
-        * @requires extension intl
-        */
-       function test_is_countable_ResourceBundle() {
-               $this->assertTrue( is_countable( new ResourceBundle( 'en', null ) ) );
-       }
-
-       /**
-        * Test is_countable() polyfill for SimpleXMLElement.
-        *
-        * @ticket 43583
-        *
-        * @requires extension simplexml
-        */
-       function test_is_countable_SimpleXMLElement() {
-               $this->assertTrue( is_countable( new SimpleXMLElement( '<xml><tag>1</tag><tag>2</tag></xml>' ) ) );
-       }
-
-       /**
-        * Test that is_iterable() is always available (either from PHP or WP).
-        *
-        * @ticket 43619
-        */
-       function test_is_iterable_availability() {
-               $this->assertTrue( function_exists( 'is_iterable' ) );
-       }
-
-       /**
-        * Test is_iterable() polyfill.
-        *
-        * @ticket 43619
-        *
-        * @dataProvider iterable_variable_test_data
-        *
-        * @param mixed $variable    Variable to check.
-        * @param bool  $is_iterable The expected return value of PHP 7.1 is_iterable() function.
-        */
-       function test_is_iterable_functionality( $variable, $is_iterable ) {
-               $this->assertSame( is_iterable( $variable ), $is_iterable );
-       }
-
-       /**
-        * Data provider for test_is_iterable_functionality().
-        *
-        * @ticket 43619
-        *
-        * @return array {
-        *     @type array {
-        *         @type mixed $variable    Variable to check.
-        *         @type bool  $is_iterable The expected return value of PHP 7.1 is_iterable() function.
-        *     }
-        * }
-        */
-       public function iterable_variable_test_data() {
-               return array(
-                       array( array(), true ),
-                       array( array( 1, 2, 3 ), true ),
-                       array( new ArrayIterator( array( 1, 2, 3 ) ), true ),
-                       array( 1, false ),
-                       array( 3.14, false ),
-                       array( new stdClass(), false ),
-               );
-       }
-}
-
-/* used in test_mb_substr_phpcore */
-class ClassA {
-       public function __toString() {
-               return 'Class A object';
-       }
-}
-
-class ArrayIteratorFake extends ArrayIterator {
-}
-
-class CountableFake implements Countable {
-       #[ReturnTypeWillChange]
-       public function count() {
-               return 16;
-       }
-}
</del></span></pre>
</div>
</div>

</body>
</html>