From e74672d71d9993046e8a3ceafccba6a2d7fbb21f Mon Sep 17 00:00:00 2001 From: Julien Mougenot Date: Thu, 15 Jun 2023 13:30:28 +0000 Subject: [PATCH] [REF] web,*: Centralize shallowEqual Before this commit, 2 implementations of a "shallowEqual" function coexisted, one in 'web/core/utils/objects.js' and another in 'web/core/utils/arrays.js'. This commit only keeps the one in objects.js and makes the other simply import and export it as well (easier to maintain while also easier to find for those who want to work with arrays), while also taking an optional comparison function argument in case the comparison needs to be more specific (e.g. compare DateTime objects). Part-of: odoo/odoo#125039 --- addons/web/static/src/core/utils/arrays.js | 21 +++---------------- addons/web/static/src/core/utils/objects.js | 14 ++++++++----- .../static/tests/core/utils/objects_tests.js | 9 ++++++++ 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/addons/web/static/src/core/utils/arrays.js b/addons/web/static/src/core/utils/arrays.js index 4bfaed52623..009007a51f9 100644 --- a/addons/web/static/src/core/utils/arrays.js +++ b/addons/web/static/src/core/utils/arrays.js @@ -1,5 +1,7 @@ /** @odoo-module **/ +import { shallowEqual as _shallowEqual } from "./objects"; + /** * 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. @@ -165,24 +167,7 @@ export function cartesian() { } } -/** - * Shallow compares two arrays. - * @template T - * @param {T[]} arrayA - * @param {T[]} arrayB - * @returns {boolean} true iff arrayA and arrayB are shallow equal - */ -export function shallowEqual(arrayA, arrayB) { - if (arrayA.length !== arrayB.length) { - return false; - } - for (let i = 0; i < arrayA.length; i++) { - if (arrayA[i] !== arrayB[i]) { - return false; - } - } - return true; -} +export const shallowEqual = _shallowEqual; /** * Returns all initial sections of a given array, e.g. for [1, 2] the array diff --git a/addons/web/static/src/core/utils/objects.js b/addons/web/static/src/core/utils/objects.js index fbf4cd1b634..20a5a0624c8 100644 --- a/addons/web/static/src/core/utils/objects.js +++ b/addons/web/static/src/core/utils/objects.js @@ -3,15 +3,19 @@ /** * Shallow compares two objects. * - * @param {Record} obj1 - * @param {Record} obj2 - * @returns {boolean} + * @template {unknown} T + * @param {T} obj1 + * @param {T} obj2 + * @param {(a: T[keyof T], b: T[keyof T]) => boolean} [comparisonFn] */ -export function shallowEqual(obj1, obj2) { +export function shallowEqual(obj1, obj2, comparisonFn = (a, b) => a === b) { + if (!obj1 || !obj2 || typeof obj1 !== "object" || typeof obj2 !== "object") { + return obj1 === obj2; + } const obj1Keys = Object.keys(obj1); return ( obj1Keys.length === Object.keys(obj2).length && - obj1Keys.every((key) => obj1[key] === obj2[key]) + obj1Keys.every((key) => comparisonFn(obj1[key], obj2[key])) ); } diff --git a/addons/web/static/tests/core/utils/objects_tests.js b/addons/web/static/tests/core/utils/objects_tests.js index 64ef3277fd0..00c920f2edd 100644 --- a/addons/web/static/tests/core/utils/objects_tests.js +++ b/addons/web/static/tests/core/utils/objects_tests.js @@ -57,4 +57,13 @@ QUnit.module("utils", () => { assert.ok(shallowEqual({ a: fn }, { a: fn })); assert.notOk(shallowEqual({ a: () => {} }, { a: () => {} })); }); + + QUnit.test("shallowEqual: custom comparison function", function (assert) { + assert.notOk(shallowEqual({ a: 1, date: new Date() }, { a: 1, date: new Date() })); + assert.ok( + shallowEqual({ a: 1, date: new Date() }, { a: 1, date: new Date() }, (a, b) => + a instanceof Date ? Number(a) === Number(b) : a === b + ) + ); + }); });