Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
BraceBalanceValidator
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
2 / 2
6
100.00% covered (success)
100.00%
1 / 1
 getIssues
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
5
 getBalance
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\Validation\Validators;
5
6use MediaWiki\Extension\Translate\MessageLoading\Message;
7use MediaWiki\Extension\Translate\Validation\MessageValidator;
8use MediaWiki\Extension\Translate\Validation\ValidationIssue;
9use MediaWiki\Extension\Translate\Validation\ValidationIssues;
10
11/**
12 * Handles brace balance validation
13 * @author Abijeet Patro
14 * @license GPL-2.0-or-later
15 * @since 2019.06
16 */
17class BraceBalanceValidator implements MessageValidator {
18    public function getIssues( Message $message, string $targetLanguage ): ValidationIssues {
19        $definition = $message->definition();
20        $translation = $message->translation();
21        $balanceIssues = [];
22        $braceTypes = [
23            [ '{', '}' ],
24            [ '[', ']' ],
25            [ '(', ')' ],
26        ];
27
28        foreach ( $braceTypes as [ $open, $close ] ) {
29            $definitionBalance = $this->getBalance( $definition, $open, $close );
30            $translationBalance = $this->getBalance( $translation, $open, $close );
31
32            if ( $definitionBalance === 0 && $translationBalance !== 0 ) {
33                $balanceIssues[] = "$open$close$translationBalance";
34            }
35        }
36
37        $issues = new ValidationIssues();
38        if ( $balanceIssues ) {
39            $params = [
40                [ 'PARAMS', $balanceIssues ],
41                [ 'COUNT', count( $balanceIssues ) ],
42            ];
43
44            // Create an issue if braces are unbalanced in translation, but balanced in the definition
45            $issue = new ValidationIssue( 'balance', 'brace', 'translate-checks-balance', $params );
46            $issues->add( $issue );
47        }
48
49        return $issues;
50    }
51
52    private function getBalance( string $source, string $str1, string $str2 ): int {
53        return substr_count( $source, $str1 ) - substr_count( $source, $str2 );
54    }
55}