summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Mougenot <jum@odoo.com>2020-07-13 13:03:23 +0000
committerMathieu Duckerts-Antoine <dam@odoo.com>2020-07-23 08:21:09 +0000
commit5698d1fab9cf36714f677ae6942201d5c9354798 (patch)
treef6f9c7e70f34adb4a3c375f42700804702aa664c
parentea1741bc743b2066e871b526fc0d7cbf30b08fef (diff)
[IMP] web: add Registry predicate
Before this commit, any value could be added to registries and the class needed to be overridden to assert that added values would answer to a certain predicate. Now, the registry can be instantiated with a given predicate function that all added value must pass to be registered (default: all values are accepted). Existing implentations have been adapted: - FieldRegistry - FieldRegistryOwl.
-rw-r--r--addons/web/static/src/js/core/registry.js13
-rw-r--r--addons/web/static/src/js/fields/field_registry.js18
-rw-r--r--addons/web/static/src/js/fields/field_registry_owl.js14
-rw-r--r--addons/web/static/tests/core/registry_tests.js15
4 files changed, 37 insertions, 23 deletions
diff --git a/addons/web/static/src/js/core/registry.js b/addons/web/static/src/js/core/registry.js
index 7b2c69db180..1ab16236e59 100644
--- a/addons/web/static/src/js/core/registry.js
+++ b/addons/web/static/src/js/core/registry.js
@@ -20,13 +20,21 @@ odoo.define("web.Registry", function (require) {
*/
class Registry {
/**
+ * @function predicate
+ * @param {any} value
+ * @returns {boolean}
+ */
+ /**
* @param {Object} [mapping] the initial data in the registry
+ * @param {predicate} [predicate=(() => true)] predicate that each
+ * added value must pass to be registered.
*/
- constructor(mapping) {
+ constructor(mapping, predicate = () => true) {
this.map = Object.create(mapping || null);
this._scoreMapping = Object.create(null);
this._sortedKeys = null;
this.listeners = []; // listening callbacks on newly added items.
+ this.predicate = predicate;
}
//--------------------------------------------------------------------------
@@ -42,6 +50,9 @@ odoo.define("web.Registry", function (require) {
* @returns {Registry} can be used to chain add calls.
*/
add(key, value, score) {
+ if (!this.predicate(value)) {
+ throw new Error(`Value of key "${key}" does not pass the addition predicate.`);
+ }
this._scoreMapping[key] = score === undefined ? key : score;
this._sortedKeys = null;
this.map[key] = value;
diff --git a/addons/web/static/src/js/fields/field_registry.js b/addons/web/static/src/js/fields/field_registry.js
index 925b405051e..ef174702579 100644
--- a/addons/web/static/src/js/fields/field_registry.js
+++ b/addons/web/static/src/js/fields/field_registry.js
@@ -1,18 +1,12 @@
odoo.define('web.field_registry', function (require) {
-"use strict";
-
-var Registry = require('web.Registry');
+ "use strict";
-var FieldRegistry = Registry.extend({
- add: function (key, value, score) {
- if (value.prototype instanceof owl.Component) {
- throw new Error("This registry should not contain any Component. Use 'web.field_registry_owl' instead.");
- }
- return this._super(...arguments);
- },
-});
+ const Registry = require('web.Registry');
-return new FieldRegistry();
+ return new Registry(
+ null,
+ (value) => !(value.prototype instanceof owl.Component)
+ );
});
odoo.define('web._field_registry', function (require) {
diff --git a/addons/web/static/src/js/fields/field_registry_owl.js b/addons/web/static/src/js/fields/field_registry_owl.js
index 907ea38a9d7..635db621829 100644
--- a/addons/web/static/src/js/fields/field_registry_owl.js
+++ b/addons/web/static/src/js/fields/field_registry_owl.js
@@ -3,16 +3,10 @@ odoo.define('web.field_registry_owl', function (require) {
const Registry = require('web.Registry');
- const FieldRegistry = Registry.extend({
- add: function (key, value, score) {
- if (!(value.prototype instanceof owl.Component)) {
- throw new Error("This registry should only contain subclasses of Component");
- }
- return this._super(...arguments);
- },
- });
-
- return new FieldRegistry();
+ return new Registry(
+ null,
+ (value) => value.prototype instanceof owl.Component
+ );
});
odoo.define('web._field_registry_owl', function (require) {
diff --git a/addons/web/static/tests/core/registry_tests.js b/addons/web/static/tests/core/registry_tests.js
index 9f9f7b467cb..eb3389a4383 100644
--- a/addons/web/static/tests/core/registry_tests.js
+++ b/addons/web/static/tests/core/registry_tests.js
@@ -70,6 +70,21 @@ QUnit.module('core', {}, function () {
assert.deepEqual(registry.values(), ['bar', 'foo', 'qux']);
});
+ QUnit.test("predicate prevents invalid values", function (assert) {
+ assert.expect(5);
+
+ const predicate = value => typeof value === "number";
+ const registry = new Registry(null, predicate);
+ registry.onAdd((key) => assert.step(key));
+
+ assert.ok(registry.add("age", 23));
+ assert.throws(
+ () => registry.add("name", "Fred"),
+ new Error(`Value of key "name" does not pass the addition predicate.`)
+ );
+ assert.deepEqual(registry.entries(), { age: 23 });
+ assert.verifySteps(["age"]);
+ });
});
});