object-path
Advanced tools
Comparing version 0.9.2 to 0.10.0
{ | ||
"name": "object-path", | ||
"version": "0.8.2", | ||
"main": "index.js", | ||
@@ -5,0 +4,0 @@ "keywords": [ |
{ | ||
"name": "object-path", | ||
"description": "Access deep properties using a path", | ||
"version": "0.6.0", | ||
"version": "0.9.2", | ||
"author": { | ||
@@ -22,2 +22,2 @@ "name": "Mario Casciaro" | ||
"license": "MIT" | ||
} | ||
} |
56
index.js
@@ -27,3 +27,3 @@ (function (root, factory){ | ||
return true; | ||
} else if (!isString(value)) { | ||
} else if (typeof value !== 'string') { | ||
for (var i in value) { | ||
@@ -43,10 +43,2 @@ if (_hasOwnProperty.call(value, i)) { | ||
function isNumber(value){ | ||
return typeof value === 'number' || toString(value) === "[object Number]"; | ||
} | ||
function isString(obj){ | ||
return typeof obj === 'string' || toString(obj) === "[object String]"; | ||
} | ||
function isObject(obj){ | ||
@@ -56,4 +48,5 @@ return typeof obj === 'object' && toString(obj) === "[object Object]"; | ||
function isArray(obj){ | ||
return typeof obj === 'object' && typeof obj.length === 'number' && toString(obj) === '[object Array]'; | ||
var isArray = Array.isArray || function(obj){ | ||
/*istanbul ignore next:cant test*/ | ||
return toStr.call(obj) === '[object Array]'; | ||
} | ||
@@ -74,9 +67,9 @@ | ||
function set(obj, path, value, doNotReplace){ | ||
if (isNumber(path)) { | ||
if (typeof path === 'number') { | ||
path = [path]; | ||
} | ||
if (isEmpty(path)) { | ||
if (!path || path.length === 0) { | ||
return obj; | ||
} | ||
if (isString(path)) { | ||
if (typeof path === 'string') { | ||
return set(obj, path.split('.').map(getKey), value, doNotReplace); | ||
@@ -96,3 +89,3 @@ } | ||
//check if we assume an array | ||
if(isNumber(path[1])) { | ||
if(typeof path[1] === 'number') { | ||
obj[currentPath] = []; | ||
@@ -108,3 +101,3 @@ } else { | ||
function del(obj, path) { | ||
if (isNumber(path)) { | ||
if (typeof path === 'number') { | ||
path = [path]; | ||
@@ -120,3 +113,3 @@ } | ||
} | ||
if(isString(path)) { | ||
if(typeof path === 'string') { | ||
return del(obj, path.split('.')); | ||
@@ -147,2 +140,3 @@ } | ||
return Object.keys(objectPath).reduce(function(proxy, prop) { | ||
/*istanbul ignore else*/ | ||
if (typeof objectPath[prop] === 'function') { | ||
@@ -161,5 +155,5 @@ proxy[prop] = objectPath[prop].bind(objectPath, obj); | ||
if (isNumber(path)) { | ||
if (typeof path === 'number') { | ||
path = [path]; | ||
} else if (isString(path)) { | ||
} else if (typeof path === 'string') { | ||
path = path.split('.'); | ||
@@ -215,7 +209,7 @@ } | ||
if (isString(value)) { | ||
if (typeof value === 'string') { | ||
return objectPath.set(obj, path, ''); | ||
} else if (isBoolean(value)) { | ||
return objectPath.set(obj, path, false); | ||
} else if (isNumber(value)) { | ||
} else if (typeof value === 'number') { | ||
return objectPath.set(obj, path, 0); | ||
@@ -258,12 +252,12 @@ } else if (isArray(value)) { | ||
objectPath.get = function (obj, path, defaultValue){ | ||
if (isNumber(path)) { | ||
if (typeof path === 'number') { | ||
path = [path]; | ||
} | ||
if (isEmpty(path)) { | ||
if (!path || path.length === 0) { | ||
return obj; | ||
} | ||
if (isEmpty(obj)) { | ||
if (obj == null) { | ||
return defaultValue; | ||
} | ||
if (isString(path)) { | ||
if (typeof path === 'string') { | ||
return objectPath.get(obj, path.split('.'), defaultValue); | ||
@@ -273,8 +267,12 @@ } | ||
var currentPath = getKey(path[0]); | ||
var nextObj | ||
if((typeof currentPath === 'number' && Array.isArray(obj)) || obj.hasOwnProperty(currentPath)) { | ||
nextObj = obj[currentPath] | ||
} | ||
if (nextObj === void 0) { | ||
return defaultValue; | ||
} | ||
if (path.length === 1) { | ||
if (obj[currentPath] === void 0) { | ||
return defaultValue; | ||
} | ||
return obj[currentPath]; | ||
return nextObj; | ||
} | ||
@@ -281,0 +279,0 @@ |
{ | ||
"name": "object-path", | ||
"description": "Access deep properties using a path", | ||
"version": "0.9.2", | ||
"description": "Access deep object properties using a path", | ||
"version": "0.10.0", | ||
"author": { | ||
@@ -14,13 +14,14 @@ "name": "Mario Casciaro" | ||
"engines": { | ||
"node": ">=0.8.0" | ||
"node": ">=0.10.0" | ||
}, | ||
"devDependencies": { | ||
"mocha": "~1.20.1", | ||
"chai": "~1.9.1", | ||
"mocha-lcov-reporter": "~0.0.1", | ||
"coveralls": "~2.11.1", | ||
"istanbul": "~0.3.0" | ||
"@mariocasciaro/benchpress": "^0.1.3", | ||
"chai": "^3.5.0", | ||
"coveralls": "^2.11.2", | ||
"istanbul": "^0.4.4", | ||
"mocha": "^2.2.4", | ||
"mocha-lcov-reporter": "^1.2.0" | ||
}, | ||
"scripts": { | ||
"test": "node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha test.js --report html -- -R spec" | ||
"test": "istanbul cover ./node_modules/mocha/bin/_mocha test.js --report html -- -R spec" | ||
}, | ||
@@ -27,0 +28,0 @@ "keywords": [ |
@@ -14,2 +14,11 @@ | ||
## Changelog | ||
### 0.10.0 | ||
* Improved performance of `get`, `set`, and `push` by 2x-3x | ||
* Introduced a benchmarking test suite | ||
* **BREAKING CHANGE**: `del` will not delete not-own properties | ||
## Install | ||
@@ -20,9 +29,9 @@ | ||
``` | ||
npm install object-path | ||
npm install object-path --save | ||
``` | ||
### Browser | ||
### Bower | ||
``` | ||
bower install object-path | ||
bower install object-path --save | ||
``` | ||
@@ -43,3 +52,5 @@ | ||
b: "d", | ||
c: ["e", "f"] | ||
c: ["e", "f"], | ||
'\u1200': 'unicode key', | ||
'dot.dot': 'key' | ||
} | ||
@@ -52,2 +63,4 @@ }; | ||
objectPath.get(obj, "a.b"); //returns "d" | ||
objectPath.get(obj, ["a", "dot.dot"]); //returns "key" | ||
objectPath.get(obj, 'a.\u1200'); //returns "unicode key" | ||
@@ -86,2 +99,3 @@ //get the first non-undefined value | ||
objectPath.ensureExists(obj, "a.k.1", "DEFAULT"); | ||
var oldVal = objectPath.ensureExists(obj, "a.b", "DEFAULT"); // oldval === "d" | ||
@@ -111,3 +125,11 @@ //deletes a path | ||
``` | ||
### Notes | ||
`object-path` is intentionally designed to access only an object's own properties | ||
### Immutability | ||
If you are looking for an *immutable* alternative of this library, you can take a look at: [object-path-immutable](https://github.com/mariocasciaro/object-path-immutable) | ||
### Credits | ||
@@ -114,0 +136,0 @@ |
156
test.js
@@ -0,1 +1,2 @@ | ||
'use strict'; | ||
var expect = require('chai').expect, | ||
@@ -18,2 +19,22 @@ objectPath = require('./index.js'); | ||
describe('get', function() { | ||
it('should return the value using unicode key', function() { | ||
var obj = { | ||
'15\u00f8C': { | ||
'3\u0111': 1 | ||
} | ||
}; | ||
expect(objectPath.get(obj, '15\u00f8C.3\u0111')).to.be.equal(1); | ||
expect(objectPath.get(obj, ['15\u00f8C','3\u0111'])).to.be.equal(1); | ||
}); | ||
it('should return the value using dot in key', function() { | ||
var obj = { | ||
'a.b': { | ||
'looks.like': 1 | ||
} | ||
}; | ||
expect(objectPath.get(obj, 'a.b.looks.like')).to.be.equal(void 0); | ||
expect(objectPath.get(obj, ['a.b','looks.like'])).to.be.equal(1); | ||
}); | ||
it('should return the value under shallow object', function() { | ||
@@ -80,3 +101,8 @@ var obj = getTestObj(); | ||
it('should skip non own properties with isEmpty', function(){ | ||
it('should return the default value when object is null or undefined', function() { | ||
expect(objectPath.get(null, 'test', 'a')).to.be.deep.equal('a'); | ||
expect(objectPath.get(undefined, 'test', 'a')).to.be.deep.equal('a'); | ||
}); | ||
it('should skip non own properties', function() { | ||
var Base = function(enabled){ }; | ||
@@ -99,2 +125,3 @@ Base.prototype = { | ||
expect(objectPath.get(extended, 'enabled')).to.be.equal(true); | ||
expect(objectPath.get(extended, 'one')).to.be.equal(undefined); | ||
}); | ||
@@ -105,2 +132,24 @@ }); | ||
describe('set', function() { | ||
it('should set the value using unicode key', function() { | ||
var obj = { | ||
'15\u00f8C': { | ||
'3\u0111': 1 | ||
} | ||
}; | ||
objectPath.set(obj, '15\u00f8C.3\u0111', 2); | ||
expect(objectPath.get(obj, '15\u00f8C.3\u0111')).to.be.equal(2); | ||
objectPath.set(obj, '15\u00f8C.3\u0111', 3); | ||
expect(objectPath.get(obj, ['15\u00f8C','3\u0111'])).to.be.equal(3); | ||
}); | ||
it('should set the value using dot in key', function() { | ||
var obj = { | ||
'a.b': { | ||
'looks.like': 1 | ||
} | ||
}; | ||
objectPath.set(obj, ['a.b','looks.like'], 2); | ||
expect(objectPath.get(obj, ['a.b','looks.like'])).to.be.equal(2); | ||
}); | ||
it('should set value under shallow object', function() { | ||
@@ -182,2 +231,16 @@ var obj = getTestObj(); | ||
describe('push', function() { | ||
it('should push value to existing array using unicode key', function() { | ||
var obj = getTestObj(); | ||
objectPath.push(obj, 'b.\u1290c', 'l'); | ||
expect(obj).to.have.deep.property('b.\u1290c.0', 'l'); | ||
objectPath.push(obj, ['b','\u1290c'], 'l'); | ||
expect(obj).to.have.deep.property('b.\u1290c.1', 'l'); | ||
}); | ||
it('should push value to existing array using dot key', function() { | ||
var obj = getTestObj(); | ||
objectPath.push(obj, ['b','z.d'], 'l'); | ||
expect(objectPath.get(obj, ['b','z.d', 0])).to.be.equal('l'); | ||
}); | ||
it('should push value to existing array', function() { | ||
@@ -219,2 +282,8 @@ var obj = getTestObj(); | ||
expect(obj).to.have.deep.property('b.g.1.l', 'test'); | ||
oldVal = objectPath.ensureExists(obj, 'b.\u8210', 'ok'); | ||
expect(oldVal).to.not.exist; | ||
expect(obj).to.have.deep.property('b.\u8210', 'ok'); | ||
oldVal = objectPath.ensureExists(obj, ['b','dot.dot'], 'ok'); | ||
expect(oldVal).to.not.exist; | ||
expect(objectPath.get(obj, ['b','dot.dot'])).to.be.equal('ok'); | ||
}); | ||
@@ -288,2 +357,12 @@ | ||
}); | ||
it('works with unicode and dot keys', function(){ | ||
var obj = { | ||
'\u7591': true, | ||
'dot.dot': false | ||
}; | ||
expect(objectPath.coalesce(obj, ['1', '\u7591', 'a.b'])).to.equal(true); | ||
expect(objectPath.coalesce(obj, ['1', ['dot.dot'], '\u7591'])).to.equal(false); | ||
}); | ||
}); | ||
@@ -338,3 +417,4 @@ | ||
objectPath.empty(obj, 'instance.test'); | ||
expect(obj.instance.test).to.equal(null); | ||
//instance.test is not own property, so it shouldn't be emptied | ||
expect(obj.instance.test).to.be.a('function'); | ||
expect(Instance.prototype.test).to.be.a('function'); | ||
@@ -380,2 +460,4 @@ | ||
objectPath.set(obj, 'b.h.az', 'test'); | ||
objectPath.set(obj, 'b.\ubeef', 'test'); | ||
objectPath.set(obj, ['b','dot.dot'], 'test'); | ||
@@ -385,2 +467,3 @@ expect(obj).to.have.deep.property('b.g.1.0','test'); | ||
expect(obj).to.have.deep.property('b.h.az','test'); | ||
expect(obj).to.have.deep.property('b.\ubeef','test'); | ||
@@ -395,2 +478,8 @@ objectPath.del(obj, 'b.h.az'); | ||
objectPath.del(obj, 'b.\ubeef'); | ||
expect(obj).to.not.have.deep.property('b.\ubeef'); | ||
objectPath.del(obj, ['b','dot.dot']); | ||
expect(objectPath.get(obj, ['b','dot.dot'])).to.be.equal(void 0); | ||
objectPath.del(obj, ['b','g','1','0']); | ||
@@ -468,3 +557,3 @@ expect(obj).to.not.have.deep.property('b.g.1.0'); | ||
it('should return false for empty object', function () { | ||
expect(objectPath.has({}, 'a')).to.be.false; | ||
expect(objectPath.has({}, 'a')).to.be.equal(false); | ||
}); | ||
@@ -474,5 +563,5 @@ | ||
var obj = getTestObj(); | ||
expect(objectPath.has(obj, '')).to.be.false; | ||
expect(objectPath.has(obj, [])).to.be.false; | ||
expect(objectPath.has(obj, [''])).to.be.false; | ||
expect(objectPath.has(obj, '')).to.be.equal(false); | ||
expect(objectPath.has(obj, [])).to.be.equal(false); | ||
expect(objectPath.has(obj, [''])).to.be.equal(false); | ||
}); | ||
@@ -482,6 +571,6 @@ | ||
var obj = getTestObj(); | ||
expect(objectPath.has(obj, 'a')).to.be.true; | ||
expect(objectPath.has(obj, ['a'])).to.be.true; | ||
expect(objectPath.has(obj, 'z')).to.be.false; | ||
expect(objectPath.has(obj, ['z'])).to.be.false; | ||
expect(objectPath.has(obj, 'a')).to.be.equal(true); | ||
expect(objectPath.has(obj, ['a'])).to.be.equal(true); | ||
expect(objectPath.has(obj, 'z')).to.be.equal(false); | ||
expect(objectPath.has(obj, ['z'])).to.be.equal(false); | ||
}); | ||
@@ -491,6 +580,6 @@ | ||
var obj = getTestObj(); | ||
expect(objectPath.has(obj.b.d, 0)).to.be.true; | ||
expect(objectPath.has(obj.b, 0)).to.be.false; | ||
expect(objectPath.has(obj.b.d, 10)).to.be.false; | ||
expect(objectPath.has(obj.b, 10)).to.be.false; | ||
expect(objectPath.has(obj.b.d, 0)).to.be.equal(true); | ||
expect(objectPath.has(obj.b, 0)).to.be.equal(false); | ||
expect(objectPath.has(obj.b.d, 10)).to.be.equal(false); | ||
expect(objectPath.has(obj.b, 10)).to.be.equal(false); | ||
}); | ||
@@ -500,6 +589,6 @@ | ||
var obj = getTestObj(); | ||
expect(objectPath.has(obj, 'b.f')).to.be.true; | ||
expect(objectPath.has(obj, ['b','f'])).to.be.true; | ||
expect(objectPath.has(obj, 'b.g')).to.be.false; | ||
expect(objectPath.has(obj, ['b','g'])).to.be.false; | ||
expect(objectPath.has(obj, 'b.f')).to.be.equal(true); | ||
expect(objectPath.has(obj, ['b','f'])).to.be.equal(true); | ||
expect(objectPath.has(obj, 'b.g')).to.be.equal(false); | ||
expect(objectPath.has(obj, ['b','g'])).to.be.equal(false); | ||
}); | ||
@@ -509,4 +598,4 @@ | ||
var obj = getTestObj(); | ||
expect(objectPath.has(obj, 'b.d.0')).to.be.true; | ||
expect(objectPath.has(obj, ['b','d',0])).to.be.true; | ||
expect(objectPath.has(obj, 'b.d.0')).to.be.equal(true); | ||
expect(objectPath.has(obj, ['b','d',0])).to.be.equal(true); | ||
}); | ||
@@ -516,6 +605,6 @@ | ||
var obj = getTestObj(); | ||
expect(objectPath.has(obj, 'b.e.1.f')).to.be.true; | ||
expect(objectPath.has(obj, ['b','e',1,'f'])).to.be.true; | ||
expect(objectPath.has(obj, 'b.e.1.f.g.h.i')).to.be.false; | ||
expect(objectPath.has(obj, ['b','e',1,'f','g','h','i'])).to.be.false; | ||
expect(objectPath.has(obj, 'b.e.1.f')).to.be.equal(true); | ||
expect(objectPath.has(obj, ['b','e',1,'f'])).to.be.equal(true); | ||
expect(objectPath.has(obj, 'b.e.1.f.g.h.i')).to.be.equal(false); | ||
expect(objectPath.has(obj, ['b','e',1,'f','g','h','i'])).to.be.equal(false); | ||
}); | ||
@@ -525,4 +614,4 @@ | ||
var obj = { '1a': 'foo' }; | ||
expect(objectPath.has(obj, '1a')).to.be.true; | ||
expect(objectPath.has(obj, ['1a'])).to.be.true; | ||
expect(objectPath.has(obj, '1a')).to.be.equal(true); | ||
expect(objectPath.has(obj, ['1a'])).to.be.equal(true); | ||
}); | ||
@@ -532,6 +621,6 @@ | ||
var obj = {}; | ||
expect(objectPath.has(obj, 'key')).to.be.false; | ||
expect(objectPath.has(obj, 'key')).to.be.equal(false); | ||
obj.key = undefined; | ||
expect(objectPath.has(obj, 'key')).to.be.true; | ||
expect(objectPath.has(obj, 'key')).to.be.equal(true); | ||
}); | ||
@@ -634,3 +723,4 @@ }); | ||
model.empty('instance.test'); | ||
expect(obj.instance.test).to.equal(null); | ||
//instance.test is not own property so it shouldn't be emptied | ||
expect(obj.instance.test).to.be.a('function'); | ||
expect(Instance.prototype.test).to.be.a('function'); | ||
@@ -699,8 +789,8 @@ | ||
expect(model.has('a')).to.be.true; | ||
expect(model.has(['a'])).to.be.true; | ||
expect(model.has('z')).to.be.false; | ||
expect(model.has(['z'])).to.be.false; | ||
expect(model.has('a')).to.be.equal(true); | ||
expect(model.has(['a'])).to.be.equal(true); | ||
expect(model.has('z')).to.be.equal(false); | ||
expect(model.has(['z'])).to.be.equal(false); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37849
10
964
133
6