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

Code before:
        $source = new ReadOnlyPromotedPropertyA(
            b: new ReadOnlyPromotedPropertyB(
                var2: 'bar',
            ),
            var1: 'foo',
        );

        $mapper = new ObjectMapper();
        $out = $mapper->map($source);

        $this->assertInstanceOf(ReadOnlyPromotedPropertyAMapped::class, $out);
        $this->assertInstanceOf(ReadOnlyPromotedPropertyBMapped::class, $out->b);
        $this->assertSame('foo', $out->var1);
        $this->assertSame('bar', $out->b->var2);
    }

    public function testClassMap()
    {
        $classMap = [
            Cost::class => CostRequestView::class,
            Quote::class => QuoteRequestView::class,
        ];

        $quote = new Quote(id: 'foo', cost: new Cost(amount: 10, tax: 20));

        $mapper = new ObjectMapper(metadataFactory: new ReverseClassObjectMapperMetadataFactory(new ReflectionObjectMapperMetadataFactory(), $classMap));

        $quoteRequestView = $mapper->map($quote);

        $this->assertInstanceOf(QuoteRequestView::class, $quoteRequestView);
        $this->assertInstanceOf(CostRequestView::class, $quoteRequestView->cost);
        $this->assertEquals(10, $quoteRequestView->cost->amount);
        $this->assertEquals(20, $quoteRequestView->cost->tax);
    }

    public function testClassMapWithSourceAttribute()
    {
        $classMap = [
            Cost::class => CostRequestView::class,
        ];

        $cost = new Cost(amount: 10, tax: 20, bar: 'bar');

        $mapper = new ObjectMapper(metadataFactory: new ReverseClassObjectMapperMetadataFactory(new ReflectionObjectMapperMetadataFactory(), $classMap));

        $costRequestView = $mapper->map($cost);

        $this->assertInstanceOf(CostRequestView::class, $costRequestView);
        $this->assertEquals('bar', $costRequestView->foo);
    }
}

Review comment (suggestion):
this should rather use the public API (parameter names are not part of it) as this gives a chance to notice unintended BC breaks in case we have to edit tests to keep them working.

Code after:
    {
        $source = new ReadOnlyPromotedPropertyA(
            b: new ReadOnlyPromotedPropertyB(
                var2: 'bar',
            ),
            var1: 'foo',
        );

        $mapper = new ObjectMapper();
        $out = $mapper->map($source);

        $this->assertInstanceOf(ReadOnlyPromotedPropertyAMapped::class, $out);
        $this->assertInstanceOf(ReadOnlyPromotedPropertyBMapped::class, $out->b);
        $this->assertSame('foo', $out->var1);
        $this->assertSame('bar', $out->b->var2);
    }

    public function testClassMap()
    {
        $classMap = [
            Quote::class => QuoteRequestView::class,
            Cost::class => CostRequestView::class,
        ];

        $quote = new Quote('foo', new Cost(10, 20));

        $mapper = new ObjectMapper(new ReverseClassObjectMapperMetadataFactory(new ReflectionObjectMapperMetadataFactory(), $classMap));

        $quoteRequestView = $mapper->map($quote);

        $this->assertInstanceOf(QuoteRequestView::class, $quoteRequestView);
        $this->assertInstanceOf(CostRequestView::class, $quoteRequestView->cost);
        $this->assertEquals(10, $quoteRequestView->cost->amount);
        $this->assertEquals(20, $quoteRequestView->cost->tax);
    }

    public function testClassMapWithSourceAttribute()
    {
        $classMap = [
            Cost::class => CostRequestWithSourceView::class,
        ];

        $cost = new Cost(10, 20, 'bar');

        $mapper = new ObjectMapper(new ReverseClassObjectMapperMetadataFactory(new ReflectionObjectMapperMetadataFactory(), $classMap));

        $costRequestView = $mapper->map($cost);

        $this->assertInstanceOf(CostRequestWithSourceView::class, $costRequestView);
        $this->assertEquals('bar', $costRequestView->foo);
    }