Comparing version
76
index.js
@@ -1,46 +0,62 @@ | ||
var isFunction = require('is-function') | ||
'use strict'; | ||
module.exports = forEach | ||
var isCallable = require('is-callable'); | ||
var toString = Object.prototype.toString | ||
var hasOwnProperty = Object.prototype.hasOwnProperty | ||
var toStr = Object.prototype.toString; | ||
var hasOwnProperty = Object.prototype.hasOwnProperty; | ||
function forEach(list, iterator, context) { | ||
if (!isFunction(iterator)) { | ||
throw new TypeError('iterator must be a function') | ||
} | ||
if (arguments.length < 3) { | ||
context = this | ||
} | ||
if (toString.call(list) === '[object Array]') | ||
forEachArray(list, iterator, context) | ||
else if (typeof list === 'string') | ||
forEachString(list, iterator, context) | ||
else | ||
forEachObject(list, iterator, context) | ||
} | ||
function forEachArray(array, iterator, context) { | ||
var forEachArray = function forEachArray(array, iterator, receiver) { | ||
for (var i = 0, len = array.length; i < len; i++) { | ||
if (hasOwnProperty.call(array, i)) { | ||
iterator.call(context, array[i], i, array) | ||
if (receiver == null) { | ||
iterator(array[i], i, array); | ||
} else { | ||
iterator.call(receiver, array[i], i, array); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
function forEachString(string, iterator, context) { | ||
var forEachString = function forEachString(string, iterator, receiver) { | ||
for (var i = 0, len = string.length; i < len; i++) { | ||
// no such thing as a sparse string. | ||
iterator.call(context, string.charAt(i), i, string) | ||
if (receiver == null) { | ||
iterator(string.charAt(i), i, string); | ||
} else { | ||
iterator.call(receiver, string.charAt(i), i, string); | ||
} | ||
} | ||
} | ||
}; | ||
function forEachObject(object, iterator, context) { | ||
var forEachObject = function forEachObject(object, iterator, receiver) { | ||
for (var k in object) { | ||
if (hasOwnProperty.call(object, k)) { | ||
iterator.call(context, object[k], k, object) | ||
if (receiver == null) { | ||
iterator(object[k], k, object); | ||
} else { | ||
iterator.call(receiver, object[k], k, object); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
var forEach = function forEach(list, iterator, thisArg) { | ||
if (!isCallable(iterator)) { | ||
throw new TypeError('iterator must be a function'); | ||
} | ||
var receiver; | ||
if (arguments.length >= 3) { | ||
receiver = thisArg; | ||
} | ||
if (toStr.call(list) === '[object Array]') { | ||
forEachArray(list, iterator, receiver); | ||
} else if (typeof list === 'string') { | ||
forEachString(list, iterator, receiver); | ||
} else { | ||
forEachObject(list, iterator, receiver); | ||
} | ||
}; | ||
module.exports = forEach; |
{ | ||
"name": "for-each", | ||
"version": "0.3.2", | ||
"version": "0.3.3", | ||
"description": "A better forEach", | ||
@@ -24,7 +24,11 @@ "keywords": [], | ||
"dependencies": { | ||
"is-function": "~1.0.0" | ||
"is-callable": "^1.1.3" | ||
}, | ||
"devDependencies": { | ||
"tape": "~1.1.0" | ||
"@ljharb/eslint-config": "^12.2.1", | ||
"eslint": "^4.19.1", | ||
"nsp": "^3.2.1", | ||
"tape": "^4.9.0" | ||
}, | ||
"license": "MIT", | ||
"licenses": [ | ||
@@ -37,3 +41,8 @@ { | ||
"scripts": { | ||
"test": "node test/test.js" | ||
"pretest": "npm run lint", | ||
"test": "npm run tests-only", | ||
"tests-only": "node test/test", | ||
"posttest": "npm run security", | ||
"lint": "eslint *.js test/*.js", | ||
"security": "nsp check" | ||
}, | ||
@@ -40,0 +49,0 @@ "testling": { |
240
test/test.js
@@ -1,95 +0,99 @@ | ||
var test = require("tape") | ||
, forEach = require("..") | ||
'use strict'; | ||
test("forEach calls each iterator", function (t) { | ||
var count = 0 | ||
t.plan(4) | ||
/* globals window */ | ||
var test = require('tape'); | ||
var forEach = require('../'); | ||
test('forEach calls each iterator', function (t) { | ||
var count = 0; | ||
t.plan(4); | ||
forEach({ a: 1, b: 2 }, function (value, key) { | ||
if (count === 0) { | ||
t.equal(value, 1) | ||
t.equal(key, "a") | ||
t.equal(value, 1); | ||
t.equal(key, 'a'); | ||
} else { | ||
t.equal(value, 2) | ||
t.equal(key, "b") | ||
t.equal(value, 2); | ||
t.equal(key, 'b'); | ||
} | ||
count++ | ||
}) | ||
}) | ||
count += 1; | ||
}); | ||
}); | ||
test("forEach calls iterator with correct this value", function (t) { | ||
var thisValue = {} | ||
test('forEach calls iterator with correct this value', function (t) { | ||
var thisValue = {}; | ||
t.plan(1) | ||
t.plan(1); | ||
forEach([0], function () { | ||
t.equal(this, thisValue) | ||
}, thisValue) | ||
}) | ||
t.equal(this, thisValue); | ||
}, thisValue); | ||
}); | ||
test('second argument: iterator', function (t) { | ||
var arr = [] | ||
t.throws(function () { forEach(arr) }, TypeError, 'undefined is not a function') | ||
t.throws(function () { forEach(arr, null) }, TypeError, 'null is not a function') | ||
t.throws(function () { forEach(arr, '') }, TypeError, 'string is not a function') | ||
t.throws(function () { forEach(arr, /a/) }, TypeError, 'regex is not a function') | ||
t.throws(function () { forEach(arr, true) }, TypeError, 'true is not a function') | ||
t.throws(function () { forEach(arr, false) }, TypeError, 'false is not a function') | ||
t.throws(function () { forEach(arr, NaN) }, TypeError, 'NaN is not a function') | ||
t.throws(function () { forEach(arr, 42) }, TypeError, '42 is not a function') | ||
t.doesNotThrow(function () { forEach(arr, function () {}) }, 'function is a function') | ||
t.doesNotThrow(function () { forEach(arr, setTimeout) }, 'setTimeout is a function') | ||
var arr = []; | ||
t['throws'](function () { forEach(arr); }, TypeError, 'undefined is not a function'); | ||
t['throws'](function () { forEach(arr, null); }, TypeError, 'null is not a function'); | ||
t['throws'](function () { forEach(arr, ''); }, TypeError, 'string is not a function'); | ||
t['throws'](function () { forEach(arr, /a/); }, TypeError, 'regex is not a function'); | ||
t['throws'](function () { forEach(arr, true); }, TypeError, 'true is not a function'); | ||
t['throws'](function () { forEach(arr, false); }, TypeError, 'false is not a function'); | ||
t['throws'](function () { forEach(arr, NaN); }, TypeError, 'NaN is not a function'); | ||
t['throws'](function () { forEach(arr, 42); }, TypeError, '42 is not a function'); | ||
t.doesNotThrow(function () { forEach(arr, function () {}); }, 'function is a function'); | ||
t.doesNotThrow(function () { forEach(arr, setTimeout); }, 'setTimeout is a function'); | ||
if (typeof window !== 'undefined') { | ||
t.doesNotThrow(function () { forEach(arr, window.alert) }, 'alert is a function') | ||
t.doesNotThrow(function () { forEach(arr, window.alert); }, 'alert is a function'); | ||
} | ||
t.end() | ||
}) | ||
t.end(); | ||
}); | ||
test('array', function (t) { | ||
var arr = [1, 2, 3] | ||
var arr = [1, 2, 3]; | ||
t.test('iterates over every item', function (st) { | ||
var index = 0 | ||
forEach(arr, function () { index += 1 }) | ||
st.equal(index, arr.length, 'iterates ' + arr.length + ' times') | ||
st.end() | ||
}) | ||
var index = 0; | ||
forEach(arr, function () { index += 1; }); | ||
st.equal(index, arr.length, 'iterates ' + arr.length + ' times'); | ||
st.end(); | ||
}); | ||
t.test('first iterator argument', function (st) { | ||
var index = 0 | ||
st.plan(arr.length) | ||
var index = 0; | ||
st.plan(arr.length); | ||
forEach(arr, function (item) { | ||
st.equal(arr[index], item, 'item ' + index + ' is passed as first argument') | ||
index += 1 | ||
}) | ||
st.equal(arr[index], item, 'item ' + index + ' is passed as first argument'); | ||
index += 1; | ||
}); | ||
st.end(); | ||
}) | ||
}); | ||
t.test('second iterator argument', function (st) { | ||
var counter = 0 | ||
st.plan(arr.length) | ||
var counter = 0; | ||
st.plan(arr.length); | ||
forEach(arr, function (item, index) { | ||
st.equal(counter, index, 'index ' + index + ' is passed as second argument') | ||
counter += 1 | ||
}) | ||
st.equal(counter, index, 'index ' + index + ' is passed as second argument'); | ||
counter += 1; | ||
}); | ||
st.end(); | ||
}) | ||
}); | ||
t.test('third iterator argument', function (st) { | ||
st.plan(arr.length) | ||
st.plan(arr.length); | ||
forEach(arr, function (item, index, array) { | ||
st.deepEqual(arr, array, 'array is passed as third argument') | ||
}) | ||
st.deepEqual(arr, array, 'array is passed as third argument'); | ||
}); | ||
st.end(); | ||
}) | ||
}); | ||
t.test('context argument', function (st) { | ||
var context = {} | ||
var context = {}; | ||
forEach([], function () { | ||
st.equal(this, context, '"this" is the passed context') | ||
}, context) | ||
st.end() | ||
}) | ||
st.equal(this, context, '"this" is the passed context'); | ||
}, context); | ||
st.end(); | ||
}); | ||
t.end() | ||
}) | ||
t.end(); | ||
}); | ||
@@ -101,81 +105,79 @@ test('object', function (t) { | ||
c: 3 | ||
} | ||
var keys = ['a', 'b', 'c'] | ||
}; | ||
var keys = ['a', 'b', 'c']; | ||
var F = function () { | ||
this.a = 1 | ||
this.b = 2 | ||
} | ||
F.prototype.c = 3 | ||
var fKeys = ['a', 'b'] | ||
var F = function F() { | ||
this.a = 1; | ||
this.b = 2; | ||
}; | ||
F.prototype.c = 3; | ||
var fKeys = ['a', 'b']; | ||
t.test('iterates over every object literal key', function (st) { | ||
var counter = 0 | ||
forEach(obj, function () { counter += 1 }) | ||
st.equal(counter, keys.length, 'iterated ' + counter + ' times') | ||
st.end() | ||
}) | ||
var counter = 0; | ||
forEach(obj, function () { counter += 1; }); | ||
st.equal(counter, keys.length, 'iterated ' + counter + ' times'); | ||
st.end(); | ||
}); | ||
t.test('iterates only over own keys', function (st) { | ||
var counter = 0 | ||
forEach(new F(), function () { counter += 1 }) | ||
st.equal(counter, fKeys.length, 'iterated ' + fKeys.length + ' times') | ||
st.end() | ||
}) | ||
var counter = 0; | ||
forEach(new F(), function () { counter += 1; }); | ||
st.equal(counter, fKeys.length, 'iterated ' + fKeys.length + ' times'); | ||
st.end(); | ||
}); | ||
t.test('first iterator argument', function (st) { | ||
var index = 0 | ||
st.plan(keys.length) | ||
var index = 0; | ||
st.plan(keys.length); | ||
forEach(obj, function (item) { | ||
st.equal(obj[keys[index]], item, 'item at key ' + keys[index] + ' is passed as first argument') | ||
index += 1 | ||
}) | ||
st.end() | ||
}) | ||
st.equal(obj[keys[index]], item, 'item at key ' + keys[index] + ' is passed as first argument'); | ||
index += 1; | ||
}); | ||
st.end(); | ||
}); | ||
t.test('second iterator argument', function (st) { | ||
var counter = 0 | ||
st.plan(keys.length) | ||
var counter = 0; | ||
st.plan(keys.length); | ||
forEach(obj, function (item, key) { | ||
st.equal(keys[counter], key, 'key ' + key + ' is passed as second argument') | ||
counter += 1 | ||
}) | ||
st.end() | ||
}) | ||
st.equal(keys[counter], key, 'key ' + key + ' is passed as second argument'); | ||
counter += 1; | ||
}); | ||
st.end(); | ||
}); | ||
t.test('third iterator argument', function (st) { | ||
st.plan(keys.length) | ||
st.plan(keys.length); | ||
forEach(obj, function (item, key, object) { | ||
st.deepEqual(obj, object, 'object is passed as third argument') | ||
}) | ||
st.end() | ||
}) | ||
st.deepEqual(obj, object, 'object is passed as third argument'); | ||
}); | ||
st.end(); | ||
}); | ||
t.test('context argument', function (st) { | ||
var context = {} | ||
var context = {}; | ||
forEach({}, function () { | ||
st.equal(this, context, '"this" is the passed context') | ||
}, context) | ||
st.end() | ||
}) | ||
st.equal(this, context, '"this" is the passed context'); | ||
}, context); | ||
st.end(); | ||
}); | ||
t.end() | ||
}) | ||
t.end(); | ||
}); | ||
test('string', function (t) { | ||
var str = 'str' | ||
var str = 'str'; | ||
t.test('second iterator argument', function (st) { | ||
var counter = 0 | ||
st.plan(str.length * 2 + 1) | ||
var counter = 0; | ||
st.plan((str.length * 2) + 1); | ||
forEach(str, function (item, index) { | ||
st.equal(counter, index, 'index ' + index + ' is passed as second argument') | ||
st.equal(str.charAt(index), item) | ||
counter += 1 | ||
}) | ||
st.equal(counter, str.length, 'iterates ' + str.length + ' times') | ||
st.end() | ||
}) | ||
t.end() | ||
}) | ||
st.equal(counter, index, 'index ' + index + ' is passed as second argument'); | ||
st.equal(str.charAt(index), item); | ||
counter += 1; | ||
}); | ||
st.equal(counter, str.length, 'iterates ' + str.length + ' times'); | ||
st.end(); | ||
}); | ||
t.end(); | ||
}); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
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
13033
34.1%9
28.57%211
8.76%4
300%2
Infinity%+ Added
+ Added
- Removed
- Removed