protoblast
Advanced tools
Comparing version 0.3.7 to 0.3.8
@@ -0,1 +1,17 @@ | ||
## 0.3.8 (2017-08-11) | ||
* Add `Function.isNameAllowed(name)` which checks if a name is allowed | ||
* Added very basic `WeakMap` polyfill | ||
* Add `Function.getArgumentNames` | ||
* Allow ability to add Function driers | ||
* Added `Number.isNumeric(input)` | ||
* `Array#sortByPath` will now interpret numbers as new directions | ||
* Added `Array#findByPath(path, value)` | ||
* `URL#addQuery` will no longer iterate over non-plain objects | ||
* Add `limit` parameter to `Object.walk` to limit the recursiveness | ||
* Add `String#splitOnce` and `String#splitLimit` | ||
* Fix `Function.inherits` not adding static methods on time | ||
* Fix `Math.removeOutliers` so it isn't too generous | ||
* Add `String#splitOnce(separator)` and `String#splitLimit(separator, times)` | ||
## 0.3.7 (2017-07-03) | ||
@@ -2,0 +18,0 @@ |
@@ -811,3 +811,3 @@ module.exports = function BlastArray(Blast, Collection) { | ||
* @since 0.1.5 | ||
* @version 0.1.5 | ||
* @version 0.3.8 | ||
* | ||
@@ -817,3 +817,3 @@ * @param {Number} _order Sort order: 1 for ascending, -1 for descending | ||
* | ||
* @param {Array} | ||
* @return {Array} | ||
*/ | ||
@@ -823,12 +823,12 @@ Blast.definePrototype('Array', 'sortByPath', function sortByPath(_order, _paths) { | ||
var paths, | ||
order, | ||
path, | ||
type, | ||
len, | ||
ord, | ||
O, | ||
i; | ||
if (typeof _order == 'number') { | ||
ord = _order; | ||
order = _order; | ||
} else { | ||
ord = -1; | ||
order = -1; | ||
} | ||
@@ -839,3 +839,5 @@ | ||
for (i = 0; i < arguments.length; i++) { | ||
if (typeof arguments[i] == 'string') { | ||
type = typeof arguments[i]; | ||
if (type == 'string' || type == 'number') { | ||
paths.push(arguments[i]); | ||
@@ -847,3 +849,2 @@ } else if (Array.isArray(arguments[i])) { | ||
O = Blast.Bound.Object; | ||
len = paths.length; | ||
@@ -854,10 +855,18 @@ | ||
var alpha, | ||
beta; | ||
beta, | ||
ord; | ||
ord = order; | ||
for (i = 0; i < len; i++) { | ||
path = paths[i]; | ||
alpha = O.path(a, path); | ||
beta = O.path(b, path); | ||
// Allow changing of direction | ||
if (typeof path == 'number') { | ||
ord = path; | ||
} | ||
alpha = Blast.Bound.Object.path(a, path); | ||
beta = Blast.Bound.Object.path(b, path); | ||
if (alpha < beta) { | ||
@@ -877,2 +886,31 @@ return 0 - ord; | ||
/** | ||
* Search the array | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.8 | ||
* @version 0.3.8 | ||
* | ||
* @param {String} path | ||
* @param {Mixed} value | ||
* | ||
* @return {Mixed} | ||
*/ | ||
Blast.definePrototype('Array', 'findByPath', function findByPath(path, value) { | ||
var length, | ||
entry, | ||
i; | ||
length = this.length; | ||
for (i = 0; i < length; i++) { | ||
entry = Blast.Bound.Object.path(this[i], path); | ||
if (entry == value) { | ||
return this[i]; | ||
} | ||
} | ||
}); | ||
/** | ||
* Shuffle the array | ||
@@ -879,0 +917,0 @@ * |
@@ -131,3 +131,3 @@ module.exports = function BlastInheritance(Blast, Collection) { | ||
* @since 0.1.3 | ||
* @version 0.3.6 | ||
* @version 0.3.8 | ||
* | ||
@@ -314,2 +314,7 @@ * @param {String|Function|Array} _parent Parent class to inherit from | ||
// See if `setMethod` is available, if not this means | ||
// Protoblast was loaded without modifying the native objects | ||
// So we add it to this extended class' constructor | ||
ensureConstructorStaticMethods(newConstructor); | ||
if (parentConstructor) { | ||
@@ -372,7 +377,2 @@ | ||
// See if `setMethod` is available, if not this means | ||
// Protoblast was loaded without modifying the native objects | ||
// So we add it to this extended class' constructor | ||
ensureConstructorStaticMethods(newConstructor); | ||
if (!targetPath) { | ||
@@ -379,0 +379,0 @@ // See if we need to set a namespace |
@@ -12,3 +12,3 @@ module.exports = function BlastFunction(Blast, Collection) { | ||
whitespace : /\s+/, | ||
keyword : /\b(?:var|let|for|if|else|in|class|function|typeof|return|with|case|break|switch|export|new|while|do|throw|catch|true|false|continue|null|undefined|try)\b/, | ||
keyword : /\b(?:var|const|let|for|if|else|in|class|function|typeof|return|with|case|break|switch|export|new|while|do|throw|catch|true|false|continue|null|undefined|try)\b/, | ||
name : /[a-zA-Z_\$][a-zA-Z_\$0-9]*/, | ||
@@ -81,2 +81,26 @@ string1 : /"(?:(?:\\\n|\\"|[^"\n]))*?"/, | ||
/** | ||
* Check if the given function name is allowed | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.8 | ||
* @version 0.3.8 | ||
* | ||
* @param {String} name The name of the function to test | ||
* | ||
* @return {Boolean} | ||
*/ | ||
Blast.defineStatic('Function', 'isNameAllowed', function isNameAllowed(name) { | ||
var result; | ||
try { | ||
eval('result = function ' + name + '() {};'); | ||
} catch (err) { | ||
return false; | ||
} | ||
return true; | ||
}); | ||
/** | ||
* Get the type of the given token | ||
@@ -178,2 +202,46 @@ * | ||
/** | ||
* Get the name of a function's arguments | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.8 | ||
* @version 0.3.8 | ||
* | ||
* @param {Function|String} fnc | ||
* | ||
* @return {Array} | ||
*/ | ||
Blast.defineStatic('Function', 'getArgumentNames', function getArgumentNames(fnc) { | ||
var result = [], | ||
started, | ||
tokens, | ||
token, | ||
i; | ||
tokens = Collection.Function.tokenize(fnc, true); | ||
for (i = 0; i < tokens.length; i++) { | ||
token = tokens[i]; | ||
if (!started) { | ||
if (token.type == 'parens' && token.value == '(') { | ||
started = true; | ||
} else { | ||
continue; | ||
} | ||
} else { | ||
if (token.type == 'parens' && token.value == ')') { | ||
break; | ||
} | ||
if (token.type == 'name') { | ||
result.push(token.value); | ||
} | ||
} | ||
} | ||
return result; | ||
}); | ||
/** | ||
* Function's should really have a name property, | ||
@@ -300,3 +368,3 @@ * this is not yet implemented in IE9, IE10 or IE11. | ||
* @since 0.1.0 | ||
* @version 0.3.4 | ||
* @version 0.3.8 | ||
* | ||
@@ -325,2 +393,6 @@ * @param {String} name The name to use for the wrapper | ||
if (!Collection.Function.isNameAllowed(name)) { | ||
name = '_' + name; | ||
} | ||
// Get the sourcecode | ||
@@ -362,3 +434,3 @@ sourcecode = 'function ' + name + method; | ||
* @since 0.1.0 | ||
* @version 0.3.4 | ||
* @version 0.3.8 | ||
* | ||
@@ -387,2 +459,6 @@ * @param {String} name The name to use for the wrapper | ||
if (!Collection.Function.isNameAllowed(name)) { | ||
name = '_' + name; | ||
} | ||
// Get the sourcecode | ||
@@ -389,0 +465,0 @@ sourcecode = 'function ' + name + unmethod; |
@@ -634,2 +634,3 @@ module.exports = function BlastInit(modifyPrototype) { | ||
'date_format', | ||
'weakmap', | ||
'function_flow', | ||
@@ -825,2 +826,5 @@ 'function_inheritance', | ||
// Make sure WeakMap is available first! | ||
require('./weakmap.js')(Blast, Collection); | ||
// Load the inheritance methods | ||
@@ -854,3 +858,3 @@ require('./function_inheritance.js')(Blast, Collection); | ||
// Now create bound methods, which are about 0,000129 ms slower | ||
Collection.Object.each(Collection, function(StaticClass, className) { | ||
Collection.Object.each(Collection, function eachCollection(StaticClass, className) { | ||
@@ -863,3 +867,3 @@ // Make sure the bound collection object exists | ||
// Add all the static functions as-is | ||
Collection.Object.each(StaticClass, function(StaticFunction, functionName) { | ||
Collection.Object.each(StaticClass, function eachClass(StaticFunction, functionName) { | ||
Blast.Bound[className][functionName] = StaticFunction; | ||
@@ -869,3 +873,3 @@ }); | ||
// Add all the prototype functions (if no static version exists already) | ||
Collection.Object.each(StaticClass.prototype, function(PrototypeFunction, functionName) { | ||
Collection.Object.each(StaticClass.prototype, function eachProperty(PrototypeFunction, functionName) { | ||
@@ -872,0 +876,0 @@ // If there is a static function with the same name, |
@@ -96,3 +96,3 @@ /** | ||
* @since 0.1.4 | ||
* @version 0.3.3 | ||
* @version 0.3.8 | ||
* | ||
@@ -176,3 +176,5 @@ * @return {Function} | ||
case 'function': | ||
return; | ||
if (!driers.Function) { | ||
return; | ||
} | ||
@@ -385,3 +387,3 @@ case 'object': | ||
* @since 0.1.4 | ||
* @version 0.2.0 | ||
* @version 0.3.8 | ||
* | ||
@@ -404,3 +406,3 @@ * @return {Function} | ||
} | ||
} else if (value && valType == 'object' && value.dry != null) { | ||
} else if (value && value.dry != null) { | ||
@@ -621,3 +623,3 @@ switch (value.dry) { | ||
* @since 0.1.6 | ||
* @version 0.3.2 | ||
* @version 0.3.8 | ||
* | ||
@@ -634,2 +636,3 @@ * @param {Object} obj | ||
var custom_args, | ||
entry_type, | ||
nameType, | ||
@@ -675,5 +678,10 @@ entry, | ||
entry = obj[keys[i]]; | ||
entry_type = typeof entry; | ||
if (entry && typeof entry == 'object') { | ||
if (entry && (entry_type == 'object' || entry_type == 'function')) { | ||
if (entry_type == 'function' && !driers.Function) { | ||
continue; | ||
} | ||
// If this has been cloned before, use that | ||
@@ -680,0 +688,0 @@ if (wm.has(entry)) { |
@@ -153,3 +153,5 @@ module.exports = function BlastMath(Blast, Collection) { | ||
/** | ||
* Standardize the numbers | ||
* Standardize the numbers: | ||
* Calculate (in units of standard deviation) how far | ||
* each value is below or above the mean. | ||
* | ||
@@ -177,3 +179,5 @@ * @author Jelle De Loecker <jelle@develry.be> | ||
numbers = new Array(arguments.length); | ||
for (i = 0; i < numbers.length; i++) numbers[i] = arguments[i]; | ||
for (i = 0; i < numbers.length; i++) { | ||
numbers[i] = arguments[i]; | ||
} | ||
} | ||
@@ -719,5 +723,5 @@ | ||
* | ||
* @author Jelle De Loecker <jelle@kipdola.be> | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.1 | ||
* @version 0.3.1 | ||
* @version 0.3.8 | ||
* | ||
@@ -736,2 +740,4 @@ * @param {Array} arr The input array | ||
values, | ||
length, | ||
index, | ||
iqr, | ||
@@ -743,2 +749,5 @@ q1, | ||
// Get the length of the input array | ||
length = arr.length; | ||
// Clone the array to determine max and min values | ||
@@ -753,11 +762,24 @@ values = arr.slice(0); | ||
/* Then find a generous IQR. This is generous because if (values.length / 4) | ||
* is not an int, then really you should average the two elements on either | ||
* side to find q1. | ||
*/ | ||
q1 = values[Math.floor((values.length / 4))]; | ||
// Get the first index | ||
index = length / 4; | ||
// Likewise for q3. | ||
q3 = values[Math.ceil((values.length * (3 / 4)))]; | ||
// If it's not an integer, we need to do some averaging | ||
if (~~index != index) { | ||
index = ~~index; | ||
q1 = (values[index] + values[index + 1]) / 2; | ||
} else { | ||
q1 = values[index]; | ||
} | ||
// Get the next index | ||
index = length * (3 / 4); | ||
// If it's not an integer, we need to do some averaging | ||
if (~~index != index) { | ||
index = ~~index; | ||
q3 = (values[index] + values[index - 1]) / 2; | ||
} else { | ||
q3 = values[index]; | ||
} | ||
iqr = q3 - q1; | ||
@@ -769,3 +791,3 @@ | ||
for (i = 0; i < arr.length; i++) { | ||
for (i = 0; i < length; i++) { | ||
x = arr[i]; | ||
@@ -772,0 +794,0 @@ |
@@ -144,2 +144,22 @@ module.exports = function BlastNumber(Blast, Collection) { | ||
/** | ||
* Determine if something is numeric | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.8 | ||
* @version 0.3.8 | ||
* | ||
* @param {Mixed} input | ||
* | ||
* @return {Boolean} | ||
*/ | ||
Blast.defineStatic('Number', 'isNumeric', function isNumeric(input) { | ||
if (typeof input == 'number') { | ||
return true; | ||
} | ||
return !isNaN(parseFloat(input)) && isFinite(input); | ||
}); | ||
/** | ||
* Return a string representing the source code of the number. | ||
@@ -146,0 +166,0 @@ * |
@@ -993,8 +993,10 @@ module.exports = function BlastObject(Blast, Collection) { | ||
* @since 0.1.6 | ||
* @version 0.2.0 | ||
* @version 0.3.8 | ||
* | ||
* @param {Object} obj | ||
* @param {Function} fnc | ||
* @param {Object} obj The object to walk over | ||
* @param {Function} fnc The function to perform on every entry | ||
* @param {Number} limit Optional recursive limit | ||
* @param {Array} seen Array to keep track of items already seen | ||
*/ | ||
Blast.defineStatic('Object', 'walk', function walk(obj, fnc, seen) { | ||
Blast.defineStatic('Object', 'walk', function walk(obj, fnc, limit, seen) { | ||
@@ -1004,2 +1006,9 @@ var key, | ||
if (typeof limit != 'number') { | ||
if (Array.isArray(limit)) { | ||
seen = limit; | ||
limit = null; | ||
} | ||
} | ||
if (!seen) { | ||
@@ -1009,2 +1018,6 @@ seen = []; | ||
if (limit == null || limit === false) { | ||
limit = Infinity; | ||
} | ||
for (key in obj) { | ||
@@ -1033,3 +1046,5 @@ | ||
// Walk this object, too | ||
walk(obj[key], fnc, seen); | ||
if (limit > 0) { | ||
walk(obj[key], fnc, limit - 1, seen); | ||
} | ||
} | ||
@@ -1036,0 +1051,0 @@ } |
@@ -532,2 +532,55 @@ module.exports = function BlastString(Blast, Collection) { | ||
/** | ||
* Split the string at the first occurence only (and append the rest) | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.8 | ||
* @version 0.3.8 | ||
* | ||
* @param {String} separator | ||
* | ||
* @return {Array} The resulting splits | ||
*/ | ||
Blast.definePrototype('String', 'splitOnce', function splitOnce(separator) { | ||
var index = this.indexOf(separator); | ||
return [ | ||
this.substr(0, index), | ||
this.substr(index+1) | ||
]; | ||
}); | ||
/** | ||
* Split the string a limited amount of times (and append the rest) | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.8 | ||
* @version 0.3.8 | ||
* | ||
* @param {String} separator | ||
* @param {Number} limit | ||
* | ||
* @return {Array} The resulting splits | ||
*/ | ||
Blast.definePrototype('String', 'splitLimit', function splitLimit(separator, limit) { | ||
var result = [], | ||
index = this.indexOf(separator), | ||
count = 0, | ||
last = 0; | ||
do { | ||
count++; | ||
result.push(this.substr(last, index-last)); | ||
last = index + 1; | ||
index = this.indexOf(separator, last); | ||
} while (index > -1 && count < limit); | ||
result.push(this.substr(last)) | ||
return result; | ||
}); | ||
/** | ||
* Remove HTML tags from the string | ||
@@ -534,0 +587,0 @@ * |
@@ -278,3 +278,3 @@ module.exports = function BlastURL(Blast, Collection) { | ||
* @since 0.1.3 | ||
* @version 0.3.6 | ||
* @version 0.3.8 | ||
* | ||
@@ -319,3 +319,4 @@ * @param {String|Object} params | ||
if (value && typeof value == 'object') { | ||
if (Array.isArray(value)) { | ||
if (Collection.Array.likeArray(value)) { | ||
for (i = 0; i < value.length; i++) { | ||
@@ -325,2 +326,6 @@ temp = params + '[' + i + ']'; | ||
} | ||
} else if (!Collection.Object.isPlainObject(value)) { | ||
// Don't iterate over non-plain objects, | ||
// like class instances | ||
Blast.Bound.URL.addQuery(this, params, String(value)); | ||
} else { | ||
@@ -327,0 +332,0 @@ for (key in value) { |
{ | ||
"name": "protoblast", | ||
"description": "Native object expansion library", | ||
"version": "0.3.7", | ||
"version": "0.3.8", | ||
"author": "Jelle De Loecker <jelle@develry.be>", | ||
@@ -15,3 +15,3 @@ "keywords": [ | ||
"repository": "skerit/protoblast", | ||
"homepage": "http://protoblast.develry.be/", | ||
"homepage": "https://protoblast.develry.be/", | ||
"license": "MIT", | ||
@@ -18,0 +18,0 @@ "scripts": { |
@@ -1,2 +0,2 @@ | ||
# ![protoblast](http://protoblast.develry.be/media/static/protoblast-small.svg?width=30) Protoblast | ||
# ![protoblast](https://protoblast.develry.be/media/static/protoblast-small.svg?width=30) Protoblast | ||
@@ -3,0 +3,0 @@ [![NPM version](http://img.shields.io/npm/v/protoblast.svg)](https://npmjs.org/package/protoblast) |
@@ -769,4 +769,65 @@ var assert = require('assert'), | ||
}); | ||
it('should allow changing the direction for multiple paths', function() { | ||
var arr = [ | ||
{a: 0, b: 1}, | ||
{a: 0, b: 3}, | ||
{a: 0, b: 2}, | ||
{a: 0, b: 0}, | ||
{a: 5, b: 1}, | ||
{a: 5, b: 0}, | ||
{a: 5, b: 2}, | ||
]; | ||
arr.sortByPath(-1, 'a', 1, 'b'); | ||
assert.equal(JSON.stringify(arr), '[{"a":5,"b":0},{"a":5,"b":1},{"a":5,"b":2},{"a":0,"b":0},{"a":0,"b":1},{"a":0,"b":2},{"a":0,"b":3}]'); | ||
}); | ||
}); | ||
describe('#findByPath(path, value)', function() { | ||
it('find the given value in the given path and return that entry', function() { | ||
var google, | ||
develry, | ||
arr, | ||
ne, | ||
fb; | ||
arr = [ | ||
null, | ||
{ | ||
name : 'facebook', | ||
link : 'http://www.facebook.com' | ||
}, | ||
1, | ||
{ | ||
name : 'google', | ||
link : 'http://www.google.be' | ||
}, | ||
false, | ||
{ | ||
name : 'deredactie', | ||
link : 'http://www.deredactie.be' | ||
}, | ||
{ | ||
name : 'develry', | ||
link : 'http://www.develry.be' | ||
} | ||
]; | ||
google = arr.findByPath('name', 'google'); | ||
develry = arr.findByPath('name', 'develry'); | ||
fb = arr.findByPath('name', 'facebook'); | ||
ne = arr.findByPath('name', 'doesnotexist'); | ||
assert.equal(google, arr[3]); | ||
assert.equal(develry, arr[6]); | ||
assert.equal(fb, arr[1]); | ||
assert.equal(ne, null); | ||
}); | ||
}); | ||
describe('#shuffle', function() { | ||
@@ -773,0 +834,0 @@ it('should randomly shuffle the array', function() { |
@@ -50,2 +50,23 @@ var assert = require('assert'), | ||
describe('.isNameAllowed(name)', function() { | ||
it('should return true for allowed names', function() { | ||
assert.equal(Function.isNameAllowed('zever'), true); | ||
assert.equal(Function.isNameAllowed('jelle'), true); | ||
}); | ||
it('should return false for reserved names', function() { | ||
assert.equal(Function.isNameAllowed('delete'), false); | ||
assert.equal(Function.isNameAllowed('continue'), false); | ||
assert.equal(Function.isNameAllowed('new'), false); | ||
assert.equal(Function.isNameAllowed('typeof'), false); | ||
}); | ||
it('should return false for names starting with numbers', function() { | ||
assert.equal(Function.isNameAllowed('3delete'), false); | ||
assert.equal(Function.isNameAllowed('3continue'), false); | ||
assert.equal(Function.isNameAllowed('3new'), false); | ||
assert.equal(Function.isNameAllowed('3typeof'), false); | ||
}); | ||
}); | ||
describe('#methodize()', function() { | ||
@@ -52,0 +73,0 @@ it('should create a new function that calls the given function with current "this" context as the first argument', function() { |
202
test/json.js
@@ -105,3 +105,3 @@ var assert = require('assert'), | ||
fnc = function test() {}, | ||
obj = {a: fnc, b: 1} | ||
obj = {a: fnc, b: 1}; | ||
@@ -115,2 +115,98 @@ dried = JSON.dry(obj); | ||
}); | ||
it('should use formatting spaces if given', function() { | ||
var expected, | ||
nr_dried, | ||
undried, | ||
dried, | ||
obj; | ||
obj = { | ||
a: [{b: 1}], | ||
c: {d: 1} | ||
}; | ||
expected = '{\n "a": [\n {\n "b": 1\n }\n ],\n "c": {\n "d": 1\n }\n}'; | ||
dried = JSON.dry(obj, null, ' '); | ||
nr_dried = JSON.dry(obj, null, 2); | ||
undried = JSON.undry(dried); | ||
assert.equal(dried, expected); | ||
assert.equal(nr_dried, expected); | ||
assert.equal(undried.c.d, obj.c.d); | ||
assert.equal(undried.a[0].b, obj.a[0].b); | ||
}); | ||
it('should handle Infinity', function() { | ||
var undried, | ||
dried, | ||
obj; | ||
obj = { | ||
a : 1, | ||
b : Infinity, | ||
c : -Infinity | ||
}; | ||
dried = JSON.dry(obj); | ||
undried = JSON.undry(dried); | ||
assert.equal(undried.a, 1); | ||
assert.equal(undried.b, Infinity); | ||
assert.equal(undried.c, -Infinity); | ||
}); | ||
it('should handle RegExp', function() { | ||
var undried, | ||
dried, | ||
obj; | ||
obj = { | ||
regex : /test/i | ||
}; | ||
dried = JSON.dry(obj); | ||
undried = JSON.undry(dried); | ||
assert.equal(undried.regex.constructor.name, 'RegExp'); | ||
assert.equal(undried.regex+'', '/test/i'); | ||
obj = /rooted/i; | ||
dried = JSON.dry(obj); | ||
undried = JSON.undry(dried); | ||
assert.equal(undried.constructor.name, 'RegExp'); | ||
assert.equal(undried+'', '/rooted/i'); | ||
}); | ||
it('should handle dates', function() { | ||
var undried, | ||
dried, | ||
obj; | ||
obj = { | ||
date : new Date() | ||
}; | ||
dried = JSON.dry(obj); | ||
undried = JSON.undry(dried); | ||
assert.equal(undried.date.constructor.name, 'Date'); | ||
assert.equal(undried.date+'', obj.date+''); | ||
obj = obj.date; | ||
dried = JSON.dry(obj); | ||
undried = JSON.undry(dried); | ||
assert.equal(undried.constructor.name, 'Date'); | ||
assert.equal(undried+'', obj+''); | ||
}); | ||
}); | ||
@@ -228,2 +324,106 @@ | ||
describe('.clone()', function() { | ||
it('should deep clone objects', function() { | ||
var original, | ||
clone; | ||
original = { | ||
date : new Date(), | ||
nr : 1, | ||
arr : [null], | ||
regex : /test/i | ||
}; | ||
original.circle = original; | ||
clone = JSON.clone(original); | ||
assert.equal(clone.date.constructor.name, 'Date'); | ||
assert.equal(clone.date+'', original.date+''); | ||
assert.equal(clone.nr, original.nr); | ||
assert.equal(clone.arr[0], original.arr[0]); | ||
assert.equal(clone.regex.constructor.name, 'RegExp'); | ||
assert.equal(clone.circle, clone); | ||
}); | ||
it('should use a clone method if it is available on the target', function() { | ||
var original, | ||
clone; | ||
original = { | ||
clone: function() { | ||
return 1; | ||
} | ||
}; | ||
clone = JSON.clone(original); | ||
assert.equal(clone, 1); | ||
}); | ||
}); | ||
describe('.registerDrier()', function() { | ||
it('should allow the use of custom drier logic', function() { | ||
var instance, | ||
undried, | ||
dried; | ||
JSON.registerDrier('CustomDrierTestClass', function dryTest(holder, key, value) { | ||
return {zever: 'notbla'}; | ||
}, {add_path: false}); | ||
instance = new CustomDrierTestClass(); | ||
dried = JSON.dry(instance); | ||
undried = JSON.undry(dried); | ||
assert.equal(undried.zever, 'notbla'); | ||
function CustomDrierTestClass() { | ||
this.zever = 'bla'; | ||
} | ||
}); | ||
it('should also be used for clones', function() { | ||
var instance, | ||
clone; | ||
JSON.registerDrier('CustomDrierTestClass', function dryTest(holder, key, value) { | ||
return {zever: 'notbla'}; | ||
}, {add_path: false}); | ||
instance = new CustomDrierTestClass(); | ||
clone = JSON.clone(instance); | ||
assert.equal(clone.zever, 'notbla'); | ||
function CustomDrierTestClass() { | ||
this.zever = 'bla'; | ||
} | ||
}); | ||
}); | ||
describe('.safeParse()', function() { | ||
it('should parse json without throwing errors', function() { | ||
var one, | ||
two; | ||
one = JSON.safeParse('{"a":1}'); | ||
two = JSON.safeParse('{broken:broken}'); | ||
assert.equal(one.a, 1); | ||
assert.equal(two, null); | ||
}); | ||
}); | ||
}); |
@@ -57,2 +57,31 @@ var assert = require('assert'), | ||
describe('.standardize(numbers)', function() { | ||
it('should return the standardized values of the input', function() { | ||
var output, | ||
input; | ||
// Prepare the input values | ||
input = [0, 1, 3]; | ||
// Get the standardized output | ||
output = Math.standardize(input); | ||
assert.equal(Math.mean(output), 0, 'The mean value of standardized values should always be 0'); | ||
// The standardDeviation of standardized values should be 1, | ||
// but these examples give 0.999... That's just a floating point rounding error thing | ||
}); | ||
it('should use the arguments', function() { | ||
var output; | ||
// Get the standardized output | ||
output = Math.standardize(0, 1, 3); | ||
assert.equal(Math.mean(output), 0, 'The mean value of standardized values should always be 0'); | ||
}); | ||
}); | ||
describe('.lowest(numbers, amount)', function() { | ||
@@ -154,2 +183,31 @@ | ||
describe('.interpolate(numbers, newlength)', function() { | ||
it('should interpolate missing numbers', function() { | ||
var input = [0, 10], | ||
three = Math.interpolate(input, 3), | ||
five = Math.interpolate(input, 5); | ||
assert.equal(three.join(','), '0,5,10'); | ||
assert.equal(five.join(','), '0,2.5,5,7.5,10'); | ||
}); | ||
}); | ||
describe('.removeOutliers(numbers, clip)', function() { | ||
it('should remove outliers', function() { | ||
var numbers = [99, 2, 4, 5, 7, 1], | ||
output = Math.removeOutliers(numbers); | ||
assert.equal(output.join(','), '2,4,5,7,1'); | ||
}); | ||
it('should clip outliers to their highest allowed value', function() { | ||
var numbers = [99, 2, 4, 5, 7, 1], | ||
output = Math.removeOutliers(numbers, true); | ||
assert.equal(output.join(','), '10.5,2,4,5,7,1'); | ||
}); | ||
}); | ||
}); |
@@ -65,2 +65,19 @@ var assert = require('assert'), | ||
describe('.isNumeric(input)', function() { | ||
it('should return true for numerical strings', function() { | ||
assert.equal(Number.isNumeric('1'), true); | ||
assert.equal(Number.isNumeric('10'), true); | ||
assert.equal(Number.isNumeric('0xFF'), true); | ||
assert.equal(Number.isNumeric('10.5'), true); | ||
assert.equal(Number.isNumeric(' 10'), true); | ||
}); | ||
it('should return false for non numerical strings, or containing text', function() { | ||
assert.equal(Number.isNumeric('1a'), false); | ||
assert.equal(Number.isNumeric('46.3a'), false); | ||
assert.equal(Number.isNumeric('text'), false); | ||
}); | ||
}); | ||
describe('#toSource()', function() { | ||
@@ -67,0 +84,0 @@ it('should return the source code representation of the number', function() { |
@@ -10,2 +10,49 @@ var assert = require('assert'), | ||
describe('.serializeAttributes(obj)', function() { | ||
it('should return serialized attributes as a string', function() { | ||
var output, | ||
obj; | ||
obj = { | ||
a : 1, | ||
b : 2 | ||
}; | ||
output = String.serializeAttributes(obj); | ||
assert.equal(output, 'a="1" b="2"'); | ||
}); | ||
}); | ||
describe('.decodeAttributes(value, separator)', function() { | ||
it('should return an object', function() { | ||
var input = 'a="1", b="2"', | ||
obj; | ||
obj = String.decodeAttributes(input); | ||
assert.equal(JSON.stringify(obj), '{"a":"1","b":"2"}'); | ||
}); | ||
it('should allow another separator', function() { | ||
var input = 'a="1"; b="2"', | ||
obj; | ||
obj = String.decodeAttributes(input, ';'); | ||
assert.equal(JSON.stringify(obj), '{"a":"1","b":"2"}'); | ||
}); | ||
}); | ||
describe('.encodeCookie(name, value, options)', function() { | ||
it('should return a valid cookie string', function() { | ||
var output = String.encodeCookie('cookiename', 'myvalue', {path: '/mypath'}); | ||
assert.equal(output, 'cookiename=myvalue; path=/mypath'); | ||
}); | ||
}); | ||
describe('#toSource()', function() { | ||
@@ -12,0 +59,0 @@ it('should return the source code representation of the string', function() { |
@@ -14,13 +14,13 @@ var assert = require('assert'), | ||
var simple = URL.parse('/test'), | ||
hard = URL.parse('http://www.codedor.be:8080/page?page=1&filter=test'); | ||
hard = URL.parse('http://www.develry.be:8080/page?page=1&filter=test'); | ||
assert.equal('/test', simple.pathname); | ||
assert.equal(simple.pathname, '/test'); | ||
assert.equal('/page', hard.pathname); | ||
assert.equal('www.codedor.be:8080', hard.host); | ||
assert.equal('8080', hard.port); | ||
assert.equal('http:', hard.protocol); | ||
assert.equal('?page=1&filter=test', hard.search); | ||
assert.equal('www.codedor.be', hard.hostname); | ||
assert.equal('http://www.codedor.be', hard.origin); | ||
assert.equal(hard.pathname, '/page'); | ||
assert.equal(hard.host, 'www.develry.be:8080'); | ||
assert.equal(hard.port, '8080'); | ||
assert.equal(hard.protocol, 'http:'); | ||
assert.equal(hard.search, '?page=1&filter=test'); | ||
assert.equal(hard.hostname, 'www.develry.be'); | ||
assert.equal(hard.origin, 'http://www.develry.be'); | ||
}); | ||
@@ -33,19 +33,58 @@ }); | ||
var ori = URL.parse('http://www.codedor.be/test'), | ||
var ori = URL.parse('http://www.develry.be/test'), | ||
clone = ori.clone(); | ||
assert.equal('http://www.codedor.be/test', ori+''); | ||
assert.equal('http://www.codedor.be/test', clone+''); | ||
assert.equal(ori+'', 'http://www.develry.be/test'); | ||
assert.equal(clone+'', 'http://www.develry.be/test'); | ||
ori.addQuery('param', 'A'); | ||
assert.equal('http://www.codedor.be/test?param=A', ori+''); | ||
assert.equal('http://www.codedor.be/test', clone+''); | ||
assert.equal(ori+'', 'http://www.develry.be/test?param=A'); | ||
assert.equal(clone+'', 'http://www.develry.be/test'); | ||
clone.addQuery('param', 'CLONE'); | ||
assert.equal('http://www.codedor.be/test?param=A', ori+''); | ||
assert.equal('http://www.codedor.be/test?param=CLONE', clone+''); | ||
assert.equal(ori+'', 'http://www.develry.be/test?param=A'); | ||
assert.equal(clone+'', 'http://www.develry.be/test?param=CLONE'); | ||
}); | ||
}); | ||
describe('#addQuery(name, value)', function() { | ||
it('should add the value to the url', function() { | ||
var ori = URL.parse('http://www.develry.be'); | ||
ori.addQuery('name', 'value'); | ||
assert.equal(String(ori), 'http://www.develry.be/?name=value'); | ||
}); | ||
it('should overwrite the value if it already exists', function() { | ||
var ori = URL.parse('http://www.develry.be'); | ||
ori.addQuery('name', 'value'); | ||
ori.addQuery('name', 'newvalue'); | ||
assert.equal(String(ori), 'http://www.develry.be/?name=newvalue'); | ||
}); | ||
it('should add multiple values if it is an array', function() { | ||
var ori = URL.parse('http://www.develry.be'); | ||
ori.addQuery('name', ['one', 'two']); | ||
assert.equal(String(ori), 'http://www.develry.be/?name%5B0%5D=one&name%5B1%5D=two'); | ||
}); | ||
it('should delete values when null is given', function() { | ||
var ori = URL.parse('http://www.develry.be/?name=ok'); | ||
ori.addQuery('name', null); | ||
assert.equal(String(ori), 'http://www.develry.be/'); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
649771
83
20547