TranslationFilesTest.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Test\Integrity\App\Language;
  7. use Magento\Framework\App\Utility\Files;
  8. use Magento\Framework\Component\ComponentRegistrar;
  9. use Magento\Setup\Module\I18n\Dictionary\Options\ResolverFactory;
  10. use Magento\Setup\Module\I18n\Locale;
  11. use Magento\Setup\Module\I18n\Pack\Writer\File\Csv;
  12. /**
  13. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  14. */
  15. class TranslationFilesTest extends TranslationFiles
  16. {
  17. /**
  18. * Context
  19. *
  20. * @var \Magento\Setup\Module\I18n\Context
  21. */
  22. protected $context;
  23. /**
  24. * Test default locale
  25. *
  26. * Check that all translation phrases in code are present in the locale files
  27. *
  28. * @param string $file
  29. * @param array $phrases
  30. *
  31. * @dataProvider defaultLocaleDataProvider
  32. */
  33. public function testDefaultLocale($file, $phrases)
  34. {
  35. $this->markTestSkipped('MAGETWO-26083');
  36. $failures = $this->comparePhrase($phrases, $this->csvParser->getDataPairs($file));
  37. $this->assertEmpty(
  38. $failures,
  39. $this->printMessage([$file => $failures])
  40. );
  41. }
  42. /**
  43. * @return array
  44. * @throws \RuntimeException
  45. */
  46. public function defaultLocaleDataProvider()
  47. {
  48. $parser = $this->prepareParser();
  49. $optionResolverFactory = new ResolverFactory();
  50. $optionResolver = $optionResolverFactory->create(BP, true);
  51. $parser->parse($optionResolver->getOptions());
  52. $defaultLocale = [];
  53. foreach ($parser->getPhrases() as $key => $phrase) {
  54. if (!$phrase->getContextType() || !$phrase->getContextValue()) {
  55. throw new \RuntimeException(sprintf('Missed context in row #%d.', $key + 1));
  56. }
  57. foreach ($phrase->getContextValue() as $context) {
  58. $phraseText = $this->eliminateSpecialChars($phrase->getPhrase());
  59. $phraseTranslation = $this->eliminateSpecialChars($phrase->getTranslation());
  60. $file = $this->buildFilePath($phrase, $context);
  61. $defaultLocale[$file]['file'] = $file;
  62. $defaultLocale[$file]['phrases'][$phraseText] = $phraseTranslation;
  63. }
  64. }
  65. return $defaultLocale;
  66. }
  67. /**
  68. * @param \Magento\Setup\Module\I18n\Dictionary\Phrase $phrase
  69. * @param array $context
  70. * @return string
  71. */
  72. protected function buildFilePath($phrase, $context)
  73. {
  74. $path = $this->getContext()->buildPathToLocaleDirectoryByContext($phrase->getContextType(), $context);
  75. return $path . Locale::DEFAULT_SYSTEM_LOCALE . '.' . Csv::FILE_EXTENSION;
  76. }
  77. /**
  78. * @return \Magento\Setup\Module\I18n\Context
  79. */
  80. protected function getContext()
  81. {
  82. if ($this->context === null) {
  83. $this->context = new \Magento\Setup\Module\I18n\Context(new ComponentRegistrar());
  84. }
  85. return $this->context;
  86. }
  87. /**
  88. * @return \Magento\Setup\Module\I18n\Parser\Contextual
  89. */
  90. protected function prepareParser()
  91. {
  92. $filesCollector = new \Magento\Setup\Module\I18n\FilesCollector();
  93. $phraseCollector = new \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer\PhraseCollector(
  94. new \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer()
  95. );
  96. $adapters = [
  97. 'php' => new \Magento\Setup\Module\I18n\Parser\Adapter\Php($phraseCollector),
  98. 'js' => new \Magento\Setup\Module\I18n\Parser\Adapter\Js(),
  99. 'xml' => new \Magento\Setup\Module\I18n\Parser\Adapter\Xml(),
  100. 'html' => new \Magento\Setup\Module\I18n\Parser\Adapter\Html(),
  101. ];
  102. $parserContextual = new \Magento\Setup\Module\I18n\Parser\Contextual(
  103. $filesCollector,
  104. new \Magento\Setup\Module\I18n\Factory(),
  105. new \Magento\Setup\Module\I18n\Context(new ComponentRegistrar())
  106. );
  107. foreach ($adapters as $type => $adapter) {
  108. $parserContextual->addAdapter($type, $adapter);
  109. }
  110. return $parserContextual;
  111. }
  112. /**
  113. * @param string $text
  114. * @return string
  115. */
  116. protected function eliminateSpecialChars($text)
  117. {
  118. return preg_replace(['/\\\\\'/', '/\\\\\\\\/'], ['\'', '\\'], $text);
  119. }
  120. /**
  121. * Test placeholders in translations.
  122. * Compares count numeric placeholders in keys and translates.
  123. *
  124. * @param string $placePath
  125. * @dataProvider getLocalePlacePath
  126. */
  127. public function testPhrasePlaceHolders($placePath)
  128. {
  129. $this->markTestSkipped('MAGETWO-26083');
  130. $files = $this->getCsvFiles($placePath);
  131. $failures = [];
  132. foreach ($files as $locale => $file) {
  133. $fileData = $this->csvParser->getDataPairs($file);
  134. foreach ($fileData as $key => $translate) {
  135. preg_match_all('/%(\d+)/', $key, $keyMatches);
  136. preg_match_all('/%(\d+)/', $translate, $translateMatches);
  137. if (count(array_unique($keyMatches[1])) != count(array_unique($translateMatches[1]))) {
  138. $failures[$locale][$key][] = $translate;
  139. }
  140. }
  141. }
  142. $this->assertEmpty(
  143. $failures,
  144. $this->printMessage(
  145. $failures,
  146. 'Found discrepancy between keys and translations in count of numeric placeholders'
  147. )
  148. );
  149. }
  150. }