summaryrefslogtreecommitdiff
path: root/addons/web
diff options
context:
space:
mode:
authorMathieu Duckerts-Antoine <dam@odoo.com>2019-04-23 15:05:27 +0000
committerMathieu Duckerts-Antoine <dam@odoo.com>2019-08-02 18:34:18 +0000
commit5894df57d34c8d9d41db9bf901502d42dac9d884 (patch)
treeef999088a48b8b0f2f846c84f304939cdccaea1a /addons/web
parente488f208d21b7cff86d22ac12e894d953ad65943 (diff)
[IMP] web: add math_utils to core
math_utils is a small library that exports two functions: - cartesian: allows to compute the cartesian products of any numbers of arrays while preserving the internal structures of their elements. - sections: returns an array with all the initial sections of the array passed as parameter.
Diffstat (limited to 'addons/web')
-rw-r--r--addons/web/static/src/js/core/math_utils.js73
-rw-r--r--addons/web/static/tests/core/math_utils_tests.js56
-rw-r--r--addons/web/views/webclient_templates.xml2
3 files changed, 131 insertions, 0 deletions
diff --git a/addons/web/static/src/js/core/math_utils.js b/addons/web/static/src/js/core/math_utils.js
new file mode 100644
index 00000000000..0eeb631125b
--- /dev/null
+++ b/addons/web/static/src/js/core/math_utils.js
@@ -0,0 +1,73 @@
+odoo.define('web.mathUtils', function () {
+"use strict";
+
+/**
+ * Same values returned as those returned by cartesian function for case n = 0
+ * and n > 1. For n = 1, brackets are put around the unique parameter elements.
+ *
+ * @returns {Array}
+ */
+function _cartesian() {
+ var args = Array.prototype.slice.call(arguments);
+ if (args.length === 0) {
+ return [undefined];
+ }
+ var firstArray = args[0].map(function (elem) {
+ return [elem];
+ });
+ if (args.length === 1) {
+ return firstArray;
+ }
+ var productOfOtherArrays = _cartesian.apply(null, args.slice(1));
+ var result = firstArray.reduce(
+ function (acc, elem) {
+ return acc.concat(productOfOtherArrays.map(function (tuple) {
+ return elem.concat(tuple);
+ }));
+ },
+ []
+ );
+ return result;
+}
+
+/**
+ * Returns the product of any number n of arrays.
+ * The internal structures of their elements is preserved.
+ * For n = 1, no brackets are put around the unique parameter elements
+ * For n = 0, the singleton [undefined] is returned since it is the unit
+ * of the cartesian product (up to isomorphism).
+ *
+ * @returns {Array}
+ */
+function cartesian() {
+ var args = Array.prototype.slice.call(arguments);
+ if (args.length === 0) {
+ return [undefined];
+ } else if (args.length === 1) {
+ return args[0];
+ } else {
+ return _cartesian.apply(null, args);
+ }
+}
+
+/**
+ * Returns all initial sections of a given array, e.g. for [1, 2] the array
+ * [[], [1], [1, 2]] is returned.
+ *
+ * @param {Array} array
+ * @returns {Array[]}
+ */
+function sections(array) {
+ var sections = [];
+ for (var i = 0; i < array.length + 1; i++) {
+ sections.push(array.slice(0, i));
+ }
+ return sections;
+}
+
+return {
+ cartesian: cartesian,
+ sections: sections,
+};
+
+});
diff --git a/addons/web/static/tests/core/math_utils_tests.js b/addons/web/static/tests/core/math_utils_tests.js
new file mode 100644
index 00000000000..894cb0be4f7
--- /dev/null
+++ b/addons/web/static/tests/core/math_utils_tests.js
@@ -0,0 +1,56 @@
+odoo.define('web.math_utils_tests', function(require) {
+"use strict";
+
+var mathUtils = require('web.mathUtils');
+var cartesian = mathUtils.cartesian;
+
+QUnit.module('mathUtils', function () {
+
+ QUnit.module('cartesian');
+
+
+ QUnit.test('cartesian product of zero arrays', function(assert) {
+ assert.expect(1);
+ assert.deepEqual(cartesian(), [undefined],
+ "the unit of the product is a singleton");
+ });
+
+ QUnit.test('cartesian product of a single array', function(assert) {
+ assert.expect(5);
+ assert.deepEqual(cartesian([]), []);
+ assert.deepEqual(cartesian([1]), [1],
+ "we don't want unecessary brackets");
+ assert.deepEqual(cartesian([1, 2]), [1, 2]);
+ assert.deepEqual(cartesian([[1, 2]]), [[1, 2]],
+ "the internal structure of elements should be preserved");
+ assert.deepEqual(cartesian([[1, 2], [3, [2]]]), [[1, 2], [3, [2]]],
+ "the internal structure of elements should be preserved");
+ });
+
+ QUnit.test('cartesian product of two arrays', function(assert) {
+ assert.expect(5);
+ assert.deepEqual(cartesian([], []), []);
+ assert.deepEqual(cartesian([1], []), []);
+ assert.deepEqual(cartesian([1], [2]), [[1, 2]]);
+ assert.deepEqual(cartesian([1, 2], [3]), [[1, 3], [2, 3]]);
+ assert.deepEqual(cartesian([[1], 4], [2, [3]]), [[[1], 2], [[1], [3]], [4, 2], [4, [3]] ],
+ "the internal structure of elements should be preserved");
+ });
+
+ QUnit.test('cartesian product of three arrays', function(assert) {
+ assert.expect(4);
+ assert.deepEqual(cartesian([], [], []), []);
+ assert.deepEqual(cartesian([1], [], [2, 5]), []);
+ assert.deepEqual(cartesian([1], [2], [3]), [[1, 2, 3]],
+ "we should have no unecessary brackets, we want elements to be 'triples'");
+ assert.deepEqual(cartesian([[1], 2], [3], [4]), [[[1], 3, 4], [2, 3, 4]],
+ "the internal structure of elements should be preserved");
+ });
+
+ QUnit.test('cartesian product of four arrays', function(assert) {
+ assert.expect(1);
+ assert.deepEqual(cartesian([1], [2], [3], [4]), [[1, 2, 3, 4]]);
+ });
+
+});
+}); \ No newline at end of file
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 2c9000ec0ff..65f29206eb2 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -250,6 +250,7 @@
<script type="text/javascript" src="/web/static/src/js/_deprecated/data.js"></script>
<script type="text/javascript" src="/web/static/src/js/core/context.js"></script>
<script type="text/javascript" src="/web/static/src/js/core/data_comparison_utils.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/core/math_utils.js"></script>
<script type="text/javascript" src="/web/static/src/js/core/misc.js"></script>
<script type="text/javascript" src="/web/static/src/js/services/crash_manager_service.js"></script>
<script type="text/javascript" src="/web/static/src/js/services/data_manager.js"></script>
@@ -664,6 +665,7 @@
<script type="text/javascript" src="/web/static/tests/core/rpc_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/core/domain_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/core/data_comparison_utils_tests.js"></script>
+ <script type="text/javascript" src="/web/static/tests/core/math_utils_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/core/mixins_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/core/time_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/core/concurrency_tests.js"></script>