Chris@0: 'Lolspeak',
Chris@0: 'zz' => 'Lolspeak2',
Chris@0: ];
Chris@0:
Chris@0: /**
Chris@0: * {@inheritdoc}
Chris@0: */
Chris@0: protected function setUp() {
Chris@0: parent::setUp();
Chris@0:
Chris@0: // Setup test_theme.
Chris@0: \Drupal::service('theme_handler')->install(['test_theme']);
Chris@0: $this->config('system.theme')->set('default', 'test_theme')->save();
Chris@0:
Chris@0: // Create and log in as admin.
Chris@0: $this->adminUser = $this->drupalCreateUser([
Chris@0: 'administer languages',
Chris@0: 'access administration pages',
Chris@0: 'administer site configuration',
Chris@0: 'translate interface'
Chris@0: ]);
Chris@0: $this->drupalLogin($this->adminUser);
Chris@0:
Chris@0: // Install languages.
Chris@0: $this->installLanguages();
Chris@0:
Chris@0: // Assign Lolspeak (xx) to be the default language.
Chris@0: $this->config('system.site')->set('default_langcode', 'xx')->save();
Chris@0: $this->rebuildContainer();
Chris@0:
Chris@0: // Check that lolspeak is the default language for the site.
Chris@0: $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage()->getId(), 'xx', 'Lolspeak is the default language');
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Test Twig "trans" tags.
Chris@0: */
Chris@0: public function testTwigTransTags() {
Chris@0: // Run this once without and once with Twig debug because trans can work
Chris@0: // differently depending on that setting.
Chris@0: $this->drupalGet('twig-theme-test/trans', ['language' => \Drupal::languageManager()->getLanguage('xx')]);
Chris@0: $this->assertTwigTransTags();
Chris@0:
Chris@0: // Enable debug, rebuild the service container, and clear all caches.
Chris@0: $parameters = $this->container->getParameter('twig.config');
Chris@0: $parameters['debug'] = TRUE;
Chris@0: $this->setContainerParameter('twig.config', $parameters);
Chris@0: $this->rebuildContainer();
Chris@0: $this->resetAll();
Chris@0:
Chris@0: $this->drupalGet('twig-theme-test/trans', ['language' => \Drupal::languageManager()->getLanguage('xx')]);
Chris@0: $this->assertTwigTransTags();
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Test empty Twig "trans" tags.
Chris@0: */
Chris@0: public function testEmptyTwigTransTags() {
Chris@0: $elements = [
Chris@0: '#type' => 'inline_template',
Chris@0: '#template' => '{% trans %}{% endtrans %}',
Chris@0: ];
Chris@0: /** @var \Drupal\Core\Render\RendererInterface $renderer */
Chris@0: $renderer = \Drupal::service('renderer');
Chris@0:
Chris@0: try {
Chris@0: $renderer->renderPlain($elements);
Chris@0:
Chris@0: $this->fail('{% trans %}{% endtrans %} did not throw an exception.');
Chris@0: }
Chris@0: catch (\Twig_Error_Syntax $e) {
Chris@0: $this->assertTrue(strstr($e->getMessage(), '{% trans %} tag cannot be empty'), '{% trans %}{% endtrans %} threw the expected exception.');
Chris@0: }
Chris@0: catch (\Exception $e) {
Chris@0: $this->fail('{% trans %}{% endtrans %} threw an unexpected exception.');
Chris@0: }
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Asserts Twig trans tags.
Chris@0: */
Chris@0: protected function assertTwigTransTags() {
Chris@0: $this->assertText(
Chris@0: 'OH HAI SUNZ',
Chris@0: '{% trans "Hello sun." %} was successfully translated.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'O HAI SUNZZZZZZZ',
Chris@0: '{% trans "Hello sun." with {"context": "Lolspeak"} %} was successfully translated.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'O HERRO ERRRF.',
Chris@0: '{{ "Hello Earth."|trans }} was successfully translated.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'OH HAI TEH MUUN',
Chris@0: '{% trans %}Hello moon.{% endtrans %} was successfully translated.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'O HAI STARRRRR',
Chris@0: '{% trans %} with {% plural count = 1 %} was successfully translated.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'O HAI 2 STARZZZZ',
Chris@0: '{% trans %} with {% plural count = 2 %} was successfully translated.'
Chris@0: );
Chris@0:
Chris@0: $this->assertRaw(
Chris@0: 'ESCAPEE: &"<>',
Chris@0: '{{ token }} was successfully translated and prefixed with "@".'
Chris@0: );
Chris@0:
Chris@0: $this->assertRaw(
Chris@0: 'PLAYSHOLDR: &"<>',
Chris@0: '{{ token|placeholder }} was successfully translated and prefixed with "%".'
Chris@0: );
Chris@0:
Chris@0: $this->assertRaw(
Chris@0: 'DIS complex token HAZ LENGTH OV: 3. IT CONTAYNZ: 12345 AN &"<>.',
Chris@0: '{{ complex.tokens }} were successfully translated with appropriate prefixes.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'I have context.',
Chris@0: '{% trans %} with a context only msgid was excluded from translation.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'I HAZ KONTEX.',
Chris@0: '{% trans with {"context": "Lolspeak"} %} was successfully translated with context.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'O HAI NU TXT.',
Chris@0: '{% trans with {"langcode": "zz"} %} was successfully translated in specified language.'
Chris@0: );
Chris@0:
Chris@0: $this->assertText(
Chris@0: 'O HAI NU TXTZZZZ.',
Chris@0: '{% trans with {"context": "Lolspeak", "langcode": "zz"} %} was successfully translated with context in specified language.'
Chris@0: );
Chris@0: // Makes sure https://www.drupal.org/node/2489024 doesn't happen without
Chris@0: // twig debug.
Chris@0: $this->assertNoText(pi(), 'Running php code inside a Twig trans is not possible.');
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Helper function: install languages.
Chris@0: */
Chris@0: protected function installLanguages() {
Chris@0: foreach ($this->languages as $langcode => $name) {
Chris@0: // Generate custom .po contents for the language.
Chris@0: $contents = $this->poFileContents($langcode);
Chris@0: if ($contents) {
Chris@0: // Add test language for translation testing.
Chris@0: $edit = [
Chris@0: 'predefined_langcode' => 'custom',
Chris@0: 'langcode' => $langcode,
Chris@0: 'label' => $name,
Chris@0: 'direction' => LanguageInterface::DIRECTION_LTR,
Chris@0: ];
Chris@0:
Chris@0: // Install the language in Drupal.
Chris@0: $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
Chris@0: $this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.');
Chris@0:
Chris@0: // Import the custom .po contents for the language.
Chris@0: $filename = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
Chris@0: file_put_contents($filename, $contents);
Chris@0: $options = [
Chris@0: 'files[file]' => $filename,
Chris@0: 'langcode' => $langcode,
Chris@0: 'customized' => TRUE,
Chris@0: ];
Chris@0: $this->drupalPostForm('admin/config/regional/translate/import', $options, t('Import'));
Chris@0: drupal_unlink($filename);
Chris@0: }
Chris@0: }
Chris@0: $this->container->get('language_manager')->reset();
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Generate a custom .po file for a specific test language.
Chris@0: *
Chris@0: * @param string $langcode
Chris@0: * The langcode of the specified language.
Chris@0: *
Chris@0: * @return string|false
Chris@0: * The .po contents for the specified language or FALSE if none exists.
Chris@0: */
Chris@0: protected function poFileContents($langcode) {
Chris@0: if ($langcode === 'xx') {
Chris@0: return <<< EOF
Chris@0: msgid ""
Chris@0: msgstr ""
Chris@0: "Project-Id-Version: Drupal 8\\n"
Chris@0: "MIME-Version: 1.0\\n"
Chris@0: "Content-Type: text/plain; charset=UTF-8\\n"
Chris@0: "Content-Transfer-Encoding: 8bit\\n"
Chris@0: "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
Chris@0:
Chris@0: msgid "Hello sun."
Chris@0: msgstr "OH HAI SUNZ"
Chris@0:
Chris@0: msgctxt "Lolspeak"
Chris@0: msgid "Hello sun."
Chris@0: msgstr "O HAI SUNZZZZZZZ"
Chris@0:
Chris@0: msgid "Hello Earth."
Chris@0: msgstr "O HERRO ERRRF."
Chris@0:
Chris@0: msgid "Hello moon."
Chris@0: msgstr "OH HAI TEH MUUN"
Chris@0:
Chris@0: msgid "Hello star."
Chris@0: msgid_plural "Hello @count stars."
Chris@0: msgstr[0] "O HAI STARRRRR"
Chris@0: msgstr[1] "O HAI @count STARZZZZ"
Chris@0:
Chris@0: msgid "Escaped: @string"
Chris@0: msgstr "ESCAPEE: @string"
Chris@0:
Chris@0: msgid "Placeholder: %string"
Chris@0: msgstr "PLAYSHOLDR: %string"
Chris@0:
Chris@0: msgid "This @token.name has a length of: @count. It contains: %token.numbers and @token.bad_text."
Chris@0: msgstr "DIS @token.name HAZ LENGTH OV: @count. IT CONTAYNZ: %token.numbers AN @token.bad_text."
Chris@0:
Chris@0: msgctxt "Lolspeak"
Chris@0: msgid "I have context."
Chris@0: msgstr "I HAZ KONTEX."
Chris@0: EOF;
Chris@0: }
Chris@0: elseif ($langcode === 'zz') {
Chris@0: return <<< EOF
Chris@0: msgid ""
Chris@0: msgstr ""
Chris@0: "Project-Id-Version: Drupal 8\\n"
Chris@0: "MIME-Version: 1.0\\n"
Chris@0: "Content-Type: text/plain; charset=UTF-8\\n"
Chris@0: "Content-Transfer-Encoding: 8bit\\n"
Chris@0: "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
Chris@0:
Chris@0: msgid "Hello new text."
Chris@0: msgstr "O HAI NU TXT."
Chris@0:
Chris@0: msgctxt "Lolspeak"
Chris@0: msgid "Hello new text."
Chris@0: msgstr "O HAI NU TXTZZZZ."
Chris@0: EOF;
Chris@0: }
Chris@0: return FALSE;
Chris@0: }
Chris@0:
Chris@0: }