Skip to content

Commit

Permalink
fix(ProxyGenerator): Handle readonly targets.
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi committed Feb 8, 2024
1 parent 5b0b9c8 commit 32ae222
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* feat: Target object can now be a lazy-loading proxy.
* fix: Bump lower bound of `symfony/var-exporter` to `6.4.1` & `7.0.1`.
* test: Add mandatory config for `symfony/framework-bundle`.
* fix(`ProxyGenerator`): Handle readonly targets.

## 0.6.7

Expand Down
13 changes: 8 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
PHP=php
COMPOSER=composer

.PHONY: test
test: dump phpstan psalm phpunit

.PHONY: dump
dump:
composer dump-autoload --optimize
$(COMPOSER) dump-autoload --optimize

.PHONY: phpstan
phpstan:
vendor/bin/phpstan analyse
$(PHP) vendor/bin/phpstan analyse

.PHONY: psalm
psalm:
vendor/bin/psalm
$(PHP) vendor/bin/psalm

.PHONY: phpunit
phpunit:
$(eval c ?=)
rm -rf var
vendor/bin/phpunit --testdox -v $(c)
$(PHP) vendor/bin/phpunit --testdox -v $(c)

.PHONY: php-cs-fixer
php-cs-fixer: tools/php-cs-fixer
$< fix --config=.php-cs-fixer.dist.php --verbose --allow-risky=yes
$(PHP) $< fix --config=.php-cs-fixer.dist.php --verbose --allow-risky=yes

.PHONY: tools/php-cs-fixer
tools/php-cs-fixer:
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"mapping",
"api",
"symfony",
"api-platform"
"api-platform",
"lazy-loading",
"proxy"
],
"authors": [
{
Expand Down
3 changes: 2 additions & 1 deletion src/Transformer/Proxy/Implementation/ProxyGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ private function generateProxyCode(string $sourceClass, string $targetClass): st
$this->getClassHeader() .
sprintf('namespace %s;', $namespace) . "\n\n" .
sprintf(
'final class %s%s',
'final %sclass %s%s',
$targetReflection->isReadOnly() ? 'readonly ' : ' ',
$shortName,
ProxyHelper::generateLazyGhost($targetReflection)
);
Expand Down
20 changes: 20 additions & 0 deletions tests/Fixtures/LazyObject/ObjectWithIdFinalDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\LazyObject;

final class ObjectWithIdFinalDto
{
public ?string $id = null;
public ?string $name = null;
}
23 changes: 23 additions & 0 deletions tests/Fixtures/LazyObject/ObjectWithIdReadOnlyDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\LazyObject;

readonly class ObjectWithIdReadOnlyDto
{
public function __construct(
public string $id,
public string $name
) {
}
}
43 changes: 42 additions & 1 deletion tests/IntegrationTest/LazyObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
use Rekalogika\Mapper\Tests\Common\AbstractFrameworkTest;
use Rekalogika\Mapper\Tests\Fixtures\LazyObject\ObjectWithId;
use Rekalogika\Mapper\Tests\Fixtures\LazyObject\ObjectWithIdDto;
use Rekalogika\Mapper\Tests\Fixtures\LazyObject\ObjectWithIdFinalDto;
use Rekalogika\Mapper\Tests\Fixtures\LazyObject\ObjectWithIdReadOnlyDto;

class LazyObjectTest extends AbstractFrameworkTest
{
Expand All @@ -32,6 +34,45 @@ public function testLazyObjectHydration(): void
$this->expectExceptionMessage('This method should not be called');
$source = new ObjectWithId();
$target = $this->mapper->map($source, ObjectWithIdDto::class);
$foo = $target->name;
$this->initialize($target);
}

public function testFinal(): void
{
// final class can't be lazy
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('This method should not be called');
$source = new ObjectWithId();
$target = $this->mapper->map($source, ObjectWithIdFinalDto::class);
$this->initialize($target);
}

/**
* In PHP 8.2, readonly class can't be lazy
*
* @requires PHP >= 8.2.0
* @requires PHP < 8.3.0
*/
public function testReadOnly82(): void
{
// should not use proxy. if a proxy is not used, it should throw an
// exception
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('This method should not be called');
$source = new ObjectWithId();
$target = $this->mapper->map($source, ObjectWithIdReadOnlyDto::class);
}

/**
* In PHP 8.3, readonly class can be lazy
*
* @requires PHP >= 8.3.0
*/
public function testReadOnly83(): void
{
// if a proxy is used, it should not throw an exception without
// initialization
$source = new ObjectWithId();
$target = $this->mapper->map($source, ObjectWithIdReadOnlyDto::class);
}
}

0 comments on commit 32ae222

Please sign in to comment.