From ac0224319ec273ec88b0e19559dce602992ad95e Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Wed, 23 Jun 2021 08:51:10 +0000 Subject: [PATCH] [FIX] web: utils/strings: sprintf support lazy translated strings Have something like: ```js sprintf("my string %s", _lt("lazy translated")); ``` Before this commit, the lazy translated term was not formatted into the string. This was because _lt returns an object containing a custom toString function, which was not handled by sprintf After this commit, sprintf is able to handle lazy translated strings closes odoo/odoo#72598 Signed-off-by: Aaron Bohy (aab) --- addons/web/static/src/core/utils/strings.js | 2 +- .../static/tests/core/utils/strings_tests.js | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/core/utils/strings.js b/addons/web/static/src/core/utils/strings.js index 4a77488bb97..b4851106d55 100644 --- a/addons/web/static/src/core/utils/strings.js +++ b/addons/web/static/src/core/utils/strings.js @@ -70,7 +70,7 @@ export function intersperse(str, indices, separator = "") { * @returns {string} */ export function sprintf(s, ...values) { - if (values.length === 1 && typeof values[0] === "object") { + if (values.length === 1 && Object.prototype.toString.call(values[0]) === "[object Object]") { const valuesDict = values[0]; s = s.replace(/\%\(?([^\)]+)\)s/g, (match, value) => valuesDict[value]); } else if (values.length > 0) { diff --git a/addons/web/static/tests/core/utils/strings_tests.js b/addons/web/static/tests/core/utils/strings_tests.js index 373546fcbc8..8895eef1500 100644 --- a/addons/web/static/tests/core/utils/strings_tests.js +++ b/addons/web/static/tests/core/utils/strings_tests.js @@ -1,6 +1,8 @@ /** @odoo-module **/ import { escapeRegExp, intersperse, sprintf } from "@web/core/utils/strings"; +import { _lt, translatedTerms } from "@web/core/l10n/translation"; +import { patchWithCleanup } from "../../helpers/utils"; QUnit.module("utils", () => { QUnit.module("strings"); @@ -62,4 +64,37 @@ QUnit.module("utils", () => { assert.deepEqual(sprintf("Hello %s!"), "Hello %s!"); assert.deepEqual(sprintf("Hello %(value)s!"), "Hello %(value)s!"); }); + + QUnit.test("sprintf properly formats numbers", (assert) => { + assert.deepEqual(sprintf("Hello %s!", 5), "Hello 5!"); + assert.deepEqual(sprintf("Hello %s and %s!", 9, 10), "Hello 9 and 10!"); + assert.deepEqual(sprintf("Hello %(x)s!", { x: 11 }), "Hello 11!"); + assert.deepEqual(sprintf("Hello %(x)s and %(y)s!", { x: 12, y: 13 }), "Hello 12 and 13!"); + }); + + QUnit.test("sprintf set behavior when value is an Array", (assert) => { + assert.deepEqual(sprintf("Hello %s!", ["inarray"]), "Hello inarray!"); + assert.deepEqual(sprintf("Hello %s and %s!", [9, "10"], [11]), "Hello 9,10 and 11!"); + assert.deepEqual(sprintf("Hello %(x)s!", { x: [11] }), "Hello 11!"); + assert.deepEqual( + sprintf("Hello %(x)s and %(y)s!", { x: [12], y: ["13"] }), + "Hello 12 and 13!" + ); + }); + + QUnit.test("sprintf supports lazy translated string", (assert) => { + patchWithCleanup(translatedTerms, { + one: "en", + two: "två", + }); + + assert.deepEqual(sprintf("Hello %s", _lt("one")), "Hello en"); + assert.deepEqual(sprintf("Hello %s %s", _lt("one"), _lt("two")), "Hello en två"); + + const vals = { + one: _lt("one"), + two: _lt("two"), + }; + assert.deepEqual(sprintf("Hello %(two)s %(one)s", vals), "Hello två en"); + }); });