Skip to content

Commit

Permalink
Upd: json support
Browse files Browse the repository at this point in the history
  • Loading branch information
yzen-dev committed Jul 3, 2024
1 parent 533522a commit 4c87cf9
Show file tree
Hide file tree
Showing 11 changed files with 523 additions and 21 deletions.
10 changes: 3 additions & 7 deletions src/ArgumentsRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,15 @@ final class ArgumentsRepository

/**
*
* @param iterable<mixed>|object|string ...$args
* @param iterable<mixed>|object ...$args
*/
public function __construct(...$args)
{
// Unpacking named arguments
$input = sizeof(func_get_args()) === 1 ? $args[0] : $args;

if (!is_array($input)) {
if (is_string($input)) {
$input = json_decode($input, true);
} else {
$input = (array)$input;
}
$input = (array)$input;
}

$this->args = $input;
Expand Down
20 changes: 19 additions & 1 deletion src/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function __construct()
* Create instance T class
*
* @param class-string<T> $class
* @param iterable<mixed>|object|string ...$args
* @param iterable<mixed>|object ...$args
*
* @return null|T
* @throws ClassNotFoundException|InstantiableClassException|ReflectionException|InvalidArgumentException
Expand Down Expand Up @@ -78,4 +78,22 @@ public function createMultiple(array $classes, array $args): ?array
}
return $result;
}

/**
* Create instance T class
*
* @param class-string<T> $class
* @param string $json
*
* @return null|T
* @throws ClassNotFoundException
* @throws InvalidArgumentException
* @throws ReflectionException
*/
public function createFromJson(string $class, string $json): mixed
{
$data = json_decode($json, true);

return $this->create($class, $data);

Check failure on line 97 in src/Hydrator.php

View workflow job for this annotation

GitHub Actions / psalm

MissingThrowsDocblock

src/Hydrator.php:97:23: MissingThrowsDocblock: ClassTransformer\Exceptions\InstantiableClassException is thrown but not caught - please either catch or add a @throws annotation (see https://psalm.dev/169)
}
}
2 changes: 1 addition & 1 deletion src/InstanceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ final class InstanceFactory

/**
* @param class-string<T> $class
* @param iterable<mixed>|object|string ...$args
* @param iterable<mixed>|object ...$args
*
* @return mixed
* @throws ClassNotFoundException|InstantiableClassException|ReflectionException|InvalidArgumentException
Expand Down
161 changes: 157 additions & 4 deletions tests/Integration/ClassTransformerFromArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Tests\Integration\DTO\BasketDTO;
use Tests\Integration\DTO\ProductDTO;
use Tests\Integration\DTO\PurchaseDTO;
use Tests\Integration\DTO\Full\PurchaseDTO as FullPurchaseDto;
use Tests\Integration\DTO\EmptyClassDto;
use Tests\Integration\DTO\ArrayScalarDTO;
use Tests\Integration\DTO\UserEmptyTypeDTO;
Expand Down Expand Up @@ -204,10 +205,7 @@ public function testTripleRecursiveArray(): void
}
}
}

/**
* @throws ReflectionException|ClassNotFoundException
*/

public function testEmptyTypeObject(): void
{
$data = $this->getBaseArrayData();
Expand All @@ -219,4 +217,159 @@ public function testEmptyTypeObject(): void
self::assertEquals($data['email'], $userDTO->email);
self::assertEquals($data['balance'], $userDTO->balance);
}

public function testFull(): void
{
$data = $this->getPurcheseObject();
$object = (new Hydrator)->create(FullPurchaseDto::class, $data);
$this->assertEquals($data['user']['id'], $object->user->id);
}

public function getPurcheseObject(): array
{
return [
'products' => [
[
'id' => 1,
'name' => 'phone',
'price' => 43.03,
'description' => 'test description for phone',
'count' => 123
],
[
'id' => 2,
'name' => 'bread',
'price' => 10.56,
'description' => 'test description for bread',
'count' => 321
],
[
'id' => 3,
'name' => 'book',
'price' => 5.5,
'description' => 'test description for book',
'count' => 333
],
[
'id' => 4,
'name' => 'PC',
'price' => 100,
'description' => 'test description for PC',
'count' => 7
]
],
'user' => [
'id' => 1,
'contact' => 'fake@mail.com',
'balance' => 10012.23,
'type' => 'admin',
'realAddress' => 'test address',
'createdAt' => '2023-04-10',
],
'createdAt' => '2023-04-10',
'address' => $this->getAddress()
];
}

private function getAddress()
{
return [
"source" => "мск сухонска 11/-89",
"result" => "г Москва, ул Сухонская, д 11, кв 89",
"postal_code" => "127642",
"country" => "Россия",
"country_iso_code" => "RU",
"federal_district" => "Центральный",
"region_fias_id" => "0c5b2444-70a0-4932-980c-b4dc0d3f02b5",
"region_kladr_id" => "7700000000000",
"region_iso_code" => "RU-MOW",
"region_with_type" => "г Москва",
"region_type" => "г",
"region_type_full" => "город",
"region" => "Москва",
"area_fias_id" => null,
"area_kladr_id" => null,
"area_with_type" => null,
"area_type" => null,
"area_type_full" => null,
"area" => null,
"city_fias_id" => null,
"city_kladr_id" => null,
"city_with_type" => null,
"city_type" => null,
"city_type_full" => null,
"city" => null,
"city_area" => "Северо-восточный",
"city_district_fias_id" => null,
"city_district_kladr_id" => null,
"city_district_with_type" => "р-н Северное Медведково",
"city_district_type" => "р-н",
"city_district_type_full" => "район",
"city_district" => "Северное Медведково",
"settlement_fias_id" => null,
"settlement_kladr_id" => null,
"settlement_with_type" => null,
"settlement_type" => null,
"settlement_type_full" => null,
"settlement" => null,
"street_fias_id" => "95dbf7fb-0dd4-4a04-8100-4f6c847564b5",
"street_kladr_id" => "77000000000283600",
"street_with_type" => "ул Сухонская",
"street_type" => "ул",
"street_type_full" => "улица",
"street" => "Сухонская",
"house_fias_id" => "5ee84ac0-eb9a-4b42-b814-2f5f7c27c255",
"house_kladr_id" => "7700000000028360004",
"house_type" => "д",
"house_type_full" => "дом",
"house" => "11",
"block_type" => null,
"block_type_full" => null,
"block" => null,
"flat_fias_id" => "f26b876b-6857-4951-b060-ec6559f04a9a",
"flat_type" => "кв",
"flat_type_full" => "квартира",
"flat" => "89",
"flat_area" => "34.6",
"square_meter_price" => "239953",
"flat_price" => "8302374",
"postal_box" => null,
"fias_id" => "f26b876b-6857-4951-b060-ec6559f04a9a",
"fias_code" => "77000000000000028360004",
"fias_level" => "9",
"kladr_id" => "7700000000028360004",
"capital_marker" => "0",
"okato" => "45280583000",
"oktmo" => "45362000",
"tax_office" => "7715",
"tax_office_legal" => "7715",
"timezone" => "UTC+3",
"geo_lat" => "55.8782557",
"geo_lon" => "37.65372",
"beltway_hit" => "IN_MKAD",
"beltway_distance" => null,
"qc_geo" => 0,
"qc_complete" => 0,
"qc_house" => 2,
"qc" => 0,
"unparsed_parts" => null,
"metro" => [
[
"distance" => 1.1,
"line" => "Калужско-Рижская",
"name" => "Бабушкинская"
],
[
"distance" => 1.2,
"line" => "Калужско-Рижская",
"name" => "Медведково"
],
[
"distance" => 2.5,
"line" => "Калужско-Рижская",
"name" => "Свиблово"
]
]
];
}
}
16 changes: 8 additions & 8 deletions tests/Integration/ClassTransformerFromJsonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function testBaseArray(): void
{
$data = $this->getBaseArrayData();

$userDTO = (new Hydrator())->create(UserDTO::class, json_encode($data));
$userDTO = (new Hydrator())->createFromJson(UserDTO::class, json_encode($data));

self::assertInstanceOf(UserDTO::class, $userDTO);
self::assertEquals($data['id'], $userDTO->id);
Expand All @@ -58,7 +58,7 @@ public function testConstructFormatArray(): void
'address_test' => 'example address',
'color' => 'White'
];
$userDTO = (new Hydrator())->create(ConstructDto::class, json_encode($data));
$userDTO = (new Hydrator())->createFromJson(ConstructDto::class, json_encode($data));
self::assertInstanceOf(ConstructDto::class, $userDTO);
self::assertEquals($data['id'], $userDTO->id);
self::assertEquals($data['email'], $userDTO->email);
Expand All @@ -76,7 +76,7 @@ public function testConstructFormatArray(): void
public function testEmptyClass(): void
{
$data = $this->getBaseArrayData();
$instance = (new Hydrator())->create(EmptyClassDto::class, json_encode($data));
$instance = (new Hydrator())->createFromJson(EmptyClassDto::class, json_encode($data));
self::assertInstanceOf(EmptyClassDto::class, $instance);
}

Expand All @@ -89,7 +89,7 @@ public function testScalarArray(): void
'stringList' => [100, 200, 300],
'intList' => [400, 500, 600]
];
$dto = (new Hydrator())->create(ArrayScalarDTO::class, json_encode($data));
$dto = (new Hydrator())->createFromJson(ArrayScalarDTO::class, json_encode($data));
self::assertInstanceOf(ArrayScalarDTO::class, $dto);
self::assertIsString($dto->stringList[0]);
self::assertEquals($dto->stringList[0], '100');
Expand All @@ -107,7 +107,7 @@ public function testNullArray(): void
'products' => null
];

$userDTO = (new Hydrator())->create(ArrayScalarDTO::class, json_encode($data));
$userDTO = (new Hydrator())->createFromJson(ArrayScalarDTO::class, json_encode($data));

self::assertInstanceOf(ArrayScalarDTO::class, $userDTO);
}
Expand Down Expand Up @@ -164,7 +164,7 @@ public function testTransformMultiple(): void
public function testRecursiveArray(): void
{
$data = $this->getRecursiveArrayData();
$purchaseDTO = (new Hydrator())->create(PurchaseDTO::class, json_encode($data));
$purchaseDTO = (new Hydrator())->createFromJson(PurchaseDTO::class, json_encode($data));

self::assertInstanceOf(PurchaseDTO::class, $purchaseDTO);
self::assertInstanceOf(UserDTO::class, $purchaseDTO->user);
Expand Down Expand Up @@ -193,7 +193,7 @@ public function testTripleRecursiveArray(): void
{
$data = $this->getTripleRecursiveArray();

$basketDTO = (new Hydrator())->create(BasketDTO::class, json_encode($data));
$basketDTO = (new Hydrator())->createFromJson(BasketDTO::class, json_encode($data));

foreach ($basketDTO->orders as $key => $purchase) {
self::assertInstanceOf(PurchaseDTO::class, $purchase);
Expand Down Expand Up @@ -223,7 +223,7 @@ public function testEmptyTypeObject(): void
{
$data = $this->getBaseArrayData();

$userDTO = (new Hydrator())->create(UserEmptyTypeDTO::class, json_encode($data));
$userDTO = (new Hydrator())->createFromJson(UserEmptyTypeDTO::class, json_encode($data));

self::assertInstanceOf(UserEmptyTypeDTO::class, $userDTO);
self::assertEquals($data['id'], $userDTO->id);
Expand Down
Loading

0 comments on commit 4c87cf9

Please sign in to comment.