131 lines
4.6 KiB
PHP
Executable File
131 lines
4.6 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
namespace Magento\Test\Integrity\Phrase;
|
|
|
|
use Magento\Framework\Component\ComponentRegistrar;
|
|
|
|
/**
|
|
* Scan source code for detects invocations of __() function or Phrase object, analyzes placeholders with arguments
|
|
* and see if they not equal
|
|
*/
|
|
class ArgumentsTest extends \Magento\Test\Integrity\Phrase\AbstractTestCase
|
|
{
|
|
/**
|
|
* @var \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer\PhraseCollector
|
|
*/
|
|
protected $_phraseCollector;
|
|
|
|
/**
|
|
* List of files that must be omitted
|
|
*
|
|
* @todo remove blacklist related logic when all files correspond to the standard
|
|
* @var array
|
|
*/
|
|
protected $blackList;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->_phraseCollector = new \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer\PhraseCollector(
|
|
new \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer(),
|
|
true,
|
|
\Magento\Framework\Phrase::class
|
|
);
|
|
|
|
$componentRegistrar = new ComponentRegistrar();
|
|
$this->blackList = [
|
|
// the file below is the only file where strings are translated without corresponding arguments
|
|
$componentRegistrar->getPath(ComponentRegistrar::MODULE, 'Magento_Translation')
|
|
. '/Model/Js/DataProvider.php',
|
|
];
|
|
}
|
|
|
|
public function testArguments()
|
|
{
|
|
$incorrectNumberOfArgumentsErrors = [];
|
|
$missedPhraseErrors = [];
|
|
foreach ($this->_getFiles() as $file) {
|
|
if (in_array($file, $this->blackList)) {
|
|
continue;
|
|
}
|
|
$this->_phraseCollector->parse($file);
|
|
|
|
foreach ($this->_phraseCollector->getPhrases() as $phrase) {
|
|
$this->checkEmptyPhrases($phrase, $missedPhraseErrors);
|
|
$this->checkArgumentMismatch($phrase, $incorrectNumberOfArgumentsErrors);
|
|
}
|
|
}
|
|
$this->assertEmpty(
|
|
$missedPhraseErrors,
|
|
sprintf(
|
|
"\n%d missed phrases were discovered: \n%s",
|
|
count($missedPhraseErrors),
|
|
implode("\n\n", $missedPhraseErrors)
|
|
)
|
|
);
|
|
$this->assertEmpty(
|
|
$incorrectNumberOfArgumentsErrors,
|
|
sprintf(
|
|
"\n%d usages of inconsistency the number of arguments and placeholders were discovered: \n%s",
|
|
count($incorrectNumberOfArgumentsErrors),
|
|
implode("\n\n", $incorrectNumberOfArgumentsErrors)
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Will check if phrase is empty
|
|
*
|
|
* @param $phrase
|
|
* @param $missedPhraseErrors
|
|
*/
|
|
private function checkEmptyPhrases($phrase, &$missedPhraseErrors)
|
|
{
|
|
if (empty(trim($phrase['phrase'], "'\"\t\n\r\0\x0B"))) {
|
|
$missedPhraseErrors[] = $this->_createMissedPhraseError($phrase);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Will check if the number of arguments does not match the number of placeholders
|
|
*
|
|
* @param $phrase
|
|
* @param $incorrectNumberOfArgumentsErrors
|
|
*/
|
|
private function checkArgumentMismatch($phrase, &$incorrectNumberOfArgumentsErrors)
|
|
{
|
|
if (preg_match_all('/%(\w+)/', $phrase['phrase'], $matches) || $phrase['arguments']) {
|
|
$placeholderCount = count(array_unique($matches[1]));
|
|
// count all occurrences of sprintf placeholders
|
|
preg_match_all('/%\b([sducoxXbgGeEfF])\b/', $phrase['phrase'], $sprintfMatches);
|
|
if (count($sprintfMatches[0]) > count(array_unique($sprintfMatches[0]))) {
|
|
$placeholderCount = $placeholderCount +
|
|
count($sprintfMatches[0]) - count(array_unique($sprintfMatches[0]));
|
|
}
|
|
|
|
// Check for zend placeholders %placeholder% and sprintf placeholders and remove from the count
|
|
if (preg_match_all(
|
|
'/%\b(([sducoxXbgGeEfF])\b|([A-Za-z]+)%)/',
|
|
$phrase['phrase'],
|
|
$placeHolders,
|
|
PREG_OFFSET_CAPTURE
|
|
)) {
|
|
foreach ($placeHolders[0] as $ph) {
|
|
// Check if char after placeholder is not a digit or letter
|
|
$charAfterPh = $phrase['phrase'][$ph[1] + strlen($ph[0])];
|
|
if (!preg_match('/[A-Za-z0-9]/', $charAfterPh)) {
|
|
$placeholderCount--;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($placeholderCount != $phrase['arguments']) {
|
|
$incorrectNumberOfArgumentsErrors[] = $this->_createPhraseError($phrase);
|
|
}
|
|
}
|
|
}
|
|
}
|