annotate core/modules/locale/tests/src/Functional/LocaleJavascriptTranslationTest.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\Functional;
Chris@0 4
Chris@18 5 use Drupal\Component\Gettext\PoItem;
Chris@0 6 use Drupal\Core\Language\LanguageInterface;
Chris@0 7 use Drupal\Tests\BrowserTestBase;
Chris@17 8 use Drupal\Component\Render\FormattableMarkup;
Chris@0 9
Chris@0 10 /**
Chris@0 11 * Tests parsing js files for translatable strings.
Chris@0 12 *
Chris@0 13 * @group locale
Chris@0 14 */
Chris@0 15 class LocaleJavascriptTranslationTest extends BrowserTestBase {
Chris@0 16
Chris@0 17 /**
Chris@0 18 * Modules to enable.
Chris@0 19 *
Chris@0 20 * @var array
Chris@0 21 */
Chris@0 22 public static $modules = ['locale', 'locale_test'];
Chris@0 23
Chris@0 24 public function testFileParsing() {
Chris@0 25
Chris@0 26 // This test is for ensuring that the regular expression in
Chris@0 27 // _locale_parse_js_file() finds translatable source strings in all valid
Chris@0 28 // JavaScript syntax regardless of the coding style used, especially with
Chris@0 29 // respect to optional whitespace, line breaks, etc.
Chris@0 30 // - We test locale_test.es6.js, because that is the one that contains a
Chris@0 31 // variety of whitespace styles.
Chris@0 32 // - We also test the transpiled locale_test.js as an extra double-check
Chris@0 33 // that JavaScript transpilation doesn't change what
Chris@0 34 // _locale_parse_js_file() finds.
Chris@0 35 $files[] = __DIR__ . '/../../locale_test.es6.js';
Chris@0 36 $files[] = __DIR__ . '/../../locale_test.js';
Chris@0 37
Chris@0 38 foreach ($files as $filename) {
Chris@0 39 // Parse the file to look for source strings.
Chris@0 40 _locale_parse_js_file($filename);
Chris@0 41
Chris@0 42 // Get all of the source strings that were found.
Chris@0 43 $strings = $this->container
Chris@0 44 ->get('locale.storage')
Chris@0 45 ->getStrings([
Chris@0 46 'type' => 'javascript',
Chris@0 47 'name' => $filename,
Chris@0 48 ]);
Chris@0 49
Chris@0 50 $source_strings = [];
Chris@0 51 foreach ($strings as $string) {
Chris@0 52 $source_strings[$string->source] = $string->context;
Chris@0 53 }
Chris@0 54
Chris@18 55 $etx = PoItem::DELIMITER;
Chris@0 56 // List of all strings that should be in the file.
Chris@0 57 $test_strings = [
Chris@0 58 'Standard Call t' => '',
Chris@0 59 'Whitespace Call t' => '',
Chris@0 60
Chris@0 61 'Single Quote t' => '',
Chris@0 62 "Single Quote \\'Escaped\\' t" => '',
Chris@0 63 'Single Quote Concat strings t' => '',
Chris@0 64
Chris@0 65 'Double Quote t' => '',
Chris@0 66 "Double Quote \\\"Escaped\\\" t" => '',
Chris@0 67 'Double Quote Concat strings t' => '',
Chris@0 68
Chris@0 69 'Context !key Args t' => 'Context string',
Chris@0 70
Chris@0 71 'Context Unquoted t' => 'Context string unquoted',
Chris@0 72 'Context Single Quoted t' => 'Context string single quoted',
Chris@0 73 'Context Double Quoted t' => 'Context string double quoted',
Chris@0 74
Chris@0 75 "Standard Call plural{$etx}Standard Call @count plural" => '',
Chris@0 76 "Whitespace Call plural{$etx}Whitespace Call @count plural" => '',
Chris@0 77
Chris@0 78 "Single Quote plural{$etx}Single Quote @count plural" => '',
Chris@0 79 "Single Quote \\'Escaped\\' plural{$etx}Single Quote \\'Escaped\\' @count plural" => '',
Chris@0 80
Chris@0 81 "Double Quote plural{$etx}Double Quote @count plural" => '',
Chris@0 82 "Double Quote \\\"Escaped\\\" plural{$etx}Double Quote \\\"Escaped\\\" @count plural" => '',
Chris@0 83
Chris@0 84 "Context !key Args plural{$etx}Context !key Args @count plural" => 'Context string',
Chris@0 85
Chris@0 86 "Context Unquoted plural{$etx}Context Unquoted @count plural" => 'Context string unquoted',
Chris@0 87 "Context Single Quoted plural{$etx}Context Single Quoted @count plural" => 'Context string single quoted',
Chris@0 88 "Context Double Quoted plural{$etx}Context Double Quoted @count plural" => 'Context string double quoted',
Chris@18 89
Chris@18 90 "No count argument plural - singular{$etx}No count argument plural - plural" => '',
Chris@0 91 ];
Chris@0 92
Chris@0 93 // Assert that all strings were found properly.
Chris@0 94 foreach ($test_strings as $str => $context) {
Chris@0 95 $args = ['%source' => $str, '%context' => $context];
Chris@0 96
Chris@0 97 // Make sure that the string was found in the file.
Chris@17 98 $this->assertTrue(isset($source_strings[$str]), new FormattableMarkup('Found source string: %source', $args));
Chris@0 99
Chris@0 100 // Make sure that the proper context was matched.
Chris@17 101 $message = $context ? new FormattableMarkup('Context for %source is %context', $args) : new FormattableMarkup('Context for %source is blank', $args);
Chris@0 102 $this->assertTrue(isset($source_strings[$str]) && $source_strings[$str] === $context, $message);
Chris@0 103 }
Chris@0 104
Chris@0 105 $this->assertEqual(count($source_strings), count($test_strings), 'Found correct number of source strings.');
Chris@0 106 }
Chris@0 107 }
Chris@0 108
Chris@0 109 /**
Chris@0 110 * Assert translations JS is added before drupal.js, because it depends on it.
Chris@0 111 */
Chris@0 112 public function testLocaleTranslationJsDependencies() {
Chris@0 113 // User to add and remove language.
Chris@0 114 $admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages', 'translate interface']);
Chris@0 115
Chris@0 116 // Add custom language.
Chris@0 117 $this->drupalLogin($admin_user);
Chris@0 118 // Code for the language.
Chris@0 119 $langcode = 'es';
Chris@0 120 // The English name for the language.
Chris@0 121 $name = $this->randomMachineName(16);
Chris@0 122 // The domain prefix.
Chris@0 123 $prefix = $langcode;
Chris@0 124 $edit = [
Chris@0 125 'predefined_langcode' => 'custom',
Chris@0 126 'langcode' => $langcode,
Chris@0 127 'label' => $name,
Chris@0 128 'direction' => LanguageInterface::DIRECTION_LTR,
Chris@0 129 ];
Chris@0 130 $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
Chris@0 131
Chris@0 132 // Set path prefix.
Chris@0 133 $edit = ["prefix[$langcode]" => $prefix];
Chris@0 134 $this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration'));
Chris@0 135
Chris@0 136 // This forces locale.admin.js string sources to be imported, which contains
Chris@0 137 // the next translation.
Chris@0 138 $this->drupalGet($prefix . '/admin/config/regional/translate');
Chris@0 139
Chris@0 140 // Translate a string in locale.admin.js to our new language.
Chris@0 141 $strings = \Drupal::service('locale.storage')
Chris@0 142 ->getStrings([
Chris@0 143 'source' => 'Show description',
Chris@0 144 'type' => 'javascript',
Chris@0 145 'name' => 'core/modules/locale/locale.admin.js',
Chris@0 146 ]);
Chris@0 147 $string = $strings[0];
Chris@0 148
Chris@0 149 $this->drupalPostForm(NULL, ['string' => 'Show description'], t('Filter'));
Chris@0 150 $edit = ['strings[' . $string->lid . '][translations][0]' => $this->randomString(16)];
Chris@0 151 $this->drupalPostForm(NULL, $edit, t('Save translations'));
Chris@0 152
Chris@0 153 // Calculate the filename of the JS including the translations.
Chris@0 154 $js_translation_files = \Drupal::state()->get('locale.translation.javascript');
Chris@0 155 $js_filename = $prefix . '_' . $js_translation_files[$prefix] . '.js';
Chris@0 156
Chris@0 157 $content = $this->getSession()->getPage()->getContent();
Chris@0 158 // Assert translations JS is included before drupal.js.
Chris@0 159 $this->assertTrue(strpos($content, $js_filename) < strpos($content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.');
Chris@0 160 }
Chris@0 161
Chris@0 162 }