Repository: symfony/symfony
File: src/Symfony/Component/Validator/Tests/Constraints/YamlValidatorTest.php (PHP)

Code before:
        $this->buildViolation('This value is not valid YAML.')
            ->setParameter('{{ error }}', 'Tags support is not enabled. Enable the "Yaml::PARSE_CUSTOM_TAGS" flag to use "!tagged" at line 1 (near "tags: [!tagged app.myclass]").')
            ->setParameter('{{ line }}', 1)
            ->setCode(Yaml::INVALID_YAML_ERROR)
            ->assertRaised();
    }

    /**
     * @dataProvider getDeprecationOnLinesData
     */
    public function testDeprecationTriggersParseException(int $yamlLine, string $yamlValue)
    {
        $parser = $this->createMock(Parser::class);
        $parser->method('getRealCurrentLineNb')->willReturn($yamlLine - 1);
        $parser->expects($this->once())
            ->method('parse')
            ->willReturnCallback(function () {
                @trigger_error('This is a simulated deprecation', \E_USER_DEPRECATED);
            });

        $validator = new class($parser) extends YamlValidator {
            public function __construct(private Parser $parser)
            {
            }

            protected function getParser(): Parser
            {
                return $this->parser;
            }
        };

        $validator->initialize($this->context);

        $constraint = new Yaml(
            message: 'myMessageTest',
        );

        $validator->validate($yamlValue, $constraint);

        $this->buildViolation('myMessageTest')
            ->setParameter('{{ error }}', 'This is a simulated deprecation at line '.$yamlLine)
            ->setParameter('{{ line }}', $yamlLine)
            ->setCode(Yaml::INVALID_YAML_ERROR)
            ->assertRaised();
    }

    public static function getValidValues()
    {
        return [
            ['planet_diameters: {earth: 12742, mars: 6779, saturn: 116460, mercury: 4879}'],
            ["key:\n  value"],

Review comment (suggestion):
instead of introducing a `getParser` protected method in the constraint validator just for testing purpose (but which will then have to be covered by BC as it is not even internal), I would prefer to trigger a deprecation during an actual parsing to allowing keeping the parser fully local to the validator.
The lazy way would be to rely on one of the deprecations of the Yaml parser itself. But this won't be future-proof as those deprecations will become errors in 8.0. However, I have an idea that should work (I haven't tested it to confirm it):

1. Create a fixture object in the testsuite that triggers a deprecation in its `__unserialize` method
2. Create a Yaml string using `!php/object` with this object
3. Run the validator with a constraint providing the `Yaml::PARSE_OBJECT` flag

Code after:
            ->setParameter('{{ error }}', 'Tags support is not enabled. Enable the "Yaml::PARSE_CUSTOM_TAGS" flag to use "!tagged" at line 1 (near "tags: [!tagged app.myclass]").')
            ->setParameter('{{ line }}', 1)
            ->setCode(Yaml::INVALID_YAML_ERROR)
            ->assertRaised();
    }

    /**
     * @dataProvider getDeprecationOnLinesData
     */
    public function testDeprecationTriggersParseException(int $yamlLine, string $yamlValue)
    {
        $lines = explode("\n", $yamlValue);
        $errorLine = end($lines);
        $expectedError = 'This is a simulated deprecation at line '.$yamlLine.' (near "'.$errorLine.'")';

        $constraint = new Yaml(
            message: 'myMessageTest',
            flags: YamlParser::PARSE_OBJECT,
        );
        $this->validator->validate($yamlValue, $constraint);
        $this->buildViolation('myMessageTest')
            ->setParameter('{{ error }}', $expectedError)
            ->setParameter('{{ line }}', $yamlLine)
            ->setCode(Yaml::INVALID_YAML_ERROR)
            ->assertRaised();
    }

    public static function getValidValues()
    {
        return [
            ['planet_diameters: {earth: 12742, mars: 6779, saturn: 116460, mercury: 4879}'],
            ["key:\n  value"],
            [null],
            [''],
            ['"null"'],
            ['null'],
            ['"string"'],
            ['1'],
            ['true'],
            [1],
        ];
    }

    public static function getInvalidValues(): array
    {
        return [
            ['{:INVALID]', 'Malformed unquoted YAML string at line 1 (near "{:INVALID]").', 1],
            ["key:\nvalue", 'Unable to parse at line 2 (near "value").', 2],
        ];
    }