dashboard/shell/utils/__tests__/array.test.ts

503 lines
14 KiB
TypeScript

import {
addObject, addObjects, clear, filterBy, findBy, getUniqueLabelKeys, insertAt, isArray, removeAt, removeObject, removeObjects, replaceWith, sameContents, uniq
} from '@shell/utils/array';
interface Obj {
key?: string;
booleanKey?: boolean;
baz?: string;
cat?: string;
}
describe('fx: addObject', () => {
it('should add items', () => {
const obj1 = { key: 'value' };
const myArray: Obj[] = [];
addObject(myArray, obj1);
expect(myArray).toStrictEqual([obj1]);
});
it('should add another item to an initial array', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'another value', booleanKey: false };
const myArray: Obj[] = [obj1];
addObject(myArray, obj2);
expect(myArray).toStrictEqual([obj1, obj2]);
});
it('should add more items without duplicate them', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'second value', booleanKey: false };
const myArray: Obj[] = [obj1];
addObject(myArray, obj2);
expect(myArray).toStrictEqual([obj1, obj2]);
});
});
describe('fx: addObjects', () => {
it('should accept empty arrays and do nothing', () => {
const myArray: Obj[] = [];
addObjects(myArray, []);
expect(myArray).toStrictEqual([]);
});
it('should add more items to an initial array', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1];
addObjects(myArray, [obj2, obj3]);
expect(myArray).toStrictEqual([obj1, obj2, obj3]);
});
it('should add new items and avoiding duplicates', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj2, obj3];
addObjects(myArray, [obj1, obj4]);
expect(myArray).toStrictEqual([obj1, obj2, obj3, obj4]);
});
it('should add new item once, if entered multiple times', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const obj5 = { cat: 'hat' };
const myArray: Obj[] = [obj1, obj2, obj3, obj4];
addObjects(myArray, [obj5, obj5, obj5, obj5]);
expect(myArray).toStrictEqual([obj1, obj2, obj3, obj4, obj5]);
});
});
describe('fx: removeObject', () => {
it('should remove an existing item', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1, obj2, obj3];
removeObject(myArray, obj2);
expect(myArray).toStrictEqual([obj1, obj3]);
});
it('should not remove unmatched items', () => {
const obj1 = { key: 'value' };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj3];
removeObject(myArray, obj4);
expect(myArray).toStrictEqual([obj1, obj3]);
});
it('should return an empty array if no item', () => {
const obj1 = { key: 'value' };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1, obj3];
removeObject(myArray, obj1);
removeObject(myArray, obj3);
expect(myArray).toStrictEqual([]);
});
});
describe('fx: removeObjects', () => {
it('should remove items', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1, obj2, obj3];
removeObjects(myArray, [obj1]);
expect(myArray).toStrictEqual([obj2, obj3]);
});
it('should not remove unmatched items', () => {
const obj1 = { key: 'value' };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj3];
removeObjects(myArray, [obj4]);
expect(myArray).toStrictEqual([obj1, obj3]);
});
it('should return an empty array if no item', () => {
const obj1 = { key: 'value' };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1, obj3];
removeObjects(myArray, [obj1, obj3]);
expect(myArray).toStrictEqual([]);
});
it('should remove multiple items', () => {
const obj1 = { key: 'value' };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1, obj3];
removeObjects(myArray, [obj1, obj3]);
expect(myArray).toStrictEqual([]);
});
it('should remove items, including duplications', () => {
const myArray = [1, 1, 2, 3, 4, 5, 9, 888, 777, 6, 6, 6, 777];
removeObjects(myArray, [1, 2, 3, 4, 5, 9, 6]);
expect(myArray).toStrictEqual([888, 777, 777]);
});
});
describe('fx: removeAt', () => {
it('should remove item at given index', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray = [obj1, obj2, obj3, obj4];
removeAt(myArray, 1);
expect(myArray).toStrictEqual([obj1, obj3, obj4]);
});
it('should remove at multiple items at given indexes', () => {
const obj1 = { key: 'value' };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray = [obj1, obj3, obj4];
removeAt(myArray, 1, 2);
expect(myArray).toStrictEqual([obj1]);
});
it('should remove the last item', () => {
const obj1 = { key: 'value' };
const myArray = [obj1];
removeAt(myArray, 0);
expect(myArray).toStrictEqual([]);
});
describe('should return error:', () => {
it('given a too high index', () => {
const obj1 = { key: 'value' };
const myArray: Obj[] = [obj1];
expect(() => removeAt(myArray, 42)).toThrow('Index + length too high');
});
it('given a too low index', () => {
const obj1 = { key: 'value' };
const myArray: Obj[] = [obj1];
expect(() => removeAt(myArray, -1)).toThrow('Index too low');
});
it('given an empty case', () => {
const myArray: Obj[] = [];
expect(() => removeAt(myArray, 0)).toThrow('Index + length too high');
});
});
});
describe('fx: isArray', () => {
it.each([
{ value: [], expected: true },
{ value: true, expected: false },
{ value: 42, expected: false },
{ value: {}, expected: false },
{ value: { length: 42 }, expected: false },
])('should parse $val as $expect', ({ value, expected }) => {
expect(isArray(value)).toBe(expected);
});
});
describe('fx: clear', () => {
it('should remove all the items', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj2, obj3, obj4];
clear(myArray);
expect(myArray).toHaveLength(0);
});
it('should not affect shallow copies', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj2, obj3, obj4];
const myCopy = myArray;
clear(myArray);
expect(myCopy).toStrictEqual(myCopy);
});
});
describe('fx: filterBy', () => {
it('should return empty array if no list of items is provided', () => {
const result = filterBy(null, { key: 'value' });
expect(result).toStrictEqual([]);
});
it('should return empty array if nothing matches all the statements', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj2, obj3, obj4];
const result = filterBy(myArray, { key: 'qux', booleanKey: false });
expect(result).toStrictEqual([]);
});
describe('should return objects', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj2, obj3, obj4];
it.each([
{
case: 'including a matching key with truthy value (boolean)',
keyOrObj: 'booleanKey',
expected: { key: 'qux', booleanKey: true }
},
{
case: 'including a matching key with truthy value (string)',
keyOrObj: 'baz',
expected: { key: 'bat', baz: 'bat' }
},
{
case: 'including a matching key with the same value (boolean)',
keyOrObj: 'booleanKey',
value: false,
expected: { key: 'baz', booleanKey: false }
},
{
case: 'including a matching key with the same value (string)',
keyOrObj: 'key',
value: 'value',
expected: { key: 'value' }
},
{
case: 'including all the declared keys and values',
keyOrObj: { key: 'qux', booleanKey: true },
expected: { key: 'qux', booleanKey: true }
},
{
case: 'including a matching key',
keyOrObj: { booleanKey: undefined },
expected: { key: 'qux', booleanKey: true }
},
])('$case', ({ keyOrObj, value, expected }) => {
const result = filterBy(myArray, keyOrObj, value);
expect(result).toStrictEqual([expected]);
});
});
});
describe('fx: findBy', () => {
it('should return undefined if no list of items is provided', () => {
const result = findBy(null, { key: 'value' });
expect(result).toBeUndefined();
});
it('should return undefined if nothing matches all the statements', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj2, obj3, obj4];
const result = findBy(myArray, { key: 'qux', booleanKey: false });
expect(result).toBeUndefined();
});
describe('should return object including', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const obj4 = { key: 'qux', booleanKey: true };
const myArray: Obj[] = [obj1, obj2, obj3, obj4];
it.each([
{
case: 'a matching key with truthy value (boolean)',
keyOrObj: 'booleanKey',
expected: { key: 'qux', booleanKey: true }
},
{
case: 'a matching key with truthy value (string)',
keyOrObj: 'baz',
expected: { key: 'bat', baz: 'bat' }
},
{
case: 'a matching key with the same value (boolean)',
keyOrObj: 'booleanKey',
value: false,
expected: { key: 'baz', booleanKey: false }
},
{
case: 'a matching key with the same value (string)',
keyOrObj: 'key',
value: 'value',
expected: { key: 'value' }
},
{
case: 'all the declared keys and values',
keyOrObj: { key: 'qux', booleanKey: true },
expected: { key: 'qux', booleanKey: true }
},
{
case: 'a matching key',
keyOrObj: { booleanKey: undefined },
expected: { key: 'qux', booleanKey: true }
},
])('$case', ({ keyOrObj, value, expected }) => {
const result = findBy(myArray, keyOrObj, value);
expect(result).toStrictEqual(expected);
});
});
});
describe('fx: insertAt', () => {
it('should insert an item at the specified index', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1, obj2];
insertAt(myArray, 1, obj3);
expect(myArray).toStrictEqual([obj1, obj3, obj2]);
});
});
describe('fx: sameContents', () => {
it('should return true if the two lists', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const a = [obj1, obj2];
const b = [obj2, obj1];
expect(sameContents(a, b)).toBe(true);
});
it('should return false if the two lists are not the same', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const a = [obj1, obj2];
const b = [obj1, obj3];
expect(sameContents(a, b)).toBe(false);
});
it('should return false if the two lists have different length', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const a = [obj1, obj2];
const b = [obj1, obj2, obj3];
expect(sameContents(a, b)).toBe(false);
});
});
describe('fx: uniq', () => {
it('should return a new array with unique items', () => {
const obj1 = { key: 'value' };
const obj2 = { key: 'baz', booleanKey: false };
const obj3 = { key: 'bat', baz: 'bat' };
const myArray: Obj[] = [obj1, obj2, obj3, obj1, obj2];
const result = uniq(myArray);
expect(result).toStrictEqual([obj1, obj2, obj3]);
expect(result).not.toBe(myArray);
});
});
describe('fx: replaceWith', () => {
it('should replace values of the array and keep the inheritance', () => {
const a = [1, 2, 3];
const b = a;
const c = [4, 5, 6];
replaceWith(a, ...c);
expect(a).toStrictEqual(c);
expect(a).toBe(b);
});
});
describe('fx: getUniqueLabelKeys', () => {
it('should get list of unique resource labels', () => {
const resources = [
{
metadata: {
labels: {
keyOne: 'value',
keyTwo: 'value',
}
}
},
{
metadata: {
labels: {
keyOne: 'value',
keyThree: 'value',
}
}
},
] as unknown as { metadata: { labels: { [name: string]: string} } }[] ;
const expected = ['keyOne', 'keyThree', 'keyTwo'];
const result = getUniqueLabelKeys(resources);
expect(result).toStrictEqual(expected);
});
});