mirror of
https://github.com/idrawjs/idraw
synced 2026-05-23 17:48:23 +00:00
114 lines
3 KiB
TypeScript
114 lines
3 KiB
TypeScript
// get-set.test.ts
|
|
import { get, set, toPath } from '@idraw/util';
|
|
|
|
describe('toPath()', () => {
|
|
test('should handle string path with dots and brackets', () => {
|
|
expect(toPath('a[0].b.c')).toEqual(['a', '0', 'b', 'c']);
|
|
expect(toPath('x.y.z')).toEqual(['x', 'y', 'z']);
|
|
expect(toPath('arr[3].prop')).toEqual(['arr', '3', 'prop']);
|
|
});
|
|
|
|
test('should handle array path', () => {
|
|
expect(toPath(['a', '0', 'b'])).toEqual(['a', '0', 'b']);
|
|
});
|
|
|
|
test('should handle empty path', () => {
|
|
expect(toPath('')).toEqual([]);
|
|
expect(toPath([])).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('get()', () => {
|
|
const testObj = {
|
|
a: {
|
|
b: {
|
|
c: 42,
|
|
d: [null, { e: 'value' }]
|
|
}
|
|
},
|
|
x: null,
|
|
y: undefined
|
|
};
|
|
|
|
test('should retrieve nested values', () => {
|
|
expect(get(testObj, 'a.b.c')).toBe(42);
|
|
expect(get(testObj, ['a', 'b', 'd', '1', 'e'])).toBe('value');
|
|
expect(get(testObj, 'a.b.d[0]')).toBe(null);
|
|
});
|
|
|
|
test('should handle invalid paths', () => {
|
|
expect(get(testObj, 'a.b.z')).toBeUndefined();
|
|
expect(get(testObj, 'x.y.z')).toBeUndefined();
|
|
expect(get(testObj, 'y.z')).toBeUndefined();
|
|
});
|
|
|
|
test('should return defaultValue for missing paths', () => {
|
|
expect(get(testObj, 'a.missing', 'default')).toBe('default');
|
|
expect(get({}, 'any.path', 123)).toBe(123);
|
|
});
|
|
|
|
test('should handle edge cases', () => {
|
|
expect(get(null, 'any.path', 'default')).toBe('default');
|
|
expect(get(undefined, 'any.path', 'default')).toBe('default');
|
|
expect(get({ a: 1 }, '')).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('set()', () => {
|
|
test('should set nested values in existing structure', () => {
|
|
const obj = { a: { b: { c: 1 } } };
|
|
set(obj, 'a.b.c', 2);
|
|
expect(obj.a.b.c).toBe(2);
|
|
});
|
|
|
|
test('should create missing path structures', () => {
|
|
const obj = {};
|
|
set(obj, 'x[0].y.z', 'value');
|
|
expect(obj).toEqual({
|
|
x: [
|
|
{
|
|
y: {
|
|
z: 'value'
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
test('should handle array indexes', () => {
|
|
const obj = { arr: [] };
|
|
set(obj, 'arr[2].name', 'third');
|
|
expect(obj.arr).toEqual([, , { name: 'third' }]); // eslint-disable-line no-sparse-arrays
|
|
});
|
|
|
|
test('should overwrite existing primitives', () => {
|
|
const obj = { a: 1 };
|
|
set(obj, 'a.b.c', 'new-value');
|
|
expect(obj).toEqual({ a: { b: { c: 'new-value' } } });
|
|
});
|
|
|
|
test('should handle empty path', () => {
|
|
const obj = { a: 1 };
|
|
set(obj, '', 42);
|
|
expect(obj).toEqual({ a: 1 });
|
|
});
|
|
|
|
test('should handle null/undefined objects', () => {
|
|
const obj = null;
|
|
set(obj, 'a.b.c', 'value');
|
|
expect(obj).toBeNull();
|
|
});
|
|
|
|
test('should create arrays when next key is numeric', () => {
|
|
const obj: any = {};
|
|
set(obj, 'arr[1].prop', 'test');
|
|
expect(Array.isArray(obj.arr)).toBe(true);
|
|
expect(obj.arr[1].prop).toBe('test');
|
|
});
|
|
|
|
test('should handle intermediate null values', () => {
|
|
const obj: any = { a: null };
|
|
set(obj, 'a.b.c', 'value');
|
|
expect(obj.a.b.c).toBe('value');
|
|
});
|
|
});
|