summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorChristophe Monniez <moc@odoo.com>2021-02-22 10:41:02 +0000
committerChristophe Monniez <moc@odoo.com>2021-03-19 10:35:55 +0000
commit9184ae45e0df179fc093c1fc48a7fa56d8fe9594 (patch)
tree04d93f222e071f688137acce243d16b96d998307 /odoo
parent0f6fdce76809af7e965f672970d74594a337f6fb (diff)
[IMP] tests: add a test to avoid translations of template strings
When a template string that contains an expression is translated, the resulting msgid is wrong. e.g.: _t(`blah blah ${expression}`) will generate a wrong msgid like this: msgid "blah blah ${expression}" With this commit, a new test is added to find and forbid translations of JS template-strings. closes odoo/odoo#68126 Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/test_lint/tests/__init__.py1
-rw-r--r--odoo/addons/test_lint/tests/test_jstranslate.py79
2 files changed, 80 insertions, 0 deletions
diff --git a/odoo/addons/test_lint/tests/__init__.py b/odoo/addons/test_lint/tests/__init__.py
index b8416fe62bf..f9bf576a3ff 100644
--- a/odoo/addons/test_lint/tests/__init__.py
+++ b/odoo/addons/test_lint/tests/__init__.py
@@ -4,3 +4,4 @@ from . import test_ecmascript
from . import test_markers
from . import test_onchange_domains
from . import test_dunderinit
+from . import test_jstranslate
diff --git a/odoo/addons/test_lint/tests/test_jstranslate.py b/odoo/addons/test_lint/tests/test_jstranslate.py
new file mode 100644
index 00000000000..696b8bef62d
--- /dev/null
+++ b/odoo/addons/test_lint/tests/test_jstranslate.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import logging
+import re
+
+from odoo import tools
+from odoo.modules import get_resource_from_path
+
+from . import lint_case
+
+_logger = logging.getLogger(__name__)
+
+TSTRING_RE = re.compile(r'_l?t\(\s*`.*?\s*`\s*\)', re.DOTALL)
+EXPRESSION_RE = re.compile(r'\$\{.+?\}')
+
+class TestJsTranslations(lint_case.LintCase):
+
+ def check_text(self, text):
+ """ Search for translated template strings that contains an expression
+ :param text: The js text to search
+ :return: A list of tuple with line number and invalid template string or an empty list
+ """
+ error_list = list()
+ for m in TSTRING_RE.finditer(text):
+ template_string = m.group(0)
+ if EXPRESSION_RE.search(template_string):
+ line_nb = text[:m.start()].count('\n') + 1
+ error_list.append((line_nb, template_string))
+ return error_list
+
+ def test_regular_expression(self):
+ bad_js = """
+ const foo = {
+ valid: _lt(`not useful but valid template-string`),
+ invalid: _lt(`invalid template-string
+ that spans multiple lines ${expression}`)
+ };
+ """
+ error_list = self.check_text(bad_js)
+ self.assertEqual(len(error_list), 1)
+ for line, template_string in error_list:
+ template_string = error_list[0][1]
+ self.assertIn('invalid template-string', template_string)
+ self.assertNotIn('but valid template-string', template_string)
+ self.assertEqual(line, 4)
+
+ def test_regular_expression_long(self):
+ bad_js = """
+ thing = _t(
+ `foo ${this + is(a, very) - long == expression}`
+ );
+ """
+
+ error_list = self.check_text(bad_js)
+ self.assertEqual(len(error_list), 1)
+ for line, template_string in error_list:
+ template_string = error_list[0][1]
+ self.assertIn('foo ${this + is(a, very) - long == expression}', template_string)
+ self.assertEqual(line, 2)
+
+ def test_js_translations(self):
+ """ Test that there are no translation of JS template strings """
+
+ counter = 0
+ failures = 0
+ for js_file in self.iter_module_files('*.js'):
+ counter += 1
+ with tools.file_open(js_file, 'r') as f:
+ js_txt = f.read()
+ error_list = self.check_text(js_txt)
+ for line_number, template_string in error_list:
+ failures += 1
+ mod, relative_path, _ = get_resource_from_path(js_file)
+ _logger.error("Translation of a template string found in `%s/%s` at line %s: %s", mod, relative_path, line_number, template_string)
+
+ _logger.info('%s files tested', counter)
+ if failures > 0:
+ self.fail("%s invalid template strings found in js files." % failures)