core-extensions
Advanced tools
Comparing version 0.2.0 to 0.3.0
345
index.js
"use strict"; | ||
Object.defineProperty( Object.prototype, 'isObject', { | ||
enumerable: false, | ||
value: function ( thing ) { | ||
return typeof thing === 'object' && !Array.isArray( thing ) && thing !== null; | ||
var lastConf = null; | ||
module.exports.init = function ( conf ) { | ||
if ( !conf ) { | ||
conf = {}; | ||
} | ||
} ); | ||
Object.defineProperty( Object.prototype, 'getType', { | ||
enumerable: false, | ||
value: function ( thing ) { | ||
conf = { | ||
isObject: typeof conf.isObject === 'string' ? conf.isObject : 'isObject', | ||
getType: typeof conf.getType === 'string' ? conf.getType : 'getType', | ||
clone: typeof conf.clone === 'string' ? conf.clone : 'clone', | ||
mixin: typeof conf.mixin === 'string' ? conf.mixin : 'mixin' | ||
}; | ||
// support calling on Object root class directly, or off a variable (doesn't work directly off of variable for undefined or null) | ||
if ( arguments.length < 1 ) { | ||
thing = this; | ||
// validate new config | ||
for ( var functionName in conf ) { | ||
if ( conf.hasOwnProperty( functionName ) ) { | ||
var nameSpace = conf[functionName]; | ||
if ( typeof nameSpace !== 'string' || nameSpace.length < 1 || nameSpace.match( /^[^A-Za-z_]/ ) || nameSpace.match( /[^A-Za-z0-9\-_]/ ) ) { | ||
throw new Error( 'Name space ' + (typeof nameSpace) + ' for ' + functionName + ' is invalid, must start with letter or underscore, and must only contain letters, numbers dashes and underscores' ); | ||
} | ||
} | ||
} | ||
// handle exceptions that typeof doesn't handle | ||
if ( thing === null ) { | ||
return 'null'; | ||
} | ||
else if ( Array.isArray( thing ) ) { | ||
return 'array'; | ||
} | ||
// undo previous configs if any | ||
if ( lastConf ) { | ||
var type = typeof thing; | ||
// more resolution on numbers | ||
if ( type === 'number' ) { | ||
if ( Math.ceil( thing ) > Math.floor( thing ) ) { | ||
type = 'float'; | ||
for ( functionName in lastConf ) { | ||
if ( lastConf.hasOwnProperty( functionName ) ) { | ||
if ( Object.prototype.hasOwnProperty( lastConf[functionName] ) ) { | ||
delete Object.prototype[lastConf[functionName]]; | ||
} | ||
} | ||
else { | ||
type = 'integer'; | ||
} | ||
} | ||
return type; | ||
} | ||
} ); | ||
lastConf = conf; | ||
var cloneDepth = 0; | ||
Object.defineProperty( Object.prototype, conf.isObject, { | ||
configurable: true, | ||
enumerable: false, | ||
value: function ( thing ) { | ||
return typeof thing === 'object' && !Array.isArray( thing ) && thing !== null; | ||
} | ||
} ); | ||
Object.defineProperty( Object.prototype, "clone", { | ||
enumerable: false, | ||
value: function () { | ||
Object.defineProperty( Object.prototype, conf.getType, { | ||
configurable: true, | ||
enumerable: false, | ||
value: function ( thing ) { | ||
cloneDepth++; | ||
// support calling on Object root class directly, or off a variable (doesn't work directly off of variable for undefined or null) | ||
if ( arguments.length < 1 ) { | ||
thing = this; | ||
} | ||
if ( cloneDepth >= 100 ) { | ||
cloneDepth = 0; | ||
throw new Error( 'max clone depth of 100 reached' ); | ||
} | ||
// handle exceptions that typeof doesn't handle | ||
if ( thing === null ) { | ||
return 'null'; | ||
} | ||
else if ( Array.isArray( thing ) ) { | ||
return 'array'; | ||
} | ||
var target = null; | ||
var type = typeof thing; | ||
if ( this instanceof Date ) { | ||
target = new Date( this.toISOString() ); | ||
} | ||
else if ( Array.isArray( this ) ) { | ||
target = []; | ||
for ( var i = 0; i < this.length; i++ ) { | ||
if ( Array.isArray( this[i] ) || Object.isObject( this[i] ) ) { | ||
target[i] = this[i].clone(); | ||
// more resolution on numbers | ||
if ( type === 'number' ) { | ||
if ( Math.ceil( thing ) > Math.floor( thing ) ) { | ||
type = 'float'; | ||
} | ||
else { | ||
target[i] = this[i]; | ||
type = 'integer'; | ||
} | ||
} | ||
return type; | ||
} | ||
else if ( Object.isObject( this ) ) { | ||
target = {}; | ||
for ( var field in this ) { | ||
if ( this.hasOwnProperty( field ) ) { | ||
if ( Array.isArray( this[field] ) || Object.isObject( this[field] ) ) { | ||
target[field] = this[field].clone(); | ||
} ); | ||
var cloneDepth = 0; | ||
Object.defineProperty( Object.prototype, conf.clone, { | ||
configurable: true, | ||
enumerable: false, | ||
value: function () { | ||
cloneDepth++; | ||
if ( cloneDepth >= 100 ) { | ||
cloneDepth = 0; | ||
throw new Error( 'max clone depth of 100 reached' ); | ||
} | ||
var target = null; | ||
if ( this instanceof Date ) { | ||
target = new Date( this.toISOString() ); | ||
} | ||
else if ( Array.isArray( this ) ) { | ||
target = []; | ||
for ( var i = 0; i < this.length; i++ ) { | ||
if ( Array.isArray( this[i] ) || Object[conf.isObject]( this[i] ) ) { | ||
target[i] = this[i][conf.clone](); | ||
} | ||
else { | ||
target[field] = this[field]; | ||
target[i] = this[i]; | ||
} | ||
} | ||
} | ||
else if ( Object[conf.isObject]( this ) ) { | ||
target = {}; | ||
for ( var field in this ) { | ||
if ( this.hasOwnProperty( field ) ) { | ||
if ( Array.isArray( this[field] ) || Object[conf.isObject]( this[field] ) ) { | ||
target[field] = this[field][conf.clone](); | ||
} | ||
else { | ||
target[field] = this[field]; | ||
} | ||
} | ||
} | ||
} | ||
else { // functions, etc. not clonable yet, and will pass through, though for primitives like strings and numbers, this is cloning | ||
target = this; | ||
} | ||
cloneDepth--; | ||
return target; | ||
} | ||
else { // functions, etc. not clonable yet, and will pass through, though for primitives like strings and numbers, this is cloning | ||
target = this; | ||
} | ||
} ); | ||
cloneDepth--; | ||
var mixinDepth = 0; | ||
return target; | ||
} | ||
} ); | ||
Object.defineProperty( Object.prototype, conf.mixin, { | ||
configurable: true, | ||
enumerable: false, | ||
value: function () { | ||
var mixinDepth = 0; | ||
mixinDepth++; | ||
Object.defineProperty( Object.prototype, "mixin", { | ||
enumerable: false, | ||
value: function () { | ||
if ( mixinDepth >= 100 ) { | ||
mixinDepth = 0; | ||
throw new Error( 'max mixin depth of 100 reached' ); | ||
} | ||
mixinDepth++; | ||
var target = this[conf.clone](); // clone so we don't modify the original | ||
if ( mixinDepth >= 100 ) { | ||
mixinDepth = 0; | ||
throw new Error( 'max mixin depth of 100 reached' ); | ||
} | ||
// handle arbitrary number of mixins. precedence is from last to first item passed in. | ||
for ( var i = 0; i < arguments.length; i++ ) { | ||
var target = this.clone(); // clone so we don't modify the original | ||
var source = arguments[i]; | ||
// handle arbitrary number of mixins. precedence is from last to first item passed in. | ||
for ( var i = 0; i < arguments.length; i++ ) { | ||
// mixin the source differently depending on what is in the destination | ||
switch ( target[conf.getType]() ) { | ||
var source = arguments[i]; | ||
case 'object': | ||
case 'array': | ||
case 'function': | ||
// mixin the source differently depending on what is in the destination | ||
switch ( target.getType() ) { | ||
// mixin in the source differently depending on its type | ||
switch ( Object[conf.getType]( source ) ) { | ||
case 'object': | ||
case 'array': | ||
case 'function': | ||
case 'array': | ||
case 'object': | ||
case 'function': | ||
// mixin in the source differently depending on its type | ||
switch ( Object.getType( source ) ) { | ||
// we don't care what descendant of object the source is | ||
for ( var field in source ) { | ||
case 'array': | ||
case 'object': | ||
case 'function': | ||
// don't mixin parent fields | ||
if ( source.hasOwnProperty( field ) ) { | ||
// we don't care what descendant of object the source is | ||
for ( var field in source ) { | ||
// if the target is an array, only take fields that are integers | ||
if ( Array.isArray( target ) ) { | ||
// don't mixin parent fields | ||
if ( source.hasOwnProperty( field ) ) { | ||
var fieldFloat = parseFloat( field ); | ||
// if the target is an array, only take fields that are integers | ||
if ( Array.isArray( target ) ) { | ||
// the field started with a number, or no number at all, then had non-numeric characters | ||
if ( isNaN( fieldFloat ) || fieldFloat.toString().length != field.length || fieldFloat[conf.getType]() != 'integer' ) { | ||
continue; | ||
} | ||
var fieldFloat = parseFloat( field ); | ||
// the field started with a number, or no number at all, then had non-numeric characters | ||
if ( isNaN( fieldFloat ) || fieldFloat.toString().length != field.length || fieldFloat.getType() != 'integer' ) { | ||
continue; | ||
} | ||
} | ||
// recurse mixin differently depending on what the target value is | ||
switch ( Object[conf.getType]( target[field] ) ) { | ||
// recurse mixin differently depending on what the target value is | ||
switch ( Object.getType( target[field] ) ) { | ||
// for any non-objects, do this | ||
case 'undefined': | ||
case 'null': | ||
// for any non-objects, do this | ||
case 'undefined': | ||
case 'null': | ||
switch ( Object[conf.getType]( source[field] ) ) { | ||
case 'undefined': | ||
// NO-OP undefined doesn't override anything | ||
break; | ||
case 'null': | ||
target[field] = null; | ||
break; | ||
default: | ||
target[field] = source[field][conf.clone](); | ||
break; | ||
} | ||
switch ( Object.getType( source[field] ) ) { | ||
case 'undefined': | ||
// NO-OP undefined doesn't override anything | ||
break; | ||
case 'null': | ||
target[field] = null; | ||
break; | ||
default: | ||
target[field] = source[field].clone(); | ||
break; | ||
} | ||
break; | ||
break; | ||
// if the target is already an object, we can mixin on it | ||
default: | ||
// if the target is already an object, we can mixin on it | ||
default: | ||
target[field] = target[field][conf.mixin]( source[field] ); | ||
target[field] = target[field].mixin( source[field] ); | ||
break; | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
break; | ||
break; | ||
default: | ||
// NO-OP, primitives can't mixin to objects, arrays and functions | ||
break; | ||
default: | ||
// NO-OP, primitives can't mixin to objects, arrays and functions | ||
break; | ||
} | ||
} | ||
break; | ||
break; | ||
default: | ||
default: | ||
// mixin in the source differently depending on its type | ||
switch ( Object.getType( source ) ) { | ||
// mixin in the source differently depending on its type | ||
switch ( Object[conf.getType]( source ) ) { | ||
// arrays and objects just replace primitives | ||
case 'array': | ||
case 'object': | ||
// arrays and objects just replace primitives | ||
case 'array': | ||
case 'object': | ||
// override primitives by just passing through a clone of parent | ||
target = source.clone(); | ||
// override primitives by just passing through a clone of parent | ||
target = source[conf.clone](); | ||
break; | ||
break; | ||
default: | ||
default: | ||
// target is a primitive and can't be null or undefined here, and all other primitives have equal precedence, so just pass through | ||
target = source; | ||
// target is a primitive and can't be null or undefined here, and all other primitives have equal precedence, so just pass through | ||
target = source; | ||
break; | ||
break; | ||
} | ||
} | ||
break; | ||
break; | ||
} | ||
} | ||
} | ||
mixinDepth--; | ||
mixinDepth--; | ||
return target; | ||
return target; | ||
} | ||
} ); | ||
} | ||
} ); | ||
return module.exports; | ||
}; | ||
// auto-init with defaults | ||
module.exports.init(); |
@@ -5,3 +5,3 @@ { | ||
"author": "Anthony Hildoer <anthony@bluerival.com>", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
@@ -6,5 +6,12 @@ core-extensions | ||
method to parallel Array.isArray(), a clone() method on all objects and a | ||
mixin() method on all objects. | ||
mixin() method on all objects, and a getType() method. | ||
Name spacing is supported as of version 0.3.0. See new init function for details. | ||
isObject() will return TRUE for anything that is typeof object, is not an Array, and is not NULL | ||
clone. | ||
getType() will return 'null' for NULL, 'array' for an Array, 'float' for a non-integer number, 'integer' for an integer number, and typeof result for all else. | ||
clone() will return a distinct copy of the object it was called from. Date objects are cloned, arrays and objects are recursively cloned down 100 levels max and all else is just passed through. | ||
mixin() will return a clone of the original object, with any passed in objects merged in recursively up to 100 levels max. mixin() accepts an arbitrary number of arguments, they will be mixed in from left to right. | ||
Documentation | ||
@@ -11,0 +18,0 @@ ==================== |
1184
test/default.js
'use strict'; | ||
require( '../' ); | ||
var assert = require( 'assert' ); | ||
var coreExtensions = require( '../' ); | ||
describe( 'Object.isObject()', function () { | ||
var nameSpaces = [ | ||
undefined, // default init | ||
{ // test uniform namespace and unset of default | ||
isObject: 'oneIsObject', | ||
getType: 'oneGetType', | ||
clone: 'one-Clone', | ||
mixin: 'oneMixin' | ||
}, | ||
{ // test uniform namespace and unset of custom namespace | ||
isObject: 'twoIsObject', | ||
getType: 'twoGetType', | ||
clone: 'twoClone', | ||
mixin: '_twoMixin' | ||
}, | ||
{ // test partial namespace and unset of custom namespace | ||
getType: 'threeGetType', | ||
clone: 'four_Clone' | ||
}, | ||
{ // test uniform namespace and unset of custom namespace | ||
isObject: 'sixIs0bject', | ||
getType: 'sixGetType4', | ||
clone: 'six-Clone', | ||
mixin: 'sixMixin' | ||
}, | ||
{ // test explicit set of default name space and unset of custom namespace | ||
isObject: 'isObject', | ||
getType: 'getType', | ||
clone: 'clone', | ||
mixin: 'mixin' | ||
} | ||
]; | ||
it( 'should return false for an array', function () { | ||
assert.equal( Object.isObject( [] ), false ); | ||
assert.equal( Object.isObject( [ "one", "two", "three" ] ), false ); | ||
} ); | ||
for ( var i = 1; i < nameSpaces.length; i++ ) { | ||
testNameSpace( nameSpaces[i] ); | ||
if ( i > 0 ) { | ||
testUnsetNameSpace( nameSpaces[i - 1] ); | ||
} | ||
it( 'should return false for NULL', function () { | ||
assert.equal( Object.isObject( null ), false ); | ||
} ); | ||
} | ||
it( 'should return false for UNDEFINED', function () { | ||
assert.equal( Object.isObject( undefined ), false ); | ||
} ); | ||
testImproperNameSpaces(); | ||
it( 'should return false for a string', function () { | ||
assert.equal( Object.isObject( "string" ), false ); | ||
assert.equal( Object.isObject( "" ), false ); | ||
} ); | ||
it( 'should return false for an integer', function () { | ||
assert.equal( Object.isObject( 1 ), false ); | ||
assert.equal( Object.isObject( 0 ), false ); | ||
assert.equal( Object.isObject( -1 ), false ); | ||
} ); | ||
function testImproperNameSpaces() { | ||
describe( 'set improper namespaces', function () { | ||
it( 'should return false for a float', function () { | ||
assert.equal( Object.isObject( 1.1 ), false ); | ||
assert.equal( Object.isObject( 0.0 ), false ); | ||
assert.equal( Object.isObject( -1.1 ), false ); | ||
} ); | ||
[ | ||
'334kj' , | ||
'hlkjdf*' , | ||
'*sdfsadf' , | ||
'sdfasdf.safasdf.' , | ||
'isObjec.t' , | ||
'isObject$' | ||
].forEach( | ||
function ( nameSpace ) { | ||
testImproperNameSpace( nameSpace ); | ||
} | ||
); | ||
it( 'should return false for a boolean', function () { | ||
assert.equal( Object.isObject( true ), false ); | ||
assert.equal( Object.isObject( false ), false ); | ||
} ); | ||
} | ||
it( 'should return true for an object {}', function () { | ||
assert.equal( Object.isObject( {} ), true ); | ||
function testImproperNameSpace( nameSpace ) { | ||
it( 'should not allow the nameSpace ' + nameSpace, function () { | ||
assert.throws( function () { | ||
coreExtensions.init( { | ||
isObject: nameSpace | ||
} ); | ||
}, Error ); | ||
} ); | ||
} | ||
describe( 'should return true for any kind of object:', function () { | ||
function testUnsetNameSpace( conf ) { | ||
it( 'new Date()', function () { | ||
assert.equal( Object.isObject( new Date() ), true ); | ||
} ); | ||
if ( !conf ) { | ||
conf = {}; | ||
} | ||
it( 'new RegExp()', function () { | ||
assert.equal( Object.isObject( new RegExp() ), true ); | ||
describe( 'unset namespace ' + JSON.stringify( conf ), function () { | ||
var expectedConf = { | ||
isObject: typeof conf.isObject === 'string' ? conf.isObject : 'isObject', | ||
getType: typeof conf.getType === 'string' ? conf.getType : 'getType', | ||
clone: typeof conf.clone === 'string' ? conf.clone : 'clone', | ||
mixin: typeof conf.mixin === 'string' ? conf.mixin : 'mixin' | ||
}; | ||
describe( 'isObject', function () { | ||
it( 'should be undefined', function () { | ||
assert.strictEqual( Object[expectedConf.isObject], undefined, 'was not undefined' ); | ||
} ); | ||
} ); | ||
describe( 'getType', function () { | ||
it( 'should be undefined', function () { | ||
assert.strictEqual( Object[expectedConf.getType], undefined, 'was not undefined' ); | ||
} ); | ||
} ); | ||
describe( 'clone', function () { | ||
it( 'should be undefined', function () { | ||
assert.strictEqual( Object[expectedConf.clone], undefined, 'was not undefined' ); | ||
} ); | ||
} ); | ||
describe( 'mixin', function () { | ||
it( 'should be undefined', function () { | ||
assert.strictEqual( Object[expectedConf.mixin], undefined, 'was not undefined' ); | ||
} ); | ||
} ); | ||
} ); | ||
} | ||
} ); | ||
function testNameSpace( conf ) { | ||
describe( 'Object.getType()', function () { | ||
describe( 'set namespace ' + JSON.stringify( conf ), function () { | ||
it( 'should handle UNDEFINED', function () { | ||
assert.equal( Object.getType( undefined ), 'undefined' ); | ||
} ); | ||
var init = conf !== undefined; | ||
it( 'should handle NULL', function () { | ||
assert.equal( Object.getType( null ), 'null' ); | ||
} ); | ||
if ( !conf ) { | ||
conf = {}; | ||
} | ||
it( 'should handle strings', function () { | ||
assert.equal( Object.getType( "string" ), "string" ); | ||
assert.equal( "string".getType(), "string" ); | ||
} ); | ||
var expectedConf = { | ||
isObject: typeof conf.isObject === 'string' ? conf.isObject : 'isObject', | ||
getType: typeof conf.getType === 'string' ? conf.getType : 'getType', | ||
clone: typeof conf.clone === 'string' ? conf.clone : 'clone', | ||
mixin: typeof conf.mixin === 'string' ? conf.mixin : 'mixin' | ||
}; | ||
it( 'should handle integers', function () { | ||
assert.equal( Object.getType( 1 ), 'integer' ); | ||
assert.equal( (1).getType(), 'integer' ); | ||
assert.equal( Object.getType( -1 ), 'integer' ); | ||
assert.equal( (-1).getType(), 'integer' ); | ||
assert.equal( Object.getType( 0 ), 'integer' ); | ||
assert.equal( (0).getType(), 'integer' ); | ||
assert.equal( Object.getType( 0.0 ), 'integer' ); | ||
assert.equal( (0.0).getType(), 'integer' ); | ||
assert.equal( Object.getType( Number.MAX_VALUE ), 'integer' ); | ||
assert.equal( (Number.MAX_VALUE).getType(), 'integer' ); | ||
assert.equal( Object.getType( -Number.MAX_VALUE ), 'integer' ); | ||
assert.equal( (-Number.MAX_VALUE).getType(), 'integer' ); | ||
} ); | ||
if ( init ) { | ||
before( function () { | ||
coreExtensions.init( conf ); | ||
} ); | ||
} | ||
it( 'should handle floats', function () { | ||
assert.equal( Object.getType( 1.1 ), 'float' ); | ||
assert.equal( (1.1).getType(), 'float' ); | ||
assert.equal( Object.getType( -1.1 ), 'float' ); | ||
assert.equal( (-1.1).getType(), 'float' ); | ||
assert.equal( Object.getType( Number.MIN_VALUE ), 'float' ); | ||
assert.equal( (Number.MIN_VALUE).getType(), 'float' ); | ||
assert.equal( Object.getType( -Number.MIN_VALUE ), 'float' ); | ||
assert.equal( (-Number.MIN_VALUE).getType(), 'float' ); | ||
} ); | ||
describe( 'isObject', function () { | ||
it( 'should handle booleans', function () { | ||
assert.equal( Object.getType( true ), 'boolean' ); | ||
assert.equal( Object.getType( false ), 'boolean' ); | ||
assert.equal( (true).getType(), 'boolean' ); | ||
assert.equal( (false).getType(), 'boolean' ); | ||
} ); | ||
it( 'should return false for an array', function () { | ||
assert.equal( Object[expectedConf.isObject]( [] ), false ); | ||
assert.equal( Object[expectedConf.isObject]( [ "one", "two", "three" ] ), false ); | ||
} ); | ||
it( 'should handle arrays', function () { | ||
assert.equal( Object.getType( [] ), 'array' ); | ||
assert.equal( Object.getType( [ "one", "two", "three" ] ), 'array' ); | ||
assert.equal( [].getType(), 'array' ); | ||
assert.equal( [ "one", "two", "three" ].getType(), 'array' ); | ||
} ); | ||
it( 'should return false for NULL', function () { | ||
assert.equal( Object[expectedConf.isObject]( null ), false ); | ||
} ); | ||
it( 'should handle functions', function () { | ||
assert.equal( Object.getType( function () { | ||
} ), 'function' ); | ||
assert.equal( (function () { | ||
}).getType(), 'function' ); | ||
} ); | ||
it( 'should return false for UNDEFINED', function () { | ||
assert.equal( Object[expectedConf.isObject]( undefined ), false ); | ||
} ); | ||
it( 'should handle {}', function () { | ||
assert.equal( Object.getType( {} ), 'object' ); | ||
assert.equal( {}.getType(), 'object' ); | ||
} ); | ||
it( 'should return false for a string', function () { | ||
assert.equal( Object[expectedConf.isObject]( "string" ), false ); | ||
assert.equal( Object[expectedConf.isObject]( "" ), false ); | ||
} ); | ||
describe( 'should handle any other kind of object:', function () { | ||
it( 'should return false for an integer', function () { | ||
assert.equal( Object[expectedConf.isObject]( 1 ), false ); | ||
assert.equal( Object[expectedConf.isObject]( 0 ), false ); | ||
assert.equal( Object[expectedConf.isObject]( -1 ), false ); | ||
} ); | ||
it( 'new Date()', function () { | ||
assert.equal( Object.getType( new Date() ), 'object' ); | ||
assert.equal( (new Date()).getType(), 'object' ); | ||
} ); | ||
it( 'should return false for a float', function () { | ||
assert.equal( Object[expectedConf.isObject]( 1.1 ), false ); | ||
assert.equal( Object[expectedConf.isObject]( 0.0 ), false ); | ||
assert.equal( Object[expectedConf.isObject]( -1.1 ), false ); | ||
} ); | ||
it( 'new RegExp()', function () { | ||
assert.equal( Object.getType( new RegExp() ), 'object' ); | ||
assert.equal( (new RegExp()).getType(), 'object' ); | ||
} ); | ||
it( 'should return false for a boolean', function () { | ||
assert.equal( Object[expectedConf.isObject]( true ), false ); | ||
assert.equal( Object[expectedConf.isObject]( false ), false ); | ||
} ); | ||
} ); | ||
it( 'should return true for an object {}', function () { | ||
assert.equal( Object[expectedConf.isObject]( {} ), true ); | ||
} ); | ||
} ); | ||
describe( 'should return true for any kind of object:', function () { | ||
describe( 'clone()', function () { | ||
it( 'new Date()', function () { | ||
assert.equal( Object[expectedConf.isObject]( new Date() ), true ); | ||
} ); | ||
describe( 'string', function () { | ||
it( 'new RegExp()', function () { | ||
assert.equal( Object[expectedConf.isObject]( new RegExp() ), true ); | ||
} ); | ||
var theString = 'the string'; | ||
} ); | ||
it( 'should return a string', function () { | ||
assert.equal( typeof (theString.clone()), 'string' ); | ||
} ); | ||
it( 'should return a new string with same value', function () { | ||
assert.equal( theString.clone(), theString ); | ||
} ); | ||
describe( 'getType', function () { | ||
} ); | ||
it( 'should handle UNDEFINED', function () { | ||
assert.equal( Object[expectedConf.getType]( undefined ), 'undefined' ); | ||
} ); | ||
describe( 'Date', function () { | ||
it( 'should handle NULL', function () { | ||
assert.equal( Object[expectedConf.getType]( null ), 'null' ); | ||
} ); | ||
var theDate = new Date(); | ||
it( 'should handle strings', function () { | ||
assert.equal( Object[expectedConf.getType]( "string" ), "string" ); | ||
assert.equal( "string"[expectedConf.getType](), "string" ); | ||
} ); | ||
it( 'should return a date object', function () { | ||
assert.ok( theDate.clone() instanceof Date ); | ||
} ); | ||
it( 'should handle integers', function () { | ||
assert.equal( Object[expectedConf.getType]( 1 ), 'integer' ); | ||
assert.equal( (1)[expectedConf.getType](), 'integer' ); | ||
assert.equal( Object[expectedConf.getType]( -1 ), 'integer' ); | ||
assert.equal( (-1)[expectedConf.getType](), 'integer' ); | ||
assert.equal( Object[expectedConf.getType]( 0 ), 'integer' ); | ||
assert.equal( (0)[expectedConf.getType](), 'integer' ); | ||
assert.equal( Object[expectedConf.getType]( 0.0 ), 'integer' ); | ||
assert.equal( (0.0)[expectedConf.getType](), 'integer' ); | ||
assert.equal( Object[expectedConf.getType]( Number.MAX_VALUE ), 'integer' ); | ||
assert.equal( (Number.MAX_VALUE)[expectedConf.getType](), 'integer' ); | ||
assert.equal( Object[expectedConf.getType]( -Number.MAX_VALUE ), 'integer' ); | ||
assert.equal( (-Number.MAX_VALUE)[expectedConf.getType](), 'integer' ); | ||
} ); | ||
it( 'should have the same ISO date', function () { | ||
assert.equal( theDate.clone().toISOString(), theDate.toISOString() ); | ||
} ); | ||
it( 'should handle floats', function () { | ||
assert.equal( Object[expectedConf.getType]( 1.1 ), 'float' ); | ||
assert.equal( (1.1)[expectedConf.getType](), 'float' ); | ||
assert.equal( Object[expectedConf.getType]( -1.1 ), 'float' ); | ||
assert.equal( (-1.1)[expectedConf.getType](), 'float' ); | ||
assert.equal( Object[expectedConf.getType]( Number.MIN_VALUE ), 'float' ); | ||
assert.equal( (Number.MIN_VALUE)[expectedConf.getType](), 'float' ); | ||
assert.equal( Object[expectedConf.getType]( -Number.MIN_VALUE ), 'float' ); | ||
assert.equal( (-Number.MIN_VALUE)[expectedConf.getType](), 'float' ); | ||
} ); | ||
it( 'should be a new object', function () { | ||
assert.notStrictEqual( theDate.clone(), theDate ); | ||
it( 'should handle booleans', function () { | ||
assert.equal( Object[expectedConf.getType]( true ), 'boolean' ); | ||
assert.equal( Object[expectedConf.getType]( false ), 'boolean' ); | ||
assert.equal( (true)[expectedConf.getType](), 'boolean' ); | ||
assert.equal( (false)[expectedConf.getType](), 'boolean' ); | ||
} ); | ||
it( 'should handle arrays', function () { | ||
assert.equal( Object[expectedConf.getType]( [] ), 'array' ); | ||
assert.equal( Object[expectedConf.getType]( [ "one", "two", "three" ] ), 'array' ); | ||
assert.equal( [][expectedConf.getType](), 'array' ); | ||
assert.equal( [ "one", "two", "three" ][expectedConf.getType](), 'array' ); | ||
} ); | ||
it( 'should handle functions', function () { | ||
assert.equal( Object[expectedConf.getType]( function () { | ||
} ), 'function' ); | ||
assert.equal( (function () { | ||
})[expectedConf.getType](), 'function' ); | ||
} ); | ||
it( 'should handle {}', function () { | ||
assert.equal( Object[expectedConf.getType]( {} ), 'object' ); | ||
assert.equal( {}[expectedConf.getType](), 'object' ); | ||
} ); | ||
describe( 'should handle any other kind of object:', function () { | ||
it( 'new Date()', function () { | ||
assert.equal( Object[expectedConf.getType]( new Date() ), 'object' ); | ||
assert.equal( (new Date())[expectedConf.getType](), 'object' ); | ||
} ); | ||
it( 'new RegExp()', function () { | ||
assert.equal( Object[expectedConf.getType]( new RegExp() ), 'object' ); | ||
assert.equal( (new RegExp())[expectedConf.getType](), 'object' ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); | ||
describe( 'clone', function () { | ||
describe( 'Objects and Arrays', function () { | ||
describe( 'string', function () { | ||
var theObject = { | ||
'array field': [ | ||
'hi', 'there' | ||
], | ||
'number': 1, | ||
'float': 1.04, | ||
'array numbers': [ | ||
1, 4.45, 32, 3, 3413, function () { | ||
} | ||
], | ||
'func': function () { | ||
}, | ||
'object': { | ||
'array field': [ | ||
'hi', 'there' | ||
], | ||
'number': 1, | ||
'float': 1.04, | ||
'array numbers': [ | ||
1, 4.45, 32, 3, 3413, | ||
{ | ||
name: 'user1' | ||
var theString = 'the string'; | ||
it( 'should return a string', function () { | ||
assert.equal( typeof (theString[expectedConf.clone]()), 'string' ); | ||
} ); | ||
it( 'should return a new string with same value', function () { | ||
assert.equal( theString[expectedConf.clone](), theString ); | ||
} ); | ||
} ); | ||
describe( 'Date', function () { | ||
var theDate = new Date(); | ||
it( 'should return a date object', function () { | ||
assert.ok( theDate[expectedConf.clone]() instanceof Date ); | ||
} ); | ||
it( 'should have the same ISO date', function () { | ||
assert.equal( theDate[expectedConf.clone]().toISOString(), theDate.toISOString() ); | ||
} ); | ||
it( 'should be a new object', function () { | ||
assert.notStrictEqual( theDate[expectedConf.clone](), theDate ); | ||
} ); | ||
} ); | ||
describe( 'Objects and Arrays', function () { | ||
var theObject = { | ||
'array field': [ | ||
'hi', 'there' | ||
], | ||
'number': 1, | ||
'float': 1.04, | ||
'array numbers': [ | ||
1, 4.45, 32, 3, 3413, function () { | ||
} | ||
], | ||
'func': function () { | ||
}, | ||
{ | ||
name: 'user2' | ||
} | ||
], | ||
'object': { | ||
'deep': { | ||
'array': [ | ||
'object': { | ||
'array field': [ | ||
'hi', 'there' | ||
], | ||
'number': 1, | ||
'float': 1.04, | ||
'array numbers': [ | ||
1, 4.45, 32, 3, 3413, | ||
{ | ||
'more:': 'here' | ||
name: 'user1' | ||
}, | ||
{ | ||
name: 'user2' | ||
} | ||
] | ||
], | ||
'object': { | ||
'deep': { | ||
'array': [ | ||
{ | ||
'more:': 'here' | ||
} | ||
] | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
it( 'should return an object', function () { | ||
assert.ok( theObject.clone() instanceof Object ); | ||
} ); | ||
it( 'should return an object', function () { | ||
assert.ok( theObject[expectedConf.clone]() instanceof Object ); | ||
} ); | ||
it( 'should have the same structure and values', function () { | ||
assert.deepEqual( theObject.clone(), theObject ); | ||
} ); | ||
it( 'should have the same structure and values', function () { | ||
assert.deepEqual( theObject[expectedConf.clone](), theObject ); | ||
} ); | ||
it( 'should be a new object', function () { | ||
assert.notStrictEqual( theObject.clone(), theObject ); | ||
} ); | ||
it( 'should be a new object', function () { | ||
assert.notStrictEqual( theObject[expectedConf.clone](), theObject ); | ||
} ); | ||
it( 'should not recurse beyond 100 levels', function () { | ||
assert.throws( function () { | ||
it( 'should not recurse beyond 100 levels', function () { | ||
assert.throws( function () { | ||
var cloneObject = {}; | ||
var ref = cloneObject; | ||
var cloneObject = {}; | ||
var ref = cloneObject; | ||
for ( var i = 0; i < 300; i++ ) { | ||
ref.nesting = {}; | ||
ref = ref.nesting; | ||
} | ||
for ( var i = 0; i < 300; i++ ) { | ||
ref.nesting = {}; | ||
ref = ref.nesting; | ||
} | ||
ref.final = "hi"; | ||
ref.final = "hi"; | ||
cloneObject.clone(); | ||
cloneObject[expectedConf.clone](); | ||
} ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); | ||
describe( 'everything else', function () { | ||
describe( 'everything else', function () { | ||
var theFunction = function () { | ||
return 'hello'; | ||
}; | ||
var theFunction = function () { | ||
return 'hello'; | ||
}; | ||
it( 'should be === of original', function () { | ||
assert.strictEqual( theFunction[expectedConf.clone](), theFunction ); | ||
} ); | ||
it( 'should be === of original', function () { | ||
assert.strictEqual( theFunction.clone(), theFunction ); | ||
} ); | ||
} ); | ||
} ); | ||
describe( 'mixin', function () { | ||
} ); | ||
describe( 'mixin()', function () { | ||
var theObject = { | ||
statusCode: 200, | ||
data: { | ||
subscription: { | ||
id: '1234567890', | ||
principal_id: 'STACK', | ||
callback_url: 'https://a.host.com', | ||
date_created: '2013-02-04T06:57:18Z', | ||
tags: { | ||
string: 'germany' | ||
} | ||
}, | ||
contacts: [ | ||
{ | ||
name: 'user1' | ||
var theObject = { | ||
statusCode: 200, | ||
data: { | ||
subscription: { | ||
id: '1234567890', | ||
principal_id: 'STACK', | ||
callback_url: 'https://a.host.com', | ||
date_created: '2013-02-04T06:57:18Z', | ||
tags: { | ||
string: 'germany' | ||
} | ||
}, | ||
contacts: [ | ||
{ | ||
name: 'user1' | ||
}, | ||
{ | ||
name: 'user2' | ||
} | ||
] | ||
}, | ||
{ | ||
name: 'user2' | ||
func: function () { | ||
} | ||
] | ||
}, | ||
func: function () { | ||
} | ||
}; | ||
}; | ||
var theDefaultObject = { | ||
statusCode: 500, | ||
data: { | ||
subscription: { | ||
id: null | ||
}, | ||
contacts: [] | ||
} | ||
}; | ||
var theDefaultObject = { | ||
statusCode: 500, | ||
data: { | ||
subscription: { | ||
id: null | ||
}, | ||
contacts: [] | ||
} | ||
}; | ||
var theArray = [ | ||
'one', | ||
1, | ||
'onepointone', | ||
1.1, | ||
{ | ||
'hi': 'germany', | ||
'bye': 'france', | ||
'an array': [ | ||
var theArray = [ | ||
'one', | ||
function () { | ||
}, | ||
1, | ||
@@ -318,343 +446,355 @@ 'onepointone', | ||
{ | ||
'hi 2': 'germany', | ||
'bye 2': 'france', | ||
'an array 2': [ | ||
'hi': 'germany', | ||
'bye': 'france', | ||
'an array': [ | ||
'one', | ||
function () { | ||
}, | ||
1, | ||
'onepointone', | ||
1.1, | ||
{ | ||
'hi 2': 'germany', | ||
'bye 2': 'france', | ||
'an array 2': [ | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
]; | ||
]; | ||
var theDefaultArray = [ | ||
'two', | ||
undefined, | ||
null, | ||
null, | ||
{ | ||
'hi': null | ||
} | ||
]; | ||
var theDefaultArray = [ | ||
'two', | ||
undefined, | ||
null, | ||
null, | ||
{ | ||
'hi': null | ||
} | ||
]; | ||
// original should not be modified | ||
it( 'should not modify original object', function () { | ||
theDefaultObject.mixin( theObject ); | ||
assert.notDeepEqual( theObject, theDefaultObject ); | ||
} ); | ||
it( 'should not modify original array', function () { | ||
theDefaultArray.mixin( theArray ); | ||
assert.notDeepEqual( theArray, theDefaultArray ); | ||
} ); | ||
// original should not be modified | ||
it( 'should not modify original object', function () { | ||
theDefaultObject[expectedConf.mixin]( theObject ); | ||
assert.notDeepEqual( theObject, theDefaultObject ); | ||
} ); | ||
it( 'should not modify original array', function () { | ||
theDefaultArray[expectedConf.mixin]( theArray ); | ||
assert.notDeepEqual( theArray, theDefaultArray ); | ||
} ); | ||
// a new one | ||
it( 'should return a new object', function () { | ||
assert.notStrictEqual( theObject.mixin( {} ), theObject ); | ||
} ); | ||
it( 'should return a new array', function () { | ||
assert.notStrictEqual( theArray.mixin( {} ), theArray ); | ||
} ); | ||
// a new one | ||
it( 'should return a new object', function () { | ||
assert.notStrictEqual( theObject[expectedConf.mixin]( {} ), theObject ); | ||
} ); | ||
it( 'should return a new array', function () { | ||
assert.notStrictEqual( theArray[expectedConf.mixin]( {} ), theArray ); | ||
} ); | ||
// deep structure with empty default | ||
it( 'should return the same deep structure with empty default object', function () { | ||
assert.notStrictEqual( {}.mixin( theObject ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with empty default array', function () { | ||
assert.notStrictEqual( [].mixin( theArray ), theArray ); | ||
} ); | ||
// deep structure with empty default | ||
it( 'should return the same deep structure with empty default object', function () { | ||
assert.notStrictEqual( {}[expectedConf.mixin]( theObject ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with empty default array', function () { | ||
assert.notStrictEqual( [][expectedConf.mixin]( theArray ), theArray ); | ||
} ); | ||
// deep structure with empty input | ||
it( 'should return the same deep structure with empty input object', function () { | ||
assert.deepEqual( theObject.mixin( {} ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with empty input array', function () { | ||
assert.deepEqual( theArray.mixin( [] ), theArray ); | ||
} ); | ||
// deep structure with empty input | ||
it( 'should return the same deep structure with empty input object', function () { | ||
assert.deepEqual( theObject[expectedConf.mixin]( {} ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with empty input array', function () { | ||
assert.deepEqual( theArray[expectedConf.mixin]( [] ), theArray ); | ||
} ); | ||
// deep structure with undefined input | ||
it( 'should return the same deep structure with undefined input object', function () { | ||
assert.deepEqual( theObject.mixin( undefined ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with undefined input array', function () { | ||
assert.deepEqual( theArray.mixin( undefined ), theArray ); | ||
} ); | ||
// deep structure with undefined input | ||
it( 'should return the same deep structure with undefined input object', function () { | ||
assert.deepEqual( theObject[expectedConf.mixin]( undefined ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with undefined input array', function () { | ||
assert.deepEqual( theArray[expectedConf.mixin]( undefined ), theArray ); | ||
} ); | ||
// deep structure with null input | ||
it( 'should return the same deep structure with null input object', function () { | ||
assert.deepEqual( theObject.mixin( null ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with null input array', function () { | ||
assert.deepEqual( theArray.mixin( null ), theArray ); | ||
} ); | ||
// deep structure with null input | ||
it( 'should return the same deep structure with null input object', function () { | ||
assert.deepEqual( theObject[expectedConf.mixin]( null ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with null input array', function () { | ||
assert.deepEqual( theArray[expectedConf.mixin]( null ), theArray ); | ||
} ); | ||
// deep structure with initialized default | ||
it( 'should return the same deep structure with initialized default object', function () { | ||
assert.deepEqual( theDefaultObject.mixin( theObject ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with initialized default array', function () { | ||
assert.deepEqual( theDefaultArray.mixin( theArray ), theArray ); | ||
} ); | ||
// deep structure with initialized default | ||
it( 'should return the same deep structure with initialized default object', function () { | ||
assert.deepEqual( theDefaultObject[expectedConf.mixin]( theObject ), theObject ); | ||
} ); | ||
it( 'should return the same deep structure with initialized default array', function () { | ||
assert.deepEqual( theDefaultArray[expectedConf.mixin]( theArray ), theArray ); | ||
} ); | ||
// mixin an object to an array | ||
it( 'should mixin all integer fields from the object to the array', function () { | ||
// mixin an object to an array | ||
it( 'should mixin all integer fields from the object to the array', function () { | ||
var theArrayFromObject = { | ||
'zero': 0, | ||
'one': 1, | ||
'two': 2, | ||
0: 0, | ||
1: 1, | ||
'2': 2, | ||
'3.0': 'three.zero', | ||
3: 3, | ||
'4.1': 4, | ||
5.2: 5, | ||
'6six': 6, | ||
7: 7 | ||
}; | ||
var theArrayFromObject = { | ||
'zero': 0, | ||
'one': 1, | ||
'two': 2, | ||
0: 0, | ||
1: 1, | ||
'2': 2, | ||
'3.0': 'three.zero', | ||
3: 3, | ||
'4.1': 4, | ||
5.2: 5, | ||
'6six': 6, | ||
7: 7 | ||
}; | ||
var theDefaultArrayFromObject = [ | ||
'zero', | ||
[ | ||
'one' | ||
], | ||
'two', | ||
'three', | ||
{ | ||
'four': 4 | ||
} | ||
]; | ||
var theDefaultArrayFromObject = [ | ||
'zero', | ||
[ | ||
'one' | ||
], | ||
'two', | ||
'three', | ||
{ | ||
'four': 4 | ||
} | ||
]; | ||
var expectedArrayFromObject = [ | ||
0, | ||
[ 'one' ], | ||
2, | ||
3, | ||
{ | ||
'four': 4 | ||
} | ||
]; | ||
expectedArrayFromObject[7] = 7; | ||
var expectedArrayFromObject = [ | ||
0, | ||
[ 'one' ], | ||
2, | ||
3, | ||
{ | ||
'four': 4 | ||
} | ||
]; | ||
expectedArrayFromObject[7] = 7; | ||
assert.deepEqual( theDefaultArrayFromObject.mixin( theArrayFromObject ), expectedArrayFromObject ); | ||
assert.deepEqual( theDefaultArrayFromObject[expectedConf.mixin]( theArrayFromObject ), expectedArrayFromObject ); | ||
} ); | ||
} ); | ||
// mixin an array to an object | ||
it( 'should mixin in an array to an object by converting the integer indexes in the array to string field names in the object', function () { | ||
// mixin an array to an object | ||
it( 'should mixin in an array to an object by converting the integer indexes in the array to string field names in the object', function () { | ||
var theObjectFromArray = [ | ||
'zero', | ||
'one', | ||
'two', | ||
'three' | ||
]; | ||
theObjectFromArray[5] = 'five'; | ||
var theObjectFromArray = [ | ||
'zero', | ||
'one', | ||
'two', | ||
'three' | ||
]; | ||
theObjectFromArray[5] = 'five'; | ||
var theDefaultObjectFromArray = { | ||
zero: 0, | ||
'one': 1, | ||
'two': 2, | ||
0: 0, | ||
1: 1, | ||
'2': 2 | ||
}; | ||
var theDefaultObjectFromArray = { | ||
zero: 0, | ||
'one': 1, | ||
'two': 2, | ||
0: 0, | ||
1: 1, | ||
'2': 2 | ||
}; | ||
var expectedObjectFromArray = { | ||
'0': 'zero', | ||
'1': 'one', | ||
'2': 'two', | ||
'3': 'three', | ||
'5': 'five', | ||
zero: 0, | ||
one: 1, | ||
two: 2 | ||
}; | ||
var expectedObjectFromArray = { | ||
'0': 'zero', | ||
'1': 'one', | ||
'2': 'two', | ||
'3': 'three', | ||
'5': 'five', | ||
zero: 0, | ||
one: 1, | ||
two: 2 | ||
}; | ||
assert.deepEqual( theDefaultObjectFromArray.mixin( theObjectFromArray ), expectedObjectFromArray ); | ||
assert.deepEqual( theDefaultObjectFromArray[expectedConf.mixin]( theObjectFromArray ), expectedObjectFromArray ); | ||
} ); | ||
} ); | ||
it( 'should mixin nested arrays to objects', function () { | ||
it( 'should mixin nested arrays to objects', function () { | ||
var theInput = { | ||
two: [ | ||
'zero', | ||
'one', | ||
'two', | ||
'three' | ||
] | ||
}; | ||
theInput.two[5] = 'five'; | ||
var theInput = { | ||
two: [ | ||
'zero', | ||
'one', | ||
'two', | ||
'three' | ||
] | ||
}; | ||
theInput.two[5] = 'five'; | ||
var theDefault = { | ||
zero: 0, | ||
'one': 1, | ||
'two': { | ||
zero: 0, | ||
'one': 1, | ||
'two': 'two', | ||
0: 0, | ||
1: 1, | ||
'2': 2 | ||
}, | ||
0: 0, | ||
1: 1, | ||
'2': 2 | ||
}; | ||
var theDefault = { | ||
zero: 0, | ||
'one': 1, | ||
'two': { | ||
zero: 0, | ||
'one': 1, | ||
'two': 'two', | ||
0: 0, | ||
1: 1, | ||
'2': 2 | ||
}, | ||
0: 0, | ||
1: 1, | ||
'2': 2 | ||
}; | ||
var expectedObject = { | ||
'0': 0, | ||
'1': 1, | ||
'2': 2, | ||
'zero': 0, | ||
'one': 1, | ||
'two': { | ||
'0': 'zero', | ||
'1': 'one', | ||
'2': 'two', | ||
'3': 'three', | ||
'5': 'five', | ||
'zero': 0, | ||
'one': 1, | ||
'two': 'two' | ||
} | ||
}; | ||
var expectedObject = { | ||
'0': 0, | ||
'1': 1, | ||
'2': 2, | ||
'zero': 0, | ||
'one': 1, | ||
'two': { | ||
'0': 'zero', | ||
'1': 'one', | ||
'2': 'two', | ||
'3': 'three', | ||
'5': 'five', | ||
'zero': 0, | ||
'one': 1, | ||
'two': 'two' | ||
} | ||
}; | ||
assert.deepEqual( theDefault.mixin( theInput ), expectedObject ); | ||
assert.deepEqual( theDefault[expectedConf.mixin]( theInput ), expectedObject ); | ||
} ); | ||
} ); | ||
it( 'should mixin arrays over primitives', function () { | ||
it( 'should mixin arrays over primitives', function () { | ||
var theArray = [ | ||
'one', | ||
'two', | ||
{ | ||
'three': 'four' | ||
}, | ||
[ | ||
'five' | ||
] | ||
]; | ||
var theArray = [ | ||
'one', | ||
'two', | ||
{ | ||
'three': 'four' | ||
}, | ||
[ | ||
'five' | ||
] | ||
]; | ||
assert.deepEqual( (true).mixin( theArray ), theArray ); | ||
assert.deepEqual( (false).mixin( theArray ), theArray ); | ||
assert.deepEqual( (1).mixin( theArray ), theArray ); | ||
assert.deepEqual( (-1).mixin( theArray ), theArray ); | ||
assert.deepEqual( (1.1).mixin( theArray ), theArray ); | ||
assert.deepEqual( (-1.1).mixin( theArray ), theArray ); | ||
assert.deepEqual( (0).mixin( theArray ), theArray ); | ||
assert.deepEqual( (0.0).mixin( theArray ), theArray ); | ||
assert.deepEqual( ("string").mixin( theArray ), theArray ); | ||
assert.deepEqual( ("").mixin( theArray ), theArray ); | ||
assert.deepEqual( (true)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( (false)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( (1)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( (-1)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( (1.1)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( (-1.1)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( (0)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( (0.0)[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( ("string")[expectedConf.mixin]( theArray ), theArray ); | ||
assert.deepEqual( ("")[expectedConf.mixin]( theArray ), theArray ); | ||
} ); | ||
} ); | ||
it( 'should mixin objects over primitives', function () { | ||
it( 'should mixin objects over primitives', function () { | ||
var theObject = { | ||
'one': 1, | ||
'two': 2, | ||
'three': { | ||
'four': 4 | ||
}, | ||
'five': [ | ||
'six' | ||
] | ||
}; | ||
var theObject = { | ||
'one': 1, | ||
'two': 2, | ||
'three': { | ||
'four': 4 | ||
}, | ||
'five': [ | ||
'six' | ||
] | ||
}; | ||
assert.deepEqual( (true).mixin( theObject ), theObject ); | ||
assert.deepEqual( (false).mixin( theObject ), theObject ); | ||
assert.deepEqual( (1).mixin( theObject ), theObject ); | ||
assert.deepEqual( (-1).mixin( theObject ), theObject ); | ||
assert.deepEqual( (1.1).mixin( theObject ), theObject ); | ||
assert.deepEqual( (-1.1).mixin( theObject ), theObject ); | ||
assert.deepEqual( (0).mixin( theObject ), theObject ); | ||
assert.deepEqual( (0.0).mixin( theObject ), theObject ); | ||
assert.deepEqual( ("string").mixin( theObject ), theObject ); | ||
assert.deepEqual( ("").mixin( theObject ), theObject ); | ||
assert.deepEqual( (true)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( (false)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( (1)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( (-1)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( (1.1)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( (-1.1)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( (0)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( (0.0)[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( ("string")[expectedConf.mixin]( theObject ), theObject ); | ||
assert.deepEqual( ("")[expectedConf.mixin]( theObject ), theObject ); | ||
} ); | ||
} ); | ||
it( 'should not mixin primitives over objects', function () { | ||
it( 'should not mixin primitives over objects', function () { | ||
var theObject = { | ||
'one': 1, | ||
'two': 2, | ||
'three': { | ||
'four': 4 | ||
}, | ||
'five': [ | ||
'six' | ||
] | ||
}; | ||
var theObject = { | ||
'one': 1, | ||
'two': 2, | ||
'three': { | ||
'four': 4 | ||
}, | ||
'five': [ | ||
'six' | ||
] | ||
}; | ||
assert.deepEqual( theObject.mixin( undefined ), theObject ); | ||
assert.deepEqual( theObject.mixin( null ), theObject ); | ||
assert.deepEqual( theObject.mixin( true ), theObject ); | ||
assert.deepEqual( theObject.mixin( false ), theObject ); | ||
assert.deepEqual( theObject.mixin( 1 ), theObject ); | ||
assert.deepEqual( theObject.mixin( -1 ), theObject ); | ||
assert.deepEqual( theObject.mixin( 1.1 ), theObject ); | ||
assert.deepEqual( theObject.mixin( -1.1 ), theObject ); | ||
assert.deepEqual( theObject.mixin( 0 ), theObject ); | ||
assert.deepEqual( theObject.mixin( 0.0 ), theObject ); | ||
assert.deepEqual( theObject.mixin( "string" ), theObject ); | ||
assert.deepEqual( theObject.mixin( "" ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( undefined ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( null ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( true ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( false ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( 1 ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( -1 ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( 1.1 ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( -1.1 ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( 0 ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( 0.0 ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( "string" ), theObject ); | ||
assert.deepEqual( theObject[expectedConf.mixin]( "" ), theObject ); | ||
} ); | ||
} ); | ||
it( 'should not mixin primitives over arrays', function () { | ||
it( 'should not mixin primitives over arrays', function () { | ||
var theArray = [ | ||
'one', | ||
'two', | ||
{ | ||
'three': 'four' | ||
}, | ||
[ | ||
'five' | ||
] | ||
]; | ||
var theArray = [ | ||
'one', | ||
'two', | ||
{ | ||
'three': 'four' | ||
}, | ||
[ | ||
'five' | ||
] | ||
]; | ||
assert.deepEqual( theArray.mixin( undefined ), theArray ); | ||
assert.deepEqual( theArray.mixin( null ), theArray ); | ||
assert.deepEqual( theArray.mixin( true ), theArray ); | ||
assert.deepEqual( theArray.mixin( false ), theArray ); | ||
assert.deepEqual( theArray.mixin( 1 ), theArray ); | ||
assert.deepEqual( theArray.mixin( -1 ), theArray ); | ||
assert.deepEqual( theArray.mixin( 1.1 ), theArray ); | ||
assert.deepEqual( theArray.mixin( -1.1 ), theArray ); | ||
assert.deepEqual( theArray.mixin( 0 ), theArray ); | ||
assert.deepEqual( theArray.mixin( 0.0 ), theArray ); | ||
assert.deepEqual( theArray.mixin( "string" ), theArray ); | ||
assert.deepEqual( theArray.mixin( "" ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( undefined ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( null ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( true ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( false ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( 1 ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( -1 ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( 1.1 ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( -1.1 ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( 0 ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( 0.0 ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( "string" ), theArray ); | ||
assert.deepEqual( theArray[expectedConf.mixin]( "" ), theArray ); | ||
} ); | ||
} ); | ||
it( 'should not recurse beyond 100 levels', function () { | ||
assert.throws( function () { | ||
it( 'should not recurse beyond 100 levels', function () { | ||
assert.throws( function () { | ||
var mixinObject1 = {}; | ||
var mixinObject2 = {}; | ||
var ref1 = mixinObject1; | ||
var ref2 = mixinObject2; | ||
var mixinObject1 = {}; | ||
var mixinObject2 = {}; | ||
var ref1 = mixinObject1; | ||
var ref2 = mixinObject2; | ||
for ( var i = 0; i < 300; i++ ) { | ||
ref1.nesting = {}; | ||
ref1 = ref1.nesting; | ||
ref2.nesting = {}; | ||
ref2 = ref2.nesting; | ||
} | ||
for ( var i = 0; i < 300; i++ ) { | ||
ref1.nesting = {}; | ||
ref1 = ref1.nesting; | ||
ref2.nesting = {}; | ||
ref2 = ref2.nesting; | ||
} | ||
ref1.final = "hi"; | ||
ref2.final = "bye"; | ||
ref1.final = "hi"; | ||
ref2.final = "bye"; | ||
mixinObject1.mixin( mixinObject2 ); | ||
mixinObject1[expectedConf.mixin]( mixinObject2 ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); | ||
} |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
32967
862
50
1