From 84dd701444cfeed49171be2c3225181c22300152 Mon Sep 17 00:00:00 2001 From: splincode Date: Fri, 18 Jun 2021 14:25:49 +0300 Subject: [PATCH 1/2] feat(@angular-ru/common): support nullable values when update array --- packages/common/array/src/update-array.ts | 15 ++++++++------- .../integration/tests/array/update-array.spec.ts | 9 +++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/common/array/src/update-array.ts b/packages/common/array/src/update-array.ts index 1679f0ac2..d7bbd0e09 100644 --- a/packages/common/array/src/update-array.ts +++ b/packages/common/array/src/update-array.ts @@ -1,18 +1,19 @@ import { isFunctionLike } from '@angular-ru/common/function'; -import { Any, CompareFn, PrimaryKey } from '@angular-ru/common/typings'; +import { Any, CompareFn, Nullable, PrimaryKey } from '@angular-ru/common/typings'; -// eslint-disable-next-line max-lines-per-function,complexity +// eslint-disable-next-line max-lines-per-function,complexity,sonarjs/cognitive-complexity export function updateArray( - sourceArray: T[] | never[], - updatedArray: T[] | never[], + sourceArray?: Nullable, + updatedArray?: Nullable, compareFnOrKey: string | CompareFn = PrimaryKey.ID ): T[] { + const preparedSourceArray: T[] = sourceArray ?? []; const newSourceArray: T[] = []; - const newUpdatedArray: T[] = updatedArray.slice(); + const newUpdatedArray: T[] = updatedArray?.slice() ?? []; const skipIndexes: Set = new Set(); - for (let i: number = 0; i < sourceArray.length; i++) { - const currentItem: T = sourceArray[i] as T; + for (let i: number = 0; i < preparedSourceArray.length; i++) { + const currentItem: T = preparedSourceArray[i] as T; let updated: boolean = false; for (let j: number = 0; j < newUpdatedArray.length; j++) { if (skipIndexes.has(j)) { diff --git a/packages/common/integration/tests/array/update-array.spec.ts b/packages/common/integration/tests/array/update-array.spec.ts index 7c0ebbeb1..57015e70e 100644 --- a/packages/common/integration/tests/array/update-array.spec.ts +++ b/packages/common/integration/tests/array/update-array.spec.ts @@ -21,6 +21,15 @@ describe('[TEST]: Array', () => { expect(updateArray(origin, [])).toEqual(origin); }); + it('nullable values', () => { + expect(updateArray()).toEqual([]); + expect(updateArray(null, null)).toEqual([]); + expect(updateArray([1], undefined)).toEqual([1]); + expect(updateArray([1], null)).toEqual([1]); + expect(updateArray(undefined, [2])).toEqual([]); + expect(updateArray(null, [2])).toEqual([]); + }); + it('should update two items', () => { expect( updateArray(origin, [ From b6c281d7b4a0f649bf778a0e092cca8aa06b003a Mon Sep 17 00:00:00 2001 From: splincode Date: Fri, 18 Jun 2021 15:31:49 +0300 Subject: [PATCH 2/2] feat(@angular-ru/common): support nullable for array utils --- packages/common/array/src/first-item.ts | 3 ++ packages/common/array/src/public_api.ts | 4 +++ packages/common/array/src/second-item.ts | 3 ++ packages/common/array/src/take-first-item.ts | 5 +++ packages/common/array/src/take-last-item.ts | 5 +++ packages/common/array/src/take-second-item.ts | 5 +++ packages/common/array/src/take-third-item.ts | 6 ++++ packages/common/array/src/third-item.ts | 3 ++ .../tests/array/utility-arrays.spec.ts | 32 ++++++++++++++++++- .../src/mark-by-filter/mark-by-filter.pipe.ts | 8 ++--- 10 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 packages/common/array/src/take-first-item.ts create mode 100644 packages/common/array/src/take-last-item.ts create mode 100644 packages/common/array/src/take-second-item.ts create mode 100644 packages/common/array/src/take-third-item.ts diff --git a/packages/common/array/src/first-item.ts b/packages/common/array/src/first-item.ts index 7adcea492..ce66e481a 100644 --- a/packages/common/array/src/first-item.ts +++ b/packages/common/array/src/first-item.ts @@ -1,5 +1,8 @@ import { Any } from '@angular-ru/common/typings'; +/** + * @deprecated: use takeFirstItem + */ export function firstItem(array?: T[] | null | undefined, fallback: Any = null): T | null { return Array.isArray(array) && array.length ? array[0] ?? fallback : null!; } diff --git a/packages/common/array/src/public_api.ts b/packages/common/array/src/public_api.ts index 35d61b832..7b90ab814 100644 --- a/packages/common/array/src/public_api.ts +++ b/packages/common/array/src/public_api.ts @@ -12,6 +12,10 @@ export { isMultipleList } from './is-multiple-list'; export { isSingleList } from './is-single-list'; export { partition } from './partition'; export { secondItem } from './second-item'; +export { takeFirstItem } from './take-first-item'; +export { takeLastItem } from './take-last-item'; +export { takeSecondItem } from './take-second-item'; +export { takeThirdItem } from './take-third-item'; export { thirdItem } from './third-item'; export { unique } from './unique'; export { uniqueArrayOf } from './unique-array-of'; diff --git a/packages/common/array/src/second-item.ts b/packages/common/array/src/second-item.ts index 4f1cfca50..1e9e8cff2 100644 --- a/packages/common/array/src/second-item.ts +++ b/packages/common/array/src/second-item.ts @@ -1,5 +1,8 @@ import { Any } from '@angular-ru/common/typings'; +/** + * @deprecated: use takeSecondItem + */ export function secondItem(array?: T[] | null | undefined, fallback: Any = null): T | null { return Array.isArray(array) && array.length ? array[1] ?? fallback : null!; } diff --git a/packages/common/array/src/take-first-item.ts b/packages/common/array/src/take-first-item.ts new file mode 100644 index 000000000..883961612 --- /dev/null +++ b/packages/common/array/src/take-first-item.ts @@ -0,0 +1,5 @@ +import { Nullable } from '@angular-ru/common/typings'; + +export function takeFirstItem(array?: Nullable): Nullable { + return array?.[0]; +} diff --git a/packages/common/array/src/take-last-item.ts b/packages/common/array/src/take-last-item.ts new file mode 100644 index 000000000..7c48f7198 --- /dev/null +++ b/packages/common/array/src/take-last-item.ts @@ -0,0 +1,5 @@ +import { Nullable } from '@angular-ru/common/typings'; + +export function takeLastItem(array?: Nullable): Nullable { + return array?.[array?.length - 1]; +} diff --git a/packages/common/array/src/take-second-item.ts b/packages/common/array/src/take-second-item.ts new file mode 100644 index 000000000..5acdb6ae6 --- /dev/null +++ b/packages/common/array/src/take-second-item.ts @@ -0,0 +1,5 @@ +import { Nullable } from '@angular-ru/common/typings'; + +export function takeSecondItem(array?: Nullable): Nullable { + return array?.[1]; +} diff --git a/packages/common/array/src/take-third-item.ts b/packages/common/array/src/take-third-item.ts new file mode 100644 index 000000000..35aa75b5e --- /dev/null +++ b/packages/common/array/src/take-third-item.ts @@ -0,0 +1,6 @@ +import { Nullable } from '@angular-ru/common/typings'; + +export function takeThirdItem(array?: Nullable): Nullable { + const thirdItemIndex: number = 2; + return array?.[thirdItemIndex]; +} diff --git a/packages/common/array/src/third-item.ts b/packages/common/array/src/third-item.ts index 55a16b634..e1742c198 100644 --- a/packages/common/array/src/third-item.ts +++ b/packages/common/array/src/third-item.ts @@ -1,5 +1,8 @@ import { Any } from '@angular-ru/common/typings'; +/** + * @deprecated: use takeThirdItem + */ export function thirdItem(array?: T[] | null | undefined, fallback: Any = null): T | null { const thirdItemIndex: number = 2; return Array.isArray(array) && array.length ? array[thirdItemIndex] ?? fallback : null!; diff --git a/packages/common/integration/tests/array/utility-arrays.spec.ts b/packages/common/integration/tests/array/utility-arrays.spec.ts index afe70e8ac..6e4031bf4 100644 --- a/packages/common/integration/tests/array/utility-arrays.spec.ts +++ b/packages/common/integration/tests/array/utility-arrays.spec.ts @@ -12,7 +12,11 @@ import { hasOneItem, partition, secondItem, - thirdItem + thirdItem, + takeFirstItem, + takeSecondItem, + takeThirdItem, + takeLastItem } from '@angular-ru/common/array'; import { isNumber } from '@angular-ru/common/number'; import { PlainObject } from '@angular-ru/common/typings'; @@ -101,6 +105,12 @@ describe('[TEST]: Array utility', () => { expect(firstItem([])).toEqual(null); expect(firstItem([1])).toEqual(1); expect(firstItem([1, 2])).toEqual(1); + + expect(takeFirstItem()).toEqual(undefined); + expect(takeFirstItem(null)).toEqual(undefined); + expect(takeFirstItem([])).toEqual(undefined); + expect(takeFirstItem([1])).toEqual(1); + expect(takeFirstItem([1, 2])).toEqual(1); }); it('is second item', () => { @@ -109,6 +119,12 @@ describe('[TEST]: Array utility', () => { expect(secondItem([])).toEqual(null); expect(secondItem([1])).toEqual(null); expect(secondItem([1, 2])).toEqual(2); + + expect(takeSecondItem()).toEqual(undefined); + expect(takeSecondItem(null)).toEqual(undefined); + expect(takeSecondItem([])).toEqual(undefined); + expect(takeSecondItem([1])).toEqual(undefined); + expect(takeSecondItem([1, 2])).toEqual(2); }); it('is third item', () => { @@ -118,6 +134,20 @@ describe('[TEST]: Array utility', () => { expect(thirdItem([1])).toEqual(null); expect(thirdItem([1, 2])).toEqual(null); expect(thirdItem([1, 2, 3])).toEqual(3); + + expect(takeThirdItem()).toEqual(undefined); + expect(takeThirdItem(null)).toEqual(undefined); + expect(takeThirdItem([])).toEqual(undefined); + expect(takeThirdItem([1])).toEqual(undefined); + expect(takeThirdItem([1, 2, 3])).toEqual(3); + }); + + it('is last item', () => { + expect(takeLastItem()).toEqual(undefined); + expect(takeLastItem(null)).toEqual(undefined); + expect(takeLastItem([])).toEqual(undefined); + expect(takeLastItem([1])).toEqual(1); + expect(takeLastItem([1, 2, 3, 4])).toEqual(4); }); it('should divide array by condition', () => { diff --git a/packages/common/pipes/src/mark-by-filter/mark-by-filter.pipe.ts b/packages/common/pipes/src/mark-by-filter/mark-by-filter.pipe.ts index 3f172a932..9eea5e6fa 100644 --- a/packages/common/pipes/src/mark-by-filter/mark-by-filter.pipe.ts +++ b/packages/common/pipes/src/mark-by-filter/mark-by-filter.pipe.ts @@ -2,22 +2,20 @@ import { Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { ensureRegexp, isRegexpStr } from '@angular-ru/common/regexp'; import { toStringVal } from '@angular-ru/common/string'; -import { Any } from '@angular-ru/common/typings'; +import { Any, Nullable } from '@angular-ru/common/typings'; import { isNotNil } from '@angular-ru/common/utils'; import { MarkedValue } from './marked-value'; -type Value = string | null | undefined; - @Pipe({ name: 'markByFilter' }) export class MarkByFilterPipe implements PipeTransform { constructor(private readonly sanitizer: DomSanitizer) {} - public transform(value: Value, filter?: Value, color: string = '#ffdd2d'): MarkedValue { + public transform(value: Nullable, filter?: Nullable, color: string = '#ffdd2d'): MarkedValue { return isNotNil(filter) ? this.search(value, filter, color) : value; } - private search(value: Value, filter?: Value, color?: string): SafeHtml { + private search(value: Nullable, filter?: Nullable, color?: string): SafeHtml { const existFilter: boolean = isNotNil(value) && isNotNil(filter); let newString: string | null | undefined = value;