Comparing version 0.6.0 to 0.7.0
@@ -1,22 +0,28 @@ | ||
# es6-shim 0.6.0 (January 15, 2013) | ||
# es6-shim 0.7.0 (2 April 2013) | ||
* Added `Array#find`, `Array#findIndex`, `Object.assign`, `Object.mixin`, | ||
`Math.cbrt`, `String.fromCodePoint`, `String#codePointAt`. | ||
* Removed `Object.isnt`. | ||
* Made Math functions fully conform spec. | ||
# es6-shim 0.6.0 (15 January 2013) | ||
* Added `Map#keys`, `Map#values`, `Map#size`, `Set#size`, `Set#clear`. | ||
# es6-shim 0.5.3 (September 2, 2012) | ||
# es6-shim 0.5.3 (2 September 2012) | ||
* Made `String#startsWith`, `String#endsWith` fully conform spec. | ||
# es6-shim 0.5.2 (June 17, 2012) | ||
# es6-shim 0.5.2 (17 June 2012) | ||
* Removed `String#toArray` and `Object.isObject` as per spec updates. | ||
# es6-shim 0.5.1 (June 14, 2012) | ||
# es6-shim 0.5.1 (14 June 2012) | ||
* Made Map and Set follow Spidermonkey implementation instead of V8. | ||
`var m = Map(); m.set('key', void 0); m.has('key');` now gives true. | ||
# es6-shim 0.5.0 (June 13, 2012) | ||
# es6-shim 0.5.0 (13 June 2012) | ||
* Added Number.MAX_INTEGER, Number.EPSILON, Number.parseInt, | ||
Number.parseFloat, Number.prototype.clz, Object.isObject. | ||
# es6-shim 0.4.1 (May 11, 2012) | ||
# es6-shim 0.4.1 (11 May 2012) | ||
* Fixed boundary checking in Number.isInteger. | ||
# es6-shim 0.4.0 (February 8, 2012) | ||
# es6-shim 0.4.0 (8 February 2012) | ||
* Added Math.log10, Math.log2, Math.log1p, Math.expm1, Math.cosh, | ||
@@ -26,12 +32,12 @@ Math.sinh, Math.tanh, Math.acosh, Math.asinh, Math.atanh, Math.hypot, | ||
# es6-shim 0.3.1 (January 30, 2012) | ||
# es6-shim 0.3.1 (30 January 2012) | ||
* Added IE8 support. | ||
# es6-shim 0.3.0 (January 27, 2012) | ||
# es6-shim 0.3.0 (27 January 2012) | ||
* Added Number.isFinite() and Object.isnt(). | ||
# es6-shim 0.2.1 (January 07, 2012) | ||
# es6-shim 0.2.1 (7 January 2012) | ||
* Fixed a bug in String#endsWith(). | ||
# es6-shim 0.2.0 (December 25, 2011) | ||
# es6-shim 0.2.0 (25 December 2011) | ||
* Added browser support. | ||
@@ -41,3 +47,3 @@ * Added tests. | ||
# es6-shim 0.1.0 (December 25, 2011) | ||
# es6-shim 0.1.0 (25 December 2011) | ||
* Initial release |
@@ -5,3 +5,3 @@ { | ||
"description": "ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"keywords": ["ecmascript", "harmony", "shim"], | ||
@@ -8,0 +8,0 @@ "main": "es6-shim.js", |
597
es6-shim.js
@@ -1,2 +0,2 @@ | ||
// ES6-shim 0.6.0 (c) 2013 Paul Miller (paulmillr.com) | ||
// ES6-shim 0.7.0 (c) 2013 Paul Miller (paulmillr.com) | ||
// ES6-shim may be freely distributed under the MIT license. | ||
@@ -10,30 +10,64 @@ // For more details and documentation: | ||
var global_isFinite = globals.isFinite; | ||
var factorial = function(value) { | ||
var result = 1; | ||
for (var i = 2; i <= value; i++) { | ||
result *= i; | ||
} | ||
return result; | ||
}; | ||
var supportsDescriptors = !!Object.defineProperty; | ||
var defineProperty = function(object, name, method) { | ||
if (!object[name]) { | ||
Object.defineProperty(object, name, { | ||
configurable: true, | ||
enumerable: false, | ||
writable: true, | ||
value: method | ||
}); | ||
} | ||
}; | ||
// Define configurable, writable and non-enumerable props | ||
// if they don’t exist. | ||
var defineProperties = function(object, map) { | ||
Object.keys(map).forEach(function(name) { | ||
defineProperty(object, name, map[name]); | ||
var method = map[name]; | ||
if (name in object) return; | ||
if (supportsDescriptors) { | ||
Object.defineProperty(object, name, { | ||
configurable: true, | ||
enumerable: false, | ||
writable: true, | ||
value: method | ||
}); | ||
} else { | ||
object[name] = method; | ||
} | ||
}); | ||
}; | ||
var ES = { | ||
ToInt32: function(x) { | ||
return x >> 0; | ||
}, | ||
ToUint32: function(x) { | ||
return x >>> 0; | ||
} | ||
}; | ||
defineProperties(String, { | ||
fromCodePoint: function() { | ||
var points = arguments; | ||
var result = []; | ||
var next; | ||
for (var i = 0, length = points.length; i < length; i++) { | ||
next = Number(points[i]); | ||
if (!Object.is(next, Number.toInteger(next)) || | ||
next < 0 || next > 0x10FFFF) { | ||
throw new RangeError('Invalid code point ' + next); | ||
} | ||
if (next < 0x10000) { | ||
result.push(String.fromCharCode(next)); | ||
} else { | ||
next -= 0x10000; | ||
result.push(String.fromCharCode((next >> 10) + 0xD800)); | ||
result.push(String.fromCharCode((next % 0x400) + 0xDC00)); | ||
} | ||
} | ||
return result.join(''); | ||
} | ||
}); | ||
defineProperties(String.prototype, { | ||
// Fast repeat, uses the `Exponentiation by squaring` algorithm. | ||
repeat: function(times) { | ||
times = Number.toInteger(times); | ||
if (times < 0 || times === Infinity) { | ||
throw new RangeError(); | ||
} | ||
if (times < 1) return ''; | ||
@@ -47,34 +81,9 @@ if (times % 2) return this.repeat(times - 1) + this; | ||
var position = arguments[1]; | ||
// Let searchStr be ToString(searchString). | ||
var searchStr = searchString.toString(); | ||
// ReturnIfAbrupt(searchStr). | ||
// Let S be the result of calling ToString, | ||
// giving it the this value as its argument. | ||
var s = this.toString(); | ||
// ReturnIfAbrupt(S). | ||
// Let pos be ToInteger(position). | ||
// (If position is undefined, this step produces the value 0). | ||
var s = String(this); | ||
var pos = (position === undefined) ? 0 : Number.toInteger(position); | ||
// ReturnIfAbrupt(pos). | ||
// Let len be the number of elements in S. | ||
var len = s.length; | ||
// Let start be min(max(pos, 0), len). | ||
var start = Math.min(Math.max(pos, 0), len); | ||
// Let searchLength be the number of elements in searchString. | ||
var searchLength = searchString.length; | ||
// If searchLength+start is greater than len, return false. | ||
if ((searchLength + start) > len) return false; | ||
// If the searchLength sequence of elements of S starting at | ||
// start is the same as the full element sequence of searchString, | ||
// return true. | ||
var index = ''.indexOf.call(s, searchString, start); | ||
@@ -86,35 +95,11 @@ return index === start; | ||
var endPosition = arguments[1]; | ||
// ReturnIfAbrupt(CheckObjectCoercible(this value)). | ||
// Let S be the result of calling ToString, giving it the this value as its argument. | ||
// ReturnIfAbrupt(S). | ||
var s = this.toString(); | ||
// Let searchStr be ToString(searchString). | ||
// ReturnIfAbrupt(searchStr). | ||
var s = String(this); | ||
var searchStr = searchString.toString(); | ||
// Let len be the number of elements in S. | ||
var len = s.length; | ||
// If endPosition is undefined, let pos be len, else let pos be ToInteger(endPosition). | ||
// ReturnIfAbrupt(pos). | ||
var pos = (endPosition === undefined) ? | ||
len : | ||
Number.toInteger(endPosition); | ||
// Let end be min(max(pos, 0), len). | ||
len : Number.toInteger(endPosition); | ||
var end = Math.min(Math.max(pos, 0), len); | ||
// Let searchLength be the number of elements in searchString. | ||
var searchLength = searchString.length; | ||
// Let start be end - searchLength. | ||
var start = end - searchLength; | ||
// If start is less than 0, return false. | ||
if (start < 0) return false; | ||
// If the searchLength sequence of elements of S starting at start is the same as the full element sequence of searchString, return true. | ||
// Otherwise, return false. | ||
var index = ''.indexOf.call(s, searchString, start); | ||
@@ -129,2 +114,15 @@ return index === start; | ||
return ''.indexOf.call(this, searchString, position) !== -1; | ||
}, | ||
codePointAt: function(pos) { | ||
var s = String(this); | ||
var position = Number.toInteger(pos); | ||
var length = s.length; | ||
if (position < 0 || position >= length) return undefined; | ||
var first = s.charCodeAt(position); | ||
var isEnd = (position + 1 === length); | ||
if (first < 0xD800 || first > 0xDBFF || isEnd) return first; | ||
var second = s.charCodeAt(position + 1); | ||
if (second < 0xDC00 || second > 0xDFFF) return first; | ||
return ((first - 0xD800) * 1024) + (second - 0xDC00) + 0x10000; | ||
} | ||
@@ -135,21 +133,58 @@ }); | ||
from: function(iterable) { | ||
var object = new Object(iterable); | ||
var array = []; | ||
var mapFn = arguments[1]; | ||
var thisArg = arguments[2]; | ||
for (var key = 0, length = object.length >>> 0; key < length; key++) { | ||
if (key in object) { | ||
array[key] = object[key]; | ||
} | ||
var list = Object(iterable); | ||
var length = ES.ToUint32(list.length); | ||
var result = typeof this === 'function' ? | ||
Object(new this(length)) : new Array(length); | ||
for (var i = 0; i < length; i++) { | ||
var value = list[i]; | ||
result[i] = mapFn ? mapFn.call(thisArg, value) : value; | ||
} | ||
return array; | ||
result.length = length; | ||
return result; | ||
}, | ||
of: function() { | ||
return Array.prototype.slice.call(arguments); | ||
return Array.from(arguments); | ||
} | ||
}); | ||
defineProperties(Array.prototype, { | ||
find: function(predicate) { | ||
var list = Object(this); | ||
var length = ES.ToUint32(list.length); | ||
if (length === 0) return undefined; | ||
if (typeof predicate !== 'function') { | ||
throw new TypeError('Array#find: predicate must be a function'); | ||
} | ||
var thisArg = arguments[1]; | ||
for (var i = 0, value; i < length && i in list; i++) { | ||
value = list[i]; | ||
if (predicate.call(thisArg, value, i, list)) return value; | ||
} | ||
return undefined; | ||
}, | ||
findIndex: function(predicate) { | ||
var list = Object(this); | ||
var length = ES.ToUint32(list.length); | ||
if (length === 0) return -1; | ||
if (typeof predicate !== 'function') { | ||
throw new TypeError('Array#findIndex: predicate must be a function'); | ||
} | ||
var thisArg = arguments[1]; | ||
for (var i = 0, value; i < length && i in list; i++) { | ||
value = list[i]; | ||
if (predicate.call(thisArg, value, i, list)) return i; | ||
} | ||
return -1; | ||
} | ||
}); | ||
defineProperties(Number, { | ||
MAX_INTEGER: 9007199254740992, | ||
MAX_INTEGER: 9007199254740991, | ||
EPSILON: 2.220446049250313e-16, | ||
@@ -192,36 +227,61 @@ | ||
defineProperties(Object, { | ||
getOwnPropertyDescriptors: function(subject) { | ||
var descs = {}; | ||
Object.getOwnPropertyNames(subject).forEach(function(propName) { | ||
descs[propName] = Object.getOwnPropertyDescriptor(subject, propName); | ||
}); | ||
return descs; | ||
}, | ||
if (supportsDescriptors) { | ||
defineProperties(Object, { | ||
getOwnPropertyDescriptors: function(subject) { | ||
var descs = {}; | ||
Object.getOwnPropertyNames(subject).forEach(function(propName) { | ||
descs[propName] = Object.getOwnPropertyDescriptor(subject, propName); | ||
}); | ||
return descs; | ||
}, | ||
getPropertyDescriptor: function(subject, name) { | ||
var pd = Object.getOwnPropertyDescriptor(subject, name); | ||
var proto = Object.getPrototypeOf(subject); | ||
while (pd === undefined && proto !== null) { | ||
pd = Object.getOwnPropertyDescriptor(proto, name); | ||
proto = Object.getPrototypeOf(proto); | ||
} | ||
return pd; | ||
}, | ||
getPropertyDescriptor: function(subject, name) { | ||
var pd = Object.getOwnPropertyDescriptor(subject, name); | ||
var proto = Object.getPrototypeOf(subject); | ||
while (pd === undefined && proto !== null) { | ||
pd = Object.getOwnPropertyDescriptor(proto, name); | ||
proto = Object.getPrototypeOf(proto); | ||
} | ||
return pd; | ||
}, | ||
getPropertyNames: function(subject) { | ||
var result = Object.getOwnPropertyNames(subject); | ||
var proto = Object.getPrototypeOf(subject); | ||
getPropertyNames: function(subject) { | ||
var result = Object.getOwnPropertyNames(subject); | ||
var proto = Object.getPrototypeOf(subject); | ||
var addProperty = function(property) { | ||
if (result.indexOf(property) === -1) { | ||
result.push(property); | ||
var addProperty = function(property) { | ||
if (result.indexOf(property) === -1) { | ||
result.push(property); | ||
} | ||
}; | ||
while (proto !== null) { | ||
Object.getOwnPropertyNames(proto).forEach(addProperty); | ||
proto = Object.getPrototypeOf(proto); | ||
} | ||
}; | ||
return result; | ||
}, | ||
while (proto !== null) { | ||
Object.getOwnPropertyNames(proto).forEach(addProperty); | ||
proto = Object.getPrototypeOf(proto); | ||
// 15.2.3.17 | ||
assign: function(target, source) { | ||
return Object.keys(source).reduce(function(target, key) { | ||
target[key] = source[key]; | ||
return target; | ||
}, target); | ||
}, | ||
// 15.2.3.18 | ||
mixin: function(target, source) { | ||
var props = Object.getOwnPropertyNames(source); | ||
return props.reduce(function(target, property) { | ||
var descriptor = Object.getOwnPropertyDescriptor(source, property); | ||
return Object.defineProperty(target, property, descriptor); | ||
}, target); | ||
} | ||
return result; | ||
}); | ||
} | ||
defineProperties(Object, { | ||
getOwnPropertyKeys: function(subject) { | ||
return Object.keys(subject); | ||
}, | ||
@@ -245,6 +305,2 @@ | ||
return x !== x && y !== y; | ||
}, | ||
isnt: function(x, y) { | ||
return !Object.is(x, y); | ||
} | ||
@@ -255,2 +311,9 @@ }); | ||
acosh: function(value) { | ||
if (Number.isNaN(value) || value < 1) { | ||
return NaN; | ||
} else if (value === 1) { | ||
return +0; | ||
} else if (value === Infinity) { | ||
return Infinity; | ||
} | ||
return Math.log(value + Math.sqrt(value * value - 1)); | ||
@@ -260,2 +323,9 @@ }, | ||
asinh: function(value) { | ||
if (Number.isNaN(value)) { | ||
return NaN; | ||
} else if (value === 0) { | ||
return value; | ||
} else if (value === Infinity || value === -Infinity) { | ||
return value; | ||
} | ||
return Math.log(value + Math.sqrt(value * value + 1)); | ||
@@ -265,6 +335,32 @@ }, | ||
atanh: function(value) { | ||
if (Number.isNaN(value) || value < -1 || value > 1) { | ||
return NaN; | ||
} else if (value === -1) { | ||
return -Infinity; | ||
} else if (value === 1) { | ||
return Infinity; | ||
} else if (value === 0) { | ||
return value; | ||
} | ||
return 0.5 * Math.log((1 + value) / (1 - value)); | ||
}, | ||
cbrt: function (value) { | ||
if (value === 0) { | ||
return value; | ||
} | ||
var negate = value < 0, result; | ||
if (negate) { value = -value; } | ||
result = Math.pow(value, 1/3); | ||
return negate ? -result : result; | ||
}, | ||
cosh: function(value) { | ||
if (value === 0) { // +0 or -0 | ||
return 1; | ||
} else if (value === Infinity || value === -Infinity) { | ||
return value; | ||
} else if (Number.isNaN(value)) { | ||
return NaN; | ||
} | ||
if (value < 0) value = -value; | ||
@@ -276,6 +372,18 @@ if (value > 21) return Math.exp(value) / 2; | ||
expm1: function(value) { | ||
if (Number.isNaN(value)) { | ||
return NaN; | ||
} else if (value === 0) { | ||
return value; | ||
} else if (value === Infinity) { | ||
return Infinity; | ||
} else if (value === -Infinity) { | ||
return -1; | ||
} | ||
var result = 0; | ||
var n = 50; | ||
for (var i = 1; i < n; i++) { | ||
result += Math.pow(value, i) / factorial(i); | ||
for (var j = 2, factorial = 1; j <= i; j++) { | ||
factorial *= j; | ||
} | ||
result += Math.pow(value, i) / factorial; | ||
} | ||
@@ -285,7 +393,39 @@ return result; | ||
hypot: function(x, y) { | ||
return Math.sqrt(x * x + y * y) || 0; | ||
hypot: function(x, y, z) { | ||
var anyNaN = false; | ||
var anyInfinity = false; | ||
var allZero = true; | ||
[x, y, z].some(function (num) { | ||
if (Number.isNaN(num)) { | ||
anyNaN = true; | ||
} else if (num === Infinity || num === -Infinity) { | ||
anyInfinity = true; | ||
} else if (num !== 0) { | ||
allZero = false; | ||
} | ||
return anyInfinity || anyNaN; | ||
}); | ||
if (anyInfinity) { | ||
return Infinity; | ||
} else if (anyNaN) { | ||
return NaN; | ||
} else if (allZero) { | ||
return 0; | ||
} | ||
if (x == null) x = 0; | ||
if (y == null) y = 0; | ||
if (z == null) z = 0; | ||
return Math.sqrt(x * x + y * y + z * z); | ||
}, | ||
log2: function(value) { | ||
if (Number.isNaN(value) || value < 0) { | ||
return NaN; | ||
} else if (value === 0) { | ||
return -Infinity; | ||
} else if (value === 1) { | ||
return 0; | ||
} else if (value === Infinity) { | ||
return Infinity; | ||
} | ||
return Math.log(value) * (1 / Math.LN2); | ||
@@ -295,2 +435,11 @@ }, | ||
log10: function(value) { | ||
if (Number.isNaN(value) || value < 0) { | ||
return NaN; | ||
} else if (value === 0) { | ||
return -Infinity; | ||
} else if (value === 1) { | ||
return 0; | ||
} else if (value === Infinity) { | ||
return Infinity; | ||
} | ||
return Math.log(value) * (1 / Math.LN10); | ||
@@ -300,6 +449,14 @@ }, | ||
log1p: function(value) { | ||
if (Number.isNaN(value) || value < -1) { | ||
return NaN; | ||
} else if (value === -1) { | ||
return -Infinity; | ||
} else if (value === 0) { | ||
return value; | ||
} else if (value === Infinity) { | ||
return Infinity; | ||
} | ||
var result = 0; | ||
var n = 50; | ||
if (value <= -1) return -Infinity; | ||
if (value < 0 || value > 1) return Math.log(1 + value); | ||
@@ -325,2 +482,9 @@ for (var i = 1; i < n; i++) { | ||
sinh: function(value) { | ||
if (Number.isNaN(value)) { | ||
return NaN; | ||
} else if (value === 0) { | ||
return value; | ||
} else if (value === Infinity || value === -Infinity) { | ||
return value; | ||
} | ||
return (Math.exp(value) - Math.exp(-value)) / 2; | ||
@@ -330,2 +494,11 @@ }, | ||
tanh: function(value) { | ||
if (Number.isNaN(value)) { | ||
return NaN; | ||
} else if (value === 0) { | ||
return value; | ||
} else if (value === Infinity) { | ||
return 1; | ||
} else if (value === -Infinity) { | ||
return -1; | ||
} | ||
return (Math.exp(value) - Math.exp(-value)) / (Math.exp(value) + Math.exp(-value)); | ||
@@ -335,2 +508,9 @@ }, | ||
trunc: function(value) { | ||
if (Number.isNaN(value)) { | ||
return NaN; | ||
} else if (value === Infinity || value === -Infinity) { | ||
return value; | ||
} else if (value === 0) { | ||
return value; | ||
} | ||
return ~~value; | ||
@@ -340,107 +520,114 @@ } | ||
defineProperties(globals, { | ||
Map: (function() { | ||
var indexOfIdentical = function(keys, key) { | ||
for (var i = 0, length = keys.length; i < length; i++) { | ||
if (Object.is(keys[i], key)) return i; | ||
} | ||
return -1; | ||
}; | ||
if (supportsDescriptors) { | ||
// Map and Set require a true ES5 environment | ||
defineProperties(globals, { | ||
Map: (function() { | ||
var indexOfIdentical = function(keys, key) { | ||
for (var i = 0, length = keys.length; i < length; i++) { | ||
if (Object.is(keys[i], key)) return i; | ||
} | ||
return -1; | ||
}; | ||
function Map() { | ||
if (!(this instanceof Map)) return new Map(); | ||
defineProperty(this, '_keys', []); | ||
defineProperty(this, '_values', []); | ||
defineProperty(this, '_size', 0); | ||
Object.defineProperty(this, 'size', { | ||
configurable: true, | ||
enumerable: false, | ||
get: (function() { | ||
return this._size; | ||
}).bind(this) | ||
}); | ||
} | ||
function Map() { | ||
if (!(this instanceof Map)) return new Map(); | ||
defineProperties(Map.prototype, { | ||
get: function(key) { | ||
var index = indexOfIdentical(this._keys, key); | ||
return index < 0 ? undefined : this._values[index]; | ||
}, | ||
defineProperties(this, { | ||
'_keys': [], | ||
'_values': [], | ||
'_size': 0 | ||
}); | ||
has: function(key) { | ||
return indexOfIdentical(this._keys, key) >= 0; | ||
}, | ||
Object.defineProperty(this, 'size', { | ||
configurable: true, | ||
enumerable: false, | ||
get: (function() { | ||
return this._size; | ||
}).bind(this) | ||
}); | ||
} | ||
set: function(key, value) { | ||
var keys = this._keys; | ||
var values = this._values; | ||
var index = indexOfIdentical(keys, key); | ||
if (index < 0) index = keys.length; | ||
keys[index] = key; | ||
values[index] = value; | ||
this._size += 1; | ||
}, | ||
defineProperties(Map.prototype, { | ||
get: function(key) { | ||
var index = indexOfIdentical(this._keys, key); | ||
return index < 0 ? undefined : this._values[index]; | ||
}, | ||
'delete': function(key) { | ||
var keys = this._keys; | ||
var values = this._values; | ||
var index = indexOfIdentical(keys, key); | ||
if (index < 0) return false; | ||
keys.splice(index, 1); | ||
values.splice(index, 1); | ||
this._size -= 1; | ||
return true; | ||
}, | ||
has: function(key) { | ||
return indexOfIdentical(this._keys, key) >= 0; | ||
}, | ||
keys: function() { | ||
return this._keys; | ||
}, | ||
set: function(key, value) { | ||
var keys = this._keys; | ||
var values = this._values; | ||
var index = indexOfIdentical(keys, key); | ||
if (index < 0) index = keys.length; | ||
keys[index] = key; | ||
values[index] = value; | ||
this._size += 1; | ||
}, | ||
values: function() { | ||
return this._values; | ||
} | ||
}); | ||
'delete': function(key) { | ||
var keys = this._keys; | ||
var values = this._values; | ||
var index = indexOfIdentical(keys, key); | ||
if (index < 0) return false; | ||
keys.splice(index, 1); | ||
values.splice(index, 1); | ||
this._size -= 1; | ||
return true; | ||
}, | ||
return Map; | ||
})(), | ||
keys: function() { | ||
return this._keys; | ||
}, | ||
Set: (function() { | ||
function Set() { | ||
if (!(this instanceof Set)) return new Set(); | ||
defineProperty(this, '[[SetData]]', new Map()); | ||
Object.defineProperty(this, 'size', { | ||
configurable: true, | ||
enumerable: false, | ||
get: (function() { | ||
return this['[[SetData]]'].size; | ||
}).bind(this) | ||
values: function() { | ||
return this._values; | ||
} | ||
}); | ||
} | ||
defineProperties(Set.prototype, { | ||
has: function(key) { | ||
return this['[[SetData]]'].has(key); | ||
}, | ||
return Map; | ||
})(), | ||
add: function(key) { | ||
this['[[SetData]]'].set(key, true); | ||
}, | ||
'delete': function(key) { | ||
return this['[[SetData]]']['delete'](key); | ||
}, | ||
clear: function() { | ||
Object.defineProperty(this, '[[SetData]]', { | ||
Set: (function() { | ||
function Set() { | ||
if (!(this instanceof Set)) return new Set(); | ||
defineProperties(this, {'[[SetData]]': new Map()}); | ||
Object.defineProperty(this, 'size', { | ||
configurable: true, | ||
enumerable: false, | ||
writable: true, | ||
value: new Map() | ||
get: (function() { | ||
return this['[[SetData]]'].size; | ||
}).bind(this) | ||
}); | ||
} | ||
}); | ||
return Set; | ||
})() | ||
}); | ||
defineProperties(Set.prototype, { | ||
has: function(key) { | ||
return this['[[SetData]]'].has(key); | ||
}, | ||
add: function(key) { | ||
this['[[SetData]]'].set(key, true); | ||
}, | ||
'delete': function(key) { | ||
return this['[[SetData]]']['delete'](key); | ||
}, | ||
clear: function() { | ||
Object.defineProperty(this, '[[SetData]]', { | ||
configurable: true, | ||
enumerable: false, | ||
writable: true, | ||
value: new Map() | ||
}); | ||
} | ||
}); | ||
return Set; | ||
})() | ||
}); | ||
} | ||
}; | ||
@@ -447,0 +634,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"description": "ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"homepage": "https://github.com/paulmillr/es6-shim/", | ||
@@ -14,6 +14,20 @@ "repository": { | ||
"scripts": { | ||
"test": "mocha --require 'test/test_helpers.js'" | ||
"test": "mocha --require test/test_helpers.js" | ||
}, | ||
"engines": { | ||
"node": "~0.8.0 || ~0.9.0" | ||
"testling": { | ||
"files": "es6-shim.js", | ||
"browsers": [ | ||
"iexplore/6.0..latest", | ||
"firefox/3.0", | ||
"firefox/15.0..latest", | ||
"firefox/nightly", | ||
"chrome/4.0", | ||
"chrome/23.0..latest", | ||
"chrome/canary", | ||
"opera/10.0..latest", | ||
"opera/next", | ||
"safari/5.0.5..latest", | ||
"ipad/6.0..latest", | ||
"iphone/6.0..latest" | ||
] | ||
}, | ||
@@ -20,0 +34,0 @@ "dependencies": {}, |
@@ -0,1 +1,2 @@ | ||
<a href="https://jepso-ci.com/paulmillr/es6-shim"><img src="https://jepso-ci.com/paulmillr/es6-shim.svg" align="right" alt="jepso-ci status" /></a> | ||
# ES6 Shim | ||
@@ -5,5 +6,3 @@ Provides compatibility shims so that legacy JavaScript engines behave as | ||
Project targets engines that support ES5 (Firefox, Chrome, Safari, Opera). With | ||
[ES5-shim](https://github.com/kriskowal/es5-shim) it could also work in older | ||
browsers. | ||
[![browser support](https://ci.testling.com/paulmillr/es6-shim.png)](https://ci.testling.com/paulmillr/es6-shim) | ||
@@ -22,31 +21,59 @@ ## Installation | ||
## Safe shims | ||
* Maps & Sets | ||
* String.prototype.repeat, String.prototype.startsWith, | ||
String.prototype.endsWith, String.prototype.contains | ||
* Array.from, Array.of | ||
* Number.MAX_INTEGER, Number.EPSILON, Number.parseInt, Number.parseFloat, | ||
Number.isNaN, Number.toInteger, Number.isInteger, Number.isFinite | ||
* Object.getOwnPropertyDescriptors, Object.getPropertyDescriptor, | ||
Object.getPropertyNames, Object.is, Object.isnt | ||
* Math.sign, Math.log10, Math.log2, Math.log1p, Math.expm1, Math.cosh, | ||
Math.sinh, Math.tanh, Math.acosh, Math.asinh, Math.atanh, Math.hypot, | ||
Math.trunc (accuracy is 1e-11). | ||
* `Map`, `Set` (ES5) | ||
* `String`: | ||
* `fromCodePoint()` | ||
* `String.prototype`: | ||
* `codePointAt()` | ||
* `repeat()` | ||
* `startsWith()` | ||
* `endsWith()` | ||
* `contains()` | ||
* `Number`: | ||
* `MAX_INTEGER` | ||
* `EPSILON` | ||
* `parseInt()` | ||
* `parseFloat()` | ||
* `isNaN()` | ||
* `toInteger()` | ||
* `isInteger()` | ||
* `isFinite()` | ||
* `Number.prototype`: | ||
* `clz()` | ||
* `Array`: | ||
* `from()` | ||
* `of()` | ||
* `Object`: | ||
* `getOwnPropertyDescriptors()` (ES5) | ||
* `getPropertyDescriptor()` (ES5) | ||
* `getPropertyNames()` (ES5) | ||
* `is()` | ||
* `assign()` | ||
* `mixin()` (ES5) | ||
* `Math`: | ||
* `sign()` | ||
* `log10()` | ||
* `log2()` | ||
* `log1p()` | ||
* `expm1()` | ||
* `cosh()` | ||
* `sinh()` | ||
* `tanh()` | ||
* `acosh()` | ||
* `asinh()` | ||
* `atanh()` | ||
* `hypot()` | ||
* `trunc()` | ||
Math functions accuracy is 1e-11. | ||
## WeakMap shim | ||
It is not possible to implement WeakMap in pure javascript. | ||
[es6-collections](https://github.com/WebReflection/es6-collections) | ||
implementation doesn't held values strongly which is critical | ||
for the collection. es6-shim decided to not include incorrect shim. | ||
The [es6-collections](https://github.com/WebReflection/es6-collections) | ||
implementation doesn't hold values strongly, which is critical | ||
for the collection. es6-shim decided to not include an incorrect shim. | ||
WeakMap has very unusual use-case so you probably won't need it at all ( | ||
use simple `Map` instead). | ||
WeakMap has a very unusual use-case so you probably won't need it at all | ||
(use simple `Map` instead). | ||
## IE8 support | ||
There are some shims that do not work in IE8, because it is simply not | ||
possible to implement them properly: | ||
* Object.getOwnPropertyDescriptors | ||
* Object.getPropertyDescriptor | ||
* Object.getPropertyNames | ||
## Getting started | ||
@@ -57,6 +84,11 @@ | ||
'abc'.endsWith('a') // false | ||
'john alice'.contains('john') // true | ||
'123'.repeat(2) // '123123' | ||
Object.is(NaN, NaN) // Fixes ===. 0 isnt -0, NaN is NaN | ||
'123'.repeat(2) // '123123' | ||
'john alice'.contains('john') // true | ||
Object.assign({a: 1}, {b: 2}) // {a: 1, b: 2} | ||
Object.mixin({a: 1}, {get b: function() {return 2}}) // {a: 1, b: getter} | ||
Number.isNaN('123') // false. isNaN('123') will give true. | ||
Number.isFinite('asd') // false. Global isFinite() will give true. | ||
Number.toInteger(2.4) // 2. converts values to IEEE754 double precision integers | ||
@@ -66,5 +98,8 @@ // Tests if value is a number, finite, | ||
Number.isInteger(2.4) // false. | ||
Number.isFinite('asd') // false. Global isFinite() will give true. | ||
Math.sign(400) // 1, 0 or -1 depending on sign. In this case 1. | ||
[5, 10, 15, 10].find(function(item) {return item / 2 === 5;}) // 10 | ||
[5, 10, 15, 10].findIndex(function(item) {return item / 2 === 5;}) // 1 | ||
// Replacement for `{}` key-value storage. | ||
@@ -101,3 +136,3 @@ // Keys can be anything. | ||
Copyright (c) 2012 Paul Miller (http://paulmillr.com) | ||
Copyright (c) 2013 Paul Miller (http://paulmillr.com) | ||
@@ -104,0 +139,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of |
describe('Array', function() { | ||
var list = [5, 10, 15, 20]; | ||
describe('Array.from()', function() { | ||
it('should create correct array from iterable', function() { | ||
(function() { | ||
expect(Array.from(arguments)).to.eql([0, 1, 2]) | ||
expect(Array.from(arguments)).to.eql([0, 1, 2]); | ||
})(0, 1, 2); | ||
@@ -22,5 +24,37 @@ | ||
it('should create correct array from arguments', function() { | ||
expect(Array.of(1, null, void 0)).to.eql([1, null, void 0]) | ||
expect(Array.of(1, null, void 0)).to.eql([1, null, void 0]); | ||
}); | ||
}); | ||
describe('Array#find', function() { | ||
it('should find item by predicate', function() { | ||
var result = list.find(function(item) {return item === 15;}); | ||
expect(result).to.equal(15); | ||
}); | ||
it('should return undefined when nothing matched', function() { | ||
var result = list.find(function(item) {return item === 'a';}); | ||
expect(result).to.equal(undefined); | ||
}); | ||
it('should throw TypeError when function was not passed', function() { | ||
expect(function() {list.find();}).to.throw(TypeError); | ||
}); | ||
}); | ||
describe('Array#findIndex', function() { | ||
it('should find item key by predicate', function() { | ||
var result = list.findIndex(function(item) {return item === 15;}); | ||
expect(result).to.equal(2); | ||
}); | ||
it('should return -1 when nothing matched', function() { | ||
var result = list.findIndex(function(item) {return item === 'a';}); | ||
expect(result).to.equal(-1); | ||
}); | ||
it('should throw TypeError when function was not passed', function() { | ||
expect(function() {list.findIndex();}).to.throw(TypeError); | ||
}); | ||
}); | ||
}); |
@@ -201,3 +201,3 @@ // Big thanks to V8 folks for test ideas. | ||
it('should throw proper errors when user invokes methods with wrong types of receiver', | ||
it.skip('should throw proper errors when user invokes methods with wrong types of receiver', | ||
function() { | ||
@@ -204,0 +204,0 @@ |
117
test/math.js
var Assertion = expect().constructor; | ||
Assertion.prototype.almostEqual = function(obj) { | ||
var allowedDiff = 1e-11; | ||
Assertion.prototype.almostEqual = function(obj, precision) { | ||
var allowedDiff = precision || 1e-11; | ||
return this.within(obj - allowedDiff, obj + allowedDiff); | ||
} | ||
}; | ||
var isPositiveZero = function (zero) { | ||
return zero === 0 && 1 / zero === Infinity; | ||
}; | ||
var isNegativeZero = function (zero) { | ||
return zero === 0 && 1 / zero === -Infinity; | ||
}; | ||
describe('Math', function() { | ||
describe('#acosh()', function() { | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.acosh(NaN))).to.be.ok; | ||
expect(Number.isNaN(Math.acosh(0))).to.be.ok; | ||
expect(Number.isNaN(Math.acosh(0.9999999))).to.be.ok; | ||
expect(isPositiveZero(Math.acosh(1))).to.be.ok; | ||
expect(Math.acosh(Infinity)).to.equal(Infinity); | ||
expect(Math.acosh(1234)).to.almostEqual(7.811163220849231); | ||
@@ -17,2 +30,7 @@ expect(Math.acosh(8.88)).to.almostEqual(2.8737631531629235); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.asinh(NaN))).to.be.ok; | ||
expect(isPositiveZero(Math.asinh(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.asinh(-0))).to.be.ok; | ||
expect(Math.asinh(Infinity)).to.equal(Infinity); | ||
expect(Math.asinh(-Infinity)).to.equal(-Infinity); | ||
expect(Math.asinh(1234)).to.almostEqual(7.811163549201245); | ||
@@ -25,2 +43,9 @@ expect(Math.asinh(9.99)).to.almostEqual(2.997227420191335); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.atanh(NaN))).to.be.ok; | ||
expect(Number.isNaN(Math.atanh(-1.00000001))).to.be.ok; | ||
expect(Number.isNaN(Math.atanh(1.00000001))).to.be.ok; | ||
expect(Math.atanh(-1)).to.equal(-Infinity); | ||
expect(Math.atanh(1)).to.equal(Infinity); | ||
expect(isPositiveZero(Math.atanh(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.atanh(-0))).to.be.ok; | ||
expect(Math.atanh(0.5)).to.almostEqual(0.5493061443340549); | ||
@@ -32,8 +57,29 @@ expect(Math.atanh(-0.5)).to.almostEqual(-0.5493061443340549); | ||
}); | ||
describe('#cbrt()', function() { | ||
it('should be correct', function () { | ||
expect(isNaN(Math.cbrt(NaN))).to.be.ok; | ||
expect(isPositiveZero(Math.cbrt(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.cbrt(-0))).to.be.ok; | ||
expect(Math.cbrt(Infinity)).to.equal(Infinity); | ||
expect(Math.cbrt(-Infinity)).to.equal(-Infinity); | ||
expect(Math.cbrt(-8)).to.almostEqual(-2); | ||
expect(Math.cbrt(8)).to.almostEqual(2); | ||
expect(Math.cbrt(-1000)).to.almostEqual(-10); | ||
expect(Math.cbrt(1000)).to.almostEqual(10); | ||
}); | ||
}); | ||
describe('#cosh()', function() { | ||
it('should be correct', function() { | ||
expect(Math.cosh(12)).to.almostEqual(81377.39571257407); | ||
expect(Math.cosh(0)).to.almostEqual(1); | ||
expect(Math.cosh(-10)).to.almostEqual(11013.232920103323); | ||
expect(Number.isNaN(Math.cosh(NaN))).to.be.ok; | ||
expect(Math.cosh(-0)).to.equal(1); | ||
expect(Math.cosh(+0)).to.equal(1); | ||
expect(Math.cosh(Infinity)).to.equal(Infinity); | ||
expect(Math.cosh(-Infinity)).to.equal(-Infinity); | ||
// Overridden precision values here are for Chrome, as of v25.0.1364.172 | ||
expect(Math.cosh(12)).to.almostEqual(81377.39571257407, 3e-11); | ||
expect(Math.cosh(22)).to.almostEqual(1792456423.065795780980053377, 1e-5); | ||
expect(Math.cosh(-10)).to.almostEqual(11013.23292010332313972137); | ||
expect(Math.cosh(-23)).to.almostEqual(4872401723.1244513000, 1e-5); | ||
}); | ||
@@ -44,2 +90,7 @@ }); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.expm1(NaN))).to.be.ok; | ||
expect(isPositiveZero(Math.expm1(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.expm1(-0))).to.be.ok; | ||
expect(Math.expm1(Infinity)).to.equal(Infinity); | ||
expect(Math.expm1(-Infinity)).to.equal(-1); | ||
expect(Math.expm1(10)).to.almostEqual(22025.465794806718); | ||
@@ -52,9 +103,26 @@ expect(Math.expm1(-10)).to.almostEqual(-0.9999546000702375); | ||
it('should be correct', function() { | ||
expect(Math.hypot(Infinity)).to.equal(Infinity); | ||
expect(Math.hypot(-Infinity)).to.equal(Infinity); | ||
expect(Math.hypot(Infinity, NaN)).to.equal(Infinity); | ||
expect(Math.hypot(-Infinity, 'Hello')).to.equal(Infinity); | ||
expect(Math.hypot(1, 2, Infinity)).to.equal(Infinity); | ||
expect(Number.isNaN(Math.hypot(NaN, 1))).to.be.ok; | ||
expect(isPositiveZero(Math.hypot())).to.be.ok; | ||
expect(isPositiveZero(Math.hypot(0, 0, 0))).to.be.ok; | ||
expect(isPositiveZero(Math.hypot(0, -0, 0))).to.be.ok; | ||
expect(isPositiveZero(Math.hypot(-0, -0, -0))).to.be.ok; | ||
expect(Math.hypot(66, 66)).to.almostEqual(93.33809511662427); | ||
expect(Math.hypot(0.1, 100)).to.almostEqual(100.0000499999875); | ||
}); | ||
}); | ||
}); | ||
describe('#log2()', function() { | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.log2(NaN))).to.be.ok; | ||
expect(Number.isNaN(Math.log2(-1e-50))).to.be.ok; | ||
expect(Math.log2(+0)).to.equal(-Infinity); | ||
expect(Math.log2(-0)).to.equal(-Infinity); | ||
expect(isPositiveZero(Math.log2(1))).to.be.ok; | ||
expect(Math.log2(Infinity)).to.equal(Infinity); | ||
expect(Math.log2(5)).to.almostEqual(2.321928094887362); | ||
@@ -67,2 +135,9 @@ expect(Math.log2(32)).to.almostEqual(5); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.log10(NaN))).to.be.ok; | ||
expect(Number.isNaN(Math.log10(-1e-50))).to.be.ok; | ||
expect(Math.log10(+0)).to.equal(-Infinity); | ||
expect(Math.log10(-0)).to.equal(-Infinity); | ||
expect(isPositiveZero(Math.log10(1))).to.be.ok; | ||
expect(Math.log10(Infinity)).to.equal(Infinity); | ||
expect(Math.log10(5)).to.almostEqual(0.6989700043360189); | ||
@@ -75,2 +150,9 @@ expect(Math.log10(50)).to.almostEqual(1.6989700043360187); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.log1p(NaN))).to.be.ok; | ||
expect(Number.isNaN(Math.log1p(-1.000000001))).to.be.ok; | ||
expect(Math.log1p(-1)).to.equal(-Infinity); | ||
expect(isPositiveZero(Math.log1p(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.log1p(-0))).to.be.ok; | ||
expect(Math.log1p(Infinity)).to.equal(Infinity); | ||
expect(Math.log1p(5)).to.almostEqual(1.791759469228055); | ||
@@ -91,4 +173,4 @@ expect(Math.log1p(50)).to.almostEqual(3.9318256327243257); | ||
expect(Math.sign(0)).to.equal(0); | ||
expect(Math.sign(-0)).to.equal(-0); | ||
expect(isPositiveZero(Math.sign(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.sign(-0))).to.be.ok; | ||
expect(Number.isNaN(Math.sign(NaN))).to.be.ok; | ||
@@ -100,2 +182,7 @@ }); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.sinh(NaN))).to.be.ok; | ||
expect(isPositiveZero(Math.sinh(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.sinh(-0))).to.be.ok; | ||
expect(Math.sinh(Infinity)).to.equal(Infinity); | ||
expect(Math.sinh(-Infinity)).to.equal(-Infinity); | ||
expect(Math.sinh(-5)).to.almostEqual(-74.20321057778875); | ||
@@ -108,2 +195,7 @@ expect(Math.sinh(2)).to.almostEqual(3.6268604078470186); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.tanh(NaN))).to.be.ok; | ||
expect(isPositiveZero(Math.tanh(+0))).to.be.ok; | ||
expect(isNegativeZero(Math.tanh(-0))).to.be.ok; | ||
expect(Math.tanh(Infinity)).to.equal(1); | ||
expect(Math.tanh(-Infinity)).to.equal(-1); | ||
expect(Math.tanh(90)).to.almostEqual(1); | ||
@@ -116,2 +208,7 @@ expect(Math.tanh(10)).to.almostEqual(0.9999999958776927); | ||
it('should be correct', function() { | ||
expect(Number.isNaN(Math.trunc(NaN))).to.be.ok; | ||
expect(isNegativeZero(Math.trunc(-0))).to.be.ok; | ||
expect(isPositiveZero(Math.trunc(+0))).to.be.ok; | ||
expect(Math.trunc(Infinity)).to.equal(Infinity); | ||
expect(Math.trunc(-Infinity)).to.equal(-Infinity); | ||
expect(Math.trunc(1.01)).to.equal(1); | ||
@@ -118,0 +215,0 @@ expect(Math.trunc(1.99)).to.equal(1); |
@@ -15,7 +15,7 @@ describe('Number', function() { | ||
it('should has max integer', function() { | ||
expect(Number.MAX_INTEGER).to.equal(9007199254740992); | ||
expect(Number.MAX_INTEGER).to.equal(9007199254740991); | ||
}); | ||
it('should has epsilon', function() { | ||
expect(Number.EPSILON).to.equal(2.220446049250313e-16); | ||
expect(Number.EPSILON).to.equal(2.2204460492503130808472633361816e-16); | ||
}); | ||
@@ -22,0 +22,0 @@ }); |
@@ -20,20 +20,2 @@ describe('Object', function() { | ||
describe('Object.isnt()', function() { | ||
it('should compare regular objects correctly', function() { | ||
[null, void 0, [0], 5, 'str', {a: null}].map(function(item) { | ||
return Object.isnt(item, item) | ||
}).forEach(function(result) { | ||
expect(result).to.not.be.ok; | ||
}); | ||
}); | ||
it('should compare 0 and -0 correctly', function() { | ||
expect(Object.isnt(0, -0)).to.be.ok; | ||
}); | ||
it('should compare NaNs correctly', function() { | ||
expect(Object.isnt(NaN, NaN)).to.not.be.ok; | ||
}); | ||
}); | ||
describe('Object.getOwnPropertyDescriptors()', function() { | ||
@@ -78,2 +60,14 @@ it('should produce an array of properties', function() { | ||
}); | ||
describe('Object.assign()', function() { | ||
it('should merge two objects', function() { | ||
expect(Object.assign({a: 1}, {b: 2})).to.eql({a: 1, b: 2}); | ||
}); | ||
}); | ||
describe('Object.mixin()', function() { | ||
it('should merge descriptors of two objects', function() { | ||
expect(Object.mixin({a: 1}, {b: 2})).to.eql({a: 1, b: 2}); | ||
}); | ||
}); | ||
}); |
describe('String', function() { | ||
describe('#repeat()', function() { | ||
it('should throw a RangeError when negative or infinite', function() { | ||
expect(function negativeOne() { return 'test'.repeat(-1); }).to.throw(RangeError); | ||
expect(function infinite() { return 'test'.repeat(Infinity); }).to.throw(RangeError); | ||
}); | ||
it('should coerce to an integer', function() { | ||
expect('test'.repeat(null)).to.eql(''); | ||
expect('test'.repeat(false)).to.eql(''); | ||
expect('test'.repeat('')).to.eql(''); | ||
expect('test'.repeat(NaN)).to.eql(''); | ||
expect('test'.repeat({})).to.eql(''); | ||
expect('test'.repeat([])).to.eql(''); | ||
expect('test'.repeat({ valueOf: function() { return 2; } })).to.eql('testtest'); | ||
}); | ||
it('should work', function() { | ||
@@ -191,2 +204,64 @@ expect('test'.repeat(3)).to.eql('testtesttest'); | ||
}); | ||
describe('.fromCodePoint()', function() { | ||
it('throws a RangeError', function() { | ||
var invalidValues = [ | ||
'abc', | ||
{}, | ||
-1, | ||
0x10FFFF + 1 | ||
]; | ||
invalidValues.forEach(function(value) { | ||
expect(function() { return String.fromCodePoint(value); }).to.throw(RangeError); | ||
}); | ||
}); | ||
it('returns the empty string with no args', function() { | ||
expect(String.fromCodePoint()).to.equal(''); | ||
}); | ||
it('has a length of zero', function() { | ||
expect(String.fromCodePoint.length).to.equal(0); | ||
}); | ||
it('works', function() { | ||
var codePoints = []; | ||
var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789…?!'; | ||
for (var i = 0; i < chars.length; ++i) { | ||
codePoints.push(chars.charCodeAt(i)); | ||
expect(String.fromCodePoint(chars.charCodeAt(i))).to.equal(chars[i]); | ||
} | ||
expect(String.fromCodePoint.apply(String, codePoints)).to.equal(chars); | ||
}); | ||
it('works with unicode', function() { | ||
expect(String.fromCodePoint(0x2500)).to.equal("\u2500"); | ||
expect(String.fromCodePoint(0x010000)).to.equal("\ud800\udc00"); | ||
expect(String.fromCodePoint(0x10FFFF)).to.equal("\udbff\udfff"); | ||
}); | ||
}); | ||
describe('#codePointAt()', function() { | ||
it('works', function() { | ||
var str = 'abc'; | ||
expect(str.codePointAt(0)).to.equal(97); | ||
expect(str.codePointAt(1)).to.equal(98); | ||
expect(str.codePointAt(2)).to.equal(99); | ||
}); | ||
it('works with unicode', function() { | ||
expect('\u2500'.codePointAt(0)).to.equal(0x2500); | ||
expect('\ud800\udc00'.codePointAt(0)).to.equal(0x10000); | ||
expect('\udbff\udfff'.codePointAt(0)).to.equal(0x10ffff); | ||
expect('\ud800\udc00\udbff\udfff'.codePointAt(0)).to.equal(0x10000); | ||
expect('\ud800\udc00\udbff\udfff'.codePointAt(1)).to.equal(0xdc00); | ||
expect('\ud800\udc00\udbff\udfff'.codePointAt(2)).to.equal(0x10ffff); | ||
}); | ||
it('returns undefined when pos is negative or too large', function() { | ||
var str = 'abc'; | ||
expect(str.codePointAt(-1)).to.be.undefined; | ||
expect(str.codePointAt(str.length)).to.be.undefined; | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
267498
20
8970
151
11
2