From 1a7120c30328adf878c4e8d67f4eb0cd3349baa2 Mon Sep 17 00:00:00 2001 From: Aliullov Vlad Date: Fri, 30 Aug 2024 12:40:01 +0400 Subject: [PATCH] Fix filtering issues for string in different locales (T1242756) --- .../js/__internal/data/m_array_query.ts | 2 +- packages/devextreme/js/core/utils/data.js | 26 ++++++++++++------- .../tests/DevExpress.data/queryArray.tests.js | 11 ++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/packages/devextreme/js/__internal/data/m_array_query.ts b/packages/devextreme/js/__internal/data/m_array_query.ts index b308ee8a8fe7..cdb326386a0f 100644 --- a/packages/devextreme/js/__internal/data/m_array_query.ts +++ b/packages/devextreme/js/__internal/data/m_array_query.ts @@ -249,7 +249,7 @@ const SortIterator = Iterator.inherit({ const compileCriteria = (function () { let langParams = {}; // eslint-disable-next-line @typescript-eslint/naming-convention - const _toComparable = (value) => toComparable(value, false, langParams); + const _toComparable = (value) => toComparable(value, false, langParams, { useUpperCase: true }); const compileUniformEqualsCriteria = (crit) => { const getter = compileGetter(crit[0][0]); diff --git a/packages/devextreme/js/core/utils/data.js b/packages/devextreme/js/core/utils/data.js index 11fb29ec699d..6ae61e02f3b1 100644 --- a/packages/devextreme/js/core/utils/data.js +++ b/packages/devextreme/js/core/utils/data.js @@ -138,6 +138,14 @@ function combineGetters(getters) { }; } +function toLowerCase(value, options) { + return options?.locale ? value.toLocaleLowerCase(options.locale) : value.toLowerCase(); +} + +function toUpperCase(value, options) { + return options?.locale ? value.toLocaleUpperCase(options.locale) : value.toUpperCase(); +} + const ensurePropValueDefined = function(obj, propName, value, options) { if(isDefined(value)) { return value; @@ -181,27 +189,27 @@ export const compileSetter = function(expr) { }; }; -export const toComparable = function(value, caseSensitive, options = {}) { +export const toComparable = function(value, caseSensitive, langParams = {}, options = { useUpperCase: false }) { if(value instanceof Date) { return value.getTime(); } - if(value && value instanceof Class && value.valueOf) { - return value.valueOf(); - } + const collatorSensitivity = langParams?.collatorOptions?.sensitivity; - const collatorSensitivity = options?.collatorOptions?.sensitivity; - - if(typeof value === 'string' && collatorSensitivity === 'base') { + if(value && value instanceof Class && value.valueOf) { + value = value.valueOf(); + } else if(typeof value === 'string' && collatorSensitivity === 'base') { const REMOVE_DIACRITICAL_MARKS_REGEXP = /[\u0300-\u036f]/g; value = value.normalize('NFD').replace(REMOVE_DIACRITICAL_MARKS_REGEXP, ''); } - const isCaseSensitive = collatorSensitivity === 'case' || caseSensitive; + const isCaseSensitive = caseSensitive || collatorSensitivity === 'case'; if(typeof value === 'string' && !isCaseSensitive) { - return options?.locale ? value.toLocaleUpperCase(options.locale) : value.toUpperCase(); + return options?.useUpperCase ? + toUpperCase(value, langParams) + : toLowerCase(value, langParams); } return value; diff --git a/packages/devextreme/testing/tests/DevExpress.data/queryArray.tests.js b/packages/devextreme/testing/tests/DevExpress.data/queryArray.tests.js index 0ecda45083af..611142c0bf4b 100644 --- a/packages/devextreme/testing/tests/DevExpress.data/queryArray.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.data/queryArray.tests.js @@ -430,6 +430,17 @@ QUnit.test('filtering use correct case insensitivity search', function(assert) { assert.false(containsUnwantedValue); }); +QUnit.test('filtering use correct case insensitivity search for AM locale', function(assert) { + const input = [ + { ID: 1, Name: 'ԵՐԵՒԱՆ' }, + { ID: 2, Name: 'Երևան' }, + ]; + + const arrayStartsWith = QUERY(input).filter(['Name', 'startswith', 'Երև']).toArray(); + + assert.equal(arrayStartsWith.length, 2); +}); + QUnit.test('missing operation means equal', function(assert) { assert.expect(1);