Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions functionsUnittests/objectFunctions/deepCloneWith.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { deepCloneWith } from '../../objectFunctions/deepCloneWith';

describe('deepCloneWith', () => {
const cloneFn = (value: any) => value;

Check warning on line 4 in functionsUnittests/objectFunctions/deepCloneWith.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/deepCloneWith.test.ts#L4

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)

// Test case 1: Deep clone a simple object
it('1. should deep clone a simple object', () => {
const obj = { a: 1, b: 2 };
const result = deepCloneWith(obj, cloneFn);
const expected = { a: 1, b: 2 };
expect(result).toEqual(expected);
expect(result).not.toBe(obj); // Ensure it's a deep clone
});

// Test case 2: Deep clone a nested object
it('2. should deep clone a nested object', () => {
const obj = { a: 1, b: { c: 2, d: 3 } };
const result = deepCloneWith(obj, cloneFn);
const expected = { a: 1, b: { c: 2, d: 3 } };
expect(result).toEqual(expected);
expect(result.b).not.toBe(obj.b); // Ensure nested object is also cloned
});

// Test case 3: Deep clone an array
it('3. should deep clone an array', () => {
const arr = [1, 2, { a: 3 }];
const result = deepCloneWith(arr, cloneFn);
const expected = [1, 2, { a: 3 }];
expect(result).toEqual(expected);
expect(result).not.toBe(arr); // Ensure it's a deep clone
expect(result[2]).not.toBe(arr[2]); // Ensure nested object is also cloned
});

// Test case 4: Use the cloneFn for cloning values
it('4. should use the cloneFn for cloning values', () => {
const obj = { a: 1, b: 2 };
const cloneFn = jest.fn(value => value);
deepCloneWith(obj, cloneFn);
expect(cloneFn).toHaveBeenCalledTimes(2);
});

// Test case 5: Deep clone an object with array properties
it('5. should deep clone an object with array properties', () => {
const obj = { a: [1, 2], b: [3, 4] };
const result = deepCloneWith(obj, cloneFn);
const expected = { a: [1, 2], b: [3, 4] };
expect(result).toEqual(expected);
expect(result.a).not.toBe(obj.a); // Ensure array is also cloned
expect(result.b).not.toBe(obj.b); // Ensure array is also cloned
});

// Test case 6: Deep clone an object with nested arrays
it('6. should deep clone an object with nested arrays', () => {
const obj = { a: [1, [2, 3]], b: [4, [5, 6]] };
const result = deepCloneWith(obj, cloneFn);
const expected = { a: [1, [2, 3]], b: [4, [5, 6]] };
expect(result).toEqual(expected);
expect(result.a[1]).not.toBe(obj.a[1]); // Ensure nested array is also cloned
expect(result.b[1]).not.toBe(obj.b[1]); // Ensure nested array is also cloned
});

// Test case 7: Deep clone an object with functions
it('7. should deep clone an object with functions', () => {
const obj = { a: 1, b: () => 2 };
const result = deepCloneWith(obj, cloneFn);
const expected = { a: 1, b: obj.b };
expect(result).toEqual(expected);
expect(result.b).toBe(obj.b); // Ensure function is not cloned
});

// Test case 8: Deep clone an object with symbols
it('8. should deep clone an object with symbols', () => {
const sym = Symbol('sym');
const obj = { a: 1, [sym]: 2 };
const result = deepCloneWith(obj, cloneFn);
const expected = { a: 1, [sym]: 2 };
expect(result).toEqual(expected);
expect(result[sym]).toBe(obj[sym]); // Ensure symbol is not cloned
});

// Test case 9: Handle non-object input (number)
it('9. should throw a TypeError if input is a number', () => {
expect(() => deepCloneWith(42 as any, cloneFn)).toThrow(TypeError);

Check warning on line 83 in functionsUnittests/objectFunctions/deepCloneWith.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/deepCloneWith.test.ts#L83

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 10: Handle non-object input (string)
it('10. should throw a TypeError if input is a string', () => {
expect(() => deepCloneWith('string' as any, cloneFn)).toThrow(TypeError);

Check warning on line 88 in functionsUnittests/objectFunctions/deepCloneWith.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/deepCloneWith.test.ts#L88

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 11: Handle non-object input (boolean)
it('11. should throw a TypeError if input is a boolean', () => {
expect(() => deepCloneWith(true as any, cloneFn)).toThrow(TypeError);

Check warning on line 93 in functionsUnittests/objectFunctions/deepCloneWith.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/deepCloneWith.test.ts#L93

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 12: Handle non-object input (null)
it('12. should throw a TypeError if input is null', () => {
expect(() => deepCloneWith(null as any, cloneFn)).toThrow(TypeError);

Check warning on line 98 in functionsUnittests/objectFunctions/deepCloneWith.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/deepCloneWith.test.ts#L98

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 13: Handle non-object input (undefined)
it('13. should throw a TypeError if input is undefined', () => {
expect(() => deepCloneWith(undefined as any, cloneFn)).toThrow(TypeError);

Check warning on line 103 in functionsUnittests/objectFunctions/deepCloneWith.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/deepCloneWith.test.ts#L103

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});
});
92 changes: 92 additions & 0 deletions functionsUnittests/objectFunctions/objectMap.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { objectMap } from '../../objectFunctions/objectMap';

describe('objectMap', () => {
// Test case 1: Map values of a simple object
it('1. should map values of a simple object', () => {
const obj = { a: 1, b: 2, c: 3 };
const result = objectMap(obj, (value) => value * 2);
const expected = { a: 2, b: 4, c: 6 };
expect(result).toEqual(expected);
});

// Test case 2: Map values of an object with different types
it('2. should map values of an object with different types', () => {
const obj = { a: 1, b: 'hello', c: true };
const result = objectMap(obj, (value) => typeof value);
const expected = { a: 'number', b: 'string', c: 'boolean' };
expect(result).toEqual(expected);
});

// Test case 3: Map values of an empty object
it('3. should return an empty object when input is an empty object', () => {
const obj = {};
const result = objectMap(obj, (value) => value);
const expected = {};
expect(result).toEqual(expected);
});

// Test case 4: Map values with keys
it('4. should map values with keys', () => {
const obj = { a: 1, b: 2, c: 3 };
const result = objectMap(obj, (value, key) => `${key}-${value}`);
const expected = { a: 'a-1', b: 'b-2', c: 'c-3' };
expect(result).toEqual(expected);
});

// Test case 5: Map values of an object with nested objects
it('5. should map values of an object with nested objects', () => {
const obj = { a: { x: 1 }, b: { y: 2 } };
const result = objectMap(obj, (value) => JSON.stringify(value));
const expected = { a: '{"x":1}', b: '{"y":2}' };
expect(result).toEqual(expected);
});

// Test case 6: Map values of an object with arrays
it('6. should map values of an object with arrays', () => {
const obj = { a: [1, 2], b: [3, 4] };
const result = objectMap(obj, (value) => value.join('-'));
const expected = { a: '1-2', b: '3-4' };
expect(result).toEqual(expected);
});

// Test case 7: Map values of an object with null values
it('7. should map values of an object with null values', () => {
const obj = { a: null, b: 2 };
const result = objectMap(obj, (value) => (value === null ? 'null' : value));
const expected = { a: 'null', b: 2 };
expect(result).toEqual(expected);
});

// Test case 8: Map values of an object with undefined values
it('8. should map values of an object with undefined values', () => {
const obj = { a: undefined, b: 2 };
const result = objectMap(obj, (value) => (value === undefined ? 'undefined' : value));
const expected = { a: 'undefined', b: 2 };
expect(result).toEqual(expected);
});

// Test case 9: Handle non-object input (number)
it('9. should throw a TypeError if input is a number', () => {
expect(() => objectMap(42 as any, (value) => value)).toThrow(TypeError);

Check warning on line 70 in functionsUnittests/objectFunctions/objectMap.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/objectMap.test.ts#L70

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 10: Handle non-object input (string)
it('10. should throw a TypeError if input is a string', () => {
expect(() => objectMap('string' as any, (value) => value)).toThrow(TypeError);

Check warning on line 75 in functionsUnittests/objectFunctions/objectMap.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/objectMap.test.ts#L75

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 11: Handle non-object input (boolean)
it('11. should throw a TypeError if input is a boolean', () => {
expect(() => objectMap(true as any, (value) => value)).toThrow(TypeError);

Check warning on line 80 in functionsUnittests/objectFunctions/objectMap.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/objectMap.test.ts#L80

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 12: Handle non-object input (null)
it('12. should throw a TypeError if input is null', () => {
expect(() => objectMap(null as any, (value) => value)).toThrow(TypeError);

Check warning on line 85 in functionsUnittests/objectFunctions/objectMap.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/objectMap.test.ts#L85

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});

// Test case 13: Handle non-object input (undefined)
it('13. should throw a TypeError if input is undefined', () => {
expect(() => objectMap(undefined as any, (value) => value)).toThrow(TypeError);

Check warning on line 90 in functionsUnittests/objectFunctions/objectMap.test.ts

View check run for this annotation

codefactor.io / CodeFactor

functionsUnittests/objectFunctions/objectMap.test.ts#L90

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
});
});
27 changes: 27 additions & 0 deletions objectFunctions/deepCloneWith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Deep clones an object using a custom clone function.
*
* @param {T} obj - The object to clone.
* @param {(value: any) => any} cloneFn - The custom clone function.
* @returns {T} - A deep clone of the object.
* @throws {TypeError} - If the input is not an object or is null.
*/
export function deepCloneWith<T>(obj: T, cloneFn: (value: any) => any): T {

Check warning on line 9 in objectFunctions/deepCloneWith.ts

View check run for this annotation

codefactor.io / CodeFactor

objectFunctions/deepCloneWith.ts#L9

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)

Check warning on line 9 in objectFunctions/deepCloneWith.ts

View check run for this annotation

codefactor.io / CodeFactor

objectFunctions/deepCloneWith.ts#L9

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
if (typeof obj !== 'object' || obj === null) {
throw new TypeError('Input must be a non-null object');
}

const newObj: any = Array.isArray(obj) ? [] : {};

Check warning on line 14 in objectFunctions/deepCloneWith.ts

View check run for this annotation

codefactor.io / CodeFactor

objectFunctions/deepCloneWith.ts#L14

Unexpected any. Specify a different type. (@typescript-eslint/no-explicit-any)
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
newObj[key] = (value && typeof value === 'object') ? deepCloneWith(value, cloneFn) : cloneFn(value);
}
}
return newObj;
}

// Example usage:
// const original = { name: 'John', address: { city: 'NY' } };
// const copy = deepCloneWith(original, value => value);
// copy.address.city = 'LA'; // Doesn't affect the original object
22 changes: 22 additions & 0 deletions objectFunctions/objectMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Maps the values of an object using a provided function.
*
* @param {Record<string, T>} obj - The object to map.
* @param {(value: T, key: string) => U} fn - The function to apply to each value.
* @returns {Record<string, U>} - A new object with the mapped values.
*/
export function objectMap<T, U>(obj: Record<string, T>, fn: (value: T, key: string) => U): Record<string, U> {
if (typeof obj !== 'object' || obj === null) {
throw new TypeError('Input must be a non-null object');
}

return Object.keys(obj).reduce((acc, key) => {
acc[key] = fn(obj[key], key);
return acc;
}, {} as Record<string, U>);
}

// Example usage:
// const original = { a: 1, b: 2, c: 3 };
// const mapped = objectMap(original, (value, key) => value * 2);
// console.log(mapped); // { a: 2, b: 4, c: 6 }
Loading
Loading