Skip to content

Commit

Permalink
patch
Browse files Browse the repository at this point in the history
  • Loading branch information
AnourValar committed Dec 1, 2023
1 parent 293e5e5 commit 87ac392
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 17 deletions.
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ parameters:
- '#Call to an undefined method#'
- '#If condition is always true#'
- '#Call to an undefined static#'
- '#Method class\@anonymous\/tests\/ServiceTest.php\:12\:\:obtain\(\)#'

excludePaths:

Expand Down
172 changes: 172 additions & 0 deletions src/MapperCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php

namespace AnourValar\LaravelAtom;

abstract class MapperCollection implements \Iterator, \JsonSerializable, \ArrayAccess
{
/**
* Mapper class
*
* @return string
*/
abstract protected function mapper(): string;

/**
* @var array
*/
protected array $data;

/**
* @param array $data
* @return void
* @throws \RuntimeException
*/
public function __construct(array $data)
{
$mapper = $this->mapper();
if (! is_subclass_of($mapper, \AnourValar\LaravelAtom\Mapper::class)) {
throw new \RuntimeException('mapper() method must return \AnourValar\LaravelAtom\Mapper compatibility class.');
}

foreach ($data as &$item) {
if (! is_object($item) || get_class($item) != $mapper) {
$item = $mapper::from($item);
}
}
unset($item);

$this->data = $data;
}

/**
* Create an object from the input
*
* @param array $data
* @return static
*/
public static function from(array $data): static
{
return new static($data);
}

/**
* Get data
*
* @return array
*/
public function toArray(): array
{
$result = [];

foreach ($this->data as $key => $item) {
$result[$key] = $item->toArray();
}

return $result;
}

/**
* @see \JsonSerializable
*
* @return array
*/
public function jsonSerialize(): array
{
return $this->toArray();
}

/**
* @see \Traversable
*
* @return mixed
*/
public function current(): mixed
{
return current($this->data);
}

/**
* @see @see \Traversable
*
* @return mixed
*/
public function key(): mixed
{
return key($this->data);
}

/**
* @see \Traversable
*
* @return void
*/
public function next(): void
{
next($this->data);
}

/**
* @see \Traversable
*
* @return void
*/
public function rewind(): void
{
reset($this->data);
}

/**
* @see \Traversable
*
* @return bool
*/
public function valid(): bool
{
return key($this->data) !== null;
}

/**
* @see \ArrayAccess
*
* @param mixed $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value): void
{
throw new \RuntimeException('Incorrect usage.');
}

/**
* @see \ArrayAccess
*
* @param mixed $offset
* @return bool
*/
public function offsetExists($offset): bool
{
return isset($this->data[$offset]);
}

/**
* @see \ArrayAccess
*
* @param mixed $offset
* @return void
*/
public function offsetUnset($offset): void
{
throw new \RuntimeException('Incorrect usage.');
}

/**
* @see \ArrayAccess
*
* @param mixed $offset
* @return mixed
*/
public function offsetGet($offset): mixed
{
return $this->data[$offset];
}
}
24 changes: 7 additions & 17 deletions src/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function __call($method, array $args)
*/
public function lock(): void
{
$sha1 = sha1('/' . $this->canonizeArgs(func_get_args()) . '/');
$sha1 = sha1(serialize($this->canonizeArgs(func_get_args())));
$connection = \DB::connection($this->config['locks']['connection']);
$table = $this->config['locks']['table'];

Expand Down Expand Up @@ -240,32 +240,22 @@ public function removeOnRollBack(int $key, string $connection = null): void
*/
protected function canonizeArgs($value)
{
if (is_scalar($value)) {
if (is_string($value)) {
$value = trim(mb_strtolower($value));
}

if ($value === '' || $value === false) {
return 0;
}

return $value;
if ($value === null && ! \App::isProduction()) {
throw new \RuntimeException('Null lock.');
}

if (is_iterable($value)) {
if (is_array($value)) {
foreach ($value as &$item) {
$item = $this->canonizeArgs($item);
}
unset($item);

return implode('/', $value);
}

if ($value === null && ! \App::isProduction()) {
throw new \RuntimeException('Null lock.');
if (is_integer($value) || is_float($value)) {
$value = (string) $value;
}

return 0;
return $value;
}

/**
Expand Down
72 changes: 72 additions & 0 deletions tests/MapperCollectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace AnourValar\LaravelAtom\Tests;

use AnourValar\LaravelAtom\Tests\Mappers\MapperCollectionSimple;
use AnourValar\LaravelAtom\Tests\Mappers\SimpleMapper;

class MapperCollectionTest extends \PHPUnit\Framework\TestCase
{
/**
* @dataProvider provideSimpleData
* @return void
*/
public function test_simple(array $data)
{
$mapper = MapperCollectionSimple::from($data);

$index = 0;
foreach ($mapper as $item) {

if ($index == 0) {
$this->assertSame(['a' => 'a1', 'b' => 'b1', 'c' => null, 'd' => 1], $item->toArray());
}

if ($index == 1) {
$this->assertSame(['a' => 'a2', 'b' => 'b2', 'c' => null, 'd' => 1], $item->toArray());
}

if ($index == 2) {
$this->assertSame(['a' => 'a3', 'b' => 'b3', 'c' => null, 'd' => 1], $item->toArray());
}

$index++;
}

$keys = array_keys($data);
$this->assertSame(
[
$keys[0] => ['a' => 'a1', 'b' => 'b1', 'c' => null, 'd' => 1],
$keys[1] => ['a' => 'a2', 'b' => 'b2', 'c' => null, 'd' => 1],
$keys[2] => ['a' => 'a3', 'b' => 'b3', 'c' => null, 'd' => 1],
],
$mapper->toArray()
);

$this->assertSame(['a' => 'a1', 'b' => 'b1', 'c' => null, 'd' => 1], $mapper[$keys[0]]->toArray());
$this->assertSame(['a' => 'a2', 'b' => 'b2', 'c' => null, 'd' => 1], $mapper[$keys[1]]->toArray());
$this->assertSame(['a' => 'a3', 'b' => 'b3', 'c' => null, 'd' => 1], $mapper[$keys[2]]->toArray());
}

public static function provideSimpleData()
{
return [
// list
[
[
['a' => 'a1', 'b' => 'b1'],
SimpleMapper::from(['a' => 'a2', 'b' => 'b2']),
['a' => 'a3', 'b' => 'b3'],
],
],
// assoc
[
[
'foo' => ['a' => 'a1', 'b' => 'b1'],
'bar' => SimpleMapper::from(['a' => 'a2', 'b' => 'b2']),
'baz' => ['a' => 'a3', 'b' => 'b3'],
],
],
];
}
}
17 changes: 17 additions & 0 deletions tests/Mappers/MapperCollectionSimple.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace AnourValar\LaravelAtom\Tests\Mappers;

use AnourValar\LaravelAtom\MapperCollection;

class MapperCollectionSimple extends MapperCollection
{
/**
* {@inheritDoc}
* @see \AnourValar\LaravelAtom\MapperCollection::mapper()
*/
protected function mapper(): string
{
return SimpleMapper::class;
}
}
34 changes: 34 additions & 0 deletions tests/ServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace AnourValar\LaravelAtom\Tests;

class ServiceTest extends \PHPUnit\Framework\TestCase
{
/**
* @return void
*/
public function test_canonizeArgs()
{
$class = new class (new \AnourValar\LaravelAtom\Registry(), []) extends \AnourValar\LaravelAtom\Service {
public function obtain()
{
return $this->canonizeArgs(func_get_args());
}
};

$this->assertSame(
[ ['foo' => 'bar'] ],
$class->obtain(['foo' => 'bar'])
);

$this->assertSame(
[ ['a' => '1', 'b' => true, 'c' => false, 'd' => '0', 'e' => ' ', 'f' => '3', 'g' => '2.5', 'h' => ''] ],
$class->obtain(['a' => 1, 'b' => true, 'c' => false, 'd' => 0, 'e' => ' ', 'f' => '3', 'g' => 2.5, 'h' => ''])
);

$this->assertSame(
[ ['one'], ['foo' => ['bar' => ['baz' => '123.45']]] ],
$class->obtain(['one'], ['foo' => ['bar' => ['baz' => 123.45]]])
);
}
}

0 comments on commit 87ac392

Please sign in to comment.