object-path-immutable
Advanced tools
Comparing version 0.5.3 to 1.0.0
61
index.js
@@ -21,2 +21,5 @@ /* globals define */ | ||
function isEmpty (value) { | ||
if (isNumber(value)) { | ||
return false | ||
} | ||
if (!value) { | ||
@@ -50,2 +53,11 @@ return true | ||
function assignToObj (target, source) { | ||
for (var key in source) { | ||
if (_hasOwnProperty.call(source, key)) { | ||
target[key] = source[key] | ||
} | ||
} | ||
return target | ||
} | ||
function getKey (key) { | ||
@@ -105,10 +117,3 @@ var intKey = parseInt(key) | ||
var res = {} | ||
for (var key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
res[key] = obj[key] | ||
} | ||
} | ||
return res | ||
return assignToObj({}, obj) | ||
} | ||
@@ -147,2 +152,5 @@ | ||
api.set = function set (dest, src, path, value) { | ||
if (isEmpty(path)) { | ||
return value | ||
} | ||
return changeImmutable(dest, src, path, function (clonedObj, finalPath) { | ||
@@ -155,2 +163,5 @@ clonedObj[finalPath] = value | ||
api.update = function update (dest, src, path, updater) { | ||
if (isEmpty(path)) { | ||
return updater(clone(src)) | ||
} | ||
return changeImmutable(dest, src, path, function (clonedObj, finalPath) { | ||
@@ -164,2 +175,9 @@ clonedObj[finalPath] = updater(clonedObj[finalPath]) | ||
var values = Array.prototype.slice.call(arguments, 3) | ||
if (isEmpty(path)) { | ||
if (!isArray(src)) { | ||
return values | ||
} else { | ||
return src.concat(values) | ||
} | ||
} | ||
return changeImmutable(dest, src, path, function (clonedObj, finalPath) { | ||
@@ -177,2 +195,11 @@ if (!isArray(clonedObj[finalPath])) { | ||
at = ~~at | ||
if (isEmpty(path)) { | ||
if (!isArray(src)) { | ||
return [value] | ||
} | ||
var first = src.slice(0, at) | ||
first.push(value) | ||
return first.concat(src.slice(at)) | ||
} | ||
return changeImmutable(dest, src, path, function (clonedObj, finalPath) { | ||
@@ -194,3 +221,6 @@ var arr = clonedObj[finalPath] | ||
api.del = function del (dest, src, path, value, at) { | ||
api.del = function del (dest, src, path) { | ||
if (isEmpty(path)) { | ||
return void 0 | ||
} | ||
return changeImmutable(dest, src, path, function (clonedObj, finalPath) { | ||
@@ -211,12 +241,13 @@ if (Array.isArray(clonedObj)) { | ||
api.assign = function assign (dest, src, path, source) { | ||
if (isEmpty(path)) { | ||
if (isEmpty(source)) { | ||
return src | ||
} | ||
return assignToObj(clone(src), source) | ||
} | ||
return changeImmutable(dest, src, path, function (clonedObj, finalPath) { | ||
source = Object(source) | ||
var target = clone(clonedObj[finalPath], true) | ||
assignToObj(target, source) | ||
for (var key in source) { | ||
if (_hasOwnProperty.call(source, key)) { | ||
target[key] = source[key] | ||
} | ||
} | ||
clonedObj[finalPath] = target | ||
@@ -223,0 +254,0 @@ return clonedObj |
{ | ||
"name": "object-path-immutable", | ||
"version": "0.5.3", | ||
"version": "1.0.0", | ||
"description": "Modify deep object properties without modifying the original object (immutability). Works great with React and Redux.", | ||
@@ -5,0 +5,0 @@ "author": "Mario Casciaro <mariocasciaro@gmail.com>", |
@@ -15,2 +15,7 @@ [![build](https://img.shields.io/travis/mariocasciaro/object-path-immutable.svg?style=flat-square)](https://travis-ci.org/mariocasciaro/object-path-immutable) | ||
## Changelog | ||
### 1.0 | ||
- **Breaking change**: The way the library handles empty paths has changed. Before this change,all the methods were returning the original object. The new behavior is as follows: | ||
- | ||
## Install | ||
@@ -17,0 +22,0 @@ |
68
test.js
@@ -66,6 +66,6 @@ /* globals describe, it */ | ||
it('should return the original object if passed an empty path', function () { | ||
it('should return the input value if passed an empty path', function () { | ||
var obj = {} | ||
expect(op.set(obj, '', 'yo')).to.be.equal(obj) | ||
expect(op.set(obj, '', 'yo')).to.be.equal('yo') | ||
}) | ||
@@ -76,3 +76,5 @@ | ||
}) | ||
}) | ||
describe('update', function () { | ||
it('should update a deep key', function () { | ||
@@ -100,2 +102,26 @@ var obj = { | ||
}) | ||
it('should work on empty path', function () { | ||
var obj = { | ||
a: { | ||
b: 1 | ||
}, | ||
c: { | ||
d: 2 | ||
} | ||
} | ||
var newObj = op.update(obj, [], function (value) { | ||
value.e = 3 | ||
return value | ||
}) | ||
expect(newObj).not.to.be.equal(obj) | ||
expect(newObj.a).to.be.equal(obj.a) | ||
expect(obj.a).to.be.eql({b: 1}) | ||
// this should be the same | ||
expect(newObj.c).to.be.equal(obj.c) | ||
expect(newObj.a.b).to.be.equal(1) | ||
expect(newObj.e).to.be.equal(3) | ||
}) | ||
}) | ||
@@ -173,12 +199,18 @@ | ||
expect(function () { | ||
op.insert({ foo: 'bar' }, 'foo', 'baz') | ||
op.insert({foo: 'bar'}, 'foo', 'baz') | ||
}).to.throw() | ||
}) | ||
it('should return the original object if passed an empty path', function () { | ||
it('should return an array with an undefined value if passed an empty path and empty value and src is not an array', function () { | ||
var obj = {} | ||
expect(op.insert(obj, '')).to.be.equal(obj) | ||
expect(op.insert(obj, '')).to.be.deep.equal([void 0]) | ||
}) | ||
it('should insert the value in src if passed an empty path', function () { | ||
var obj = ['a', 'b', 'c'] | ||
expect(op.insert(obj, '', 'd', 1)).to.be.deep.equal(['a', 'd', 'b', 'c']) | ||
}) | ||
it('should insert at a numeric path', function () { | ||
@@ -220,10 +252,16 @@ expect(op.insert([[23, 42]], 0, 'yo', 1)).to.deep.equal([[23, 'yo', 42]]) | ||
it('should return the original object if passed an empty path', function () { | ||
it('should push into the cloned original object if passed an empty path', function () { | ||
var obj = ['yoo'] | ||
expect(op.push(obj, '', 'yo')).to.deep.equal(['yoo', 'yo']) | ||
}) | ||
it('returns new array if passed an empty path and src is not an array', function () { | ||
var obj = {} | ||
expect(op.push(obj, '', 'yo')).to.be.equal(obj) | ||
expect(op.push(obj, '', 'yo')).to.deep.equal(['yo']) | ||
}) | ||
it('should push at a numeric path', function () { | ||
expect(op.insert([[]], 0, 'yo')).to.deep.equal([['yo']]) | ||
expect(op.push([[]], 0, 'yo')).to.deep.equal([['yo']]) | ||
}) | ||
@@ -266,6 +304,6 @@ }) | ||
it('should return the original object if passed an empty path', function () { | ||
it('should return undefined if passed an empty path', function () { | ||
var obj = {} | ||
expect(op.del(obj, '')).to.be.equal(obj) | ||
expect(op.del(obj, '')).to.be.equal(undefined) | ||
}) | ||
@@ -293,3 +331,3 @@ | ||
var newObj = op.assign(obj, 'a', { b: 3 }) | ||
var newObj = op.assign(obj, 'a', {b: 3}) | ||
@@ -311,3 +349,3 @@ expect(newObj).not.to.be.equal(obj) | ||
var newObj = op.assign(obj, 'a', { c: 2 }) | ||
var newObj = op.assign(obj, 'a', {c: 2}) | ||
@@ -317,3 +355,3 @@ expect(newObj).not.to.be.equal(obj) | ||
expect(obj.a).to.be.eql({b: 1}) | ||
expect(newObj.a).to.be.eql({ b: 1, c: 2 }) | ||
expect(newObj.a).to.be.eql({b: 1, c: 2}) | ||
}) | ||
@@ -329,3 +367,3 @@ | ||
var newObj = op.assign(obj, 'a.b', { f: 'a' }) | ||
var newObj = op.assign(obj, 'a.b', {f: 'a'}) | ||
@@ -338,3 +376,3 @@ expect(newObj).not.to.be.equal(obj) | ||
it('should return the original object if passed an empty path', function () { | ||
it('should return the original object if passed an empty path and an empty value to assign', function () { | ||
var obj = {} | ||
@@ -341,0 +379,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
24206
607
0
200