Skip to content

Commit 604011d

Browse files
committed
getNestedProperty
1 parent 5e15403 commit 604011d

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

spec/Utils.spec.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,55 @@ describe('Utils', () => {
122122
expect(result).toBe('{"name":"test","number":42,"nested":{"key":"value"}}');
123123
});
124124
});
125+
126+
describe('getNestedProperty', () => {
127+
it('should get top-level property', () => {
128+
const obj = { foo: 'bar' };
129+
expect(Utils.getNestedProperty(obj, 'foo')).toBe('bar');
130+
});
131+
132+
it('should get nested property with dot notation', () => {
133+
const obj = { database: { options: { enabled: true } } };
134+
expect(Utils.getNestedProperty(obj, 'database.options.enabled')).toBe(true);
135+
});
136+
137+
it('should return undefined for non-existent property', () => {
138+
const obj = { foo: 'bar' };
139+
expect(Utils.getNestedProperty(obj, 'baz')).toBeUndefined();
140+
});
141+
142+
it('should return undefined for non-existent nested property', () => {
143+
const obj = { database: { options: {} } };
144+
expect(Utils.getNestedProperty(obj, 'database.options.enabled')).toBeUndefined();
145+
});
146+
147+
it('should return undefined when path traverses non-object', () => {
148+
const obj = { database: 'string' };
149+
expect(Utils.getNestedProperty(obj, 'database.options.enabled')).toBeUndefined();
150+
});
151+
152+
it('should return undefined for null object', () => {
153+
expect(Utils.getNestedProperty(null, 'foo')).toBeUndefined();
154+
});
155+
156+
it('should return undefined for empty path', () => {
157+
const obj = { foo: 'bar' };
158+
expect(Utils.getNestedProperty(obj, '')).toBeUndefined();
159+
});
160+
161+
it('should handle value of 0', () => {
162+
const obj = { database: { timeout: 0 } };
163+
expect(Utils.getNestedProperty(obj, 'database.timeout')).toBe(0);
164+
});
165+
166+
it('should handle value of false', () => {
167+
const obj = { database: { enabled: false } };
168+
expect(Utils.getNestedProperty(obj, 'database.enabled')).toBe(false);
169+
});
170+
171+
it('should handle value of empty string', () => {
172+
const obj = { database: { name: '' } };
173+
expect(Utils.getNestedProperty(obj, 'database.name')).toBe('');
174+
});
175+
});
125176
});

src/Utils.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,31 @@ class Utils {
444444
return value;
445445
};
446446
}
447+
448+
/**
449+
* Gets a nested property value from an object using dot notation.
450+
* @param {Object} obj The object to get the property from.
451+
* @param {String} path The property path in dot notation, e.g. 'databaseOptions.allowPublicExplain'.
452+
* @returns {any} The property value or undefined if not found.
453+
* @example
454+
* const obj = { database: { options: { enabled: true } } };
455+
* Utils.getNestedProperty(obj, 'database.options.enabled');
456+
* // Output: true
457+
*/
458+
static getNestedProperty(obj, path) {
459+
if (!obj || !path) {
460+
return undefined;
461+
}
462+
const keys = path.split('.');
463+
let current = obj;
464+
for (const key of keys) {
465+
if (current == null || typeof current !== 'object') {
466+
return undefined;
467+
}
468+
current = current[key];
469+
}
470+
return current;
471+
}
447472
}
448473

449474
module.exports = Utils;

0 commit comments

Comments
 (0)