Bones/node_modules/es6-shim/test/math.js

849 lines
30 KiB
JavaScript
Raw Normal View History

2017-05-17 13:45:25 -04:00
var Assertion = expect().constructor;
Assertion.prototype.almostEqual = function (obj, precision) {
'use strict';
var allowedDiff = precision || 1e-11;
return this.within(obj - allowedDiff, obj + allowedDiff);
};
describe('Math', function () {
var functionsHaveNames = (function foo() {}).name === 'foo';
var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
var isPositiveZero = function (zero) {
'use strict';
return zero === 0 && 1 / zero === Infinity;
};
var isNegativeZero = function (zero) {
'use strict';
return zero === 0 && 1 / zero === -Infinity;
};
var numberIsNaN = Number.isNaN || function (value) {
return value !== value;
};
var valueOfIsNaN = { valueOf: function () { return NaN; } };
var valueOfIsInfinity = { valueOf: function () { return Infinity; } };
var EPSILON = Number.EPSILON || 2.2204460492503130808472633361816e-16;
ifShimIt('is on the exported object', function () {
var exported = require('../');
expect(exported.Math).to.equal(Math);
});
describe('.acosh()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'acosh')) {
return it('exists', function () {
expect(Math).to.have.property('acosh');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.acosh).to.have.property('name', 'acosh');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('acosh').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.acosh).to.have.property('length', 1);
});
it('should be correct', function () {
expect(numberIsNaN(Math.acosh(NaN))).to.equal(true);
expect(numberIsNaN(Math.acosh(0))).to.equal(true);
expect(numberIsNaN(Math.acosh(0.9999999))).to.equal(true);
expect(numberIsNaN(Math.acosh(-1e300))).to.equal(true);
expect(Math.acosh(1e+99)).to.almostEqual(228.64907138697046);
expect(isPositiveZero(Math.acosh(1))).to.equal(true);
expect(Math.acosh(Infinity)).to.equal(Infinity);
expect(Math.acosh(1234)).to.almostEqual(7.811163220849231);
expect(Math.acosh(8.88)).to.almostEqual(2.8737631531629235);
expect(Math.acosh(1e160)).to.almostEqual(369.10676205960726);
expect(Math.acosh(Number.MAX_VALUE)).to.almostEqual(710.4758600739439);
});
});
describe('.asinh()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'asinh')) {
return it('exists', function () {
expect(Math).to.have.property('asinh');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.asinh).to.have.property('name', 'asinh');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('asinh').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.asinh).to.have.property('length', 1);
});
it('should be correct for NaN', function () {
expect(numberIsNaN(Math.asinh(NaN))).to.equal(true);
});
it('should be correct for zeroes', function () {
expect(isPositiveZero(Math.asinh(+0))).to.equal(true);
expect(isNegativeZero(Math.asinh(-0))).to.equal(true);
});
it('should be correct for Infinities', function () {
expect(Math.asinh(Infinity)).to.equal(Infinity);
expect(Math.asinh(-Infinity)).to.equal(-Infinity);
});
it('should be correct', function () {
expect(Math.asinh(1234)).to.almostEqual(7.811163549201245);
expect(Math.asinh(9.99)).to.almostEqual(2.997227420191335);
expect(Math.asinh(1e150)).to.almostEqual(346.0809111296668);
expect(Math.asinh(1e7)).to.almostEqual(16.811242831518268);
expect(Math.asinh(-1e7)).to.almostEqual(-16.811242831518268);
});
});
describe('.atanh()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'atanh')) {
return it('exists', function () {
expect(Math).to.have.property('atanh');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.atanh).to.have.property('name', 'atanh');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('atanh').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.atanh).to.have.property('length', 1);
});
it('should be correct', function () {
expect(numberIsNaN(Math.atanh(NaN))).to.equal(true);
expect(numberIsNaN(Math.atanh(-1.00000001))).to.equal(true);
expect(numberIsNaN(Math.atanh(1.00000001))).to.equal(true);
expect(numberIsNaN(Math.atanh(-1e300))).to.equal(true);
expect(numberIsNaN(Math.atanh(1e300))).to.equal(true);
expect(Math.atanh(-1)).to.equal(-Infinity);
expect(Math.atanh(1)).to.equal(Infinity);
expect(isPositiveZero(Math.atanh(+0))).to.equal(true);
expect(isNegativeZero(Math.atanh(-0))).to.equal(true);
expect(Math.atanh(0.5)).to.almostEqual(0.5493061443340549);
expect(Math.atanh(-0.5)).to.almostEqual(-0.5493061443340549);
expect(Math.atanh(-0.5)).to.almostEqual(-0.5493061443340549);
expect(Math.atanh(0.444)).to.almostEqual(0.47720201260109457);
});
});
describe('.cbrt()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'cbrt')) {
return it('exists', function () {
expect(Math).to.have.property('cbrt');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.cbrt).to.have.property('name', 'cbrt');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('cbrt').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.cbrt).to.have.property('length', 1);
});
it('should be correct', function () {
expect(isNaN(Math.cbrt(NaN))).to.equal(true);
expect(isPositiveZero(Math.cbrt(+0))).to.equal(true);
expect(isNegativeZero(Math.cbrt(-0))).to.equal(true);
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);
expect(Math.cbrt(-1e-300)).to.almostEqual(-1e-100);
expect(Math.cbrt(1e-300)).to.almostEqual(1e-100);
expect(Math.cbrt(-1e+300)).to.almostEqual(-1e+100);
expect(Math.cbrt(1e+300)).to.almostEqual(1e+100);
});
});
describe('.clz32()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'clz32')) {
return it('exists', function () {
expect(Math).to.have.property('clz32');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.clz32).to.have.property('name', 'clz32');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('clz32').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.clz32).to.have.property('length', 1);
});
it('should have proper uint32 conversion', function () {
var integers = [5295, -5295, -9007199254740991, 9007199254740991, 0, -0];
var nonNumbers = [undefined, true, null, {}, [], 'str'];
var nonIntegers = [-9007199254741992, 9007199254741992, 5.9];
integers.forEach(function (item) {
expect(Math.clz32(item)).to.be.within(0, 32);
});
nonIntegers.forEach(function (item) {
expect(Math.clz32(item)).to.be.within(0, 32);
});
nonNumbers.forEach(function (item) {
expect(Math.clz32(item)).to.equal(item === true ? 31 : 32);
});
expect(Math.clz32(true)).to.equal(Math.clz32(1));
expect(Math.clz32('')).to.equal(Math.clz32(0));
expect(Math.clz32('10')).to.equal(Math.clz32(10));
expect(Math.clz32(0.1)).to.equal(32);
expect(Math.clz32(-1)).to.equal(0);
expect(Math.clz32(1)).to.equal(31);
expect(Math.clz32(0xFFFFFFFF)).to.equal(0);
expect(Math.clz32(0x1FFFFFFFF)).to.equal(0);
expect(Math.clz32(0x111111111)).to.equal(3);
expect(Math.clz32(0x11111111)).to.equal(3);
});
it('returns 32 for numbers that coerce to 0', function () {
var zeroishes = [
0,
-0,
NaN,
Infinity,
-Infinity,
0x100000000,
undefined,
null,
false,
'',
'str',
{},
[],
[1, 2]
];
zeroishes.forEach(function (zeroish) {
expect(Math.clz32(zeroish)).to.equal(32);
});
});
});
describe('.cosh()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'cosh')) {
return it('exists', function () {
expect(Math).to.have.property('cosh');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.cosh).to.have.property('name', 'cosh');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('cosh').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.cosh).to.have.property('length', 1);
});
it('should be correct for NaN', function () {
expect(numberIsNaN(Math.cosh(NaN))).to.equal(true);
});
it('should be correct for Infinities', function () {
expect(Math.cosh(Infinity)).to.equal(Infinity);
expect(Math.cosh(-Infinity)).to.equal(Infinity);
});
it('should be correct for zeroes', function () {
expect(Math.cosh(-0)).to.equal(1);
expect(Math.cosh(+0)).to.equal(1);
});
it('should be correct', function () {
// Overridden precision values here are for Chrome, as of v25.0.1364.172
// Broadened slightly for Firefox 31
expect(Math.cosh(12)).to.almostEqual(81377.39571257407, 9e-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);
expect(Math.cosh(-2e-17)).to.equal(1);
});
});
describe('.expm1()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'expm1')) {
return it('exists', function () {
expect(Math).to.have.property('expm1');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.expm1).to.have.property('name', 'expm1');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('expm1').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.expm1).to.have.property('length', 1);
});
it('should be correct for NaN', function () {
expect(numberIsNaN(Math.expm1(NaN))).to.equal(true);
});
it('should be correct for zeroes', function () {
expect(isPositiveZero(Math.expm1(+0))).to.equal(true);
expect(isNegativeZero(Math.expm1(-0))).to.equal(true);
});
it('should be correct for Infinity', function () {
expect(Math.expm1(Infinity)).to.equal(Infinity);
expect(Math.expm1(-Infinity)).to.equal(-1);
});
it('should be correct for arbitrary numbers', function () {
expect(Math.expm1(10)).to.almostEqual(22025.465794806716516957900645284244366353512618556781);
expect(Math.expm1(-10)).to.almostEqual(-0.99995460007023751514846440848443944938976208191113);
expect(Math.expm1(-2e-17)).to.almostEqual(-2e-17);
});
it('works with very negative numbers', function () {
expect(Math.expm1(-38)).to.almostEqual(-1);
expect(Math.expm1(-8675309)).to.almostEqual(-1);
expect(Math.expm1(-4815162342)).to.almostEqual(-1);
});
});
describe('.hypot()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'hypot')) {
return it('exists', function () {
expect(Math).to.have.property('hypot');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.hypot).to.have.property('name', 'hypot');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('hypot').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.hypot).to.have.property('length', 2);
});
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(NaN, Infinity)).to.equal(Infinity);
expect(Math.hypot(-Infinity, 'Hello')).to.equal(Infinity);
expect(Math.hypot(1, 2, Infinity)).to.equal(Infinity);
expect(numberIsNaN(Math.hypot(NaN, 1))).to.equal(true);
expect(isPositiveZero(Math.hypot())).to.equal(true);
expect(isPositiveZero(Math.hypot(0, 0, 0))).to.equal(true);
expect(isPositiveZero(Math.hypot(0, -0, 0))).to.equal(true);
expect(isPositiveZero(Math.hypot(-0, -0, -0))).to.equal(true);
expect(Math.hypot(66, 66)).to.almostEqual(93.33809511662427);
expect(Math.hypot(0.1, 100)).to.almostEqual(100.0000499999875);
});
it('should coerce to a number', function () {
expect(Math.hypot('Infinity', 0)).to.equal(Infinity);
expect(Math.hypot('3', '3', '3', '3')).to.equal(6);
});
it('should take more than 3 arguments', function () {
expect(Math.hypot(66, 66, 66)).to.almostEqual(114.3153532995459);
expect(Math.hypot(66, 66, 66, 66)).to.equal(132);
});
it('should have the right length', function () {
expect(Math.hypot.length).to.equal(2);
});
it('works for very large or small numbers', function () {
expect(Math.hypot(1e+300, 1e+300)).to.almostEqual(1.4142135623730952e+300);
expect(Math.hypot(1e-300, 1e-300)).to.almostEqual(1.4142135623730952e-300);
expect(Math.hypot(1e+300, 1e+300, 2, 3)).to.almostEqual(1.4142135623730952e+300);
});
});
describe('.log2()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'log2')) {
return it('exists', function () {
expect(Math).to.have.property('log2');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.log2).to.have.property('name', 'log2');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('log2').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.log2).to.have.property('length', 1);
});
it('is correct for small numbers', function () {
expect(numberIsNaN(Math.log2(-1e-50))).to.equal(true);
});
it('is correct for edge cases', function () {
expect(numberIsNaN(Math.log2(NaN))).to.equal(true);
expect(Math.log2(+0)).to.equal(-Infinity);
expect(Math.log2(-0)).to.equal(-Infinity);
expect(isPositiveZero(Math.log2(1))).to.equal(true);
expect(Math.log2(Infinity)).to.equal(Infinity);
});
it('should have the right precision', function () {
expect(Math.log2(5)).to.almostEqual(2.321928094887362);
expect(Math.log2(32)).to.almostEqual(5);
});
});
describe('.log10', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'log10')) {
return it('exists', function () {
expect(Math).to.have.property('log10');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.log10).to.have.property('name', 'log10');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('log10').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.log10).to.have.property('length', 1);
});
it('should be correct for edge cases', function () {
expect(numberIsNaN(Math.log10(NaN))).to.equal(true);
expect(numberIsNaN(Math.log10(-1e-50))).to.equal(true);
expect(Math.log10(+0)).to.equal(-Infinity);
expect(Math.log10(-0)).to.equal(-Infinity);
expect(isPositiveZero(Math.log10(1))).to.equal(true);
expect(Math.log10(Infinity)).to.equal(Infinity);
});
it('should have the right precision', function () {
expect(Math.log10(5)).to.almostEqual(0.698970004336018);
expect(Math.log10(50)).to.almostEqual(1.6989700043360187);
});
});
describe('.log1p', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'log1p')) {
return it('exists', function () {
expect(Math).to.have.property('log1p');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.log1p).to.have.property('name', 'log1p');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('log1p').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.log1p).to.have.property('length', 1);
});
it('should be correct', function () {
expect(numberIsNaN(Math.log1p(NaN))).to.equal(true);
expect(numberIsNaN(Math.log1p(-1.000000001))).to.equal(true);
expect(Math.log1p(-1)).to.equal(-Infinity);
expect(isPositiveZero(Math.log1p(+0))).to.equal(true);
expect(isNegativeZero(Math.log1p(-0))).to.equal(true);
expect(Math.log1p(Infinity)).to.equal(Infinity);
expect(Math.log1p(5)).to.almostEqual(1.791759469228055);
expect(Math.log1p(50)).to.almostEqual(3.9318256327243257);
expect(Math.log1p(-1e-17)).to.equal(-1e-17);
expect(Math.log1p(-2e-17)).to.equal(-2e-17);
});
});
describe('.sign()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'sign')) {
return it('exists', function () {
expect(Math).to.have.property('sign');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.sign).to.have.property('name', 'sign');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('sign').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.sign).to.have.property('length', 1);
});
it('should be correct', function () {
// we also verify that [[ToNumber]] is being called
[Infinity, 1].forEach(function (value) {
expect(Math.sign(value)).to.equal(1);
expect(Math.sign(String(value))).to.equal(1);
});
expect(Math.sign(true)).to.equal(1);
[-Infinity, -1].forEach(function (value) {
expect(Math.sign(value)).to.equal(-1);
expect(Math.sign(String(value))).to.equal(-1);
});
expect(isPositiveZero(Math.sign(+0))).to.equal(true);
expect(isPositiveZero(Math.sign('0'))).to.equal(true);
expect(isPositiveZero(Math.sign('+0'))).to.equal(true);
expect(isPositiveZero(Math.sign(''))).to.equal(true);
expect(isPositiveZero(Math.sign(' '))).to.equal(true);
expect(isPositiveZero(Math.sign(null))).to.equal(true);
expect(isPositiveZero(Math.sign(false))).to.equal(true);
expect(isNegativeZero(Math.sign(-0))).to.equal(true);
expect(isNegativeZero(Math.sign('-0'))).to.equal(true);
expect(numberIsNaN(Math.sign(NaN))).to.equal(true);
expect(numberIsNaN(Math.sign('NaN'))).to.equal(true);
expect(numberIsNaN(Math.sign(undefined))).to.equal(true);
});
});
describe('.sinh()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'sinh')) {
return it('exists', function () {
expect(Math).to.have.property('sinh');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.sinh).to.have.property('name', 'sinh');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('sinh').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.sinh).to.have.property('length', 1);
});
it('should be correct', function () {
expect(numberIsNaN(Math.sinh(NaN))).to.equal(true);
expect(isPositiveZero(Math.sinh(+0))).to.equal(true);
expect(isNegativeZero(Math.sinh(-0))).to.equal(true);
expect(Math.sinh(Infinity)).to.equal(Infinity);
expect(Math.sinh(-Infinity)).to.equal(-Infinity);
expect(Math.sinh(-5)).to.almostEqual(-74.20321057778875);
expect(Math.sinh(2)).to.almostEqual(3.6268604078470186);
expect(Math.sinh(-2e-17)).to.equal(-2e-17);
});
});
describe('.tanh()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'tanh')) {
return it('exists', function () {
expect(Math).to.have.property('tanh');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.tanh).to.have.property('name', 'tanh');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('tanh').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.tanh).to.have.property('length', 1);
});
it('should be correct', function () {
expect(numberIsNaN(Math.tanh(NaN))).to.equal(true);
expect(isPositiveZero(Math.tanh(+0))).to.equal(true);
expect(isNegativeZero(Math.tanh(-0))).to.equal(true);
expect(Math.tanh(Infinity)).to.equal(1);
expect(Math.tanh(-Infinity)).to.equal(-1);
expect(Math.tanh(19)).to.almostEqual(1);
expect(Math.tanh(-19)).to.almostEqual(-1);
expect(Math.tanh(20)).to.equal(1); // JS loses precision for true value at this integer
expect(Math.tanh(-20)).to.equal(-1); // JS loses precision for true value at this integer
expect(Math.tanh(10)).to.almostEqual(0.9999999958776927);
expect(Math.tanh(-2e-17)).to.equal(-2e-17);
});
});
describe('.trunc()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'trunc')) {
return it('exists', function () {
expect(Math).to.have.property('trunc');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.trunc).to.have.property('name', 'trunc');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('trunc').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.trunc).to.have.property('length', 1);
});
it('should be correct', function () {
expect(numberIsNaN(Math.trunc(NaN))).to.equal(true);
expect(isNegativeZero(Math.trunc(-0))).to.equal(true);
expect(isPositiveZero(Math.trunc(+0))).to.equal(true);
expect(Math.trunc(Infinity)).to.equal(Infinity);
expect(Math.trunc(-Infinity)).to.equal(-Infinity);
expect(Math.trunc(1.01)).to.equal(1);
expect(Math.trunc(1.99)).to.equal(1);
expect(Math.trunc(-555.555)).to.equal(-555);
expect(Math.trunc(-1.99)).to.equal(-1);
});
it('should coerce to a number immediately', function () {
expect(Math.trunc(valueOfIsInfinity)).to.equal(Infinity);
expect(numberIsNaN(Math.trunc(valueOfIsNaN))).to.equal(true);
});
});
describe('.imul()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'imul')) {
return it('exists', function () {
expect(Math).to.have.property('imul');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.imul).to.have.property('name', 'imul');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('imul').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.imul).to.have.property('length', 2);
});
var str = 'str';
var obj = {};
var arr = [];
it('should be correct for non-numbers', function () {
expect(Math.imul(false, 7)).to.equal(0);
expect(Math.imul(7, false)).to.equal(0);
expect(Math.imul(false, false)).to.equal(0);
expect(Math.imul(true, 7)).to.equal(7);
expect(Math.imul(7, true)).to.equal(7);
expect(Math.imul(true, true)).to.equal(1);
expect(Math.imul(undefined, 7)).to.equal(0);
expect(Math.imul(7, undefined)).to.equal(0);
expect(Math.imul(undefined, undefined)).to.equal(0);
expect(Math.imul(str, 7)).to.equal(0);
expect(Math.imul(7, str)).to.equal(0);
expect(Math.imul(obj, 7)).to.equal(0);
expect(Math.imul(7, obj)).to.equal(0);
expect(Math.imul(arr, 7)).to.equal(0);
expect(Math.imul(7, arr)).to.equal(0);
});
it('should be correct for hex values', function () {
expect(Math.imul(0xffffffff, 5)).to.equal(-5);
expect(Math.imul(0xfffffffe, 5)).to.equal(-10);
});
it('should be correct', function () {
expect(Math.imul(2, 4)).to.equal(8);
expect(Math.imul(-1, 8)).to.equal(-8);
expect(Math.imul(-2, -2)).to.equal(4);
expect(Math.imul(-0, 7)).to.equal(0);
expect(Math.imul(7, -0)).to.equal(0);
expect(Math.imul(0.1, 7)).to.equal(0);
expect(Math.imul(7, 0.1)).to.equal(0);
expect(Math.imul(0.9, 7)).to.equal(0);
expect(Math.imul(7, 0.9)).to.equal(0);
expect(Math.imul(1.1, 7)).to.equal(7);
expect(Math.imul(7, 1.1)).to.equal(7);
expect(Math.imul(1.9, 7)).to.equal(7);
expect(Math.imul(7, 1.9)).to.equal(7);
});
it('should be correct for objects with valueOf', function () {
var x = {
x: 0,
valueOf: function () { this.x += 1; return this.x; }
};
expect(Math.imul(x, 1)).to.equal(1);
expect(Math.imul(1, x)).to.equal(2);
expect(Math.imul(x, 1)).to.equal(3);
expect(Math.imul(1, x)).to.equal(4);
expect(Math.imul(x, 1)).to.equal(5);
});
});
describe('.round()', function () {
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.round).to.have.property('name', 'round');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('round').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.round).to.have.property('length', 1);
});
it('works for edge cases', function () {
expect(numberIsNaN(Math.round(NaN))).to.equal(true);
expect(isPositiveZero(Math.round(0))).to.equal(true);
expect(isNegativeZero(Math.round(-0))).to.equal(true);
expect(Math.round(Infinity)).to.equal(Infinity);
expect(Math.round(-Infinity)).to.equal(-Infinity);
});
it('returns 0 for (0,0.5)', function () {
expect(Math.round(0.5)).not.to.equal(0);
expect(Math.round(0.5 - (EPSILON / 4))).to.equal(0);
expect(Math.round(0 + (EPSILON / 4))).to.equal(0);
});
it('returns -0 for (-0.5,0)', function () {
expect(Math.round(-0.5)).to.equal(0);
expect(Math.round(-0.5 - (EPSILON / 3.99))).not.to.equal(0);
expect(isNegativeZero(Math.round(-0.5 + (EPSILON / 3.99)))).to.equal(true);
expect(isNegativeZero(Math.round(0 - (EPSILON / 3.99)))).to.equal(true);
});
it('returns 1 / Number.EPSILON + 1 for 1 / Number.EPSILON + 1', function () {
var inverseEpsilonPlus1 = (1 / EPSILON) + 1;
expect(Math.round(inverseEpsilonPlus1)).to.equal(inverseEpsilonPlus1);
});
it('returns 2 / Number.EPSILON - 1 for 2 / Number.EPSILON - 1', function () {
var twiceInverseEpsilonMinus1 = (2 / EPSILON) - 1;
expect(Math.round(twiceInverseEpsilonMinus1)).to.equal(twiceInverseEpsilonMinus1);
});
});
describe('.fround()', function () {
if (!Object.prototype.hasOwnProperty.call(Math, 'fround')) {
return it('exists', function () {
expect(Math).to.have.property('fround');
});
}
ifFunctionsHaveNamesIt('has the right name', function () {
expect(Math.fround).to.have.property('name', 'fround');
});
it('is not enumerable', function () {
expect(Math).ownPropertyDescriptor('fround').to.have.property('enumerable', false);
});
it('has the right arity', function () {
expect(Math.fround).to.have.property('length', 1);
});
// Mozilla's reference tests: https://bug900125.bugzilla.mozilla.org/attachment.cgi?id=793163
it('returns NaN for undefined', function () {
expect(numberIsNaN(Math.fround())).to.equal(true);
});
it('returns NaN for NaN', function () {
expect(numberIsNaN(Math.fround(NaN))).to.equal(true);
});
it('works for zeroes and infinities', function () {
expect(isPositiveZero(Math.fround(0))).to.equal(true);
expect(isPositiveZero(Math.fround({ valueOf: function () { return 0; } }))).to.equal(true);
expect(isNegativeZero(Math.fround(-0))).to.equal(true);
expect(isNegativeZero(Math.fround({ valueOf: function () { return -0; } }))).to.equal(true);
expect(Math.fround(Infinity)).to.equal(Infinity);
expect(Math.fround({ valueOf: function () { return Infinity; } })).to.equal(Infinity);
expect(Math.fround(-Infinity)).to.equal(-Infinity);
expect(Math.fround({ valueOf: function () { return -Infinity; } })).to.equal(-Infinity);
});
it('returns infinity for large numbers', function () {
expect(Math.fround(1.7976931348623157e+308)).to.equal(Infinity);
expect(Math.fround(-1.7976931348623157e+308)).to.equal(-Infinity);
expect(Math.fround(3.4028235677973366e+38)).to.equal(Infinity);
});
it('returns zero for really small numbers', function () {
expect(Number.MIN_VALUE).to.equal(5e-324);
expect(Math.fround(Number.MIN_VALUE)).to.equal(0);
expect(Math.fround(-Number.MIN_VALUE)).to.equal(0);
});
it('rounds properly', function () {
expect(Math.fround(3)).to.equal(3);
expect(Math.fround(-3)).to.equal(-3);
});
it('rounds properly with the max float 32', function () {
var maxFloat32 = 3.4028234663852886e+38;
expect(Math.fround(maxFloat32)).to.equal(maxFloat32);
expect(Math.fround(-maxFloat32)).to.equal(-maxFloat32);
// round-nearest rounds down to maxFloat32
expect(Math.fround(maxFloat32 + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 2))).to.equal(maxFloat32);
});
it('rounds properly with the min float 32', function () {
var minFloat32 = 1.401298464324817e-45;
expect(Math.fround(minFloat32)).to.equal(minFloat32);
expect(Math.fround(-minFloat32)).to.equal(-minFloat32);
expect(Math.fround(minFloat32 / 2)).to.equal(0);
expect(Math.fround(-minFloat32 / 2)).to.equal(0);
expect(Math.fround((minFloat32 / 2) + Math.pow(2, -202))).to.equal(minFloat32);
expect(Math.fround((-minFloat32 / 2) - Math.pow(2, -202))).to.equal(-minFloat32);
});
});
});