diff --git a/lib/undefsafe.js b/lib/undefsafe.js index c9d0204..f3701de 100644 --- a/lib/undefsafe.js +++ b/lib/undefsafe.js @@ -1,7 +1,43 @@ 'use strict'; function undefsafe(obj, path, value) { - var parts = path.split('.'); + + // I'm not super keen on this private function, but it's because + // it'll also be use in the browser and I wont *one* function exposed + function split(path) { + var res = []; + var level = 0; + var key = ''; + + for (var i = 0; i < path.length; i++) { + var c = path.substr(i, 1); + + if (level === 0 && (c === '.' || c === '[')) { + if (c === '[') { + level++; + i++; + c = path.substr(i, 1); + } + res.push(key); + key = ''; + continue; + } + + if (c === ']') { + level--; + key = key.slice(0, -1); + continue; + } + + key += c; + } + + res.push(key); + + return res; + } + + var parts = split(path); var key = null; var type = typeof obj; var root = obj; diff --git a/test/undefsafe.test.js b/test/undefsafe.test.js index 8ef512e..9bd973f 100644 --- a/test/undefsafe.test.js +++ b/test/undefsafe.test.js @@ -41,6 +41,35 @@ test('should handle null properties', function (t) { t.end(); }); +test('should find properties with periods in them', function (t) { + var value = { + a: { 'one.two': true } + }; + + var r = undefsafe(value, 'a["one.two"]'); + t.equal(r, true, 'a["one.two"]: ' + r); + + value = { + a: { 'one.two.and\three': true } + }; + + r = undefsafe(value, `a['one.two.and\three']`); + t.equal(r, true, 'weird: ' + r); + + value = { + a: { 'one.two.and\three': [ + false, + true, + ] } + }; + + r = undefsafe(value, `a['one.two.and\three'].1`); + t.equal(r, true, 'combo: ' + r); + + t.end(); +}); + + test('should find deep object properties', function (t) { var value = { a: {