seamless-immutable
Advanced tools
Comparing version 6.2.0 to 6.3.0
{ | ||
"name": "seamless-immutable", | ||
"version": "6.2.0", | ||
"version": "6.3.0", | ||
"description": "Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.", | ||
@@ -9,2 +9,3 @@ "main": "src/seamless-immutable.js", | ||
"coveralls": "2.11.8", | ||
"deep-equal": "1.0.1", | ||
"envify": "3.4.0", | ||
@@ -16,3 +17,3 @@ "grunt": "0.4.5", | ||
"jscheck": "0.2.0", | ||
"lodash": "4.5.1", | ||
"lodash": "4.15.0", | ||
"mocha": "2.4.5", | ||
@@ -19,0 +20,0 @@ "mocha-istanbul": "0.2.0", |
@@ -224,2 +224,20 @@ seamless-immutable | ||
### replace | ||
```javascript | ||
var obj1 = Immutable({a: {b: 'test'}, c: 'test'}) | ||
var obj2 = obj1.replace({a: {b: 'test'}}, {deep: true}) | ||
// returns Immutable({a: {b: 'test'}}); | ||
obj1 === obj2 | ||
// returns false | ||
obj1.b === obj2.b | ||
// returns true because child .b objects were identical | ||
``` | ||
Returns an Immutable Object containing the properties and values of the | ||
second object only. With deep merge, all child objects are checked for | ||
equality and the original immutable object is returned when possible. | ||
A second argument can be provided to perform a deep merge: `{deep: true}`. | ||
### set | ||
@@ -239,2 +257,4 @@ | ||
A second argument can be provided to perform a deep compare: `{deep: true}`. | ||
### setIn | ||
@@ -249,2 +269,4 @@ | ||
A second argument can be provided to perform a deep compare: `{deep: true}`. | ||
### update | ||
@@ -313,2 +335,6 @@ | ||
#### 6.3.0 | ||
Adds optional deep compare for `.set`, `.setIn` and `.replace` | ||
#### 6.2.0 | ||
@@ -315,0 +341,0 @@ |
@@ -42,2 +42,7 @@ (function() { | ||
function isEqual(a, b) { | ||
// Avoid false positives due to (NaN !== NaN) evaluating to true | ||
return (a === b || (a !== a && b !== b)); | ||
} | ||
function isMergableObject(target) { | ||
@@ -105,5 +110,12 @@ return target !== null && typeof target === "object" && !(Array.isArray(target)) && !(target instanceof Date); | ||
function arraySet(idx, value) { | ||
if (idx in this && this[idx] === value) { | ||
return this; | ||
function arraySet(idx, value, config) { | ||
var deep = config && config.deep; | ||
if (idx in this) { | ||
if (deep && this[idx] !== value && isMergableObject(value) && isMergableObject(this[idx])) { | ||
value = this[idx].merge(value, {deep: true, mode: 'replace'}); | ||
} | ||
if (isEqual(this[idx], value)) { | ||
return this; | ||
} | ||
} | ||
@@ -118,7 +130,7 @@ | ||
function arraySetIn(pth, value) { | ||
function arraySetIn(pth, value, config) { | ||
var head = pth[0]; | ||
if (pth.length === 1) { | ||
return arraySet.call(this, head, value); | ||
return arraySet.call(this, head, value, config); | ||
} else { | ||
@@ -346,2 +358,3 @@ var tail = pth.slice(1); | ||
deep = config && config.deep, | ||
mode = config && config.mode || 'merge', | ||
merger = config && config.merger, | ||
@@ -360,6 +373,4 @@ result; | ||
(mergerResult !== undefined) || | ||
(!currentObj.hasOwnProperty(key) || | ||
((immutableValue !== currentValue) && | ||
// Avoid false positives due to (NaN !== NaN) evaluating to true | ||
(immutableValue === immutableValue)))) { | ||
(!currentObj.hasOwnProperty(key)) || | ||
!isEqual(immutableValue, currentValue)) { | ||
@@ -376,5 +387,3 @@ var newValue; | ||
// We check (newValue === newValue) because (NaN !== NaN) in JS | ||
if (((currentValue !== newValue) && (newValue === newValue)) || | ||
!currentObj.hasOwnProperty(key)) { | ||
if (!isEqual(currentValue, newValue) || !currentObj.hasOwnProperty(key)) { | ||
if (result === undefined) { | ||
@@ -390,2 +399,14 @@ // Make a shallow clone of the current object. | ||
function clearDroppedKeys(currentObj, otherObj) { | ||
for (var key in currentObj) { | ||
if (!otherObj.hasOwnProperty(key)) { | ||
if (result === undefined) { | ||
// Make a shallow clone of the current object. | ||
result = quickCopy(currentObj, currentObj.instantiateEmptyObject()); | ||
} | ||
delete result[key]; | ||
} | ||
} | ||
} | ||
var key; | ||
@@ -401,5 +422,8 @@ | ||
} | ||
if (mode === 'replace') { | ||
clearDroppedKeys(this, other); | ||
} | ||
} else { | ||
// We also accept an Array | ||
for (var index=0; index < other.length; index++) { | ||
for (var index = 0, length = other.length; index < length; index++) { | ||
var otherFromArray = other[index]; | ||
@@ -423,8 +447,23 @@ | ||
function objectReplace(value, config) { | ||
var deep = config && config.deep; | ||
// Calling .replace() with no arguments is a no-op. Don't bother cloning. | ||
if (arguments.length === 0) { | ||
return this; | ||
} | ||
if (value === null || typeof value !== "object") { | ||
throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not " + JSON.stringify(value)); | ||
} | ||
return this.merge(value, {deep: deep, mode: 'replace'}); | ||
} | ||
var immutableEmptyObject = Immutable({}); | ||
function objectSetIn(path, value) { | ||
function objectSetIn(path, value, config) { | ||
var head = path[0]; | ||
if (path.length === 1) { | ||
return objectSet.call(this, head, value); | ||
return objectSet.call(this, head, value, config); | ||
} | ||
@@ -452,5 +491,12 @@ | ||
function objectSet(property, value) { | ||
if (this.hasOwnProperty(property) && this[property] === value) { | ||
return this; | ||
function objectSet(property, value, config) { | ||
var deep = config && config.deep; | ||
if (this.hasOwnProperty(property)) { | ||
if (deep && this[property] !== value && isMergableObject(value) && isMergableObject(this[property])) { | ||
value = this[property].merge(value, {deep: true, mode: 'replace'}); | ||
} | ||
if (isEqual(this[property], value)) { | ||
return this; | ||
} | ||
} | ||
@@ -517,2 +563,3 @@ | ||
addPropertyTo(obj, "merge", merge); | ||
addPropertyTo(obj, "replace", objectReplace); | ||
addPropertyTo(obj, "without", without); | ||
@@ -609,2 +656,3 @@ addPropertyTo(obj, "asMutable", asMutableObject); | ||
Immutable.merge = toStatic(merge); | ||
Immutable.replace = toStatic(objectReplace); | ||
Immutable.without = toStatic(without); | ||
@@ -611,0 +659,0 @@ Immutable.asMutable = toStaticObjectOrArray(asMutableObject, asMutableArray); |
@@ -1,1 +0,1 @@ | ||
/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b,c){a(b,c,function(){throw new f("The "+c+" method cannot be invoked on an Immutable data structure.")})}function c(b){a(b,I,!0)}function d(a){return"object"==typeof a?null===a||Boolean(Object.getOwnPropertyDescriptor(a,I)):!0}function e(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function f(a){var b=new Error(a);return b.__proto__=f,b}function g(a,d){c(a);for(var e in d)d.hasOwnProperty(e)&&b(a,d[e]);return Object.freeze(a),a}function h(b,c){var d=b[c];a(b,c,function(){return D(d.apply(b,arguments))})}function i(a,b){if(a in this&&this[a]===b)return this;var c=p.call(this);return c[a]=D(b),k(c)}function j(a,b){var c=a[0];if(1===a.length)return i.call(this,c,b);var d,e=a.slice(1),f=this[c];if("object"==typeof f&&null!==f&&"function"==typeof f.setIn)d=f.setIn(e,b);else{var g=e[0];d=""!==g&&isFinite(g)?j.call(O,e,b):u.call(P,e,b)}if(c in this&&f===d)return this;var h=p.call(this);return h[c]=d,k(h)}function k(b){for(var c in M)if(M.hasOwnProperty(c)){var d=M[c];h(b,d)}a(b,"flatMap",n),a(b,"asObject",q),a(b,"asMutable",p),a(b,"set",i),a(b,"setIn",j),a(b,"update",w),a(b,"updateIn",y);for(var e=0,f=b.length;f>e;e++)b[e]=D(b[e]);return g(b,L)}function l(b){return a(b,"asMutable",m),g(b,N)}function m(){return new Date(this.getTime())}function n(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return k(c)}function o(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return-1!==b.indexOf(c)}}var c=this.instantiateEmptyObject();for(var d in this)this.hasOwnProperty(d)&&a(this[d],d)===!1&&(c[d]=this[d]);return B(c,{instantiateEmptyObject:this.instantiateEmptyObject})}function p(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(r(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function q(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return B(c)}function r(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,I)||a instanceof Date?a:a.asMutable({deep:!0})}function s(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function t(a,b){function c(a,c,f){var g=D(c[f]),j=i&&i(a[f],g,b),k=a[f];if(void 0!==d||void 0!==j||!a.hasOwnProperty(f)||g!==k&&g===g){var l;l=j?j:h&&e(k)&&e(g)?k.merge(g,b):g,(k!==l&&l===l||!a.hasOwnProperty(f))&&(void 0===d&&(d=s(a,a.instantiateEmptyObject())),d[f]=l)}}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var d,f,g=Array.isArray(a),h=b&&b.deep,i=b&&b.merger;if(g)for(var j=0;j<a.length;j++){var k=a[j];for(f in k)k.hasOwnProperty(f)&&c(void 0!==d?d:this,k,f)}else for(f in a)Object.getOwnPropertyDescriptor(a,f)&&c(this,a,f);return void 0===d?this:B(d,{instantiateEmptyObject:this.instantiateEmptyObject})}function u(a,b){var c=a[0];if(1===a.length)return v.call(this,c,b);var d,e=a.slice(1),f=this[c];if(d=this.hasOwnProperty(c)&&"object"==typeof f&&null!==f&&"function"==typeof f.setIn?f.setIn(e,b):u.call(P,e,b),this.hasOwnProperty(c)&&f===d)return this;var g=s(this,this.instantiateEmptyObject());return g[c]=d,B(g,this)}function v(a,b){if(this.hasOwnProperty(a)&&this[a]===b)return this;var c=s(this,this.instantiateEmptyObject());return c[a]=D(b),B(c,this)}function w(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return this.set(a,b.apply(d,[d].concat(c)))}function x(a,b){for(var c=0,d=b.length;null!=a&&d>c;c++)a=a[b[c]];return c&&c==d?a:void 0}function y(a,b){var c=Array.prototype.slice.call(arguments,2),d=x(this,a);return this.setIn(a,b.apply(d,[d].concat(c)))}function z(a){var b,c=this.instantiateEmptyObject();if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=r(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function A(){return{}}function B(b,c){var d=c&&c.instantiateEmptyObject?c.instantiateEmptyObject:A;return a(b,"merge",t),a(b,"without",o),a(b,"asMutable",z),a(b,"instantiateEmptyObject",d),a(b,"set",v),a(b,"setIn",u),a(b,"update",w),a(b,"updateIn",y),g(b,J)}function C(a){return"object"==typeof a&&null!==a&&(a.$$typeof===H||a.$$typeof===G)}function D(a,b,c){if(d(a)||C(a))return a;if(Array.isArray(a))return k(a.slice());if(a instanceof Date)return l(new Date(a.getTime()));var e=b&&b.prototype,g=e&&e!==Object.prototype?function(){return Object.create(e)}:A,h=g();if(null==c&&(c=64),0>=c)throw new f("Attempt to construct Immutable from a deeply nested object was detected. Have you tried to wrap an object with circular references (e.g. React element)? See https://github.com/rtfeldman/seamless-immutable/wiki/Deeply-nested-object-was-detected for details.");c-=1;for(var i in a)Object.getOwnPropertyDescriptor(a,i)&&(h[i]=D(a[i],void 0,c));return B(h,{instantiateEmptyObject:g})}function E(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function F(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}var G="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),H=60103,I="__immutable_invariants_hold",J=["setPrototypeOf"],K=["keys"],L=J.concat(["push","pop","sort","splice","shift","unshift","reverse"]),M=K.concat(["map","filter","slice","concat","reduce","reduceRight"]),N=J.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);f.prototype=Error.prototype;var O=D([]),P=D({});D.from=D,D.isImmutable=d,D.ImmutableError=f,D.merge=E(t),D.without=E(o),D.asMutable=F(z,p),D.set=F(v,i),D.setIn=F(u,j),D.update=E(w),D.updateIn=E(y),D.flatMap=E(n),D.asObject=E(q),Object.freeze(D),"object"==typeof module?module.exports=D:"object"==typeof exports?exports.Immutable=D:"object"==typeof window?window.Immutable=D:"object"==typeof global&&(global.Immutable=D)}(); | ||
/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b,c){a(b,c,function(){throw new g("The "+c+" method cannot be invoked on an Immutable data structure.")})}function c(b){a(b,K,!0)}function d(a){return"object"==typeof a?null===a||Boolean(Object.getOwnPropertyDescriptor(a,K)):!0}function e(a,b){return a===b||a!==a&&b!==b}function f(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function g(a){var b=new Error(a);return b.__proto__=g,b}function h(a,d){c(a);for(var e in d)d.hasOwnProperty(e)&&b(a,d[e]);return Object.freeze(a),a}function i(b,c){var d=b[c];a(b,c,function(){return F(d.apply(b,arguments))})}function j(a,b,c){var d=c&&c.deep;if(a in this&&(d&&this[a]!==b&&f(b)&&f(this[a])&&(b=this[a].merge(b,{deep:!0,mode:"replace"})),e(this[a],b)))return this;var g=q.call(this);return g[a]=F(b),l(g)}function k(a,b,c){var d=a[0];if(1===a.length)return j.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if("object"==typeof g&&null!==g&&"function"==typeof g.setIn)e=g.setIn(f,b);else{var h=f[0];e=""!==h&&isFinite(h)?k.call(Q,f,b):w.call(R,f,b)}if(d in this&&g===e)return this;var i=q.call(this);return i[d]=e,l(i)}function l(b){for(var c in O)if(O.hasOwnProperty(c)){var d=O[c];i(b,d)}a(b,"flatMap",o),a(b,"asObject",r),a(b,"asMutable",q),a(b,"set",j),a(b,"setIn",k),a(b,"update",y),a(b,"updateIn",A);for(var e=0,f=b.length;f>e;e++)b[e]=F(b[e]);return h(b,N)}function m(b){return a(b,"asMutable",n),h(b,P)}function n(){return new Date(this.getTime())}function o(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return l(c)}function p(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return-1!==b.indexOf(c)}}var c=this.instantiateEmptyObject();for(var d in this)this.hasOwnProperty(d)&&a(this[d],d)===!1&&(c[d]=this[d]);return D(c,{instantiateEmptyObject:this.instantiateEmptyObject})}function q(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(s(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function r(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return D(c)}function s(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,K)||a instanceof Date?a:a.asMutable({deep:!0})}function t(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function u(a,b){function c(a,c,d){var h=F(c[d]),i=l&&l(a[d],h,b),k=a[d];if(void 0!==g||void 0!==i||!a.hasOwnProperty(d)||!e(h,k)){var m;m=i?i:j&&f(k)&&f(h)?k.merge(h,b):h,e(k,m)&&a.hasOwnProperty(d)||(void 0===g&&(g=t(a,a.instantiateEmptyObject())),g[d]=m)}}function d(a,b){for(var c in a)b.hasOwnProperty(c)||(void 0===g&&(g=t(a,a.instantiateEmptyObject())),delete g[c])}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var g,h,i=Array.isArray(a),j=b&&b.deep,k=b&&b.mode||"merge",l=b&&b.merger;if(i)for(var m=0,n=a.length;n>m;m++){var o=a[m];for(h in o)o.hasOwnProperty(h)&&c(void 0!==g?g:this,o,h)}else{for(h in a)Object.getOwnPropertyDescriptor(a,h)&&c(this,a,h);"replace"===k&&d(this,a)}return void 0===g?this:D(g,{instantiateEmptyObject:this.instantiateEmptyObject})}function v(a,b){var c=b&&b.deep;if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not "+JSON.stringify(a));return this.merge(a,{deep:c,mode:"replace"})}function w(a,b,c){var d=a[0];if(1===a.length)return x.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if(e=this.hasOwnProperty(d)&&"object"==typeof g&&null!==g&&"function"==typeof g.setIn?g.setIn(f,b):w.call(R,f,b),this.hasOwnProperty(d)&&g===e)return this;var h=t(this,this.instantiateEmptyObject());return h[d]=e,D(h,this)}function x(a,b,c){var d=c&&c.deep;if(this.hasOwnProperty(a)&&(d&&this[a]!==b&&f(b)&&f(this[a])&&(b=this[a].merge(b,{deep:!0,mode:"replace"})),e(this[a],b)))return this;var g=t(this,this.instantiateEmptyObject());return g[a]=F(b),D(g,this)}function y(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return this.set(a,b.apply(d,[d].concat(c)))}function z(a,b){for(var c=0,d=b.length;null!=a&&d>c;c++)a=a[b[c]];return c&&c==d?a:void 0}function A(a,b){var c=Array.prototype.slice.call(arguments,2),d=z(this,a);return this.setIn(a,b.apply(d,[d].concat(c)))}function B(a){var b,c=this.instantiateEmptyObject();if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=s(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function C(){return{}}function D(b,c){var d=c&&c.instantiateEmptyObject?c.instantiateEmptyObject:C;return a(b,"merge",u),a(b,"replace",v),a(b,"without",p),a(b,"asMutable",B),a(b,"instantiateEmptyObject",d),a(b,"set",x),a(b,"setIn",w),a(b,"update",y),a(b,"updateIn",A),h(b,L)}function E(a){return"object"==typeof a&&null!==a&&(a.$$typeof===J||a.$$typeof===I)}function F(a,b,c){if(d(a)||E(a))return a;if(Array.isArray(a))return l(a.slice());if(a instanceof Date)return m(new Date(a.getTime()));var e=b&&b.prototype,f=e&&e!==Object.prototype?function(){return Object.create(e)}:C,h=f();if(null==c&&(c=64),0>=c)throw new g("Attempt to construct Immutable from a deeply nested object was detected. Have you tried to wrap an object with circular references (e.g. React element)? See https://github.com/rtfeldman/seamless-immutable/wiki/Deeply-nested-object-was-detected for details.");c-=1;for(var i in a)Object.getOwnPropertyDescriptor(a,i)&&(h[i]=F(a[i],void 0,c));return D(h,{instantiateEmptyObject:f})}function G(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function H(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}var I="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),J=60103,K="__immutable_invariants_hold",L=["setPrototypeOf"],M=["keys"],N=L.concat(["push","pop","sort","splice","shift","unshift","reverse"]),O=M.concat(["map","filter","slice","concat","reduce","reduceRight"]),P=L.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);g.prototype=Error.prototype;var Q=F([]),R=F({});F.from=F,F.isImmutable=d,F.ImmutableError=g,F.merge=G(u),F.replace=G(v),F.without=G(p),F.asMutable=H(B,q),F.set=H(x,j),F.setIn=H(w,k),F.update=G(y),F.updateIn=G(A),F.flatMap=G(o),F.asObject=G(r),Object.freeze(F),"object"==typeof module?module.exports=F:"object"==typeof exports?exports.Immutable=F:"object"==typeof window?window.Immutable=F:"object"==typeof global&&(global.Immutable=F)}(); |
@@ -1,1 +0,1 @@ | ||
/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b){a(b,H,!0)}function c(a){return"object"==typeof a?null===a||Boolean(Object.getOwnPropertyDescriptor(a,H)):!0}function d(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function e(a){var b=new Error(a);return b.__proto__=e,b}function f(a,c){b(a);return a}function g(b,c){var d=b[c];a(b,c,function(){return C(d.apply(b,arguments))})}function h(a,b){if(a in this&&this[a]===b)return this;var c=o.call(this);return c[a]=C(b),j(c)}function i(a,b){var c=a[0];if(1===a.length)return h.call(this,c,b);var d,e=a.slice(1),f=this[c];if("object"==typeof f&&null!==f&&"function"==typeof f.setIn)d=f.setIn(e,b);else{var g=e[0];d=""!==g&&isFinite(g)?i.call(N,e,b):t.call(O,e,b)}if(c in this&&f===d)return this;var k=o.call(this);return k[c]=d,j(k)}function j(b){for(var c in L)if(L.hasOwnProperty(c)){var d=L[c];g(b,d)}a(b,"flatMap",m),a(b,"asObject",p),a(b,"asMutable",o),a(b,"set",h),a(b,"setIn",i),a(b,"update",v),a(b,"updateIn",x);for(var e=0,j=b.length;j>e;e++)b[e]=C(b[e]);return f(b,K)}function k(b){return a(b,"asMutable",l),f(b,M)}function l(){return new Date(this.getTime())}function m(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return j(c)}function n(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return-1!==b.indexOf(c)}}var c=this.instantiateEmptyObject();for(var d in this)this.hasOwnProperty(d)&&a(this[d],d)===!1&&(c[d]=this[d]);return A(c,{instantiateEmptyObject:this.instantiateEmptyObject})}function o(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(q(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function p(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return A(c)}function q(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,H)||a instanceof Date?a:a.asMutable({deep:!0})}function r(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function s(a,b){function c(a,c,f){var g=C(c[f]),j=i&&i(a[f],g,b),k=a[f];if(void 0!==e||void 0!==j||!a.hasOwnProperty(f)||g!==k&&g===g){var l;l=j?j:h&&d(k)&&d(g)?k.merge(g,b):g,(k!==l&&l===l||!a.hasOwnProperty(f))&&(void 0===e&&(e=r(a,a.instantiateEmptyObject())),e[f]=l)}}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var e,f,g=Array.isArray(a),h=b&&b.deep,i=b&&b.merger;if(g)for(var j=0;j<a.length;j++){var k=a[j];for(f in k)k.hasOwnProperty(f)&&c(void 0!==e?e:this,k,f)}else for(f in a)Object.getOwnPropertyDescriptor(a,f)&&c(this,a,f);return void 0===e?this:A(e,{instantiateEmptyObject:this.instantiateEmptyObject})}function t(a,b){var c=a[0];if(1===a.length)return u.call(this,c,b);var d,e=a.slice(1),f=this[c];if(d=this.hasOwnProperty(c)&&"object"==typeof f&&null!==f&&"function"==typeof f.setIn?f.setIn(e,b):t.call(O,e,b),this.hasOwnProperty(c)&&f===d)return this;var g=r(this,this.instantiateEmptyObject());return g[c]=d,A(g,this)}function u(a,b){if(this.hasOwnProperty(a)&&this[a]===b)return this;var c=r(this,this.instantiateEmptyObject());return c[a]=C(b),A(c,this)}function v(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return this.set(a,b.apply(d,[d].concat(c)))}function w(a,b){for(var c=0,d=b.length;null!=a&&d>c;c++)a=a[b[c]];return c&&c==d?a:void 0}function x(a,b){var c=Array.prototype.slice.call(arguments,2),d=w(this,a);return this.setIn(a,b.apply(d,[d].concat(c)))}function y(a){var b,c=this.instantiateEmptyObject();if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=q(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function z(){return{}}function A(b,c){var d=c&&c.instantiateEmptyObject?c.instantiateEmptyObject:z;return a(b,"merge",s),a(b,"without",n),a(b,"asMutable",y),a(b,"instantiateEmptyObject",d),a(b,"set",u),a(b,"setIn",t),a(b,"update",v),a(b,"updateIn",x),f(b,I)}function B(a){return"object"==typeof a&&null!==a&&(a.$$typeof===G||a.$$typeof===F)}function C(a,b,d){if(c(a)||B(a))return a;if(Array.isArray(a))return j(a.slice());if(a instanceof Date)return k(new Date(a.getTime()));var e=b&&b.prototype,f=e&&e!==Object.prototype?function(){return Object.create(e)}:z,g=f();for(var h in a)Object.getOwnPropertyDescriptor(a,h)&&(g[h]=C(a[h],void 0,d));return A(g,{instantiateEmptyObject:f})}function D(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function E(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}var F="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),G=60103,H="__immutable_invariants_hold",I=["setPrototypeOf"],J=["keys"],K=I.concat(["push","pop","sort","splice","shift","unshift","reverse"]),L=J.concat(["map","filter","slice","concat","reduce","reduceRight"]),M=I.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);e.prototype=Error.prototype;var N=C([]),O=C({});C.from=C,C.isImmutable=c,C.ImmutableError=e,C.merge=D(s),C.without=D(n),C.asMutable=E(y,o),C.set=E(u,h),C.setIn=E(t,i),C.update=D(v),C.updateIn=D(x),C.flatMap=D(m),C.asObject=D(p),Object.freeze(C),"object"==typeof module?module.exports=C:"object"==typeof exports?exports.Immutable=C:"object"==typeof window?window.Immutable=C:"object"==typeof global&&(global.Immutable=C)}(); | ||
/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b){a(b,J,!0)}function c(a){return"object"==typeof a?null===a||Boolean(Object.getOwnPropertyDescriptor(a,J)):!0}function d(a,b){return a===b||a!==a&&b!==b}function e(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function f(a){var b=new Error(a);return b.__proto__=f,b}function g(a,c){b(a);return a}function h(b,c){var d=b[c];a(b,c,function(){return E(d.apply(b,arguments))})}function i(a,b,c){var f=c&&c.deep;if(a in this&&(f&&this[a]!==b&&e(b)&&e(this[a])&&(b=this[a].merge(b,{deep:!0,mode:"replace"})),d(this[a],b)))return this;var g=p.call(this);return g[a]=E(b),k(g)}function j(a,b,c){var d=a[0];if(1===a.length)return i.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if("object"==typeof g&&null!==g&&"function"==typeof g.setIn)e=g.setIn(f,b);else{var h=f[0];e=""!==h&&isFinite(h)?j.call(P,f,b):v.call(Q,f,b)}if(d in this&&g===e)return this;var l=p.call(this);return l[d]=e,k(l)}function k(b){for(var c in N)if(N.hasOwnProperty(c)){var d=N[c];h(b,d)}a(b,"flatMap",n),a(b,"asObject",q),a(b,"asMutable",p),a(b,"set",i),a(b,"setIn",j),a(b,"update",x),a(b,"updateIn",z);for(var e=0,f=b.length;f>e;e++)b[e]=E(b[e]);return g(b,M)}function l(b){return a(b,"asMutable",m),g(b,O)}function m(){return new Date(this.getTime())}function n(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return k(c)}function o(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return-1!==b.indexOf(c)}}var c=this.instantiateEmptyObject();for(var d in this)this.hasOwnProperty(d)&&a(this[d],d)===!1&&(c[d]=this[d]);return C(c,{instantiateEmptyObject:this.instantiateEmptyObject})}function p(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(r(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function q(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return C(c)}function r(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,J)||a instanceof Date?a:a.asMutable({deep:!0})}function s(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function t(a,b){function c(a,c,f){var h=E(c[f]),i=l&&l(a[f],h,b),k=a[f];if(void 0!==g||void 0!==i||!a.hasOwnProperty(f)||!d(h,k)){var m;m=i?i:j&&e(k)&&e(h)?k.merge(h,b):h,d(k,m)&&a.hasOwnProperty(f)||(void 0===g&&(g=s(a,a.instantiateEmptyObject())),g[f]=m)}}function f(a,b){for(var c in a)b.hasOwnProperty(c)||(void 0===g&&(g=s(a,a.instantiateEmptyObject())),delete g[c])}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var g,h,i=Array.isArray(a),j=b&&b.deep,k=b&&b.mode||"merge",l=b&&b.merger;if(i)for(var m=0,n=a.length;n>m;m++){var o=a[m];for(h in o)o.hasOwnProperty(h)&&c(void 0!==g?g:this,o,h)}else{for(h in a)Object.getOwnPropertyDescriptor(a,h)&&c(this,a,h);"replace"===k&&f(this,a)}return void 0===g?this:C(g,{instantiateEmptyObject:this.instantiateEmptyObject})}function u(a,b){var c=b&&b.deep;if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not "+JSON.stringify(a));return this.merge(a,{deep:c,mode:"replace"})}function v(a,b,c){var d=a[0];if(1===a.length)return w.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if(e=this.hasOwnProperty(d)&&"object"==typeof g&&null!==g&&"function"==typeof g.setIn?g.setIn(f,b):v.call(Q,f,b),this.hasOwnProperty(d)&&g===e)return this;var h=s(this,this.instantiateEmptyObject());return h[d]=e,C(h,this)}function w(a,b,c){var f=c&&c.deep;if(this.hasOwnProperty(a)&&(f&&this[a]!==b&&e(b)&&e(this[a])&&(b=this[a].merge(b,{deep:!0,mode:"replace"})),d(this[a],b)))return this;var g=s(this,this.instantiateEmptyObject());return g[a]=E(b),C(g,this)}function x(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return this.set(a,b.apply(d,[d].concat(c)))}function y(a,b){for(var c=0,d=b.length;null!=a&&d>c;c++)a=a[b[c]];return c&&c==d?a:void 0}function z(a,b){var c=Array.prototype.slice.call(arguments,2),d=y(this,a);return this.setIn(a,b.apply(d,[d].concat(c)))}function A(a){var b,c=this.instantiateEmptyObject();if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=r(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function B(){return{}}function C(b,c){var d=c&&c.instantiateEmptyObject?c.instantiateEmptyObject:B;return a(b,"merge",t),a(b,"replace",u),a(b,"without",o),a(b,"asMutable",A),a(b,"instantiateEmptyObject",d),a(b,"set",w),a(b,"setIn",v),a(b,"update",x),a(b,"updateIn",z),g(b,K)}function D(a){return"object"==typeof a&&null!==a&&(a.$$typeof===I||a.$$typeof===H)}function E(a,b,d){if(c(a)||D(a))return a;if(Array.isArray(a))return k(a.slice());if(a instanceof Date)return l(new Date(a.getTime()));var e=b&&b.prototype,f=e&&e!==Object.prototype?function(){return Object.create(e)}:B,g=f();for(var h in a)Object.getOwnPropertyDescriptor(a,h)&&(g[h]=E(a[h],void 0,d));return C(g,{instantiateEmptyObject:f})}function F(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function G(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}var H="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),I=60103,J="__immutable_invariants_hold",K=["setPrototypeOf"],L=["keys"],M=K.concat(["push","pop","sort","splice","shift","unshift","reverse"]),N=L.concat(["map","filter","slice","concat","reduce","reduceRight"]),O=K.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);f.prototype=Error.prototype;var P=E([]),Q=E({});E.from=E,E.isImmutable=c,E.ImmutableError=f,E.merge=F(t),E.replace=F(u),E.without=F(o),E.asMutable=G(A,p),E.set=G(w,i),E.setIn=G(v,j),E.update=F(x),E.updateIn=F(z),E.flatMap=F(n),E.asObject=F(q),Object.freeze(E),"object"==typeof module?module.exports=E:"object"==typeof exports?exports.Immutable=E:"object"==typeof window?window.Immutable=E:"object"==typeof global&&(global.Immutable=E)}(); |
@@ -42,2 +42,7 @@ (function() { | ||
function isEqual(a, b) { | ||
// Avoid false positives due to (NaN !== NaN) evaluating to true | ||
return (a === b || (a !== a && b !== b)); | ||
} | ||
function isMergableObject(target) { | ||
@@ -105,5 +110,12 @@ return target !== null && typeof target === "object" && !(Array.isArray(target)) && !(target instanceof Date); | ||
function arraySet(idx, value) { | ||
if (idx in this && this[idx] === value) { | ||
return this; | ||
function arraySet(idx, value, config) { | ||
var deep = config && config.deep; | ||
if (idx in this) { | ||
if (deep && this[idx] !== value && isMergableObject(value) && isMergableObject(this[idx])) { | ||
value = this[idx].merge(value, {deep: true, mode: 'replace'}); | ||
} | ||
if (isEqual(this[idx], value)) { | ||
return this; | ||
} | ||
} | ||
@@ -118,7 +130,7 @@ | ||
function arraySetIn(pth, value) { | ||
function arraySetIn(pth, value, config) { | ||
var head = pth[0]; | ||
if (pth.length === 1) { | ||
return arraySet.call(this, head, value); | ||
return arraySet.call(this, head, value, config); | ||
} else { | ||
@@ -346,2 +358,3 @@ var tail = pth.slice(1); | ||
deep = config && config.deep, | ||
mode = config && config.mode || 'merge', | ||
merger = config && config.merger, | ||
@@ -360,6 +373,4 @@ result; | ||
(mergerResult !== undefined) || | ||
(!currentObj.hasOwnProperty(key) || | ||
((immutableValue !== currentValue) && | ||
// Avoid false positives due to (NaN !== NaN) evaluating to true | ||
(immutableValue === immutableValue)))) { | ||
(!currentObj.hasOwnProperty(key)) || | ||
!isEqual(immutableValue, currentValue)) { | ||
@@ -376,5 +387,3 @@ var newValue; | ||
// We check (newValue === newValue) because (NaN !== NaN) in JS | ||
if (((currentValue !== newValue) && (newValue === newValue)) || | ||
!currentObj.hasOwnProperty(key)) { | ||
if (!isEqual(currentValue, newValue) || !currentObj.hasOwnProperty(key)) { | ||
if (result === undefined) { | ||
@@ -390,2 +399,14 @@ // Make a shallow clone of the current object. | ||
function clearDroppedKeys(currentObj, otherObj) { | ||
for (var key in currentObj) { | ||
if (!otherObj.hasOwnProperty(key)) { | ||
if (result === undefined) { | ||
// Make a shallow clone of the current object. | ||
result = quickCopy(currentObj, currentObj.instantiateEmptyObject()); | ||
} | ||
delete result[key]; | ||
} | ||
} | ||
} | ||
var key; | ||
@@ -401,5 +422,8 @@ | ||
} | ||
if (mode === 'replace') { | ||
clearDroppedKeys(this, other); | ||
} | ||
} else { | ||
// We also accept an Array | ||
for (var index=0; index < other.length; index++) { | ||
for (var index = 0, length = other.length; index < length; index++) { | ||
var otherFromArray = other[index]; | ||
@@ -423,8 +447,23 @@ | ||
function objectReplace(value, config) { | ||
var deep = config && config.deep; | ||
// Calling .replace() with no arguments is a no-op. Don't bother cloning. | ||
if (arguments.length === 0) { | ||
return this; | ||
} | ||
if (value === null || typeof value !== "object") { | ||
throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not " + JSON.stringify(value)); | ||
} | ||
return this.merge(value, {deep: deep, mode: 'replace'}); | ||
} | ||
var immutableEmptyObject = Immutable({}); | ||
function objectSetIn(path, value) { | ||
function objectSetIn(path, value, config) { | ||
var head = path[0]; | ||
if (path.length === 1) { | ||
return objectSet.call(this, head, value); | ||
return objectSet.call(this, head, value, config); | ||
} | ||
@@ -452,5 +491,12 @@ | ||
function objectSet(property, value) { | ||
if (this.hasOwnProperty(property) && this[property] === value) { | ||
return this; | ||
function objectSet(property, value, config) { | ||
var deep = config && config.deep; | ||
if (this.hasOwnProperty(property)) { | ||
if (deep && this[property] !== value && isMergableObject(value) && isMergableObject(this[property])) { | ||
value = this[property].merge(value, {deep: true, mode: 'replace'}); | ||
} | ||
if (isEqual(this[property], value)) { | ||
return this; | ||
} | ||
} | ||
@@ -517,2 +563,3 @@ | ||
addPropertyTo(obj, "merge", merge); | ||
addPropertyTo(obj, "replace", objectReplace); | ||
addPropertyTo(obj, "without", without); | ||
@@ -609,2 +656,3 @@ addPropertyTo(obj, "asMutable", asMutableObject); | ||
Immutable.merge = toStatic(merge); | ||
Immutable.replace = toStatic(objectReplace); | ||
Immutable.without = toStatic(without); | ||
@@ -611,0 +659,0 @@ Immutable.asMutable = toStaticObjectOrArray(asMutableObject, asMutableArray); |
@@ -14,3 +14,3 @@ var JSC = require("jscheck"); | ||
var immutable = Immutable([]); | ||
var mutable = immutable.asMutable(); | ||
var mutable = Immutable.asMutable(immutable); | ||
@@ -26,3 +26,3 @@ assertIsArray(mutable); | ||
var immutable = Immutable(array); | ||
var mutable = immutable.asMutable(); | ||
var mutable = Immutable.asMutable(immutable); | ||
@@ -42,3 +42,3 @@ assertIsArray(mutable); | ||
var immutable = Immutable(array); | ||
var mutable = immutable.asMutable({ deep: true }); | ||
var mutable = Immutable.asMutable(immutable, { deep: true }); | ||
@@ -45,0 +45,0 @@ assertIsArray(mutable); |
@@ -20,3 +20,3 @@ var JSC = require("jscheck"); | ||
var result = array.asObject(function(value, index) { | ||
var result = Immutable.asObject(array, function(value, index) { | ||
assert.strictEqual((typeof index), "number"); | ||
@@ -40,3 +40,3 @@ | ||
var result = array.asObject(); | ||
var result = Immutable.asObject(array); | ||
@@ -50,3 +50,4 @@ TestUtils.assertJsonEqual(result, obj); | ||
var expected = Immutable({all: "your base", are: {belong: "to us"}}); | ||
var actual = Immutable([{key: "all", value: "your base"}, {key: "are", value: {belong: "to us"}}]).asObject(function(elem) { | ||
var actual = Immutable([{key: "all", value: "your base"}, {key: "are", value: {belong: "to us"}}]); | ||
actual = Immutable.asObject(actual, function(elem) { | ||
return [elem.key, elem.value]; | ||
@@ -53,0 +54,0 @@ }); |
@@ -15,3 +15,3 @@ var JSC = require("jscheck"); | ||
var expected = Immutable(["foo", "foo2", "bar", "bar2", "baz", "baz2"]); | ||
var actual = Immutable(["foo", "bar", "baz"]).flatMap(function(elem) { | ||
var actual = Immutable.flatMap(Immutable(["foo", "bar", "baz"]), function(elem) { | ||
return [elem, elem + "2"]; | ||
@@ -28,3 +28,3 @@ }); | ||
var expected = _.map(array, iterator); | ||
var actual = Immutable(array).flatMap(iterator); | ||
var actual = Immutable.flatMap(Immutable(array), iterator); | ||
@@ -39,3 +39,3 @@ TestUtils.assertJsonEqual(actual, expected); | ||
var expected = _.map(array, iterator); | ||
var actual = Immutable(array).flatMap(iterator); | ||
var actual = Immutable.flatMap(Immutable(array), iterator); | ||
@@ -51,3 +51,3 @@ TestUtils.assertJsonEqual(actual, expected); | ||
var expected = _.flatten(_.map(array, iterator)); | ||
var actual = Immutable(array).flatMap(iterator); | ||
var actual = Immutable.flatMap(Immutable(array), iterator); | ||
@@ -61,3 +61,3 @@ TestUtils.assertJsonEqual(actual, expected); | ||
var expected = _.flatten(array); | ||
var actual = Immutable(array).flatMap(); | ||
var actual = Immutable.flatMap(Immutable(array)); | ||
@@ -73,3 +73,3 @@ TestUtils.assertJsonEqual(actual, expected); | ||
check(100, [JSC.array()], function(array) { | ||
var actual = Immutable(array).flatMap(iterator); | ||
var actual = Immutable.flatMap(array, iterator); | ||
@@ -76,0 +76,0 @@ TestUtils.assertJsonEqual(actual, expected); |
@@ -23,12 +23,43 @@ var JSC = require("jscheck"); | ||
var immutable = Immutable(array); | ||
var mutable = immutable.asMutable(); | ||
var mutable = array.slice(); | ||
var index = JSC.integer(0, array.length); | ||
var newValue = JSC.any(); | ||
immutable = Immutable.set(immutable, index, newValue); | ||
mutable[index] = newValue; | ||
var resultImmutable = Immutable.set(immutable, index, newValue); | ||
var resultMutable = mutable.slice(); | ||
resultMutable[index] = newValue; | ||
TestUtils.assertJsonEqual(immutable, mutable); | ||
TestUtils.assertJsonEqual(resultImmutable, resultMutable); | ||
}); | ||
}); | ||
it("sets an array element with deep compare if provided the deep flag", function () { | ||
check(100, [ JSC.array([TestUtils.TraversableObjectSpecifier]) ], function(array) { | ||
var immutable = Immutable(array); | ||
var mutable = array.slice(); | ||
var index = JSC.integer(0, array.length); | ||
var newValue; | ||
do { | ||
value = JSC.any()(); | ||
} while (TestUtils.isDeepEqual(value, array[index])); | ||
var resultImmutable = immutable.set(index, newValue, {deep: true}); | ||
var resultMutable = mutable.slice(); | ||
resultMutable[index] = newValue; | ||
TestUtils.assertJsonEqual( | ||
resultImmutable, | ||
resultMutable | ||
); | ||
assert.notEqual( | ||
immutable, | ||
resultImmutable | ||
); | ||
assert.equal( | ||
resultImmutable.set(index, newValue, {deep: true}), | ||
resultImmutable | ||
); | ||
}); | ||
}); | ||
}); | ||
@@ -40,2 +71,3 @@ | ||
var immutable = Immutable(array); | ||
var mutable = array.slice(); | ||
var value = JSC.any()(); | ||
@@ -51,16 +83,46 @@ | ||
var mutable = immutable.asMutable(); | ||
TestUtils.assertJsonEqual(immutable, mutable); | ||
if (Immutable.isImmutable(mutable[idx])) { | ||
mutable[idx] = mutable[idx].asMutable(); | ||
} | ||
mutable[idx][key] = value; | ||
var resultMutable = mutable.slice(); | ||
resultMutable[idx][key] = value; | ||
TestUtils.assertJsonEqual( | ||
Immutable.setIn(immutable, [idx, key], value), | ||
mutable | ||
resultMutable | ||
); | ||
}); | ||
}); | ||
it("sets a property by path with deep compare if provided the deep flag", function () { | ||
check(100, [ JSC.array([TestUtils.TraversableObjectSpecifier]) ], function(array) { | ||
var immutable = Immutable(array); | ||
var mutable = array.slice(); | ||
var idx = JSC.integer(0, array.length-1); | ||
var key = JSC.one_of(_.keys(immutable[idx]))(); | ||
var value; | ||
do { | ||
value = JSC.any()(); | ||
} while (TestUtils.isDeepEqual(value, immutable[idx][key])); | ||
TestUtils.assertJsonEqual(immutable, mutable); | ||
var resultImmutable = Immutable.setIn(immutable, [idx, key], value, {deep: true}); | ||
var resultMutable = mutable.slice(); | ||
resultMutable[idx][key] = value; | ||
TestUtils.assertJsonEqual( | ||
resultImmutable, | ||
resultMutable | ||
); | ||
assert.notEqual( | ||
immutable, | ||
resultImmutable | ||
); | ||
assert.equal( | ||
Immutable.setIn(resultImmutable, [idx, key], value, {deep: true}), | ||
resultImmutable | ||
); | ||
}); | ||
}); | ||
}); | ||
}; |
var testMerge = require("./ImmutableObject/test-merge.js"); | ||
var testReplace = require("./ImmutableObject/test-replace.js"); | ||
var testCompat = require("./ImmutableObject/test-compat.js"); | ||
@@ -23,2 +24,3 @@ var testWithout = require("./ImmutableObject/test-without.js"); | ||
testMerge(config); | ||
testReplace(config); | ||
testWithout(config); | ||
@@ -25,0 +27,0 @@ testAsMutable(config); |
@@ -40,3 +40,3 @@ var JSC = require("jscheck"); | ||
var immutable = Immutable(obj); | ||
var mutable = immutable.asMutable({ deep: true }); | ||
var mutable = Immutable.asMutable(immutable, { deep: true }); | ||
@@ -55,3 +55,3 @@ assertNotArray(mutable); | ||
var test = Immutable({ testDate: new Date()}); | ||
test.asMutable({deep: true}); | ||
Immutable.asMutable(test, {deep: true}); | ||
}); | ||
@@ -58,0 +58,0 @@ }); |
@@ -114,6 +114,22 @@ var JSC = require("jscheck"); | ||
it("does not reproduce #70", function() { | ||
var c = Immutable({a: {b: 1}}); | ||
it("does not reproduce except when required #70", function() { | ||
var immutable = Immutable({a: {b: 1, c: 1}}); | ||
assert.strictEqual(c, Immutable.merge(c, {a: {b: 1}}, {deep: true})); | ||
// Non-deep merge is never equal for deep objects. | ||
assert.notStrictEqual(immutable, Immutable.merge(immutable, {a: {b: 1}})); | ||
// Deep merge for only some of the keys is equal, except in replace mode. | ||
assert.strictEqual(immutable, Immutable.merge(immutable, {a: {b: 1}}, {deep: true})); | ||
assert.notStrictEqual(immutable, Immutable.merge(immutable, {a: {b: 1}}, {deep: true, mode: 'replace'})); | ||
// Identical child objects in deep merge remain equal. | ||
assert.strictEqual(immutable.a, Immutable.merge(immutable, {d: {e: 2}}, {deep: true}).a); | ||
// Deep merge for all of the keys is always equal. | ||
assert.strictEqual(immutable, Immutable.merge(immutable, {a: {b: 1, c: 1}}, {deep: true})); | ||
assert.strictEqual(immutable, Immutable.merge(immutable, {a: {b: 1, c: 1}}, {deep: true, mode: 'replace'})); | ||
// Deep merge with updated data is never equal. | ||
assert.notStrictEqual(immutable, Immutable.merge(immutable, {a: {b: 1, c: 2}}, {deep: true})); | ||
assert.notStrictEqual(immutable, Immutable.merge(immutable, {a: {b: 1, c: 2}}, {deep: true, mode: 'replace'})); | ||
}); | ||
@@ -128,2 +144,4 @@ | ||
Immutable.merge(identicalImmutable, mutable, {deep: true})); | ||
assert.strictEqual(identicalImmutable, | ||
Immutable.merge(identicalImmutable, mutable, {deep: true, mode: 'replace'})); | ||
}); | ||
@@ -301,2 +319,6 @@ }); | ||
describe("when passed a single object with deep set to true and mode set to replace", function() { | ||
generateMergeTestsFor([TestUtils.ComplexObjectSpecifier()], {deep: true, mode: 'replace'}); | ||
}); | ||
describe("when passed a single object with a custom merger", function() { | ||
@@ -314,2 +336,6 @@ generateMergeTestsFor([TestUtils.ComplexObjectSpecifier()], {merger: arrayMerger()}); | ||
describe("when passed an array of objects with deep set to true and mode set to replace", function() { | ||
generateMergeTestsFor([generateArrayOfObjects], {deep: true, mode: 'replace'}); | ||
}); | ||
describe("when passed an array of objects with a custom merger", function() { | ||
@@ -316,0 +342,0 @@ generateMergeTestsFor([generateArrayOfObjects], {merger: arrayMerger()}); |
@@ -23,3 +23,3 @@ var JSC = require("jscheck"); | ||
var immutable = Immutable(ob); | ||
var mutable = immutable.asMutable(); | ||
var mutable = Object.assign({}, ob); | ||
var prop = getPathComponent(); | ||
@@ -34,4 +34,32 @@ var value = JSC.any()(); | ||
}); | ||
it("sets a property by name with deep compare if provided the deep flag", function () { | ||
check(100, [TestUtils.ComplexObjectSpecifier()], function(ob) { | ||
var immutable = Immutable(ob); | ||
var mutable = Object.assign({}, ob); | ||
var prop = getPathComponent(); | ||
var value; | ||
do { | ||
value = JSC.any()(); | ||
} while (TestUtils.isDeepEqual(value, immutable[prop])); | ||
var resultImmutable = Immutable.set(immutable, prop, value, {deep: true}); | ||
var resultMutable = _.set(mutable, prop, value); | ||
TestUtils.assertJsonEqual( | ||
resultImmutable, | ||
resultMutable | ||
); | ||
assert.notEqual( | ||
immutable, | ||
resultImmutable | ||
); | ||
assert.equal( | ||
Immutable.set(resultImmutable, prop, value, {deep: true}), | ||
resultImmutable | ||
); | ||
}); | ||
}); | ||
}); | ||
describe("#setIn", function() { | ||
@@ -41,4 +69,3 @@ it("sets a property by path", function () { | ||
var immutable = Immutable(ob); | ||
var mutable = immutable.asMutable(); | ||
var value = JSC.any()(); | ||
var mutable = Object.assign({}, ob); | ||
@@ -52,2 +79,7 @@ TestUtils.assertJsonEqual(immutable, mutable); | ||
var value; | ||
do { | ||
value = JSC.any()(); | ||
} while (TestUtils.isDeepEqual(value, _.get(immutable, path))); | ||
TestUtils.assertJsonEqual( | ||
@@ -60,2 +92,3 @@ Immutable.setIn(immutable, path, value), | ||
it("handles setting a new object on existing leaf array correctly", function () { | ||
@@ -71,3 +104,34 @@ var ob = {foo: []}; | ||
}); | ||
it("sets a property by path with deep compare if provided the deep flag", function () { | ||
check(100, [TestUtils.ComplexObjectSpecifier()], function(ob) { | ||
var immutable = Immutable(ob); | ||
var mutable = Object.assign({}, ob); | ||
var value = JSC.any()(); | ||
TestUtils.assertJsonEqual(immutable, mutable); | ||
var path = [], depth = JSC.integer(1, 5)(); | ||
for (var j = 0; j < depth; j++) { | ||
path.push(getPathComponent()); | ||
} | ||
var resultImmutable = Immutable.setIn(immutable, path, value, {deep: true}); | ||
var resultMutable = _.set(mutable, path, value); | ||
TestUtils.assertJsonEqual( | ||
resultImmutable, | ||
resultMutable | ||
); | ||
assert.notEqual( | ||
immutable, | ||
resultImmutable | ||
); | ||
assert.equal( | ||
Immutable.setIn(resultImmutable, path, value, {deep: true}), | ||
resultImmutable | ||
); | ||
}); | ||
}); | ||
}); | ||
}; |
@@ -67,6 +67,6 @@ var JSC = require("jscheck"); | ||
it("returns the same result as a corresponding without(predicate)", function() { | ||
var expected = immutable.without(dropKeysPredicate(keys)); | ||
var expected = Immutable.without(immutable, dropKeysPredicate(keys)); | ||
var actual = useVarArgs ? | ||
immutable.without.apply(immutable, keys) : | ||
immutable.without(keys); | ||
Immutable.without.apply(Immutable, [immutable].concat(keys)) : | ||
Immutable.without(immutable, keys); | ||
TestUtils.assertJsonEqual(actual, expected); | ||
@@ -77,3 +77,3 @@ }); | ||
var expectedKeys = _.difference(_.keys(immutable), keys); | ||
var result = immutable.without(keys); | ||
var result = Immutable.without(immutable, keys); | ||
@@ -88,3 +88,4 @@ TestUtils.assertJsonEqual(_.keys(result), expectedKeys); | ||
var expected = Immutable({cat: "meow", dog: "woof"}); | ||
var actual = Immutable({cat: "meow", dog: "woof", fox: "???"}).without("fox"); | ||
var actual = Immutable({cat: "meow", dog: "woof", fox: "???"}); | ||
actual = Immutable.without(actual, "fox"); | ||
@@ -97,6 +98,8 @@ TestUtils.assertJsonEqual(actual, expected); | ||
var expected = Immutable({cat: "meow", dog: "woof"}); | ||
var actual = Immutable({cat: "meow", dog: "woof", 42: "???"}).without(42); | ||
var actual = Immutable({cat: "meow", dog: "woof", 42: "???"}); | ||
actual = Immutable.without(actual, 42); | ||
TestUtils.assertJsonEqual(actual, expected); | ||
actual = Immutable({cat: "meow", dog: "woof", 42: "???", 0.5: "xxx"}).without([42, 0.5]); | ||
actual = Immutable({cat: "meow", dog: "woof", 42: "???", 0.5: "xxx"}); | ||
actual = Immutable.without(actual, [42, 0.5]); | ||
TestUtils.assertJsonEqual(actual, expected); | ||
@@ -108,3 +111,3 @@ }); | ||
var expected = Immutable(obj); | ||
var actual = expected.without(); | ||
var actual = Immutable.without(expected); | ||
@@ -120,3 +123,3 @@ TestUtils.assertJsonEqual(actual, expected); | ||
var immutable = Immutable(data, {prototype: TestClass.prototype}); | ||
var result = immutable.without('b'); | ||
var result = Immutable.without(immutable, 'b'); | ||
@@ -144,3 +147,3 @@ TestUtils.assertJsonEqual(result, _.omit(data, 'b')); | ||
var expectedKeys = _.difference(_.keys(immutable), keys); | ||
var result = immutable.without(dropKeysPredicate(keys)); | ||
var result = Immutable.without(immutable, dropKeysPredicate(keys)); | ||
@@ -156,3 +159,3 @@ TestUtils.assertJsonEqual(_.keys(result), expectedKeys); | ||
it("returns an Immutable Object", function() { | ||
var result = immutable.without(dropKeysPredicate(keys)); | ||
var result = Immutable.without(immutable, dropKeysPredicate(keys)); | ||
assert.instanceOf(result, Object); | ||
@@ -167,3 +170,3 @@ TestUtils.assertIsDeeplyImmutable(result); | ||
var actual = immutable.without(function (value, key) { | ||
var actual = Immutable.without(immutable, function (value, key) { | ||
return _.includes(keys, key); | ||
@@ -170,0 +173,0 @@ }); |
var JSC = require("jscheck"); | ||
var assert = require("chai").assert; | ||
var _ = require("lodash"); | ||
var deepEqual = require("deep-equal"); | ||
@@ -127,2 +128,7 @@ function assertJsonEqual(first, second) { | ||
function isDeepEqual(a, b) { | ||
// Avoid false positives due to (NaN !== NaN) evaluating to true | ||
return (deepEqual(a, b) || (a !== a && b !== b)); | ||
} | ||
module.exports = function(Immutable) { | ||
@@ -138,4 +144,5 @@ return { | ||
check: check, | ||
checkImmutableMutable: wrapCheckImmutableMutable(Immutable) | ||
checkImmutableMutable: wrapCheckImmutableMutable(Immutable), | ||
isDeepEqual: isDeepEqual | ||
} | ||
}; |
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
171736
35
3176
479
15