annotate core/modules/system/src/Tests/Theme/TwigTransTest.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\system\Tests\Theme;
Chris@0 4
Chris@0 5 use Drupal\Core\Language\LanguageInterface;
Chris@0 6 use Drupal\simpletest\WebTestBase;
Chris@0 7
Chris@0 8 /**
Chris@0 9 * Tests Twig "trans" tags.
Chris@0 10 *
Chris@0 11 * @group Theme
Chris@0 12 */
Chris@0 13 class TwigTransTest extends WebTestBase {
Chris@0 14
Chris@0 15 /**
Chris@0 16 * Modules to enable.
Chris@0 17 *
Chris@0 18 * @var array
Chris@0 19 */
Chris@0 20 public static $modules = [
Chris@0 21 'theme_test',
Chris@0 22 'twig_theme_test',
Chris@0 23 'locale',
Chris@0 24 'language'
Chris@0 25 ];
Chris@0 26
Chris@0 27 /**
Chris@0 28 * An administrative user for testing.
Chris@0 29 *
Chris@0 30 * @var \Drupal\user\Entity\User
Chris@0 31 */
Chris@0 32 protected $adminUser;
Chris@0 33
Chris@0 34 /**
Chris@0 35 * Custom languages.
Chris@0 36 *
Chris@0 37 * @var array
Chris@0 38 */
Chris@0 39 protected $languages = [
Chris@0 40 'xx' => 'Lolspeak',
Chris@0 41 'zz' => 'Lolspeak2',
Chris@0 42 ];
Chris@0 43
Chris@0 44 /**
Chris@0 45 * {@inheritdoc}
Chris@0 46 */
Chris@0 47 protected function setUp() {
Chris@0 48 parent::setUp();
Chris@0 49
Chris@0 50 // Setup test_theme.
Chris@0 51 \Drupal::service('theme_handler')->install(['test_theme']);
Chris@0 52 $this->config('system.theme')->set('default', 'test_theme')->save();
Chris@0 53
Chris@0 54 // Create and log in as admin.
Chris@0 55 $this->adminUser = $this->drupalCreateUser([
Chris@0 56 'administer languages',
Chris@0 57 'access administration pages',
Chris@0 58 'administer site configuration',
Chris@0 59 'translate interface'
Chris@0 60 ]);
Chris@0 61 $this->drupalLogin($this->adminUser);
Chris@0 62
Chris@0 63 // Install languages.
Chris@0 64 $this->installLanguages();
Chris@0 65
Chris@0 66 // Assign Lolspeak (xx) to be the default language.
Chris@0 67 $this->config('system.site')->set('default_langcode', 'xx')->save();
Chris@0 68 $this->rebuildContainer();
Chris@0 69
Chris@0 70 // Check that lolspeak is the default language for the site.
Chris@0 71 $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage()->getId(), 'xx', 'Lolspeak is the default language');
Chris@0 72 }
Chris@0 73
Chris@0 74 /**
Chris@0 75 * Test Twig "trans" tags.
Chris@0 76 */
Chris@0 77 public function testTwigTransTags() {
Chris@0 78 // Run this once without and once with Twig debug because trans can work
Chris@0 79 // differently depending on that setting.
Chris@0 80 $this->drupalGet('twig-theme-test/trans', ['language' => \Drupal::languageManager()->getLanguage('xx')]);
Chris@0 81 $this->assertTwigTransTags();
Chris@0 82
Chris@0 83 // Enable debug, rebuild the service container, and clear all caches.
Chris@0 84 $parameters = $this->container->getParameter('twig.config');
Chris@0 85 $parameters['debug'] = TRUE;
Chris@0 86 $this->setContainerParameter('twig.config', $parameters);
Chris@0 87 $this->rebuildContainer();
Chris@0 88 $this->resetAll();
Chris@0 89
Chris@0 90 $this->drupalGet('twig-theme-test/trans', ['language' => \Drupal::languageManager()->getLanguage('xx')]);
Chris@0 91 $this->assertTwigTransTags();
Chris@0 92 }
Chris@0 93
Chris@0 94 /**
Chris@0 95 * Test empty Twig "trans" tags.
Chris@0 96 */
Chris@0 97 public function testEmptyTwigTransTags() {
Chris@0 98 $elements = [
Chris@0 99 '#type' => 'inline_template',
Chris@0 100 '#template' => '{% trans %}{% endtrans %}',
Chris@0 101 ];
Chris@0 102 /** @var \Drupal\Core\Render\RendererInterface $renderer */
Chris@0 103 $renderer = \Drupal::service('renderer');
Chris@0 104
Chris@0 105 try {
Chris@0 106 $renderer->renderPlain($elements);
Chris@0 107
Chris@0 108 $this->fail('{% trans %}{% endtrans %} did not throw an exception.');
Chris@0 109 }
Chris@0 110 catch (\Twig_Error_Syntax $e) {
Chris@0 111 $this->assertTrue(strstr($e->getMessage(), '{% trans %} tag cannot be empty'), '{% trans %}{% endtrans %} threw the expected exception.');
Chris@0 112 }
Chris@0 113 catch (\Exception $e) {
Chris@0 114 $this->fail('{% trans %}{% endtrans %} threw an unexpected exception.');
Chris@0 115 }
Chris@0 116 }
Chris@0 117
Chris@0 118 /**
Chris@0 119 * Asserts Twig trans tags.
Chris@0 120 */
Chris@0 121 protected function assertTwigTransTags() {
Chris@0 122 $this->assertText(
Chris@0 123 'OH HAI SUNZ',
Chris@0 124 '{% trans "Hello sun." %} was successfully translated.'
Chris@0 125 );
Chris@0 126
Chris@0 127 $this->assertText(
Chris@0 128 'O HAI SUNZZZZZZZ',
Chris@0 129 '{% trans "Hello sun." with {"context": "Lolspeak"} %} was successfully translated.'
Chris@0 130 );
Chris@0 131
Chris@0 132 $this->assertText(
Chris@0 133 'O HERRO ERRRF.',
Chris@0 134 '{{ "Hello Earth."|trans }} was successfully translated.'
Chris@0 135 );
Chris@0 136
Chris@0 137 $this->assertText(
Chris@0 138 'OH HAI TEH MUUN',
Chris@0 139 '{% trans %}Hello moon.{% endtrans %} was successfully translated.'
Chris@0 140 );
Chris@0 141
Chris@0 142 $this->assertText(
Chris@0 143 'O HAI STARRRRR',
Chris@0 144 '{% trans %} with {% plural count = 1 %} was successfully translated.'
Chris@0 145 );
Chris@0 146
Chris@0 147 $this->assertText(
Chris@0 148 'O HAI 2 STARZZZZ',
Chris@0 149 '{% trans %} with {% plural count = 2 %} was successfully translated.'
Chris@0 150 );
Chris@0 151
Chris@0 152 $this->assertRaw(
Chris@0 153 'ESCAPEE: &amp;&quot;&lt;&gt;',
Chris@0 154 '{{ token }} was successfully translated and prefixed with "@".'
Chris@0 155 );
Chris@0 156
Chris@0 157 $this->assertRaw(
Chris@0 158 'PLAYSHOLDR: <em class="placeholder">&amp;&quot;&lt;&gt;</em>',
Chris@0 159 '{{ token|placeholder }} was successfully translated and prefixed with "%".'
Chris@0 160 );
Chris@0 161
Chris@0 162 $this->assertRaw(
Chris@0 163 'DIS complex token HAZ LENGTH OV: 3. IT CONTAYNZ: <em class="placeholder">12345</em> AN &amp;&quot;&lt;&gt;.',
Chris@0 164 '{{ complex.tokens }} were successfully translated with appropriate prefixes.'
Chris@0 165 );
Chris@0 166
Chris@0 167 $this->assertText(
Chris@0 168 'I have context.',
Chris@0 169 '{% trans %} with a context only msgid was excluded from translation.'
Chris@0 170 );
Chris@0 171
Chris@0 172 $this->assertText(
Chris@0 173 'I HAZ KONTEX.',
Chris@0 174 '{% trans with {"context": "Lolspeak"} %} was successfully translated with context.'
Chris@0 175 );
Chris@0 176
Chris@0 177 $this->assertText(
Chris@0 178 'O HAI NU TXT.',
Chris@0 179 '{% trans with {"langcode": "zz"} %} was successfully translated in specified language.'
Chris@0 180 );
Chris@0 181
Chris@0 182 $this->assertText(
Chris@0 183 'O HAI NU TXTZZZZ.',
Chris@0 184 '{% trans with {"context": "Lolspeak", "langcode": "zz"} %} was successfully translated with context in specified language.'
Chris@0 185 );
Chris@0 186 // Makes sure https://www.drupal.org/node/2489024 doesn't happen without
Chris@0 187 // twig debug.
Chris@0 188 $this->assertNoText(pi(), 'Running php code inside a Twig trans is not possible.');
Chris@0 189 }
Chris@0 190
Chris@0 191 /**
Chris@0 192 * Helper function: install languages.
Chris@0 193 */
Chris@0 194 protected function installLanguages() {
Chris@0 195 foreach ($this->languages as $langcode => $name) {
Chris@0 196 // Generate custom .po contents for the language.
Chris@0 197 $contents = $this->poFileContents($langcode);
Chris@0 198 if ($contents) {
Chris@0 199 // Add test language for translation testing.
Chris@0 200 $edit = [
Chris@0 201 'predefined_langcode' => 'custom',
Chris@0 202 'langcode' => $langcode,
Chris@0 203 'label' => $name,
Chris@0 204 'direction' => LanguageInterface::DIRECTION_LTR,
Chris@0 205 ];
Chris@0 206
Chris@0 207 // Install the language in Drupal.
Chris@0 208 $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
Chris@0 209 $this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.');
Chris@0 210
Chris@0 211 // Import the custom .po contents for the language.
Chris@0 212 $filename = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
Chris@0 213 file_put_contents($filename, $contents);
Chris@0 214 $options = [
Chris@0 215 'files[file]' => $filename,
Chris@0 216 'langcode' => $langcode,
Chris@0 217 'customized' => TRUE,
Chris@0 218 ];
Chris@0 219 $this->drupalPostForm('admin/config/regional/translate/import', $options, t('Import'));
Chris@0 220 drupal_unlink($filename);
Chris@0 221 }
Chris@0 222 }
Chris@0 223 $this->container->get('language_manager')->reset();
Chris@0 224 }
Chris@0 225
Chris@0 226 /**
Chris@0 227 * Generate a custom .po file for a specific test language.
Chris@0 228 *
Chris@0 229 * @param string $langcode
Chris@0 230 * The langcode of the specified language.
Chris@0 231 *
Chris@0 232 * @return string|false
Chris@0 233 * The .po contents for the specified language or FALSE if none exists.
Chris@0 234 */
Chris@0 235 protected function poFileContents($langcode) {
Chris@0 236 if ($langcode === 'xx') {
Chris@0 237 return <<< EOF
Chris@0 238 msgid ""
Chris@0 239 msgstr ""
Chris@0 240 "Project-Id-Version: Drupal 8\\n"
Chris@0 241 "MIME-Version: 1.0\\n"
Chris@0 242 "Content-Type: text/plain; charset=UTF-8\\n"
Chris@0 243 "Content-Transfer-Encoding: 8bit\\n"
Chris@0 244 "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
Chris@0 245
Chris@0 246 msgid "Hello sun."
Chris@0 247 msgstr "OH HAI SUNZ"
Chris@0 248
Chris@0 249 msgctxt "Lolspeak"
Chris@0 250 msgid "Hello sun."
Chris@0 251 msgstr "O HAI SUNZZZZZZZ"
Chris@0 252
Chris@0 253 msgid "Hello Earth."
Chris@0 254 msgstr "O HERRO ERRRF."
Chris@0 255
Chris@0 256 msgid "Hello moon."
Chris@0 257 msgstr "OH HAI TEH MUUN"
Chris@0 258
Chris@0 259 msgid "Hello star."
Chris@0 260 msgid_plural "Hello @count stars."
Chris@0 261 msgstr[0] "O HAI STARRRRR"
Chris@0 262 msgstr[1] "O HAI @count STARZZZZ"
Chris@0 263
Chris@0 264 msgid "Escaped: @string"
Chris@0 265 msgstr "ESCAPEE: @string"
Chris@0 266
Chris@0 267 msgid "Placeholder: %string"
Chris@0 268 msgstr "PLAYSHOLDR: %string"
Chris@0 269
Chris@0 270 msgid "This @token.name has a length of: @count. It contains: %token.numbers and @token.bad_text."
Chris@0 271 msgstr "DIS @token.name HAZ LENGTH OV: @count. IT CONTAYNZ: %token.numbers AN @token.bad_text."
Chris@0 272
Chris@0 273 msgctxt "Lolspeak"
Chris@0 274 msgid "I have context."
Chris@0 275 msgstr "I HAZ KONTEX."
Chris@0 276 EOF;
Chris@0 277 }
Chris@0 278 elseif ($langcode === 'zz') {
Chris@0 279 return <<< EOF
Chris@0 280 msgid ""
Chris@0 281 msgstr ""
Chris@0 282 "Project-Id-Version: Drupal 8\\n"
Chris@0 283 "MIME-Version: 1.0\\n"
Chris@0 284 "Content-Type: text/plain; charset=UTF-8\\n"
Chris@0 285 "Content-Transfer-Encoding: 8bit\\n"
Chris@0 286 "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
Chris@0 287
Chris@0 288 msgid "Hello new text."
Chris@0 289 msgstr "O HAI NU TXT."
Chris@0 290
Chris@0 291 msgctxt "Lolspeak"
Chris@0 292 msgid "Hello new text."
Chris@0 293 msgstr "O HAI NU TXTZZZZ."
Chris@0 294 EOF;
Chris@0 295 }
Chris@0 296 return FALSE;
Chris@0 297 }
Chris@0 298
Chris@0 299 }