Skip to content
Browse files

added new static method m8.update

  • Loading branch information...
1 parent 1f3ccf8 commit 4c175ea1fa050de136265648ef35ecea8ded3c04 @constantology committed Sep 26, 2012
Showing with 110 additions and 16 deletions.
  1. +8 −3 README.md
  2. +30 −1 m8.js
  3. +1 −1 m8.min.js
  4. +1 −1 package.json
  5. +2 −1 src/expose.js
  6. +28 −0 src/lib.js
  7. +40 −9 test/m8.test.js
View
11 README.md
@@ -172,8 +172,8 @@ Attempts to coerce primitive values "trapped" in Strings, into their real types.
```
-### m8.copy( destination:Object, source:Object[, no_overwrite:Boolean] ):Object
-Copies the properties – accessible via `Object.keys` – from the `source` Object to the `destination` Object and returns the `destination` Object.
+### m8.copy( target:Object, source:Object[, no_overwrite:Boolean] ):Object
+Copies the properties – accessible via `Object.keys` – from the `source` Object to the `target` Object and returns the `target` Object.
#### Example:
@@ -488,7 +488,7 @@ Tries the returns the `length` property of the passed `item`.
```
-### m8.merge( destination:Array|Object, source:Array|Object ):Boolean
+### m8.merge( target:Array|Object, source:Array|Object ):Boolean
Performs a "deep copy" of all the properties in `source` to `target`, so that `target` does not reference any child Arrays and/ or Objects that belong to `source`.
### m8.nativeType( item:Mixed ):String
@@ -618,6 +618,11 @@ Returns the normalised `type` of the passed item.
```
+### m8.update( target:Array|Object, source:Array|Object ):Boolean
+Performs a "deep copy" of all the properties in `source` **that are not already contained in** `target`, so that `target` does not reference any child Arrays and/ or Objects that belong to `source`.
+
+This works similarly to `m8.merge` except that existing properties are not overwritten.
+
## static properties
### m8.ENV:String
View
31 m8.js
@@ -256,6 +256,34 @@
: UNDEF;
}
+ function update( target, source ) {
+ if ( !source ) return merge( target );
+
+ switch ( nativeType( source ) ) {
+ case 'object' : return Object.keys( source ).reduce( update_object, { source : source, target : target } ).target;
+ case 'array' : return source.reduce( update_array, target );
+ default : return target;
+ }
+ }
+
+ function update_array( target, source, i ) {
+ target[i] = !got( target, i )
+ ? merge( source )
+ : nativeType( target[i] ) == nativeType( source )
+ ? update( target[i], source )
+ : target[i];
+ return target;
+ }
+
+ function update_object( o, key ) {
+ o.target[key] = !got( o.target, key )
+ ? merge( o.source[key] )
+ : nativeType( o.target[key] ) == nativeType( o.source[key] )
+ ? update( o.target[key], o.source[key] )
+ : o.target[key];
+ return o;
+ }
+
/*~ m8/src/lib.x.js ~*/
// Commonjs Modules 1.1.1: http://wiki.commonjs.org/wiki/Modules/1.1.1
// notes section: http://wiki.commonjs.org/wiki/Modules/ProposalForNativeExtension
@@ -408,7 +436,8 @@
describe : describe, empty : empty, exists : exists, expose : expose, got : got,
guid : guid, has : has, id : id, iter : iter, len : len,
merge : merge, nativeType : nativeType, noop : noop, obj : obj, range : range,
- remove : remove, tostr : tostr, type : type, valof : valof, x : x
+ remove : remove, tostr : tostr, type : type, update : update, valof : valof,
+ x : x
}, 'w' );
x( Object, Array, Boolean, Function );
View
2 m8.min.js
@@ -1 +1 @@
-!function(e,t,n){"use strict";function N(e){return e}function C(e,t){switch(st(e)){case"array":break;case"string":e=e.split(".");break;default:return k(t)}y.test(e[0])&&(t=N,e.shift());if(!e.length)return k(t);e[0].indexOf("^")||(t||e[0]=="^"?e.shift():e[0]=e[0].substring(1)),t=k(t);var n;while(n=e.shift())t=t[n]||(t[n]=G());return t}function k(t){return s=="commonjs"?t?W(t)?t.exports:t:module.exports:t||e}function L(e){var t=Number(e),n;return isNaN(t)?(n=String(e))in f?f[n]:e:t}function A(e,t,n){n=n===!0,t||(t=e,e=G());for(var r in t)!q(t,r)||n&&q(e,r)||(e[r]=t[r]);return e}function O(e,n,r){var i=E.call(arguments,3),s=j(e,n),o,u,a,f;switch(st(i[0])){case"string":u=d[i.shift()];break;case"object":u=i.shift();break;default:a=st(r),u=a!="object"&&s?Object.getOwnPropertyDescriptor(e,n):null,!u||(u=a=="function"?d.cw:d.cew)}return f=i.shift()===!0,o=i.shift()===!0,s&&!f?o&&new Error(t+".def cannot overwrite existing property: "+n+", in item type: "+ot(e)+"."):(a!="object"&&u&&(r=_(r,u)),(r.get||r.set)&&delete r.writable,Object.defineProperty(e,n,r)),N}function M(e,t,n,r,i){n||(n="cw");for(var s in t)!q(t,s)||O(e,s,t[s],n,r,i);return N}function _(e,t){return A(st(e)=="object"?e:{value:e},st(t)=="object"?t:d[String(t).toLowerCase()]||d.cew,!0)}function D(e){return!P(e)||!V(e)&&X(e)||!1}function P(e){return!(e===null||e===u||typeof e=="number"&&isNaN(e))}function H(t,n,i){typeof n!="string"&&t[r]&&(i=n,n=t[r]);if(s=="commonjs"&&W(i))i.exports=t;else{i||(i=e);var o=i[n],u=_({value:t},"ew");o&&X(o)?O(t=o,"__",u):O(i,n,u)}return i=G(),i[r]=n,i[__type__]="library",M(t,i,"w",!0),t}function B(e){return e.name||e.displayName||(String(e).match(b)||["",""])[1].trim()}function j(e,t){return arguments.length>2?R(j,e,Array.coerce(arguments,1)):t in Object(e)}function F(){return S.replace(g,I)}function I(e){var t=v()*16|0;return(e=="x"?t:t&3|8).toString(16)}function q(e,t){return arguments.length>2?R(q,e,Array.coerce(arguments,1)):o.hasOwnProperty.call(e,t)}function R(e,t,n){return n.some(function(n){return e(t,n)})}function U(e,t){return e?j(e,"id")&&!D(e.id)?e.id:e.id=z(t):z(t)}function z(e){return(e||p)+"-"+ ++h}function W(e){if(a===null)return!1;try{return e instanceof a}catch(t){return!1}}function X(e){return j(e,"length")||st(e)=="object"}function V(e){return("length"in(e=Object(e))?e:Object.keys(e)).length}function $(e,t){var n;if(!t)switch(n=st(e)){case"array":case"object":t=e,e=new(t.constructor||Object);break;default:return e}else n=st(t);switch(n){case"object":return Object.keys(t).reduce(K,{source:t,target:e}).target;case"array":return e.length=t.length,t.reduce(J,e);default:return t}}function J(e,t,n){return e[n]=st(e[n])===st(t)?$(e[n],t):$(t),e}function K(e,t){return e.target[t]=st(e.target[t])===st(e.source[t])?$(e.target[t],e.source[t]):$(e.source[t]),e}function Q(){}function G(e){var t=Object.create(null);return typeof e=="object"?A(t,e):t}function Y(e,t){var n=[e];while(++e<=t)n.push(e);return n}function Z(e,t){t=Array.isArray(t)?t:E.call(arguments,1);var n=Array.isArray(e)?et:tt;return t.forEach(n,e),e}function et(e){var t=this.indexOf(e);t=~t?t:!isNaN(e)&&e in this?e:t,t<0||this.splice(t,1)}function tt(e){delete this[e]}function nt(e){return o.toString.call(e)}function rt(e){return o.valueOf.call(e)}function it(e){return e==c?c:e==l||e=="nodelist"?l:!e.indexOf("htm")&&e.lastIndexOf("element")+7===e.length?"htmlelement":!1}function st(e){var t=nt(e);return t in x?x[t]:x[t]=t.split(" ")[1].split("]")[0].replace(w,"$1").toLowerCase()}function ot(e){return e===null||e===u?!1:j(e,__type__)?e[__type__]:Object.getPrototypeOf(e)===null?"nullobject":u}function ut(){return E.call(arguments).forEach(ft),N}function at(e){e(this,N)}function ft(e){j(e,i)||O(e,i,0,"w");var t=T[e[r]||B(e)];if(!t)return;t.slice(e[i]).forEach(at,e),e[i]=t.length}typeof global=="undefined"?e:e=global;var r="__name__",__type__="__type__",i="__xid__",s=typeof module!="undefined"&&"exports"in module&&typeof require=="function"?"commonjs":typeof navigator!="undefined"?"browser":"other",o=Object.prototype,u,a=s!="commonjs"?null:require("module"),f=[!1,NaN,null,!0,u].reduce(function(e,t){return e[String(t)]=t,e},G()),l="htmlcollection",c="htmldocument",h=999,p="anon",d=function(){var e={ce:"ec",cw:"wc",ew:"we",cew:"cwe ecw ewc wce wec".split(" ")},t="configurable enumerable writable".split(" "),n={c:[!0,!1,!1],ce:[!0,!0,!1],cew:[!0,!0,!0],cw:[!0,!1,!0],e:[!1,!0,!1],ew:[!1,!0,!0],r:[!1,!1,!1],w:[!1,!1,!0]},r=Object.keys(n).reduce(function(r,i){function s(e){r[e]=r[i]}var o=e[i];return r[i]=t.reduce(function(e,t,r){return e[t]=n[i][r],e},G()),!o||(Array.isArray(o)?o.forEach(s):s(o)),r},G());return delete r[u],r}(),v=Math.random,m=/global|window/i,g=/[xy]/g,y=new RegExp("^\\u005E?"+t),b=/[\s\(]*function([^\(]+).*/,w=/^[Ww]ebkit|[Mm]oz|O|[Mm]s|[Kk]html(.*)$/,E=Array.prototype.slice,S="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",x={"[object Object]":"object"},T={Array:[],Boolean:[],Date:[],Function:[],Number:[],Object:[],RegExp:[],String:[]};O(ut,"cache",function(e,t){return typeof e=="string"||(e=e[r]||B(e)),T[e]||(T[e]=[]),T[e].push(t),N},"w"),ut.cache("Array",function(e){O(e,"coerce",function(e,t,n){return j(e,"length")?(t=ot(t)=="number"?t>0?t:0:0,n=ot(n)=="number"?n>t?n:n<=0?e.length+n:t+n:e.length,E.call(e,t,n)):[e]},"w"),O(e.prototype,"find",function(e,t){var n=-1,r=this.length>>>0;t||(t=this);while(++n<r)if(!!e.call(t,this[n],n,this))return this[n];return null},"w")}),ut.cache("Boolean",function(e){O(e,"coerce",function(e){switch(ot(e)){case"boolean":return e;case"nan":case!1:return!1;case"number":case"string":return e in f?!!f[e]:Number(e)!==0}return!0},"w")}),ut.cache("Function",function(e){function t(e){return!e||e in o}function n(){return this.toString()}function i(){return this}var s="__xname__",o={Anonymous:!0,anonymous:!0},u={mimic:function(e,t){var r=e.valueOf();return M(this,{displayName:t||B(r),toString:n.bind(r),valueOf:i.bind(r)},"c",!0),this}};u[r]={get:function(){if(!this[s]){var e=this.valueOf(),n=e!==this?t(e[r])?null:e[r]:null,i=n||B(this);!t(i)||t(this.displayName)||(i=this.displayName),O(this,s,i||"anonymous","w")}return this[s]}},M(e.prototype,u,"w"),O(e,"anon_list",{value:o},"w")}),ut.cache("Object",function(e){O(e.prototype,__type__,A({get:function(){var e,t=this,n=t.constructor,i=st(t),s=it(i)||(m.test(i)?"global":!1);return s?s:i=="number"?isNaN(t)?"nan":"number":i=="object"&&typeof n=="function"&&n[__type__]!="function"?(e=String(n[r]).toLowerCase(),!e||e=="anonymous"?n[__type__]||i:e):i}},d.r)),M(e,{key:function(t,n){return e.keys(e(t)).find(function(e){return t[e]===n})},reduce:function(t,n,r){return e.keys(e(t)).reduce(function(e,r,i){return e=n.call(t,e,t[r],r,t,i),e},r)},value:function(t,n){if(isNaN(n)){if(j(t,n))return t[n];if(!!~n.indexOf(".")){var r;n=n.split(".");while(r=n.shift())if((t=e.value(t,r))===u)break;return t}}return D(t)?u:P(t[n])?t[n]:typeof t.get=="function"?t.get(n):typeof t.getAttribute=="function"?t.getAttribute(n):u},values:function(t){return e.keys(Object(t)).map(function(e){return t[e]})}},"w")}),X(n)||(n=s=="commonjs"?module:e),M(N=H(N,t,n),{ENV:s,global:{value:e},modes:{value:d},bless:C,coerce:L,copy:A,def:O,defs:M,describe:_,empty:D,exists:P,expose:H,got:j,guid:F,has:q,id:U,iter:X,len:V,merge:$,nativeType:st,noop:Q,obj:G,range:Y,remove:Z,tostr:nt,type:ot,valof:rt,x:ut},"w"),ut(Object,Array,Boolean,Function)}(this,"m8")
+!function(e,t,n){"use strict";function N(e){return e}function C(e,t){switch(st(e)){case"array":break;case"string":e=e.split(".");break;default:return k(t)}y.test(e[0])&&(t=N,e.shift());if(!e.length)return k(t);e[0].indexOf("^")||(t||e[0]=="^"?e.shift():e[0]=e[0].substring(1)),t=k(t);var n;while(n=e.shift())t=t[n]||(t[n]=G());return t}function k(t){return s=="commonjs"?t?W(t)?t.exports:t:module.exports:t||e}function L(e){var t=Number(e),n;return isNaN(t)?(n=String(e))in f?f[n]:e:t}function A(e,t,n){n=n===!0,t||(t=e,e=G());for(var r in t)!q(t,r)||n&&q(e,r)||(e[r]=t[r]);return e}function O(e,n,r){var i=E.call(arguments,3),s=j(e,n),o,u,a,f;switch(st(i[0])){case"string":u=d[i.shift()];break;case"object":u=i.shift();break;default:a=st(r),u=a!="object"&&s?Object.getOwnPropertyDescriptor(e,n):null,!u||(u=a=="function"?d.cw:d.cew)}return f=i.shift()===!0,o=i.shift()===!0,s&&!f?o&&new Error(t+".def cannot overwrite existing property: "+n+", in item type: "+ot(e)+"."):(a!="object"&&u&&(r=_(r,u)),(r.get||r.set)&&delete r.writable,Object.defineProperty(e,n,r)),N}function M(e,t,n,r,i){n||(n="cw");for(var s in t)!q(t,s)||O(e,s,t[s],n,r,i);return N}function _(e,t){return A(st(e)=="object"?e:{value:e},st(t)=="object"?t:d[String(t).toLowerCase()]||d.cew,!0)}function D(e){return!P(e)||!V(e)&&X(e)||!1}function P(e){return!(e===null||e===u||typeof e=="number"&&isNaN(e))}function H(t,n,i){typeof n!="string"&&t[r]&&(i=n,n=t[r]);if(s=="commonjs"&&W(i))i.exports=t;else{i||(i=e);var o=i[n],u=_({value:t},"ew");o&&X(o)?O(t=o,"__",u):O(i,n,u)}return i=G(),i[r]=n,i[__type__]="library",M(t,i,"w",!0),t}function B(e){return e.name||e.displayName||(String(e).match(b)||["",""])[1].trim()}function j(e,t){return arguments.length>2?R(j,e,Array.coerce(arguments,1)):t in Object(e)}function F(){return S.replace(g,I)}function I(e){var t=v()*16|0;return(e=="x"?t:t&3|8).toString(16)}function q(e,t){return arguments.length>2?R(q,e,Array.coerce(arguments,1)):o.hasOwnProperty.call(e,t)}function R(e,t,n){return n.some(function(n){return e(t,n)})}function U(e,t){return e?j(e,"id")&&!D(e.id)?e.id:e.id=z(t):z(t)}function z(e){return(e||p)+"-"+ ++h}function W(e){if(a===null)return!1;try{return e instanceof a}catch(t){return!1}}function X(e){return j(e,"length")||st(e)=="object"}function V(e){return("length"in(e=Object(e))?e:Object.keys(e)).length}function $(e,t){var n;if(!t)switch(n=st(e)){case"array":case"object":t=e,e=new(t.constructor||Object);break;default:return e}else n=st(t);switch(n){case"object":return Object.keys(t).reduce(K,{source:t,target:e}).target;case"array":return e.length=t.length,t.reduce(J,e);default:return t}}function J(e,t,n){return e[n]=st(e[n])===st(t)?$(e[n],t):$(t),e}function K(e,t){return e.target[t]=st(e.target[t])===st(e.source[t])?$(e.target[t],e.source[t]):$(e.source[t]),e}function Q(){}function G(e){var t=Object.create(null);return typeof e=="object"?A(t,e):t}function Y(e,t){var n=[e];while(++e<=t)n.push(e);return n}function Z(e,t){t=Array.isArray(t)?t:E.call(arguments,1);var n=Array.isArray(e)?et:tt;return t.forEach(n,e),e}function et(e){var t=this.indexOf(e);t=~t?t:!isNaN(e)&&e in this?e:t,t<0||this.splice(t,1)}function tt(e){delete this[e]}function nt(e){return o.toString.call(e)}function rt(e){return o.valueOf.call(e)}function it(e){return e==c?c:e==l||e=="nodelist"?l:!e.indexOf("htm")&&e.lastIndexOf("element")+7===e.length?"htmlelement":!1}function st(e){var t=nt(e);return t in x?x[t]:x[t]=t.split(" ")[1].split("]")[0].replace(w,"$1").toLowerCase()}function ot(e){return e===null||e===u?!1:j(e,__type__)?e[__type__]:Object.getPrototypeOf(e)===null?"nullobject":u}function ut(e,t){if(!t)return $(e);switch(st(t)){case"object":return Object.keys(t).reduce(ft,{source:t,target:e}).target;case"array":return t.reduce(at,e);default:return e}}function at(e,t,n){return e[n]=j(e,n)?st(e[n])==st(t)?ut(e[n],t):e[n]:$(t),e}function ft(e,t){return e.target[t]=j(e.target,t)?st(e.target[t])==st(e.source[t])?ut(e.target[t],e.source[t]):e.target[t]:$(e.source[t]),e}function lt(){return E.call(arguments).forEach(ht),N}function ct(e){e(this,N)}function ht(e){j(e,i)||O(e,i,0,"w");var t=T[e[r]||B(e)];if(!t)return;t.slice(e[i]).forEach(ct,e),e[i]=t.length}typeof global=="undefined"?e:e=global;var r="__name__",__type__="__type__",i="__xid__",s=typeof module!="undefined"&&"exports"in module&&typeof require=="function"?"commonjs":typeof navigator!="undefined"?"browser":"other",o=Object.prototype,u,a=s!="commonjs"?null:require("module"),f=[!1,NaN,null,!0,u].reduce(function(e,t){return e[String(t)]=t,e},G()),l="htmlcollection",c="htmldocument",h=999,p="anon",d=function(){var e={ce:"ec",cw:"wc",ew:"we",cew:"cwe ecw ewc wce wec".split(" ")},t="configurable enumerable writable".split(" "),n={c:[!0,!1,!1],ce:[!0,!0,!1],cew:[!0,!0,!0],cw:[!0,!1,!0],e:[!1,!0,!1],ew:[!1,!0,!0],r:[!1,!1,!1],w:[!1,!1,!0]},r=Object.keys(n).reduce(function(r,i){function s(e){r[e]=r[i]}var o=e[i];return r[i]=t.reduce(function(e,t,r){return e[t]=n[i][r],e},G()),!o||(Array.isArray(o)?o.forEach(s):s(o)),r},G());return delete r[u],r}(),v=Math.random,m=/global|window/i,g=/[xy]/g,y=new RegExp("^\\u005E?"+t),b=/[\s\(]*function([^\(]+).*/,w=/^[Ww]ebkit|[Mm]oz|O|[Mm]s|[Kk]html(.*)$/,E=Array.prototype.slice,S="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",x={"[object Object]":"object"},T={Array:[],Boolean:[],Date:[],Function:[],Number:[],Object:[],RegExp:[],String:[]};O(lt,"cache",function(e,t){return typeof e=="string"||(e=e[r]||B(e)),T[e]||(T[e]=[]),T[e].push(t),N},"w"),lt.cache("Array",function(e){O(e,"coerce",function(e,t,n){return j(e,"length")?(t=ot(t)=="number"?t>0?t:0:0,n=ot(n)=="number"?n>t?n:n<=0?e.length+n:t+n:e.length,E.call(e,t,n)):[e]},"w"),O(e.prototype,"find",function(e,t){var n=-1,r=this.length>>>0;t||(t=this);while(++n<r)if(!!e.call(t,this[n],n,this))return this[n];return null},"w")}),lt.cache("Boolean",function(e){O(e,"coerce",function(e){switch(ot(e)){case"boolean":return e;case"nan":case!1:return!1;case"number":case"string":return e in f?!!f[e]:Number(e)!==0}return!0},"w")}),lt.cache("Function",function(e){function t(e){return!e||e in o}function n(){return this.toString()}function i(){return this}var s="__xname__",o={Anonymous:!0,anonymous:!0},u={mimic:function(e,t){var r=e.valueOf();return M(this,{displayName:t||B(r),toString:n.bind(r),valueOf:i.bind(r)},"c",!0),this}};u[r]={get:function(){if(!this[s]){var e=this.valueOf(),n=e!==this?t(e[r])?null:e[r]:null,i=n||B(this);!t(i)||t(this.displayName)||(i=this.displayName),O(this,s,i||"anonymous","w")}return this[s]}},M(e.prototype,u,"w"),O(e,"anon_list",{value:o},"w")}),lt.cache("Object",function(e){O(e.prototype,__type__,A({get:function(){var e,t=this,n=t.constructor,i=st(t),s=it(i)||(m.test(i)?"global":!1);return s?s:i=="number"?isNaN(t)?"nan":"number":i=="object"&&typeof n=="function"&&n[__type__]!="function"?(e=String(n[r]).toLowerCase(),!e||e=="anonymous"?n[__type__]||i:e):i}},d.r)),M(e,{key:function(t,n){return e.keys(e(t)).find(function(e){return t[e]===n})},reduce:function(t,n,r){return e.keys(e(t)).reduce(function(e,r,i){return e=n.call(t,e,t[r],r,t,i),e},r)},value:function(t,n){if(isNaN(n)){if(j(t,n))return t[n];if(!!~n.indexOf(".")){var r;n=n.split(".");while(r=n.shift())if((t=e.value(t,r))===u)break;return t}}return D(t)?u:P(t[n])?t[n]:typeof t.get=="function"?t.get(n):typeof t.getAttribute=="function"?t.getAttribute(n):u},values:function(t){return e.keys(Object(t)).map(function(e){return t[e]})}},"w")}),X(n)||(n=s=="commonjs"?module:e),M(N=H(N,t,n),{ENV:s,global:{value:e},modes:{value:d},bless:C,coerce:L,copy:A,def:O,defs:M,describe:_,empty:D,exists:P,expose:H,got:j,guid:F,has:q,id:U,iter:X,len:V,merge:$,nativeType:st,noop:Q,obj:G,range:Y,remove:Z,tostr:nt,type:ot,update:ut,valof:rt,x:lt},"w"),lt(Object,Array,Boolean,Function)}(this,"m8")
View
2 package.json
@@ -27,5 +27,5 @@
"scripts" : {
"test" : "mocha -c --ignore-leaks -R spec -u tdd ./test/*.test.js"
},
- "version" : "0.2.8"
+ "version" : "0.2.9"
}
View
3 src/expose.js
@@ -8,7 +8,8 @@
describe : describe, empty : empty, exists : exists, expose : expose, got : got,
guid : guid, has : has, id : id, iter : iter, len : len,
merge : merge, nativeType : nativeType, noop : noop, obj : obj, range : range,
- remove : remove, tostr : tostr, type : type, valof : valof, x : x
+ remove : remove, tostr : tostr, type : type, update : update, valof : valof,
+ x : x
}, 'w' );
x( Object, Array, Boolean, Function );
View
28 src/lib.js
@@ -201,3 +201,31 @@
? 'nullobject'
: UNDEF;
}
+
+ function update( target, source ) {
+ if ( !source ) return merge( target );
+
+ switch ( nativeType( source ) ) {
+ case 'object' : return Object.keys( source ).reduce( update_object, { source : source, target : target } ).target;
+ case 'array' : return source.reduce( update_array, target );
+ default : return target;
+ }
+ }
+
+ function update_array( target, source, i ) {
+ target[i] = !got( target, i )
+ ? merge( source )
+ : nativeType( target[i] ) == nativeType( source )
+ ? update( target[i], source )
+ : target[i];
+ return target;
+ }
+
+ function update_object( o, key ) {
+ o.target[key] = !got( o.target, key )
+ ? merge( o.source[key] )
+ : nativeType( o.target[key] ) == nativeType( o.source[key] )
+ ? update( o.target[key], o.source[key] )
+ : o.target[key];
+ return o;
+ }
View
49 test/m8.test.js
@@ -190,13 +190,19 @@ suite( 'm8', function() {
} );
test( '<static> m8.merge', function( done ) {
- var expected = { foo : 'bar', items : [{ value : 1 }, { items : [{ value : 1 }, { items : [{ value : 1 }, { value : 2 }, { value : 3 }], value : 2 }, { value : 3 }], value : 2 }, { value : 3 }]},
- returned = m8.merge( m8.obj(), expected );
+ var expected = { foo : 'bar', items : [ { value : 1 }, { items : [ { value : 1 }, { items : [ { value : 1 }, { value : 2 }, { value : 3 } ], value : 2 }, { value : 3 } ], value : 2 }, { value : 3 } ] },
+ returned = m8.merge( m8.obj(), expected ),
+ overwritten = m8.merge( { items : [ { value : '1 2 3' }, { items : m8.range( 1, 100 ) } ] }, expected );
- expect( returned ).not.to.equal( expected );
+ expect( returned ).to.not.equal( expected );
expect( returned ).to.eql( expected );
- expect( returned.items ).not.to.equal( expected.items );
- expect( returned.items[1].items[1] ).not.to.equal( expected.items[1].items[1] );
+ expect( returned.items ).to.not.equal( expected.items );
+ expect( returned.items[1].items[1] ).to.not.equal( expected.items[1].items[1] );
+
+ expect( overwritten.items[0].value ).to.equal( 1 );
+ expect( overwritten.items[1].items.length ).to.equal( 3 );
+ expect( overwritten.items[1].items ).to.not.equal( expected.items[1].items );
+ expect( overwritten.items[2].value ).to.equal( 3 );
done();
} );
@@ -225,8 +231,8 @@ suite( 'm8', function() {
expect( m8.type( returned ) ).to.eql( 'nullobject' );
expect( Object.getPrototypeOf( returned ) ).to.equal( null );
expect( m8.nativeType( returned ) ).to.equal( 'object' );
- expect( m8.nativeType( returned ) ).not.to.equal( 'nullobject' );
- expect( m8.type( returned ) ).not.to.equal( 'object' );
+ expect( m8.nativeType( returned ) ).to.not.equal( 'nullobject' );
+ expect( m8.type( returned ) ).to.not.equal( 'object' );
done();
} );
@@ -273,6 +279,31 @@ suite( 'm8', function() {
done();
} );
+ test( '<static> m8.update', function( done ) {
+ var expected = { foo : 'bar', items : [ { id : 1, value : 1 }, { items : [ { value : 1 }, { items : [ { value : 1 }, { value : 2 }, { value : 3 } ], value : 2 }, { value : 3 } ], value : 2 }, { value : 3 } ] },
+ returned = m8.update( m8.obj(), expected ),
+ overwritten = m8.update( { foo : 'foo', items : [ { value : '1 2 3' }, { items : [ { id : 0 }, { items : [ { id : 2 } ] }].concat( m8.range( 0, 3 ) ) } ] }, expected );
+
+ expect( returned ).to.not.equal( expected );
+ expect( returned ).to.eql( expected );
+ expect( returned.items ).to.not.equal( expected.items );
+ expect( returned.items[1].items[1] ).to.not.equal( expected.items[1].items[1] );
+
+ expect( overwritten.foo ).to.equal( 'foo' );
+ expect( overwritten.items[1].items.length ).to.equal( 6 );
+ expect( overwritten.items[0].id ).to.equal( 1 );
+ expect( overwritten.items[0].value ).to.equal( '1 2 3' );
+ expect( overwritten.items[0] ).to.not.equal( expected.items[0] );
+ expect( overwritten.items[1].items[0].id ).to.equal( 0 );
+ expect( overwritten.items[1].items[0].value ).to.equal( 1 );
+ expect( overwritten.items[1].items[1].items.length ).to.equal( 3 );
+ expect( overwritten.items[1].items[1].items[0].id ).to.equal( 2 );
+ expect( overwritten.items[1].items[1].items[0].value ).to.equal( 1 );
+ expect( overwritten.items[1].items[1].items.length ).to.not.equal( expected.items[1].items[1].items );
+
+ done();
+ } );
+
test( '<static> Array.coerce returns an Array based on the passed item', function( done ) {
expect( Array.coerce( [1, 2, 3] ) ).to.eql( [1, 2, 3] );
expect( Array.coerce( { foo : 'bar' } ) ).to.eql( [{ foo : 'bar' }] );
@@ -327,8 +358,8 @@ suite( 'm8', function() {
function two() {}
two.mimic( one );
- expect( one ).not.to.equal( two );
- expect( one ).not.to.equal( two );
+ expect( one ).to.not.equal( two );
+ expect( one ).to.not.equal( two );
expect( one.valueOf() ).to.equal( two.valueOf() );
expect( one.toString() ).to.equal( two.toString() );

0 comments on commit 4c175ea

Please sign in to comment.
Something went wrong with that request. Please try again.