generated from chevere/package-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
245 additions
and
5 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Chevere. | ||
* | ||
* (c) Rodolfo Berrios <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Chevere\VarSupport; | ||
|
||
use Chevere\VarSupport\Interfaces\BreadcrumbInterface; | ||
use OutOfBoundsException; | ||
use function Chevere\Message\message; | ||
|
||
final class Breadcrumb implements BreadcrumbInterface | ||
{ | ||
/** | ||
* @var array<int, string> | ||
*/ | ||
private array $items = []; | ||
|
||
private int $pos = -1; | ||
|
||
private int $id = -1; | ||
|
||
public function __toString(): string | ||
{ | ||
if ($this->items === []) { | ||
return ''; | ||
} | ||
|
||
$return = ''; | ||
foreach ($this->items as $item) { | ||
$return .= sprintf('[%s]', $item); | ||
} | ||
|
||
return $return; | ||
} | ||
|
||
public function toArray(): array | ||
{ | ||
return $this->items; | ||
} | ||
|
||
public function has(int $pos): bool | ||
{ | ||
return array_key_exists($pos, $this->items); | ||
} | ||
|
||
public function count(): int | ||
{ | ||
return count($this->items); | ||
} | ||
|
||
public function pos(): int | ||
{ | ||
return $this->pos; | ||
} | ||
|
||
public function withAdded(string $item): BreadcrumbInterface | ||
{ | ||
$new = clone $this; | ||
++$new->id; | ||
$new->items[$new->id] = $item; | ||
$new->pos = $new->id; | ||
|
||
return $new; | ||
} | ||
|
||
public function withRemoved(int $pos): BreadcrumbInterface | ||
{ | ||
if (! array_key_exists($pos, $this->items)) { | ||
throw new OutOfBoundsException( | ||
(string) message( | ||
'Pos `%pos%` not found', | ||
pos: $pos | ||
) | ||
); | ||
} | ||
$new = clone $this; | ||
unset($new->items[$pos]); | ||
|
||
return $new; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Chevere. | ||
* | ||
* (c) Rodolfo Berrios <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Chevere\VarSupport\Interfaces; | ||
|
||
use Countable; | ||
use Stringable; | ||
|
||
/** | ||
* Describe a general purpose iterator companion which builds a breadcrumb | ||
* path for nested variables, enabling to easily locate current position. | ||
*/ | ||
interface BreadcrumbInterface extends Stringable, Countable | ||
{ | ||
/** | ||
* Returns an string representation of the object. | ||
* | ||
* ```php | ||
* return '[item0][item1][itemN]...[itemN+1]'; | ||
* ``` | ||
*/ | ||
public function __toString(): string; | ||
|
||
/** | ||
* Returns an array representation of the object. | ||
* | ||
* ```php | ||
* return [0 => 'item',]; | ||
* ``` | ||
* @return array<int, string> | ||
*/ | ||
public function toArray(): array; | ||
|
||
/** | ||
* Indicates whether the instance has the given position. | ||
*/ | ||
public function has(int $pos): bool; | ||
|
||
/** | ||
* Returns the current breadcrumb position. | ||
*/ | ||
public function pos(): int; | ||
|
||
/** | ||
* Return an instance with the specified added item. | ||
* | ||
* This method MUST retain the state of the current instance, and return | ||
* an instance that contains the specified added item. | ||
*/ | ||
public function withAdded(string $item): self; | ||
|
||
/** | ||
* Return an instance with the specified pos removed. | ||
* | ||
* This method MUST retain the state of the current instance, and return | ||
* an instance that contains the specified pos removed. | ||
*/ | ||
public function withRemoved(int $pos): self; | ||
} |
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Chevere. | ||
* | ||
* (c) Rodolfo Berrios <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Chevere\Tests; | ||
|
||
use Chevere\VarSupport\Breadcrumb; | ||
use OutOfBoundsException; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
final class BreadcrumbTest extends TestCase | ||
{ | ||
public function testConstruct(): void | ||
{ | ||
$breadcrumb = new Breadcrumb(); | ||
$this->assertEmpty($breadcrumb->toArray()); | ||
$this->assertEmpty($breadcrumb->__toString()); | ||
$this->assertCount(0, $breadcrumb); | ||
$this->assertFalse($breadcrumb->has(0)); | ||
$this->assertSame(-1, $breadcrumb->pos()); | ||
} | ||
|
||
public function testWithAddedItems(): void | ||
{ | ||
$items = [ | ||
'test-0', | ||
'test-1', | ||
'test-2', | ||
]; | ||
$breadcrumb = new Breadcrumb(); | ||
$withAdded = $breadcrumb; | ||
foreach ($items as $pos => $item) { | ||
$withAdded = $withAdded->withAdded($item); | ||
$this->assertTrue($withAdded->has($pos)); | ||
$this->assertSame($pos, $withAdded->pos()); | ||
$this->assertContains($item, $withAdded->toArray()); | ||
$this->assertStringContainsString($item, $withAdded->__toString()); | ||
} | ||
$this->assertNotSame($breadcrumb, $withAdded); | ||
$this->assertSame($items, $withAdded->toArray()); | ||
$this->assertSame( | ||
'[' . implode('][', $items) . ']', | ||
$withAdded->__toString() | ||
); | ||
$withRemoved = $withAdded->withRemoved(1); | ||
$this->assertNotSame($withAdded, $withRemoved); | ||
$this->assertNotContains($items[1], $withRemoved->toArray()); | ||
$this->assertStringNotContainsString($items[1], $withRemoved->__toString()); | ||
} | ||
|
||
public function testWithRemovedItems(): void | ||
{ | ||
$items = [ | ||
'test-0', | ||
'test-1', | ||
'test-2', | ||
]; | ||
$breadcrumb = new Breadcrumb(); | ||
$pos = 0; | ||
foreach ($items as $pos => $item) { | ||
$breadcrumb = $breadcrumb | ||
->withAdded($item) | ||
->withRemoved($pos); | ||
$this->assertFalse($breadcrumb->has($pos)); | ||
$this->assertNotContains($item, $breadcrumb->toArray()); | ||
$this->assertStringNotContainsString($item, $breadcrumb->__toString()); | ||
} | ||
$this->assertCount(0, $breadcrumb); | ||
$this->assertEmpty($breadcrumb->toArray()); | ||
$this->assertEmpty($breadcrumb->__toString()); | ||
$this->expectException(OutOfBoundsException::class); | ||
$breadcrumb->withRemoved($pos); | ||
} | ||
} |