From b5d4175e189240d6305e55ce84e76a2f20343053 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Fri, 23 Feb 2024 11:44:25 +0100 Subject: [PATCH 1/9] start migrating the files --- tests/unit/{LocalizeTests.js => LocalizeTests.ts} | 0 tests/unit/{TranslateTest.js => TranslateTest.ts} | 4 +++- ...ployTest.js => createOrUpdateStagingDeployTest.ts} | 11 +++++++---- ...anceParametersTest.js => enhanceParametersTest.ts} | 1 + ...sionUpdaterTest.js => nativeVersionUpdaterTest.ts} | 0 5 files changed, 11 insertions(+), 5 deletions(-) rename tests/unit/{LocalizeTests.js => LocalizeTests.ts} (100%) rename tests/unit/{TranslateTest.js => TranslateTest.ts} (96%) rename tests/unit/{createOrUpdateStagingDeployTest.js => createOrUpdateStagingDeployTest.ts} (98%) rename tests/unit/{enhanceParametersTest.js => enhanceParametersTest.ts} (96%) rename tests/unit/{nativeVersionUpdaterTest.js => nativeVersionUpdaterTest.ts} (100%) diff --git a/tests/unit/LocalizeTests.js b/tests/unit/LocalizeTests.ts similarity index 100% rename from tests/unit/LocalizeTests.js rename to tests/unit/LocalizeTests.ts diff --git a/tests/unit/TranslateTest.js b/tests/unit/TranslateTest.ts similarity index 96% rename from tests/unit/TranslateTest.js rename to tests/unit/TranslateTest.ts index d23fa52fc798..fd3c4f474e88 100644 --- a/tests/unit/TranslateTest.js +++ b/tests/unit/TranslateTest.ts @@ -1,8 +1,10 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import {AnnotationError} from '@actions/core'; import _ from 'underscore'; +import * as translations from '@src/languages/translations'; import CONFIG from '../../src/CONFIG'; import CONST from '../../src/CONST'; -import * as translations from '../../src/languages/translations'; +// import * as translations from '../../src/languages/translations'; import * as Localize from '../../src/libs/Localize'; const originalTranslations = _.clone(translations); diff --git a/tests/unit/createOrUpdateStagingDeployTest.js b/tests/unit/createOrUpdateStagingDeployTest.ts similarity index 98% rename from tests/unit/createOrUpdateStagingDeployTest.js rename to tests/unit/createOrUpdateStagingDeployTest.ts index 75600f0d4fc8..28daf8c1674d 100644 --- a/tests/unit/createOrUpdateStagingDeployTest.js +++ b/tests/unit/createOrUpdateStagingDeployTest.ts @@ -1,7 +1,8 @@ /** * @jest-environment node */ -import * as core from '@actions/core'; + +/* eslint-disable @typescript-eslint/naming-convention */ import * as fns from 'date-fns'; import {vol} from 'memfs'; import path from 'path'; @@ -19,7 +20,9 @@ const mockGetPullRequestsMergedBetween = jest.fn(); beforeAll(() => { // Mock core module - core.getInput = mockGetInput; + jest.mock('@actions/core', () => ({ + getInput: mockGetInput, + })); // Mock octokit module const moctokit = { @@ -295,7 +298,7 @@ describe('createOrUpdateStagingDeployCash', () => { owner: CONST.GITHUB_OWNER, repo: CONST.APP_REPO, issue_number: openStagingDeployCashBefore.number, - // eslint-disable-next-line max-len + // eslint-disable-next-line max-len, @typescript-eslint/naming-convention html_url: `https://github.com/Expensify/App/issues/${openStagingDeployCashBefore.number}`, // eslint-disable-next-line max-len body: @@ -371,7 +374,7 @@ describe('createOrUpdateStagingDeployCash', () => { owner: CONST.GITHUB_OWNER, repo: CONST.APP_REPO, issue_number: openStagingDeployCashBefore.number, - // eslint-disable-next-line max-len + // eslint-disable-next-line max-len, @typescript-eslint/naming-convention html_url: `https://github.com/Expensify/App/issues/${openStagingDeployCashBefore.number}`, // eslint-disable-next-line max-len body: diff --git a/tests/unit/enhanceParametersTest.js b/tests/unit/enhanceParametersTest.ts similarity index 96% rename from tests/unit/enhanceParametersTest.js rename to tests/unit/enhanceParametersTest.ts index 6829732f1633..bf2756767401 100644 --- a/tests/unit/enhanceParametersTest.js +++ b/tests/unit/enhanceParametersTest.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import Onyx from 'react-native-onyx'; import CONFIG from '../../src/CONFIG'; import enhanceParameters from '../../src/libs/Network/enhanceParameters'; diff --git a/tests/unit/nativeVersionUpdaterTest.js b/tests/unit/nativeVersionUpdaterTest.ts similarity index 100% rename from tests/unit/nativeVersionUpdaterTest.js rename to tests/unit/nativeVersionUpdaterTest.ts From 7338370938dd1736eeae0c54c6a34ffda5d41b59 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 26 Feb 2024 09:22:28 +0100 Subject: [PATCH 2/9] finish migrating createOrUpdateStagingDeployTest to TypeScript --- tests/unit/TranslateTest.ts | 1 + tests/unit/createOrUpdateStagingDeployTest.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/unit/TranslateTest.ts b/tests/unit/TranslateTest.ts index fd3c4f474e88..48baed43b448 100644 --- a/tests/unit/TranslateTest.ts +++ b/tests/unit/TranslateTest.ts @@ -2,6 +2,7 @@ import {AnnotationError} from '@actions/core'; import _ from 'underscore'; import * as translations from '@src/languages/translations'; +import {TranslationPaths} from '@src/languages/types'; import CONFIG from '../../src/CONFIG'; import CONST from '../../src/CONST'; // import * as translations from '../../src/languages/translations'; diff --git a/tests/unit/createOrUpdateStagingDeployTest.ts b/tests/unit/createOrUpdateStagingDeployTest.ts index 28daf8c1674d..38ba4942a785 100644 --- a/tests/unit/createOrUpdateStagingDeployTest.ts +++ b/tests/unit/createOrUpdateStagingDeployTest.ts @@ -52,8 +52,8 @@ beforeAll(() => { list: jest.fn().mockResolvedValue([]), }, }, - paginate: jest.fn().mockImplementation((objectMethod) => objectMethod().then(({data}) => data)), - }; + paginate: jest.fn().mockImplementation((objectMethod: () => Promise<{data: unknown}>) => objectMethod().then(({data}) => data)), + } as typeof GithubUtils.octokit; GithubUtils.internalOctokit = moctokit; // Mock GitUtils From a81d98204cddd8d01abc38ab8f46083dc7acb0b6 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 26 Feb 2024 10:39:26 +0100 Subject: [PATCH 3/9] remove lodash from TranslateTest --- tests/unit/TranslateTest.ts | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/unit/TranslateTest.ts b/tests/unit/TranslateTest.ts index 48baed43b448..cdae72466d01 100644 --- a/tests/unit/TranslateTest.ts +++ b/tests/unit/TranslateTest.ts @@ -1,14 +1,12 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {AnnotationError} from '@actions/core'; -import _ from 'underscore'; import * as translations from '@src/languages/translations'; -import {TranslationPaths} from '@src/languages/types'; +import type {TranslationFlatObject} from '@src/languages/types'; import CONFIG from '../../src/CONFIG'; import CONST from '../../src/CONST'; -// import * as translations from '../../src/languages/translations'; import * as Localize from '../../src/libs/Localize'; -const originalTranslations = _.clone(translations); +const originalTranslations = {...translations}; translations.default = { [CONST.LOCALES.EN]: translations.flattenObject({ testKey1: 'English', @@ -58,28 +56,32 @@ describe('translate', () => { }); describe('Translation Keys', () => { - function traverseKeyPath(source, path, keyPaths) { - const pathArray = keyPaths || []; + function traverseKeyPath(source: TranslationFlatObject, path?: string, keyPaths?: string[]): string[] { + const pathArray = keyPaths ?? []; const keyPath = path ? `${path}.` : ''; - _.each(_.keys(source), (key) => { - if (_.isObject(source[key]) && !_.isFunction(source[key])) { + Object.keys(source).forEach((key) => { + if (typeof source[key] === 'object' && typeof source[key] !== 'function') { traverseKeyPath(source[key], keyPath + key, pathArray); } else { pathArray.push(keyPath + key); } }); + return pathArray; } - const excludeLanguages = [CONST.LOCALES.EN, CONST.LOCALES.ES_ES]; - const languages = _.without(_.keys(originalTranslations.default), ...excludeLanguages); + function arrayDifference(array1: string[], array2: string[]): string[] { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); + } + const excludeLanguages: Array<'en' | 'es-ES'> = [CONST.LOCALES.EN, CONST.LOCALES.ES_ES]; + const languages = Object.keys(originalTranslations.default).filter((ln) => !(excludeLanguages as string[]).includes(ln)); const mainLanguage = originalTranslations.default.en; const mainLanguageKeys = traverseKeyPath(mainLanguage); - _.each(languages, (ln) => { + languages.forEach((ln) => { const languageKeys = traverseKeyPath(originalTranslations.default[ln]); it(`Does ${ln} locale have all the keys`, () => { - const hasAllKeys = _.difference(mainLanguageKeys, languageKeys); + const hasAllKeys = arrayDifference(mainLanguageKeys, languageKeys); if (hasAllKeys.length) { console.debug(`🏹 [ ${hasAllKeys.join(', ')} ] are missing from ${ln}.js`); AnnotationError(`🏹 [ ${hasAllKeys.join(', ')} ] are missing from ${ln}.js`); @@ -88,7 +90,7 @@ describe('Translation Keys', () => { }); it(`Does ${ln} locale have unused keys`, () => { - const hasAllKeys = _.difference(languageKeys, mainLanguageKeys); + const hasAllKeys = arrayDifference(languageKeys, mainLanguageKeys); if (hasAllKeys.length) { console.debug(`🏹 [ ${hasAllKeys.join(', ')} ] are unused keys in ${ln}.js`); AnnotationError(`🏹 [ ${hasAllKeys.join(', ')} ] are unused keys in ${ln}.js`); From eb5121cae49bcd46535ac57605576b8bc28ccca6 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 26 Feb 2024 15:57:51 +0100 Subject: [PATCH 4/9] type casting in TranslateTest --- tests/unit/TranslateTest.ts | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/unit/TranslateTest.ts b/tests/unit/TranslateTest.ts index cdae72466d01..6268410a2a1a 100644 --- a/tests/unit/TranslateTest.ts +++ b/tests/unit/TranslateTest.ts @@ -1,12 +1,13 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import {AnnotationError} from '@actions/core'; import * as translations from '@src/languages/translations'; -import type {TranslationFlatObject} from '@src/languages/types'; +import type {TranslationFlatObject, TranslationPaths} from '@src/languages/types'; import CONFIG from '../../src/CONFIG'; import CONST from '../../src/CONST'; import * as Localize from '../../src/libs/Localize'; const originalTranslations = {...translations}; + +// @ts-expect-error - We are modifying the translations object for testing purposes translations.default = { [CONST.LOCALES.EN]: translations.flattenObject({ testKey1: 'English', @@ -25,33 +26,36 @@ translations.default = { describe('translate', () => { it('Test present key in full locale', () => { - expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey1')).toBe('Spanish ES'); + expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey1' as TranslationPaths)).toBe('Spanish ES'); }); it('Test when key is not found in full locale, but present in language', () => { - expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey2')).toBe('Spanish Word 2'); - expect(Localize.translate(CONST.LOCALES.ES, 'testKey2')).toBe('Spanish Word 2'); + expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey2' as TranslationPaths)).toBe('Spanish Word 2'); + expect(Localize.translate(CONST.LOCALES.ES, 'testKey2' as TranslationPaths)).toBe('Spanish Word 2'); }); it('Test when key is not found in full locale and language, but present in default', () => { - expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey3')).toBe('Test Word 3'); + expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey3' as TranslationPaths)).toBe('Test Word 3'); }); test('Test when key is not found in default', () => { - expect(() => Localize.translate(CONST.LOCALES.ES_ES, 'testKey4')).toThrow(Error); + expect(() => Localize.translate(CONST.LOCALES.ES_ES, 'testKey4' as TranslationPaths)).toThrow(Error); }); test('Test when key is not found in default (Production Mode)', () => { const ORIGINAL_IS_IN_PRODUCTION = CONFIG.IS_IN_PRODUCTION; + // @ts-expect-error - We are modifying the CONFIG object for testing purposes CONFIG.IS_IN_PRODUCTION = true; - expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey4')).toBe('testKey4'); + expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey4' as TranslationPaths)).toBe('testKey4'); + // @ts-expect-error - We are modifying the CONFIG object for testing purposes CONFIG.IS_IN_PRODUCTION = ORIGINAL_IS_IN_PRODUCTION; }); it('Test when translation value is a function', () => { const expectedValue = 'With variable Test Variable'; const testVariable = 'Test Variable'; - expect(Localize.translate(CONST.LOCALES.EN, 'testKeyGroup.testFunction', {testVariable})).toBe(expectedValue); + // @ts-expect-error - We are modifying the translations object for testing purposes + expect(Localize.translate(CONST.LOCALES.EN, 'testKeyGroup.testFunction' as TranslationPaths, {testVariable})).toBe(expectedValue); }); }); @@ -60,7 +64,7 @@ describe('Translation Keys', () => { const pathArray = keyPaths ?? []; const keyPath = path ? `${path}.` : ''; Object.keys(source).forEach((key) => { - if (typeof source[key] === 'object' && typeof source[key] !== 'function') { + if (typeof source[key as keyof TranslationFlatObject] === 'object' && typeof source[key as keyof TranslationFlatObject] !== 'function') { traverseKeyPath(source[key], keyPath + key, pathArray); } else { pathArray.push(keyPath + key); @@ -78,13 +82,13 @@ describe('Translation Keys', () => { const mainLanguageKeys = traverseKeyPath(mainLanguage); languages.forEach((ln) => { - const languageKeys = traverseKeyPath(originalTranslations.default[ln]); + const languageKeys = traverseKeyPath(originalTranslations.default[ln as keyof typeof originalTranslations.default]); it(`Does ${ln} locale have all the keys`, () => { const hasAllKeys = arrayDifference(mainLanguageKeys, languageKeys); if (hasAllKeys.length) { console.debug(`🏹 [ ${hasAllKeys.join(', ')} ] are missing from ${ln}.js`); - AnnotationError(`🏹 [ ${hasAllKeys.join(', ')} ] are missing from ${ln}.js`); + Error(`🏹 [ ${hasAllKeys.join(', ')} ] are missing from ${ln}.js`); } expect(hasAllKeys).toEqual([]); }); @@ -93,7 +97,7 @@ describe('Translation Keys', () => { const hasAllKeys = arrayDifference(languageKeys, mainLanguageKeys); if (hasAllKeys.length) { console.debug(`🏹 [ ${hasAllKeys.join(', ')} ] are unused keys in ${ln}.js`); - AnnotationError(`🏹 [ ${hasAllKeys.join(', ')} ] are unused keys in ${ln}.js`); + Error(`🏹 [ ${hasAllKeys.join(', ')} ] are unused keys in ${ln}.js`); } expect(hasAllKeys).toEqual([]); }); @@ -102,7 +106,7 @@ describe('Translation Keys', () => { describe('flattenObject', () => { it('It should work correctly', () => { - const func = ({content}) => `This is the content: ${content}`; + const func = ({content}: {content: string}) => `This is the content: ${content}`; const simpleObject = { common: { yes: 'Yes', From 99fcce89f5e0536b4b45aba52cac322853f95790 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 26 Feb 2024 16:12:08 +0100 Subject: [PATCH 5/9] migrate TranslateTest to TypeScript --- tests/unit/TranslateTest.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/TranslateTest.ts b/tests/unit/TranslateTest.ts index 6268410a2a1a..ab7241ede42a 100644 --- a/tests/unit/TranslateTest.ts +++ b/tests/unit/TranslateTest.ts @@ -65,6 +65,7 @@ describe('Translation Keys', () => { const keyPath = path ? `${path}.` : ''; Object.keys(source).forEach((key) => { if (typeof source[key as keyof TranslationFlatObject] === 'object' && typeof source[key as keyof TranslationFlatObject] !== 'function') { + // @ts-expect-error - We are modifying the translations object for testing purposes traverseKeyPath(source[key], keyPath + key, pathArray); } else { pathArray.push(keyPath + key); From 128debb2d3f9d8b3dff276fb56efdb5ed793fafd Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Tue, 27 Feb 2024 15:22:24 +0100 Subject: [PATCH 6/9] apply suggested changes --- src/types/utils/asMutable.ts | 5 +++++ tests/unit/TranslateTest.ts | 35 +++++++++++++++++----------------- tests/utils/arrayDifference.ts | 5 +++++ 3 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 src/types/utils/asMutable.ts create mode 100644 tests/utils/arrayDifference.ts diff --git a/src/types/utils/asMutable.ts b/src/types/utils/asMutable.ts new file mode 100644 index 000000000000..57c49058cd14 --- /dev/null +++ b/src/types/utils/asMutable.ts @@ -0,0 +1,5 @@ +import type {Writable} from 'type-fest'; + +const asMutable = (value: T): Writable => value as Writable; + +export default asMutable; diff --git a/tests/unit/TranslateTest.ts b/tests/unit/TranslateTest.ts index ab7241ede42a..40ece1d7525e 100644 --- a/tests/unit/TranslateTest.ts +++ b/tests/unit/TranslateTest.ts @@ -1,14 +1,15 @@ /* eslint-disable @typescript-eslint/naming-convention */ +import CONFIG from '@src/CONFIG'; +import CONST from '@src/CONST'; import * as translations from '@src/languages/translations'; import type {TranslationFlatObject, TranslationPaths} from '@src/languages/types'; -import CONFIG from '../../src/CONFIG'; -import CONST from '../../src/CONST'; -import * as Localize from '../../src/libs/Localize'; +import * as Localize from '@src/libs/Localize'; +import asMutable from '@src/types/utils/asMutable'; +import arrayDifference from '../utils/arrayDifference'; const originalTranslations = {...translations}; -// @ts-expect-error - We are modifying the translations object for testing purposes -translations.default = { +asMutable(translations).default = { [CONST.LOCALES.EN]: translations.flattenObject({ testKey1: 'English', testKey2: 'Test Word 2', @@ -44,17 +45,15 @@ describe('translate', () => { test('Test when key is not found in default (Production Mode)', () => { const ORIGINAL_IS_IN_PRODUCTION = CONFIG.IS_IN_PRODUCTION; - // @ts-expect-error - We are modifying the CONFIG object for testing purposes - CONFIG.IS_IN_PRODUCTION = true; + asMutable(CONFIG).IS_IN_PRODUCTION = true; expect(Localize.translate(CONST.LOCALES.ES_ES, 'testKey4' as TranslationPaths)).toBe('testKey4'); - // @ts-expect-error - We are modifying the CONFIG object for testing purposes - CONFIG.IS_IN_PRODUCTION = ORIGINAL_IS_IN_PRODUCTION; + asMutable(CONFIG).IS_IN_PRODUCTION = ORIGINAL_IS_IN_PRODUCTION; }); it('Test when translation value is a function', () => { const expectedValue = 'With variable Test Variable'; const testVariable = 'Test Variable'; - // @ts-expect-error - We are modifying the translations object for testing purposes + // @ts-expect-error - TranslationPaths doesn't include testKeyGroup.testFunction as a valid key expect(Localize.translate(CONST.LOCALES.EN, 'testKeyGroup.testFunction' as TranslationPaths, {testVariable})).toBe(expectedValue); }); }); @@ -63,8 +62,8 @@ describe('Translation Keys', () => { function traverseKeyPath(source: TranslationFlatObject, path?: string, keyPaths?: string[]): string[] { const pathArray = keyPaths ?? []; const keyPath = path ? `${path}.` : ''; - Object.keys(source).forEach((key) => { - if (typeof source[key as keyof TranslationFlatObject] === 'object' && typeof source[key as keyof TranslationFlatObject] !== 'function') { + (Object.keys(source) as Array).forEach((key) => { + if (typeof source[key] === 'object' && typeof source[key] !== 'function') { // @ts-expect-error - We are modifying the translations object for testing purposes traverseKeyPath(source[key], keyPath + key, pathArray); } else { @@ -74,11 +73,9 @@ describe('Translation Keys', () => { return pathArray; } - function arrayDifference(array1: string[], array2: string[]): string[] { - return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); - } - const excludeLanguages: Array<'en' | 'es-ES'> = [CONST.LOCALES.EN, CONST.LOCALES.ES_ES]; - const languages = Object.keys(originalTranslations.default).filter((ln) => !(excludeLanguages as string[]).includes(ln)); + + const excludeLanguages = [CONST.LOCALES.EN, CONST.LOCALES.ES_ES]; + const languages = Object.keys(originalTranslations.default).filter((ln) => !excludeLanguages.some((excludeLanguage) => excludeLanguage === ln)); const mainLanguage = originalTranslations.default.en; const mainLanguageKeys = traverseKeyPath(mainLanguage); @@ -105,9 +102,11 @@ describe('Translation Keys', () => { }); }); +type ReportContentArgs = {content: string}; + describe('flattenObject', () => { it('It should work correctly', () => { - const func = ({content}: {content: string}) => `This is the content: ${content}`; + const func = ({content}: ReportContentArgs) => `This is the content: ${content}`; const simpleObject = { common: { yes: 'Yes', diff --git a/tests/utils/arrayDifference.ts b/tests/utils/arrayDifference.ts new file mode 100644 index 000000000000..71c3c2c8f015 --- /dev/null +++ b/tests/utils/arrayDifference.ts @@ -0,0 +1,5 @@ +function arrayDifference(array1: T[], array2: T[]): T[] { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); +} + +export default arrayDifference; From 4c9375a07fa1f4631acdcfe6a514591bbc9e9f7b Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 28 Feb 2024 07:56:29 +0100 Subject: [PATCH 7/9] move arrayDifference to global utils --- {tests => src}/utils/arrayDifference.ts | 0 tests/unit/TranslateTest.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {tests => src}/utils/arrayDifference.ts (100%) diff --git a/tests/utils/arrayDifference.ts b/src/utils/arrayDifference.ts similarity index 100% rename from tests/utils/arrayDifference.ts rename to src/utils/arrayDifference.ts diff --git a/tests/unit/TranslateTest.ts b/tests/unit/TranslateTest.ts index 40ece1d7525e..0be29a29cb12 100644 --- a/tests/unit/TranslateTest.ts +++ b/tests/unit/TranslateTest.ts @@ -5,7 +5,7 @@ import * as translations from '@src/languages/translations'; import type {TranslationFlatObject, TranslationPaths} from '@src/languages/types'; import * as Localize from '@src/libs/Localize'; import asMutable from '@src/types/utils/asMutable'; -import arrayDifference from '../utils/arrayDifference'; +import arrayDifference from '@src/utils/arrayDifference'; const originalTranslations = {...translations}; From 21d3998cf8c22493d75a05c45dd686a0433e3a1c Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 4 Mar 2024 09:39:19 +0100 Subject: [PATCH 8/9] apply suggested changes to arrayDifference util funciton --- src/utils/arrayDifference.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/arrayDifference.ts b/src/utils/arrayDifference.ts index 71c3c2c8f015..c1c87544aa25 100644 --- a/src/utils/arrayDifference.ts +++ b/src/utils/arrayDifference.ts @@ -1,4 +1,4 @@ -function arrayDifference(array1: T[], array2: T[]): T[] { +function arrayDifference(array1: TItem[], array2: TItem[]): TItem[] { return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } From 0edff36847885b5eb0a6a9cebe54216487ed5175 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 6 Mar 2024 10:34:54 +0100 Subject: [PATCH 9/9] document arrayDifference function --- src/utils/arrayDifference.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/arrayDifference.ts b/src/utils/arrayDifference.ts index c1c87544aa25..d011f8d5067b 100644 --- a/src/utils/arrayDifference.ts +++ b/src/utils/arrayDifference.ts @@ -1,3 +1,7 @@ +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ function arrayDifference(array1: TItem[], array2: TItem[]): TItem[] { return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); }