Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

tree-kit

Package Overview
Dependencies
Maintainers
1
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tree-kit - npm Package Compare versions

Comparing version 0.5.26 to 0.5.27

.eslintrc.js

419

browser/tree-kit.js

@@ -1,9 +0,9 @@

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.treeKit = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.treeKit = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -15,6 +15,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -46,7 +46,7 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -58,6 +58,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -80,7 +80,6 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

module.exports = function clone( originalObject , circular )
{
module.exports = function clone( originalObject , circular ) {
// First create an empty object with
// same prototype of our original source
var propertyIndex , descriptor , keys , current , nextSource , indexOf ,

@@ -94,28 +93,23 @@ copies = [ {

targetReferences = [ cloneObject ] ;
// First in, first out
while ( current = copies.shift() ) // jshint ignore:line
{
while ( ( current = copies.shift() ) ) {
keys = Object.getOwnPropertyNames( current.source ) ;
for ( propertyIndex = 0 ; propertyIndex < keys.length ; propertyIndex ++ )
{
for ( propertyIndex = 0 ; propertyIndex < keys.length ; propertyIndex ++ ) {
// Save the source's descriptor
descriptor = Object.getOwnPropertyDescriptor( current.source , keys[ propertyIndex ] ) ;
if ( ! descriptor.value || typeof descriptor.value !== 'object' )
{
if ( ! descriptor.value || typeof descriptor.value !== 'object' ) {
Object.defineProperty( current.target , keys[ propertyIndex ] , descriptor ) ;
continue ;
}
nextSource = descriptor.value ;
descriptor.value = Array.isArray( nextSource ) ? [] : Object.create( Object.getPrototypeOf( nextSource ) ) ;
if ( circular )
{
if ( circular ) {
indexOf = sourceReferences.indexOf( nextSource ) ;
if ( indexOf !== -1 )
{
if ( indexOf !== -1 ) {
// The source is already referenced, just assign reference

@@ -126,13 +120,13 @@ descriptor.value = targetReferences[ indexOf ] ;

}
sourceReferences.push( nextSource ) ;
targetReferences.push( descriptor.value ) ;
}
Object.defineProperty( current.target , keys[ propertyIndex ] , descriptor ) ;
copies.push( { source: nextSource , target: descriptor.value } ) ;
}
}
return cloneObject ;

@@ -144,7 +138,7 @@ } ;

Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -156,6 +150,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -205,22 +199,17 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

*/
function extend( options , target )
{
function extend( options , target , ... sources ) {
//console.log( "\nextend():\n" , arguments ) ;
var i , source , newTarget = false , length = arguments.length ;
if ( length < 3 ) { return target ; }
var sources = Array.prototype.slice.call( arguments , 2 ) ;
length = sources.length ;
var i , source , newTarget = false , length = sources.length ;
if ( ! length ) { return target ; }
if ( ! options || typeof options !== 'object' ) { options = {} ; }
var runtime = { depth: 0 , prefix: '' } ;
if ( ! options.maxDepth && options.deep && ! options.circular ) { options.maxDepth = 100 ; }
if ( options.deepFunc ) { options.deep = true ; }
if ( options.deepFilter && typeof options.deepFilter === 'object' )
{
if ( options.deepFilter && typeof options.deepFilter === 'object' ) {
if ( options.deepFilter.whitelist && ( ! Array.isArray( options.deepFilter.whitelist ) || ! options.deepFilter.whitelist.length ) ) { delete options.deepFilter.whitelist ; }

@@ -230,6 +219,5 @@ if ( options.deepFilter.blacklist && ( ! Array.isArray( options.deepFilter.blacklist ) || ! options.deepFilter.blacklist.length ) ) { delete options.deepFilter.blacklist ; }

}
// 'flat' option force 'deep'
if ( options.flat )
{
if ( options.flat ) {
options.deep = true ;

@@ -241,5 +229,4 @@ options.proto = false ;

}
if ( options.unflat )
{
if ( options.unflat ) {
options.deep = false ;

@@ -251,30 +238,24 @@ options.proto = false ;

}
// If the prototype is applied, only owned properties should be copied
if ( options.inherit ) { options.own = true ; options.proto = false ; }
else if ( options.proto ) { options.own = true ; }
if ( ! target || ( typeof target !== 'object' && typeof target !== 'function' ) )
{
if ( ! target || ( typeof target !== 'object' && typeof target !== 'function' ) ) {
newTarget = true ;
}
if ( ! options.skipRoot && ( options.inherit || options.proto ) )
{
for ( i = length - 1 ; i >= 0 ; i -- )
{
if ( ! options.skipRoot && ( options.inherit || options.proto ) ) {
for ( i = length - 1 ; i >= 0 ; i -- ) {
source = sources[ i ] ;
if ( source && ( typeof source === 'object' || typeof source === 'function' ) )
{
if ( options.inherit )
{
if ( source && ( typeof source === 'object' || typeof source === 'function' ) ) {
if ( options.inherit ) {
if ( newTarget ) { target = Object.create( source ) ; }
else { Object.setPrototypeOf( target , source ) ; }
}
else if ( options.proto )
{
else if ( options.proto ) {
if ( newTarget ) { target = Object.create( Object.getPrototypeOf( source ) ) ; }
else { Object.setPrototypeOf( target , Object.getPrototypeOf( source ) ) ; }
}
break ;

@@ -284,11 +265,9 @@ }

}
else if ( newTarget )
{
else if ( newTarget ) {
target = {} ;
}
runtime.references = { sources: [] , targets: [] } ;
for ( i = 0 ; i < length ; i ++ )
{
for ( i = 0 ; i < length ; i ++ ) {
source = sources[ i ] ;

@@ -298,3 +277,3 @@ if ( ! source || ( typeof source !== 'object' && typeof source !== 'function' ) ) { continue ; }

}
return target ;

@@ -307,26 +286,22 @@ }

function extendOne( runtime , options , target , source )
{
function extendOne( runtime , options , target , source ) {
//console.log( "\nextendOne():\n" , arguments ) ;
//process.exit() ;
var j , jmax , sourceKeys , sourceKey , sourceValue , sourceValueProto ,
value , sourceDescriptor , targetKey , targetPointer , path ,
indexOfSource = -1 ;
// Max depth check
if ( options.maxDepth && runtime.depth > options.maxDepth )
{
if ( options.maxDepth && runtime.depth > options.maxDepth ) {
throw new Error( '[tree] extend(): max depth reached(' + options.maxDepth + ')' ) ;
}
if ( options.circular )
{
if ( options.circular ) {
runtime.references.sources.push( source ) ;
runtime.references.targets.push( target ) ;
}
if ( options.own )
{
if ( options.own ) {
if ( options.nonEnum ) { sourceKeys = Object.getOwnPropertyNames( source ) ; }

@@ -336,70 +311,63 @@ else { sourceKeys = Object.keys( source ) ; }

else { sourceKeys = source ; }
for ( sourceKey in sourceKeys )
{
for ( sourceKey in sourceKeys ) {
if ( options.own ) { sourceKey = sourceKeys[ sourceKey ] ; }
// OMG, this DEPRECATED __proto__ shit is still alive and can be used to hack anything ><
if ( sourceKey === '__proto__' ) { continue ; }
// If descriptor is on, get it now
if ( options.descriptor )
{
if ( options.descriptor ) {
sourceDescriptor = Object.getOwnPropertyDescriptor( source , sourceKey ) ;
sourceValue = sourceDescriptor.value ;
}
else
{
else {
// We have to trigger an eventual getter only once
sourceValue = source[ sourceKey ] ;
}
targetPointer = target ;
targetKey = runtime.prefix + sourceKey ;
// Do not copy if property is a function and we don't want them
if ( options.nofunc && typeof sourceValue === 'function' ) { continue; }
if ( options.nofunc && typeof sourceValue === 'function' ) { continue ; }
// 'unflat' mode computing
if ( options.unflat && runtime.depth === 0 )
{
if ( options.unflat && runtime.depth === 0 ) {
path = sourceKey.split( options.unflat ) ;
jmax = path.length - 1 ;
if ( jmax )
{
for ( j = 0 ; j < jmax ; j ++ )
{
if ( jmax ) {
for ( j = 0 ; j < jmax ; j ++ ) {
if ( ! targetPointer[ path[ j ] ] ||
( typeof targetPointer[ path[ j ] ] !== 'object' &&
typeof targetPointer[ path[ j ] ] !== 'function' ) )
{
typeof targetPointer[ path[ j ] ] !== 'function' ) ) {
targetPointer[ path[ j ] ] = {} ;
}
targetPointer = targetPointer[ path[ j ] ] ;
}
targetKey = runtime.prefix + path[ jmax ] ;
}
}
if ( options.deep &&
if ( options.deep && // eslint-disable-line no-constant-condition
sourceValue &&
( typeof sourceValue === 'object' || ( options.deepFunc && typeof sourceValue === 'function' ) ) &&
( ! options.descriptor || ! sourceDescriptor.get ) &&
// not a condition we just cache sourceValueProto now
// not a condition we just cache sourceValueProto now... ok it's trashy ><
( ( sourceValueProto = Object.getPrototypeOf( sourceValue ) ) || true ) &&
( ! options.deepFilter ||
( ( ! options.deepFilter.whitelist || options.deepFilter.whitelist.indexOf( sourceValueProto ) !== -1 ) &&
( ! options.deepFilter.blacklist || options.deepFilter.blacklist.indexOf( sourceValueProto ) === -1 ) ) ) )
{
if ( options.circular )
{
( ! options.deepFilter.blacklist || options.deepFilter.blacklist.indexOf( sourceValueProto ) === -1 ) ) ) ) {
if ( options.circular ) {
indexOfSource = runtime.references.sources.indexOf( sourceValue ) ;
}
if ( options.flat )
{
if ( options.flat ) {
// No circular references reconnection when in 'flat' mode
if ( indexOfSource >= 0 ) { continue ; }
extendOne(

@@ -410,9 +378,6 @@ { depth: runtime.depth + 1 , prefix: runtime.prefix + sourceKey + options.flat , references: runtime.references } ,

}
else
{
if ( indexOfSource >= 0 )
{
else {
if ( indexOfSource >= 0 ) {
// Circular references reconnection...
if ( options.descriptor )
{
if ( options.descriptor ) {
Object.defineProperty( targetPointer , targetKey , {

@@ -425,12 +390,10 @@ value: runtime.references.targets[ indexOfSource ] ,

}
else
{
else {
targetPointer[ targetKey ] = runtime.references.targets[ indexOfSource ] ;
}
continue ;
}
if ( ! targetPointer[ targetKey ] || ! targetPointer.hasOwnProperty( targetKey ) || ( typeof targetPointer[ targetKey ] !== 'object' && typeof targetPointer[ targetKey ] !== 'function' ) )
{
if ( ! targetPointer[ targetKey ] || ! targetPointer.hasOwnProperty( targetKey ) || ( typeof targetPointer[ targetKey ] !== 'object' && typeof targetPointer[ targetKey ] !== 'function' ) ) {
if ( Array.isArray( sourceValue ) ) { value = [] ; }

@@ -440,5 +403,4 @@ else if ( options.proto ) { value = Object.create( sourceValueProto ) ; } // jshint ignore:line

else { value = {} ; }
if ( options.descriptor )
{
if ( options.descriptor ) {
Object.defineProperty( targetPointer , targetKey , {

@@ -451,22 +413,18 @@ value: value ,

}
else
{
else {
targetPointer[ targetKey ] = value ;
}
}
else if ( options.proto && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValueProto )
{
else if ( options.proto && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValueProto ) {
Object.setPrototypeOf( targetPointer[ targetKey ] , sourceValueProto ) ;
}
else if ( options.inherit && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValue )
{
else if ( options.inherit && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValue ) {
Object.setPrototypeOf( targetPointer[ targetKey ] , sourceValue ) ;
}
if ( options.circular )
{
if ( options.circular ) {
runtime.references.sources.push( sourceValue ) ;
runtime.references.targets.push( targetPointer[ targetKey ] ) ;
}
// Recursively extends sub-object

@@ -479,13 +437,11 @@ extendOne(

}
else if ( options.preserve && targetPointer[ targetKey ] !== undefined )
{
else if ( options.preserve && targetPointer[ targetKey ] !== undefined ) {
// Do not overwrite, and so do not delete source's properties that were not moved
continue ;
}
else if ( ! options.inherit )
{
else if ( ! options.inherit ) {
if ( options.descriptor ) { Object.defineProperty( targetPointer , targetKey , sourceDescriptor ) ; }
else { targetPointer[ targetKey ] = sourceValue ; }
}
// Delete owned property of the source object

@@ -500,7 +456,7 @@ if ( options.move ) { delete source[ sourceKey ] ; }

Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -512,6 +468,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -535,32 +491,26 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

treePath.op = function op( type , object , path , value )
{
treePath.op = function op( type , object , path , value ) {
var i , parts , last , pointer , key , isArray = false , pathArrayMode = false , isGenericSet , canBeEmpty = true ;
if ( ! object || ( typeof object !== 'object' && typeof object !== 'function' ) )
{
if ( ! object || ( typeof object !== 'object' && typeof object !== 'function' ) ) {
return ;
}
if ( typeof path === 'string' )
{
if ( typeof path === 'string' ) {
// Split the path into parts
if ( path ) { parts = path.match( /([.#\[\]]|[^.#\[\]]+)/g ) ; }
if ( path ) { parts = path.match( /([.#[\]]|[^.#[\]]+)/g ) ; }
else { parts = [ '' ] ; }
if ( parts[ 0 ] === '.' ) { parts.unshift( '' ) ; }
if ( parts[ parts.length - 1 ] === '.' ) { parts.push( '' ) ; }
}
else if ( Array.isArray( path ) )
{
else if ( Array.isArray( path ) ) {
parts = path ;
pathArrayMode = true ;
}
else
{
else {
throw new TypeError( '[tree.path] .' + type + '(): the path argument should be a string or an array' ) ;
}
switch ( type )
{
switch ( type ) {
case 'get' :

@@ -584,63 +534,53 @@ case 'delete' :

}
//console.log( parts ) ;
// The pointer start at the object's root
pointer = object ;
last = parts.length - 1 ;
for ( i = 0 ; i <= last ; i ++ )
{
if ( pathArrayMode )
{
if ( key === undefined )
{
for ( i = 0 ; i <= last ; i ++ ) {
if ( pathArrayMode ) {
if ( key === undefined ) {
key = parts[ i ] ;
continue ;
}
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) )
{
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) ) {
if ( ! isGenericSet ) { return undefined ; }
pointer[ key ] = {} ;
}
pointer = pointer[ key ] ;
key = parts[ i ] ;
continue ;
}
else if ( parts[ i ] === '.' )
{
else if ( parts[ i ] === '.' ) {
isArray = false ;
if ( key === undefined )
{
if ( ! canBeEmpty )
{
if ( key === undefined ) {
if ( ! canBeEmpty ) {
canBeEmpty = true ;
continue ;
}
key = '' ;
}
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) )
{
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) ) {
if ( ! isGenericSet ) { return undefined ; }
pointer[ key ] = {} ;
}
pointer = pointer[ key ] ;
canBeEmpty = true ;
continue ;
}
else if ( parts[ i ] === '#' || parts[ i ] === '[' )
{
else if ( parts[ i ] === '#' || parts[ i ] === '[' ) {
isArray = true ;
canBeEmpty = false ;
if ( key === undefined )
{
if ( key === undefined ) {
// The root element cannot be altered, we are in trouble if an array is expected but we have only a regular object.

@@ -650,15 +590,13 @@ if ( ! Array.isArray( pointer ) ) { return undefined ; }

}
if ( ! pointer[ key ] || ! Array.isArray( pointer[ key ] ) )
{
if ( ! pointer[ key ] || ! Array.isArray( pointer[ key ] ) ) {
if ( ! isGenericSet ) { return undefined ; }
pointer[ key ] = [] ;
}
pointer = pointer[ key ] ;
continue ;
}
else if ( parts[ i ] === ']' )
{
else if ( parts[ i ] === ']' ) {
// Closing bracket: do nothing

@@ -668,13 +606,12 @@ canBeEmpty = false ;

}
canBeEmpty = false ;
if ( ! isArray ) { key = parts[ i ] ; continue ; }
switch ( parts[ i ] )
{
switch ( parts[ i ] ) {
case 'length' :
key = parts[ i ] ;
break ;
// Pseudo-key

@@ -697,5 +634,5 @@ case 'first' :

break ;
// default = number
default:
default :
// Convert the string key to a numerical index

@@ -705,5 +642,4 @@ key = parseInt( parts[ i ] , 10 ) ;

}
switch ( type )
{
switch ( type ) {
case 'get' :

@@ -742,4 +678,3 @@ return pointer[ key ] ;

if ( ! pointer[ key ] ) { pointer[ key ] = value ; }
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) )
{
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) ) {
pointer[ key ] = pointer[ key ].concat( value ) ;

@@ -751,4 +686,3 @@ }

if ( ! pointer[ key ] ) { pointer[ key ] = value ; }
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) )
{
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) ) {
pointer[ key ] = value.concat( pointer[ key ] ) ;

@@ -801,4 +735,3 @@ }

// Upgrade an object so it can support get, set and delete at its root
treePath.upgrade = function upgrade( object )
{
treePath.upgrade = function upgrade( object ) {
Object.defineProperties( object , {

@@ -823,2 +756,2 @@ get: { value: treePath.op.bind( undefined , 'get' , object ) } ,

},{}]},{},[1])(1)
});
});

@@ -1,1 +0,1 @@

(function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.treeKit=e()}})(function(){var e,t,r;return function e(t,r,n){function i(o,s){if(!r[o]){if(!t[o]){var u=typeof require=="function"&&require;if(!s&&u)return u(o,!0);if(f)return f(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var a=r[o]={exports:{}};t[o][0].call(a.exports,function(e){var r=t[o][1][e];return i(r?r:e)},a,a.exports,e,t,r,n)}return r[o].exports}var f=typeof require=="function"&&require;for(var o=0;o<n.length;o++)i(n[o]);return i}({1:[function(e,t,r){"use strict";var n={};t.exports=n;n.extend=e("./extend.js");n.clone=e("./clone.js");n.path=e("./path.js")},{"./clone.js":2,"./extend.js":3,"./path.js":4}],2:[function(e,t,r){"use strict";t.exports=function e(t,r){var n,i,f,o,s,u,c=[{source:t,target:Array.isArray(t)?[]:Object.create(Object.getPrototypeOf(t))}],a=c[0].target,p=[t],d=[a];while(o=c.shift()){f=Object.getOwnPropertyNames(o.source);for(n=0;n<f.length;n++){i=Object.getOwnPropertyDescriptor(o.source,f[n]);if(!i.value||typeof i.value!=="object"){Object.defineProperty(o.target,f[n],i);continue}s=i.value;i.value=Array.isArray(s)?[]:Object.create(Object.getPrototypeOf(s));if(r){u=p.indexOf(s);if(u!==-1){i.value=d[u];Object.defineProperty(o.target,f[n],i);continue}p.push(s);d.push(i.value)}Object.defineProperty(o.target,f[n],i);c.push({source:s,target:i.value})}}return a}},{}],3:[function(e,t,r){"use strict";function n(e,t){var r,n,f=false,o=arguments.length;if(o<3){return t}var s=Array.prototype.slice.call(arguments,2);o=s.length;if(!e||typeof e!=="object"){e={}}var u={depth:0,prefix:""};if(!e.maxDepth&&e.deep&&!e.circular){e.maxDepth=100}if(e.deepFunc){e.deep=true}if(e.deepFilter&&typeof e.deepFilter==="object"){if(e.deepFilter.whitelist&&(!Array.isArray(e.deepFilter.whitelist)||!e.deepFilter.whitelist.length)){delete e.deepFilter.whitelist}if(e.deepFilter.blacklist&&(!Array.isArray(e.deepFilter.blacklist)||!e.deepFilter.blacklist.length)){delete e.deepFilter.blacklist}if(!e.deepFilter.whitelist&&!e.deepFilter.blacklist){delete e.deepFilter}}if(e.flat){e.deep=true;e.proto=false;e.inherit=false;e.unflat=false;if(typeof e.flat!=="string"){e.flat="."}}if(e.unflat){e.deep=false;e.proto=false;e.inherit=false;e.flat=false;if(typeof e.unflat!=="string"){e.unflat="."}}if(e.inherit){e.own=true;e.proto=false}else if(e.proto){e.own=true}if(!t||typeof t!=="object"&&typeof t!=="function"){f=true}if(!e.skipRoot&&(e.inherit||e.proto)){for(r=o-1;r>=0;r--){n=s[r];if(n&&(typeof n==="object"||typeof n==="function")){if(e.inherit){if(f){t=Object.create(n)}else{Object.setPrototypeOf(t,n)}}else if(e.proto){if(f){t=Object.create(Object.getPrototypeOf(n))}else{Object.setPrototypeOf(t,Object.getPrototypeOf(n))}}break}}}else if(f){t={}}u.references={sources:[],targets:[]};for(r=0;r<o;r++){n=s[r];if(!n||typeof n!=="object"&&typeof n!=="function"){continue}i(u,e,t,n)}return t}t.exports=n;function i(e,t,r,n){var f,o,s,u,c,a,p,d,l,b,y,h=-1;if(t.maxDepth&&e.depth>t.maxDepth){throw new Error("[tree] extend(): max depth reached("+t.maxDepth+")")}if(t.circular){e.references.sources.push(n);e.references.targets.push(r)}if(t.own){if(t.nonEnum){s=Object.getOwnPropertyNames(n)}else{s=Object.keys(n)}}else{s=n}for(u in s){if(t.own){u=s[u]}if(t.descriptor){d=Object.getOwnPropertyDescriptor(n,u);c=d.value}else{c=n[u]}b=r;l=e.prefix+u;if(t.nofunc&&typeof c==="function"){continue}if(t.unflat&&e.depth===0){y=u.split(t.unflat);o=y.length-1;if(o){for(f=0;f<o;f++){if(!b[y[f]]||typeof b[y[f]]!=="object"&&typeof b[y[f]]!=="function"){b[y[f]]={}}b=b[y[f]]}l=e.prefix+y[o]}}if(t.deep&&c&&(typeof c==="object"||t.deepFunc&&typeof c==="function")&&(!t.descriptor||!d.get)&&((a=Object.getPrototypeOf(c))||true)&&(!t.deepFilter||(!t.deepFilter.whitelist||t.deepFilter.whitelist.indexOf(a)!==-1)&&(!t.deepFilter.blacklist||t.deepFilter.blacklist.indexOf(a)===-1))){if(t.circular){h=e.references.sources.indexOf(c)}if(t.flat){if(h>=0){continue}i({depth:e.depth+1,prefix:e.prefix+u+t.flat,references:e.references},t,b,c)}else{if(h>=0){if(t.descriptor){Object.defineProperty(b,l,{value:e.references.targets[h],enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{b[l]=e.references.targets[h]}continue}if(!b[l]||!b.hasOwnProperty(l)||typeof b[l]!=="object"&&typeof b[l]!=="function"){if(Array.isArray(c)){p=[]}else if(t.proto){p=Object.create(a)}else if(t.inherit){p=Object.create(c)}else{p={}}if(t.descriptor){Object.defineProperty(b,l,{value:p,enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{b[l]=p}}else if(t.proto&&Object.getPrototypeOf(b[l])!==a){Object.setPrototypeOf(b[l],a)}else if(t.inherit&&Object.getPrototypeOf(b[l])!==c){Object.setPrototypeOf(b[l],c)}if(t.circular){e.references.sources.push(c);e.references.targets.push(b[l])}i({depth:e.depth+1,prefix:"",references:e.references},t,b[l],c)}}else if(t.preserve&&b[l]!==undefined){continue}else if(!t.inherit){if(t.descriptor){Object.defineProperty(b,l,d)}else{b[l]=c}}if(t.move){delete n[u]}}}},{}],4:[function(e,t,r){"use strict";var n={};t.exports=n;n.op=function e(t,r,n,i){var f,o,s,u,c,a=false,p=false,d,l=true;if(!r||typeof r!=="object"&&typeof r!=="function"){return}if(typeof n==="string"){if(n){o=n.match(/([.#\[\]]|[^.#\[\]]+)/g)}else{o=[""]}if(o[0]==="."){o.unshift("")}if(o[o.length-1]==="."){o.push("")}}else if(Array.isArray(n)){o=n;p=true}else{throw new TypeError("[tree.path] ."+t+"(): the path argument should be a string or an array")}switch(t){case"get":case"delete":d=false;break;case"set":case"define":case"inc":case"dec":case"append":case"prepend":case"concat":case"insert":case"autoPush":d=true;break;default:throw new TypeError("[tree.path] .op(): wrong type of operation '"+t+"'")}u=r;s=o.length-1;for(f=0;f<=s;f++){if(p){if(c===undefined){c=o[f];continue}if(!u[c]||typeof u[c]!=="object"&&typeof u[c]!=="function"){if(!d){return undefined}u[c]={}}u=u[c];c=o[f];continue}else if(o[f]==="."){a=false;if(c===undefined){if(!l){l=true;continue}c=""}if(!u[c]||typeof u[c]!=="object"&&typeof u[c]!=="function"){if(!d){return undefined}u[c]={}}u=u[c];l=true;continue}else if(o[f]==="#"||o[f]==="["){a=true;l=false;if(c===undefined){if(!Array.isArray(u)){return undefined}continue}if(!u[c]||!Array.isArray(u[c])){if(!d){return undefined}u[c]=[]}u=u[c];continue}else if(o[f]==="]"){l=false;continue}l=false;if(!a){c=o[f];continue}switch(o[f]){case"length":c=o[f];break;case"first":c=0;break;case"last":c=u.length-1;if(c<0){c=0}break;case"next":if(!d){return undefined}c=u.length;break;case"insert":if(!d){return undefined}u.unshift(undefined);c=0;break;default:c=parseInt(o[f],10)}}switch(t){case"get":return u[c];case"delete":if(a&&typeof c==="number"){u.splice(c,1)}else{delete u[c]}return;case"set":u[c]=i;return u[c];case"define":if(!(c in u)){u[c]=i}return u[c];case"inc":if(typeof u[c]==="number"){u[c]++}else if(!u[c]||typeof u[c]!=="object"){u[c]=1}return u[c];case"dec":if(typeof u[c]==="number"){u[c]--}else if(!u[c]||typeof u[c]!=="object"){u[c]=-1}return u[c];case"append":if(!u[c]){u[c]=[i]}else if(Array.isArray(u[c])){u[c].push(i)}return u[c];case"prepend":if(!u[c]){u[c]=[i]}else if(Array.isArray(u[c])){u[c].unshift(i)}return u[c];case"concat":if(!u[c]){u[c]=i}else if(Array.isArray(u[c])&&Array.isArray(i)){u[c]=u[c].concat(i)}return u[c];case"insert":if(!u[c]){u[c]=i}else if(Array.isArray(u[c])&&Array.isArray(i)){u[c]=i.concat(u[c])}return u[c];case"autoPush":if(u[c]===undefined){u[c]=i}else if(Array.isArray(u[c])){u[c].push(i)}else{u[c]=[u[c],i]}return u[c]}};n.get=n.op.bind(undefined,"get");n.delete=n.op.bind(undefined,"delete");n.set=n.op.bind(undefined,"set");n.define=n.op.bind(undefined,"define");n.inc=n.op.bind(undefined,"inc");n.dec=n.op.bind(undefined,"dec");n.append=n.op.bind(undefined,"append");n.prepend=n.op.bind(undefined,"prepend");n.concat=n.op.bind(undefined,"concat");n.insert=n.op.bind(undefined,"insert");n.autoPush=n.op.bind(undefined,"autoPush");n.prototype={get:function(e){return n.get(this,e)},delete:function(e){return n.delete(this,e)},set:function(e,t){return n.set(this,e,t)},define:function(e,t){return n.define(this,e,t)},inc:function(e,t){return n.inc(this,e,t)},dec:function(e,t){return n.dec(this,e,t)},append:function(e,t){return n.append(this,e,t)},prepend:function(e,t){return n.prepend(this,e,t)},concat:function(e,t){return n.concat(this,e,t)},insert:function(e,t){return n.insert(this,e,t)},autoPush:function(e,t){return n.autoPush(this,e,t)}};n.upgrade=function e(t){Object.defineProperties(t,{get:{value:n.op.bind(undefined,"get",t)},delete:{value:n.op.bind(undefined,"delete",t)},set:{value:n.op.bind(undefined,"set",t)},define:{value:n.op.bind(undefined,"define",t)},inc:{value:n.op.bind(undefined,"inc",t)},dec:{value:n.op.bind(undefined,"dec",t)},append:{value:n.op.bind(undefined,"append",t)},prepend:{value:n.op.bind(undefined,"prepend",t)},concat:{value:n.op.bind(undefined,"concat",t)},insert:{value:n.op.bind(undefined,"insert",t)},autoPush:{value:n.op.bind(undefined,"autoPush",t)}})}},{}]},{},[1])(1)});
(function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.treeKit=e()}})(function(){var e,t,r;return function(){function e(t,r,n){function i(o,s){if(!r[o]){if(!t[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(f)return f(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var a=r[o]={exports:{}};t[o][0].call(a.exports,function(e){var r=t[o][1][e];return i(r||e)},a,a.exports,e,t,r,n)}return r[o].exports}for(var f="function"==typeof require&&require,o=0;o<n.length;o++)i(n[o]);return i}return e}()({1:[function(e,t,r){"use strict";var n={};t.exports=n;n.extend=e("./extend.js");n.clone=e("./clone.js");n.path=e("./path.js")},{"./clone.js":2,"./extend.js":3,"./path.js":4}],2:[function(e,t,r){"use strict";t.exports=function e(t,r){var n,i,f,o,s,u,c=[{source:t,target:Array.isArray(t)?[]:Object.create(Object.getPrototypeOf(t))}],a=c[0].target,p=[t],d=[a];while(o=c.shift()){f=Object.getOwnPropertyNames(o.source);for(n=0;n<f.length;n++){i=Object.getOwnPropertyDescriptor(o.source,f[n]);if(!i.value||typeof i.value!=="object"){Object.defineProperty(o.target,f[n],i);continue}s=i.value;i.value=Array.isArray(s)?[]:Object.create(Object.getPrototypeOf(s));if(r){u=p.indexOf(s);if(u!==-1){i.value=d[u];Object.defineProperty(o.target,f[n],i);continue}p.push(s);d.push(i.value)}Object.defineProperty(o.target,f[n],i);c.push({source:s,target:i.value})}}return a}},{}],3:[function(e,t,r){"use strict";function n(e,t,...r){var n,f,o=false,s=r.length;if(!s){return t}if(!e||typeof e!=="object"){e={}}var u={depth:0,prefix:""};if(!e.maxDepth&&e.deep&&!e.circular){e.maxDepth=100}if(e.deepFunc){e.deep=true}if(e.deepFilter&&typeof e.deepFilter==="object"){if(e.deepFilter.whitelist&&(!Array.isArray(e.deepFilter.whitelist)||!e.deepFilter.whitelist.length)){delete e.deepFilter.whitelist}if(e.deepFilter.blacklist&&(!Array.isArray(e.deepFilter.blacklist)||!e.deepFilter.blacklist.length)){delete e.deepFilter.blacklist}if(!e.deepFilter.whitelist&&!e.deepFilter.blacklist){delete e.deepFilter}}if(e.flat){e.deep=true;e.proto=false;e.inherit=false;e.unflat=false;if(typeof e.flat!=="string"){e.flat="."}}if(e.unflat){e.deep=false;e.proto=false;e.inherit=false;e.flat=false;if(typeof e.unflat!=="string"){e.unflat="."}}if(e.inherit){e.own=true;e.proto=false}else if(e.proto){e.own=true}if(!t||typeof t!=="object"&&typeof t!=="function"){o=true}if(!e.skipRoot&&(e.inherit||e.proto)){for(n=s-1;n>=0;n--){f=r[n];if(f&&(typeof f==="object"||typeof f==="function")){if(e.inherit){if(o){t=Object.create(f)}else{Object.setPrototypeOf(t,f)}}else if(e.proto){if(o){t=Object.create(Object.getPrototypeOf(f))}else{Object.setPrototypeOf(t,Object.getPrototypeOf(f))}}break}}}else if(o){t={}}u.references={sources:[],targets:[]};for(n=0;n<s;n++){f=r[n];if(!f||typeof f!=="object"&&typeof f!=="function"){continue}i(u,e,t,f)}return t}t.exports=n;function i(e,t,r,n){var f,o,s,u,c,a,p,d,l,b,y,h=-1;if(t.maxDepth&&e.depth>t.maxDepth){throw new Error("[tree] extend(): max depth reached("+t.maxDepth+")")}if(t.circular){e.references.sources.push(n);e.references.targets.push(r)}if(t.own){if(t.nonEnum){s=Object.getOwnPropertyNames(n)}else{s=Object.keys(n)}}else{s=n}for(u in s){if(t.own){u=s[u]}if(u==="__proto__"){continue}if(t.descriptor){d=Object.getOwnPropertyDescriptor(n,u);c=d.value}else{c=n[u]}b=r;l=e.prefix+u;if(t.nofunc&&typeof c==="function"){continue}if(t.unflat&&e.depth===0){y=u.split(t.unflat);o=y.length-1;if(o){for(f=0;f<o;f++){if(!b[y[f]]||typeof b[y[f]]!=="object"&&typeof b[y[f]]!=="function"){b[y[f]]={}}b=b[y[f]]}l=e.prefix+y[o]}}if(t.deep&&c&&(typeof c==="object"||t.deepFunc&&typeof c==="function")&&(!t.descriptor||!d.get)&&((a=Object.getPrototypeOf(c))||true)&&(!t.deepFilter||(!t.deepFilter.whitelist||t.deepFilter.whitelist.indexOf(a)!==-1)&&(!t.deepFilter.blacklist||t.deepFilter.blacklist.indexOf(a)===-1))){if(t.circular){h=e.references.sources.indexOf(c)}if(t.flat){if(h>=0){continue}i({depth:e.depth+1,prefix:e.prefix+u+t.flat,references:e.references},t,b,c)}else{if(h>=0){if(t.descriptor){Object.defineProperty(b,l,{value:e.references.targets[h],enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{b[l]=e.references.targets[h]}continue}if(!b[l]||!b.hasOwnProperty(l)||typeof b[l]!=="object"&&typeof b[l]!=="function"){if(Array.isArray(c)){p=[]}else if(t.proto){p=Object.create(a)}else if(t.inherit){p=Object.create(c)}else{p={}}if(t.descriptor){Object.defineProperty(b,l,{value:p,enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{b[l]=p}}else if(t.proto&&Object.getPrototypeOf(b[l])!==a){Object.setPrototypeOf(b[l],a)}else if(t.inherit&&Object.getPrototypeOf(b[l])!==c){Object.setPrototypeOf(b[l],c)}if(t.circular){e.references.sources.push(c);e.references.targets.push(b[l])}i({depth:e.depth+1,prefix:"",references:e.references},t,b[l],c)}}else if(t.preserve&&b[l]!==undefined){continue}else if(!t.inherit){if(t.descriptor){Object.defineProperty(b,l,d)}else{b[l]=c}}if(t.move){delete n[u]}}}},{}],4:[function(e,t,r){"use strict";var n={};t.exports=n;n.op=function e(t,r,n,i){var f,o,s,u,c,a=false,p=false,d,l=true;if(!r||typeof r!=="object"&&typeof r!=="function"){return}if(typeof n==="string"){if(n){o=n.match(/([.#[\]]|[^.#[\]]+)/g)}else{o=[""]}if(o[0]==="."){o.unshift("")}if(o[o.length-1]==="."){o.push("")}}else if(Array.isArray(n)){o=n;p=true}else{throw new TypeError("[tree.path] ."+t+"(): the path argument should be a string or an array")}switch(t){case"get":case"delete":d=false;break;case"set":case"define":case"inc":case"dec":case"append":case"prepend":case"concat":case"insert":case"autoPush":d=true;break;default:throw new TypeError("[tree.path] .op(): wrong type of operation '"+t+"'")}u=r;s=o.length-1;for(f=0;f<=s;f++){if(p){if(c===undefined){c=o[f];continue}if(!u[c]||typeof u[c]!=="object"&&typeof u[c]!=="function"){if(!d){return undefined}u[c]={}}u=u[c];c=o[f];continue}else if(o[f]==="."){a=false;if(c===undefined){if(!l){l=true;continue}c=""}if(!u[c]||typeof u[c]!=="object"&&typeof u[c]!=="function"){if(!d){return undefined}u[c]={}}u=u[c];l=true;continue}else if(o[f]==="#"||o[f]==="["){a=true;l=false;if(c===undefined){if(!Array.isArray(u)){return undefined}continue}if(!u[c]||!Array.isArray(u[c])){if(!d){return undefined}u[c]=[]}u=u[c];continue}else if(o[f]==="]"){l=false;continue}l=false;if(!a){c=o[f];continue}switch(o[f]){case"length":c=o[f];break;case"first":c=0;break;case"last":c=u.length-1;if(c<0){c=0}break;case"next":if(!d){return undefined}c=u.length;break;case"insert":if(!d){return undefined}u.unshift(undefined);c=0;break;default:c=parseInt(o[f],10)}}switch(t){case"get":return u[c];case"delete":if(a&&typeof c==="number"){u.splice(c,1)}else{delete u[c]}return;case"set":u[c]=i;return u[c];case"define":if(!(c in u)){u[c]=i}return u[c];case"inc":if(typeof u[c]==="number"){u[c]++}else if(!u[c]||typeof u[c]!=="object"){u[c]=1}return u[c];case"dec":if(typeof u[c]==="number"){u[c]--}else if(!u[c]||typeof u[c]!=="object"){u[c]=-1}return u[c];case"append":if(!u[c]){u[c]=[i]}else if(Array.isArray(u[c])){u[c].push(i)}return u[c];case"prepend":if(!u[c]){u[c]=[i]}else if(Array.isArray(u[c])){u[c].unshift(i)}return u[c];case"concat":if(!u[c]){u[c]=i}else if(Array.isArray(u[c])&&Array.isArray(i)){u[c]=u[c].concat(i)}return u[c];case"insert":if(!u[c]){u[c]=i}else if(Array.isArray(u[c])&&Array.isArray(i)){u[c]=i.concat(u[c])}return u[c];case"autoPush":if(u[c]===undefined){u[c]=i}else if(Array.isArray(u[c])){u[c].push(i)}else{u[c]=[u[c],i]}return u[c]}};n.get=n.op.bind(undefined,"get");n.delete=n.op.bind(undefined,"delete");n.set=n.op.bind(undefined,"set");n.define=n.op.bind(undefined,"define");n.inc=n.op.bind(undefined,"inc");n.dec=n.op.bind(undefined,"dec");n.append=n.op.bind(undefined,"append");n.prepend=n.op.bind(undefined,"prepend");n.concat=n.op.bind(undefined,"concat");n.insert=n.op.bind(undefined,"insert");n.autoPush=n.op.bind(undefined,"autoPush");n.prototype={get:function(e){return n.get(this,e)},delete:function(e){return n.delete(this,e)},set:function(e,t){return n.set(this,e,t)},define:function(e,t){return n.define(this,e,t)},inc:function(e,t){return n.inc(this,e,t)},dec:function(e,t){return n.dec(this,e,t)},append:function(e,t){return n.append(this,e,t)},prepend:function(e,t){return n.prepend(this,e,t)},concat:function(e,t){return n.concat(this,e,t)},insert:function(e,t){return n.insert(this,e,t)},autoPush:function(e,t){return n.autoPush(this,e,t)}};n.upgrade=function e(t){Object.defineProperties(t,{get:{value:n.op.bind(undefined,"get",t)},delete:{value:n.op.bind(undefined,"delete",t)},set:{value:n.op.bind(undefined,"set",t)},define:{value:n.op.bind(undefined,"define",t)},inc:{value:n.op.bind(undefined,"inc",t)},dec:{value:n.op.bind(undefined,"dec",t)},append:{value:n.op.bind(undefined,"append",t)},prepend:{value:n.op.bind(undefined,"prepend",t)},concat:{value:n.op.bind(undefined,"concat",t)},insert:{value:n.op.bind(undefined,"insert",t)},autoPush:{value:n.op.bind(undefined,"autoPush",t)}})}},{}]},{},[1])(1)});
# Tree Kit

@@ -269,8 +268,1 @@

Full BDD spec generated by Mocha:
/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -20,0 +20,0 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -36,7 +36,6 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

module.exports = function clone( originalObject , circular )
{
module.exports = function clone( originalObject , circular ) {
// First create an empty object with
// same prototype of our original source
var propertyIndex , descriptor , keys , current , nextSource , indexOf ,

@@ -50,28 +49,23 @@ copies = [ {

targetReferences = [ cloneObject ] ;
// First in, first out
while ( current = copies.shift() ) // jshint ignore:line
{
while ( ( current = copies.shift() ) ) {
keys = Object.getOwnPropertyNames( current.source ) ;
for ( propertyIndex = 0 ; propertyIndex < keys.length ; propertyIndex ++ )
{
for ( propertyIndex = 0 ; propertyIndex < keys.length ; propertyIndex ++ ) {
// Save the source's descriptor
descriptor = Object.getOwnPropertyDescriptor( current.source , keys[ propertyIndex ] ) ;
if ( ! descriptor.value || typeof descriptor.value !== 'object' )
{
if ( ! descriptor.value || typeof descriptor.value !== 'object' ) {
Object.defineProperty( current.target , keys[ propertyIndex ] , descriptor ) ;
continue ;
}
nextSource = descriptor.value ;
descriptor.value = Array.isArray( nextSource ) ? [] : Object.create( Object.getPrototypeOf( nextSource ) ) ;
if ( circular )
{
if ( circular ) {
indexOf = sourceReferences.indexOf( nextSource ) ;
if ( indexOf !== -1 )
{
if ( indexOf !== -1 ) {
// The source is already referenced, just assign reference

@@ -82,14 +76,14 @@ descriptor.value = targetReferences[ indexOf ] ;

}
sourceReferences.push( nextSource ) ;
targetReferences.push( descriptor.value ) ;
}
Object.defineProperty( current.target , keys[ propertyIndex ] , descriptor ) ;
copies.push( { source: nextSource , target: descriptor.value } ) ;
}
}
return cloneObject ;
} ;
/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -36,26 +36,23 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

function diff( left , right , options )
{
function diff( left , right , options ) {
var i , key , keyPath ,
leftKeys , rightKeys , leftTypeof , rightTypeof ,
depth , diffObject , length , arrayMode ;
leftTypeof = typeof left ;
rightTypeof = typeof right ;
if (
! left || ( leftTypeof !== 'object' && leftTypeof !== 'function' ) ||
! right || ( rightTypeof !== 'object' && rightTypeof !== 'function' )
)
{
) {
throw new Error( '[tree] diff() needs objects as argument #0 and #1' ) ;
}
if ( ! options || typeof options !== 'object' ) { options = {} ; }
depth = options.depth || 0 ;
// Things applied only for the root, not for recursive call
if ( ! depth )
{
if ( ! depth ) {
options.diffObject = {} ;

@@ -65,14 +62,12 @@ if ( ! options.path ) { options.path = '' ; }

}
diffObject = options.diffObject ;
// Left part
if ( Array.isArray( left ) )
{
if ( Array.isArray( left ) ) {
arrayMode = true ;
length = left.length ;
}
else
{
else {
arrayMode = false ;

@@ -82,57 +77,50 @@ leftKeys = Object.keys( left ) ;

}
for ( i = 0 ; i < length ; i ++ )
{
for ( i = 0 ; i < length ; i ++ ) {
key = arrayMode ? i : leftKeys[ i ] ;
keyPath = options.path + options.pathSeparator + key ;
//console.log( 'L keyPath:' , keyPath ) ;
if ( ! right.hasOwnProperty( key ) )
{
if ( ! right.hasOwnProperty( key ) ) {
diffObject[ keyPath ] = { path: keyPath , message: 'does not exist in right-hand side' } ;
continue ;
}
leftTypeof = typeof left[ key ] ;
rightTypeof = typeof right[ key ] ;
if ( leftTypeof !== rightTypeof )
{
if ( leftTypeof !== rightTypeof ) {
diffObject[ keyPath ] = { path: keyPath , message: 'different typeof: ' + leftTypeof + ' - ' + rightTypeof } ;
continue ;
}
if ( leftTypeof === 'object' || leftTypeof === 'function' )
{
if ( leftTypeof === 'object' || leftTypeof === 'function' ) {
// Cleanup the 'null is an object' mess
if ( ! left[ key ] )
{
if ( ! left[ key ] ) {
if ( right[ key ] ) { diffObject[ keyPath ] = { path: keyPath , message: 'different type: null - Object' } ; }
continue ;
}
if ( ! right[ key ] )
{
if ( ! right[ key ] ) {
diffObject[ keyPath ] = { path: keyPath , message: 'different type: Object - null' } ;
continue ;
}
if ( Array.isArray( left[ key ] ) && ! Array.isArray( right[ key ] ) )
{
if ( Array.isArray( left[ key ] ) && ! Array.isArray( right[ key ] ) ) {
diffObject[ keyPath ] = { path: keyPath , message: 'different type: Array - Object' } ;
continue ;
}
if ( ! Array.isArray( left[ key ] ) && Array.isArray( right[ key ] ) )
{
if ( ! Array.isArray( left[ key ] ) && Array.isArray( right[ key ] ) ) {
diffObject[ keyPath ] = { path: keyPath , message: 'different type: Object - Array' } ;
continue ;
}
diff( left[ key ] , right[ key ] , { path: keyPath , pathSeparator: options.pathSeparator , depth: depth + 1 , diffObject: diffObject } ) ;
diff( left[ key ] , right[ key ] , {
path: keyPath , pathSeparator: options.pathSeparator , depth: depth + 1 , diffObject: diffObject
} ) ;
continue ;
}
if ( left[ key ] !== right[ key ] )
{
if ( left[ key ] !== right[ key ] ) {
diffObject[ keyPath ] = { path: keyPath , message: 'different value: ' + left[ key ] + ' - ' + right[ key ] } ;

@@ -142,12 +130,10 @@ continue ;

}
// Right part
if ( Array.isArray( right ) )
{
if ( Array.isArray( right ) ) {
arrayMode = true ;
length = right.length ;
}
else
{
else {
arrayMode = false ;

@@ -157,11 +143,9 @@ rightKeys = Object.keys( right ) ;

}
for ( i = 0 ; i < length ; i ++ )
{
for ( i = 0 ; i < length ; i ++ ) {
key = arrayMode ? i : rightKeys[ i ] ;
keyPath = options.path + options.pathSeparator + key ;
//console.log( 'R keyPath:' , keyPath ) ;
if ( ! left.hasOwnProperty( key ) )
{
if ( ! left.hasOwnProperty( key ) ) {
diffObject[ keyPath ] = { path: keyPath , message: 'does not exist in left-hand side' } ;

@@ -171,3 +155,3 @@ continue ;

}
return Object.keys( diffObject ).length ? diffObject : null ;

@@ -174,0 +158,0 @@ }

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -63,22 +63,17 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

*/
function extend( options , target )
{
function extend( options , target , ... sources ) {
//console.log( "\nextend():\n" , arguments ) ;
var i , source , newTarget = false , length = arguments.length ;
if ( length < 3 ) { return target ; }
var sources = Array.prototype.slice.call( arguments , 2 ) ;
length = sources.length ;
var i , source , newTarget = false , length = sources.length ;
if ( ! length ) { return target ; }
if ( ! options || typeof options !== 'object' ) { options = {} ; }
var runtime = { depth: 0 , prefix: '' } ;
if ( ! options.maxDepth && options.deep && ! options.circular ) { options.maxDepth = 100 ; }
if ( options.deepFunc ) { options.deep = true ; }
if ( options.deepFilter && typeof options.deepFilter === 'object' )
{
if ( options.deepFilter && typeof options.deepFilter === 'object' ) {
if ( options.deepFilter.whitelist && ( ! Array.isArray( options.deepFilter.whitelist ) || ! options.deepFilter.whitelist.length ) ) { delete options.deepFilter.whitelist ; }

@@ -88,6 +83,5 @@ if ( options.deepFilter.blacklist && ( ! Array.isArray( options.deepFilter.blacklist ) || ! options.deepFilter.blacklist.length ) ) { delete options.deepFilter.blacklist ; }

}
// 'flat' option force 'deep'
if ( options.flat )
{
if ( options.flat ) {
options.deep = true ;

@@ -99,5 +93,4 @@ options.proto = false ;

}
if ( options.unflat )
{
if ( options.unflat ) {
options.deep = false ;

@@ -109,30 +102,24 @@ options.proto = false ;

}
// If the prototype is applied, only owned properties should be copied
if ( options.inherit ) { options.own = true ; options.proto = false ; }
else if ( options.proto ) { options.own = true ; }
if ( ! target || ( typeof target !== 'object' && typeof target !== 'function' ) )
{
if ( ! target || ( typeof target !== 'object' && typeof target !== 'function' ) ) {
newTarget = true ;
}
if ( ! options.skipRoot && ( options.inherit || options.proto ) )
{
for ( i = length - 1 ; i >= 0 ; i -- )
{
if ( ! options.skipRoot && ( options.inherit || options.proto ) ) {
for ( i = length - 1 ; i >= 0 ; i -- ) {
source = sources[ i ] ;
if ( source && ( typeof source === 'object' || typeof source === 'function' ) )
{
if ( options.inherit )
{
if ( source && ( typeof source === 'object' || typeof source === 'function' ) ) {
if ( options.inherit ) {
if ( newTarget ) { target = Object.create( source ) ; }
else { Object.setPrototypeOf( target , source ) ; }
}
else if ( options.proto )
{
else if ( options.proto ) {
if ( newTarget ) { target = Object.create( Object.getPrototypeOf( source ) ) ; }
else { Object.setPrototypeOf( target , Object.getPrototypeOf( source ) ) ; }
}
break ;

@@ -142,11 +129,9 @@ }

}
else if ( newTarget )
{
else if ( newTarget ) {
target = {} ;
}
runtime.references = { sources: [] , targets: [] } ;
for ( i = 0 ; i < length ; i ++ )
{
for ( i = 0 ; i < length ; i ++ ) {
source = sources[ i ] ;

@@ -156,3 +141,3 @@ if ( ! source || ( typeof source !== 'object' && typeof source !== 'function' ) ) { continue ; }

}
return target ;

@@ -165,26 +150,22 @@ }

function extendOne( runtime , options , target , source )
{
function extendOne( runtime , options , target , source ) {
//console.log( "\nextendOne():\n" , arguments ) ;
//process.exit() ;
var j , jmax , sourceKeys , sourceKey , sourceValue , sourceValueProto ,
value , sourceDescriptor , targetKey , targetPointer , path ,
indexOfSource = -1 ;
// Max depth check
if ( options.maxDepth && runtime.depth > options.maxDepth )
{
if ( options.maxDepth && runtime.depth > options.maxDepth ) {
throw new Error( '[tree] extend(): max depth reached(' + options.maxDepth + ')' ) ;
}
if ( options.circular )
{
if ( options.circular ) {
runtime.references.sources.push( source ) ;
runtime.references.targets.push( target ) ;
}
if ( options.own )
{
if ( options.own ) {
if ( options.nonEnum ) { sourceKeys = Object.getOwnPropertyNames( source ) ; }

@@ -194,70 +175,63 @@ else { sourceKeys = Object.keys( source ) ; }

else { sourceKeys = source ; }
for ( sourceKey in sourceKeys )
{
for ( sourceKey in sourceKeys ) {
if ( options.own ) { sourceKey = sourceKeys[ sourceKey ] ; }
// OMG, this DEPRECATED __proto__ shit is still alive and can be used to hack anything ><
if ( sourceKey === '__proto__' ) { continue ; }
// If descriptor is on, get it now
if ( options.descriptor )
{
if ( options.descriptor ) {
sourceDescriptor = Object.getOwnPropertyDescriptor( source , sourceKey ) ;
sourceValue = sourceDescriptor.value ;
}
else
{
else {
// We have to trigger an eventual getter only once
sourceValue = source[ sourceKey ] ;
}
targetPointer = target ;
targetKey = runtime.prefix + sourceKey ;
// Do not copy if property is a function and we don't want them
if ( options.nofunc && typeof sourceValue === 'function' ) { continue; }
if ( options.nofunc && typeof sourceValue === 'function' ) { continue ; }
// 'unflat' mode computing
if ( options.unflat && runtime.depth === 0 )
{
if ( options.unflat && runtime.depth === 0 ) {
path = sourceKey.split( options.unflat ) ;
jmax = path.length - 1 ;
if ( jmax )
{
for ( j = 0 ; j < jmax ; j ++ )
{
if ( jmax ) {
for ( j = 0 ; j < jmax ; j ++ ) {
if ( ! targetPointer[ path[ j ] ] ||
( typeof targetPointer[ path[ j ] ] !== 'object' &&
typeof targetPointer[ path[ j ] ] !== 'function' ) )
{
typeof targetPointer[ path[ j ] ] !== 'function' ) ) {
targetPointer[ path[ j ] ] = {} ;
}
targetPointer = targetPointer[ path[ j ] ] ;
}
targetKey = runtime.prefix + path[ jmax ] ;
}
}
if ( options.deep &&
if ( options.deep && // eslint-disable-line no-constant-condition
sourceValue &&
( typeof sourceValue === 'object' || ( options.deepFunc && typeof sourceValue === 'function' ) ) &&
( ! options.descriptor || ! sourceDescriptor.get ) &&
// not a condition we just cache sourceValueProto now
// not a condition we just cache sourceValueProto now... ok it's trashy ><
( ( sourceValueProto = Object.getPrototypeOf( sourceValue ) ) || true ) &&
( ! options.deepFilter ||
( ( ! options.deepFilter.whitelist || options.deepFilter.whitelist.indexOf( sourceValueProto ) !== -1 ) &&
( ! options.deepFilter.blacklist || options.deepFilter.blacklist.indexOf( sourceValueProto ) === -1 ) ) ) )
{
if ( options.circular )
{
( ! options.deepFilter.blacklist || options.deepFilter.blacklist.indexOf( sourceValueProto ) === -1 ) ) ) ) {
if ( options.circular ) {
indexOfSource = runtime.references.sources.indexOf( sourceValue ) ;
}
if ( options.flat )
{
if ( options.flat ) {
// No circular references reconnection when in 'flat' mode
if ( indexOfSource >= 0 ) { continue ; }
extendOne(

@@ -268,9 +242,6 @@ { depth: runtime.depth + 1 , prefix: runtime.prefix + sourceKey + options.flat , references: runtime.references } ,

}
else
{
if ( indexOfSource >= 0 )
{
else {
if ( indexOfSource >= 0 ) {
// Circular references reconnection...
if ( options.descriptor )
{
if ( options.descriptor ) {
Object.defineProperty( targetPointer , targetKey , {

@@ -283,12 +254,10 @@ value: runtime.references.targets[ indexOfSource ] ,

}
else
{
else {
targetPointer[ targetKey ] = runtime.references.targets[ indexOfSource ] ;
}
continue ;
}
if ( ! targetPointer[ targetKey ] || ! targetPointer.hasOwnProperty( targetKey ) || ( typeof targetPointer[ targetKey ] !== 'object' && typeof targetPointer[ targetKey ] !== 'function' ) )
{
if ( ! targetPointer[ targetKey ] || ! targetPointer.hasOwnProperty( targetKey ) || ( typeof targetPointer[ targetKey ] !== 'object' && typeof targetPointer[ targetKey ] !== 'function' ) ) {
if ( Array.isArray( sourceValue ) ) { value = [] ; }

@@ -298,5 +267,4 @@ else if ( options.proto ) { value = Object.create( sourceValueProto ) ; } // jshint ignore:line

else { value = {} ; }
if ( options.descriptor )
{
if ( options.descriptor ) {
Object.defineProperty( targetPointer , targetKey , {

@@ -309,22 +277,18 @@ value: value ,

}
else
{
else {
targetPointer[ targetKey ] = value ;
}
}
else if ( options.proto && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValueProto )
{
else if ( options.proto && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValueProto ) {
Object.setPrototypeOf( targetPointer[ targetKey ] , sourceValueProto ) ;
}
else if ( options.inherit && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValue )
{
else if ( options.inherit && Object.getPrototypeOf( targetPointer[ targetKey ] ) !== sourceValue ) {
Object.setPrototypeOf( targetPointer[ targetKey ] , sourceValue ) ;
}
if ( options.circular )
{
if ( options.circular ) {
runtime.references.sources.push( sourceValue ) ;
runtime.references.targets.push( targetPointer[ targetKey ] ) ;
}
// Recursively extends sub-object

@@ -337,13 +301,11 @@ extendOne(

}
else if ( options.preserve && targetPointer[ targetKey ] !== undefined )
{
else if ( options.preserve && targetPointer[ targetKey ] !== undefined ) {
// Do not overwrite, and so do not delete source's properties that were not moved
continue ;
}
else if ( ! options.inherit )
{
else if ( ! options.inherit ) {
if ( options.descriptor ) { Object.defineProperty( targetPointer , targetKey , sourceDescriptor ) ; }
else { targetPointer[ targetKey ] = sourceValue ; }
}
// Delete owned property of the source object

@@ -350,0 +312,0 @@ if ( options.move ) { delete source[ sourceKey ] ; }

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -36,4 +36,3 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

exports.defineLazyProperty = function defineLazyProperty( object , name , func )
{
exports.defineLazyProperty = function defineLazyProperty( object , name , func ) {
Object.defineProperty( object , name , {

@@ -43,5 +42,5 @@ configurable: true ,

get: function() {
var value = func() ;
Object.defineProperty( object , name , {

@@ -53,3 +52,3 @@ configurable: true ,

} ) ;
return value ;

@@ -56,0 +55,0 @@ }

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -46,3 +46,3 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

== Mask-family class ==
Recursively select values in the input object if the same path in the mask object is set.

@@ -58,4 +58,3 @@ */

masklib.Mask = function Mask()
{
masklib.Mask = function Mask() {
throw new Error( 'Cannot create a tree.Mask() directly' ) ;

@@ -81,18 +80,16 @@ } ;

*/
masklib.createMask = function createMask( maskArgument , options )
{
if ( maskArgument === null || typeof maskArgument !== 'object' )
{
masklib.createMask = function createMask( maskArgument , options ) {
if ( maskArgument === null || typeof maskArgument !== 'object' ) {
throw new TypeError( '[tree] .createMask() : Argument #1 should be an object' ) ;
}
if ( options !== null && typeof options === 'object' ) { options = tree.extend( null , {} , maskDefaultOptions , options ) ; }
else { options = maskDefaultOptions ; }
var mask = Object.create( masklib.Mask.prototype , {
__options__: { value: options , writable: true }
} ) ;
tree.extend( null , mask , maskArgument ) ;
return mask ;

@@ -104,12 +101,9 @@ } ;

// Apply the mask to an input tree
masklib.Mask.prototype.applyTo = function applyTo( input , context , contextOverideDefault )
{
masklib.Mask.prototype.applyTo = function applyTo( input , context , contextOverideDefault ) {
// Arguments checking
if ( input === null || typeof input !== 'object' )
{
if ( input === null || typeof input !== 'object' ) {
throw new TypeError( '[tree] .applyTo() : Argument #1 should be an object' ) ;
}
if ( contextOverideDefault )
{
if ( contextOverideDefault ) {
context = tree.extend( null ,

@@ -124,4 +118,3 @@ {

}
else if ( context === undefined )
{
else if ( context === undefined ) {
context = {

@@ -133,4 +126,4 @@ mask: this ,

}
// Init

@@ -142,50 +135,41 @@ //console.log( context ) ;

j , inputKey , inputValue , inputKeyList ;
if ( Array.isArray( input ) ) { output = [] ; }
else { output = {} ; }
// Iterate through mask properties
for ( i = 0 ; i < maskKeyList.length ; i ++ )
{
for ( i = 0 ; i < maskKeyList.length ; i ++ ) {
key = maskKeyList[ i ] ;
maskValue = context.mask[ key ] ;
//console.log( '\nnext loop: ' , key , maskValue ) ;
// The special key * is a wildcard, it match everything
if ( key === '*' )
{
if ( key === '*' ) {
//console.log( 'wildcard' ) ;
inputKeyList = Object.keys( input ) ;
for ( j = 0 ; j < inputKeyList.length ; j ++ )
{
for ( j = 0 ; j < inputKeyList.length ; j ++ ) {
inputKey = inputKeyList[ j ] ;
inputValue = input[ inputKey ] ;
//console.log( '*: ' , inputKey ) ;
nextPath = context.path + context.options.pathSeparator + inputKey ;
// If it is an array or object, recursively check it
if ( maskValue !== null && typeof maskValue === 'object' )
{
if ( input[ inputKey ] !== null && typeof input[ inputKey ] === 'object' )
{
if ( input[ inputKey ] instanceof masklib.Mask )
{
output[ inputKey ] = input[ inputKey ].applyTo( input[ inputKey ] , { path: nextPath } , true ) ;
if ( maskValue !== null && typeof maskValue === 'object' ) {
if ( inputValue !== null && typeof inputValue === 'object' ) {
if ( inputValue instanceof masklib.Mask ) {
output[ inputKey ] = inputValue.applyTo( inputValue , { path: nextPath } , true ) ;
}
else
{
output[ inputKey ] = this.applyTo( input[ inputKey ] , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;
else {
output[ inputKey ] = this.applyTo( inputValue , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;
}
}
else if ( typeof context.options.leaf === 'function' )
{
else if ( typeof context.options.leaf === 'function' ) {
output[ inputKey ] = this.applyTo( {} , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;
}
}
else if ( maskValue !== null && typeof context.options.leaf === 'function' )
{
else if ( maskValue !== null && typeof context.options.leaf === 'function' ) {
//console.log( 'leaf callback' ) ;

@@ -195,37 +179,28 @@ result = context.options.leaf( input , inputKey , maskValue , nextPath ) ;

}
else
{
if ( context.options.clone && ( input[ inputKey ] !== null && typeof input[ inputKey ] === 'object' ) )
{
output[ inputKey ] = tree.extend( { deep: true } , {} , input[ inputKey ] ) ;
}
else
{
output[ inputKey ] = input[ inputKey ] ;
}
else if ( context.options.clone && ( inputValue !== null && typeof inputValue === 'object' ) ) {
output[ inputKey ] = tree.extend( { deep: true } , {} , inputValue ) ;
}
else {
output[ inputKey ] = inputValue ;
}
}
continue ;
}
nextPath = context.path + context.options.pathSeparator + key ;
// If it is an object, recursively check it
//if ( maskValue instanceof masklib.Mask )
if ( maskValue !== null && typeof maskValue === 'object' )
{
if ( maskValue !== null && typeof maskValue === 'object' ) {
//console.log( 'sub' ) ;
if ( input.hasOwnProperty( key ) && input[ key ] !== null && typeof input[ key ] === 'object' )
{
if ( input.hasOwnProperty( key ) && input[ key ] !== null && typeof input[ key ] === 'object' ) {
//console.log( 'recursive call' ) ;
if ( input.key instanceof masklib.Mask )
{
if ( input.key instanceof masklib.Mask ) {
output[ key ] = input.key.applyTo( input[ key ] , { path: nextPath } , true ) ;
}
else
{
else {
output[ key ] = this.applyTo( input[ key ] , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;

@@ -235,4 +210,3 @@ }

// recursive call only if there are callback
else if ( context.options.leaf )
{
else if ( context.options.leaf ) {
//console.log( 'recursive call' ) ;

@@ -243,8 +217,6 @@ output[ key ] = this.applyTo( {} , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;

// If mask exists, add the key
else if ( input.hasOwnProperty( key ) )
{
else if ( input.hasOwnProperty( key ) ) {
//console.log( 'property found' ) ;
if ( maskValue !== undefined && typeof context.options.leaf === 'function' )
{
if ( maskValue !== undefined && typeof context.options.leaf === 'function' ) {
//console.log( 'leaf callback' ) ;

@@ -254,16 +226,10 @@ result = context.options.leaf( input , key , maskValue , nextPath ) ;

}
else
{
if ( context.options.clone && ( input[ key ] !== null && typeof input[ key ] === 'object' ) )
{
output[ key ] = tree.extend( { deep: true } , {} , input[ key ] ) ;
}
else
{
output[ key ] = input[ key ] ;
}
else if ( context.options.clone && ( input[ key ] !== null && typeof input[ key ] === 'object' ) ) {
output[ key ] = tree.extend( { deep: true } , {} , input[ key ] ) ;
}
else {
output[ key ] = input[ key ] ;
}
}
else if ( maskValue !== undefined && typeof context.options.leaf === 'function' )
{
else if ( maskValue !== undefined && typeof context.options.leaf === 'function' ) {
//console.log( 'leaf callback' ) ;

@@ -274,3 +240,3 @@ result = context.options.leaf( input , key , maskValue , nextPath ) ;

}
return output ;

@@ -283,4 +249,3 @@ } ;

masklib.InverseMask = function InverseMask()
{
masklib.InverseMask = function InverseMask() {
throw new Error( 'Cannot create a tree.InverseMask() directly' ) ;

@@ -298,18 +263,16 @@ } ;

*/
masklib.createInverseMask = function createInverseMask( maskArgument , options )
{
if ( maskArgument === null || typeof maskArgument !== 'object' )
{
masklib.createInverseMask = function createInverseMask( maskArgument , options ) {
if ( maskArgument === null || typeof maskArgument !== 'object' ) {
throw new TypeError( '[tree] .createInverseMask() : Argument #1 should be an object' ) ;
}
if ( options !== null && typeof options === 'object' ) { options = tree.extend( null , {} , maskDefaultOptions , options ) ; }
else { options = maskDefaultOptions ; }
var mask = Object.create( masklib.InverseMask.prototype , {
__options__: { value: options , writable: true }
} ) ;
tree.extend( null , mask , maskArgument ) ;
return mask ;

@@ -321,12 +284,9 @@ } ;

// Apply the mask to an input tree
masklib.InverseMask.prototype.applyTo = function applyTo( input , context , contextOverideDefault )
{
masklib.InverseMask.prototype.applyTo = function applyTo( input , context , contextOverideDefault ) {
// Arguments checking
if ( input === null || typeof input !== 'object' )
{
if ( input === null || typeof input !== 'object' ) {
throw new TypeError( '[tree] .applyTo() : Argument #1 should be an object' ) ;
}
if ( contextOverideDefault )
{
if ( contextOverideDefault ) {
context = tree.extend( null ,

@@ -341,4 +301,3 @@ {

}
else if ( context === undefined )
{
else if ( context === undefined ) {
context = {

@@ -350,4 +309,4 @@ mask: this ,

}
// Init

@@ -359,73 +318,61 @@ //console.log( context ) ;

j , inputKey , inputValue , inputKeyList ;
if ( Array.isArray( input ) ) { output = tree.extend( { deep: true } , [] , input ) ; }
else { output = tree.extend( { deep: true } , {} , input ) ; }
//console.log( output ) ;
// Iterate through mask properties
for ( i = 0 ; i < maskKeyList.length ; i ++ )
{
for ( i = 0 ; i < maskKeyList.length ; i ++ ) {
key = maskKeyList[ i ] ;
maskValue = context.mask[ key ] ;
//console.log( '\nnext loop: ' , key , maskValue ) ;
// The special key * is a wildcard, it match everything
if ( key === '*' )
{
if ( key === '*' ) {
//console.log( 'wildcard' ) ;
inputKeyList = Object.keys( input ) ;
for ( j = 0 ; j < inputKeyList.length ; j ++ )
{
for ( j = 0 ; j < inputKeyList.length ; j ++ ) {
inputKey = inputKeyList[ j ] ;
inputValue = input[ inputKey ] ;
//console.log( '*: ' , inputKey ) ;
nextPath = context.path + context.options.pathSeparator + inputKey ;
// If it is an array or object, recursively check it
if ( maskValue !== null && typeof maskValue === 'object' )
{
if ( input[ inputKey ] !== null && typeof input[ inputKey ] === 'object' )
{
if ( input[ inputKey ] instanceof masklib.Mask )
{
output[ inputKey ] = input[ inputKey ].applyTo( input[ inputKey ] , { path: nextPath } , true ) ;
if ( maskValue !== null && typeof maskValue === 'object' ) {
if ( inputValue !== null && typeof inputValue === 'object' ) {
if ( inputValue instanceof masklib.Mask ) {
output[ inputKey ] = inputValue.applyTo( inputValue , { path: nextPath } , true ) ;
}
else
{
output[ inputKey ] = this.applyTo( input[ inputKey ] , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;
else {
output[ inputKey ] = this.applyTo( inputValue , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;
}
}
}
else
{
else {
delete output[ inputKey ] ;
}
}
continue ;
}
nextPath = context.path + context.options.pathSeparator + key ;
// If it is an object, recursively check it
//if ( maskValue instanceof masklib.Mask )
if ( maskValue !== null && typeof maskValue === 'object' )
{
if ( maskValue !== null && typeof maskValue === 'object' ) {
//console.log( 'sub' ) ;
if ( input.hasOwnProperty( key ) && input[ key ] !== null && typeof input[ key ] === 'object' )
{
if ( input.hasOwnProperty( key ) && input[ key ] !== null && typeof input[ key ] === 'object' ) {
//console.log( 'recursive call' ) ;
if ( input.key instanceof masklib.Mask )
{
if ( input.key instanceof masklib.Mask ) {
output[ key ] = input.key.applyTo( input[ key ] , { path: nextPath } , true ) ;
}
else
{
else {
output[ key ] = this.applyTo( input[ key ] , tree.extend( null , {} , context , { mask: maskValue , path: nextPath } ) ) ;

@@ -436,9 +383,8 @@ }

// If mask exists, remove the key
else if ( input.hasOwnProperty( key ) )
{
else if ( input.hasOwnProperty( key ) ) {
delete output[ key ] ;
}
}
return output ;
} ;
/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -37,32 +37,26 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

treePath.op = function op( type , object , path , value )
{
treePath.op = function op( type , object , path , value ) {
var i , parts , last , pointer , key , isArray = false , pathArrayMode = false , isGenericSet , canBeEmpty = true ;
if ( ! object || ( typeof object !== 'object' && typeof object !== 'function' ) )
{
if ( ! object || ( typeof object !== 'object' && typeof object !== 'function' ) ) {
return ;
}
if ( typeof path === 'string' )
{
if ( typeof path === 'string' ) {
// Split the path into parts
if ( path ) { parts = path.match( /([.#\[\]]|[^.#\[\]]+)/g ) ; }
if ( path ) { parts = path.match( /([.#[\]]|[^.#[\]]+)/g ) ; }
else { parts = [ '' ] ; }
if ( parts[ 0 ] === '.' ) { parts.unshift( '' ) ; }
if ( parts[ parts.length - 1 ] === '.' ) { parts.push( '' ) ; }
}
else if ( Array.isArray( path ) )
{
else if ( Array.isArray( path ) ) {
parts = path ;
pathArrayMode = true ;
}
else
{
else {
throw new TypeError( '[tree.path] .' + type + '(): the path argument should be a string or an array' ) ;
}
switch ( type )
{
switch ( type ) {
case 'get' :

@@ -86,63 +80,53 @@ case 'delete' :

}
//console.log( parts ) ;
// The pointer start at the object's root
pointer = object ;
last = parts.length - 1 ;
for ( i = 0 ; i <= last ; i ++ )
{
if ( pathArrayMode )
{
if ( key === undefined )
{
for ( i = 0 ; i <= last ; i ++ ) {
if ( pathArrayMode ) {
if ( key === undefined ) {
key = parts[ i ] ;
continue ;
}
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) )
{
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) ) {
if ( ! isGenericSet ) { return undefined ; }
pointer[ key ] = {} ;
}
pointer = pointer[ key ] ;
key = parts[ i ] ;
continue ;
}
else if ( parts[ i ] === '.' )
{
else if ( parts[ i ] === '.' ) {
isArray = false ;
if ( key === undefined )
{
if ( ! canBeEmpty )
{
if ( key === undefined ) {
if ( ! canBeEmpty ) {
canBeEmpty = true ;
continue ;
}
key = '' ;
}
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) )
{
if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) ) {
if ( ! isGenericSet ) { return undefined ; }
pointer[ key ] = {} ;
}
pointer = pointer[ key ] ;
canBeEmpty = true ;
continue ;
}
else if ( parts[ i ] === '#' || parts[ i ] === '[' )
{
else if ( parts[ i ] === '#' || parts[ i ] === '[' ) {
isArray = true ;
canBeEmpty = false ;
if ( key === undefined )
{
if ( key === undefined ) {
// The root element cannot be altered, we are in trouble if an array is expected but we have only a regular object.

@@ -152,15 +136,13 @@ if ( ! Array.isArray( pointer ) ) { return undefined ; }

}
if ( ! pointer[ key ] || ! Array.isArray( pointer[ key ] ) )
{
if ( ! pointer[ key ] || ! Array.isArray( pointer[ key ] ) ) {
if ( ! isGenericSet ) { return undefined ; }
pointer[ key ] = [] ;
}
pointer = pointer[ key ] ;
continue ;
}
else if ( parts[ i ] === ']' )
{
else if ( parts[ i ] === ']' ) {
// Closing bracket: do nothing

@@ -170,13 +152,12 @@ canBeEmpty = false ;

}
canBeEmpty = false ;
if ( ! isArray ) { key = parts[ i ] ; continue ; }
switch ( parts[ i ] )
{
switch ( parts[ i ] ) {
case 'length' :
key = parts[ i ] ;
break ;
// Pseudo-key

@@ -199,5 +180,5 @@ case 'first' :

break ;
// default = number
default:
default :
// Convert the string key to a numerical index

@@ -207,5 +188,4 @@ key = parseInt( parts[ i ] , 10 ) ;

}
switch ( type )
{
switch ( type ) {
case 'get' :

@@ -244,4 +224,3 @@ return pointer[ key ] ;

if ( ! pointer[ key ] ) { pointer[ key ] = value ; }
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) )
{
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) ) {
pointer[ key ] = pointer[ key ].concat( value ) ;

@@ -253,4 +232,3 @@ }

if ( ! pointer[ key ] ) { pointer[ key ] = value ; }
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) )
{
else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) ) {
pointer[ key ] = value.concat( pointer[ key ] ) ;

@@ -303,4 +281,3 @@ }

// Upgrade an object so it can support get, set and delete at its root
treePath.upgrade = function upgrade( object )
{
treePath.upgrade = function upgrade( object ) {
Object.defineProperties( object , {

@@ -307,0 +284,0 @@ get: { value: treePath.op.bind( undefined , 'get' , object ) } ,

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -43,9 +43,9 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

tree.extend( null , tree ,
// Tier 1
require( './lazy.js' ) ,
// Tier 2
{ clone: require( './clone.js' ) } ,
// Tier 3

@@ -52,0 +52,0 @@ { path: require( './path.js' ) } ,

{
"name": "tree-kit",
"version": "0.5.26",
"version": "0.5.27",
"description": "Tree utilities which provides a full-featured extend and object-cloning facility, and various tools to deal with nested object structures.",

@@ -12,10 +12,7 @@ "main": "lib/tree.js",

"devDependencies": {
"browserify": "^13.0.1",
"expect.js": "^0.3.1",
"jshint": "^2.5.6",
"mocha": "^2.2.5",
"uglify-js": "^2.7.0"
"browserify": "^16.2.2",
"uglify-js-es6": "^2.8.9"
},
"scripts": {
"test": "mocha -R dot"
"test": "tea-time -R dot"
},

@@ -41,2 +38,9 @@ "repository": {

},
"config": {
"tea-time": {
"coverDir": [
"lib"
]
}
},
"copyright": {

@@ -46,3 +50,3 @@ "title": "Tree Kit",

2014,
2016
2018
],

@@ -49,0 +53,0 @@ "owner": "Cédric Ronvel"

# Tree Kit

@@ -269,2082 +268,1 @@

Full BDD spec generated by Mocha:
# TOC
- [clone()](#clone)
- [Diff](#diff)
- [extend()](#extend)
- [defineLazyProperty()](#definelazyproperty)
- [Masks](#masks)
- [Inverse masks](#inverse-masks)
- [Tree's path on objects](#trees-path-on-objects)
- [Tree's path on arrays](#trees-path-on-arrays)
- [Tree's path on mixed object and arrays](#trees-path-on-mixed-object-and-arrays)
- [Inheritance, using Object.create( tree.path.prototype )](#inheritance-using-objectcreate-treepathprototype-)
- [Tree's array path on objects](#trees-array-path-on-objects)
<a name=""></a>
<a name="clone"></a>
# clone()
basic incomplete test.
```js
var proto = {
proto1: 'proto1' ,
proto2: 'proto2' ,
hello: function() { console.log( "Hello!" ) ; }
} ;
var o = Object.create( proto ) ;
o.own1 = 'own1' ;
o.own2 = 'own2' ;
o.nested = { a: 1 , b: 2 } ;
var getter = function() { return 5 ; } ;
var setter = function( value ) {} ;
Object.defineProperties( o , {
nonEnum1: { value: 'nonEnum1' } ,
nonEnum2: { value: 'nonEnum2' , writable: true } ,
nonEnum3: { value: 'nonEnum3' , configurable: true } ,
nonEnumNested: { value: { c: 3 , d: 4 } } ,
getter: { get: getter } ,
getterAndSetter: { get: getter , set: setter }
} ) ;
var i , r ;
// Basic tests with and without circular checks
for ( i = 0 ; i <= 1 ; i ++ )
{
if ( i === 0 ) { r = tree.clone( o ) ;}
else { r = tree.clone( o , true ) ; }
expect( Object.getOwnPropertyNames( r ) ).to.eql( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.eql( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.eql( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( r.nested ).not.to.be( o.nested ) ;
expect( r.nested ).to.eql( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.eql( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.eql( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.eql( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.eql( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nonEnumNested ).not.to.be( o.nonEnumNested ) ;
expect( r.nonEnumNested ).to.eql( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.eql( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.eql( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.eql( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
expect( r.__proto__ ).to.equal( proto ) ; // jshint ignore:line
expect( r.proto1 ).to.be( 'proto1' ) ;
expect( r.proto2 ).to.be( 'proto2' ) ;
expect( typeof r.hello ).to.equal( 'function' ) ;
}
```
circular references test.
```js
var c , o = {
a: 'a',
sub: {
b: 'b'
},
sub2: {
c: 'c'
}
} ;
o.loop = o ;
o.sub.loop = o ;
o.subcopy = o.sub ;
o.sub.link = o.sub2 ;
o.sub2.link = o.sub ;
c = tree.clone( o , true ) ;
expect( c.loop ).to.be( c ) ;
expect( c.sub ).to.be( c.subcopy ) ;
expect( c.sub.loop ).to.be( c ) ;
expect( c.subcopy.loop ).to.be( c ) ;
expect( c.sub.link ).to.be( c.sub2 ) ;
expect( c.sub2.link ).to.be( c.sub ) ;
```
cloning an array.
```js
var a , c ;
a = [ 'one' , 'two' , 'three' ] ;
c = tree.clone( a ) ;
expect( c ).to.eql( a ) ;
expect( Array.isArray( c ) ).to.be.ok() ;
a = [ 'one' , [ 'two' , 'three' ] ] ;
c = tree.clone( a ) ;
expect( c ).to.eql( a ) ;
expect( Array.isArray( c ) ).to.be.ok() ;
expect( Array.isArray( c[ 1 ] ) ).to.be.ok() ;
```
<a name="diff"></a>
# Diff
should return an array of differences for two objects without nested object.
```js
var a = {
a: 'a',
b: 2,
c: 'three'
} ;
var b = {
b: 2,
c: 3,
d: 'dee'
} ;
var diff = tree.diff( a , b ) ;
//console.log( JSON.stringify( diff , null , ' ' ) ) ;
expect( diff ).not.to.be( null ) ;
expect( diff ).to.only.have.keys( '.a', '.c', '.d' ) ;
```
should return an array of differences for two objects with nested objects.
```js
var a = {
a: 'a',
b: 2,
c: 'three',
sub: {
e: 5,
f: 'six',
subsub: {
g: 'gee',
h: 'h'
}
},
suba: {
j: 'djay'
}
} ;
var b = {
b: 2,
c: 3,
d: 'dee',
sub: {
e: 5,
f: 6,
subsub: {
g: 'gee',
i: 'I'
}
},
subb: {
k: 'k'
}
} ;
var diff = tree.diff( a , b ) ;
//console.log( JSON.stringify( diff , null , ' ' ) ) ;
expect( diff ).not.to.be( null ) ;
expect( diff ).to.only.have.keys( '.a', '.c', '.d', '.sub.f', '.sub.subsub.h', '.sub.subsub.i', '.suba', '.subb' ) ;
```
<a name="extend"></a>
# extend()
should extend correctly an empty Object with a flat Object without depth (with or without the 'deep' option).
```js
var copy ;
var expected = {
d : 4 ,
e : undefined ,
f : 3.14 ,
g : 6 ,
h : [] ,
i : 'iii'
} ;
copy = extend( { deep: true } , {} , input.subtree.subtree ) ;
expect( extend( null , copy , input.subtree.subtree2 ) ).to.eql( expected ) ;
copy = extend( { deep: true } , {} , input.subtree.subtree ) ;
expect( extend( { deep: true } , copy , input.subtree.subtree2 ) ).to.eql( expected ) ;
```
should extend an empty Object with a deep Object performing a SHALLOW copy, the result should be equal to the deep Object, nested object MUST be equal AND identical.
```js
var copy = extend( null , {} , input.subtree ) ;
expect( copy ).to.eql( input.subtree ) ;
expect( copy ).not.to.equal( input.subtree ) ;
expect( copy.subtree2 ).to.equal( input.subtree.subtree2 ) ;
```
with the 'deep' option should extend an empty Object with a deep Object performing a DEEP copy, the result should be equal to the deep Object, nested object MUST be equal BUT NOT identical.
```js
var copy = extend( { deep: true } , {} , input.subtree ) ;
expect( copy ).to.eql( input.subtree ) ;
expect( copy ).not.to.equal( input.subtree ) ;
expect( copy.subtree2 ).not.to.equal( input.subtree.subtree2 ) ;
```
with the 'deep' option, sources functions are still simply copied/referenced into target.
```js
var copy = extend( { deep: true } , {} , input.subtreeWithFunction ) ;
//console.log( copy ) ;
expect( copy ).to.eql( input.subtreeWithFunction ) ;
expect( copy ).not.to.equal( input.subtreeWithFunction ) ;
expect( copy.Func.prototype ).to.equal( input.subtreeWithFunction.Func.prototype ) ;
```
with the 'deep' & 'deepFunc' options, sources functions are treated like regular objects, creating an object rather than a function in the target location, and performing a deep copy of them.
```js
var copy = extend( { deep: true, deepFunc: true } , {} , input.subtreeWithFunction ) ;
expect( copy ).not.to.eql( input.subtreeWithFunction ) ;
expect( copy ).to.eql( { z: 'Zee' , Func: { prop: 'property' } } ) ;
```
should extend (by default) properties of the prototype chain.
```js
var proto = {
proto1: 'proto1' ,
proto2: 'proto2' ,
} ;
var o = Object.create( proto ) ;
o.own1 = 'own1' ;
o.own2 = 'own2' ;
expect( extend( null , {} , o ) ).to.eql( {
proto1: 'proto1' ,
proto2: 'proto2' ,
own1: 'own1' ,
own2: 'own2'
} ) ;
expect( extend( { deep: true } , {} , o ) ).to.eql( {
proto1: 'proto1' ,
proto2: 'proto2' ,
own1: 'own1' ,
own2: 'own2'
} ) ;
```
with the 'own' option, it should ONLY extend OWNED properties, non-enumerable properties and properties of the prototype chain are SKIPPED.
```js
var proto = {
proto1: 'proto1' ,
proto2: 'proto2' ,
} ;
var o = Object.create( proto ) ;
o.own1 = 'own1' ;
o.own2 = 'own2' ;
Object.defineProperties( o , {
nonEnum1: { value: 'nonEnum1' } ,
nonEnum2: { value: 'nonEnum2' }
} ) ;
expect( extend( { own: true } , {} , o ) ).to.eql( {
own1: 'own1' ,
own2: 'own2'
} ) ;
expect( extend( { deep: true, own: true } , {} , o ) ).to.eql( {
own1: 'own1' ,
own2: 'own2'
} ) ;
```
with the 'own' & 'nonEnum' option, it should ONLY extend OWNED properties, enumerable or not, but properties of the prototype chain are SKIPPED.
```js
var proto = {
proto1: 'proto1' ,
proto2: 'proto2' ,
} ;
var o = Object.create( proto ) ;
o.own1 = 'own1' ;
o.own2 = 'own2' ;
Object.defineProperties( o , {
nonEnum1: { value: 'nonEnum1' } ,
nonEnum2: { value: 'nonEnum2' }
} ) ;
expect( extend( { own: true , nonEnum: true } , {} , o ) ).to.eql( {
own1: 'own1' ,
own2: 'own2' ,
nonEnum1: 'nonEnum1' ,
nonEnum2: 'nonEnum2'
} ) ;
expect( extend( { deep: true, own: true , nonEnum: true } , {} , o ) ).to.eql( {
own1: 'own1' ,
own2: 'own2' ,
nonEnum1: 'nonEnum1' ,
nonEnum2: 'nonEnum2'
} ) ;
```
with the 'descriptor' option, it should preserve descriptor as well.
```js
var r ;
var proto = {
proto1: 'proto1' ,
proto2: 'proto2' ,
} ;
var o = Object.create( proto ) ;
o.own1 = 'own1' ;
o.own2 = 'own2' ;
o.nested = { a: 1 , b: 2 } ;
var getter = function() { return 5 ; } ;
var setter = function( value ) {} ;
Object.defineProperties( o , {
nonEnum1: { value: 'nonEnum1' } ,
nonEnum2: { value: 'nonEnum2' , writable: true } ,
nonEnum3: { value: 'nonEnum3' , configurable: true } ,
nonEnumNested: { value: { c: 3 , d: 4 } } ,
getter: { get: getter } ,
getterAndSetter: { get: getter , set: setter }
} ) ;
r = extend( { own: true , nonEnum: true , descriptor: true } , {} , o ) ;
expect( Object.getOwnPropertyNames( r ) ).to.eql( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.eql( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.eql( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( r.nested ).to.be( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.eql( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.eql( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.eql( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.eql( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nonEnumNested ).to.be( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.eql( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.eql( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.eql( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
r = extend( { deep: true , own: true , nonEnum: true , descriptor: true } , {} , o ) ;
expect( Object.getOwnPropertyNames( r ) ).to.eql( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.eql( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.eql( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( r.nested ).not.to.be( o.nested ) ;
expect( r.nested ).to.eql( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.eql( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.eql( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.eql( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.eql( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nonEnumNested ).not.to.be( o.nonEnumNested ) ;
expect( r.nonEnumNested ).to.eql( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.eql( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.eql( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.eql( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
```
with the 'deep' option should extend a deep Object into another deep Object correctly.
```js
var copy ;
copy = extend( { deep: true } , {} , input.subtree ) ;
expect( extend( null , copy , input.anotherSubtree ) ).to.eql( {
a : 'A' ,
b : 2 ,
subtree: {
l : '1one' ,
m : false ,
n : 'nay'
} ,
c : 'plusplus' ,
subtree2: {
p : true ,
q : [4,5,6] ,
r : '2'
} ,
j : 'Djay' ,
k : 'ok' ,
o : 'mg'
} ) ;
copy = extend( { deep: true } , {} , input.subtree ) ;
expect( extend( { deep: true } , copy , input.anotherSubtree ) ).to.eql( {
a : 'A' ,
b : 2 ,
subtree: {
d : 4 ,
e : undefined ,
f : 3.14 ,
l : '1one' ,
m : false ,
n : 'nay'
} ,
c : 'plusplus' ,
subtree2: {
g : 6 ,
h : [] ,
i : 'iii',
p : true ,
q : [4,5,6] ,
r : '2'
} ,
j : 'Djay' ,
k : 'ok' ,
o : 'mg'
} ) ;
```
with the 'proto' option and a null (or falsy) target, it should create and return a new Object with the prototype of the source Object.
```js
var e , o , proto ;
proto = {
proto1: 'proto1' ,
proto2: 'proto2' ,
hello: function() { console.log( "Hello!" ) ; }
} ;
o = Object.create( proto ) ;
o.own1 = 'own1' ;
o.own2 = 'own2' ;
e = extend( { proto: true } , null , o ) ;
expect( e ).not.to.be( o ) ;
expect( e.__proto__ ).to.equal( proto ) ; // jshint ignore:line
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' } ) ;
expect( e.proto1 ).to.be( 'proto1' ) ;
expect( e.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.hello ).to.equal( 'function' ) ;
```
with the 'proto' option should change the prototype of each target properties for the prototype of the related source properties, if 'deep' is enabled it does so recursively.
```js
var e , o , proto1 , proto2 ;
proto1 = {
proto1: 'proto1' ,
hello: function() { console.log( "Hello!" ) ; }
} ;
proto2 = {
proto2: 'proto2' ,
world: function() { console.log( "World!" ) ; }
} ;
o = {
own1: 'own1' ,
own2: 'own2' ,
embed1: Object.create( proto1 , { a: { value: 'a' , enumerable: true } } ) ,
embed2: Object.create( proto2 , { b: { value: 'b' , enumerable: true } } )
} ;
e = extend( { proto: true } , {} , o ) ;
expect( e ).not.to.be( o ) ;
expect( e ).to.eql( {
own1: 'own1' ,
own2: 'own2' ,
embed1: { a: 'a' } ,
embed2: { b: 'b' }
} ) ;
expect( e.embed1 ).to.be( o.embed1 ) ;
expect( e.embed2 ).to.be( o.embed2 ) ;
expect( e.embed1.proto1 ).to.be( 'proto1' ) ;
expect( e.embed2.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.embed1.hello ).to.equal( 'function' ) ;
expect( typeof e.embed2.world ).to.equal( 'function' ) ;
e = extend( { proto: true, deep: true } , {} , o ) ;
expect( e ).not.to.be( o ) ;
expect( e ).to.eql( {
own1: 'own1' ,
own2: 'own2' ,
embed1: { a: 'a' } ,
embed2: { b: 'b' }
} ) ;
expect( e.embed1 ).not.to.be( o.embed1 ) ;
expect( e.embed2 ).not.to.be( o.embed2 ) ;
expect( e.embed1.proto1 ).to.be( 'proto1' ) ;
expect( e.embed2.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.embed1.hello ).to.equal( 'function' ) ;
expect( typeof e.embed2.world ).to.equal( 'function' ) ;
```
with 'nofunc' option should skip function.
```js
var e , o , proto ;
proto = {
proto1: 'proto1' ,
proto2: 'proto2' ,
hello: function() { console.log( "Hello..." ) ; }
} ;
o = Object.create( proto ) ;
o.own1 = 'own1' ;
o.world = function() { console.log( "world!!!" ) ; } ;
o.own2 = 'own2' ;
// default behaviour
e = extend( { nofunc: true } , null , o ) ;
expect( e ).not.to.be( o ) ;
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' , proto1: 'proto1' , proto2: 'proto2' } ) ;
// with 'own'
e = extend( { nofunc: true , own: true } , null , o ) ;
expect( e ).not.to.be( o ) ;
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' } ) ;
// with 'proto', function exists if there are in the prototype
e = extend( { nofunc: true , proto: true } , null , o ) ;
expect( e ).not.to.be( o ) ;
expect( e.__proto__ ).to.equal( proto ) ; // jshint ignore:line
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' } ) ;
expect( e.proto1 ).to.be( 'proto1' ) ;
expect( e.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.hello ).to.equal( 'function' ) ;
```
with 'preserve' option should not overwrite existing properties in the target.
```js
var e , o ;
e = {
one: '1' ,
two: 2 ,
three: 'THREE'
} ;
o = {
three: 3 ,
four: '4'
} ;
extend( { preserve: true } , e , o ) ;
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , four: '4' } ) ;
expect( o ).to.eql( { three: 3 , four: '4' } ) ;
```
with 'move' option should move source properties to target properties, i.e. delete them form the source.
```js
var e , o ;
e = {
one: '1' ,
two: 2 ,
three: 'THREE'
} ;
o = {
three: 3 ,
four: '4'
} ;
extend( { move: true } , e , o ) ;
expect( e ).to.eql( { one: '1' , two: 2 , three: 3 , four: '4' } ) ;
expect( o ).to.eql( {} ) ;
```
with 'preserve' and 'move' option should not overwrite existing properties in the target, so it should not move/delete them from the source object.
```js
var e , o ;
e = {
one: '1' ,
two: 2 ,
three: 'THREE'
} ;
o = {
three: 3 ,
four: '4'
} ;
extend( { preserve: true , move: true } , e , o ) ;
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , four: '4' } ) ;
expect( o ).to.eql( { three: 3 } ) ;
```
with 'inherit' option should inherit rather than extend: each source property create a new Object or mutate existing Object into the related target property, using itself as the prototype.
```js
var e , o ;
o = {
three: 3 ,
four: '4' ,
subtree: {
five: 'FIVE' ,
six: 6
}
} ;
e = {} ;
extend( { inherit: true } , e , o ) ;
expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( {} ) ;
expect( e.three ).to.be( 3 ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree ).to.equal( o.subtree ) ;
e = {
one: '1' ,
two: 2 ,
three: 'THREE' ,
} ;
extend( { inherit: true } , e , o ) ;
expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree ).to.eql( { five: 'FIVE' , six: 6 } ) ;
e = {
one: '1' ,
two: 2 ,
three: 'THREE' ,
subtree: {
six: 'SIX' ,
seven: 7
}
} ;
extend( { inherit: true } , e , o ) ;
expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , subtree: { six: 'SIX' , seven: 7 } } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree ).to.eql( { six: 'SIX' , seven: 7 } ) ;
expect( e.subtree.five ).to.equal( undefined ) ;
```
with 'inherit' and 'deep' option should inherit recursively.
```js
var e , o ;
o = {
three: 3 ,
four: '4' ,
subtree: {
five: 'FIVE' ,
six: 6
}
} ;
e = {} ;
extend( { inherit: true , deep: true } , e , o ) ;
expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { subtree: {} } ) ;
expect( e.three ).to.be( 3 ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree.__proto__ ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree.five ).to.equal( 'FIVE' ) ;
expect( e.subtree.six ).to.equal( 6 ) ;
e = {
one: '1' ,
two: 2 ,
three: 'THREE' ,
} ;
extend( { inherit: true , deep: true } , e , o ) ;
expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , subtree: {} } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree.__proto__ ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree ).to.eql( {} ) ;
expect( e.subtree.five ).to.equal( 'FIVE' ) ;
expect( e.subtree.six ).to.equal( 6 ) ;
e = {
one: '1' ,
two: 2 ,
three: 'THREE' ,
subtree: {
six: 'SIX' ,
seven: 7
}
} ;
extend( { inherit: true , deep: true } , e , o ) ;
expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , subtree: { six: 'SIX' , seven: 7 } } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree.__proto__ ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree ).to.eql( { six: 'SIX' , seven: 7 } ) ;
expect( e.subtree.five ).to.equal( 'FIVE' ) ;
```
with 'flat' option.
```js
var e , o ;
o = {
three: 3 ,
four: '4' ,
subtree: {
five: 'FIVE' ,
six: 6 ,
subsubtree: {
subsubsubtree: { one: 'ONE' } ,
seven: 'seven'
} ,
emptysubtree: {}
} ,
eight: 8 ,
anothersubtree: {
nine: '9'
}
} ;
e = extend( { flat: true } , {} , o ) ;
expect( e ).to.eql( {
three: 3 ,
four: '4' ,
'subtree.five': 'FIVE' ,
'subtree.six': 6 ,
'subtree.subsubtree.seven': 'seven' ,
'subtree.subsubtree.subsubsubtree.one': 'ONE' ,
eight: 8 ,
'anothersubtree.nine': '9'
} ) ;
e = extend( { flat: '/' } , {} , o ) ;
expect( e ).to.eql( {
three: 3 ,
four: '4' ,
'subtree/five': 'FIVE' ,
'subtree/six': 6 ,
'subtree/subsubtree/seven': 'seven' ,
'subtree/subsubtree/subsubsubtree/one': 'ONE' ,
eight: 8 ,
'anothersubtree/nine': '9'
} ) ;
```
with 'unflat' option.
```js
var e , o ;
o = {
three: 3 ,
four: '4' ,
'subtree.five': 'FIVE' ,
'subtree.six': 6 ,
'subtree.subsubtree.seven': 'seven' ,
'subtree.subsubtree.subsubsubtree.one': 'ONE' ,
eight: 8 ,
'anothersubtree.nine': '9'
} ;
e = extend( { unflat: true } , {} , o ) ;
expect( e ).to.eql( {
three: 3 ,
four: '4' ,
subtree: {
five: 'FIVE' ,
six: 6 ,
subsubtree: {
subsubsubtree: { one: 'ONE' } ,
seven: 'seven'
}
} ,
eight: 8 ,
anothersubtree: {
nine: '9'
}
} ) ;
o = {
three: 3 ,
four: '4' ,
'subtree/five': 'FIVE' ,
'subtree/six': 6 ,
'subtree/subsubtree/seven': 'seven' ,
'subtree/subsubtree/subsubsubtree/one': 'ONE' ,
eight: 8 ,
'anothersubtree/nine': '9'
} ;
e = extend( { unflat: '/' } , {} , o ) ;
expect( e ).to.eql( {
three: 3 ,
four: '4' ,
subtree: {
five: 'FIVE' ,
six: 6 ,
subsubtree: {
subsubsubtree: { one: 'ONE' } ,
seven: 'seven'
}
} ,
eight: 8 ,
anothersubtree: {
nine: '9'
}
} ) ;
```
with 'deepFilter' option, using blacklist.
```js
var buf = new Buffer( "My buffer" ) ;
var o = {
one: '1' ,
buf: buf ,
subtree: {
two: 2 ,
three: 'THREE'
}
} ;
var e = extend( { deep: true, deepFilter: { blacklist: [ Buffer.prototype ] } } , {} , o ) ;
o.subtree.three = 3 ;
buf[ 0 ] = 'm'.charCodeAt() ;
expect( e.buf ).to.be.a( Buffer ) ;
expect( e.buf.toString() ).to.be( "my buffer" ) ;
expect( e.buf ).to.be( buf ) ;
expect( e ).to.eql( {
one: '1' ,
buf: buf ,
subtree: {
two: 2 ,
three: 'THREE'
}
} ) ;
```
with 'deepFilter' option, using whitelist.
```js
var buf = new Buffer( "My buffer" ) ;
var o = {
one: '1' ,
buf: buf ,
subtree: {
two: 2 ,
three: 'THREE'
}
} ;
var e = extend( { deep: true, deepFilter: { whitelist: [ Object.prototype ] } } , {} , o ) ;
o.subtree.three = 3 ;
buf[ 0 ] = 'm'.charCodeAt() ;
expect( e.buf ).to.be.a( Buffer ) ;
expect( e.buf.toString() ).to.be( "my buffer" ) ;
expect( e.buf ).to.be( buf ) ;
expect( e ).to.eql( {
one: '1' ,
buf: buf ,
subtree: {
two: 2 ,
three: 'THREE'
}
} ) ;
```
circular references test.
```js
var c , o = {
a: 'a',
sub: {
b: 'b'
},
sub2: {
c: 'c'
}
} ;
o.loop = o ;
o.sub.loop = o ;
o.subcopy = o.sub ;
o.sub.link = o.sub2 ;
o.sub2.link = o.sub ;
try {
c = extend( { deep: true } , null , o ) ;
throw new Error( 'Should throw an error: max depth reached' ) ;
}
catch ( error ) {
}
c = extend( { deep: true , circular: true } , null , o ) ;
expect( c.loop ).to.be( c ) ;
expect( c.sub ).to.be( c.subcopy ) ;
expect( c.sub.loop ).to.be( c ) ;
expect( c.subcopy.loop ).to.be( c ) ;
expect( c.sub.link ).to.be( c.sub2 ) ;
expect( c.sub2.link ).to.be( c.sub ) ;
```
<a name="definelazyproperty"></a>
# defineLazyProperty()
should define property using a getter that after its first execution is reconfigured as its return-value and is not writable.
```js
var object = {} ;
var counter = 0 ;
tree.defineLazyProperty( object , 'myprop' , function() {
counter ++ ;
return counter ;
} ) ;
expect( object.myprop ).to.be( 1 ) ;
expect( object.myprop ).to.be( 1 ) ;
expect( object.myprop ).to.be( 1 ) ;
expect( counter ).to.be( 1 ) ;
expect( function() { object.myprop ++ ; } ).to.throwError() ;
expect( object.myprop ).to.be( 1 ) ;
```
<a name="masks"></a>
# Masks
should apply a simple mask tree to the input tree.
```js
var mask = tree.createMask( {
int: true,
float: true,
attachement: {
filename: true,
unexistant: true
},
unexistant: true,
subtree: {
subtree: true
}
} ) ;
var output = mask.applyTo( input ) ;
expect( output ).to.eql( {
int: 12,
float: 2.47,
attachement: {
filename: 'preview.png'
},
subtree: {
subtree: {
d: 4,
e: undefined,
f: 3.14
}
}
} ) ;
```
should apply a mask tree with wildcard '*' to the input tree.
```js
var mask = tree.createMask( {
'files': {
'*': {
size: true,
unexistant: true
}
}
} ) ;
var output = mask.applyTo( input ) ;
expect( output.files ).to.be.an( Object ) ;
expect( output ).to.eql( {
files: {
'background.png' : {
size : '97856'
} ,
'header.png' : {
size : '44193'
} ,
'footer.png' : {
size : '36411'
}
}
} ) ;
```
should apply a mask tree with wildcard '*' to match array in the input tree.
```js
var mask = tree.createMask( {
'filesArray': {
'*': {
name: true,
size: true,
unexistant: true
}
}
} ) ;
var output = mask.applyTo( input ) ;
expect( output.filesArray ).to.be.an( Array ) ;
expect( output ).to.eql( {
filesArray: [
{
name : 'background.png' ,
size : '97856'
} ,
{
name : 'header.png' ,
size : '44193'
} ,
{
name : 'footer.png' ,
size : '36411'
}
]
} ) ;
//console.log( "\n\n\n\n" , output , "\n\n\n\n" ) ;
```
should apply a mask with a mask's leaf callback to the input tree.
```js
var leaf = function leaf( input , key , argument , path ) {
//console.log( 'LEAF: ' , input , key , argument , path ) ;
if ( ! input.hasOwnProperty( key ) ) { return new Error( 'not_found' ) ; }
if ( typeof input[ key ] === 'number' ) { return input[ key ] + argument ; }
return input[ key ] ;
} ;
var mask = tree.createMask(
{
int: 87 ,
float: 14 ,
subtree: {
subtree: {
f: 0.0016
}
} ,
unexistant: 45
} ,
{ leaf: leaf }
) ;
var output = mask.applyTo( input ) ;
expect( output ).to.eql( {
int: 99,
float: 16.47,
subtree: {
subtree: {
f: 3.1416
}
}
} ) ;
```
should apply a mask containing other masks to the input tree.
```js
var mask = tree.createMask( {
int: true,
float: true,
attachement: tree.createMask( {
filename: true,
unexistant: true
} ),
unexistant: true,
subtree: tree.createMask( {
subtree: true
} )
} ) ;
var output = mask.applyTo( input ) ;
expect( output ).to.eql( {
int: 12,
float: 2.47,
attachement: {
filename: 'preview.png'
},
subtree: {
subtree: {
d: 4,
e: undefined,
f: 3.14
}
}
} ) ;
```
<a name="inverse-masks"></a>
# Inverse masks
should apply a simple mask tree to the input tree.
```js
var mask = tree.createInverseMask( {
a: true,
subtree: {
d: true
},
subtree2: true
} ) ;
var output = mask.applyTo( input.subtree ) ;
//console.log( output ) ;
expect( output ).to.eql( {
b: 2,
subtree: {
e: undefined,
f: 3.14
},
c: 'plusplus'
} ) ;
```
<a name="trees-path-on-objects"></a>
# Tree's path on objects
path.get() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
expect( tree.path.get( o , 'a' ) ).to.be( 5 ) ;
expect( tree.path.get( o , 'sub' ) ).to.eql( {
b: "toto" ,
sub: {
c: true
}
} ) ;
expect( tree.path.get( o , 'sub.b' ) ).to.be( "toto" ) ;
expect( tree.path.get( o , 'sub.sub' ) ).to.eql( { c: true } ) ;
expect( tree.path.get( o , 'sub.sub.c' ) ).to.be( true ) ;
expect( tree.path.get( o , 'd' ) ).to.be( null ) ;
expect( tree.path.get( o , 'nothing' ) ).to.be( undefined ) ;
expect( tree.path.get( o , 'sub.nothing' ) ).to.be( undefined ) ;
expect( tree.path.get( o , 'nothing.nothing' ) ).to.be( undefined ) ;
```
path.delete() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true ,
sub: {
f: ''
}
}
} ,
d: null
} ;
tree.path.delete( o , 'a' ) ;
tree.path.delete( o , 'sub.sub' ) ;
tree.path.delete( o , 'non.existant.path' ) ;
expect( o ).to.eql( {
sub: {
b: "toto" ,
} ,
d: null
} ) ;
```
path.set() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
tree.path.set( o , 'a' , "8" ) ;
tree.path.set( o , 'sub.b' , false ) ;
tree.path.set( o , 'sub.sub' , { x: 18 , y: 27 } ) ;
tree.path.set( o , 'non.existant.path' , 'new' ) ;
expect( o ).to.eql( {
a: "8" ,
sub: {
b: false ,
sub: {
x: 18 ,
y: 27
}
} ,
d: null ,
non: {
existant: {
path: 'new'
}
}
} ) ;
```
path.define() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
tree.path.define( o , 'a' , "8" ) ;
tree.path.define( o , 'sub.b' , false ) ;
tree.path.define( o , 'unexistant' , '!' ) ;
tree.path.define( o , 'sub.sub' , { x: 18 , y: 27 } ) ;
tree.path.define( o , 'non.existant.path' , 'new' ) ;
expect( o ).to.eql( {
a: 5 ,
unexistant: '!' ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null ,
non: {
existant: {
path: 'new'
}
}
} ) ;
```
path.inc() and path.dec() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: 10 ,
sub: {
c: true
}
} ,
d: null
} ;
tree.path.inc( o , 'a' ) ;
tree.path.dec( o , 'sub.b' ) ;
tree.path.inc( o , 'sub' ) ;
tree.path.dec( o , 'sub.sub' ) ;
tree.path.inc( o , 'non.existant.path' ) ;
tree.path.dec( o , 'another.non.existant.path' ) ;
expect( o ).to.eql( {
a: 6 ,
sub: {
b: 9 ,
sub: {
c: true
}
} ,
d: null ,
non: {
existant: {
path: 1
}
} ,
another: {
non: {
existant: {
path: -1
}
}
}
} ) ;
```
path.append() and path.prepend() on object structure.
```js
var o = {
a: null ,
sub: {
b: [ 'some' ] ,
sub: {
c: [ 'value' ]
}
} ,
} ;
tree.path.append( o , 'a' , 'hello' ) ;
tree.path.append( o , 'sub.b' , 'value' ) ;
tree.path.prepend( o , 'sub.sub.c' , 'other' ) ;
tree.path.prepend( o , 'sub.sub.c' , 'some' ) ;
tree.path.append( o , 'sub.sub.c' , '!' ) ;
tree.path.append( o , 'non.existant.path' , '!' ) ;
tree.path.prepend( o , 'another.non.existant.path' , '!' ) ;
expect( o ).to.eql( {
a: [ 'hello' ] ,
sub: {
b: [ 'some' , 'value' ] ,
sub: {
c: [ 'some' , 'other' , 'value' , '!' ]
}
} ,
non: {
existant: {
path: [ '!' ]
}
} ,
another: {
non: {
existant: {
path: [ '!' ]
}
}
}
} ) ;
```
path.concat() and path.insert() on object structure.
```js
var o = {
a: null ,
sub: {
b: [ 'hi' ] ,
sub: {
c: [ 'again' ]
}
} ,
} ;
tree.path.concat( o , 'a' , [ 'hello' , 'world' ] ) ;
tree.path.concat( o , 'sub.b' , [ 'hello' , 'world' ] ) ;
tree.path.insert( o , 'sub.sub.c' , [ 'hello' , 'world' ] ) ;
expect( o ).to.eql( {
a: [ 'hello' , 'world' ] ,
sub: {
b: [ 'hi' , 'hello' , 'world' ] ,
sub: {
c: [ 'hello' , 'world' , 'again' ]
}
}
} ) ;
```
path.autoPush().
```js
var o = {
a: 1 ,
sub: {
b: [ 'some' ] ,
sub: {
c: [ 'some' , 'other' , 'value' ]
}
} ,
} ;
tree.path.autoPush( o , 'a' , 'hello' ) ;
tree.path.autoPush( o , 'd' , 'D' ) ;
tree.path.autoPush( o , 'sub.b' , 'value' ) ;
tree.path.autoPush( o , 'sub.sub.c' , '!' ) ;
tree.path.autoPush( o , 'non.existant.path' , '!' ) ;
expect( o ).to.eql( {
a: [ 1 , 'hello' ] ,
d: 'D' ,
sub: {
b: [ 'some' , 'value' ] ,
sub: {
c: [ 'some' , 'other' , 'value' , '!' ]
}
} ,
non: {
existant: {
path: '!'
}
}
} ) ;
```
empty keys.
```js
var o ;
o = {
a: 5 ,
"": {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
expect( tree.path.get( o , 'a' ) ).to.be( 5 ) ;
expect( tree.path.get( o , '' ) ).to.eql( { b: "toto" , sub: { c: true } } ) ;
expect( tree.path.get( o , '.b' ) ).to.be( "toto" ) ;
expect( tree.path.get( o , '.sub' ) ).to.eql( { c: true } ) ;
expect( tree.path.get( o , '.sub.c' ) ).to.be( true ) ;
o = {
"": {
"": {
"": {
a: 1 ,
b: 2
}
}
} ,
} ;
expect( tree.path.get( o , '' ) ).to.eql( { "": { "": { a: 1 , b: 2 } } } ) ;
expect( tree.path.get( o , '.' ) ).to.eql( { "": { a: 1 , b: 2 } } ) ;
expect( tree.path.get( o , '..' ) ).to.eql( { a: 1 , b: 2 } ) ;
expect( tree.path.get( o , '...a' ) ).to.eql( 1 ) ;
```
<a name="trees-path-on-arrays"></a>
# Tree's path on arrays
path.get() on a simple array.
```js
var a = [ 'a' , 'b' , 'c' ] ;
expect( tree.path.get( a , '0' ) ).to.be( 'a' ) ;
expect( tree.path.get( a , '1' ) ).to.be( 'b' ) ;
expect( tree.path.get( a , '2' ) ).to.be( 'c' ) ;
expect( tree.path.get( a , '3' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '#0' ) ).to.be( 'a' ) ;
expect( tree.path.get( a , '#1' ) ).to.be( 'b' ) ;
expect( tree.path.get( a , '#2' ) ).to.be( 'c' ) ;
expect( tree.path.get( a , '#3' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '[0]' ) ).to.be( 'a' ) ;
expect( tree.path.get( a , '[1]' ) ).to.be( 'b' ) ;
expect( tree.path.get( a , '[2]' ) ).to.be( 'c' ) ;
expect( tree.path.get( a , '[3]' ) ).to.be( undefined ) ;
expect( tree.path.get( a , 'length' ) ).to.be( 3 ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 3 ) ;
expect( tree.path.get( a , 'first' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '#first' ) ).to.be( 'a' ) ;
expect( tree.path.get( a , 'last' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '#last' ) ).to.be( 'c' ) ;
expect( tree.path.get( a , 'next' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '#next' ) ).to.be( undefined ) ;
```
path.get() on nested arrays.
```js
var a = [ 'a' , [ [ 'b' , 'c' ] , 'd' , [ 'e' , 'f' ] ] ] ;
expect( tree.path.get( a , '#0' ) ).to.be( 'a' ) ;
expect( tree.path.get( a , '#1' ) ).to.eql( [ [ 'b' , 'c' ] , 'd' , [ 'e' , 'f' ] ] ) ;
expect( tree.path.get( a , '#2' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '[0]' ) ).to.be( 'a' ) ;
expect( tree.path.get( a , '[1]' ) ).to.eql( [ [ 'b' , 'c' ] , 'd' , [ 'e' , 'f' ] ] ) ;
expect( tree.path.get( a , '[2]' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 2 ) ;
expect( tree.path.get( a , '#first' ) ).to.be( 'a' ) ;
expect( tree.path.get( a , '#last' ) ).to.eql( [ [ 'b' , 'c' ] , 'd' , [ 'e' , 'f' ] ] ) ;
expect( tree.path.get( a , '#next' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '1#0' ) ).to.eql( [ 'b' , 'c' ] ) ;
expect( tree.path.get( a , '1#1' ) ).to.eql( 'd' ) ;
expect( tree.path.get( a , '1#2' ) ).to.eql( [ 'e' , 'f' ] ) ;
expect( tree.path.get( a , '1#3' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '[1][0]' ) ).to.eql( [ 'b' , 'c' ] ) ;
expect( tree.path.get( a , '[1][1]' ) ).to.eql( 'd' ) ;
expect( tree.path.get( a , '[1][2]' ) ).to.eql( [ 'e' , 'f' ] ) ;
expect( tree.path.get( a , '[1][3]' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '1#length' ) ).to.be( 3 ) ;
expect( tree.path.get( a , '1#first' ) ).to.eql( [ 'b' , 'c' ] ) ;
expect( tree.path.get( a , '1#last' ) ).to.eql( [ 'e' , 'f' ] ) ;
expect( tree.path.get( a , '1#next' ) ).to.be( undefined ) ;
expect( tree.path.get( a , '1#2#last' ) ).to.eql( 'f' ) ;
```
path.set() on a simple array.
```js
var a ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.set( a , '1' , 'B' ) ;
tree.path.set( a , '#last' , 3 ) ;
tree.path.set( a , '#next' , 'D' ) ;
tree.path.set( a , '#first' , 1 ) ;
expect( a ).to.eql( [ 1 , 'B' , 3 , 'D' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 4 ) ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.set( a , '[1]' , 'BBB' ) ;
tree.path.set( a , '#last' , 3 ) ;
tree.path.set( a , '#next' , 'D' ) ;
tree.path.set( a , '#first' , 1 ) ;
expect( a ).to.eql( [ 1 , 'BBB' , 3 , 'D' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 4 ) ;
```
path.set() using multiple #next and #insert.
```js
var a = [ 'a' , 'b' , 'c' ] ;
tree.path.set( a , '#next' , 'D' ) ;
tree.path.set( a , '#next.f#next' , 'g' ) ;
tree.path.set( a , '#next#next#next' , 'E' ) ;
tree.path.set( a , '#insert' , '@' ) ;
tree.path.set( a , '#last#insert' , '@' ) ;
expect( a ).to.eql( [ '@' , 'a' , 'b' , 'c' , 'D' , { f: [ 'g' ] } , [ '@' , [ 'E' ] ] ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 7 ) ;
```
path.delete() on a simple array.
```js
var a ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.delete( a , '1' ) ;
//expect( a ).to.eql( [ 'a' , undefined , 'c' ] ) ; // expect() bug here...
expect( tree.path.get( a , '#length' ) ).to.be( 3 ) ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.delete( a , '#1' ) ;
expect( a ).to.eql( [ 'a' , 'c' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 2 ) ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.delete( a , '[1]' ) ;
expect( a ).to.eql( [ 'a' , 'c' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 2 ) ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.delete( a , '#2' ) ;
expect( a ).to.eql( [ 'a' , 'b' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 2 ) ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.delete( a , '[2]' ) ;
expect( a ).to.eql( [ 'a' , 'b' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 2 ) ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.delete( a , '#last' ) ;
expect( a ).to.eql( [ 'a' , 'b' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 2 ) ;
tree.path.delete( a , '#last' ) ;
expect( a ).to.eql( [ 'a' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 1 ) ;
tree.path.delete( a , '#last' ) ;
expect( a ).to.eql( [] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 0 ) ;
a = [ 'a' , 'b' , 'c' ] ;
tree.path.delete( a , '#first' ) ;
expect( a ).to.eql( [ 'b' , 'c' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 2 ) ;
tree.path.delete( a , '#first' ) ;
expect( a ).to.eql( [ 'c' ] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 1 ) ;
tree.path.delete( a , '#first' ) ;
expect( a ).to.eql( [] ) ;
expect( tree.path.get( a , '#length' ) ).to.be( 0 ) ;
```
<a name="trees-path-on-mixed-object-and-arrays"></a>
# Tree's path on mixed object and arrays
path.get() on a simple array.
```js
var a = {
method: 'get' ,
populate: [ 'parents', 'godfather' ]
} ;
expect( tree.path.get( a , 'method' ) ).to.be( 'get' ) ;
expect( tree.path.get( a , 'populate' ) ).to.eql( [ 'parents', 'godfather' ] ) ;
expect( tree.path.get( a , 'populate[0]' ) ).to.be( 'parents' ) ;
expect( tree.path.get( a , 'populate[1]' ) ).to.be( 'godfather' ) ;
expect( tree.path.get( a , 'populate[2]' ) ).to.be( undefined ) ;
```
path.set() on a simple array.
```js
var a = {
method: 'get' ,
populate: [ 'parent', 'godfather' ]
} ;
tree.path.set( a , 'method' , 'post' ) ;
tree.path.set( a , 'populate[0]' , 'friends' ) ;
expect( a ).to.eql( {
method: 'post' ,
populate: [ 'friends', 'godfather' ]
} ) ;
```
<a name="inheritance-using-objectcreate-treepathprototype-"></a>
# Inheritance, using Object.create( tree.path.prototype )
.get().
```js
var o = Object.create( tree.path.prototype ) ;
o.a = 5 ;
o.sub = {
b: "toto" ,
sub: {
c: true
}
} ;
o.d = null ;
expect( o.get( 'a' ) ).to.be( 5 ) ;
expect( o.get( 'sub' ) ).to.eql( {
b: "toto" ,
sub: {
c: true
}
} ) ;
expect( o.get( 'sub.b' ) ).to.be( "toto" ) ;
expect( o.get( 'sub.sub' ) ).to.eql( { c: true } ) ;
expect( o.get( 'sub.sub.c' ) ).to.be( true ) ;
expect( o.get( 'd' ) ).to.be( null ) ;
expect( o.get( 'nothing' ) ).to.be( undefined ) ;
expect( o.get( 'sub.nothing' ) ).to.be( undefined ) ;
expect( o.get( 'nothing.nothing' ) ).to.be( undefined ) ;
```
.delete().
```js
var o = Object.create( tree.path.prototype ) ;
o.a = 5 ;
o.sub = {
b: "toto" ,
sub: {
c: true ,
sub: {
f: ''
}
}
} ;
o.d = null ;
o.delete( 'a' ) ;
o.delete( 'sub.sub' ) ;
o.delete( 'non.existant.path' ) ;
expect( o ).to.eql( {
sub: {
b: "toto" ,
} ,
d: null
} ) ;
```
.set().
```js
var o = Object.create( tree.path.prototype ) ;
o.a = 5 ;
o.sub = {
b: "toto" ,
sub: {
c: true
}
} ;
o.d = null ;
o.set( 'a' , "8" ) ;
o.set( 'sub.b' , false ) ;
o.set( 'sub.sub' , { x: 18 , y: 27 } ) ;
o.set( 'non.existant.path' , 'new' ) ;
expect( o ).to.eql( {
a: "8" ,
sub: {
b: false ,
sub: {
x: 18 ,
y: 27
}
} ,
d: null ,
non: {
existant: {
path: 'new'
}
}
} ) ;
```
.define().
```js
var o = Object.create( tree.path.prototype ) ;
o.a = 5 ;
o.sub = {
b: "toto" ,
sub: {
c: true
}
} ;
o.d = null ;
o.define( 'a' , "8" ) ;
o.define( 'sub.b' , false ) ;
o.define( 'unexistant' , '!' ) ;
o.define( 'sub.sub' , { x: 18 , y: 27 } ) ;
o.define( 'non.existant.path' , 'new' ) ;
expect( o ).to.eql( {
a: 5 ,
unexistant: '!' ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null ,
non: {
existant: {
path: 'new'
}
}
} ) ;
```
.inc() and .dec().
```js
var o = Object.create( tree.path.prototype ) ;
o.a = 5 ;
o.sub = {
b: 10 ,
sub: {
c: true
}
} ;
o.d = null ;
o.inc( 'a' ) ;
o.dec( 'sub.b' ) ;
o.inc( 'sub' ) ;
o.dec( 'sub.sub' ) ;
o.inc( 'non.existant.path' ) ;
o.dec( 'another.non.existant.path' ) ;
expect( o ).to.eql( {
a: 6 ,
sub: {
b: 9 ,
sub: {
c: true
}
} ,
d: null ,
non: {
existant: {
path: 1
}
} ,
another: {
non: {
existant: {
path: -1
}
}
}
} ) ;
```
<a name="trees-array-path-on-objects"></a>
# Tree's array path on objects
path.get() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
expect( tree.path.get( o , [ 'a' ] ) ).to.be( 5 ) ;
expect( tree.path.get( o , [ 'sub' ] ) ).to.eql( {
b: "toto" ,
sub: {
c: true
}
} ) ;
expect( tree.path.get( o , [ 'sub' , 'b' ] ) ).to.be( "toto" ) ;
expect( tree.path.get( o , [ 'sub' , 'sub' ] ) ).to.eql( { c: true } ) ;
expect( tree.path.get( o , [ 'sub' , 'sub' , 'c' ] ) ).to.be( true ) ;
expect( tree.path.get( o , [ 'd' ] ) ).to.be( null ) ;
expect( tree.path.get( o , [ 'nothing' ] ) ).to.be( undefined ) ;
expect( tree.path.get( o , [ 'sub' , 'nothing' ] ) ).to.be( undefined ) ;
expect( tree.path.get( o , [ 'nothing' , 'nothing' ] ) ).to.be( undefined ) ;
```
path.delete() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true ,
sub: {
f: ''
}
}
} ,
d: null
} ;
tree.path.delete( o , [ 'a' ] ) ;
tree.path.delete( o , [ 'sub' , 'sub' ] ) ;
tree.path.delete( o , [ 'non' , 'existant' , 'path' ] ) ;
expect( o ).to.eql( {
sub: {
b: "toto" ,
} ,
d: null
} ) ;
```
path.set() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
tree.path.set( o , [ 'a' ] , "8" ) ;
tree.path.set( o , [ 'sub' , 'b' ] , false ) ;
tree.path.set( o , [ 'sub' , 'sub' ] , { x: 18 , y: 27 } ) ;
tree.path.set( o , [ 'non' , 'existant' , 'path' ] , 'new' ) ;
expect( o ).to.eql( {
a: "8" ,
sub: {
b: false ,
sub: {
x: 18 ,
y: 27
}
} ,
d: null ,
non: {
existant: {
path: 'new'
}
}
} ) ;
```
path.define() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
tree.path.define( o , [ 'a' ] , "8" ) ;
tree.path.define( o , [ 'sub' , 'b' ] , false ) ;
tree.path.define( o , [ 'unexistant' ] , '!' ) ;
tree.path.define( o , [ 'sub' , 'sub' ] , { x: 18 , y: 27 } ) ;
tree.path.define( o , [ 'non' , 'existant' , 'path' ] , 'new' ) ;
expect( o ).to.eql( {
a: 5 ,
unexistant: '!' ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null ,
non: {
existant: {
path: 'new'
}
}
} ) ;
```
path.inc() and path.dec() on object structure.
```js
var o = {
a: 5 ,
sub: {
b: 10 ,
sub: {
c: true
}
} ,
d: null
} ;
tree.path.inc( o , [ 'a' ] ) ;
tree.path.dec( o , [ 'sub' , 'b' ] ) ;
tree.path.inc( o , [ 'sub' ] ) ;
tree.path.dec( o , [ 'sub' , 'sub' ] ) ;
tree.path.inc( o , [ 'non' , 'existant' , 'path' ] ) ;
tree.path.dec( o , [ 'another' , 'non' , 'existant' , 'path' ] ) ;
expect( o ).to.eql( {
a: 6 ,
sub: {
b: 9 ,
sub: {
c: true
}
} ,
d: null ,
non: {
existant: {
path: 1
}
} ,
another: {
non: {
existant: {
path: -1
}
}
}
} ) ;
```

@@ -0,3 +1,26 @@

/*
Tree Kit
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var i2 = 0 , d = 0 , o = {} ;

@@ -4,0 +27,0 @@ module.exports = o ;

@@ -0,3 +1,26 @@

/*
Tree Kit
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var i , j , l , k , v , o = {} ;

@@ -4,0 +27,0 @@ module.exports = o ;

@@ -0,3 +1,26 @@

/*
Tree Kit
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var i , j , l , k , v , o = {} ;

@@ -4,0 +27,0 @@ module.exports = o ;

@@ -0,3 +1,26 @@

/*
Tree Kit
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var i , j , l , k , v , o = {} ;

@@ -4,0 +27,0 @@ module.exports = o ;

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -28,5 +28,2 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

/* jshint unused:false */
/* global describe, it, before, after */
"use strict" ;

@@ -37,3 +34,2 @@

var tree = require( '../lib/tree.js' ) ;
var expect = require( 'expect.js' ) ;

@@ -85,16 +81,16 @@

expect( Object.getOwnPropertyNames( r ) ).to.eql( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.eql( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.eql( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyNames( r ) ).to.equal( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.equal( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.equal( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( r.nested ).not.to.be( o.nested ) ;
expect( r.nested ).to.eql( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.eql( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.eql( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.eql( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.eql( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nested ).to.equal( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.equal( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.equal( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.equal( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.equal( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nonEnumNested ).not.to.be( o.nonEnumNested ) ;
expect( r.nonEnumNested ).to.eql( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.eql( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.eql( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.eql( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
expect( r.nonEnumNested ).to.equal( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.equal( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.equal( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.equal( { get: getter , set: setter , enumerable: false , configurable: false } ) ;

@@ -143,3 +139,3 @@ expect( r.__proto__ ).to.equal( proto ) ; // jshint ignore:line

c = tree.clone( a ) ;
expect( c ).to.eql( a ) ;
expect( c ).to.equal( a ) ;
expect( Array.isArray( c ) ).to.be.ok() ;

@@ -149,3 +145,3 @@

c = tree.clone( a ) ;
expect( c ).to.eql( a ) ;
expect( c ).to.equal( a ) ;
expect( Array.isArray( c ) ).to.be.ok() ;

@@ -152,0 +148,0 @@ expect( Array.isArray( c[ 1 ] ) ).to.be.ok() ;

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -28,5 +28,2 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

/* jshint unused:false */
/* global describe, it, before, after */
"use strict" ;

@@ -37,3 +34,2 @@

var tree = require( '../lib/tree.js' ) ;
var expect = require( 'expect.js' ) ;

@@ -67,3 +63,3 @@

expect( diff ).not.to.be( null ) ;
expect( diff ).to.only.have.keys( '.a', '.c', '.d' ) ;
expect( diff ).to.only.have.own.keys( '.a', '.c', '.d' ) ;
} ) ;

@@ -110,3 +106,3 @@

expect( diff ).not.to.be( null ) ;
expect( diff ).to.only.have.keys( '.a', '.c', '.d', '.sub.f', '.sub.subsub.h', '.sub.subsub.i', '.suba', '.subb' ) ;
expect( diff ).to.only.have.own.keys( '.a', '.c', '.d', '.sub.f', '.sub.subsub.h', '.sub.subsub.i', '.suba', '.subb' ) ;
} ) ;

@@ -113,0 +109,0 @@ } ) ;

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -28,5 +28,2 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

/* jshint unused:false */
/* global describe, it, before, after */
"use strict" ;

@@ -37,3 +34,2 @@

var extend = require( '../lib/extend.js' ) ;
var expect = require( 'expect.js' ) ;

@@ -175,5 +171,4 @@

var copy = extend( null , {} , input.subtree ) ;
expect( copy ).to.eql( input.subtree ) ;
expect( copy ).not.to.equal( input.subtree ) ;
expect( copy.subtree2 ).to.equal( input.subtree.subtree2 ) ;
expect( copy ).to.be.a.shallow.clone.of( input.subtree ) ;
expect( copy ).to.equal( input.subtree ) ;
} ) ;

@@ -183,5 +178,5 @@

var copy = extend( { deep: true } , {} , input.subtree ) ;
expect( copy ).to.eql( input.subtree ) ;
expect( copy ).not.to.equal( input.subtree ) ;
expect( copy.subtree2 ).not.to.equal( input.subtree.subtree2 ) ;
expect( copy ).to.equal( input.subtree ) ;
expect( copy ).not.to.be.a.shallow.clone.of( input.subtree ) ;
expect( copy.subtree2 ).not.to.be.a.shallow.clone.of( input.subtree.subtree2 ) ;
} ) ;

@@ -192,5 +187,4 @@

//console.log( copy ) ;
expect( copy ).to.eql( input.subtreeWithFunction ) ;
expect( copy ).not.to.equal( input.subtreeWithFunction ) ;
expect( copy.Func.prototype ).to.equal( input.subtreeWithFunction.Func.prototype ) ;
expect( copy ).to.equal( input.subtreeWithFunction ) ;
expect( copy.Func.prototype ).to.be( input.subtreeWithFunction.Func.prototype ) ;
} ) ;

@@ -200,4 +194,4 @@

var copy = extend( { deep: true, deepFunc: true } , {} , input.subtreeWithFunction ) ;
expect( copy ).not.to.eql( input.subtreeWithFunction ) ;
expect( copy ).to.eql( { z: 'Zee' , Func: { prop: 'property' } } ) ;
expect( copy ).not.to.equal( input.subtreeWithFunction ) ;
expect( copy ).to.equal( { z: 'Zee' , Func: { prop: 'property' } } ) ;
} ) ;

@@ -217,3 +211,3 @@

expect( extend( null , {} , o ) ).to.eql( {
expect( extend( null , {} , o ) ).to.equal( {
proto1: 'proto1' ,

@@ -225,3 +219,3 @@ proto2: 'proto2' ,

expect( extend( { deep: true } , {} , o ) ).to.eql( {
expect( extend( { deep: true } , {} , o ) ).to.equal( {
proto1: 'proto1' ,

@@ -251,3 +245,3 @@ proto2: 'proto2' ,

expect( extend( { own: true } , {} , o ) ).to.eql( {
expect( extend( { own: true } , {} , o ) ).to.equal( {
own1: 'own1' ,

@@ -257,3 +251,3 @@ own2: 'own2'

expect( extend( { deep: true, own: true } , {} , o ) ).to.eql( {
expect( extend( { deep: true, own: true } , {} , o ) ).to.equal( {
own1: 'own1' ,

@@ -281,3 +275,3 @@ own2: 'own2'

expect( extend( { own: true , nonEnum: true } , {} , o ) ).to.eql( {
expect( extend( { own: true , nonEnum: true } , {} , o ) ).to.equal( {
own1: 'own1' ,

@@ -289,3 +283,3 @@ own2: 'own2' ,

expect( extend( { deep: true, own: true , nonEnum: true } , {} , o ) ).to.eql( {
expect( extend( { deep: true, own: true , nonEnum: true } , {} , o ) ).to.equal( {
own1: 'own1' ,

@@ -328,31 +322,31 @@ own2: 'own2' ,

expect( Object.getOwnPropertyNames( r ) ).to.eql( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.eql( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.eql( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyNames( r ) ).to.equal( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.equal( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.equal( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( r.nested ).to.be( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.eql( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.eql( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.eql( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.eql( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.equal( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.equal( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.equal( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.equal( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nonEnumNested ).to.be( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.eql( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.eql( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.eql( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.equal( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.equal( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.equal( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
r = extend( { deep: true , own: true , nonEnum: true , descriptor: true } , {} , o ) ;
expect( Object.getOwnPropertyNames( r ) ).to.eql( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.eql( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.eql( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyNames( r ) ).to.equal( [ 'own1' , 'own2' , 'nested' , 'nonEnum1' , 'nonEnum2' , 'nonEnum3' , 'nonEnumNested' , 'getter' , 'getterAndSetter' ] ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own1' ) ).to.equal( { value: 'own1' , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'own2' ) ).to.equal( { value: 'own2' , enumerable: true , writable: true , configurable: true } ) ;
expect( r.nested ).not.to.be( o.nested ) ;
expect( r.nested ).to.eql( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.eql( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.eql( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.eql( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.eql( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nested ).to.equal( o.nested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nested' ) ).to.equal( { value: o.nested , enumerable: true , writable: true , configurable: true } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum1' ) ).to.equal( { value: 'nonEnum1' , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum2' ) ).to.equal( { value: 'nonEnum2' , enumerable: false , writable: true , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnum3' ) ).to.equal( { value: 'nonEnum3' , enumerable: false , writable: false , configurable: true } ) ;
expect( r.nonEnumNested ).not.to.be( o.nonEnumNested ) ;
expect( r.nonEnumNested ).to.eql( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.eql( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.eql( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.eql( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
expect( r.nonEnumNested ).to.equal( o.nonEnumNested ) ;
expect( Object.getOwnPropertyDescriptor( r , 'nonEnumNested' ) ).to.equal( { value: o.nonEnumNested , enumerable: false , writable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getter' ) ).to.equal( { get: getter , set: undefined , enumerable: false , configurable: false } ) ;
expect( Object.getOwnPropertyDescriptor( r , 'getterAndSetter' ) ).to.equal( { get: getter , set: setter , enumerable: false , configurable: false } ) ;
} ) ;

@@ -365,3 +359,3 @@

copy = extend( { deep: true } , {} , input.subtree ) ;
expect( extend( null , copy , input.anotherSubtree ) ).to.eql( {
expect( extend( null , copy , input.anotherSubtree ) ).to.equal( {
a : 'A' ,

@@ -386,3 +380,3 @@ b : 2 ,

copy = extend( { deep: true } , {} , input.subtree ) ;
expect( extend( { deep: true } , copy , input.anotherSubtree ) ).to.eql( {
expect( extend( { deep: true } , copy , input.anotherSubtree ) ).to.equal( {
a : 'A' ,

@@ -430,7 +424,7 @@ b : 2 ,

expect( e ).not.to.be( o ) ;
expect( e.__proto__ ).to.equal( proto ) ; // jshint ignore:line
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' } ) ;
expect( e.__proto__ ).to.be( proto ) ;
expect( e ).to.be.like( { own1: 'own1' , own2: 'own2' } ) ;
expect( e.proto1 ).to.be( 'proto1' ) ;
expect( e.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.hello ).to.equal( 'function' ) ;
expect( e.hello ).to.be.a( 'function' ) ;
} ) ;

@@ -461,4 +455,4 @@

expect( e ).not.to.be( o ) ;
expect( e ).to.eql( {
expect( e ).to.be.a.shallow.clone.of( o ) ;
expect( e ).to.be.like( {
own1: 'own1' ,

@@ -473,4 +467,4 @@ own2: 'own2' ,

expect( e.embed2.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.embed1.hello ).to.equal( 'function' ) ;
expect( typeof e.embed2.world ).to.equal( 'function' ) ;
expect( e.embed1.hello ).to.be.a( 'function' ) ;
expect( e.embed2.world ).to.be.a( 'function' ) ;

@@ -481,3 +475,3 @@

expect( e ).not.to.be( o ) ;
expect( e ).to.eql( {
expect( e ).to.be.like( {
own1: 'own1' ,

@@ -492,4 +486,4 @@ own2: 'own2' ,

expect( e.embed2.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.embed1.hello ).to.equal( 'function' ) ;
expect( typeof e.embed2.world ).to.equal( 'function' ) ;
expect( e.embed1.hello ).to.be.a( 'function' ) ;
expect( e.embed2.world ).to.be.a( 'function' ) ;
} ) ;

@@ -515,3 +509,3 @@

expect( e ).not.to.be( o ) ;
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' , proto1: 'proto1' , proto2: 'proto2' } ) ;
expect( e ).to.be.like( { own1: 'own1' , own2: 'own2' , proto1: 'proto1' , proto2: 'proto2' } ) ;

@@ -521,3 +515,3 @@ // with 'own'

expect( e ).not.to.be( o ) ;
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' } ) ;
expect( e ).to.be.like( { own1: 'own1' , own2: 'own2' } ) ;

@@ -527,7 +521,7 @@ // with 'proto', function exists if there are in the prototype

expect( e ).not.to.be( o ) ;
expect( e.__proto__ ).to.equal( proto ) ; // jshint ignore:line
expect( e ).to.eql( { own1: 'own1' , own2: 'own2' } ) ;
expect( e.__proto__ ).to.be( proto ) ;
expect( e ).to.be.like( { own1: 'own1' , own2: 'own2' } ) ;
expect( e.proto1 ).to.be( 'proto1' ) ;
expect( e.proto2 ).to.be( 'proto2' ) ;
expect( typeof e.hello ).to.equal( 'function' ) ;
expect( e.hello ).to.be.a( 'function' ) ;
} ) ;

@@ -551,4 +545,4 @@

extend( { preserve: true } , e , o ) ;
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , four: '4' } ) ;
expect( o ).to.eql( { three: 3 , four: '4' } ) ;
expect( e ).to.equal( { one: '1' , two: 2 , three: 'THREE' , four: '4' } ) ;
expect( o ).to.equal( { three: 3 , four: '4' } ) ;
} ) ;

@@ -572,4 +566,4 @@

extend( { move: true } , e , o ) ;
expect( e ).to.eql( { one: '1' , two: 2 , three: 3 , four: '4' } ) ;
expect( o ).to.eql( {} ) ;
expect( e ).to.equal( { one: '1' , two: 2 , three: 3 , four: '4' } ) ;
expect( o ).to.equal( {} ) ;
} ) ;

@@ -593,4 +587,4 @@

extend( { preserve: true , move: true } , e , o ) ;
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , four: '4' } ) ;
expect( o ).to.eql( { three: 3 } ) ;
expect( e ).to.equal( { one: '1' , two: 2 , three: 'THREE' , four: '4' } ) ;
expect( o ).to.equal( { three: 3 } ) ;
} ) ;

@@ -615,7 +609,7 @@

expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( {} ) ;
expect( e.__proto__ ).to.be( o ) ;
expect( e ).to.be.like( {} ) ;
expect( e.three ).to.be( 3 ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree ).to.equal( o.subtree ) ;
expect( e.subtree ).to.be.a.shallow.clone.of( o.subtree ) ;

@@ -631,8 +625,8 @@

expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' } ) ;
expect( e.__proto__ ).to.be( o ) ;
expect( e ).to.be.like( { one: '1' , two: 2 , three: 'THREE' } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree ).to.eql( { five: 'FIVE' , six: 6 } ) ;
expect( e.subtree ).to.be.a.shallow.clone.of( o.subtree ) ;
expect( e.subtree ).to.be.like( { five: 'FIVE' , six: 6 } ) ;

@@ -652,8 +646,8 @@

expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , subtree: { six: 'SIX' , seven: 7 } } ) ;
expect( e.__proto__ ).to.be( o ) ;
expect( e ).to.be.like( { one: '1' , two: 2 , three: 'THREE' , subtree: { six: 'SIX' , seven: 7 } } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree ).to.eql( { six: 'SIX' , seven: 7 } ) ;
expect( e.subtree.five ).to.equal( undefined ) ;
expect( e.subtree ).to.be.like( { six: 'SIX' , seven: 7 } ) ;
expect( e.subtree.five ).to.be( undefined ) ;
} ) ;

@@ -678,9 +672,9 @@

expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { subtree: {} } ) ;
expect( e.__proto__ ).to.be( o ) ;
expect( e ).to.be.like( { subtree: {} } ) ;
expect( e.three ).to.be( 3 ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree.__proto__ ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree.five ).to.equal( 'FIVE' ) ;
expect( e.subtree.six ).to.equal( 6 ) ;
expect( e.subtree.__proto__ ).to.be( o.subtree ) ;
expect( e.subtree.five ).to.be( 'FIVE' ) ;
expect( e.subtree.six ).to.be( 6 ) ;

@@ -696,10 +690,10 @@

expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , subtree: {} } ) ;
expect( e.__proto__ ).to.be( o ) ;
expect( e ).to.be.like( { one: '1' , two: 2 , three: 'THREE' , subtree: {} } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree.__proto__ ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree ).to.eql( {} ) ;
expect( e.subtree.five ).to.equal( 'FIVE' ) ;
expect( e.subtree.six ).to.equal( 6 ) ;
expect( e.subtree.__proto__ ).to.be( o.subtree ) ;
expect( e.subtree ).to.be.like( {} ) ;
expect( e.subtree.five ).to.be( 'FIVE' ) ;
expect( e.subtree.six ).to.be( 6 ) ;

@@ -719,9 +713,9 @@

expect( e.__proto__ ).to.equal( o ) ; // jshint ignore:line
expect( e ).to.eql( { one: '1' , two: 2 , three: 'THREE' , subtree: { six: 'SIX' , seven: 7 } } ) ;
expect( e.__proto__ ).to.be( o ) ;
expect( e ).to.be.like( { one: '1' , two: 2 , three: 'THREE' , subtree: { six: 'SIX' , seven: 7 } } ) ;
expect( e.three ).to.be( 'THREE' ) ;
expect( e.four ).to.be( '4' ) ;
expect( e.subtree.__proto__ ).to.equal( o.subtree ) ; // jshint ignore:line
expect( e.subtree ).to.eql( { six: 'SIX' , seven: 7 } ) ;
expect( e.subtree.five ).to.equal( 'FIVE' ) ;
expect( e.subtree.__proto__ ).to.be( o.subtree ) ;
expect( e.subtree ).to.be.like( { six: 'SIX' , seven: 7 } ) ;
expect( e.subtree.five ).to.be( 'FIVE' ) ;
} ) ;

@@ -752,3 +746,3 @@

e = extend( { flat: true } , {} , o ) ;
expect( e ).to.eql( {
expect( e ).to.equal( {
three: 3 ,

@@ -765,3 +759,3 @@ four: '4' ,

e = extend( { flat: '/' } , {} , o ) ;
expect( e ).to.eql( {
expect( e ).to.equal( {
three: 3 ,

@@ -794,3 +788,3 @@ four: '4' ,

e = extend( { unflat: true } , {} , o ) ;
expect( e ).to.eql( {
expect( e ).to.equal( {
three: 3 ,

@@ -824,3 +818,3 @@ four: '4' ,

e = extend( { unflat: '/' } , {} , o ) ;
expect( e ).to.eql( {
expect( e ).to.equal( {
three: 3 ,

@@ -865,3 +859,3 @@ four: '4' ,

expect( e ).to.eql( {
expect( e ).to.equal( {
one: '1' ,

@@ -899,3 +893,3 @@ buf: buf ,

expect( e ).to.eql( {
expect( e ).to.equal( {
one: '1' ,

@@ -902,0 +896,0 @@ buf: buf ,

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -28,5 +28,2 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

/* jshint unused:false */
/* global describe, it, before, after */
"use strict" ;

@@ -37,3 +34,5 @@

var tree = require( '../lib/tree.js' ) ;
var expect = require( 'expect.js' ) ;
/* Tests */

@@ -59,3 +58,3 @@

expect( counter ).to.be( 1 ) ;
expect( function() { object.myprop ++ ; } ).to.throwError() ;
expect( function() { object.myprop ++ ; } ).to.throw() ;
expect( object.myprop ).to.be( 1 ) ;

@@ -62,0 +61,0 @@ } ) ;

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -28,5 +28,2 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

/* jshint unused:false */
/* global describe, it, before, after */
"use strict" ;

@@ -37,3 +34,2 @@

var tree = require( '../lib/tree.js' ) ;
var expect = require( 'expect.js' ) ;

@@ -40,0 +36,0 @@

/*
Tree Kit
Copyright (c) 2014 - 2016 Cédric Ronvel
Copyright (c) 2014 - 2018 Cédric Ronvel
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -14,6 +14,6 @@ of this software and associated documentation files (the "Software"), to deal

furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

@@ -28,5 +28,2 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

/* jshint unused:false */
/* global describe, it, before, after */
"use strict" ;

@@ -37,3 +34,2 @@

var tree = require( '../lib/tree.js' ) ;
var expect = require( 'expect.js' ) ;

@@ -79,2 +75,21 @@

/*
it( "bracket notation on object" , function() {
var o = {
a: 5 ,
sub: {
b: "toto" ,
sub: {
c: true
}
} ,
d: null
} ;
expect( tree.path.get( o , '[a]' ) ).to.be( 5 ) ;
expect( tree.path.get( o , '[sub][sub][c]' ) ).to.be( true ) ;
} ) ;
*/
it( "path.delete() on object structure" , function() {

@@ -615,3 +630,3 @@

expect( o ).to.eql( {
expect( o ).to.be.like( {
sub: {

@@ -643,3 +658,3 @@ b: "toto" ,

expect( o ).to.eql( {
expect( o ).to.be.like( {
a: "8" ,

@@ -682,3 +697,3 @@ sub: {

expect( o ).to.eql( {
expect( o ).to.be.like( {
a: 5 ,

@@ -721,3 +736,3 @@ unexistant: '!' ,

expect( o ).to.eql( {
expect( o ).to.be.like( {
a: 6 ,

@@ -766,3 +781,3 @@ sub: {

expect( tree.path.get( o , [ 'a' ] ) ).to.be( 5 ) ;
expect( tree.path.get( o , [ 'sub' ] ) ).to.eql( {
expect( tree.path.get( o , [ 'sub' ] ) ).to.be.like( {
b: "toto" ,

@@ -775,3 +790,3 @@ sub: {

expect( tree.path.get( o , [ 'sub' , 'b' ] ) ).to.be( "toto" ) ;
expect( tree.path.get( o , [ 'sub' , 'sub' ] ) ).to.eql( { c: true } ) ;
expect( tree.path.get( o , [ 'sub' , 'sub' ] ) ).to.be.like( { c: true } ) ;
expect( tree.path.get( o , [ 'sub' , 'sub' , 'c' ] ) ).to.be( true ) ;

@@ -804,3 +819,3 @@ expect( tree.path.get( o , [ 'd' ] ) ).to.be( null ) ;

expect( o ).to.eql( {
expect( o ).to.be.like( {
sub: {

@@ -832,3 +847,3 @@ b: "toto" ,

expect( o ).to.eql( {
expect( o ).to.be.like( {
a: "8" ,

@@ -871,3 +886,3 @@ sub: {

expect( o ).to.eql( {
expect( o ).to.be.like( {
a: 5 ,

@@ -910,3 +925,3 @@ unexistant: '!' ,

expect( o ).to.eql( {
expect( o ).to.be.like( {
a: 6 ,

@@ -913,0 +928,0 @@ sub: {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc