Version 1.0.0

This commit is contained in:
diffhead
2025-11-16 01:51:25 +04:00
committed by Viktor Smagin
commit 8cb7f400fd
43 changed files with 4462 additions and 0 deletions

57
tests/BuilderTest.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests;
use Diffhead\PHP\DataEnrichmentKit\Builder;
use Diffhead\PHP\DataEnrichmentKit\Exception\TargetIsNull;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Builder::class)]
#[CoversMethod(Builder::class, 'withTarget')]
#[CoversMethod(Builder::class, 'item')]
#[CoversMethod(Builder::class, 'target')]
#[CoversMethod(Builder::class, 'build')]
class BuilderTest extends TestCase
{
public function testBuildingWithTarget(): void
{
$builder = Builder::withTarget('entity', 'field');
$this->assertInstanceOf(Builder::class, $builder);
}
public function testItemsInsideTheRequest(): void
{
$builder = new Builder();
$builder->item('key', 'alias');
$request = $builder->target('entity', 'field')->build();
$this->assertCount(1, $request->items()->getIterator());
$this->assertEquals('key', $request->items()->getIterator()[0]->key());
$this->assertEquals('alias', $request->items()->getIterator()[0]->alias());
}
public function testTargetInsideTheRequest(): void
{
$builder = new Builder();
$builder->target('entity', 'field');
$request = $builder->build();
$this->assertEquals('entity', $request->target()->entity());
$this->assertEquals('field', $request->target()->field());
}
public function testBuildThrowsExceptionWhenTargetIsNull(): void
{
$this->expectException(TargetIsNull::class);
$builder = new Builder();
$builder->build();
}
}

116
tests/EnricherTest.php Normal file
View File

@@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests;
use Diffhead\PHP\DataEnrichmentKit\Enricher;
use Diffhead\PHP\DataEnrichmentKit\Interface\Repository;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
use Diffhead\PHP\DataEnrichmentKit\Service\Enrichment;
use Diffhead\PHP\DataEnrichmentKit\Storage\Repositories;
use Diffhead\PHP\DataEnrichmentKit\Storage\Requests;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
#[CoversClass(Enricher::class)]
class EnricherTest extends TestCase
{
public function testEnrich(): void
{
$posts = [
[
'user_id' => 1,
'content' => 'Post by user 1'
],
[
'user_id' => 2,
'content' => 'Post by user 2'
],
[
'user_id' => 3,
'content' => 'Post by user 3'
],
];
$enrichment = new Enrichment($this->getRepositories());
$enricher = new Enricher($enrichment);
$items = new ItemsBag();
$items->push(new Item('*.user_id', 'user'));
$target = new Target('user', 'id');
$requests = new Requests([
new Request($items, $target)
]);
$enriched = $enricher->enrich($posts, $requests);
$this->assertSame(
[
'user_id' => 1,
'content' => 'Post by user 1',
'user' => [
'id' => 1,
'name' => 'Blank.1',
],
],
$enriched[0]
);
$this->assertSame(
[
'user_id' => 2,
'content' => 'Post by user 2',
'user' => [
'id' => 2,
'name' => 'Blank.2',
],
],
$enriched[1]
);
$this->assertSame(
[
'user_id' => 3,
'content' => 'Post by user 3',
'user' => [
'id' => 3,
'name' => 'Blank.3',
],
],
$enriched[2]
);
}
private function getRepositories(): Repositories
{
return new Repositories([
'user' => new EnricherTestUserRepository(),
]);
}
}
class EnricherTestUserRepository implements Repository
{
public function getByFieldValues(string $field, array $values): iterable
{
return [
$this->getBlankWithId(1),
$this->getBlankWithId(2),
$this->getBlankWithId(3),
];
}
private function getBlankWithId(int $id): array
{
return [
'id' => $id,
'name' => sprintf('Blank.%d', $id)
];
}
}

127
tests/MessageTest.php Normal file
View File

@@ -0,0 +1,127 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests;
use Diffhead\PHP\DataEnrichmentKit\Exception\PayloadIsNotJson;
use Diffhead\PHP\DataEnrichmentKit\Header;
use Diffhead\PHP\DataEnrichmentKit\Message;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
use Diffhead\PHP\DataEnrichmentKit\Service\Parser;
use Diffhead\PHP\DataEnrichmentKit\Service\Serializer;
use Diffhead\PHP\DataEnrichmentKit\Storage\Requests;
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\Stream;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Message::class)]
#[CoversMethod(Message::class, 'setRequests')]
#[CoversMethod(Message::class, 'getRequests')]
class MessageTest extends TestCase
{
public function testSetRequests(): void
{
$serializer = new Serializer();
$parser = new Parser();
$message = new Message($serializer, $parser);
$psrFactory = new Psr17Factory();
$psrMessage = $psrFactory->createResponse();
$itemsBag = new ItemsBag();
$itemsBag->push(new Item('key1', 'alias1'));
$target = new Target('entity', 'field');
$requests = new Requests([
new Request($itemsBag, $target)
]);
$header = Header::XEnrichmentRequest;
$result = $message->setRequests($psrMessage, $header, $requests);
$this->assertTrue($result->hasHeader($header->value));
$this->assertNotEmpty($result->getHeader($header->value));
}
public function testGetRequests(): void
{
$serializer = new Serializer();
$parser = new Parser();
$message = new Message($serializer, $parser);
$header = Header::XEnrichmentRequest;
$psrFactory = new Psr17Factory();
$psrMessage = $psrFactory->createResponse()
->withHeader($header->value, 'key1+alias1@entity,field');
$requests = $message->getRequests($psrMessage, $header);
$this->assertInstanceOf(Requests::class, $requests);
$this->assertCount(1, $requests);
}
public function testGetPayload(): void
{
$serializer = new Serializer();
$parser = new Parser();
$message = new Message($serializer, $parser);
$psrFactory = new Psr17Factory();
$psrMessage = $psrFactory->createResponse()
->withBody(Stream::create('{"key":"value"}'));
$payload = $message->getPayload($psrMessage);
$this->assertIsArray($payload);
$this->assertSame(['key' => 'value'], $payload);
}
public function testGetPayloadThrowsExceptionOnNonJson(): void
{
$this->expectException(\JsonException::class);
$serializer = new Serializer();
$parser = new Parser();
$message = new Message($serializer, $parser);
$psrFactory = new Psr17Factory();
$psrMessage = $psrFactory->createResponse()
->withBody(Stream::create('Invalid JSON'));
$this->expectException(PayloadIsNotJson::class);
$message->getPayload($psrMessage);
}
public function testSetPayload(): void
{
$serializer = new Serializer();
$parser = new Parser();
$message = new Message($serializer, $parser);
$psrFactory = new Psr17Factory();
$psrMessage = $psrFactory->createResponse();
$payload = ['key' => 'value'];
$payloadString = json_encode($payload, JSON_THROW_ON_ERROR);
$result = $message->setPayload($psrMessage, $payload);
$this->assertEquals($payloadString, (string) $result->getBody());
$payloadNew = ['newKey' => 'newValue'];
$payloadNewString = json_encode($payloadNew, JSON_THROW_ON_ERROR);
$resultNew = $message->setPayload($result, $payloadNew);
$this->assertEquals($payloadNewString, (string) $resultNew->getBody());
}
}

24
tests/Object/ItemTest.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Interface;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Item::class)]
#[CoversMethod(Item::class, 'key')]
#[CoversMethod(Item::class, 'alias')]
class ItemTest extends TestCase
{
public function testProperlyInitialized(): void
{
$item = new Item('key', 'alias');
$this->assertEquals('key', $item->key());
$this->assertEquals('alias', $item->alias());
}
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Object;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(ItemsBag::class)]
#[CoversMethod(ItemsBag::class, 'push')]
#[CoversMethod(ItemsBag::class, 'getIterator')]
class ItemsBagTest extends TestCase
{
public function testProperlyInitialized(): void
{
$itemsBag = new ItemsBag();
$item = new Item('key', 'alias');
$itemsBag->push($item);
$this->assertCount(1, iterator_to_array($itemsBag->getIterator()));
$this->assertSame($item, iterator_to_array($itemsBag->getIterator())[0]);
}
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Object;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Request::class)]
#[CoversMethod(Request::class, 'items')]
#[CoversMethod(Request::class, 'target')]
class RequestTest extends TestCase
{
public function testProperlyInitialized(): void
{
$itemsBag = new ItemsBag();
$target = new Target('entity', 'field');
$request = new Request($itemsBag, $target);
$this->assertSame($itemsBag, $request->items());
$this->assertSame($target, $request->target());
}
}

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Object;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Target::class)]
#[CoversMethod(Target::class, 'entity')]
#[CoversMethod(Target::class, 'field')]
class TargetTest extends TestCase
{
public function testProperlyInitialized(): void
{
$target = new Target('entity', 'field');
$this->assertEquals('entity', $target->entity());
$this->assertEquals('field', $target->field());
}
}

View File

@@ -0,0 +1,403 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Service;
use Diffhead\PHP\DataEnrichmentKit\Interface\Enrichment as EnrichmentInterface;
use Diffhead\PHP\DataEnrichmentKit\Interface\Repository;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
use Diffhead\PHP\DataEnrichmentKit\Service\Enrichment;
use Diffhead\PHP\DataEnrichmentKit\Storage\Repositories;
use Diffhead\PHP\DataEnrichmentKit\Storage\Requests;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Enrichment::class)]
#[CoversMethod(Enrichment::class, 'enrich')]
class EnrichmentTest extends TestCase
{
public function testImplementsEnrichmentInterface(): void
{
$this->assertInstanceOf(
EnrichmentInterface::class,
new Enrichment($this->getRepositories())
);
}
public function testEnrichmentJsonObjectWithArraysInside(): void
{
$payload = [
"data" => [
[
'user_id' => 1,
'content' => 'Post by user 1'
],
[
'user_id' => 2,
'content' => 'Post by user 2'
],
]
];
$items = new ItemsBag();
$items->push(new Item('data.*.user_id', 'user'));
$target = new Target('user', 'id');
$requests = new Requests();
$requests->append(new Request($items, $target));
$enrichment = new Enrichment($this->getRepositories());
$enriched = $enrichment->enrich($payload, $requests);
$this->assertSame(
[
'user_id' => 1,
'content' => 'Post by user 1',
'user' => [
'id' => 1,
'name' => 'Blank.1',
],
],
$enriched['data'][0]
);
$this->assertSame(
[
'user_id' => 2,
'content' => 'Post by user 2',
'user' => [
'id' => 2,
'name' => 'Blank.2',
],
],
$enriched['data'][1]
);
}
public function testEnrichmentJsonObject(): void
{
$payload = [
'user_id' => 1,
'content' => 'Post by user 1'
];
$items = new ItemsBag();
$items->push(new Item('user_id', 'user'));
$target = new Target('user', 'id');
$requests = new Requests();
$requests->append(new Request($items, $target));
$enrichment = new Enrichment($this->getRepositories());
$enriched = $enrichment->enrich($payload, $requests);
$this->assertSame(
[
'user_id' => 1,
'content' => 'Post by user 1',
'user' => [
'id' => 1,
'name' => 'Blank.1',
],
],
$enriched
);
}
public function testEnrichArrayItemsUsingProperlyRequest(): void
{
$posts = [
[
'user_id' => 1,
'content' => 'Post by user 1'
],
[
'user_id' => 2,
'content' => 'Post by user 2'
],
[
'user_id' => 3,
'content' => 'Post by user 3'
],
];
$items = new ItemsBag();
$items->push(new Item('*.user_id', 'user'));
$target = new Target('user', 'id');
$requests = new Requests();
$requests->append(new Request($items, $target));
$enrichment = new Enrichment($this->getRepositories());
$enriched = $enrichment->enrich($posts, $requests);
$this->assertSame(
[
'user_id' => 1,
'content' => 'Post by user 1',
'user' => [
'id' => 1,
'name' => 'Blank.1',
],
],
$enriched[0]
);
$this->assertSame(
[
'user_id' => 2,
'content' => 'Post by user 2',
'user' => [
'id' => 2,
'name' => 'Blank.2',
],
],
$enriched[1]
);
$this->assertSame(
[
'user_id' => 3,
'content' => 'Post by user 3',
'user' => [
'id' => 3,
'name' => 'Blank.3',
],
],
$enriched[2]
);
}
public function tesEnrichArrayItemsWithoutExistingTargets(): void
{
$posts = [
[
'user_id' => 10,
'content' => 'Post by user 10'
],
[
'user_id' => 20,
'content' => 'Post by user 20'
],
];
$items = new ItemsBag();
$items->push(new Item('*.user_id', 'user'));
$target = new Target('user', 'id');
$requests = new Requests();
$requests->append(new Request($items, $target));
$enrichment = new Enrichment($this->getRepositories());
$enriched = $enrichment->enrich($posts, $requests);
$this->assertSame(
[
'user_id' => 10,
'content' => 'Post by user 10',
'user' => null,
],
$enriched[0]
);
$this->assertSame(
[
'user_id' => 20,
'content' => 'Post by user 20',
'user' => null,
],
$enriched[1]
);
}
public function testEnrichArrayUsingNotWildcardKey(): void
{
$posts = [
[
'user_id' => 1,
'content' => 'Post by user 1'
],
];
$items = new ItemsBag();
$items->push(
new Item('data.invalid_path', 'user')
);
$target = new Target('user', 'id');
$requests = new Requests();
$requests->append(new Request($items, $target));
$enrichment = new Enrichment($this->getRepositories());
$enriched = $enrichment->enrich($posts, $requests);
$this->assertSame(
[
[
'user_id' => 1,
'content' => 'Post by user 1',
],
'data' => [
'user' => null
]
],
$enriched
);
}
public function testEnrichNestedArrayItems(): void
{
$categoriesGroups = [
[
[
'category_id' => 1,
'name' => 'Category 1',
'creator_id' => 1
],
[
'category_id' => 2,
'name' => 'Category 2',
'creator_id' => 3
],
]
];
$items = new ItemsBag();
$items->push(new Item('*.*.creator_id', 'creator'));
$target = new Target('user', 'id');
$requests = new Requests();
$requests->append(new Request($items, $target));
$enrichment = new Enrichment($this->getRepositories());
$enriched = $enrichment->enrich($categoriesGroups, $requests);
$this->assertSame(
[
[
[
'category_id' => 1,
'name' => 'Category 1',
'creator_id' => 1,
'creator' => [
'id' => 1,
'name' => 'Blank.1',
],
],
[
'category_id' => 2,
'name' => 'Category 2',
'creator_id' => 3,
'creator' => [
'id' => 3,
'name' => 'Blank.3',
],
],
]
],
$enriched
);
}
public function testProperlyWorkingWithRepositoriesReturnNonArrayAccessObject(): void
{
$posts = [
[
'user_id' => 1,
'content' => 'Post by user 1'
],
];
$items = new ItemsBag();
$items->push(new Item('*.user_id', 'user'));
$target = new Target('user', 'id');
$requests = new Requests();
$requests->append(new Request($items, $target));
$enrichment = new Enrichment($this->getRepositories(true));
$enriched = $enrichment->enrich($posts, $requests);
$this->assertSame(
[
'user_id' => 1,
'content' => 'Post by user 1',
'user' => [
'id' => 1,
'name' => 'Blank.1',
],
],
$enriched[0]
);
}
private function getRepositories(bool $repoUsingGenerator = false): Repositories
{
return new Repositories([
'user' => $repoUsingGenerator
? new EnrichmentTestUserRepositoryUsingGenerator()
: new EnrichmentTestUserRepository()
]);
}
}
class EnrichmentTestUserRepository implements Repository
{
public function getByFieldValues(string $field, array $values): iterable
{
return array_filter(
[
$this->getBlankWithId(1),
$this->getBlankWithId(2),
$this->getBlankWithId(3),
],
fn ($item) => in_array($item[$field], $values, true)
);
}
private function getBlankWithId(int $id): array
{
return [
'id' => $id,
'name' => sprintf('Blank.%d', $id)
];
}
}
class EnrichmentTestUserRepositoryUsingGenerator implements Repository
{
public function getByFieldValues(string $field, array $values): iterable
{
$items = [
$this->getBlankWithId(1),
$this->getBlankWithId(2),
$this->getBlankWithId(3),
];
foreach ($items as $item) {
if (in_array($item[$field], $values, true)) {
yield $item;
}
}
}
private function getBlankWithId(int $id): array
{
return [
'id' => $id,
'name' => sprintf('Blank.%d', $id)
];
}
}

View File

@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Service;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Service\Parser;
use Diffhead\PHP\DataEnrichmentKit\Exception\InvalidRequest;
use Diffhead\PHP\DataEnrichmentKit\Interface\Parser as ParserInterface;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Parser::class)]
#[CoversMethod(Parser::class, 'parse')]
class ParserTest extends TestCase
{
public function testImplementsParserInterface(): void
{
$this->assertInstanceOf(ParserInterface::class, new Parser());
}
public function testParseValidInput(): void
{
$parser = new Parser();
$input = 'key1+alias1,key2+alias2@entity,field';
$request = $parser->parse($input);
$this->assertInstanceOf(Request::class, $request);
$this->assertEquals('entity', $request->target()->entity());
$this->assertEquals('field', $request->target()->field());
$items = iterator_to_array($request->items()->getIterator());
$this->assertCount(2, $items);
$this->assertEquals('key1', $items[0]->key());
$this->assertEquals('alias1', $items[0]->alias());
$this->assertEquals('key2', $items[1]->key());
$this->assertEquals('alias2', $items[1]->alias());
}
public function testParseThrowsExceptionOnEmptyTarget(): void
{
$this->expectException(InvalidRequest::class);
$parser = new Parser();
$parser->parse('key1+alias1,key2+alias2@');
}
public function testParseThrowsExceptionOnInvalidTarget(): void
{
$this->expectException(InvalidRequest::class);
$parser = new Parser();
$parser->parse('key1+alias1,key2+alias2@entity');
}
public function testParseThrowsExceptionOnEmptyInput(): void
{
$this->expectException(InvalidRequest::class);
$parser = new Parser();
$parser->parse('');
}
}

View File

@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Service;
use Diffhead\PHP\DataEnrichmentKit\Interface\Serializer as SerializerInterface;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
use Diffhead\PHP\DataEnrichmentKit\Service\Serializer;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Serializer::class)]
#[CoversMethod(Serializer::class, 'toString')]
class SerializerTest extends TestCase
{
public function testImplementsSerializerInterface(): void
{
$this->assertInstanceOf(SerializerInterface::class, new Serializer());
}
public function testToString(): void
{
$itemsBag = new ItemsBag();
$itemsBag->push(new Item('key1', 'alias1'));
$itemsBag->push(new Item('key2', 'alias2'));
$target = new Target('entity', 'field');
$request = new Request($itemsBag, $target);
$serializer = new Serializer();
$result = $serializer->toString($request);
$this->assertEquals('key1+alias1,key2+alias2@entity,field', $result);
}
public function testToStringWithEmptyAlias(): void
{
$itemsBag = new ItemsBag();
$itemsBag->push(new Item('key1'));
$itemsBag->push(new Item('key2', 'alias2'));
$target = new Target('entity', 'field');
$request = new Request($itemsBag, $target);
$serializer = new Serializer();
$result = $serializer->toString($request);
$this->assertEquals('key1,key2+alias2@entity,field', $result);
}
}

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Storage;
use Diffhead\PHP\DataEnrichmentKit\Exception\RepositoryNotFound;
use Diffhead\PHP\DataEnrichmentKit\Interface\Repository;
use Diffhead\PHP\DataEnrichmentKit\Storage\Repositories;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Repositories::class)]
#[CoversMethod(Repositories::class, 'set')]
#[CoversMethod(Repositories::class, 'get')]
class RepositoriesTest extends TestCase
{
public function testSetAndGet(): void
{
$repositories = new Repositories();
$mockRepository = new class implements Repository {
public function getByFieldValues(string $field, array $values): array
{
return [
['field' => $field, 'value' => $values[0]],
];
}
};
$repositories->set('target', $mockRepository);
$retrievedRepository = $repositories->get('target');
$this->assertSame($mockRepository, $retrievedRepository);
}
public function testGetThrowsExceptionWhenRepositoryNotFound(): void
{
$this->expectException(RepositoryNotFound::class);
$repositories = new Repositories();
$repositories->get('nonexistent_target');
}
}

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Storage;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
use Diffhead\PHP\DataEnrichmentKit\Storage\Requests;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Requests::class)]
#[CoversMethod(Requests::class, 'append')]
#[CoversMethod(Requests::class, 'count')]
#[CoversMethod(Requests::class, 'requests')]
class RequestsTest extends TestCase
{
public function testAppendAndCount(): void
{
$requests = new Requests();
$this->assertEquals(0, $requests->count());
$request = new Request(new ItemsBag(), new Target('entity', 'field'));
$requests->append($request);
$this->assertEquals(1, $requests->count());
}
public function testRequestsAreSame(): void
{
$request1 = new Request(new ItemsBag(), new Target('entity', 'field'));
$request2 = new Request(new ItemsBag(), new Target('entity2', 'field2'));
$requests = new Requests([$request1, $request2]);
$requestsArray = iterator_to_array($requests);
$this->assertCount(2, $requestsArray);
$this->assertSame($request1, $requestsArray[0]);
$this->assertSame($request2, $requestsArray[1]);
}
}

322
tests/Utility/ArrTest.php Normal file
View File

@@ -0,0 +1,322 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Tests\Utility;
use Diffhead\PHP\DataEnrichmentKit\Utility\Arr;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
#[CoversClass(Arr::class)]
#[CoversMethod(Arr::class, 'get')]
#[CoversMethod(Arr::class, 'set')]
class ArrTest extends TestCase
{
public function testGetExistingItems(): void
{
$array = [
'user' => [
'id' => 1,
'name' => 'John Doe',
'address' => [
'city' => 'New York',
'zip' => '10001',
],
],
'posts' => [
['id' => 101, 'title' => 'First Post'],
['id' => 102, 'title' => 'Second Post'],
],
];
$this->assertEquals(1, Arr::get('user.id', $array));
$this->assertEquals('John Doe', Arr::get('user.name', $array));
$this->assertEquals('New York', Arr::get('user.address.city', $array));
$this->assertEquals('10001', Arr::get('user.address.zip', $array));
$this->assertEquals(101, Arr::get('posts.0.id', $array));
$this->assertEquals('First Post', Arr::get('posts.0.title', $array));
$this->assertEquals(102, Arr::get('posts.1.id', $array));
$this->assertEquals('Second Post', Arr::get('posts.1.title', $array));
}
public function testGetExistingItemsFromNestedArray(): void
{
$array = [
[
'orders' => [
['id' => 201, 'amount' => 150],
['id' => 202, 'amount' => 200],
]
],
[
'orders' => [
['id' => 203, 'amount' => 250],
['id' => 204, 'amount' => 300],
]
]
];
$this->assertEquals(201, Arr::get('0.orders.0.id', $array));
$this->assertEquals(200, Arr::get('0.orders.1.amount', $array));
$this->assertEquals(203, Arr::get('1.orders.0.id', $array));
$this->assertEquals(300, Arr::get('1.orders.1.amount', $array));
}
public function testGetMultipleExistingItems(): void
{
$array = [
'users' => [
['name' => 'John Doe'],
['name' => 'Jane Smith'],
['name' => 'Alice Johnson'],
],
'posts' => [
'categories' => [
[
'name' => 'Tech',
'posts' => [
['title' => 'Latest Tech Trends'],
['title' => 'AI Innovations']
]
],
[
'name' => 'Health',
'posts' => [
['title' => 'Wellness Tips'],
['title' => 'Nutrition Advice']
]
]
]
],
];
$this->assertSame(
[
'John Doe',
'Jane Smith',
'Alice Johnson'
],
Arr::get('users.*.name', $array)
);
$this->assertSame(
[
'Latest Tech Trends',
'AI Innovations',
'Wellness Tips',
'Nutrition Advice'
],
Arr::get('posts.categories.*.posts.*.title', $array)
);
}
public function testGetMultipleExistingItemsInsideNestedArray(): void
{
$array = [
[
'orders' => [
['id' => 201, 'amount' => 150],
['id' => 202, 'amount' => 200],
]
],
[
'orders' => [
['id' => 203, 'amount' => 250],
['id' => 204, 'amount' => 300],
]
]
];
$this->assertSame(
[
150,
200,
250,
300
],
Arr::get('*.orders.*.amount', $array)
);
}
public function testGetNonExistingItems(): void
{
$array = [
'user' => [
'id' => 1,
'name' => 'John Doe',
],
];
$this->assertNull(Arr::get('user.age', $array));
$this->assertEquals('Unknown', Arr::get('user.age', $array, 'Unknown'));
$this->assertNull(Arr::get('user.address.city', $array));
$this->assertEquals('N/A', Arr::get('user.address.city', $array, 'N/A'));
$this->assertNull(Arr::get('posts.0.id', $array));
}
public function testGetMultipleNonExistingItems(): void
{
$array = [
'users' => [
['name' => 'John Doe'],
['name' => 'Jane Smith'],
],
];
$this->assertSame([], Arr::get('users.*.age', $array));
$this->assertSame([], Arr::get('users.*.address.*.city', $array));
}
public function testSetValuesAtExistingPaths(): void
{
$origin = [
'user' => [
'id' => 1,
'name' => 'John Doe',
],
];
$updated = Arr::set('user.name', $origin, 'Jane Smith');
$updated = Arr::set('user.id', $updated, 2);
$this->assertEquals('Jane Smith', $updated['user']['name']);
$this->assertEquals(2, $updated['user']['id']);
}
public function testSetMultipleValuesAtExistingPaths(): void
{
$origin = [
'users' => [
['name' => 'John Doe'],
['name' => 'Jane Smith'],
],
];
$updated = Arr::set('users.*.age', $origin, 29);
$updated = Arr::set('users.*.source', $updated, 'facebook');
$this->assertEquals(29, $updated['users'][0]['age']);
$this->assertEquals(29, $updated['users'][1]['age']);
$this->assertEquals('facebook', $updated['users'][0]['source']);
$this->assertEquals('facebook', $updated['users'][1]['source']);
}
public function testSetValuesAtNonExistingPaths(): void
{
$origin = [
'user' => [
'id' => 1,
'name' => 'John Doe',
],
];
$updated = Arr::set('user.address.city', $origin, 'New York');
$updated = Arr::set('user.address.zip', $updated, '10001');
$updated = Arr::set('posts.0.id', $updated, 101);
$updated = Arr::set('posts.0.title', $updated, 'First Post');
$this->assertEquals('New York', $updated['user']['address']['city']);
$this->assertEquals('10001', $updated['user']['address']['zip']);
$this->assertEquals(101, $updated['posts'][0]['id']);
$this->assertEquals('First Post', $updated['posts'][0]['title']);
}
public function testSetMultipleValuesAtNonExistingPaths(): void
{
$origin = [
'users' => [],
];
$updated = Arr::set('users.*.name', $origin, 'John Doe');
$updated = Arr::set('users.*.age', $updated, 30);
$this->assertCount(1, $updated['users']);
$this->assertEquals('John Doe', $updated['users'][0]['name']);
$this->assertEquals(30, $updated['users'][0]['age']);
}
public function testHavingValueAtExistingPath(): void
{
$array = [
'user' => [
'id' => 1,
'name' => 'John Doe',
'address' => [
'city' => 'New York',
'zip' => '10001',
],
],
];
$this->assertTrue(Arr::has('user.id', $array));
$this->assertTrue(Arr::has('user.name', $array));
$this->assertTrue(Arr::has('user.address.city', $array));
$this->assertTrue(Arr::has('user.address.zip', $array));
}
public function testHavingValueAtExistingPathUsingWildcardNonStrictMode(): void
{
$array = [
'users' => [
['age' => 25],
['name' => 'Jane Smith'],
[
'name' => 'Alice Johnson',
'phones' => [
['type' => 'mobile', 'number' => '123-456-7890'],
['type' => 'home', 'number' => '098-765-4321'],
],
],
],
];
$this->assertTrue(Arr::has('users.*.name', $array));
$this->assertTrue(Arr::has('users.*.phones.*.number', $array));
}
public function testHavingValueAtExistingPathUsingWildcardStrictMode(): void
{
$array = [
'users' => [
['age' => 25],
['name' => 'Alice Brandon'],
],
'users_with_phones' => [
[
'name' => 'Bob Brown',
'phones' => [
['type' => 'mobile', 'number' => '555-555-5555'],
],
],
[
'name' => 'Carol White',
'phones' => [
['type' => 'home', 'number' => '444-444-4444'],
],
]
]
];
$this->assertFalse(Arr::has('users.*.name', $array, true));
$this->assertTrue(Arr::has('users_with_phones.*.phones.*.number', $array, true));
}
public function testHavingValueAtNonExistingPathUsingWildcard(): void
{
$array = [
'users' => [
['name' => 'John Doe'],
['name' => 'Jane Smith'],
],
];
$this->assertFalse(Arr::has('users.*.age', $array));
$this->assertFalse(Arr::has('users.*.address.city', $array));
$this->assertFalse(Arr::has('users.*.phones.*.type', $array));
}
}