Skip to content

Commit

Permalink
PHP 8.1 support (for static analyses), improve code quality with `inf…
Browse files Browse the repository at this point in the history
…ection` tool.
  • Loading branch information
roquie committed Jan 11, 2022
1 parent f0b0d7d commit 3610636
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 36 deletions.
11 changes: 8 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"php": ">=7.4"
},
"require-dev": {
"phpstan/phpstan": "^0.12.5",
"infection/infection": "^0.26.0",
"phpstan/phpstan": "^1.3.3",
"phpunit/phpunit": "^9",
"symfony/var-dumper": "^5.0"
},
Expand All @@ -28,15 +29,19 @@
}
},
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"infection/extension-installer": true
}
},
"archive": {
"exclude": ["obelix.jpg"]
},
"scripts": {
"check": [
"phpunit --stop-on-fail --coverage-text",
"phpstan analyse src --level 8"
"phpstan analyse src --level 8",
"infection --threads=4 -s"
]
}
}
13 changes: 13 additions & 0 deletions infection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "vendor/infection/infection/resources/schema.json",
"source": {
"directories": [
"src"
]
},
"mutators": {
"@default": true
},
"minMsi": 100,
"minCoveredMsi": 100
}
40 changes: 27 additions & 13 deletions src/Dot.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Spacetab\Obelix;

use InvalidArgumentException;
use RecursiveArrayIterator;
use RecursiveIteratorIterator;

Expand All @@ -12,48 +13,58 @@ final class Dot
private const DELIMITER = '.';
private const WILDCARD = '*';

/**
* @var array<mixed>
*/
/** @var array<mixed> */
private array $items;

/**
* @var array<string, mixed>
*/
/** @var array<string, mixed> */
private static array $cache = [];

/** @var non-empty-string */
private string $delimiter = self::DELIMITER;

/** @var non-empty-string */
private string $wildcard = self::WILDCARD;

/**
* Dot constructor.
*
* @param array<mixed>|\Spacetab\Obelix\Dot $items
* @param array<mixed>|Dot $items
*/
public function __construct($items = [])
{
if ($items instanceof self) {
if (is_array($items)) {
$this->items = $items;
} elseif (/** @infection-ignore-all */ $items instanceof self) {
$this->items = $items->toArray();
self::$cache = $items->getCache();
} else {
$this->items = (array) $items;
throw new InvalidArgumentException('The items argument must be an array or Dot instance.');
}
}

public function setDelimiter(string $delimiter): void
{
if ($delimiter === '') {
throw new InvalidArgumentException('The delimiter must not be an empty string.');
}

$this->delimiter = $delimiter;
}

public function setWildcard(string $wildcard): void
{
if ($wildcard === '') {
throw new InvalidArgumentException('The wildcard must not be an empty string.');
}

$this->wildcard = $wildcard;
}

/**
* @param string $path
* @param mixed|null $default
* @return \Spacetab\Obelix\ResultSet
*
* @return ResultSet
*/
public function get(string $path, $default = null): ResultSet
{
Expand All @@ -72,8 +83,8 @@ public function get(string $path, $default = null): ResultSet
$pathway = [];
$flatArray = null;

$segments = (array) explode($this->delimiter, $path);
$countSegments = count($segments);
$segments = explode($this->delimiter, $path);
$countSegments = count($segments);

$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($this->items), RecursiveIteratorIterator::SELF_FIRST);

Expand All @@ -92,6 +103,7 @@ public function get(string $path, $default = null): ResultSet
}

$value = $flatArray === null ? $default : array_values($flatArray);
$flatArray = $flatArray ?? [$path => $default];

if (is_countable($value) && count($value) === 1) {
// @phpstan-ignore-next-line
Expand All @@ -100,7 +112,7 @@ public function get(string $path, $default = null): ResultSet

self::$cache[$path] = [$value, $flatArray];

return new ResultSet($value, $flatArray ?? []);
return new ResultSet($value, $flatArray);
}

/**
Expand All @@ -115,9 +127,11 @@ private function isUserPathEqualsRealPath(array $user, array $real): bool
}

$i = 0;
// @infection-ignore-all
$equals = false;

foreach ($user as $item) {
// @infection-ignore-all
$val = $real[$i] ?? false;

// to work with integer indexes in string path (for cases like "foo.0")
Expand Down
68 changes: 48 additions & 20 deletions tests/DotTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,40 @@

namespace Spacetab\Tests\Obelix;

use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use Spacetab\Obelix;
use stdClass;

class DotTest extends TestCase
{
public function testGetItemsFromSimpleArrayAndSingleValue()
public function testWhenDeveloperPassInvalidValueToConstructor(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The items argument must be an array or Dot instance.');

new Obelix\Dot(new stdClass());
}

public function testWhenDeveloperPassInvalidValueToDelimiterSetter(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The delimiter must not be an empty string.');

$dot = new Obelix\Dot([]);
$dot->setDelimiter('');
}

public function testWhenDeveloperPassInvalidValueToWildcardSetter(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The wildcard must not be an empty string.');

$dot = new Obelix\Dot([]);
$dot->setWildcard('');
}

public function testGetItemsFromSimpleArrayAndSingleValue(): void
{
$array = [
'foo' => [
Expand All @@ -28,7 +56,7 @@ public function testGetItemsFromSimpleArrayAndSingleValue()
], $result->getMap());
}

public function testGetItemsFromSimpleArrayAndItReturnsCorrectAssociativeArray()
public function testGetItemsFromSimpleArrayAndItReturnsCorrectAssociativeArray(): void
{
$array = [
'foo' => [
Expand Down Expand Up @@ -58,7 +86,7 @@ public function testGetItemsFromSimpleArrayAndItReturnsCorrectAssociativeArray()
], $result->getMap());
}

public function testGetItemsFromSimpleArrayAndItReturnsCorrectIndexedArray()
public function testGetItemsFromSimpleArrayAndItReturnsCorrectIndexedArray(): void
{
$array = [
'foo' => [
Expand Down Expand Up @@ -88,7 +116,7 @@ public function testGetItemsFromSimpleArrayAndItReturnsCorrectIndexedArray()
], $result->getMap());
}

public function testGetNotExistingItemsFromArray()
public function testGetNotExistingItemsFromArray(): void
{
$array = [
'foo' => [
Expand All @@ -104,10 +132,10 @@ public function testGetNotExistingItemsFromArray()
$result = $dot->get('foo.bar.40', 'default');

$this->assertSame('default', $result->getValue());
$this->assertSame([], $result->getMap());
$this->assertSame(['foo.bar.40' => 'default'], $result->getMap());
}

public function testGetItemByIndexFromArray()
public function testGetItemByIndexFromArray(): void
{
$array = [
'foo' => [
Expand All @@ -124,7 +152,7 @@ public function testGetItemByIndexFromArray()
], $result->getMap());
}

public function testGetItemsSelectedByWildcardSimpleCase()
public function testGetItemsSelectedByWildcardSimpleCase(): void
{
$array = [
'foo' => [
Expand Down Expand Up @@ -152,7 +180,7 @@ public function testGetItemsSelectedByWildcardSimpleCase()
], $result->getMap());
}

public function testGetItemsSelectedByWildcardAtEndPathString()
public function testGetItemsSelectedByWildcardAtEndPathString(): void
{
$k = [
['key' => 1],
Expand Down Expand Up @@ -180,7 +208,7 @@ public function testGetItemsSelectedByWildcardAtEndPathString()
], $result->getMap());
}

public function testGetItemsSelectedByWildcardHardCase()
public function testGetItemsSelectedByWildcardHardCase(): void
{
$array = [
'test' => [
Expand Down Expand Up @@ -246,7 +274,7 @@ public function testGetItemsSelectedByWildcardHardCase()
], $result->getMap());
}

public function testDotReturnsCorrectCacheKeyValues()
public function testDotReturnsCorrectCacheKeyValues(): void
{
$array = [
'foo' => [
Expand All @@ -264,7 +292,7 @@ public function testDotReturnsCorrectCacheKeyValues()
], $dot->getCache());
}

public function testDotCacheHit()
public function testDotCacheHit(): void
{
$array = [
'foo' => [
Expand Down Expand Up @@ -295,7 +323,7 @@ public function testDotCacheHit()
], $keyHit->getMap());
}

public function testCacheClearedOnDestructorCall()
public function testCacheClearedOnDestructorCall(): void
{
$array = [
'foo' => [
Expand All @@ -318,7 +346,7 @@ public function testCacheClearedOnDestructorCall()
$this->assertSame([], $dot->toArray());
}

public function testHowToDotObjectAcceptsDotObject()
public function testHowToDotObjectAcceptsDotObject(): void
{
$array = [
'foo' => [
Expand All @@ -340,7 +368,7 @@ public function testHowToDotObjectAcceptsDotObject()
$this->assertSame($array, $dot2->toArray());
}

public function testHowToDotObjectWorksWithOtherDelimiterAndWildcard()
public function testHowToDotObjectWorksWithOtherDelimiterAndWildcard(): void
{
$array = [
'foo' => [
Expand All @@ -359,7 +387,7 @@ public function testHowToDotObjectWorksWithOtherDelimiterAndWildcard()
$this->assertSame([1, 2], $dot->get('foo:bar:@:key')->getValue());
}

public function testGetItemWithWildcardAndAssociativeArray()
public function testGetItemWithWildcardAndAssociativeArray(): void
{
$array = [
'foo' => [
Expand All @@ -385,7 +413,7 @@ public function testGetItemWithWildcardAndAssociativeArray()
], $dot->get('foo.*.*')->getMap());
}

public function testGetItemWhereWildcardPassedAsSingleSymbol()
public function testGetItemWhereWildcardPassedAsSingleSymbol(): void
{
$array = [
[1, 3, 4]
Expand All @@ -400,7 +428,7 @@ public function testGetItemWhereWildcardPassedAsSingleSymbol()
], $result->getMap());
}

public function testGetItemWhenSecondKeyIsNotUniqueInSubArrays()
public function testGetItemWhenSecondKeyIsNotUniqueInSubArrays(): void
{
$array = [
'server' => [
Expand Down Expand Up @@ -435,7 +463,7 @@ public function testGetItemWhenSecondKeyIsNotUniqueInSubArrays()
], $dot->get('server.headers')->getMap());
}

public function testWhenALotOfManyKeysAndValuesAreSameAkaHardestTest()
public function testWhenALotOfManyKeysAndValuesAreSameAkaHardestTest(): void
{
$array = [
'foo' => [
Expand Down Expand Up @@ -482,7 +510,7 @@ public function testWhenALotOfManyKeysAndValuesAreSameAkaHardestTest()
],
true,
[],
new \stdClass()
new stdClass()
]
],
'bar' => 1,
Expand Down Expand Up @@ -519,7 +547,7 @@ public function testWhenALotOfManyKeysAndValuesAreSameAkaHardestTest()
$this->assertSame(['foo.baz.acme' => $expected], $result->getMap());

$result = $dot->get('foo.faa.2');
$this->assertInstanceOf(\stdClass::class, $result->getValue());
$this->assertInstanceOf(stdClass::class, $result->getValue());
$this->assertSame($array['foo']['faa'][2], $result->getValue());
$this->assertSame(['foo.faa.2' => $array['foo']['faa'][2]], $result->getMap());

Expand Down

0 comments on commit 3610636

Please sign in to comment.