camote-utils
Version:
A comprehensive TypeScript utility library featuring advanced string and number formatting, data structures, and algorithms
300 lines (257 loc) • 11 kB
text/typescript
import { deepClone, deepCompareObjects, deepCompare, deepMerge, deepExclude, deepSortAlphabetical } from '../src/formatters/deep';
describe('deepClone', () => {
it('should create a deep copy of a simple object', () => {
const original = { a: 1, b: 2 };
const cloned = deepClone(original);
expect(cloned).toEqual(original);
expect(cloned).not.toBe(original);
});
it('should create a deep copy of a nested object', () => {
const original = { a: { b: { c: 3 } } };
const cloned = deepClone(original);
expect(cloned).toEqual(original);
expect(cloned.a).not.toBe(original.a);
expect(cloned.a.b).not.toBe(original.a.b);
});
it('should create a deep copy of an array', () => {
const original = [1, 2, 3];
const cloned = deepClone(original);
expect(cloned).toEqual(original);
expect(cloned).not.toBe(original);
});
it('should create a deep copy of a nested array', () => {
const original = [[1, 2], [3, 4]];
const cloned = deepClone(original);
expect(cloned).toEqual(original);
expect(cloned[0]).not.toBe(original[0]);
});
it('should create a deep copy of a date', () => {
const original = new Date();
const cloned = deepClone(original);
expect(cloned).toEqual(original);
expect(cloned).not.toBe(original);
});
it('should handle null and undefined', () => {
expect(deepClone(null)).toBe(null);
expect(deepClone(undefined)).toBe(undefined);
});
it('should create a deep copy of a complex object', () => {
const original = {
name: "John",
age: 30,
hobbies: ["reading", "gaming"],
details: {
birthDate: new Date(),
address: {
city: "New York",
zip: "10001"
}
}
};
const cloned = deepClone(original);
expect(cloned).toEqual(original);
expect(cloned).not.toBe(original);
expect(cloned.hobbies).not.toBe(original.hobbies);
expect(cloned.details).not.toBe(original.details);
expect(cloned.details.address).not.toBe(original.details.address);
});
});
describe('deepCompareObjects', () => {
test('should return differences between two objects', () => {
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 3 } };
const differences = deepCompareObjects(obj1, obj2, true);
expect(differences).toEqual({ b: { c: 3 } });
});
test('should return false for unequal objects', () => {
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 3 } };
const areEqual = deepCompareObjects(obj1, obj2);
expect(areEqual).toBe(false);
});
test('should return differences between two arrays of objects', () => {
const array1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
const array2 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Charlie' }];
const arrayDifferences = deepCompareObjects(array1, array2, true);
expect(arrayDifferences).toEqual([{ id: 2, name: 'Charlie' }]);
});
test('should return differences for nested objects', () => {
const nestedObj1 = { users: [{ id: 1, name: 'Alice' }], settings: { theme: 'dark' } };
const nestedObj2 = { users: [{ id: 1, name: 'Alice' }], settings: { theme: 'light' } };
const nestedDifferences = deepCompareObjects(nestedObj1, nestedObj2, true);
expect(nestedDifferences).toEqual({ settings: { theme: 'light' } });
});
});
describe('deepCompare', () => {
test('should return true for equal between two string', () => {
const str1 = 'hello';
const str2 = 'hello';
const differences = deepCompare(str1, str2);
expect(differences).toEqual(true);
});
test('should return true for null', () => {
const str1 = null;
const str2 = 'hello';
const differences = deepCompare(str1, str2);
expect(differences).toEqual(false);
});
test('should return true for equal between two arrays', () => {
const array1 = ['Alice', 'James'];
const array2 = ['Alice'];
const differences = deepCompare(array1, array2);
expect(differences).toEqual(false);
})
test('should return differences between two arrays', () => {
const array1 = ['Alice'];
const array2 = ['Alice', 'James'];
const differences = deepCompare(array1, array2, true);
expect(differences).toEqual(['James']);
})
test('should return differences between two objects', () => {
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 3 } };
const differences = deepCompare(obj1, obj2, true);
expect(differences).toEqual({ b: { c: 3 } });
});
test('should return object for zero', () => {
const obj1 = { a: 33 };
const obj2 = { a: 0 };
const differences = deepCompare(obj1, obj2, true);
expect(differences).toEqual(obj2);
});
test('should return false for unequal objects', () => {
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 3 } };
const areEqual = deepCompare(obj1, obj2);
expect(areEqual).toBe(false);
});
test('should return differences between two arrays of objects', () => {
const array1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
const array2 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Charlie' }];
const arrayDifferences = deepCompare(array1, array2, true);
expect(arrayDifferences).toEqual([{ id: 2, name: 'Charlie' }]);
});
test('should return differences for nested objects', () => {
const nestedObj1 = { users: [{ id: 1, name: 'Alice' }], settings: { theme: 'dark' } };
const nestedObj2 = { users: [{ id: 1, name: 'Alice' }], settings: { theme: 'light' } };
const nestedDifferences = deepCompare(nestedObj1, nestedObj2, true);
expect(nestedDifferences).toEqual({ settings: { theme: 'light' } });
});
test('should return false for nested objects', () => {
const nestedObj1 = { data: null };
const nestedObj2 = { data: 'not null' };
const nestedDifferences = deepCompare(nestedObj1, nestedObj2);
expect(nestedDifferences).toEqual(false);
});
});
describe('deepExclude', () => {
test('should exclude specified values from the array', () => {
const sourceArray = [1, 2, 3, { id: 4 }, { id: 5 }];
const valuesToExclude = [2, { id: 5 }];
const result = deepExclude(sourceArray, valuesToExclude, item => (typeof item === 'object' ? item.id : item));
expect(result).toEqual([1, 3, { id: 4 }]);
});
test('should exclude specified objects from the array based on key', () => {
const sourceArray = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Bob' }];
const valuesToExclude = [{ id: 2, name: 'Jane' }];
const result = deepExclude(sourceArray, valuesToExclude, item => item.id);
expect(result).toEqual([{ id: 1, name: 'John' }, { id: 3, name: 'Bob' }]);
});
test('should handle null values correctly', () => {
const sourceArray = [null, { id: 1 }, { id: 2 }];
const valuesToExclude = [null, { id: 2 }];
const result = deepExclude(sourceArray, valuesToExclude, item => (typeof item === 'object' ? item?.id : item));
expect(result).toEqual([{ id: 1 }]);
});
test('should handle arrays of primitive values', () => {
const sourceArray = [1, 2, 3, 4];
const valuesToExclude = [2, 4];
const result = deepExclude(sourceArray, valuesToExclude);
expect(result).toEqual([1, 3]);
});
it('should exclude specified values from an array of strings', () => {
const sourceArray = ['apple', 'banana', 'cherry', 'date'];
const valuesToExclude = ['banana', 'date'];
const result = deepExclude(sourceArray, valuesToExclude);
expect(result).toEqual(['apple', 'cherry']);
});
});
describe('deepMerge', () => {
it('should merge two simple objects', () => {
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3 };
const merged = deepMerge(obj1, obj2);
expect(merged).toEqual({ a: 1, b: 2, c: 3 });
});
it('should merge nested objects', () => {
const obj1 = { a: { b: 1 } };
const obj2 = { a: { c: 2 }, d: 3 };
const merged = deepMerge(obj1, obj2);
expect(merged).toEqual({ a: { b: 1, c: 2 }, d: 3 });
});
it('should merge arrays', () => {
const obj1 = { arr: [1, 2] };
const obj2 = { arr: [2, 3] };
const merged = deepMerge(obj1, obj2);
expect(merged).toEqual({ arr: [1, 2, 3] });
});
it('should exclude specified keys', () => {
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4, e: 5 };
const merged = deepMerge(obj1, obj2, ['d', 'e']);
expect(merged).toEqual({ a: 1, b: 2, c: 3 });
});
it('should merge arrays correctly without duplicates', () => {
const obj1 = { arr: [1, 2, 3] };
const obj2 = { arr: [3, 4, 5] };
const merged = deepMerge(obj1, obj2);
expect(merged).toEqual({ arr: [1, 2, 3, 4, 5] });
});
});
describe('deepSortAlphabetical', () => {
it('should sort an object alphabetically', () => {
const obj = { a: 1, b: 2, c: 3 };
const sorted = deepSortAlphabetical(obj);
expect(sorted).toEqual({ a: 1, b: 2, c: 3 });
});
it('should sort an object alphabetically in reverse', () => {
const obj = { a: 1, b: 2, c: 3 };
const sorted = deepSortAlphabetical(obj, true);
expect(sorted).toEqual({ c: 3, b: 2, a: 1 });
});
it('should sort nested objects', () => {
const obj = { b: { c: 3, a: 1 }, a: 2 };
const sorted = deepSortAlphabetical(obj);
expect(sorted).toEqual({ a: 2, b: { a: 1, c: 3 } });
});
it('should sort arrays of objects', () => {
const arr = [{ b: 2 }, { a: 1 }, { c: 3 }];
const sorted = deepSortAlphabetical(arr);
expect(sorted).toEqual([{ a: 1 }, { b: 2 }, { c: 3 }]);
});
it('should handle empty objects', () => {
const obj = {};
const sorted = deepSortAlphabetical(obj);
expect(sorted).toEqual({});
});
it('should handle arrays with mixed types', () => {
const arr = [3, 1, 2, { b: 2 }, { a: 1 }];
const sorted = deepSortAlphabetical(arr);
expect(sorted).toEqual([{ a: 1 }, { b: 2 }, 1, 2, 3]);
});
it('should sort deeply nested structures', () => {
const obj = { d: { b: 2, a: 1 }, a: { c: 3, b: 2 } };
const sorted = deepSortAlphabetical(obj);
expect(sorted).toEqual({ a: { b: 2, c: 3 }, d: { a: 1, b: 2 } });
});
it('should handle arrays with objects having the same keys', () => {
const arr = [{ a: 1, b: 2 }, { a: 3, b: 4 }];
const sorted = deepSortAlphabetical(arr);
expect(sorted).toEqual([{ a: 1, b: 2 }, { a: 3, b: 4 }]);
});
it('should handle null and undefined values gracefully', () => {
const obj = { a: null, b: undefined, c: 3 };
const sorted = deepSortAlphabetical(obj);
expect(sorted).toEqual({ a: null, b: undefined, c: 3 });
});
});