[Pkg-javascript-commits] [node-es5-shim] 01/03: Imported Upstream version 4.4.1
Julien Puydt
julien.puydt at laposte.net
Sat Jan 2 13:30:15 UTC 2016
This is an automated email from the git hooks/post-receive script.
jpuydt-guest pushed a commit to branch master
in repository node-es5-shim.
commit 4024950389c1ffc3cd8c8196cad78f2c4abc4476
Author: Julien Puydt <julien.puydt at laposte.net>
Date: Sat Jan 2 14:20:19 2016 +0100
Imported Upstream version 4.4.1
---
.eslintrc | 3 +-
.jscs.json | 26 +-
.travis.yml | 9 +-
CHANGES | 46 +++
README.md | 11 +-
component.json | 2 +-
es5-sham.js | 8 +-
es5-sham.map | 2 +-
es5-sham.min.js | 4 +-
es5-shim.js | 413 +++++++++++++++++------
es5-shim.map | 2 +-
es5-shim.min.js | 4 +-
package.json | 15 +-
tests/index.html | 10 +-
tests/index.min.html | 8 +-
tests/native.html | 10 +-
tests/spec/s-array.js | 852 +++++++++++++++++++++++++++++++++++++++++------
tests/spec/s-date.js | 21 +-
tests/spec/s-error.js | 50 +++
tests/spec/s-function.js | 4 +-
tests/spec/s-global.js | 20 +-
tests/spec/s-number.js | 24 +-
tests/spec/s-object.js | 69 ++--
tests/spec/s-regexp.js | 27 ++
tests/spec/s-string.js | 36 +-
25 files changed, 1361 insertions(+), 315 deletions(-)
diff --git a/.eslintrc b/.eslintrc
index 2cea9de..d362d1d 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -14,7 +14,7 @@
"max-statements": [1, 30],
"new-cap": [2, { "capIsNewExceptions": ["ToInteger", "ToObject", "ToPrimitive", "ToUint32"] }],
"no-constant-condition": [1],
- "no-extend-native": [2, {"exceptions": ["Date"]}],
+ "no-extend-native": [2, {"exceptions": ["Date", "Error", "RegExp"]}],
"no-extra-parens": [0],
"no-extra-semi": [1],
"no-func-assign": [1],
@@ -27,6 +27,7 @@
"no-magic-numbers": [0],
"no-native-reassign": [2, {"exceptions": ["Date", "parseInt"]}],
"no-new-func": [1],
+ "no-plusplus": [1],
"no-restricted-syntax": [2, "ContinueStatement", "DebuggerStatement", "LabeledStatement", "WithStatement"],
"no-shadow": [1],
"no-unused-vars": [1, { "vars": "all", "args": "after-used" }],
diff --git a/.jscs.json b/.jscs.json
index bd4d449..629794b 100644
--- a/.jscs.json
+++ b/.jscs.json
@@ -9,13 +9,17 @@
"disallowIdentifierNames": [],
- "requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"],
+ "requireCurlyBraces": {
+ "allExcept": [],
+ "keywords": ["if", "else", "for", "while", "do", "try", "catch"]
+ },
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"],
"disallowSpaceAfterKeywords": [],
"disallowSpaceBeforeComma": true,
+ "disallowSpaceAfterComma": false,
"disallowSpaceBeforeSemicolon": true,
"disallowNodeTypes": [
@@ -126,7 +130,23 @@
"disallowNestedTernaries": { "maxLevel": 7 },
- "requireSpaceAfterComma": true,
- "requireAlignedMultilineParams": false
+ "requireSpaceAfterComma": { "allExcept": ["trailing"] },
+ "requireAlignedMultilineParams": false,
+
+ "requireSpacesInGenerator": {
+ "afterStar": true
+ },
+
+ "disallowSpacesInGenerator": {
+ "beforeStar": true
+ },
+
+ "disallowVar": false,
+
+ "requireArrayDestructuring": false,
+
+ "requireEnhancedObjectLiterals": false,
+
+ "requireObjectDestructuring": false
}
diff --git a/.travis.yml b/.travis.yml
index 324496c..95aa579 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,7 @@
language: node_js
node_js:
+ - "5.1"
+ - "5.0"
- "4.2"
- "4.1"
- "4.0"
@@ -30,11 +32,15 @@ node_js:
- "0.6"
- "0.4"
before_install:
- - '[ "${TRAVIS_NODE_VERSION}" = "0.6" ] || npm install -g npm at 1.4.28 && npm install -g npm'
+ - 'if [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then case "$(npm --version)" in 1.*) npm install -g npm at 1.4.28 ;; 2.*) npm install -g npm at 2 ;; esac ; fi'
+ - 'if [ "${TRAVIS_NODE_VERSION}" != "0.6" ] && [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then npm install -g npm; fi'
+script:
+ - 'if [ "${TRAVIS_NODE_VERSION}" != "4.2" ]; then npm run tests-only ; else npm test ; fi'
sudo: false
matrix:
fast_finish: true
allow_failures:
+ - node_js: "5.0"
- node_js: "4.1"
- node_js: "4.0"
- node_js: "iojs-v3.2"
@@ -55,6 +61,5 @@ matrix:
- node_js: "iojs-v1.0"
- node_js: "0.11"
- node_js: "0.9"
- - node_js: "0.8"
- node_js: "0.6"
- node_js: "0.4"
diff --git a/CHANGES b/CHANGES
index 43fed63..c96bd0d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,49 @@
+4.4.1
+ - [Fix] ensure that IE 11 in compatibility mode doesn't throw (#370)
+ - [Docs] add missing shimmed things
+
+4.4.0
+ - [New] Detect and patch `RegExp#toString` in IE 8, which returns flags in the wrong order (#364)
+ - [Fix] Patch `Array#sort` on {Chrome, Safari, IE < 9, FF 4} that throws improperly, per ES5 (#354)
+ - [Fix] In IE 6, `window.external` makes `Object.keys` throw
+ - [Fix] `Array#slice`: boxed string access on IE <= 8 (#349)
+ - [Fix] `Array#join`: fix IE 6-8 join called on string literal (#352)
+ - [Fix] Ensure that `Error#message` and `Error#name` are non-enumerable (#358)
+ - [Fix: sham] `Object.getOwnPropertyDescriptor`: In Opera 11.6, `propertyIsEnumerable` is a nonshadowable global, like `toString`
+ - [Robustness] Use a bound form of `Array#slice.call`
+ - [Tests] Properly check for descriptor support in IE <= 8
+ - [Tests] on `node` `v5.1`
+ - [Tests] Add `Array#slice` tests (#346)
+ - [Dev Deps] update `uglify-js`, `eslint`, `jscs`, `uglify-js`, `semver`
+ - [Docs] Fix broken UMD links (#344)
+
+4.3.1
+ - [Fix] `String#split`: revert part of dcce96ae21185a69d2d40e67416e7496b73e8e47 which broke in older browsers (#342)
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`
+ - [Tests] Firefox allows `Number#toPrecision` values of [1,100], which the spec permits
+
+4.3.0
+ - [New] `Array#push`: in IE <= 7, `Array#push` was not generic (#336)
+ - [New] `Array#push` in Opera `10.6` has a super weird bug when pushing `undefined`
+ - [New] `Array#join`: In IE <= 7, passing `undefined` didn't use the default separator (#333)
+ - [New] `Error#toString`: prints out the proper message in IE 7 and below (#334)
+ - [New] `Number#toPrecision`: IE 7 and below incorrectly throw when an explicit `undefined` precision is passed (#340)
+ - [Fix] `String#lastIndexOf`: ensure the correct length in IE 8
+ - [Fix] ensure `parseInt` accepts negative and plus-prefixed hex values (#332)
+ - [Robustness] Use a bound `Array#push` instead of relying on `Function#call`
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`
+ - [Tests] Add some conditionals to avoid impossible-to-fix test failures in IE 6-8, due to it being unable to distinguish between `undefined` and an absent index (#114)
+ - [Tests] Fix false negatives in IE 6-8 with jasmine comparing arrays to arraylikes (#114)
+ - [Tests] add additional `Array#shift` tests (#337)
+ - [Tests] Add additional `Array#splice` tests (#339)
+ - [Tests] Add `Array#pop` tests, just in case (#338)
+ - [Tests] include `global` tests in HTML test files
+ - [Tests] Make sure the HTML tests run with the right charset
+ - [Tests] ensure `node` `v0.8` tests stay passing.
+ - [Tests] Prevent nondeterminism in the tests - this sometime produced values that are one ms off
+ - [Tests] on `node` `v5.0`
+ - [Tests] fix npm upgrades for older nodes
+
4.2.0
- [shim: new] Overwrite `String#lastIndexOf` in IE 9, 10, 11, and Edge, so it has proper unicode support.
- [Dev Deps] update `eslint`, `jscs`
diff --git a/README.md b/README.md
index 81d6a87..12549e1 100644
--- a/README.md
+++ b/README.md
@@ -35,9 +35,13 @@ simply `npm install` and `npm test`.
* Array.prototype.indexOf
* Array.prototype.lastIndexOf
* Array.prototype.map
+* Array.prototype.slice
* Array.prototype.some
+* Array.prototype.sort
* Array.prototype.reduce
* Array.prototype.reduceRight
+* Array.prototype.push
+* Array.prototype.join
* Array.isArray
* Date.now
* Date.prototype.toJSON
@@ -48,14 +52,20 @@ simply `npm install` and `npm test`.
* :warning: Caveat: bound functions don't have checks in ``call`` and
``apply`` to avoid executing as a constructor.
* Number.prototype.toFixed
+* Number.prototype.toPrecision
* Object.keys
* String.prototype.split
* String.prototype.trim
+* String.prototype.lastIndexOf
* String.prototype.replace
* Firefox (through v29) natively handles capturing groups incorrectly.
* Date.parse (for ISO parsing)
* Date.prototype.toISOString
* parseInt
+* Error.prototype.toString
+* Error.prototype.name
+* Error.prototype.message
+* RegExp.prototype.toString
## Shams
@@ -164,4 +174,3 @@ simply `npm install` and `npm test`.
[dev-deps-svg]: https://david-dm.org/es-shims/es5-shim/dev-status.svg
[dev-deps-url]: https://david-dm.org/es-shims/es5-shim#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/es5-shim.png?downloads=true&stars=true
-
diff --git a/component.json b/component.json
index 60a6d6e..afc39c4 100644
--- a/component.json
+++ b/component.json
@@ -2,7 +2,7 @@
"name": "es5-shim",
"repo": "es-shims/es5-shim",
"description": "ECMAScript 5 compatibility shims for legacy JavaScript engines",
- "version": "v4.2.0",
+ "version": "v4.4.1",
"keywords": [
"shim",
"es5",
diff --git a/es5-sham.js b/es5-sham.js
index 9a15cbd..bc21634 100644
--- a/es5-sham.js
+++ b/es5-sham.js
@@ -10,7 +10,7 @@
;
// UMD (Universal Module Definition)
-// see https://github.com/umdjs/umd/blob/master/returnExports.js
+// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
(function (root, factory) {
'use strict';
@@ -29,10 +29,10 @@
}
}(this, function () {
-var call = Function.prototype.call;
+var call = Function.call;
var prototypeOfObject = Object.prototype;
var owns = call.bind(prototypeOfObject.hasOwnProperty);
-var propertyIsEnumerable = call.bind(prototypeOfObject.propertyIsEnumerable);
+var isEnumerable = call.bind(prototypeOfObject.propertyIsEnumerable);
var toStr = call.bind(prototypeOfObject.toString);
// If JS engine supports accessors creating shortcuts.
@@ -131,7 +131,7 @@ if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {
// If object has a property then it's for sure `configurable`, and
// probably `enumerable`. Detect enumerability though.
descriptor = {
- enumerable: propertyIsEnumerable(object, property),
+ enumerable: isEnumerable(object, property),
configurable: true
};
diff --git a/es5-sham.map b/es5-sham.map
index f37dfcb..3ed2a57 100644
--- a/es5-sham.map
+++ b/es5-sham.map
@@ -1 +1 @@
-{"version":3,"sources":["es5-sham.js"],"names":["root","factory","define","amd","exports","module","returnExports","this","call","Function","prototype","prototypeOfObject","Object","owns","bind","hasOwnProperty","propertyIsEnumerable","toStr","toString","defineGetter","defineSetter","lookupGetter","lookupSetter","supportsAccessors","__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__","getPrototypeOf","object","proto","__proto__","constructor","doesGetOwnPropertyDes [...]
\ No newline at end of file
+{"version":3,"sources":["es5-sham.js"],"names":["root","factory","define","amd","exports","module","returnExports","this","call","Function","prototypeOfObject","Object","prototype","owns","bind","hasOwnProperty","isEnumerable","propertyIsEnumerable","toStr","toString","defineGetter","defineSetter","lookupGetter","lookupSetter","supportsAccessors","__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__","getPrototypeOf","object","proto","__proto__","constructor","doesGe [...]
\ No newline at end of file
diff --git a/es5-sham.min.js b/es5-sham.min.js
index 415504b..389699d 100644
--- a/es5-sham.min.js
+++ b/es5-sham.min.js
@@ -1,7 +1,7 @@
/*!
* https://github.com/es-shims/es5-shim
* @license es5-shim Copyright 2009-2015 by contributors, MIT License
- * see https://github.com/es-shims/es5-shim/blob/v4.2.0/LICENSE
+ * see https://github.com/es-shims/es5-shim/blob/v4.4.1/LICENSE
*/
-(function(e,t){"use strict";if(typeof define==="function"&&define.amd){define(t)}else if(typeof exports==="object"){module.exports=t()}else{e.returnExports=t()}})(this,function(){var e=Function.prototype.call;var t=Object.prototype;var r=e.bind(t.hasOwnProperty);var n=e.bind(t.propertyIsEnumerable);var o=e.bind(t.toString);var i;var c;var f;var a;var l=r(t,"__defineGetter__");if(l){i=e.bind(t.__defineGetter__);c=e.bind(t.__defineSetter__);f=e.bind(t.__lookupGetter__);a=e.bind(t.__lookupS [...]
+(function(e,t){"use strict";if(typeof define==="function"&&define.amd){define(t)}else if(typeof exports==="object"){module.exports=t()}else{e.returnExports=t()}})(this,function(){var e=Function.call;var t=Object.prototype;var r=e.bind(t.hasOwnProperty);var n=e.bind(t.propertyIsEnumerable);var o=e.bind(t.toString);var i;var c;var f;var a;var l=r(t,"__defineGetter__");if(l){i=e.bind(t.__defineGetter__);c=e.bind(t.__defineSetter__);f=e.bind(t.__lookupGetter__);a=e.bind(t.__lookupSetter__)}i [...]
//# sourceMappingURL=es5-sham.map
diff --git a/es5-shim.js b/es5-shim.js
index 5daa667..6022eee 100644
--- a/es5-shim.js
+++ b/es5-shim.js
@@ -10,7 +10,7 @@
;
// UMD (Universal Module Definition)
-// see https://github.com/umdjs/umd/blob/master/returnExports.js
+// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
(function (root, factory) {
'use strict';
@@ -56,6 +56,7 @@ var array_push = ArrayPrototype.push;
var array_unshift = ArrayPrototype.unshift;
var array_concat = ArrayPrototype.concat;
var call = FunctionPrototype.call;
+var apply = FunctionPrototype.apply;
var max = Math.max;
var min = Math.min;
@@ -68,19 +69,18 @@ var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegEx
var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
/* inlined from http://npmjs.com/define-properties */
+var supportsDescriptors = $Object.defineProperty && (function () {
+ try {
+ var obj = {};
+ $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
+ for (var _ in obj) { return false; }
+ return obj.x === obj;
+ } catch (e) { /* this is ES3 */
+ return false;
+ }
+}());
var defineProperties = (function (has) {
- var supportsDescriptors = $Object.defineProperty && (function () {
- try {
- var obj = {};
- $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
- for (var _ in obj) { return false; }
- return obj.x === obj;
- } catch (e) { /* this is ES3 */
- return false;
- }
- }());
-
- // Define configurable, writable and non-enumerable props
+ // Define configurable, writable, and non-enumerable props
// if they don't exist.
var defineProperty;
if (supportsDescriptors) {
@@ -163,7 +163,6 @@ var ES = {
// http://es5.github.com/#x9.9
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
ToObject: function (o) {
- /* jshint eqnull: true */
if (o == null) { // this matches both null and undefined
throw new TypeError("can't convert " + o + ' to object');
}
@@ -321,12 +320,17 @@ defineProperties(FunctionPrototype, {
});
// _Please note: Shortcuts are defined after `Function.prototype.bind` as we
-// us it in defining shortcuts.
+// use it in defining shortcuts.
var owns = call.bind(ObjectPrototype.hasOwnProperty);
var toStr = call.bind(ObjectPrototype.toString);
+var arraySlice = call.bind(array_slice);
+var arraySliceApply = apply.bind(array_slice);
var strSlice = call.bind(StringPrototype.slice);
var strSplit = call.bind(StringPrototype.split);
var strIndexOf = call.bind(StringPrototype.indexOf);
+var push = call.bind(array_push);
+var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
+var arraySort = call.bind(ArrayPrototype.sort);
//
// Array
@@ -395,7 +399,7 @@ var properlyBoxesContext = function properlyBoxed(method) {
};
defineProperties(ArrayPrototype, {
- forEach: function forEach(callbackfn /*, thisArg*/) {
+ forEach: function forEach(callbackfn/*, thisArg*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var i = -1;
@@ -460,7 +464,7 @@ defineProperties(ArrayPrototype, {
// http://es5.github.com/#x15.4.4.20
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
defineProperties(ArrayPrototype, {
- filter: function filter(callbackfn /*, thisArg*/) {
+ filter: function filter(callbackfn/*, thisArg*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
@@ -480,7 +484,7 @@ defineProperties(ArrayPrototype, {
if (i in self) {
value = self[i];
if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
- array_push.call(result, value);
+ push(result, value);
}
}
}
@@ -492,7 +496,7 @@ defineProperties(ArrayPrototype, {
// http://es5.github.com/#x15.4.4.16
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
defineProperties(ArrayPrototype, {
- every: function every(callbackfn /*, thisArg*/) {
+ every: function every(callbackfn/*, thisArg*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
@@ -550,7 +554,7 @@ if (ArrayPrototype.reduce) {
reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
}
defineProperties(ArrayPrototype, {
- reduce: function reduce(callbackfn /*, initialValue*/) {
+ reduce: function reduce(callbackfn/*, initialValue*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
@@ -653,7 +657,7 @@ defineProperties(ArrayPrototype, {
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
defineProperties(ArrayPrototype, {
- indexOf: function indexOf(searchElement /*, fromIndex */) {
+ indexOf: function indexOf(searchElement/*, fromIndex */) {
var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
var length = ES.ToUint32(self.length);
@@ -682,7 +686,7 @@ defineProperties(ArrayPrototype, {
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
defineProperties(ArrayPrototype, {
- lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */) {
+ lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
var length = ES.ToUint32(self.length);
@@ -733,9 +737,9 @@ defineProperties(ArrayPrototype, {
var args = arguments;
this.length = max(ES.ToInteger(this.length), 0);
if (arguments.length > 0 && typeof deleteCount !== 'number') {
- args = array_slice.call(arguments);
+ args = arraySlice(arguments);
if (args.length < 2) {
- array_push.call(args, this.length - start);
+ push(args, this.length - start);
} else {
args[1] = ES.ToInteger(deleteCount);
}
@@ -782,7 +786,7 @@ defineProperties(ArrayPrototype, {
k += 1;
}
- var items = array_slice.call(arguments, 2);
+ var items = arraySlice(arguments, 2);
var itemCount = items.length;
var to;
if (itemCount < actualDeleteCount) {
@@ -826,6 +830,112 @@ defineProperties(ArrayPrototype, {
}
}, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
+var originalJoin = ArrayPrototype.join;
+var hasStringJoinBug;
+try {
+ hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
+} catch (e) {
+ hasStringJoinBug = true;
+}
+if (hasStringJoinBug) {
+ defineProperties(ArrayPrototype, {
+ join: function join(separator) {
+ var sep = typeof separator === 'undefined' ? ',' : separator;
+ return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
+ }
+ }, hasStringJoinBug);
+}
+
+var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
+if (hasJoinUndefinedBug) {
+ defineProperties(ArrayPrototype, {
+ join: function join(separator) {
+ var sep = typeof separator === 'undefined' ? ',' : separator;
+ return originalJoin.call(this, sep);
+ }
+ }, hasJoinUndefinedBug);
+}
+
+var pushShim = function push(item) {
+ var O = ES.ToObject(this);
+ var n = ES.ToUint32(O.length);
+ var i = 0;
+ while (i < arguments.length) {
+ O[n + i] = arguments[i];
+ i += 1;
+ }
+ O.length = n + i;
+ return n + i;
+};
+
+var pushIsNotGeneric = (function () {
+ var obj = {};
+ var result = Array.prototype.push.call(obj, undefined);
+ return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
+}());
+defineProperties(ArrayPrototype, {
+ push: function push(item) {
+ if (isArray(this)) {
+ return array_push.apply(this, arguments);
+ }
+ return pushShim.apply(this, arguments);
+ }
+}, pushIsNotGeneric);
+
+// This fixes a very weird bug in Opera 10.6 when pushing `undefined
+var pushUndefinedIsWeird = (function () {
+ var arr = [];
+ var result = arr.push(undefined);
+ return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
+}());
+defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
+
+// ES5 15.2.3.14
+// http://es5.github.io/#x15.4.4.10
+// Fix boxed string bug
+defineProperties(ArrayPrototype, {
+ slice: function (start, end) {
+ var arr = isString(this) ? strSplit(this, '') : this;
+ return arraySliceApply(arr, arguments);
+ }
+}, splitString);
+
+var sortIgnoresNonFunctions = (function () {
+ try {
+ [1, 2].sort(null);
+ [1, 2].sort({});
+ return true;
+ } catch (e) { /**/ }
+ return false;
+}());
+var sortThrowsOnRegex = (function () {
+ // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
+ try {
+ [1, 2].sort(/a/);
+ return false;
+ } catch (e) { /**/ }
+ return true;
+}());
+var sortIgnoresUndefined = (function () {
+ // applies in IE 8, for one.
+ try {
+ [1, 2].sort(undefined);
+ return true;
+ } catch (e) { /**/ }
+ return false;
+}());
+defineProperties(ArrayPrototype, {
+ sort: function sort(compareFn) {
+ if (typeof compareFn === 'undefined') {
+ return arraySort(this);
+ }
+ if (!isCallable(compareFn)) {
+ throw new TypeError('Array.prototype.sort callback must be a function');
+ }
+ return arraySort(this, compareFn);
+ }
+}, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
+
//
// Object
// ======
@@ -851,7 +961,8 @@ var blacklistedKeys = {
$frames: true,
$frameElement: true,
$webkitIndexedDB: true,
- $webkitStorageInfo: true
+ $webkitStorageInfo: true,
+ $external: true
};
var hasAutomationEqualityBug = (function () {
/* globals window */
@@ -916,14 +1027,14 @@ defineProperties($Object, {
var skipProto = hasProtoEnumBug && isFn;
if ((isStr && hasStringEnumBug) || isArgs) {
for (var i = 0; i < object.length; ++i) {
- array_push.call(theKeys, $String(i));
+ push(theKeys, $String(i));
}
}
if (!isArgs) {
for (var name in object) {
if (!(skipProto && name === 'prototype') && owns(object, name)) {
- array_push.call(theKeys, $String(name));
+ push(theKeys, $String(name));
}
}
}
@@ -933,7 +1044,7 @@ defineProperties($Object, {
for (var j = 0; j < dontEnumsLength; j++) {
var dontEnum = dontEnums[j];
if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
- array_push.call(theKeys, dontEnum);
+ push(theKeys, dontEnum);
}
}
}
@@ -953,7 +1064,7 @@ var originalKeys = $Object.keys;
defineProperties($Object, {
keys: function keys(object) {
if (isArguments(object)) {
- return originalKeys(array_slice.call(object));
+ return originalKeys(arraySlice(object));
} else {
return originalKeys(object);
}
@@ -1009,8 +1120,8 @@ defineProperties(Date.prototype, {
}
// pad milliseconds to have three digits.
return (
- year + '-' + array_slice.call(result, 0, 2).join('-') +
- 'T' + array_slice.call(result, 2).join(':') + '.' +
+ year + '-' + arraySlice(result, 0, 2).join('-') +
+ 'T' + arraySlice(result, 2).join(':') + '.' +
strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z'
);
}
@@ -1081,7 +1192,6 @@ if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
/* global Date: true */
/* eslint-disable no-undef */
var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
- var secondsWithinMaxSafeUnsigned32Bit = Math.floor(maxSafeUnsigned32Bit / 1e3);
var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
Date = (function (NativeDate) {
/* eslint-enable no-undef */
@@ -1322,91 +1432,104 @@ var toFixedHelpers = {
}
};
-defineProperties(NumberPrototype, {
- toFixed: function toFixed(fractionDigits) {
- var f, x, s, m, e, z, j, k;
-
- // Test for NaN and round fractionDigits down
- f = $Number(fractionDigits);
- f = isActualNaN(f) ? 0 : Math.floor(f);
-
- if (f < 0 || f > 20) {
- throw new RangeError('Number.toFixed called with invalid number of decimals');
- }
-
- x = $Number(this);
-
- if (isActualNaN(x)) {
- return 'NaN';
- }
+var toFixedShim = function toFixed(fractionDigits) {
+ var f, x, s, m, e, z, j, k;
- // If it is too big or small, return the string value of the number
- if (x <= -1e21 || x >= 1e21) {
- return $String(x);
- }
+ // Test for NaN and round fractionDigits down
+ f = $Number(fractionDigits);
+ f = isActualNaN(f) ? 0 : Math.floor(f);
- s = '';
+ if (f < 0 || f > 20) {
+ throw new RangeError('Number.toFixed called with invalid number of decimals');
+ }
- if (x < 0) {
- s = '-';
- x = -x;
- }
+ x = $Number(this);
- m = '0';
+ if (isActualNaN(x)) {
+ return 'NaN';
+ }
- if (x > 1e-21) {
- // 1e-21 < x < 1e21
- // -70 < log2(x) < 70
- e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
- z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
- z *= 0x10000000000000; // Math.pow(2, 52);
- e = 52 - e;
+ // If it is too big or small, return the string value of the number
+ if (x <= -1e21 || x >= 1e21) {
+ return $String(x);
+ }
- // -18 < e < 122
- // x = z / 2 ^ e
- if (e > 0) {
- toFixedHelpers.multiply(0, z);
- j = f;
+ s = '';
- while (j >= 7) {
- toFixedHelpers.multiply(1e7, 0);
- j -= 7;
- }
+ if (x < 0) {
+ s = '-';
+ x = -x;
+ }
- toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
- j = e - 1;
+ m = '0';
+
+ if (x > 1e-21) {
+ // 1e-21 < x < 1e21
+ // -70 < log2(x) < 70
+ e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
+ z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
+ z *= 0x10000000000000; // Math.pow(2, 52);
+ e = 52 - e;
+
+ // -18 < e < 122
+ // x = z / 2 ^ e
+ if (e > 0) {
+ toFixedHelpers.multiply(0, z);
+ j = f;
+
+ while (j >= 7) {
+ toFixedHelpers.multiply(1e7, 0);
+ j -= 7;
+ }
- while (j >= 23) {
- toFixedHelpers.divide(1 << 23);
- j -= 23;
- }
+ toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
+ j = e - 1;
- toFixedHelpers.divide(1 << j);
- toFixedHelpers.multiply(1, 1);
- toFixedHelpers.divide(2);
- m = toFixedHelpers.numToString();
- } else {
- toFixedHelpers.multiply(0, z);
- toFixedHelpers.multiply(1 << (-e), 0);
- m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
+ while (j >= 23) {
+ toFixedHelpers.divide(1 << 23);
+ j -= 23;
}
+
+ toFixedHelpers.divide(1 << j);
+ toFixedHelpers.multiply(1, 1);
+ toFixedHelpers.divide(2);
+ m = toFixedHelpers.numToString();
+ } else {
+ toFixedHelpers.multiply(0, z);
+ toFixedHelpers.multiply(1 << (-e), 0);
+ m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
}
+ }
- if (f > 0) {
- k = m.length;
+ if (f > 0) {
+ k = m.length;
- if (k <= f) {
- m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
- } else {
- m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
- }
+ if (k <= f) {
+ m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
} else {
- m = s + m;
+ m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
}
+ } else {
+ m = s + m;
+ }
+
+ return m;
+};
+defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
- return m;
+var hasToPrecisionUndefinedBug = (function () {
+ try {
+ return 1.0.toPrecision(undefined) === '1';
+ } catch (e) {
+ return true;
+ }
+}());
+var originalToPrecision = NumberPrototype.toPrecision;
+defineProperties(NumberPrototype, {
+ toPrecision: function toPrecision(precision) {
+ return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
}
-}, hasToFixedBugs);
+}, hasToPrecisionUndefinedBug);
//
// String
@@ -1441,7 +1564,7 @@ if (
var maxSafe32BitInt = Math.pow(2, 32) - 1;
StringPrototype.split = function (separator, limit) {
- var string = this;
+ var string = String(this);
if (typeof separator === 'undefined' && limit === 0) {
return [];
}
@@ -1460,7 +1583,6 @@ if (
// Make `global` and avoid `lastIndex` issues by working with a copy
separator2, match, lastIndex, lastLength;
var separatorCopy = new RegExp(separator.source, flags + 'g');
- string += ''; // Type-convert
if (!compliantExecNpcg) {
// Doesn't need flags gy, but they don't hurt
separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
@@ -1478,7 +1600,7 @@ if (
// `separatorCopy.lastIndex` is not reliable cross-browser
lastIndex = match.index + match[0].length;
if (lastIndex > lastLastIndex) {
- array_push.call(output, strSlice(string, lastLastIndex, match.index));
+ push(output, strSlice(string, lastLastIndex, match.index));
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if (!compliantExecNpcg && match.length > 1) {
@@ -1493,7 +1615,7 @@ if (
/* eslint-enable no-loop-func */
}
if (match.length > 1 && match.index < string.length) {
- array_push.apply(output, array_slice.call(match, 1));
+ array_push.apply(output, arraySlice(match, 1));
}
lastLength = match[0].length;
lastLastIndex = lastIndex;
@@ -1508,10 +1630,10 @@ if (
}
if (lastLastIndex === string.length) {
if (lastLength || !separatorCopy.test('')) {
- array_push.call(output, '');
+ push(output, '');
}
} else {
- array_push.call(output, strSlice(string, lastLastIndex));
+ push(output, strSlice(string, lastLastIndex));
}
return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output;
};
@@ -1534,7 +1656,7 @@ var str_replace = StringPrototype.replace;
var replaceReportsGroupsCorrectly = (function () {
var groups = [];
'x'.replace(/x(.)?/g, function (match, group) {
- array_push.call(groups, group);
+ push(groups, group);
});
return groups.length === 1 && typeof groups[0] === 'undefined';
}());
@@ -1552,7 +1674,7 @@ if (!replaceReportsGroupsCorrectly) {
searchValue.lastIndex = 0;
var args = searchValue.exec(match) || [];
searchValue.lastIndex = originalLastIndex;
- array_push.call(args, arguments[length - 2], arguments[length - 1]);
+ push(args, arguments[length - 2], arguments[length - 1]);
return replaceValue.apply(this, args);
};
return str_replace.call(this, searchValue, wrappedReplaceValue);
@@ -1598,7 +1720,7 @@ defineProperties(StringPrototype, {
}
}, hasTrimWhitespaceBug);
-var hasLastIndexBug = String.prototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
+var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
defineProperties(StringPrototype, {
lastIndexOf: function lastIndexOf(searchString) {
if (typeof this === 'undefined' || this === null) {
@@ -1622,11 +1744,20 @@ defineProperties(StringPrototype, {
}
}, hasLastIndexBug);
+var originalLastIndexOf = StringPrototype.lastIndexOf;
+defineProperties(StringPrototype, {
+ lastIndexOf: function lastIndexOf(searchString) {
+ return originalLastIndexOf.apply(this, arguments);
+ }
+}, StringPrototype.lastIndexOf.length !== 1);
+
// ES-5 15.1.2.2
+/* eslint-disable radix */
if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
+/* eslint-enable radix */
/* global parseInt: true */
parseInt = (function (origParseInt) {
- var hexRegex = /^0[xX]/;
+ var hexRegex = /^[\-+]?0[xX]/;
return function parseInt(str, radix) {
var string = $String(str).trim();
var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
@@ -1635,4 +1766,66 @@ if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
}(parseInt));
}
+if (String(new RangeError('test')) !== 'RangeError: test') {
+ var errorToStringShim = function toString() {
+ if (typeof this === 'undefined' || this === null) {
+ throw new TypeError("can't convert " + this + ' to object');
+ }
+ var name = this.name;
+ if (typeof name === 'undefined') {
+ name = 'Error';
+ } else if (typeof name !== 'string') {
+ name = $String(name);
+ }
+ var msg = this.message;
+ if (typeof msg === 'undefined') {
+ msg = '';
+ } else if (typeof msg !== 'string') {
+ msg = $String(msg);
+ }
+ if (!name) {
+ return msg;
+ }
+ if (!msg) {
+ return name;
+ }
+ return name + ': ' + msg;
+ };
+ // can't use defineProperties here because of toString enumeration issue in IE <= 8
+ Error.prototype.toString = errorToStringShim;
+}
+
+if (supportsDescriptors) {
+ var ensureNonEnumerable = function (obj, prop) {
+ if (isEnum(obj, prop)) {
+ var desc = Object.getOwnPropertyDescriptor(obj, prop);
+ desc.enumerable = false;
+ Object.defineProperty(obj, prop, desc);
+ }
+ };
+ ensureNonEnumerable(Error.prototype, 'message');
+ if (Error.prototype.message !== '') {
+ Error.prototype.message = '';
+ }
+ ensureNonEnumerable(Error.prototype, 'name');
+}
+
+if (String(/a/mig) !== '/a/gim') {
+ var regexToString = function toString() {
+ var str = '/' + this.source + '/';
+ if (this.global) {
+ str += 'g';
+ }
+ if (this.ignoreCase) {
+ str += 'i';
+ }
+ if (this.multiline) {
+ str += 'm';
+ }
+ return str;
+ };
+ // can't use defineProperties here because of toString enumeration issue in IE <= 8
+ RegExp.prototype.toString = regexToString;
+}
+
}));
diff --git a/es5-shim.map b/es5-shim.map
index d5aeacc..a45d038 100644
--- a/es5-shim.map
+++ b/es5-shim.map
@@ -1 +1 @@
-{"version":3,"sources":["es5-shim.js"],"names":["root","factory","define","amd","exports","module","returnExports","this","$Array","Array","ArrayPrototype","prototype","$Object","Object","ObjectPrototype","FunctionPrototype","Function","$String","String","StringPrototype","$Number","Number","NumberPrototype","array_slice","slice","array_splice","splice","array_push","push","array_unshift","unshift","array_concat","concat","call","max","Math","min","to_string","toString","hasToStringTag", [...]
\ No newline at end of file
+{"version":3,"sources":["es5-shim.js"],"names":["root","factory","define","amd","exports","module","returnExports","this","$Array","Array","ArrayPrototype","prototype","$Object","Object","ObjectPrototype","FunctionPrototype","Function","$String","String","StringPrototype","$Number","Number","NumberPrototype","array_slice","slice","array_splice","splice","array_push","push","array_unshift","unshift","array_concat","concat","call","apply","max","Math","min","to_string","toString","hasToStr [...]
\ No newline at end of file
diff --git a/es5-shim.min.js b/es5-shim.min.js
index 7a73022..5b43dbe 100644
--- a/es5-shim.min.js
+++ b/es5-shim.min.js
@@ -1,7 +1,7 @@
/*!
* https://github.com/es-shims/es5-shim
* @license es5-shim Copyright 2009-2015 by contributors, MIT License
- * see https://github.com/es-shims/es5-shim/blob/v4.2.0/LICENSE
+ * see https://github.com/es-shims/es5-shim/blob/v4.4.1/LICENSE
*/
-(function(e,t){"use strict";if(typeof define==="function"&&define.amd){define(t)}else if(typeof exports==="object"){module.exports=t()}else{e.returnExports=t()}})(this,function(){var e=Array;var t=e.prototype;var r=Object;var n=r.prototype;var a=Function.prototype;var i=String;var o=i.prototype;var l=Number;var u=l.prototype;var f=t.slice;var s=t.splice;var c=t.push;var v=t.unshift;var p=t.concat;var h=a.call;var g=Math.max;var y=Math.min;var d=n.toString;var w=typeof Symbol==="function" [...]
+(function(r,t){"use strict";if(typeof define==="function"&&define.amd){define(t)}else if(typeof exports==="object"){module.exports=t()}else{r.returnExports=t()}})(this,function(){var r=Array;var t=r.prototype;var e=Object;var n=e.prototype;var i=Function.prototype;var a=String;var o=a.prototype;var u=Number;var f=u.prototype;var l=t.slice;var s=t.splice;var c=t.push;var v=t.unshift;var p=t.concat;var h=i.call;var g=i.apply;var y=Math.max;var d=Math.min;var m=n.toString;var w=typeof Symbo [...]
//# sourceMappingURL=es5-shim.map
diff --git a/package.json b/package.json
index fa958fa..611bbf0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "es5-shim",
- "version": "4.2.0",
+ "version": "4.4.1",
"description": "ECMAScript 5 compatibility shims for legacy JavaScript engines",
"homepage": "http://github.com/es-shims/es5-shim/",
"contributors": [
@@ -25,20 +25,21 @@
"minify": "npm run minify-shim && npm run minify-sham",
"minify-shim": "uglifyjs es5-shim.js --keep-fnames --comments --source-map=es5-shim.map -m -b ascii_only=true,beautify=false > es5-shim.min.js",
"minify-sham": "uglifyjs es5-sham.js --keep-fnames --comments --source-map=es5-sham.map -m -b ascii_only=true,beautify=false > es5-sham.min.js",
- "test": "npm run lint && jasmine-node --matchall ./ tests/spec/",
+ "test": "npm run lint && npm run tests-only",
+ "tests-only": "jasmine-node --matchall ./ tests/spec/",
"test-native": "jasmine-node --matchall tests/spec/",
"lint": "npm run jscs && npm run eslint",
"eslint": "eslint tests/helpers/*.js tests/spec/*.js es5-shim.js es5-sham.js",
"jscs": "jscs tests/helpers/*.js tests/spec/*.js es5-shim.js es5-sham.js"
},
"devDependencies": {
- "eslint": "^1.7.3",
- "@ljharb/eslint-config": "^1.4.1",
+ "eslint": "^1.10.1",
+ "@ljharb/eslint-config": "^1.6.0",
"jasmine-node": "^1.14.5",
- "jscs": "^2.4.0",
- "uglify-js": "^2.5.0",
+ "jscs": "^2.6.0",
+ "uglify-js": "^2.6.1",
"replace": "^0.3.0",
- "semver": "^5.0.3"
+ "semver": "^5.1.0"
},
"engines": {
"node": ">=0.4.0"
diff --git a/tests/index.html b/tests/index.html
index a797edd..f09492d 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -1,6 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
+ <meta charset="utf-8" />
<title>Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine_favicon.png">
@@ -19,11 +20,14 @@
<!-- include spec files here... -->
<script src="spec/s-array.js"></script>
+ <script src="spec/s-date.js"></script>
+ <script src="spec/s-error.js"></script>
<script src="spec/s-function.js"></script>
- <script src="spec/s-string.js"></script>
- <script src="spec/s-object.js"></script>
+ <script src="spec/s-global.js"></script>
<script src="spec/s-number.js"></script>
- <script src="spec/s-date.js"></script>
+ <script src="spec/s-object.js"></script>
+ <script src="spec/s-string.js"></script>
+ <script src="spec/s-regexp.js"></script>
<script type="text/javascript">
diff --git a/tests/index.min.html b/tests/index.min.html
index b8ac467..5a265ca 100644
--- a/tests/index.min.html
+++ b/tests/index.min.html
@@ -18,11 +18,13 @@
<!-- include spec files here... -->
<script src="spec/s-array.js"></script>
+ <script src="spec/s-date.js"></script>
+ <script src="spec/s-error.js"></script>
<script src="spec/s-function.js"></script>
- <script src="spec/s-string.js"></script>
- <script src="spec/s-object.js"></script>
+ <script src="spec/s-global.js"></script>
<script src="spec/s-number.js"></script>
- <script src="spec/s-date.js"></script>
+ <script src="spec/s-object.js"></script>
+ <script src="spec/s-string.js"></script>
<script type="text/javascript">
diff --git a/tests/native.html b/tests/native.html
index 82631ff..37811fa 100644
--- a/tests/native.html
+++ b/tests/native.html
@@ -1,6 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
+ <meta charset="utf-8" />
<title>Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine_favicon.png">
@@ -15,11 +16,14 @@
<!-- include spec files here... -->
<script src="spec/s-array.js"></script>
+ <script src="spec/s-date.js"></script>
+ <script src="spec/s-error.js"></script>
<script src="spec/s-function.js"></script>
- <script src="spec/s-string.js"></script>
- <script src="spec/s-object.js"></script>
+ <script src="spec/s-global.js"></script>
<script src="spec/s-number.js"></script>
- <script src="spec/s-date.js"></script>
+ <script src="spec/s-object.js"></script>
+ <script src="spec/s-string.js"></script>
+ <script src="spec/s-regexp.js"></script>
<script type="text/javascript">
diff --git a/tests/spec/s-array.js b/tests/spec/s-array.js
index 4de5872..734f7aa 100644
--- a/tests/spec/s-array.js
+++ b/tests/spec/s-array.js
@@ -1,19 +1,24 @@
/* global describe, it, expect, beforeEach, jasmine, xit */
var toStr = Object.prototype.toString;
-// var canDistinguishSparseFromUndefined = 0 in [undefined]; // IE 6 - 8 have a bug where this returns false.
+var canDistinguishSparseFromUndefined = 0 in [undefined]; // IE 6 - 8 have a bug where this returns false.
+var ifHasDenseUndefinedsIt = canDistinguishSparseFromUndefined ? it : xit;
+var undefinedIfNoSparseBug = canDistinguishSparseFromUndefined ? undefined : { valueOf: function () { return 0; } };
var hasStrictMode = (function () {
'use strict';
return !this;
}());
+var ifHasStrictIt = hasStrictMode ? it : xit;
describe('Array', function () {
var testSubject;
+
beforeEach(function () {
- testSubject = [2, 3, undefined, true, 'hej', null, false, 0];
+ testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, false, 0];
delete testSubject[1];
});
+
var createArrayLikeFromArray = function createArrayLikeFromArray(arr) {
var o = {};
Array.prototype.forEach.call(arr, function (e, i) {
@@ -23,24 +28,26 @@ describe('Array', function () {
return o;
};
- describe('forEach', function () {
+ describe('#forEach()', function () {
var expected, actual;
beforeEach(function () {
- expected = { 0: 2, 2: undefined, 3: true, 4: 'hej', 5: null, 6: false, 7: 0 };
+ expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true, 4: 'hej', 5: null, 6: false, 7: 0 };
actual = {};
});
+
it('should pass the right parameters', function () {
- var callback = jasmine.createSpy('callback'),
- array = ['1'];
+ var callback = jasmine.createSpy('callback');
+ var array = ['1'];
array.forEach(callback);
expect(callback).toHaveBeenCalledWith('1', 0, array);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = [1, 2, 3],
- i = 0;
+ var arr = [1, 2, 3];
+ var i = 0;
arr.forEach(function (a) {
- i++;
+ i += 1;
arr.push(a + 3);
});
expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
@@ -52,12 +59,14 @@ describe('Array', function () {
[1].forEach(function () { context = this; });
expect(context).toBe(function () { return this; }.call());
});
+
it('should iterate all', function () {
testSubject.forEach(function (obj, index) {
actual[index] = obj;
});
expect(actual).toExactlyMatch(expected);
});
+
it('should iterate all using a context', function () {
var o = { a: actual };
@@ -74,9 +83,10 @@ describe('Array', function () {
});
expect(actual).toExactlyMatch(expected);
});
+
it('should iterate all in an array-like object using a context', function () {
- var ts = createArrayLikeFromArray(testSubject),
- o = { a: actual };
+ var ts = createArrayLikeFromArray(testSubject);
+ var o = { a: actual };
Array.prototype.forEach.call(ts, function (obj, index) {
this.a[index] = obj;
@@ -86,6 +96,7 @@ describe('Array', function () {
describe('strings', function () {
var str = 'Hello, World!';
+
it('should iterate all in a string', function () {
actual = [];
Array.prototype.forEach.call(str, function (item, index) {
@@ -93,6 +104,7 @@ describe('Array', function () {
});
expect(actual).toExactlyMatch(str.split(''));
});
+
it('should iterate all in a string using a context', function () {
actual = [];
var o = { a: actual };
@@ -102,6 +114,7 @@ describe('Array', function () {
expect(actual).toExactlyMatch(str.split(''));
});
});
+
it('should have a boxed object as list argument of callback', function () {
var listArg;
Array.prototype.forEach.call('foo', function (item, index, list) {
@@ -110,23 +123,22 @@ describe('Array', function () {
expect(typeof listArg).toBe('object');
expect(toStr.call(listArg)).toBe('[object String]');
});
- if (hasStrictMode) {
- it('does not autobox the content in strict mode', function () {
- var context;
- [1].forEach(function () {
- 'use strict';
- context = this;
- }, 'x');
- expect(typeof context).toBe('string');
- });
- }
+ ifHasStrictIt('does not autobox the content in strict mode', function () {
+ var context;
+ [1].forEach(function () {
+ 'use strict';
+
+ context = this;
+ }, 'x');
+ expect(typeof context).toBe('string');
+ });
});
- describe('some', function () {
+ describe('#some()', function () {
var actual, expected, numberOfRuns;
beforeEach(function () {
- expected = { 0: 2, 2: undefined, 3: true };
+ expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true };
actual = {};
numberOfRuns = 0;
});
@@ -137,17 +149,19 @@ describe('Array', function () {
array.some(callback);
expect(callback).toHaveBeenCalledWith('1', 0, array);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = [1, 2, 3],
- i = 0;
+ var arr = [1, 2, 3];
+ var i = 0;
arr.some(function (a) {
- i++;
+ i += 1;
arr.push(a + 3);
return i > 3;
});
expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
expect(i).toBe(3);
});
+
it('should set the right context when given none', function () {
var context;
[1].some(function () { context = this; });
@@ -158,10 +172,12 @@ describe('Array', function () {
actual = testSubject.some(function () {});
expect(actual).toBeFalsy();
});
+
it('should return true if it is stopped somewhere', function () {
actual = testSubject.some(function () { return true; });
expect(actual).toBeTruthy();
});
+
it('should return false if there are no elements', function () {
actual = [].some(function () { return true; });
expect(actual).toBeFalsy();
@@ -175,6 +191,7 @@ describe('Array', function () {
});
expect(actual).toExactlyMatch(expected);
});
+
it('should stop after 3 elements using a context', function () {
var o = { a: actual };
testSubject.some(function (obj, index) {
@@ -194,6 +211,7 @@ describe('Array', function () {
});
expect(actual).toExactlyMatch(expected);
});
+
it('should stop after 3 elements in an array-like object using a context', function () {
var ts = createArrayLikeFromArray(testSubject);
var o = { a: actual };
@@ -204,6 +222,7 @@ describe('Array', function () {
}, o);
expect(actual).toExactlyMatch(expected);
});
+
it('should have a boxed object as list argument of callback', function () {
var listArg;
Array.prototype.some.call('foo', function (item, index, list) {
@@ -213,11 +232,11 @@ describe('Array', function () {
expect(toStr.call(listArg)).toBe('[object String]');
});
});
- describe('every', function () {
+ describe('#every()', function () {
var actual, expected, numberOfRuns;
beforeEach(function () {
- expected = { 0: 2, 2: undefined, 3: true };
+ expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true };
actual = {};
numberOfRuns = 0;
});
@@ -228,17 +247,19 @@ describe('Array', function () {
array.every(callback);
expect(callback).toHaveBeenCalledWith('1', 0, array);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = [1, 2, 3],
- i = 0;
+ var arr = [1, 2, 3];
+ var i = 0;
arr.every(function (a) {
- i++;
+ i += 1;
arr.push(a + 3);
return i <= 3;
});
expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
expect(i).toBe(3);
});
+
it('should set the right context when given none', function () {
var context;
[1].every(function () { context = this; });
@@ -252,10 +273,12 @@ describe('Array', function () {
actual = [].every(function () { return false; });
expect(actual).toBeTruthy();
});
+
it('should return true if it runs to the end', function () {
actual = [1, 2, 3].every(function () { return true; });
expect(actual).toBeTruthy();
});
+
it('should return false if it is stopped before the end', function () {
actual = [1, 2, 3].every(function () { return false; });
expect(actual).toBeFalsy();
@@ -269,6 +292,7 @@ describe('Array', function () {
});
expect(actual).toExactlyMatch(expected);
});
+
it('should stop after 3 elements using a context', function () {
var o = { a: actual };
testSubject.every(function (obj, index) {
@@ -288,6 +312,7 @@ describe('Array', function () {
});
expect(actual).toExactlyMatch(expected);
});
+
it('should stop after 3 elements in an array-like object using a context', function () {
var ts = createArrayLikeFromArray(testSubject);
var o = { a: actual };
@@ -298,6 +323,7 @@ describe('Array', function () {
}, o);
expect(actual).toExactlyMatch(expected);
});
+
it('should have a boxed object as list argument of callback', function () {
var listArg;
Array.prototype.every.call('foo', function (item, index, list) {
@@ -308,15 +334,14 @@ describe('Array', function () {
});
});
- describe('indexOf', function () {
+ describe('#indexOf()', function () {
'use strict';
var actual, expected;
beforeEach(function () {
- testSubject = [2, 3, undefined, true, 'hej', null, 2, false, 0];
+ testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0];
delete testSubject[1];
-
});
it('should find the element', function () {
@@ -324,21 +349,25 @@ describe('Array', function () {
actual = testSubject.indexOf('hej');
expect(actual).toBe(expected);
});
+
it('should not find the element', function () {
expected = -1;
actual = testSubject.indexOf('mus');
expect(actual).toBe(expected);
});
- it('should find undefined as well', function () {
+
+ ifHasDenseUndefinedsIt('should find undefined as well', function () {
expected = -1;
actual = testSubject.indexOf(undefined);
expect(actual).not.toBe(expected);
});
- it('should skip unset indexes', function () {
+
+ ifHasDenseUndefinedsIt('should skip unset indexes', function () {
expected = 2;
actual = testSubject.indexOf(undefined);
expect(actual).toBe(expected);
});
+
it('should use a strict test', function () {
actual = testSubject.indexOf(null);
expect(actual).toBe(5);
@@ -346,53 +375,63 @@ describe('Array', function () {
actual = testSubject.indexOf('2');
expect(actual).toBe(-1);
});
+
it('should skip the first if fromIndex is set', function () {
expect(testSubject.indexOf(2, 2)).toBe(6);
expect(testSubject.indexOf(2, 0)).toBe(0);
expect(testSubject.indexOf(2, 6)).toBe(6);
});
+
it('should work with negative fromIndex', function () {
expect(testSubject.indexOf(2, -3)).toBe(6);
expect(testSubject.indexOf(2, -9)).toBe(0);
});
+
it('should work with fromIndex being greater than the length', function () {
expect(testSubject.indexOf(0, 20)).toBe(-1);
});
+
it('should work with fromIndex being negative and greater than the length', function () {
expect(testSubject.indexOf('hej', -20)).toBe(4);
});
describe('Array-like', function ArrayLike() {
- var indexOf = Array.prototype.indexOf,
- testAL;
+ var indexOf = Array.prototype.indexOf;
+ var testAL;
+
beforeEach(function beforeEach() {
testAL = {};
- testSubject = [2, 3, undefined, true, 'hej', null, 2, false, 0];
+ testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0];
testSubject.forEach(function (o, i) {
testAL[i] = o;
});
testAL.length = testSubject.length;
});
+
it('should find the element (array-like)', function () {
expected = 4;
actual = indexOf.call(testAL, 'hej');
expect(actual).toBe(expected);
});
+
it('should not find the element (array-like)', function () {
expected = -1;
actual = indexOf.call(testAL, 'mus');
expect(actual).toBe(expected);
});
- it('should find undefined as well (array-like)', function () {
+
+ ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () {
expected = -1;
actual = indexOf.call(testAL, undefined);
expect(actual).not.toBe(expected);
});
- it('should skip unset indexes (array-like)', function () {
+
+ ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () {
expected = 2;
actual = indexOf.call(testAL, undefined);
expect(actual).toBe(expected);
});
+
it('should use a strict test (array-like)', function () {
actual = Array.prototype.indexOf.call(testAL, null);
expect(actual).toBe(5);
@@ -400,54 +439,63 @@ describe('Array', function () {
actual = Array.prototype.indexOf.call(testAL, '2');
expect(actual).toBe(-1);
});
+
it('should skip the first if fromIndex is set (array-like)', function () {
expect(indexOf.call(testAL, 2, 2)).toBe(6);
expect(indexOf.call(testAL, 2, 0)).toBe(0);
expect(indexOf.call(testAL, 2, 6)).toBe(6);
});
+
it('should work with negative fromIndex (array-like)', function () {
expect(indexOf.call(testAL, 2, -3)).toBe(6);
expect(indexOf.call(testAL, 2, -9)).toBe(0);
});
+
it('should work with fromIndex being greater than the length (array-like)', function () {
expect(indexOf.call(testAL, 0, 20)).toBe(-1);
});
+
it('should work with fromIndex being negative and greater than the length (array-like)', function () {
expect(indexOf.call(testAL, 'hej', -20)).toBe(4);
});
});
});
- describe('lastIndexOf', function () {
+ describe('#lastIndexOf()', function () {
'use strict';
var actual, expected;
beforeEach(function () {
- testSubject = [2, 3, undefined, true, 'hej', null, 2, 3, false, 0];
+ testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, 3, false, 0];
delete testSubject[1];
delete testSubject[7];
});
+
describe('Array', function () {
it('should find the element', function () {
expected = 4;
actual = testSubject.lastIndexOf('hej');
expect(actual).toBe(expected);
});
+
it('should not find the element', function () {
expected = -1;
actual = testSubject.lastIndexOf('mus');
expect(actual).toBe(expected);
});
- it('should find undefined as well', function () {
+
+ ifHasDenseUndefinedsIt('should find undefined as well', function () {
expected = -1;
actual = testSubject.lastIndexOf(undefined);
expect(actual).not.toBe(expected);
});
- it('should skip unset indexes', function () {
+
+ ifHasDenseUndefinedsIt('should skip unset indexes', function () {
expected = 2;
actual = testSubject.lastIndexOf(undefined);
expect(actual).toBe(expected);
});
+
it('should use a strict test', function () {
actual = testSubject.lastIndexOf(null);
expect(actual).toBe(5);
@@ -455,26 +503,31 @@ describe('Array', function () {
actual = testSubject.lastIndexOf('2');
expect(actual).toBe(-1);
});
+
it('should skip the first if fromIndex is set', function () {
expect(testSubject.lastIndexOf(2, 2)).toBe(0);
expect(testSubject.lastIndexOf(2, 0)).toBe(0);
expect(testSubject.lastIndexOf(2, 6)).toBe(6);
});
+
it('should work with negative fromIndex', function () {
expect(testSubject.lastIndexOf(2, -3)).toBe(6);
expect(testSubject.lastIndexOf(2, -9)).toBe(0);
});
+
it('should work with fromIndex being greater than the length', function () {
expect(testSubject.lastIndexOf(2, 20)).toBe(6);
});
+
it('should work with fromIndex being negative and greater than the length', function () {
expect(testSubject.lastIndexOf(2, -20)).toBe(-1);
});
});
describe('Array like', function () {
- var lastIndexOf = Array.prototype.lastIndexOf,
- testAL;
+ var lastIndexOf = Array.prototype.lastIndexOf;
+ var testAL;
+
beforeEach(function () {
testAL = {};
testSubject.forEach(function (o, i) {
@@ -482,26 +535,31 @@ describe('Array', function () {
});
testAL.length = testSubject.length;
});
+
it('should find the element (array-like)', function () {
expected = 4;
actual = lastIndexOf.call(testAL, 'hej');
expect(actual).toBe(expected);
});
+
it('should not find the element (array-like)', function () {
expected = -1;
actual = lastIndexOf.call(testAL, 'mus');
expect(actual).toBe(expected);
});
- it('should find undefined as well (array-like)', function () {
+
+ ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () {
expected = -1;
actual = lastIndexOf.call(testAL, undefined);
expect(actual).not.toBe(expected);
});
- it('should skip unset indexes (array-like)', function () {
+
+ ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () {
expected = 2;
actual = lastIndexOf.call(testAL, undefined);
expect(actual).toBe(expected);
});
+
it('should use a strict test (array-like)', function () {
actual = lastIndexOf.call(testAL, null);
expect(actual).toBe(5);
@@ -509,48 +567,52 @@ describe('Array', function () {
actual = lastIndexOf.call(testAL, '2');
expect(actual).toBe(-1);
});
+
it('should skip the first if fromIndex is set', function () {
expect(lastIndexOf.call(testAL, 2, 2)).toBe(0);
expect(lastIndexOf.call(testAL, 2, 0)).toBe(0);
expect(lastIndexOf.call(testAL, 2, 6)).toBe(6);
});
+
it('should work with negative fromIndex', function () {
expect(lastIndexOf.call(testAL, 2, -3)).toBe(6);
expect(lastIndexOf.call(testAL, 2, -9)).toBe(0);
});
+
it('should work with fromIndex being greater than the length', function () {
expect(lastIndexOf.call(testAL, 2, 20)).toBe(6);
});
+
it('should work with fromIndex being negative and greater than the length', function () {
expect(lastIndexOf.call(testAL, 2, -20)).toBe(-1);
});
});
});
- describe('filter', function () {
- var filteredArray,
- callback = function callback(o, i) {
- return i !== 3 && i !== 5;
- };
+ describe('#filter()', function () {
+ var filteredArray;
+ var callback = function callback(o, i) {
+ return i !== 3 && i !== 5;
+ };
beforeEach(function () {
- testSubject = [2, 3, undefined, true, 'hej', 3, null, false, 0];
+ testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', 3, null, false, 0];
delete testSubject[1];
- filteredArray = [2, undefined, 'hej', null, false, 0];
+ filteredArray = [2, undefinedIfNoSparseBug, 'hej', null, false, 0];
});
describe('Array object', function () {
-
it('should call the callback with the proper arguments', function () {
var predicate = jasmine.createSpy('predicate');
var arr = ['1'];
arr.filter(predicate);
expect(predicate).toHaveBeenCalledWith('1', 0, arr);
});
+
it('should not affect elements added to the array after it has begun', function () {
var arr = [1, 2, 3];
var i = 0;
arr.filter(function (a) {
- i++;
+ i += 1;
if (i <= 4) {
arr.push(a + 3);
}
@@ -559,7 +621,8 @@ describe('Array', function () {
expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
expect(i).toBe(3);
});
- it('should skip non-set values', function () {
+
+ ifHasDenseUndefinedsIt('should skip unset values', function () {
var passedValues = {};
testSubject = [1, 2, 3, 4];
delete testSubject[1];
@@ -569,6 +632,7 @@ describe('Array', function () {
});
expect(passedValues).toExactlyMatch(testSubject);
});
+
it('should pass the right context to the filter', function () {
var passedValues = {};
testSubject = [1, 2, 3, 4];
@@ -579,20 +643,24 @@ describe('Array', function () {
}, passedValues);
expect(passedValues).toExactlyMatch(testSubject);
});
+
it('should set the right context when given none', function () {
var context;
[1].filter(function () { context = this; });
expect(context).toBe(function () { return this; }.call());
});
+
it('should remove only the values for which the callback returns false', function () {
var result = testSubject.filter(callback);
expect(result).toExactlyMatch(filteredArray);
});
+
it('should leave the original array untouched', function () {
var copy = testSubject.slice();
testSubject.filter(callback);
expect(testSubject).toExactlyMatch(copy);
});
+
it('should not be affected by same-index mutation', function () {
var results = [1, 2, 3].filter(function (value, index, array) {
array[index] = 'a';
@@ -601,30 +669,34 @@ describe('Array', function () {
expect(results).toEqual([1, 2, 3]);
});
});
+
describe('Array like', function () {
beforeEach(function () {
testSubject = createArrayLikeFromArray(testSubject);
});
+
it('should call the predicate with the proper arguments', function () {
var predicate = jasmine.createSpy('predicate');
var arr = createArrayLikeFromArray(['1']);
Array.prototype.filter.call(arr, predicate);
expect(predicate).toHaveBeenCalledWith('1', 0, arr);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = createArrayLikeFromArray([1, 2, 3]),
- i = 0;
+ var arr = createArrayLikeFromArray([1, 2, 3]);
+ var i = 0;
Array.prototype.filter.call(arr, function (a) {
- i++;
+ i += 1;
if (i <= 4) {
arr[i + 2] = a + 3;
arr.length += 1;
}
return true;
});
- expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
+ expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]);
expect(i).toBe(3);
});
+
it('should skip non-set values', function () {
var passedValues = createArrayLikeFromArray([]);
testSubject = createArrayLikeFromArray([1, 2, 3, 4]);
@@ -636,11 +708,13 @@ describe('Array', function () {
});
expect(passedValues).toEqual(testSubject);
});
+
it('should set the right context when given none', function () {
var context;
Array.prototype.filter.call(createArrayLikeFromArray([1]), function () { context = this; }, undefined);
expect(context).toBe(function () { return this; }.call());
});
+
it('should pass the right context to the filter', function () {
var passedValues = {};
testSubject = createArrayLikeFromArray([1, 2, 3, 4]);
@@ -652,16 +726,19 @@ describe('Array', function () {
}, passedValues);
expect(passedValues).toEqual(testSubject);
});
+
it('should remove only the values for which the callback returns false', function () {
var result = Array.prototype.filter.call(testSubject, callback);
expect(result).toExactlyMatch(filteredArray);
});
+
it('should leave the original array untouched', function () {
var copy = createArrayLikeFromArray(testSubject);
Array.prototype.filter.call(testSubject, callback);
expect(testSubject).toExactlyMatch(copy);
});
});
+
it('should have a boxed object as list argument of callback', function () {
var actual;
Array.prototype.filter.call('foo', function (item, index, list) {
@@ -671,7 +748,7 @@ describe('Array', function () {
expect(toStr.call(actual)).toBe('[object String]');
});
});
- describe('map', function () {
+ describe('#map()', function () {
var callback;
beforeEach(function () {
var i = 0;
@@ -686,6 +763,7 @@ describe('Array', function () {
array.map(mapper);
expect(mapper).toHaveBeenCalledWith(1, 0, array);
});
+
it('should set the context correctly', function () {
var context = {};
testSubject.map(function (o, i) {
@@ -693,39 +771,44 @@ describe('Array', function () {
}, context);
expect(context).toExactlyMatch(testSubject);
});
+
it('should set the right context when given none', function () {
var context;
[1].map(function () { context = this; });
expect(context).toBe(function () { return this; }.call());
});
+
it('should not change the array it is called on', function () {
var copy = testSubject.slice();
testSubject.map(callback);
expect(testSubject).toExactlyMatch(copy);
});
+
it('should only run for the number of objects in the array when it started', function () {
- var arr = [1, 2, 3],
- i = 0;
+ var arr = [1, 2, 3];
+ var i = 0;
arr.map(function (o) {
arr.push(o + 3);
- i++;
+ i += 1;
return o;
});
expect(arr).toExactlyMatch([1, 2, 3, 4, 5, 6]);
expect(i).toBe(3);
});
+
it('should properly translate the values as according to the callback', function () {
- var result = testSubject.map(callback),
- expected = [0, 0, 1, 2, 3, 4, 5, 6];
+ var result = testSubject.map(callback);
+ var expected = [0, 0, 1, 2, 3, 4, 5, 6];
delete expected[1];
expect(result).toExactlyMatch(expected);
});
+
it('should skip non-existing values', function () {
- var array = [1, 2, 3, 4],
- i = 0;
+ var array = [1, 2, 3, 4];
+ var i = 0;
delete array[2];
array.map(function () {
- i++;
+ i += 1;
});
expect(i).toBe(3);
});
@@ -734,12 +817,14 @@ describe('Array', function () {
beforeEach(function () {
testSubject = createArrayLikeFromArray(testSubject);
});
+
it('should call mapper with the right parameters', function () {
var mapper = jasmine.createSpy('mapper');
var array = createArrayLikeFromArray([1]);
Array.prototype.map.call(array, mapper);
expect(mapper).toHaveBeenCalledWith(1, 0, array);
});
+
it('should set the context correctly', function () {
var context = {};
Array.prototype.map.call(testSubject, function (o, i) {
@@ -748,43 +833,49 @@ describe('Array', function () {
}, context);
expect(context).toEqual(testSubject);
});
+
it('should set the right context when given none', function () {
var context;
Array.prototype.map.call(createArrayLikeFromArray([1]), function () { context = this; });
expect(context).toBe(function () { return this; }.call());
});
+
it('should not change the array it is called on', function () {
var copy = createArrayLikeFromArray(testSubject);
Array.prototype.map.call(testSubject, callback);
expect(testSubject).toExactlyMatch(copy);
});
+
it('should only run for the number of objects in the array when it started', function () {
- var arr = createArrayLikeFromArray([1, 2, 3]),
- i = 0;
+ var arr = createArrayLikeFromArray([1, 2, 3]);
+ var i = 0;
Array.prototype.map.call(arr, function (o) {
Array.prototype.push.call(arr, o + 3);
- i++;
+ i += 1;
return o;
});
- expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
+ expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]);
expect(i).toBe(3);
});
+
it('should properly translate the values as according to the callback', function () {
- var result = Array.prototype.map.call(testSubject, callback),
- expected = [0, 0, 1, 2, 3, 4, 5, 6];
+ var result = Array.prototype.map.call(testSubject, callback);
+ var expected = [0, 0, 1, 2, 3, 4, 5, 6];
delete expected[1];
expect(result).toExactlyMatch(expected);
});
+
it('should skip non-existing values', function () {
- var array = createArrayLikeFromArray([1, 2, 3, 4]),
- i = 0;
+ var array = createArrayLikeFromArray([1, 2, 3, 4]);
+ var i = 0;
delete array[2];
Array.prototype.map.call(array, function () {
- i++;
+ i += 1;
});
expect(i).toBe(3);
});
});
+
it('should have a boxed object as list argument of callback', function () {
var actual;
Array.prototype.map.call('foo', function (item, index, list) {
@@ -795,7 +886,7 @@ describe('Array', function () {
});
});
- describe('reduce', function () {
+ describe('#reduce()', function () {
beforeEach(function () {
testSubject = [1, 2, 3];
});
@@ -806,16 +897,18 @@ describe('Array', function () {
testSubject.reduce(spy);
expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);
});
+
it('should start with the right initialValue', function () {
var spy = jasmine.createSpy().andReturn(0);
testSubject.reduce(spy, 0);
expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = [1, 2, 3],
- i = 0;
+ var arr = [1, 2, 3];
+ var i = 0;
arr.reduce(function (a, b) {
- i++;
+ i += 1;
if (i <= 4) {
arr.push(a + 3);
}
@@ -824,6 +917,7 @@ describe('Array', function () {
expect(arr).toEqual([1, 2, 3, 4, 5]);
expect(i).toBe(2);
});
+
it('should work as expected for empty arrays', function () {
var spy = jasmine.createSpy();
expect(function () {
@@ -831,16 +925,19 @@ describe('Array', function () {
}).toThrow();
expect(spy).not.toHaveBeenCalled();
});
+
it('should throw correctly if no callback is given', function () {
expect(function () {
testSubject.reduce();
}).toThrow();
});
+
it('should return the expected result', function () {
expect(testSubject.reduce(function (a, b) {
return String(a || '') + String(b || '');
- })).toEqual(testSubject.join(''));
+ })).toBe(testSubject.join(''));
});
+
it('should not directly affect the passed array', function () {
var copy = testSubject.slice();
testSubject.reduce(function (a, b) {
@@ -848,6 +945,7 @@ describe('Array', function () {
});
expect(testSubject).toEqual(copy);
});
+
it('should skip non-set values', function () {
delete testSubject[1];
var visited = {};
@@ -859,6 +957,7 @@ describe('Array', function () {
expect(visited).toEqual({ 1: true, 3: true });
});
+
it('should have the right length', function () {
expect(testSubject.reduce.length).toBe(1);
});
@@ -868,21 +967,24 @@ describe('Array', function () {
testSubject = createArrayLikeFromArray(testSubject);
testSubject.reduce = Array.prototype.reduce;
});
+
it('should pass the correct arguments to the callback', function () {
var spy = jasmine.createSpy().andReturn(0);
testSubject.reduce(spy);
expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);
});
+
it('should start with the right initialValue', function () {
var spy = jasmine.createSpy().andReturn(0);
testSubject.reduce(spy, 0);
expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = createArrayLikeFromArray([1, 2, 3]),
- i = 0;
+ var arr = createArrayLikeFromArray([1, 2, 3]);
+ var i = 0;
Array.prototype.reduce.call(arr, function (a, b) {
- i++;
+ i += 1;
if (i <= 4) {
arr[i + 2] = a + 3;
}
@@ -898,6 +1000,7 @@ describe('Array', function () {
});
expect(i).toBe(2);
});
+
it('should work as expected for empty arrays', function () {
var spy = jasmine.createSpy();
expect(function () {
@@ -905,16 +1008,19 @@ describe('Array', function () {
}).toThrow();
expect(spy).not.toHaveBeenCalled();
});
+
it('should throw correctly if no callback is given', function () {
expect(function () {
testSubject.reduce();
}).toThrow();
});
+
it('should return the expected result', function () {
expect(testSubject.reduce(function (a, b) {
return String(a || '') + String(b || '');
- })).toEqual('123');
+ })).toBe('123');
});
+
it('should not directly affect the passed array', function () {
var copy = createArrayLikeFromArray(testSubject);
testSubject.reduce(function (a, b) {
@@ -923,6 +1029,7 @@ describe('Array', function () {
delete testSubject.reduce;
expect(testSubject).toEqual(copy);
});
+
it('should skip non-set values', function () {
delete testSubject[1];
var visited = {};
@@ -934,10 +1041,12 @@ describe('Array', function () {
expect(visited).toEqual({ 1: true, 3: true });
});
+
it('should have the right length', function () {
expect(testSubject.reduce.length).toBe(1);
});
});
+
it('should have a boxed object as list argument of callback', function () {
var actual;
Array.prototype.reduce.call('foo', function (accumulator, item, index, list) {
@@ -947,7 +1056,7 @@ describe('Array', function () {
expect(toStr.call(actual)).toBe('[object String]');
});
});
- describe('reduceRight', function () {
+ describe('#reduceRight()', function () {
beforeEach(function () {
testSubject = [1, 2, 3];
});
@@ -958,16 +1067,18 @@ describe('Array', function () {
testSubject.reduceRight(spy);
expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);
});
+
it('should start with the right initialValue', function () {
var spy = jasmine.createSpy().andReturn(0);
testSubject.reduceRight(spy, 0);
expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = [1, 2, 3],
- i = 0;
+ var arr = [1, 2, 3];
+ var i = 0;
arr.reduceRight(function (a, b) {
- i++;
+ i += 1;
if (i <= 4) {
arr.push(a + 3);
}
@@ -976,6 +1087,7 @@ describe('Array', function () {
expect(arr).toEqual([1, 2, 3, 6, 5]);
expect(i).toBe(2);
});
+
it('should work as expected for empty arrays', function () {
var spy = jasmine.createSpy();
expect(function () {
@@ -983,24 +1095,28 @@ describe('Array', function () {
}).toThrow();
expect(spy).not.toHaveBeenCalled();
});
+
it('should work as expected for empty arrays with an initial value', function () {
- var spy = jasmine.createSpy(),
- result;
+ var spy = jasmine.createSpy();
+ var result;
result = [].reduceRight(spy, '');
expect(spy).not.toHaveBeenCalled();
expect(result).toBe('');
});
+
it('should throw correctly if no callback is given', function () {
expect(function () {
testSubject.reduceRight();
}).toThrow();
});
+
it('should return the expected result', function () {
expect(testSubject.reduceRight(function (a, b) {
return String(a || '') + String(b || '');
})).toBe('321');
});
+
it('should not directly affect the passed array', function () {
var copy = testSubject.slice();
testSubject.reduceRight(function (a, b) {
@@ -1008,6 +1124,7 @@ describe('Array', function () {
});
expect(testSubject).toEqual(copy);
});
+
it('should skip non-set values', function () {
delete testSubject[1];
var visited = {};
@@ -1019,6 +1136,7 @@ describe('Array', function () {
expect(visited).toEqual({ 1: true, 3: true });
});
+
it('should have the right length', function () {
expect(testSubject.reduceRight.length).toBe(1);
});
@@ -1028,21 +1146,24 @@ describe('Array', function () {
testSubject = createArrayLikeFromArray(testSubject);
testSubject.reduceRight = Array.prototype.reduceRight;
});
+
it('should pass the correct arguments to the callback', function () {
var spy = jasmine.createSpy().andReturn(0);
testSubject.reduceRight(spy);
expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);
});
+
it('should start with the right initialValue', function () {
var spy = jasmine.createSpy().andReturn(0);
testSubject.reduceRight(spy, 0);
expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);
});
+
it('should not affect elements added to the array after it has begun', function () {
- var arr = createArrayLikeFromArray([1, 2, 3]),
- i = 0;
+ var arr = createArrayLikeFromArray([1, 2, 3]);
+ var i = 0;
Array.prototype.reduceRight.call(arr, function (a, b) {
- i++;
+ i += 1;
if (i <= 4) {
arr[i + 2] = a + 3;
}
@@ -1058,6 +1179,7 @@ describe('Array', function () {
});
expect(i).toBe(2);
});
+
it('should work as expected for empty arrays', function () {
var spy = jasmine.createSpy();
expect(function () {
@@ -1065,16 +1187,19 @@ describe('Array', function () {
}).toThrow();
expect(spy).not.toHaveBeenCalled();
});
+
it('should throw correctly if no callback is given', function () {
expect(function () {
testSubject.reduceRight();
}).toThrow();
});
+
it('should return the expected result', function () {
expect(testSubject.reduceRight(function (a, b) {
return String(a || '') + String(b || '');
- })).toEqual('321');
+ })).toBe('321');
});
+
it('should not directly affect the passed array', function () {
var copy = createArrayLikeFromArray(testSubject);
testSubject.reduceRight(function (a, b) {
@@ -1083,6 +1208,7 @@ describe('Array', function () {
delete testSubject.reduceRight;
expect(testSubject).toEqual(copy);
});
+
it('should skip non-set values', function () {
delete testSubject[1];
var visited = {};
@@ -1094,10 +1220,12 @@ describe('Array', function () {
expect(visited).toEqual({ 1: true, 3: true });
});
+
it('should have the right length', function () {
expect(testSubject.reduceRight.length).toBe(1);
});
});
+
it('should have a boxed object as list argument of callback', function () {
var actual;
Array.prototype.reduceRight.call('foo', function (accumulator, item, index, list) {
@@ -1108,7 +1236,7 @@ describe('Array', function () {
});
});
- describe('isArray', function () {
+ describe('.isArray()', function () {
it('should be true for Array', function () {
expect(Array.isArray([])).toBe(true);
});
@@ -1154,13 +1282,59 @@ describe('Array', function () {
}
});
- describe('unshift', function () {
+ describe('#shift()', function () {
+ it('works on arrays', function () {
+ var arr = [1, 2];
+ var result = arr.shift();
+ expect(result).toBe(1);
+ expect(arr.length).toBe(1);
+ expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);
+ expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(false);
+ expect(arr[0]).toBe(2);
+ expect(arr[1]).toBeUndefined();
+ });
+
+ it('is generic', function () {
+ var obj = { 0: 1, 1: 2, length: 2 };
+ var result = Array.prototype.shift.call(obj);
+ expect(result).toBe(1);
+ expect(obj.length).toBe(1);
+ expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);
+ expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(false);
+ expect(obj[0]).toBe(2);
+ expect(obj[1]).toBeUndefined();
+ });
+ });
+
+ describe('#unshift()', function () {
it('should return length', function () {
expect([].unshift(0)).toBe(1);
});
+
+ it('works on arrays', function () {
+ var arr = [1];
+ var result = arr.unshift(undefined);
+ expect(result).toBe(2);
+ expect(arr.length).toBe(2);
+ expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);
+ expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(true);
+ expect(arr[0]).toBeUndefined();
+ expect(arr[1]).toBe(1);
+ });
+
+ it('is generic', function () {
+ var obj = { 0: 1, length: 1 };
+ var result = Array.prototype.unshift.call(obj, undefined);
+ expect(result).toBe(2);
+ expect(obj.length).toBe(2);
+ expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);
+ expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(true);
+ expect(obj[0]).toBeUndefined();
+ expect(obj[1]).toBe(1);
+ });
});
- describe('splice', function () {
+ describe('#splice()', function () {
var b = ['b'];
var a = [1, 'a', b];
var test;
@@ -1292,7 +1466,7 @@ describe('Array', function () {
expect(obj[0]).toBe(1);
});
- it('should not break on sparse arrays in Opera', function () {
+ ifHasDenseUndefinedsIt('should not break on sparse arrays in Opera', function () {
// test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196
var n = 256;
var arr = [];
@@ -1301,7 +1475,7 @@ describe('Array', function () {
expect(arr[n]).toBe('a');
});
- it('should not break on sparse arrays in Safari 7/8', function () {
+ ifHasDenseUndefinedsIt('should not break on sparse arrays in Safari 7/8', function () {
// test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196
var justFine = new Array(1e5 - 1);
justFine[10] = 'x';
@@ -1317,4 +1491,472 @@ describe('Array', function () {
});
});
+ describe('#join()', function () {
+ it('defaults to a comma separator when none is provided', function () {
+ expect([1, 2].join()).toBe('1,2');
+ });
+
+ it('defaults to a comma separator when undefined is provided', function () {
+ expect([1, 2].join(undefined)).toBe('1,2');
+ });
+
+ it('works, extended', function () {
+ expect([].join()).toBe('');
+ expect([undefined].join()).toBe('');
+ expect([undefined, undefined].join()).toBe(',');
+ expect([null, null].join()).toBe(',');
+ expect([undefined, undefined].join('|')).toBe('|');
+ expect([null, null].join('|')).toBe('|');
+ expect([1, 2, 3].join('|')).toBe('1|2|3');
+ expect([1, 2, 3].join(null)).toBe('1null2null3');
+ expect([1, 2, 3].join({})).toBe('1[object Object]2[object Object]3');
+ expect([1, 2, 3].join('')).toBe('123');
+ });
+
+ it('is generic', function () {
+ var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 3 };
+ expect(Array.prototype.join.call(obj, ',')).toBe('1,2,3');
+ });
+
+ it('works with a string literal', function () {
+ var str = '123';
+ expect(Array.prototype.join.call(str, ',')).toBe('1,2,3');
+ });
+
+ it('works with `arguments`', function () {
+ var args = (function () { return arguments; }(1, 2, 3));
+ expect(Array.prototype.join.call(args, ',')).toBe('1,2,3');
+ });
+ });
+
+ describe('#push()', function () {
+ it('works on arrays', function () {
+ var arr = [];
+ var result = arr.push(undefined);
+ expect(result).toBe(1);
+ expect(arr.length).toBe(1);
+ expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);
+ expect(arr[0]).toBeUndefined();
+ });
+
+ it('is generic', function () {
+ var obj = {};
+ var result = Array.prototype.push.call(obj, undefined);
+ expect(result).toBe(1);
+ expect(obj.length).toBe(1);
+ expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);
+ expect(obj[0]).toBeUndefined();
+ });
+ });
+
+ describe('#pop()', function () {
+ it('works on arrays', function () {
+ var arr = [1, 2, 3];
+ var result = arr.pop();
+ expect(result).toBe(3);
+ expect(arr.length).toBe(2);
+ expect(Object.prototype.hasOwnProperty.call(arr, 2)).toBe(false);
+ expect(arr[2]).toBeUndefined();
+ });
+
+ it('is generic', function () {
+ var obj = { 0: 1, 1: 2, 2: 3, length: 3 };
+ var result = Array.prototype.pop.call(obj);
+ expect(result).toBe(3);
+ expect(obj.length).toBe(2);
+ expect(Object.prototype.hasOwnProperty.call(obj, 2)).toBe(false);
+ expect(obj[2]).toBeUndefined();
+ });
+ });
+
+ describe('#slice()', function () {
+ it('works on arrays', function () {
+ var arr = [1, 2, 3, 4];
+ var result = arr.slice(1, 3);
+ expect(result).toEqual([2, 3]);
+ });
+
+ it('is generic', function () {
+ var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 };
+ var result = Array.prototype.slice.call(obj, 1, 3);
+ expect(result).toEqual([2, 3]);
+ });
+
+ it('works with `arguments`', function () {
+ var obj = (function () {
+ return arguments;
+ }(1, 2, 3, 4));
+ var result = Array.prototype.slice.call(obj, 1, 3);
+ expect(result).toEqual([2, 3]);
+ });
+
+ it('boxed string access', function () {
+ var obj = '1234';
+ var result = Array.prototype.slice.call(obj, 1, 3);
+ expect(result).toEqual(['2', '3']);
+ });
+ });
+
+ describe('#sort()', function () {
+ describe('usage', function () {
+ it('requires a function or undefined as first argument', function () {
+ var actual = [1, 2];
+ expect(actual.sort()).toBe(actual);
+ expect(actual.sort(undefined)).toBe(actual);
+ expect(actual.sort(function () { return 0; })).toBe(actual);
+ });
+
+ it('requires a non-function or non-undefined to throw a `TypeError`', function () {
+ expect(function () { [1, 2].sort(null); }).toThrow();
+ expect(function () { [1, 2].sort(1); }).toThrow();
+ expect(function () { [1, 2].sort(''); }).toThrow();
+ expect(function () { [1, 2].sort(true); }).toThrow();
+ expect(function () { [1, 2].sort({}); }).toThrow();
+ expect(function () { [1, 2].sort([]); }).toThrow();
+ expect(function () { [1, 2].sort(new Date()); }).toThrow();
+ expect(function () { [1, 2].sort(/pattern/); }).toThrow();
+ });
+ });
+
+ describe('ascending', function () {
+ it('[5,2,4,6,1,3] should result in [1,2,3,4,5,6]', function () {
+ var actual = [5, 2, 4, 6, 1, 3];
+ var expected = [1, 2, 3, 4, 5, 6];
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[5,2,2,6,1,3] should result in [1,2,2,3,5,6]', function () {
+ var actual = [5, 2, 2, 6, 1, 3];
+ var expected = [1, 2, 2, 3, 5, 6];
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[0,0,0,0,0,1] should result in [0,0,0,0,0,1]', function () {
+ var actual = [0, 0, 0, 0, 0, 1];
+ var expected = [0, 0, 0, 0, 0, 1];
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[0,0,0,0,0,-1] should result in [-1,0,0,0,0,0]', function () {
+ var actual = [0, 0, 0, 0, 0, -1];
+ var expected = [-1, 0, 0, 0, 0, 0];
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,a,c,b] should result in [a,b,c,d,e,f]', function () {
+ var actual = ['f', 'e', 'd', 'a', 'c', 'b'];
+ var expected = ['a', 'b', 'c', 'd', 'e', 'f'];
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,,,,a,c,b] should result in [a,b,c,d,e,f,,,]', function () {
+ var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b'];
+ delete actual[3];
+ delete actual[4];
+ var expected = ['a', 'b', 'c', 'd', 'e', 'f'];
+ expected.length = 8;
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,,null,,a,c,b] should result in [a,b,c,d,e,f,null,,,]', function () {
+ var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b'];
+ delete actual[3];
+ delete actual[5];
+ var expected = ['a', 'b', 'c', 'd', 'e', 'f', null];
+ expected.length = 9;
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,,null,undefined,a,c,b] should result in [a,b,c,d,e,f,null,undefined,,]', function () {
+ var actual = ['f', 'e', 'd', 1, null, undefined, 'a', 'c', 'b'];
+ delete actual[3];
+ var expected = ['a', 'b', 'c', 'd', 'e', 'f', null, undefined];
+ expected.length = 9;
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[] should result in []', function () {
+ var actual = [];
+ var expected = [];
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('[1] should result in [1]', function () {
+ var actual = [1];
+ var expected = [1];
+ actual.sort();
+ expect(actual).toEqual(expected);
+ });
+
+ it('result should find only greater or equal values', function () {
+ var actual = [];
+ var i;
+ for (i = 0; i < 100; i += 1) {
+ actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3));
+ }
+ actual.sort();
+ for (i = 0; i < actual.length - 1; i += 1) {
+ expect(actual[i] <= actual[i + 1]).toBe(true);
+ }
+ });
+ });
+
+ describe('descending', function () {
+ var descending = function (left, right) {
+ var leftS = String(left);
+ var rightS = String(right);
+ if (leftS === rightS) {
+ return +0;
+ }
+ if (leftS < rightS) {
+ return 1;
+ }
+ return -1;
+ };
+
+ it('[5,2,4,6,1,3] should result in [6,5,4,3,2,1]', function () {
+ var actual = [5, 2, 4, 6, 1, 3];
+ var expected = [6, 5, 4, 3, 2, 1];
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[5,2,2,6,1,3] should result in [6,5,4,2,2,1]', function () {
+ var actual = [5, 2, 2, 6, 1, 3];
+ var expected = [6, 5, 3, 2, 2, 1];
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[0,0,0,0,0,1] should result in [1,0,0,0,0,0]', function () {
+ var actual = [0, 0, 0, 0, 0, 1];
+ var expected = [1, 0, 0, 0, 0, 0];
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[0,0,0,0,0,-1] should result in [0,0,0,0,0,-1]', function () {
+ var actual = [0, 0, 0, 0, 0, -1];
+ var expected = [0, 0, 0, 0, 0, -1];
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,a,c,b] should result in [f,e,d,c,b,a]', function () {
+ var actual = ['f', 'e', 'd', 'a', 'c', 'b'];
+ var expected = ['f', 'e', 'd', 'c', 'b', 'a'];
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,,,a,c,b] should result in [f,e,d,c,b,a,,,]', function () {
+ var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b'];
+ delete actual[3];
+ delete actual[4];
+ var expected = ['f', 'e', 'd', 'c', 'b', 'a'];
+ expected.length = 8;
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,,null,,a,c,b] should result in [null,f,e,d,c,b,a,,,]', function () {
+ var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b'];
+ delete actual[3];
+ delete actual[5];
+ var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a'];
+ expected.length = 9;
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[f,e,d,undefined,null,,a,c,b] should result in [null,f,e,d,c,b,a,undefined,,]', function () {
+ var actual = ['f', 'e', 'd', undefined, null, 2, 'a', 'c', 'b'];
+ delete actual[5];
+ var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a', undefined];
+ expected.length = 9;
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[] should result in []', function () {
+ var actual = [];
+ var expected = [];
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('[1] should result in [1]', function () {
+ var actual = [1];
+ var expected = [1];
+ actual.sort(descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('result should find only lesser or equal values', function () {
+ var actual = [];
+ var i;
+ for (i = 0; i < 100; i += 1) {
+ actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3));
+ }
+ actual.sort(descending);
+ for (i = 0; i < actual.length - 1; i += 1) {
+ expect(actual[i] >= actual[i + 1]).toBe(true);
+ }
+ });
+ });
+
+ describe('returned value', function () {
+ it('should be the source object', function () {
+ var actual = [1, 3, 2];
+ expect(actual.sort()).toBe(actual);
+ });
+ });
+
+ describe('when used generically', function () {
+ var descending = function (left, right) {
+ var leftS = String(left);
+ var rightS = String(right);
+ if (leftS === rightS) {
+ return +0;
+ }
+ if (leftS < rightS) {
+ return 1;
+ }
+ return -1;
+ };
+
+ var args = function () {
+ return arguments;
+ };
+
+ it('should not sort objects without length', function () {
+ var actual = {
+ 0: 5,
+ 1: 2,
+ 2: 4,
+ 3: 6,
+ 4: 1,
+ 5: 3
+ };
+ var expected = {
+ 0: 5,
+ 1: 2,
+ 2: 4,
+ 3: 6,
+ 4: 1,
+ 5: 3
+ };
+ Array.prototype.sort.call(actual);
+ expect(actual).toEqual(expected);
+ Array.prototype.sort.call(actual, descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('should sort objects ascending with length', function () {
+ var actual = {
+ 0: 5,
+ 1: 2,
+ 2: 4,
+ 3: 6,
+ 4: 1,
+ 5: 3,
+ length: 6
+ };
+ var expected = {
+ 0: 1,
+ 1: 2,
+ 2: 3,
+ 3: 4,
+ 4: 5,
+ 5: 6,
+ length: 6
+ };
+ Array.prototype.sort.call(actual);
+ expect(actual).toEqual(expected);
+ });
+
+ it('should sort objects descending with length', function () {
+ var actual = {
+ 0: 5,
+ 1: 2,
+ 2: 4,
+ 3: 6,
+ 4: 1,
+ 5: 3,
+ length: 6
+ };
+ var expected = {
+ 0: 6,
+ 1: 5,
+ 2: 4,
+ 3: 3,
+ 4: 2,
+ 5: 1,
+ length: 6
+ };
+ Array.prototype.sort.call(actual, descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('should sort objects descending with mixed content types and with length', function () {
+ var actual = {
+ 0: 5,
+ 1: 2,
+ 2: 4,
+ 4: null,
+ 6: 1,
+ 7: 3,
+ length: 8
+ };
+ var expected = {
+ 0: null,
+ 1: 5,
+ 2: 4,
+ 3: 3,
+ 4: 2,
+ 5: 1,
+ length: 8
+ };
+ Array.prototype.sort.call(actual, descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('should sort `arguments` object ascending', function () {
+ var actual = args(5, 2, 4, 6, 1, 3);
+ var expected = args(1, 2, 3, 4, 5, 6);
+ Array.prototype.sort.call(actual);
+ expect(actual).toEqual(expected);
+ });
+
+ it('should sort `arguments` object ascending with mixed content types', function () {
+ var actual = args(5, 2, 4, null, 1, 3);
+ var expected = args(1, 2, 3, 4, 5, null);
+ Array.prototype.sort.call(actual);
+ expect(actual).toEqual(expected);
+ });
+
+ it('should sort `arguments` object descending', function () {
+ var actual = args(5, 2, 4, 6, 1, 3);
+ var expected = args(6, 5, 4, 3, 2, 1);
+ Array.prototype.sort.call(actual, descending);
+ expect(actual).toEqual(expected);
+ });
+
+ it('should sort `arguments` object descending with mixed content types', function () {
+ var actual = args(5, 2, 4, null, 1, 3);
+ var expected = args(null, 5, 4, 3, 2, 1);
+ Array.prototype.sort.call(actual, descending);
+ expect(actual).toEqual(expected);
+ });
+ });
+ });
});
diff --git a/tests/spec/s-date.js b/tests/spec/s-date.js
index 49858f9..c43d64b 100644
--- a/tests/spec/s-date.js
+++ b/tests/spec/s-date.js
@@ -16,7 +16,7 @@ describe('Date', function () {
var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit;
var has = Object.prototype.hasOwnProperty;
- describe('now', function () {
+ describe('.now()', function () {
it('should be the current time', function () {
var before = (new Date()).getTime();
var middle = Date.now();
@@ -49,7 +49,8 @@ describe('Date', function () {
});
it('works as a function', function () {
- expect(Date(0)).toBe(String(Date(0)));
+ var zeroDate = Date(0);
+ expect(zeroDate).toBe(String(zeroDate));
var value = Date(1441705534578);
expect(value).toBe(String(value));
});
@@ -75,7 +76,7 @@ describe('Date', function () {
});
});
- describe('parse', function () {
+ describe('.parse()', function () {
// TODO: Write the rest of the test.
ifSupportsDescriptorsIt('is not enumerable', function () {
@@ -167,13 +168,13 @@ describe('Date', function () {
var actual = Number(new Date(1970, 0));
var expected = parseInt(actual, 10);
expect(actual).toBeDefined();
- expect(actual).toEqual(expected);
+ expect(actual).toBe(expected);
expect(isNaN(actual)).toBeFalsy();
});
});
- describe('toString', function () {
+ describe('#toString()', function () {
var actual;
beforeEach(function () {
@@ -188,7 +189,7 @@ describe('Date', function () {
});
});
- describe('valueOf', function () {
+ describe('#valueOf()', function () {
// Note that new Date(1970, 0).valueOf() is 0 in UTC timezone.
// Check check that it's a number (and an int), not that it's "truthy".
var actual;
@@ -207,14 +208,14 @@ describe('Date', function () {
});
});
- describe('getUTCDate', function () {
+ describe('#getUTCDate()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(new Date(-3509827334573292).getUTCDate()).toBe(1);
});
});
- describe('getUTCMonth', function () {
+ describe('#getUTCMonth()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(new Date(-3509827334573292).getUTCMonth()).toBe(0);
@@ -226,7 +227,7 @@ describe('Date', function () {
});
});
- describe('toISOString', function () {
+ describe('#toISOString()', function () {
// TODO: write the rest of the test.
it('should support extended years', function () {
@@ -241,7 +242,7 @@ describe('Date', function () {
});
- describe('toJSON', function () {
+ describe('#toJSON()', function () {
// Opera 11.6x/12 bug
it('should call toISOString', function () {
diff --git a/tests/spec/s-error.js b/tests/spec/s-error.js
new file mode 100644
index 0000000..7f38bab
--- /dev/null
+++ b/tests/spec/s-error.js
@@ -0,0 +1,50 @@
+/* global describe, it, xit, expect */
+
+describe('Error', function () {
+ 'use strict';
+
+ var supportsDescriptors = Object.defineProperty && (function () {
+ try {
+ var obj = {};
+ Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
+ for (var _ in obj) { return false; }
+ return obj.x === obj;
+ } catch (e) { /* this is ES3 */
+ return false;
+ }
+ }());
+ var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit;
+
+ describe('#toString()', function () {
+ it('stringifies a newed error properly', function () {
+ var msg = 'test';
+ var error = new RangeError(msg);
+ expect(error.name).toBe('RangeError');
+ expect(error.message).toBe(msg);
+ expect(String(error)).toBe(error.name + ': ' + msg);
+ });
+
+ it('stringifies a thrown error properly', function () {
+ var msg = 'test';
+ var error;
+ try {
+ throw new RangeError(msg);
+ } catch (e) {
+ error = e;
+ }
+ expect(error.name).toBe('RangeError');
+ expect(error.message).toBe(msg);
+ expect(String(error)).toBe(error.name + ': ' + msg);
+ });
+ });
+
+ describe('enumerability of prototype properties', function () {
+ ifSupportsDescriptorsIt('#message', function () {
+ expect(Object.prototype.propertyIsEnumerable.call(Error.prototype, 'message')).toBe(false);
+ });
+
+ ifSupportsDescriptorsIt('#name', function () {
+ expect(Object.prototype.propertyIsEnumerable.call(Error.prototype, 'name')).toBe(false);
+ });
+ });
+});
diff --git a/tests/spec/s-function.js b/tests/spec/s-function.js
index de84946..97237ad 100644
--- a/tests/spec/s-function.js
+++ b/tests/spec/s-function.js
@@ -3,7 +3,7 @@
describe('Function', function () {
'use strict';
- describe('apply', function () {
+ describe('#apply()', function () {
it('works with arraylike objects', function () {
var arrayLike = { length: 4, 0: 1, 2: 4, 3: true };
var expectedArray = [1, undefined, 4, true];
@@ -14,7 +14,7 @@ describe('Function', function () {
});
});
- describe('bind', function () {
+ describe('#bind()', function () {
var actual;
var testSubject = {
diff --git a/tests/spec/s-global.js b/tests/spec/s-global.js
index 81f03c6..4c0c97a 100644
--- a/tests/spec/s-global.js
+++ b/tests/spec/s-global.js
@@ -8,6 +8,8 @@ describe('global methods', function () {
var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
describe('parseInt', function () {
+ /* eslint-disable radix */
+
ifFunctionsHaveNamesIt('has the right name', function () {
expect(parseInt.name).toBe('parseInt');
});
@@ -46,10 +48,18 @@ describe('global methods', function () {
expect(parseInt(ws + '0x16')).toBe(parseInt('0x16', 16));
});
- it('defaults the radix properly when not a true number', function () {
- var fakeZero = { valueOf: function () { return 0; } };
- expect(parseInt('08', fakeZero)).toBe(parseInt('08', 10));
- expect(parseInt('0x16', fakeZero)).toBe(parseInt('0x16', 16));
- });
+ it('defaults the radix properly when not a true number', function () {
+ var fakeZero = { valueOf: function () { return 0; } };
+ expect(parseInt('08', fakeZero)).toBe(parseInt('08', 10));
+ expect(parseInt('0x16', fakeZero)).toBe(parseInt('0x16', 16));
+ });
+
+ it('allows sign-prefixed hex values', function () {
+ expect(parseInt('-0xF')).toBe(-15);
+ expect(parseInt('-0xF', 16)).toBe(-15);
+ expect(parseInt('+0xF')).toBe(15);
+ expect(parseInt('+0xF', 16)).toBe(15);
+ });
+ /* eslint-enable radix */
});
});
diff --git a/tests/spec/s-number.js b/tests/spec/s-number.js
index 9955486..441a7a9 100644
--- a/tests/spec/s-number.js
+++ b/tests/spec/s-number.js
@@ -3,7 +3,7 @@
describe('Number', function () {
'use strict';
- describe('toFixed', function () {
+ describe('#toFixed()', function () {
it('should convert numbers correctly', function () {
expect((0.00008).toFixed(3)).toBe('0.000');
expect((0.9).toFixed(0)).toBe('1');
@@ -13,6 +13,28 @@ describe('Number', function () {
});
});
+ describe('#toPrecision()', function () {
+ // the spec allows for this test to fail.
+ it('throws a RangeError when < 1 or > 21', function () {
+ expect(function () { return (0.9).toPrecision(0); }).toThrow();
+ // Firefox allows values up to 100
+ expect(function () { return (0.9).toPrecision(101); }).toThrow();
+ });
+
+ it('works as expected', function () {
+ expect((0.00008).toPrecision(3)).toBe('0.0000800');
+ expect((1.255).toPrecision(2)).toBe('1.3');
+ expect((1843654265.0774949).toPrecision(13)).toBe('1843654265.077');
+ expect(NaN.toPrecision(1)).toBe('NaN');
+ });
+
+ it('works with an undefined precision', function () {
+ var num = 123.456;
+ expect(num.toPrecision()).toBe(String(num));
+ expect(num.toPrecision(undefined)).toBe(String(num));
+ });
+ });
+
describe('constants', function () {
it('should have MAX_VALUE', function () {
expect(Number.MAX_VALUE).toBe(1.7976931348623157e308);
diff --git a/tests/spec/s-object.js b/tests/spec/s-object.js
index a86878d..3065c66 100644
--- a/tests/spec/s-object.js
+++ b/tests/spec/s-object.js
@@ -1,5 +1,15 @@
/* global describe, it, xit, expect, beforeEach, jasmine, window */
+var supportsDescriptors = Object.defineProperty && (function () {
+ try {
+ var obj = {};
+ Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
+ for (var _ in obj) { return false; }
+ return obj.x === obj;
+ } catch (e) { /* this is ES3 */
+ return false;
+ }
+}());
var ifWindowIt = typeof window === 'undefined' ? xit : it;
var extensionsPreventible = typeof Object.preventExtensions === 'function' && (function () {
var obj = {};
@@ -130,8 +140,8 @@ describe('Object', function () {
ifWindowIt('can serialize all objects on the `window`', function () {
var has = Object.prototype.hasOwnProperty;
var windowItemKeys, exception;
- var blacklistedKeys = ['window', 'console', 'parent', 'self', 'frame', 'frames', 'frameElement'];
- if (Object.defineProperty) {
+ var blacklistedKeys = ['window', 'console', 'parent', 'self', 'frame', 'frames', 'frameElement', 'external'];
+ if (supportsDescriptors) {
Object.defineProperty(window, 'thrower', { configurable: true, get: function () { throw new RangeError('thrower!'); } });
}
for (var k in window) {
@@ -142,15 +152,17 @@ describe('Object', function () {
} catch (e) {
exception = e;
}
- expect(Array.isArray(windowItemKeys)).toEqual(true);
+ expect(Array.isArray(windowItemKeys)).toBe(true);
expect(exception).toBeUndefined();
}
}
- delete window.thrower;
+ if (supportsDescriptors) {
+ delete window.thrower;
+ }
});
});
- describe('Object.isExtensible', function () {
+ describe('.isExtensible()', function () {
var obj = { };
it('should return true if object is extensible', function () {
@@ -179,7 +191,7 @@ describe('Object', function () {
});
});
- describe('Object.defineProperty', function () {
+ describe('.defineProperty()', function () {
var obj;
beforeEach(function () {
@@ -234,7 +246,7 @@ describe('Object', function () {
});
});
- describe('Object.getOwnPropertyDescriptor', function () {
+ describe('.getOwnPropertyDescriptor()', function () {
it('should return undefined because the object does not own the property', function () {
var descr = Object.getOwnPropertyDescriptor({}, 'name');
@@ -243,12 +255,14 @@ describe('Object', function () {
it('should return a data descriptor', function () {
var descr = Object.getOwnPropertyDescriptor({ name: 'Testing' }, 'name');
+ var expected = {
+ value: 'Testing',
+ enumerable: true,
+ writable: true,
+ configurable: true
+ };
- expect(descr).not.toBeUndefined();
- expect(descr.value).toBe('Testing');
- expect(descr.writable).toBe(true);
- expect(descr.enumerable).toBe(true);
- expect(descr.configurable).toBe(true);
+ expect(descr).toEqual(expected);
});
it('should return undefined because the object does not own the property', function () {
@@ -258,22 +272,17 @@ describe('Object', function () {
});
it('should return a data descriptor', function () {
- var obj = Object.create({}, {
- name: {
- value: 'Testing',
- configurable: true,
- enumerable: true,
- writable: true
- }
- });
+ var expected = {
+ value: 'Testing',
+ configurable: true,
+ enumerable: true,
+ writable: true
+ };
+ var obj = Object.create({}, { name: expected });
var descr = Object.getOwnPropertyDescriptor(obj, 'name');
- expect(descr).not.toBeUndefined();
- expect(descr.value).toBe('Testing');
- expect(descr.writable).toBe(true);
- expect(descr.enumerable).toBe(true);
- expect(descr.configurable).toBe(true);
+ expect(descr).toEqual(expected);
});
it('should throw error for non object', function () {
@@ -286,7 +295,7 @@ describe('Object', function () {
});
});
- describe('Object.getPrototypeOf', function () {
+ describe('.getPrototypeOf()', function () {
it('should return the [[Prototype]] of an object', function () {
var Foo = function () {};
@@ -320,11 +329,11 @@ describe('Object', function () {
it('should return null on Object.create(null)', function () {
var obj = Object.create(null);
- expect(Object.getPrototypeOf(obj)).toBe(null);
+ expect(Object.getPrototypeOf(obj) === null).toBe(true);
});
});
- describe('Object.defineProperties', function () {
+ describe('.defineProperties()', function () {
it('should define the constructor property', function () {
var target = {};
var newProperties = {
@@ -333,11 +342,11 @@ describe('Object', function () {
}
};
Object.defineProperties(target, newProperties);
- expect(target.constructor).toEqual('new constructor');
+ expect(target.constructor).toBe('new constructor');
});
});
- describe('Object.create', function () {
+ describe('.create()', function () {
it('should create objects with no properties when called as `Object.create(null)`', function () {
var obj = Object.create(null);
diff --git a/tests/spec/s-regexp.js b/tests/spec/s-regexp.js
new file mode 100644
index 0000000..a336602
--- /dev/null
+++ b/tests/spec/s-regexp.js
@@ -0,0 +1,27 @@
+/* global describe, it, expect */
+
+describe('RegExp', function () {
+ 'use strict';
+
+ describe('#toString()', function () {
+ describe('literals', function () {
+ it('should return correct flags and in correct order', function () {
+ expect(String(/pattern/)).toBe('/pattern/');
+ expect(String(/pattern/i)).toBe('/pattern/i');
+ expect(String(/pattern/mi)).toBe('/pattern/im');
+ expect(String(/pattern/im)).toBe('/pattern/im');
+ expect(String(/pattern/mgi)).toBe('/pattern/gim');
+ });
+ });
+
+ describe('objects', function () {
+ it('should return correct flags and in correct order', function () {
+ expect(String(new RegExp('pattern'))).toBe('/pattern/');
+ expect(String(new RegExp('pattern', 'i'))).toBe('/pattern/i');
+ expect(String(new RegExp('pattern', 'mi'))).toBe('/pattern/im');
+ expect(String(new RegExp('pattern', 'im'))).toBe('/pattern/im');
+ expect(String(new RegExp('pattern', 'mgi'))).toBe('/pattern/gim');
+ });
+ });
+ });
+});
diff --git a/tests/spec/s-string.js b/tests/spec/s-string.js
index 5e5f6e6..8f15157 100644
--- a/tests/spec/s-string.js
+++ b/tests/spec/s-string.js
@@ -3,11 +3,11 @@
describe('String', function () {
'use strict';
- describe('trim', function () {
+ describe('#trim()', function () {
var test = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFFHello, World!\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
it('trims all ES5 whitespace', function () {
- expect(test.trim()).toEqual('Hello, World!');
+ expect(test.trim()).toBe('Hello, World!');
expect(test.trim().length).toBe(13);
});
@@ -17,7 +17,7 @@ describe('String', function () {
});
});
- describe('replace', function () {
+ describe('#replace()', function () {
it('returns undefined for non-capturing groups', function () {
var groups = [];
'x'.replace(/x(.)?/g, function (m, group) {
@@ -37,7 +37,7 @@ describe('String', function () {
});
});
- describe('split', function () {
+ describe('#split()', function () {
var test = 'ab';
it('If "separator" is undefined must return Array with one String - "this" string', function () {
@@ -232,34 +232,34 @@ describe('String', function () {
describe('#indexOf()', function () {
it('has basic support', function () {
- expect('abcab'.indexOf('a')).toEqual(0);
- expect('abcab'.indexOf('a', 1)).toEqual(3);
- expect('abcab'.indexOf('a', 4)).toEqual(-1);
+ expect('abcab'.indexOf('a')).toBe(0);
+ expect('abcab'.indexOf('a', 1)).toBe(3);
+ expect('abcab'.indexOf('a', 4)).toBe(-1);
});
it('works with unicode', function () {
- expect('あいabcあいabc'.indexOf('あい')).toEqual(0);
- expect('あいabcあいabc'.indexOf('あい', 0)).toEqual(0);
- expect('あいabcあいabc'.indexOf('あい', 1)).toEqual(5);
- expect('あいabcあいabc'.indexOf('あい', 6)).toEqual(-1);
+ expect('あいabcあいabc'.indexOf('あい')).toBe(0);
+ expect('あいabcあいabc'.indexOf('あい', 0)).toBe(0);
+ expect('あいabcあいabc'.indexOf('あい', 1)).toBe(5);
+ expect('あいabcあいabc'.indexOf('あい', 6)).toBe(-1);
});
});
describe('#lastIndexOf()', function () {
it('has the right length', function () {
- expect(String.prototype.lastIndexOf.length).toEqual(1);
+ expect(String.prototype.lastIndexOf.length).toBe(1);
});
it('has basic support', function () {
- expect('abcd'.lastIndexOf('d')).toEqual(3);
- expect('abcd'.lastIndexOf('d', 3)).toEqual(3);
- expect('abcd'.lastIndexOf('d', 2)).toEqual(-1);
+ expect('abcd'.lastIndexOf('d')).toBe(3);
+ expect('abcd'.lastIndexOf('d', 3)).toBe(3);
+ expect('abcd'.lastIndexOf('d', 2)).toBe(-1);
});
it('works with unicode', function () {
- expect('abcあい'.lastIndexOf('あい')).toEqual(3);
- expect('abcあい'.lastIndexOf('あい', 3)).toEqual(3);
- expect('abcあい'.lastIndexOf('あい', 2)).toEqual(-1);
+ expect('abcあい'.lastIndexOf('あい')).toBe(3);
+ expect('abcあい'.lastIndexOf('あい', 3)).toBe(3);
+ expect('abcあい'.lastIndexOf('あい', 2)).toBe(-1);
});
});
});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-es5-shim.git
More information about the Pkg-javascript-commits
mailing list