author | Andreas Tolfsen <ato@sny.no> |
Sat, 30 Sep 2017 17:06:29 +0100 | |
changeset 385909 | df3e0cc4a9bfc95f84d241eb3b2cef9da332de87 |
parent 385908 | ee470df77e3fbb980c953051470c2c074a0c6065 |
child 385910 | 2fe618b2b66030c44ce1e69eb2b84dc36e5211fb |
push id | 32672 |
push user | archaeopteryx@coole-files.de |
push date | Fri, 13 Oct 2017 09:00:05 +0000 |
treeherder | mozilla-central@3efcb26e5f37 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | whimboo |
bugs | 1403577 |
milestone | 58.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/testing/marionette/format.js @@ -0,0 +1,85 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = ["truncate"]; + +const MAX_STRING_LENGTH = 250; + +/** + * Template literal that truncates string values in arbitrary objects. + * + * Given any object, the template will walk the object and truncate + * any strings it comes across to a reasonable limit. This is suitable + * when you have arbitrary data and data integrity is not important. + * + * The strings are truncated in the middle so that the beginning and + * the end is preserved. This will make a long, truncated string look + * like "X <...> Y", where X and Y are half the number of characters + * of the maximum string length from either side of the string. + * + * Usage: + * + * <pre><code> + * truncate`Hello ${"x".repeat(260)}!`; + * // Hello xxx ... xxx! + * </code></pre> + * + * Functions named <code>toJSON</code> or <code>toString</code> + * on objects will be called. + */ +function truncate(strings, ...values) { + function walk(obj) { + const typ = Object.prototype.toString.call(obj); + + switch (typ) { + case "[object Undefined]": + case "[object Null]": + case "[object Boolean]": + case "[object Number]": + return obj; + + case "[object String]": + if (obj.length > MAX_STRING_LENGTH) { + let s1 = obj.substring(0, (MAX_STRING_LENGTH / 2)); + let s2 = obj.substring(obj.length - (MAX_STRING_LENGTH / 2)); + return `${s1} ... ${s2}`; + } + return obj; + + case "[object Array]": + return obj.map(walk); + + // arbitrary object + default: + if (Object.getOwnPropertyNames(obj).includes("toString") && + typeof obj.toString == "function") { + return walk(obj.toString()); + } + + let rv = {}; + for (let prop in obj) { + rv[prop] = walk(obj[prop]); + } + return rv; + } + } + + let res = []; + for (let i = 0; i < strings.length; ++i) { + res.push(strings[i]); + if (i < values.length) { + let obj = walk(values[i]); + let t = Object.prototype.toString.call(obj); + if (t == "[object Array]" || t == "[object Object]") { + res.push(JSON.stringify(obj)); + } else { + res.push(obj); + } + } + } + return res.join(""); +} +this.truncate = truncate;
--- a/testing/marionette/jar.mn +++ b/testing/marionette/jar.mn @@ -31,16 +31,17 @@ marionette.jar: content/addon.js (addon.js) content/session.js (session.js) content/transport.js (transport.js) content/packets.js (packets.js) content/stream-utils.js (stream-utils.js) content/reftest.js (reftest.js) content/reftest.xul (reftest.xul) content/dom.js (dom.js) + content/format.js (format.js) #ifdef ENABLE_TESTS content/test.xul (chrome/test.xul) content/test2.xul (chrome/test2.xul) content/test_dialog.dtd (chrome/test_dialog.dtd) content/test_dialog.properties (chrome/test_dialog.properties) content/test_dialog.xul (chrome/test_dialog.xul) content/test_nested_iframe.xul (chrome/test_nested_iframe.xul) content/test_anonymous_content.xul (chrome/test_anonymous_content.xul)
new file mode 100644 --- /dev/null +++ b/testing/marionette/test_format.js @@ -0,0 +1,70 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const {utils: Cu} = Components; + +const {truncate} = Cu.import("chrome://marionette/content/format.js", {}); + +const MAX_STRING_LENGTH = 250; +const HALF = "x".repeat(MAX_STRING_LENGTH / 2); + +add_test(function test_truncate_empty() { + equal(truncate``, ""); + run_next_test(); +}); + +add_test(function test_truncate_noFields() { + equal(truncate`foo bar`, "foo bar"); + run_next_test(); +}); + +add_test(function test_truncate_multipleFields() { + equal(truncate`${0}`, "0"); + equal(truncate`${1}${2}${3}`, "123"); + equal(truncate`a${1}b${2}c${3}`, "a1b2c3"); + run_next_test(); +}); + +add_test(function test_truncate_primitiveFields() { + equal(truncate`${123}`, "123"); + equal(truncate`${true}`, "true"); + equal(truncate`${null}`, ""); + equal(truncate`${undefined}`, ""); + run_next_test(); +}); + +add_test(function test_truncate_string() { + equal(truncate`${"foo"}`, "foo"); + equal(truncate`${"x".repeat(250)}`, "x".repeat(250)); + equal(truncate`${"x".repeat(260)}`, `${HALF} ... ${HALF}`); + run_next_test(); +}); + +add_test(function test_truncate_array() { + equal(truncate`${["foo"]}`, JSON.stringify(["foo"])); + equal(truncate`${"foo"} ${["bar"]}`, `foo ${JSON.stringify(["bar"])}`); + equal(truncate`${["x".repeat(260)]}`, JSON.stringify([`${HALF} ... ${HALF}`])); + + run_next_test(); +}); + +add_test(function test_truncate_object() { + equal(truncate`${{}}`, JSON.stringify({})); + equal(truncate`${{foo: "bar"}}`, JSON.stringify({foo: "bar"})); + equal(truncate`${{foo: "x".repeat(260)}}`, JSON.stringify({foo: `${HALF} ... ${HALF}`})); + equal(truncate`${{foo: ["bar"]}}`, JSON.stringify({foo: ["bar"]})); + equal(truncate`${{foo: ["bar", {baz: 42}]}}`, JSON.stringify({foo: ["bar", {baz: 42}]})); + + let complex = { + toString() { return "hello world"; } + }; + equal(truncate`${complex}`, "hello world"); + + let longComplex = { + toString() { return "x".repeat(260); } + }; + equal(truncate`${longComplex}`, `${HALF} ... ${HALF}`); + + run_next_test(); +});
--- a/testing/marionette/unit.ini +++ b/testing/marionette/unit.ini @@ -8,12 +8,13 @@ skip-if = appname == "thunderbird" [test_action.js] [test_assert.js] [test_cookie.js] [test_dom.js] [test_element.js] [test_error.js] +[test_format.js] [test_message.js] [test_navigate.js] [test_session.js] [test_sync.js]