Last active
January 15, 2022 02:21
-
-
Save funder7/a306e78148bffdaf186da2bbc401a1cb to your computer and use it in GitHub Desktop.
Unit testing a function that (tries to) determine if an array is associative (php >= 7.3)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Tests\Unit; | |
// based on original work from the PHP Laravel framework | |
if (!function_exists('str_contains')) | |
{ | |
function str_contains($haystack, $needle) { | |
return $needle !== '' && mb_strpos($haystack, $needle) !== false; | |
} | |
} | |
// Matteo Galletti - https://www.php.net/manual/en/function.array-is-list | |
if (!function_exists('array_is_list')) | |
{ | |
function array_is_list(array $a) { | |
return $a === [] || (array_keys($a) === range(0, count($a) - 1)); | |
} | |
} | |
use PHPUnit\Framework\TestCase; | |
/** | |
* @version php@>=7.3 | |
*/ | |
class ArrayUtilTest extends TestCase | |
{ | |
/** | |
* Check if an array is associative | |
* | |
* @link https://gist.github.com/Thinkscape/1965669#gistcomment-4029335 (method5,6) Benchmarks | |
* @throws \JsonException array to json conversion problem | |
*/ | |
public static function isAssociative(array $arr): bool | |
{ | |
// consider empty, and [0, 1, 2, ...] sequential | |
if (empty($arr) || array_is_list($arr)) { | |
return false; | |
} | |
// first scenario: | |
// [ 1 => [*any*] ] | |
// [ 'a' => [*any*] ] | |
foreach ( $arr as $key => $value ) { | |
if (is_array($value)) { | |
return true; | |
} | |
} | |
// second scenario: read the json string | |
$jsonNest = json_encode($arr, JSON_THROW_ON_ERROR); | |
return str_contains($jsonNest, '{'); | |
} | |
/** | |
* Associative (true) expectation | |
* | |
* @throws \JsonException | |
* @return void | |
*/ | |
public function testAssociativeArrayCases(): void | |
{ | |
foreach ( $this->associativeValues() as $associativeArray ) { | |
$this->assertTrue( | |
ArrayUtil::isAssociative($associativeArray), | |
">> " . json_encode($associativeArray) . "\nwas not recognized as associative" | |
); | |
} | |
} | |
/** | |
* Sequential (false) expectation | |
* | |
* @throws \JsonException | |
* @return void | |
*/ | |
public function testSequentialArrayCases(): void | |
{ | |
foreach ( $this->sequentialValues() as $seqArray ) { | |
$this->assertFalse( | |
ArrayUtil::isAssociative($seqArray), | |
'>> ' . json_encode($seqArray) . "\nwas not recognized as sequential" | |
); | |
} | |
} | |
private function associativeValues(): array | |
{ | |
$assocNum[1] = 0; | |
$assocNum[2] = 1; | |
$other[0] = 'a'; | |
$other[2] = 'b'; | |
$other[3] = 'c'; | |
$another = [ 'b' => 0, '1' => 1 ]; | |
$anotherOne = [ '1' => 3, '2' => 4 ]; | |
$assocIntCharArr[3] = [ 'a' ]; | |
$assocIntCharAssoc[4] = [ 'a' => 'b' ]; | |
return [ | |
[ 'a' => 'b' ], | |
[ 'a' => 'a' ], | |
[ 'a' => [] ], | |
[ 'a' => 1 ], | |
[ 'b' => 0 ], | |
[ 'a' => [ 'a', 'b', 'c' ] ], | |
[ 'a' => 1, 'b' => 2, 'c' => [ 1, 2, 3 ] ], | |
[ 'a' => 1, 'b' => 2, 'c' => [ 0, 1, 2 ] ], | |
[ 'a' => [ 1 ] ], | |
[ 'b' => [ 0 ] ], | |
$assocNum, | |
$other, | |
$another, | |
$anotherOne, | |
$assocIntCharArr, | |
$assocIntCharAssoc, | |
]; | |
} | |
private function sequentialValues(): array | |
{ | |
return [ | |
[ 1, 2, 3 ], | |
[ 0, 1, 2 ], | |
[ 0, 0, 0 ], | |
[ 1 ], | |
[ 0 ], | |
[ [ 10, 20, 30 ] ], | |
[ [ [ 30, 40, 50 ] ] ] | |
]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment