protoblast
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -0,1 +1,13 @@ | ||
## 0.3.0 (2016-06-22) | ||
* Added `Informer#unsee` method, so 'after' and such can be reset | ||
* Added `Number#bitAt` method, to return the bit at the specified position | ||
* `Array#clip` 'highest' value is now optional | ||
* `Array#employ` has been removed | ||
* `Function.benchmark` will now calculate overhead based on self-created dummies | ||
* If another Protoblast instance is detected during loading, it will only be | ||
returned if the major & minor version is the same and the patch is higher. | ||
Otherwise, a new instance is created. This is only the case in the | ||
non-global-modifying mode. | ||
## 0.2.1 (2016-06-06) | ||
@@ -2,0 +14,0 @@ |
162
lib/array.js
@@ -425,3 +425,3 @@ module.exports = function BlastArray(Blast, Collection) { | ||
* @since 0.1.3 | ||
* @version 0.1.3 | ||
* @version 0.3.0 | ||
* | ||
@@ -438,6 +438,19 @@ * @param {Number} lowest The lowest allowed value | ||
// If no lowest is given, infinity is allowed | ||
if (lowest == null) { | ||
lowest = -Infinity; | ||
} | ||
// If no highest is given, infinity is allowed | ||
if (highest == null) { | ||
highest = +Infinity; | ||
} | ||
// Iterate over all the elements in the array | ||
for (i = 0; i < length; i++) { | ||
if (!(lowest < this[i])) { | ||
// Value is too low | ||
this[i] = lowest; | ||
} else if (!(highest > this[i])) { | ||
// Value is too high | ||
this[i] = highest; | ||
@@ -753,150 +766,3 @@ } | ||
var reEmployArgs = /^(?:\$(\d+))|(?:(\$i))|(?:(\$\$\+))|(?:(\$\$\-))|(?:(\$\$))$/; | ||
/** | ||
* Apply the given `fnc` function with the `args` array, | ||
* but `forEach` value that is in `this` array. | ||
* | ||
* Arg substitution is: | ||
* - $0, $1, ... for values in the current element (All is cast to array) | ||
* - $$ for the complete, un-cast value | ||
* - $i for the current index | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.1.4 | ||
* @version 0.1.4 | ||
* | ||
* @param {Array} args The args to apply to the function | ||
* @param {Object} _obj The context to get the function from | ||
* @param {String|Function} _fnc The function to use (or string) | ||
* | ||
* @return {Array} | ||
*/ | ||
Blast.definePrototype('Array', 'employ', function employ(args, _obj, _fnc) { | ||
var arrayLength, | ||
argsLength, | ||
context, | ||
result, | ||
cargs, | ||
temp, | ||
key, | ||
map, | ||
fnc, | ||
el, | ||
i; | ||
// Make sure the args is an array | ||
args = Collection.Array.cast(args); | ||
arrayLength = this.length; | ||
argsLength = args.length; | ||
map = {}; | ||
// Passed functions with no context will get called using null | ||
if (typeof _obj === 'function') { | ||
fnc = _obj; | ||
context = null; | ||
} else { | ||
// Passed objects become the calling context | ||
context = _obj; | ||
// If the last arg is a string, we need to get that function | ||
// from the passed context | ||
if (typeof _fnc === 'string') { | ||
fnc = context[_fnc]; | ||
} else { | ||
fnc = _fnc; | ||
} | ||
} | ||
// Create a new array that will be returned as the result | ||
result = new Array(arrayLength); | ||
// See where we can substitute arguments | ||
for (i = 0; i < argsLength; i++) { | ||
if (typeof args[i] !== 'string') { | ||
continue; | ||
} | ||
// Look for string arg replacement tokens | ||
temp = reEmployArgs.exec(args[i]); | ||
if (!temp) { | ||
continue; | ||
} | ||
if (temp[1]) { | ||
// Map the argument number `i` to the number `temp[1]` inside array | ||
map[i] = parseInt(temp[1]); | ||
} else { | ||
map[i] = temp[0]; | ||
} | ||
} | ||
for (i = 0; i < arrayLength; i++) { | ||
// Always create a shallow clone of the args array | ||
cargs = args.slice(0); | ||
// Replace all the placeholders | ||
for (key in map) { | ||
if (typeof map[key] == 'string') { | ||
switch (map[key]) { | ||
// The entire element, non-cast | ||
case '$$': | ||
cargs[key] = this[i]; | ||
break; | ||
// The previous element | ||
case '$$-': | ||
cargs[key] = this[i-1]; | ||
break; | ||
// The next element | ||
case '$$+': | ||
cargs[key] = this[i+1]; | ||
break; | ||
// The index | ||
case '$i': | ||
cargs[key] = i; | ||
break; | ||
} | ||
} else { | ||
// Get the current element | ||
el = Collection.Array.cast(this[i]); | ||
cargs[key] = el[map[key]]; | ||
} | ||
} | ||
// Call the actual function, try to use call when possible | ||
switch (argsLength) { | ||
case 1: | ||
result[i] = fnc.call(context, cargs[0]); | ||
break; | ||
case 2: | ||
result[i] = fnc.call(context, cargs[0], cargs[1]); | ||
break; | ||
case 3: | ||
result[i] = fnc.call(context, cargs[0], cargs[1], cargs[2]); | ||
break; | ||
default: | ||
result[i] = fnc.apply(context, cargs); | ||
} | ||
} | ||
return result; | ||
}); | ||
/** | ||
* Get all the values that are either in the first or in the second array, | ||
@@ -903,0 +769,0 @@ * but not in both |
@@ -95,3 +95,3 @@ module.exports = function BlastBenchmark(Blast, Collection) { | ||
* @since 0.1.2 | ||
* @version 0.1.2 | ||
* @version 0.3.0 | ||
* | ||
@@ -102,3 +102,3 @@ * @param {Number} runs | ||
var dummy = Collection.Function.dummy, | ||
var dummy = Function(), | ||
start, | ||
@@ -108,3 +108,3 @@ i; | ||
// Call dummy now to get it jitted | ||
Collection.Function.dummy(); | ||
dummy(); | ||
@@ -161,2 +161,3 @@ start = Blast.performanceNow(); | ||
// Actually execute the function "shard" amount of times | ||
for (i = 0; i < shard; i++) { | ||
@@ -233,5 +234,6 @@ fn(); | ||
// Calculate how many times to do the test | ||
shard = 1 + ~~((testruns/300)*sizes[r]); | ||
Collection.Function.doAmount(shard, fn, function(err, runs, elapsed) { | ||
Collection.Function.doAmount(shard, fn, function done(err, runs, elapsed) { | ||
elapsed = elapsed - (shard * (asyncOverhead/testruns)); | ||
@@ -369,3 +371,3 @@ samples.push(~~((shard/elapsed)*1000)); | ||
Blast.getEventLatencyBaseline(function(err, median) { | ||
asyncTest(fn, runs, median+(getFunctionOverhead(runs)*8), function(err, result) { | ||
asyncTest(fn, runs, median+(getFunctionOverhead(runs)*8), function asyncDone(err, result) { | ||
@@ -372,0 +374,0 @@ var next, |
@@ -20,6 +20,5 @@ module.exports = function BlastFunctionFlow(Blast, Collection) { | ||
* @since 0.1.2 | ||
* @version 0.1.2 | ||
* @version 0.3.0 | ||
*/ | ||
function dummy() {}; | ||
Blast.defineStatic('Function', 'dummy', dummy); | ||
Blast.defineStatic('Function', 'dummy', Function()); | ||
@@ -26,0 +25,0 @@ /** |
@@ -604,2 +604,17 @@ module.exports = function BlastInformer(Blast, Collection) { | ||
/** | ||
* Unsee an event type | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.0 | ||
* @version 0.3.0 | ||
* | ||
* @param {String} type | ||
*/ | ||
Informer.setMethod(function unsee(type) { | ||
if (this.simpleSeen[type]) { | ||
this.simpleSeen[type] = false; | ||
} | ||
}); | ||
/** | ||
* Look for all the functions that listen to the given type/filter | ||
@@ -606,0 +621,0 @@ * |
@@ -5,5 +5,9 @@ module.exports = function BlastInit(modifyPrototype) { | ||
Collection, | ||
other_ver, | ||
package, | ||
Globals, | ||
version, | ||
Names, | ||
Blast, | ||
temp, | ||
key; | ||
@@ -14,6 +18,2 @@ | ||
// Get the debug environment variable | ||
// This is not meant to debug protoblast | ||
Blast.DEBUG = !!process.env.DEBUG; | ||
// Is it a pure, regular browser? | ||
@@ -64,2 +64,27 @@ Blast.isBrowser = false; | ||
// Get the debug environment variable | ||
// This is not meant to debug protoblast | ||
if (typeof process != 'undefined') { | ||
Blast.DEBUG = !!process.env.DEBUG; | ||
} else { | ||
Blast.DEBUG = !!Blast.Globals.DEBUG; | ||
} | ||
// Get version information of this protoblast instance | ||
if (Blast.isNode) { | ||
package = require(__dirname + '/../package.json'); | ||
// Split the version | ||
temp = package.version.split('.'); | ||
// Interpret the numbers | ||
version = { | ||
major : parseInt(temp[0]), | ||
minor : parseInt(temp[1]), | ||
patch : parseInt(temp[2]) | ||
}; | ||
Blast.version = version; | ||
} | ||
// Maybe we can return an existing protoblast collection | ||
@@ -69,3 +94,19 @@ if (Globals.__Protoblast) { | ||
if (!modifyPrototype || (modifyPrototype && Globals.__Protoblast.modifyPrototype)) { | ||
return Globals.__Protoblast; | ||
// See if the versions match on node.js | ||
if (Blast.isNode) { | ||
// Get the other version info | ||
other_ver = Globals.__Protoblast.version; | ||
// See if we can use the earlier loaded protoblast instance | ||
if (other_ver && other_ver.major == version.major && other_ver.minor == version.minor) { | ||
// If the earlier loaded protoblast instance has a higher patch, we can safely use that | ||
if (other_ver.patch > version.patch) { | ||
return Globals.__Protoblast; | ||
} | ||
} | ||
} else { | ||
return Globals.__Protoblast; | ||
} | ||
} else { | ||
@@ -82,3 +123,6 @@ Blast = Globals.__Protoblast; | ||
Globals.__Protoblast = Blast; | ||
// Don't overwrite another protoblast instance | ||
if (!other_ver) { | ||
Globals.__Protoblast = Blast; | ||
} | ||
@@ -85,0 +129,0 @@ Names = [ |
@@ -215,2 +215,16 @@ module.exports = function BlastNumber(Blast, Collection) { | ||
/** | ||
* Return the bit at the specified position | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.3.0 | ||
* @version 0.3.0 | ||
* | ||
* @param {Number} position Which bit to get | ||
* | ||
* @return {Number} | ||
*/ | ||
Blast.definePrototype('Number', 'bitAt', function bitAt(position) { | ||
return Number((this >> position) % 2 != 0); | ||
}); | ||
}; |
{ | ||
"name": "protoblast", | ||
"description": "Add useful methods to native objects", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"author": "Jelle De Loecker <jelle@develry.be>", | ||
@@ -20,2 +20,3 @@ "keywords": [ | ||
}, | ||
"main": "lib/init.js", | ||
"devDependencies": { | ||
@@ -22,0 +23,0 @@ "browserify": "5.11.0", |
@@ -6,2 +6,5 @@ var assert = require('assert'), | ||
var empty_array = [], | ||
full_array = [0, 1, 2]; | ||
before(function() { | ||
@@ -11,2 +14,23 @@ Blast = require('../index.js')(); | ||
describe('.likeArray(variable)', function() { | ||
it('should return true if it is an array', function() { | ||
assert.equal(true, Array.likeArray(empty_array)); | ||
}); | ||
it('should return true if it is an arguments object', function() { | ||
assert.equal(true, Array.likeArray(arguments)); | ||
}); | ||
it('should return true if it is an array-like object', function(){ | ||
assert.equal(true, Array.likeArray({length: 1})); | ||
}); | ||
it('should return false if it is not an array-like object', function() { | ||
assert.equal(false, Array.likeArray(null)); | ||
assert.equal(false, Array.likeArray({})); | ||
assert.equal(false, Array.likeArray(true)); | ||
assert.equal(false, Array.likeArray('string')); | ||
}); | ||
}); | ||
describe('.cast(variable)', function() { | ||
@@ -340,2 +364,11 @@ it('should return an array parameter without modifying it', function() { | ||
}); | ||
it('should allow negative new indexes', function() { | ||
var arr = [0, 1, 2, 3]; | ||
arr.move(1, -1); | ||
assert.equal(arr.join(','), '0,2,3,1'); | ||
}); | ||
}); | ||
@@ -421,2 +454,18 @@ | ||
describe('#clip(lowest, highest)', function() { | ||
it('should clip lowest values', function() { | ||
var arr = [0, 2, 55, 3, 76]; | ||
arr.clip(3); | ||
assert.equal(arr.join(','), '3,3,55,3,76'); | ||
}); | ||
it('should clip highest values', function() { | ||
var arr = [0, 2, 55, 78, 64]; | ||
arr.clip(null, 55); | ||
assert.equal(arr.join(','), '0,2,55,55,55'); | ||
}); | ||
}); | ||
describe('#closest(goal)', function() { | ||
@@ -629,16 +678,2 @@ it('should return the closest value in the array', function() { | ||
describe('#employ(args, obj, function)', function() { | ||
it('apply the given function', function() { | ||
var args = [[1, 'a'], [2, 'b'], [3, 'c']], | ||
result = ''; | ||
args.employ(['$1', '$0'], function(character, number) { | ||
result += character + number; | ||
}); | ||
assert.equal(result, 'a1b2c3'); | ||
}); | ||
}); | ||
describe('#exclusive(secondArray)', function() { | ||
@@ -695,5 +730,20 @@ it('return all the values that are in the first array or in the second array, but not in both', function() { | ||
assert.equal('[{"a":3},{"a":2},{"a":1},{"a":0}]', JSON.stringify(arr)); | ||
assert.equal(JSON.stringify(arr), '[{"a":3},{"a":2},{"a":1},{"a":0}]'); | ||
}); | ||
it('should be stable', function() { | ||
var arr = [ | ||
{a: 3}, | ||
{a: 1, s: 0}, | ||
{a: 1, s: 1}, | ||
{a: 0} | ||
]; | ||
arr.sortByPath('a'); | ||
assert.equal(JSON.stringify(arr), '[{"a":3},{"a":1,"s":0},{"a":1,"s":1},{"a":0}]'); | ||
}); | ||
it('should reverse the sort', function() { | ||
@@ -709,3 +759,3 @@ var arr = [ | ||
assert.equal('[{"a":0},{"a":1},{"a":2},{"a":3}]', JSON.stringify(arr)); | ||
assert.equal(JSON.stringify(arr), '[{"a":0},{"a":1},{"a":2},{"a":3}]'); | ||
}); | ||
@@ -724,3 +774,3 @@ | ||
assert.equal('[{"a":5,"b":1},{"a":5,"b":0},{"a":0,"b":1},{"a":0,"b":0}]', JSON.stringify(arr)); | ||
assert.equal(JSON.stringify(arr), '[{"a":5,"b":1},{"a":5,"b":0},{"a":0,"b":1},{"a":0,"b":0}]'); | ||
}); | ||
@@ -727,0 +777,0 @@ }); |
@@ -37,3 +37,67 @@ var assert = require('assert'), | ||
}); | ||
it('should allow benchmarks without named functions', function() { | ||
var old = console.log, | ||
captured; | ||
console.log = function(message) { | ||
captured = message; | ||
} | ||
var result = Function.benchmark(function() { | ||
'test'.indexOf('t'); | ||
}); | ||
console.log = old; | ||
assert.equal(result.iterations > 1, true); | ||
assert.equal(result.max > 1, true); | ||
assert.equal(result.ops > 1, true); | ||
assert.equal(result.median > 1, true); | ||
assert.equal(result.mean > 1, true); | ||
assert.equal(isFinite(result.deviation), true); | ||
assert.equal(isFinite(result.samplecount), true); | ||
assert.equal(isFinite(result.samplehit), true); | ||
assert.equal(captured.length > 0, true); | ||
assert.equal(captured.indexOf('Benchmark did') == 0, true, 'There should not be a function name'); | ||
}); | ||
it('should benchmark the given function synchronously and callback when done', function() { | ||
Function.benchmark(function indexOfTest() { | ||
'test'.indexOf('t'); | ||
}, function sync_is_done(err, result) { | ||
assert.equal(result.iterations > 1, true); | ||
assert.equal(result.max > 1, true); | ||
assert.equal(result.ops > 1, true); | ||
assert.equal(result.median > 1, true); | ||
assert.equal(result.mean > 1, true); | ||
assert.equal(isFinite(result.deviation), true); | ||
assert.equal(isFinite(result.samplecount), true); | ||
assert.equal(isFinite(result.samplehit), true); | ||
}); | ||
}); | ||
it('should benchmark the given function asynchronously', function(done) { | ||
Function.benchmark(function indexOfTest(next) { | ||
'test'.indexOf('t'); | ||
setImmediate(next); | ||
}, function test_is_done(err, result) { | ||
assert.equal(result.iterations > 1, true); | ||
assert.equal(result.max > 1, true); | ||
assert.equal(result.ops > 1, true); | ||
assert.equal(result.median > 1, true); | ||
assert.equal(result.mean > 1, true); | ||
assert.equal(isFinite(result.deviation), true); | ||
assert.equal(isFinite(result.samplecount), true); | ||
assert.equal(isFinite(result.samplehit), true); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
var assert = require('assert'), | ||
Blast; | ||
describe('Deck', function() { | ||
describe('Iterator', function() { | ||
@@ -6,0 +6,0 @@ before(function() { |
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
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
584879
18488
16