Solution: 3

PHPUnit 10.2.2 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.14
Configuration: phpunit.xml

.....                                                               5 / 5 (100%)

Time: 00:00.002, Memory: 24.41 MB

Measurements
 ✔ Centimeters can be converted to int
 ✔ Centimeters can be converted to meters
 ✔ Centimeters cannot be negative
 ✔ Meters can be converted to float
 ✔ Meters cannot be negative

OK (5 tests, 5 assertions)
Output of phpunit --testdox
Execute phpunit --testdox

The conversion to meter is actually nothing else than the conversion to an integer, but of course with meter as return type. So we can write a corresponding test:

#[Test]
public function centimeters_can_be_converted_to_meters(): void
{
    $centimeters = 123;
    $measure = new Centimeter($centimeters);

    $this->assertEquals(new Meter(1.23), $measure->asMeter());
}
MeasurementsTest.php

This is quickly implemented:

public function asMeter(): Meter
{
    return new Meter($this->centimeters / 100);
}
Centimeter.php

The solution at a glance:

<?php declare(strict_types=1);

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

#[CoversClass(Meter::class)]
#[CoversClass(Centimeter::class)]
class MeasurementsTest extends TestCase
{
    #[Test]
    public function centimeters_can_be_converted_to_int(): void
    {
        $centimeters = 23;
        $measure = new Centimeter($centimeters);

        $this->assertEquals($centimeters, $measure->asInt());
    }

    #[Test]
    public function centimeters_can_be_converted_to_meters(): void
    {
        $centimeters = 123;
        $measure = new Centimeter($centimeters);

        $this->assertEquals(new Meter(1.23), $measure->asMeter());
    }

    #[Test]
    public function centimeters_cannot_be_negative(): void
    {
        $this->expectException(RuntimeException::class);

        new Centimeter(-1);
    }

    #[Test]
    public function meters_can_be_converted_to_float(): void
    {
        $meters = 1.5;
        $measure = new Meter($meters);

        $this->assertEquals($meters, $measure->asFloat());
    }

    #[Test]
    public function meters_cannot_be_negative(): void
    {
        $this->expectException(RuntimeException::class);

        new Meter(-1);
    }
}
MeasurementsTest.php
<?php declare(strict_types=1);

class Centimeter
{
    private readonly int $centimeters;

    public function __construct(int $centimeters)
    {
        $this->ensureNotNegative($centimeters);

        $this->centimeters = $centimeters;
    }

    public function asInt(): int
    {
        return $this->centimeters;
    }

    public function asMeter(): Meter
    {
        return new Meter($this->centimeters / 100);
    }

    private function ensureNotNegative(int $centimeters): void
    {
        if ($centimeters < 0) {
            throw new RuntimeException('Measure cannot be negative');
        }
    }
}
Centimeter.php
<?php declare(strict_types=1);

class Meter
{
    private readonly float $meters;

    public function __construct(float $meters)
    {
        $this->ensureNotNegative($meters);

        $this->meters = $meters;
    }

    public function asFloat(): float
    {
        return $this->meters;
    }

    private function ensureNotNegative(float $meters): void
    {
        if ($meters < 0) {
            throw new RuntimeException('Measure cannot be negative');
        }
    }
}
Meter.php