annotate core/modules/locale/tests/src/Unit/LocaleLookupTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\locale\Unit;
Chris@0 4
Chris@18 5 use Drupal\Component\Gettext\PoItem;
Chris@0 6 use Drupal\Core\DependencyInjection\ContainerBuilder;
Chris@0 7 use Drupal\locale\LocaleLookup;
Chris@0 8 use Drupal\Tests\UnitTestCase;
Chris@0 9 use Symfony\Component\HttpFoundation\Request;
Chris@0 10 use Symfony\Component\HttpFoundation\RequestStack;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * @coversDefaultClass \Drupal\locale\LocaleLookup
Chris@0 14 * @group locale
Chris@0 15 */
Chris@0 16 class LocaleLookupTest extends UnitTestCase {
Chris@0 17
Chris@0 18 /**
Chris@0 19 * A mocked storage to use when instantiating LocaleTranslation objects.
Chris@0 20 *
Chris@0 21 * @var \Drupal\locale\StringStorageInterface|\PHPUnit_Framework_MockObject_MockObject
Chris@0 22 */
Chris@0 23 protected $storage;
Chris@0 24
Chris@0 25 /**
Chris@0 26 * A mocked cache object.
Chris@0 27 *
Chris@0 28 * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
Chris@0 29 */
Chris@0 30 protected $cache;
Chris@0 31
Chris@0 32 /**
Chris@0 33 * A mocked lock object.
Chris@0 34 *
Chris@0 35 * @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
Chris@0 36 */
Chris@0 37 protected $lock;
Chris@0 38
Chris@0 39 /**
Chris@0 40 * A mocked user object built from AccountInterface.
Chris@0 41 *
Chris@0 42 * @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
Chris@0 43 */
Chris@0 44 protected $user;
Chris@0 45
Chris@0 46 /**
Chris@0 47 * A mocked config factory built with UnitTestCase::getConfigFactoryStub().
Chris@0 48 *
Chris@0 49 * @var \Drupal\Core\Config\ConfigFactory|\PHPUnit_Framework_MockObject_MockBuilder
Chris@0 50 */
Chris@0 51 protected $configFactory;
Chris@0 52
Chris@0 53 /**
Chris@0 54 * A mocked language manager built from LanguageManagerInterface.
Chris@0 55 *
Chris@0 56 * @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit_Framework_MockObject_MockObject
Chris@0 57 */
Chris@0 58 protected $languageManager;
Chris@0 59
Chris@0 60 /**
Chris@0 61 * The request stack.
Chris@0 62 *
Chris@0 63 * @var \Symfony\Component\HttpFoundation\RequestStack
Chris@0 64 */
Chris@0 65 protected $requestStack;
Chris@0 66
Chris@0 67 /**
Chris@0 68 * {@inheritdoc}
Chris@0 69 */
Chris@0 70 protected function setUp() {
Chris@0 71 $this->storage = $this->getMock('Drupal\locale\StringStorageInterface');
Chris@0 72 $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
Chris@0 73 $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
Chris@0 74 $this->lock->expects($this->never())
Chris@0 75 ->method($this->anything());
Chris@0 76
Chris@0 77 $this->user = $this->getMock('Drupal\Core\Session\AccountInterface');
Chris@0 78 $this->user->expects($this->any())
Chris@0 79 ->method('getRoles')
Chris@0 80 ->will($this->returnValue(['anonymous']));
Chris@0 81
Chris@0 82 $this->configFactory = $this->getConfigFactoryStub(['locale.settings' => ['cache_strings' => FALSE]]);
Chris@0 83
Chris@0 84 $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
Chris@0 85 $this->requestStack = new RequestStack();
Chris@0 86
Chris@0 87 $container = new ContainerBuilder();
Chris@0 88 $container->set('current_user', $this->user);
Chris@0 89 \Drupal::setContainer($container);
Chris@0 90 }
Chris@0 91
Chris@0 92 /**
Chris@0 93 * Tests locale lookups without fallback.
Chris@0 94 *
Chris@0 95 * @covers ::resolveCacheMiss
Chris@0 96 */
Chris@0 97 public function testResolveCacheMissWithoutFallback() {
Chris@0 98 $args = [
Chris@0 99 'language' => 'en',
Chris@0 100 'source' => 'test',
Chris@0 101 'context' => 'irrelevant',
Chris@0 102 ];
Chris@0 103
Chris@0 104 $result = (object) [
Chris@0 105 'translation' => 'test',
Chris@0 106 ];
Chris@0 107
Chris@0 108 $this->cache->expects($this->once())
Chris@0 109 ->method('get')
Chris@0 110 ->with('locale:en:irrelevant:anonymous', FALSE);
Chris@0 111
Chris@0 112 $this->storage->expects($this->once())
Chris@0 113 ->method('findTranslation')
Chris@0 114 ->with($this->equalTo($args))
Chris@0 115 ->will($this->returnValue($result));
Chris@0 116
Chris@0 117 $locale_lookup = $this->getMockBuilder('Drupal\locale\LocaleLookup')
Chris@0 118 ->setConstructorArgs(['en', 'irrelevant', $this->storage, $this->cache, $this->lock, $this->configFactory, $this->languageManager, $this->requestStack])
Chris@0 119 ->setMethods(['persist'])
Chris@0 120 ->getMock();
Chris@0 121 $locale_lookup->expects($this->never())
Chris@0 122 ->method('persist');
Chris@0 123 $this->assertSame('test', $locale_lookup->get('test'));
Chris@0 124 }
Chris@0 125
Chris@0 126 /**
Chris@0 127 * Tests locale lookups with fallback.
Chris@0 128 *
Chris@0 129 * Note that context is irrelevant here. It is not used but it is required.
Chris@0 130 *
Chris@0 131 * @covers ::resolveCacheMiss
Chris@0 132 *
Chris@0 133 * @dataProvider resolveCacheMissWithFallbackProvider
Chris@0 134 */
Chris@0 135 public function testResolveCacheMissWithFallback($langcode, $string, $context, $expected) {
Chris@0 136 // These are fake words!
Chris@0 137 $translations = [
Chris@0 138 'en' => [
Chris@0 139 'test' => 'test',
Chris@0 140 'fake' => 'fake',
Chris@0 141 'missing pl' => 'missing pl',
Chris@0 142 'missing cs' => 'missing cs',
Chris@0 143 'missing both' => 'missing both',
Chris@0 144 ],
Chris@0 145 'pl' => [
Chris@0 146 'test' => 'test po polsku',
Chris@0 147 'fake' => 'ściema',
Chris@0 148 'missing cs' => 'zaginiony czech',
Chris@0 149 ],
Chris@0 150 'cs' => [
Chris@0 151 'test' => 'test v české',
Chris@0 152 'fake' => 'falešný',
Chris@0 153 'missing pl' => 'chybějící pl',
Chris@0 154 ],
Chris@0 155 ];
Chris@0 156 $this->storage->expects($this->any())
Chris@0 157 ->method('findTranslation')
Chris@0 158 ->will($this->returnCallback(function ($argument) use ($translations) {
Chris@0 159 if (isset($translations[$argument['language']][$argument['source']])) {
Chris@0 160 return (object) ['translation' => $translations[$argument['language']][$argument['source']]];
Chris@0 161 }
Chris@0 162 return TRUE;
Chris@0 163 }));
Chris@0 164
Chris@0 165 $this->languageManager->expects($this->any())
Chris@0 166 ->method('getFallbackCandidates')
Chris@0 167 ->will($this->returnCallback(function (array $context = []) {
Chris@0 168 switch ($context['langcode']) {
Chris@0 169 case 'pl':
Chris@0 170 return ['cs', 'en'];
Chris@0 171
Chris@0 172 case 'cs':
Chris@0 173 return ['en'];
Chris@0 174
Chris@0 175 default:
Chris@0 176 return [];
Chris@0 177 }
Chris@0 178 }));
Chris@0 179
Chris@0 180 $this->cache->expects($this->once())
Chris@0 181 ->method('get')
Chris@0 182 ->with('locale:' . $langcode . ':' . $context . ':anonymous', FALSE);
Chris@0 183
Chris@0 184 $locale_lookup = new LocaleLookup($langcode, $context, $this->storage, $this->cache, $this->lock, $this->configFactory, $this->languageManager, $this->requestStack);
Chris@0 185 $this->assertSame($expected, $locale_lookup->get($string));
Chris@0 186 }
Chris@0 187
Chris@0 188 /**
Chris@0 189 * Provides test data for testResolveCacheMissWithFallback().
Chris@0 190 */
Chris@0 191 public function resolveCacheMissWithFallbackProvider() {
Chris@0 192 return [
Chris@0 193 ['cs', 'test', 'irrelevant', 'test v české'],
Chris@0 194 ['cs', 'fake', 'irrelevant', 'falešný'],
Chris@0 195 ['cs', 'missing pl', 'irrelevant', 'chybějící pl'],
Chris@0 196 ['cs', 'missing cs', 'irrelevant', 'missing cs'],
Chris@0 197 ['cs', 'missing both', 'irrelevant', 'missing both'],
Chris@0 198
Chris@0 199 // Testing PL with fallback to cs, en.
Chris@0 200 ['pl', 'test', 'irrelevant', 'test po polsku'],
Chris@0 201 ['pl', 'fake', 'irrelevant', 'ściema'],
Chris@0 202 ['pl', 'missing pl', 'irrelevant', 'chybějící pl'],
Chris@0 203 ['pl', 'missing cs', 'irrelevant', 'zaginiony czech'],
Chris@0 204 ['pl', 'missing both', 'irrelevant', 'missing both'],
Chris@0 205 ];
Chris@0 206 }
Chris@0 207
Chris@0 208 /**
Chris@0 209 * Tests locale lookups with persistent tracking.
Chris@0 210 *
Chris@0 211 * @covers ::resolveCacheMiss
Chris@0 212 */
Chris@0 213 public function testResolveCacheMissWithPersist() {
Chris@0 214 $args = [
Chris@0 215 'language' => 'en',
Chris@0 216 'source' => 'test',
Chris@0 217 'context' => 'irrelevant',
Chris@0 218 ];
Chris@0 219
Chris@0 220 $result = (object) [
Chris@0 221 'translation' => 'test',
Chris@0 222 ];
Chris@0 223
Chris@0 224 $this->storage->expects($this->once())
Chris@0 225 ->method('findTranslation')
Chris@0 226 ->with($this->equalTo($args))
Chris@0 227 ->will($this->returnValue($result));
Chris@0 228
Chris@0 229 $this->configFactory = $this->getConfigFactoryStub(['locale.settings' => ['cache_strings' => TRUE]]);
Chris@0 230 $locale_lookup = $this->getMockBuilder('Drupal\locale\LocaleLookup')
Chris@0 231 ->setConstructorArgs(['en', 'irrelevant', $this->storage, $this->cache, $this->lock, $this->configFactory, $this->languageManager, $this->requestStack])
Chris@0 232 ->setMethods(['persist'])
Chris@0 233 ->getMock();
Chris@0 234 $locale_lookup->expects($this->once())
Chris@0 235 ->method('persist');
Chris@0 236
Chris@0 237 $this->assertSame('test', $locale_lookup->get('test'));
Chris@0 238 }
Chris@0 239
Chris@0 240 /**
Chris@0 241 * Tests locale lookups without a found translation.
Chris@0 242 *
Chris@0 243 * @covers ::resolveCacheMiss
Chris@0 244 */
Chris@0 245 public function testResolveCacheMissNoTranslation() {
Chris@0 246 $string = $this->getMock('Drupal\locale\StringInterface');
Chris@0 247 $string->expects($this->once())
Chris@0 248 ->method('addLocation')
Chris@0 249 ->will($this->returnSelf());
Chris@0 250 $this->storage->expects($this->once())
Chris@0 251 ->method('findTranslation')
Chris@0 252 ->will($this->returnValue(NULL));
Chris@0 253 $this->storage->expects($this->once())
Chris@0 254 ->method('createString')
Chris@0 255 ->will($this->returnValue($string));
Chris@0 256
Chris@0 257 $request = Request::create('/test');
Chris@0 258 $this->requestStack->push($request);
Chris@0 259
Chris@0 260 $locale_lookup = $this->getMockBuilder('Drupal\locale\LocaleLookup')
Chris@0 261 ->setConstructorArgs(['en', 'irrelevant', $this->storage, $this->cache, $this->lock, $this->configFactory, $this->languageManager, $this->requestStack])
Chris@0 262 ->setMethods(['persist'])
Chris@0 263 ->getMock();
Chris@0 264 $locale_lookup->expects($this->never())
Chris@0 265 ->method('persist');
Chris@0 266
Chris@0 267 $this->assertTrue($locale_lookup->get('test'));
Chris@0 268 }
Chris@0 269
Chris@12 270 /**
Chris@12 271 * Tests locale lookups with old plural style of translations.
Chris@12 272 *
Chris@12 273 * @param array $translations
Chris@12 274 * The source with translations.
Chris@12 275 * @param string $langcode
Chris@12 276 * The language code of translation string.
Chris@12 277 * @param string $string
Chris@12 278 * The string for translation.
Chris@12 279 * @param bool $is_fix
Chris@12 280 * The flag about expected fix translation.
Chris@12 281 *
Chris@12 282 * @covers ::resolveCacheMiss
Chris@12 283 * @dataProvider providerFixOldPluralTranslationProvider
Chris@12 284 */
Chris@12 285 public function testFixOldPluralStyleTranslations($translations, $langcode, $string, $is_fix) {
Chris@12 286 $this->storage->expects($this->any())
Chris@12 287 ->method('findTranslation')
Chris@12 288 ->will($this->returnCallback(function ($argument) use ($translations) {
Chris@12 289 if (isset($translations[$argument['language']][$argument['source']])) {
Chris@12 290 return (object) ['translation' => $translations[$argument['language']][$argument['source']]];
Chris@12 291 }
Chris@12 292 return TRUE;
Chris@12 293 }));
Chris@12 294 $this->languageManager->expects($this->any())
Chris@12 295 ->method('getFallbackCandidates')
Chris@12 296 ->will($this->returnCallback(function (array $context = []) {
Chris@12 297 switch ($context['langcode']) {
Chris@12 298 case 'by':
Chris@12 299 return ['ru'];
Chris@12 300 }
Chris@12 301 }));
Chris@12 302 $this->cache->expects($this->once())
Chris@12 303 ->method('get')
Chris@12 304 ->with('locale:' . $langcode . '::anonymous', FALSE);
Chris@12 305
Chris@12 306 $locale_lookup = new LocaleLookup($langcode, '', $this->storage, $this->cache, $this->lock, $this->configFactory, $this->languageManager, $this->requestStack);
Chris@12 307 $this->assertSame($is_fix, strpos($locale_lookup->get($string), '@count[2]') === FALSE);
Chris@12 308 }
Chris@12 309
Chris@12 310 /**
Chris@12 311 * Provides test data for testResolveCacheMissWithFallback().
Chris@12 312 */
Chris@12 313 public function providerFixOldPluralTranslationProvider() {
Chris@12 314 $translations = [
Chris@12 315 'by' => [
Chris@12 316 'word1' => '@count[2] word-by',
Chris@18 317 'word2' => implode(PoItem::DELIMITER, ['word-by', '@count[2] word-by']),
Chris@12 318 ],
Chris@12 319 'ru' => [
Chris@12 320 'word3' => '@count[2] word-ru',
Chris@18 321 'word4' => implode(PoItem::DELIMITER, ['word-ru', '@count[2] word-ru']),
Chris@12 322 ],
Chris@12 323 ];
Chris@12 324 return [
Chris@12 325 'no-plural' => [$translations, 'by', 'word1', FALSE],
Chris@12 326 'no-plural from other language' => [$translations, 'by', 'word3', FALSE],
Chris@12 327 'plural' => [$translations, 'by', 'word2', TRUE],
Chris@12 328 'plural from other language' => [$translations, 'by', 'word4', TRUE],
Chris@12 329 ];
Chris@12 330 }
Chris@12 331
Chris@0 332 }