Repository: symfony/symfony
File: src/Symfony/Component/ObjectMapper/Tests/ObjectMapperTest.php (PHP)

Code before:
    {
        yield [new ObjectMapper()];
        yield [new ObjectMapper(new ReflectionObjectMapperMetadataFactory(), PropertyAccess::createPropertyAccessor())];
    }

    public function testMapInitializesLazyObject()
    {
        $lazy = new LazyFoo();
        $mapper = new ObjectMapper();
        $mapper->map($lazy, \stdClass::class);
        $this->assertTrue($lazy->isLazyObjectInitialized());
    }

    #[RequiresPhp('>=8.4')]
    public function testMapInitializesNativePhp84LazyObject()
    {
        $initialized = false;
        $initializer = function () use (&$initialized) {
            $initialized = true;

            $p = new MyProxy();
            $p->name = 'test';

            return $p;
        };

        $r = new \ReflectionClass(MyProxy::class);
        $lazyObj = $r->newLazyProxy($initializer);
        $this->assertFalse($initialized);
        $mapper = new ObjectMapper();
        $d = $mapper->map($lazyObj, MyProxy::class);
        $this->assertSame('test', $d->name);
        $this->assertTrue($initialized);
    }

    public function testDecorateObjectMapper()
    {
        $mapper = new ObjectMapper();
        $myMapper = new class($mapper) implements ObjectMapperInterface {
            public function __construct(private ObjectMapperInterface $mapper)
            {
                $this->mapper = $mapper->withObjectMapper($this);
            }

            public function map(object $source, object|string|null $target = null): object
            {
                $mapped = $this->mapper->map($source, $target);

                if ($source instanceof C) {
                    $mapped->baz = 'got decorated';
                }

Review comment (suggestion):
This test got transformed and now only tests that an embeded relation does call the decorated mapper. 
The previous test (based on https://github.com/api-platform/core/commit/d06b1a0a0e9dcde7fcdb585b435cd617620b098b) was based on a leaking object map which isn't great (thanks @nicolas-grekas for the fix). The new non-leaky behavior will need an update for our particular use case inside API Platform and that's fine. 

Code after:

    public function testMapInitializesLazyObject()
    {
        $lazy = new LazyFoo();
        $mapper = new ObjectMapper();
        $mapper->map($lazy, \stdClass::class);
        $this->assertTrue($lazy->isLazyObjectInitialized());
    }

    #[RequiresPhp('>=8.4')]
    public function testMapInitializesNativePhp84LazyObject()
    {
        $initialized = false;
        $initializer = function () use (&$initialized) {
            $initialized = true;

            $p = new MyProxy();
            $p->name = 'test';

            return $p;
        };

        $r = new \ReflectionClass(MyProxy::class);
        $lazyObj = $r->newLazyProxy($initializer);
        $this->assertFalse($initialized);
        $mapper = new ObjectMapper();
        $d = $mapper->map($lazyObj, MyProxy::class);
        $this->assertSame('test', $d->name);
        $this->assertTrue($initialized);
    }

    public function testDecorateObjectMapper()
    {
        $mapper = new ObjectMapper();
        $myMapper = new class($mapper) implements ObjectMapperInterface {
            public function __construct(private ObjectMapperInterface $mapper)
            {
                $this->mapper = $mapper->withObjectMapper($this);
            }

            public function map(object $source, object|string|null $target = null): object
            {
                $mapped = $this->mapper->map($source, $target);

                if ($source instanceof C) {
                    $mapped->baz = 'got decorated';
                }

                return $mapped;
            }
        };