mirror of https://github.com/rancher/dashboard.git
503 lines
14 KiB
TypeScript
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);
|
|
});
|
|
});
|