View source
<?php
namespace Drupal\Tests\system\Functional\Theme;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Tests\BrowserTestBase;
class TwigTransTest extends BrowserTestBase {
public static $modules = [
'theme_test',
'twig_theme_test',
'locale',
'language',
];
protected $defaultTheme = 'stark';
protected $adminUser;
protected $languages = [
'xx' => 'Lolspeak',
'zz' => 'Lolspeak2',
];
protected function setUp() {
parent::setUp();
\Drupal::service('theme_installer')
->install([
'test_theme',
]);
$this
->config('system.theme')
->set('default', 'test_theme')
->save();
$this->adminUser = $this
->drupalCreateUser([
'administer languages',
'access administration pages',
'administer site configuration',
'translate interface',
]);
$this
->drupalLogin($this->adminUser);
$this
->installLanguages();
$this
->config('system.site')
->set('default_langcode', 'xx')
->save();
$this
->rebuildContainer();
$this
->assertEqual(\Drupal::languageManager()
->getDefaultLanguage()
->getId(), 'xx', 'Lolspeak is the default language');
}
public function testTwigTransTags() {
$this
->drupalGet('twig-theme-test/trans', [
'language' => \Drupal::languageManager()
->getLanguage('xx'),
]);
$this
->assertTwigTransTags();
$parameters = $this->container
->getParameter('twig.config');
$parameters['debug'] = TRUE;
$this
->setContainerParameter('twig.config', $parameters);
$this
->rebuildContainer();
$this
->resetAll();
$this
->drupalGet('twig-theme-test/trans', [
'language' => \Drupal::languageManager()
->getLanguage('xx'),
]);
$this
->assertTwigTransTags();
}
public function testEmptyTwigTransTags() {
$elements = [
'#type' => 'inline_template',
'#template' => '{% trans %}{% endtrans %}',
];
$renderer = \Drupal::service('renderer');
try {
$renderer
->renderPlain($elements);
$this
->fail('{% trans %}{% endtrans %} did not throw an exception.');
} catch (\Twig_Error_Syntax $e) {
$this
->assertStringContainsString('{% trans %} tag cannot be empty', $e
->getMessage());
} catch (\Exception $e) {
$this
->fail('{% trans %}{% endtrans %} threw an unexpected exception.');
}
}
protected function assertTwigTransTags() {
$this
->assertText('OH HAI SUNZ', '{% trans "Hello sun." %} was successfully translated.');
$this
->assertText('O HAI SUNZZZZZZZ', '{% trans "Hello sun." with {"context": "Lolspeak"} %} was successfully translated.');
$this
->assertText('O HERRO ERRRF.', '{{ "Hello Earth."|trans }} was successfully translated.');
$this
->assertText('OH HAI TEH MUUN', '{% trans %}Hello moon.{% endtrans %} was successfully translated.');
$this
->assertText('O HAI STARRRRR', '{% trans %} with {% plural count = 1 %} was successfully translated.');
$this
->assertText('O HAI 2 STARZZZZ', '{% trans %} with {% plural count = 2 %} was successfully translated.');
$this
->assertRaw('ESCAPEE: &"<>', '{{ token }} was successfully translated and prefixed with "@".');
$this
->assertRaw('PLAYSHOLDR: <em class="placeholder">&"<></em>', '{{ token|placeholder }} was successfully translated and prefixed with "%".');
$this
->assertRaw('DIS complex token HAZ LENGTH OV: 3. IT CONTAYNZ: <em class="placeholder">12345</em> AN &"<>.', '{{ complex.tokens }} were successfully translated with appropriate prefixes.');
$this
->assertText('I have context.', '{% trans %} with a context only msgid was excluded from translation.');
$this
->assertText('I HAZ KONTEX.', '{% trans with {"context": "Lolspeak"} %} was successfully translated with context.');
$this
->assertText('O HAI NU TXT.', '{% trans with {"langcode": "zz"} %} was successfully translated in specified language.');
$this
->assertText('O HAI NU TXTZZZZ.', '{% trans with {"context": "Lolspeak", "langcode": "zz"} %} was successfully translated with context in specified language.');
$this
->assertNoText(pi(), 'Running php code inside a Twig trans is not possible.');
}
protected function installLanguages() {
$file_system = \Drupal::service('file_system');
foreach ($this->languages as $langcode => $name) {
$contents = $this
->poFileContents($langcode);
if ($contents) {
$edit = [
'predefined_langcode' => 'custom',
'langcode' => $langcode,
'label' => $name,
'direction' => LanguageInterface::DIRECTION_LTR,
];
$this
->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
$this
->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.');
$filename = $file_system
->tempnam('temporary://', "po_") . '.po';
file_put_contents($filename, $contents);
$options = [
'files[file]' => $filename,
'langcode' => $langcode,
'customized' => TRUE,
];
$this
->drupalPostForm('admin/config/regional/translate/import', $options, t('Import'));
$file_system
->unlink($filename);
}
}
$this->container
->get('language_manager')
->reset();
}
protected function poFileContents($langcode) {
if ($langcode === 'xx') {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "Hello sun."
msgstr "OH HAI SUNZ"
msgctxt "Lolspeak"
msgid "Hello sun."
msgstr "O HAI SUNZZZZZZZ"
msgid "Hello Earth."
msgstr "O HERRO ERRRF."
msgid "Hello moon."
msgstr "OH HAI TEH MUUN"
msgid "Hello star."
msgid_plural "Hello @count stars."
msgstr[0] "O HAI STARRRRR"
msgstr[1] "O HAI @count STARZZZZ"
msgid "Escaped: @string"
msgstr "ESCAPEE: @string"
msgid "Placeholder: %string"
msgstr "PLAYSHOLDR: %string"
msgid "This @token.name has a length of: @count. It contains: %token.numbers and @token.bad_text."
msgstr "DIS @token.name HAZ LENGTH OV: @count. IT CONTAYNZ: %token.numbers AN @token.bad_text."
msgctxt "Lolspeak"
msgid "I have context."
msgstr "I HAZ KONTEX."
EOF;
}
elseif ($langcode === 'zz') {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "Hello new text."
msgstr "O HAI NU TXT."
msgctxt "Lolspeak"
msgid "Hello new text."
msgstr "O HAI NU TXTZZZZ."
EOF;
}
return FALSE;
}
}