diff options
| author | Xavier Morel <xmo@odoo.com> | 2021-04-28 11:46:52 +0000 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2021-04-29 05:46:03 +0000 |
| commit | 251b77c959af37fa0da6739ea978ca4f198414cb (patch) | |
| tree | 4fdd9c7fa37aac07dc01b99e715cb9ec8f627086 | |
| parent | deaa4d7dd2690ce389be6709e1b387ae990b514f (diff) | |
[FIX] *: bunch of mismarked translation specifiers
`_(xyz)` will wrap them in an underscore.js object, which when used in
a string context will just return the string. So it's basically a
no-op, but it certainly doesn't translate the terms.
closes odoo/odoo#70000
Related: odoo/enterprise#18001
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
5 files changed, 57 insertions, 24 deletions
diff --git a/addons/point_of_sale/static/src/js/Screens/ClientListScreen/ClientDetailsEdit.js b/addons/point_of_sale/static/src/js/Screens/ClientListScreen/ClientDetailsEdit.js index 1ac4cf05077..facee796bed 100644 --- a/addons/point_of_sale/static/src/js/Screens/ClientListScreen/ClientDetailsEdit.js +++ b/addons/point_of_sale/static/src/js/Screens/ClientListScreen/ClientDetailsEdit.js @@ -1,6 +1,7 @@ odoo.define('point_of_sale.ClientDetailsEdit', function(require) { 'use strict'; + const { _t } = require('web.core'); const { getDataURLFromFile } = require('web.utils'); const PosComponent = require('point_of_sale.PosComponent'); const Registries = require('point_of_sale.Registries'); @@ -47,7 +48,7 @@ odoo.define('point_of_sale.ClientDetailsEdit', function(require) { if ((!this.props.partner.name && !processedChanges.name) || processedChanges.name === '' ){ return this.showPopup('ErrorPopup', { - title: _('A Customer Name Is Required'), + title: _t('A Customer Name Is Required'), }); } processedChanges.id = this.props.partner.id || false; diff --git a/addons/pos_adyen/static/src/js/payment_adyen.js b/addons/pos_adyen/static/src/js/payment_adyen.js index 02a6afdc579..2d53c46146e 100644 --- a/addons/pos_adyen/static/src/js/payment_adyen.js +++ b/addons/pos_adyen/static/src/js/payment_adyen.js @@ -38,7 +38,7 @@ var PaymentAdyen = PaymentInterface.extend({ if (line) { line.set_payment_status('retry'); } - this._show_error(_('Could not connect to the Odoo server, please check your internet connection and try again.')); + this._show_error(_t('Could not connect to the Odoo server, please check your internet connection and try again.')); return Promise.reject(data); // prevent subsequent onFullFilled's from being called }, @@ -114,7 +114,7 @@ var PaymentAdyen = PaymentInterface.extend({ var self = this; if (this.pos.get_order().selected_paymentline.amount < 0) { - this._show_error(_('Cannot process transactions with negative amount.')); + this._show_error(_t('Cannot process transactions with negative amount.')); return Promise.resolve(); } @@ -150,7 +150,7 @@ var PaymentAdyen = PaymentInterface.extend({ // Only valid response is a 200 OK HTTP response which is // represented by true. if (! ignore_error && data !== "ok") { - self._show_error(_('Cancelling the payment failed. Please cancel it manually on the payment terminal.')); + self._show_error(_t('Cancelling the payment failed. Please cancel it manually on the payment terminal.')); } }); }, diff --git a/addons/survey/static/src/js/survey_session_manage.js b/addons/survey/static/src/js/survey_session_manage.js index 9af7e15d84d..dc9898e718d 100644 --- a/addons/survey/static/src/js/survey_session_manage.js +++ b/addons/survey/static/src/js/survey_session_manage.js @@ -330,7 +330,7 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend({ // Display last screen if leaderboard activated self.isLastQuestion = true; self._setupLeaderboard().then(function () { - self.$('.o_survey_session_leaderboard_title').text(_('Final Leaderboard')); + self.$('.o_survey_session_leaderboard_title').text(_t('Final Leaderboard')); self.$('.o_survey_session_navigation_next').addClass('d-none'); self.$('.o_survey_leaderboard_buttons').removeClass('d-none'); self.leaderBoard.showLeaderboard(false, false); diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js index a35c793e5c6..29321862d99 100644 --- a/addons/web/static/src/js/core/ajax.js +++ b/addons/web/static/src/js/core/ajax.js @@ -311,7 +311,7 @@ function get_file(options) { xhr.onerror = function () { if (options.error) { options.error({ - message: _("Something happened while trying to contact the server, check that the server is online and that you still have a working network connection."), + message: _t("Something happened while trying to contact the server, check that the server is online and that you still have a working network connection."), data: { title: _t("Could not connect to the server") } }); } diff --git a/odoo/addons/test_lint/tests/test_jstranslate.py b/odoo/addons/test_lint/tests/test_jstranslate.py index 696b8bef62d..64a73a3d474 100644 --- a/odoo/addons/test_lint/tests/test_jstranslate.py +++ b/odoo/addons/test_lint/tests/test_jstranslate.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +# pylint: disable=unbalanced-tuple-unpacking import logging import re @@ -13,13 +14,16 @@ _logger = logging.getLogger(__name__) TSTRING_RE = re.compile(r'_l?t\(\s*`.*?\s*`\s*\)', re.DOTALL) EXPRESSION_RE = re.compile(r'\$\{.+?\}') +UNDERSCORE_RE = re.compile(r'\b_\(\s*[\'"]') 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 + """ Search for translation errors in the text + + :param text: The js text to search + :return: A list of tuple with line number and invalid template string, + or None for underscore errors """ error_list = list() for m in TSTRING_RE.finditer(text): @@ -27,6 +31,11 @@ class TestJsTranslations(lint_case.LintCase): if EXPRESSION_RE.search(template_string): line_nb = text[:m.start()].count('\n') + 1 error_list.append((line_nb, template_string)) + + for m in UNDERSCORE_RE.finditer(text): + lineno = text[:m.start()].count('\n') + 1 + error_list.append((lineno, None)) + return error_list def test_regular_expression(self): @@ -39,11 +48,10 @@ class TestJsTranslations(lint_case.LintCase): """ 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) + [(line, template_string)] = error_list + self.assertEqual(line, 4) + self.assertIn('invalid template-string', template_string) + self.assertNotIn('but valid template-string', template_string) def test_regular_expression_long(self): bad_js = """ @@ -54,25 +62,49 @@ class TestJsTranslations(lint_case.LintCase): 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) + [(line, template_string)] = error_list + self.assertEqual(line, 2) + self.assertIn('foo ${this + is(a, very) - long == expression}', template_string) + + def test_matches_underscore(self): + bad_js = """ + const thing1 = _('literal0'); + const thing0 = _([]); + const thing2 = _("literal1"); + """ + self.assertEqual( + self.check_text(bad_js), + [(2, None), (4, None)] + ) def test_js_translations(self): - """ Test that there are no translation of JS template strings """ + """ Test that there are no translation of JS template strings or underscore + calls misused as translation markers + """ counter = 0 failures = 0 for js_file in self.iter_module_files('*.js'): + # lodash has string methods and occurrences of `_('text')` in its comments + if js_file.endswith('/lodash.js'): + continue + 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) + + 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) + if template_string: + prefix = "Translation of a template string" + suffix = template_string + else: + prefix = "underscore.js used as translation function" + suffix = "_t and _lt are the JS translation functions" + + _logger.error("%s found in `%s/%s` at line %s: %s", prefix, mod, relative_path, line_number, suffix) _logger.info('%s files tested', counter) if failures > 0: |
