1 | var EPSILON = Number.EPSILON || 2.2204460492503130808472633361816e-16;
|
2 |
|
3 | var Assertion = expect().constructor;
|
4 | Assertion.prototype.almostEqual = function (obj, precision) {
|
5 | 'use strict';
|
6 |
|
7 | var allowedDiff = precision || 1e-11;
|
8 | return this.within(obj - allowedDiff, obj + allowedDiff);
|
9 | };
|
10 |
|
11 | Assertion.prototype.haveULPDistance = function (expected, distance) {
|
12 | var actual = this._obj;
|
13 | return this.above(Math.abs(1 - (actual / expected)) / EPSILON, distance);
|
14 | };
|
15 |
|
16 | describe('Math', function () {
|
17 | var functionsHaveNames = (function foo() {}).name === 'foo';
|
18 | var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
|
19 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
|
20 |
|
21 | var isPositiveZero = function (zero) {
|
22 | 'use strict';
|
23 |
|
24 | return zero === 0 && 1 / zero === Infinity;
|
25 | };
|
26 | var isNegativeZero = function (zero) {
|
27 | 'use strict';
|
28 |
|
29 | return zero === 0 && 1 / zero === -Infinity;
|
30 | };
|
31 | var numberIsNaN = Number.isNaN || function (value) {
|
32 | return value !== value;
|
33 | };
|
34 | var valueOfIsNaN = { valueOf: function () { return NaN; } };
|
35 | var valueOfIsInfinity = { valueOf: function () { return Infinity; } };
|
36 |
|
37 | ifShimIt('is on the exported object', function () {
|
38 | var exported = require('../');
|
39 | expect(exported.Math).to.equal(Math);
|
40 | });
|
41 |
|
42 | describe('.acosh()', function () {
|
43 | if (!Object.prototype.hasOwnProperty.call(Math, 'acosh')) {
|
44 | return it('exists', function () {
|
45 | expect(Math).to.have.property('acosh');
|
46 | });
|
47 | }
|
48 |
|
49 | ifFunctionsHaveNamesIt('has the right name', function () {
|
50 | expect(Math.acosh).to.have.property('name', 'acosh');
|
51 | });
|
52 |
|
53 | it('is not enumerable', function () {
|
54 | expect(Math).ownPropertyDescriptor('acosh').to.have.property('enumerable', false);
|
55 | });
|
56 |
|
57 | it('has the right arity', function () {
|
58 | expect(Math.acosh).to.have.property('length', 1);
|
59 | });
|
60 |
|
61 | it('should be correct', function () {
|
62 | expect(numberIsNaN(Math.acosh(NaN))).to.equal(true);
|
63 | expect(numberIsNaN(Math.acosh(0))).to.equal(true);
|
64 | expect(numberIsNaN(Math.acosh(0.9999999))).to.equal(true);
|
65 | expect(numberIsNaN(Math.acosh(-1e300))).to.equal(true);
|
66 | expect(Math.acosh(1e+99)).to.almostEqual(228.64907138697046);
|
67 | expect(isPositiveZero(Math.acosh(1))).to.equal(true);
|
68 | expect(Math.acosh(Infinity)).to.equal(Infinity);
|
69 | expect(Math.acosh(1234)).to.almostEqual(7.811163220849231);
|
70 | expect(Math.acosh(8.88)).to.almostEqual(2.8737631531629235);
|
71 | expect(Math.acosh(1e160)).to.almostEqual(369.10676205960726);
|
72 | expect(Math.acosh(Number.MAX_VALUE)).to.almostEqual(710.4758600739439);
|
73 | });
|
74 |
|
75 | it('works for EPSILON values near 1', function () {
|
76 | var result = Math.acosh(1 + EPSILON);
|
77 | var expected = Math.sqrt(2 * EPSILON);
|
78 |
|
79 | expect(result).to.almostEqual(expected);
|
80 | expect(result).to.haveULPDistance(expected, 8);
|
81 | });
|
82 | });
|
83 |
|
84 | describe('.asinh()', function () {
|
85 | if (!Object.prototype.hasOwnProperty.call(Math, 'asinh')) {
|
86 | return it('exists', function () {
|
87 | expect(Math).to.have.property('asinh');
|
88 | });
|
89 | }
|
90 |
|
91 | ifFunctionsHaveNamesIt('has the right name', function () {
|
92 | expect(Math.asinh).to.have.property('name', 'asinh');
|
93 | });
|
94 |
|
95 | it('is not enumerable', function () {
|
96 | expect(Math).ownPropertyDescriptor('asinh').to.have.property('enumerable', false);
|
97 | });
|
98 |
|
99 | it('has the right arity', function () {
|
100 | expect(Math.asinh).to.have.property('length', 1);
|
101 | });
|
102 |
|
103 | it('should be correct for NaN', function () {
|
104 | expect(numberIsNaN(Math.asinh(NaN))).to.equal(true);
|
105 | });
|
106 |
|
107 | it('should be correct for zeroes', function () {
|
108 | expect(isPositiveZero(Math.asinh(+0))).to.equal(true);
|
109 | expect(isNegativeZero(Math.asinh(-0))).to.equal(true);
|
110 | });
|
111 |
|
112 | it('should be correct for Infinities', function () {
|
113 | expect(Math.asinh(Infinity)).to.equal(Infinity);
|
114 | expect(Math.asinh(-Infinity)).to.equal(-Infinity);
|
115 | });
|
116 |
|
117 | it('should be correct', function () {
|
118 | expect(Math.asinh(1234)).to.almostEqual(7.811163549201245);
|
119 | expect(Math.asinh(9.99)).to.almostEqual(2.997227420191335);
|
120 | expect(Math.asinh(1e150)).to.almostEqual(346.0809111296668);
|
121 | expect(Math.asinh(1e7)).to.almostEqual(16.811242831518268);
|
122 | expect(Math.asinh(-1e7)).to.almostEqual(-16.811242831518268);
|
123 | });
|
124 |
|
125 | it('is correct for extreme non-infinities', function () {
|
126 | expect(Math.asinh(1e+300)).not.to.equal(Infinity);
|
127 | expect(Math.asinh(1e+300)).to.almostEqual(691.4686750787736);
|
128 | });
|
129 | });
|
130 |
|
131 | describe('.atanh()', function () {
|
132 | if (!Object.prototype.hasOwnProperty.call(Math, 'atanh')) {
|
133 | return it('exists', function () {
|
134 | expect(Math).to.have.property('atanh');
|
135 | });
|
136 | }
|
137 |
|
138 | ifFunctionsHaveNamesIt('has the right name', function () {
|
139 | expect(Math.atanh).to.have.property('name', 'atanh');
|
140 | });
|
141 |
|
142 | it('is not enumerable', function () {
|
143 | expect(Math).ownPropertyDescriptor('atanh').to.have.property('enumerable', false);
|
144 | });
|
145 |
|
146 | it('has the right arity', function () {
|
147 | expect(Math.atanh).to.have.property('length', 1);
|
148 | });
|
149 |
|
150 | it('should be correct', function () {
|
151 | expect(numberIsNaN(Math.atanh(NaN))).to.equal(true);
|
152 | expect(numberIsNaN(Math.atanh(-1.00000001))).to.equal(true);
|
153 | expect(numberIsNaN(Math.atanh(1.00000001))).to.equal(true);
|
154 | expect(numberIsNaN(Math.atanh(-1e300))).to.equal(true);
|
155 | expect(numberIsNaN(Math.atanh(1e300))).to.equal(true);
|
156 | expect(Math.atanh(-1)).to.equal(-Infinity);
|
157 | expect(Math.atanh(1)).to.equal(Infinity);
|
158 | expect(isPositiveZero(Math.atanh(+0))).to.equal(true);
|
159 | expect(isNegativeZero(Math.atanh(-0))).to.equal(true);
|
160 | expect(Math.atanh(0.5)).to.almostEqual(0.5493061443340549);
|
161 | expect(Math.atanh(-0.5)).to.almostEqual(-0.5493061443340549);
|
162 | expect(Math.atanh(-0.5)).to.almostEqual(-0.5493061443340549);
|
163 | expect(Math.atanh(0.444)).to.almostEqual(0.47720201260109457);
|
164 | });
|
165 |
|
166 | it('is correct for extreme non-infinities', function () {
|
167 | expect(Math.atanh(1e-300)).not.to.equal(0);
|
168 | expect(Math.atanh(1e-300)).to.almostEqual(1e-300);
|
169 | });
|
170 | });
|
171 |
|
172 | describe('.cbrt()', function () {
|
173 | if (!Object.prototype.hasOwnProperty.call(Math, 'cbrt')) {
|
174 | return it('exists', function () {
|
175 | expect(Math).to.have.property('cbrt');
|
176 | });
|
177 | }
|
178 |
|
179 | ifFunctionsHaveNamesIt('has the right name', function () {
|
180 | expect(Math.cbrt).to.have.property('name', 'cbrt');
|
181 | });
|
182 |
|
183 | it('is not enumerable', function () {
|
184 | expect(Math).ownPropertyDescriptor('cbrt').to.have.property('enumerable', false);
|
185 | });
|
186 |
|
187 | it('has the right arity', function () {
|
188 | expect(Math.cbrt).to.have.property('length', 1);
|
189 | });
|
190 |
|
191 | it('should be correct', function () {
|
192 | expect(isNaN(Math.cbrt(NaN))).to.equal(true);
|
193 | expect(isPositiveZero(Math.cbrt(+0))).to.equal(true);
|
194 | expect(isNegativeZero(Math.cbrt(-0))).to.equal(true);
|
195 | expect(Math.cbrt(Infinity)).to.equal(Infinity);
|
196 | expect(Math.cbrt(-Infinity)).to.equal(-Infinity);
|
197 | expect(Math.cbrt(-8)).to.almostEqual(-2);
|
198 | expect(Math.cbrt(8)).to.almostEqual(2);
|
199 | expect(Math.cbrt(-1000)).to.almostEqual(-10);
|
200 | expect(Math.cbrt(1000)).to.almostEqual(10);
|
201 | });
|
202 |
|
203 | it('is correct at extremes', function () {
|
204 | var result = Math.cbrt(1e-300);
|
205 | var expected = 1e-100;
|
206 | expect(result).to.almostEqual(expected);
|
207 | expect(result).to.haveULPDistance(expected, 8);
|
208 |
|
209 | expect(Math.cbrt(-1e-300)).to.almostEqual(-1e-100);
|
210 | expect(Math.cbrt(-1e+300)).to.almostEqual(-1e+100);
|
211 | expect(Math.cbrt(1e+300)).to.almostEqual(1e+100);
|
212 | });
|
213 | });
|
214 |
|
215 | describe('.clz32()', function () {
|
216 | if (!Object.prototype.hasOwnProperty.call(Math, 'clz32')) {
|
217 | return it('exists', function () {
|
218 | expect(Math).to.have.property('clz32');
|
219 | });
|
220 | }
|
221 |
|
222 | ifFunctionsHaveNamesIt('has the right name', function () {
|
223 | expect(Math.clz32).to.have.property('name', 'clz32');
|
224 | });
|
225 |
|
226 | it('is not enumerable', function () {
|
227 | expect(Math).ownPropertyDescriptor('clz32').to.have.property('enumerable', false);
|
228 | });
|
229 |
|
230 | it('has the right arity', function () {
|
231 | expect(Math.clz32).to.have.property('length', 1);
|
232 | });
|
233 |
|
234 | it('should have proper uint32 conversion', function () {
|
235 | var integers = [5295, -5295, -9007199254740991, 9007199254740991, 0, -0];
|
236 | var nonNumbers = [undefined, true, null, {}, [], 'str'];
|
237 | var nonIntegers = [-9007199254741992, 9007199254741992, 5.9];
|
238 |
|
239 | integers.forEach(function (item) {
|
240 | expect(Math.clz32(item)).to.be.within(0, 32);
|
241 | });
|
242 | nonIntegers.forEach(function (item) {
|
243 | expect(Math.clz32(item)).to.be.within(0, 32);
|
244 | });
|
245 | nonNumbers.forEach(function (item) {
|
246 | expect(Math.clz32(item)).to.equal(item === true ? 31 : 32);
|
247 | });
|
248 | expect(Math.clz32(true)).to.equal(Math.clz32(1));
|
249 | expect(Math.clz32('')).to.equal(Math.clz32(0));
|
250 | expect(Math.clz32('10')).to.equal(Math.clz32(10));
|
251 | expect(Math.clz32(0.1)).to.equal(32);
|
252 | expect(Math.clz32(-1)).to.equal(0);
|
253 | expect(Math.clz32(1)).to.equal(31);
|
254 | expect(Math.clz32(0xFFFFFFFF)).to.equal(0);
|
255 | expect(Math.clz32(0x1FFFFFFFF)).to.equal(0);
|
256 | expect(Math.clz32(0x111111111)).to.equal(3);
|
257 | expect(Math.clz32(0x11111111)).to.equal(3);
|
258 | });
|
259 |
|
260 | it('returns 32 for numbers that coerce to 0', function () {
|
261 | var zeroishes = [
|
262 | 0,
|
263 | -0,
|
264 | NaN,
|
265 | Infinity,
|
266 | -Infinity,
|
267 | 0x100000000,
|
268 | undefined,
|
269 | null,
|
270 | false,
|
271 | '',
|
272 | 'str',
|
273 | {},
|
274 | [],
|
275 | [1, 2]
|
276 | ];
|
277 | zeroishes.forEach(function (zeroish) {
|
278 | expect(Math.clz32(zeroish)).to.equal(32);
|
279 | });
|
280 | });
|
281 | });
|
282 |
|
283 | describe('.cosh()', function () {
|
284 | if (!Object.prototype.hasOwnProperty.call(Math, 'cosh')) {
|
285 | return it('exists', function () {
|
286 | expect(Math).to.have.property('cosh');
|
287 | });
|
288 | }
|
289 |
|
290 | ifFunctionsHaveNamesIt('has the right name', function () {
|
291 | expect(Math.cosh).to.have.property('name', 'cosh');
|
292 | });
|
293 |
|
294 | it('is not enumerable', function () {
|
295 | expect(Math).ownPropertyDescriptor('cosh').to.have.property('enumerable', false);
|
296 | });
|
297 |
|
298 | it('has the right arity', function () {
|
299 | expect(Math.cosh).to.have.property('length', 1);
|
300 | });
|
301 |
|
302 | it('should be correct for NaN', function () {
|
303 | expect(numberIsNaN(Math.cosh(NaN))).to.equal(true);
|
304 | });
|
305 |
|
306 | it('should be correct for Infinities', function () {
|
307 | expect(Math.cosh(Infinity)).to.equal(Infinity);
|
308 | expect(Math.cosh(-Infinity)).to.equal(Infinity);
|
309 | });
|
310 |
|
311 | it('should be correct for zeroes', function () {
|
312 | expect(Math.cosh(-0)).to.equal(1);
|
313 | expect(Math.cosh(+0)).to.equal(1);
|
314 | });
|
315 |
|
316 | it('should be correct', function () {
|
317 |
|
318 |
|
319 | expect(Math.cosh(12)).to.almostEqual(81377.39571257407, 9e-11);
|
320 | expect(Math.cosh(22)).to.almostEqual(1792456423.065795780980053377, 1e-5);
|
321 | expect(Math.cosh(-10)).to.almostEqual(11013.23292010332313972137);
|
322 | expect(Math.cosh(-23)).to.almostEqual(4872401723.1244513000, 1e-5);
|
323 | expect(Math.cosh(-2e-17)).to.equal(1);
|
324 | });
|
325 |
|
326 | it('is correct for extreme non-infinities', function () {
|
327 | expect(Math.cosh(710)).not.to.equal(Infinity);
|
328 | expect(Math.cosh(710) / 1e+308).to.almostEqual(1.1169973830808557);
|
329 | });
|
330 | });
|
331 |
|
332 | describe('.expm1()', function () {
|
333 | if (!Object.prototype.hasOwnProperty.call(Math, 'expm1')) {
|
334 | return it('exists', function () {
|
335 | expect(Math).to.have.property('expm1');
|
336 | });
|
337 | }
|
338 |
|
339 | ifFunctionsHaveNamesIt('has the right name', function () {
|
340 | expect(Math.expm1).to.have.property('name', 'expm1');
|
341 | });
|
342 |
|
343 | it('is not enumerable', function () {
|
344 | expect(Math).ownPropertyDescriptor('expm1').to.have.property('enumerable', false);
|
345 | });
|
346 |
|
347 | it('has the right arity', function () {
|
348 | expect(Math.expm1).to.have.property('length', 1);
|
349 | });
|
350 |
|
351 | it('should be correct for NaN', function () {
|
352 | expect(numberIsNaN(Math.expm1(NaN))).to.equal(true);
|
353 | });
|
354 |
|
355 | it('should be correct for zeroes', function () {
|
356 | expect(isPositiveZero(Math.expm1(+0))).to.equal(true);
|
357 | expect(isNegativeZero(Math.expm1(-0))).to.equal(true);
|
358 | });
|
359 |
|
360 | it('should be correct for Infinity', function () {
|
361 | expect(Math.expm1(Infinity)).to.equal(Infinity);
|
362 | expect(Math.expm1(-Infinity)).to.equal(-1);
|
363 | });
|
364 |
|
365 | it('should be correct for arbitrary numbers', function () {
|
366 | expect(Math.expm1(10)).to.almostEqual(22025.465794806716516957900645284244366353512618556781);
|
367 | expect(Math.expm1(-10)).to.almostEqual(-0.99995460007023751514846440848443944938976208191113);
|
368 | expect(Math.expm1(-2e-17)).to.almostEqual(-2e-17);
|
369 | });
|
370 |
|
371 | it('works with very negative numbers', function () {
|
372 | expect(Math.expm1(-38)).to.almostEqual(-1);
|
373 | expect(Math.expm1(-8675309)).to.almostEqual(-1);
|
374 | expect(Math.expm1(-4815162342)).to.almostEqual(-1);
|
375 | });
|
376 | });
|
377 |
|
378 | describe('.hypot()', function () {
|
379 | if (!Object.prototype.hasOwnProperty.call(Math, 'hypot')) {
|
380 | return it('exists', function () {
|
381 | expect(Math).to.have.property('hypot');
|
382 | });
|
383 | }
|
384 |
|
385 | ifFunctionsHaveNamesIt('has the right name', function () {
|
386 | expect(Math.hypot).to.have.property('name', 'hypot');
|
387 | });
|
388 |
|
389 | it('is not enumerable', function () {
|
390 | expect(Math).ownPropertyDescriptor('hypot').to.have.property('enumerable', false);
|
391 | });
|
392 |
|
393 | it('has the right arity', function () {
|
394 | expect(Math.hypot).to.have.property('length', 2);
|
395 | });
|
396 |
|
397 | it('should be correct', function () {
|
398 | expect(Math.hypot(Infinity)).to.equal(Infinity);
|
399 | expect(Math.hypot(-Infinity)).to.equal(Infinity);
|
400 | expect(Math.hypot(Infinity, NaN)).to.equal(Infinity);
|
401 | expect(Math.hypot(NaN, Infinity)).to.equal(Infinity);
|
402 | expect(Math.hypot(-Infinity, 'Hello')).to.equal(Infinity);
|
403 | expect(Math.hypot(1, 2, Infinity)).to.equal(Infinity);
|
404 | expect(numberIsNaN(Math.hypot(NaN, 1))).to.equal(true);
|
405 | expect(isPositiveZero(Math.hypot())).to.equal(true);
|
406 | expect(isPositiveZero(Math.hypot(0, 0, 0))).to.equal(true);
|
407 | expect(isPositiveZero(Math.hypot(0, -0, 0))).to.equal(true);
|
408 | expect(isPositiveZero(Math.hypot(-0, -0, -0))).to.equal(true);
|
409 | expect(Math.hypot(66, 66)).to.almostEqual(93.33809511662427);
|
410 | expect(Math.hypot(0.1, 100)).to.almostEqual(100.0000499999875);
|
411 | });
|
412 |
|
413 | it('should coerce to a number', function () {
|
414 | expect(Math.hypot('Infinity', 0)).to.equal(Infinity);
|
415 | expect(Math.hypot('3', '3', '3', '3')).to.equal(6);
|
416 | });
|
417 |
|
418 | it('should take more than 3 arguments', function () {
|
419 | expect(Math.hypot(66, 66, 66)).to.almostEqual(114.3153532995459);
|
420 | expect(Math.hypot(66, 66, 66, 66)).to.equal(132);
|
421 | });
|
422 |
|
423 | it('should have the right length', function () {
|
424 | expect(Math.hypot.length).to.equal(2);
|
425 | });
|
426 |
|
427 | it('works for very large or small numbers', function () {
|
428 | expect(Math.hypot(1e+300, 1e+300)).to.almostEqual(1.4142135623730952e+300);
|
429 | expect(Math.hypot(1e-300, 1e-300)).to.almostEqual(1.4142135623730952e-300);
|
430 | expect(Math.hypot(1e+300, 1e+300, 2, 3)).to.almostEqual(1.4142135623730952e+300);
|
431 | });
|
432 | });
|
433 |
|
434 | describe('.log2()', function () {
|
435 | if (!Object.prototype.hasOwnProperty.call(Math, 'log2')) {
|
436 | return it('exists', function () {
|
437 | expect(Math).to.have.property('log2');
|
438 | });
|
439 | }
|
440 |
|
441 | ifFunctionsHaveNamesIt('has the right name', function () {
|
442 | expect(Math.log2).to.have.property('name', 'log2');
|
443 | });
|
444 |
|
445 | it('is not enumerable', function () {
|
446 | expect(Math).ownPropertyDescriptor('log2').to.have.property('enumerable', false);
|
447 | });
|
448 |
|
449 | it('has the right arity', function () {
|
450 | expect(Math.log2).to.have.property('length', 1);
|
451 | });
|
452 |
|
453 | it('is correct for small numbers', function () {
|
454 | expect(numberIsNaN(Math.log2(-1e-50))).to.equal(true);
|
455 | });
|
456 |
|
457 | it('is correct for edge cases', function () {
|
458 | expect(numberIsNaN(Math.log2(NaN))).to.equal(true);
|
459 | expect(Math.log2(+0)).to.equal(-Infinity);
|
460 | expect(Math.log2(-0)).to.equal(-Infinity);
|
461 | expect(isPositiveZero(Math.log2(1))).to.equal(true);
|
462 | expect(Math.log2(Infinity)).to.equal(Infinity);
|
463 | });
|
464 |
|
465 | it('should have the right precision', function () {
|
466 | expect(Math.log2(5)).to.almostEqual(2.321928094887362);
|
467 | expect(Math.log2(32)).to.almostEqual(5);
|
468 | });
|
469 | });
|
470 |
|
471 | describe('.log10', function () {
|
472 | if (!Object.prototype.hasOwnProperty.call(Math, 'log10')) {
|
473 | return it('exists', function () {
|
474 | expect(Math).to.have.property('log10');
|
475 | });
|
476 | }
|
477 |
|
478 | ifFunctionsHaveNamesIt('has the right name', function () {
|
479 | expect(Math.log10).to.have.property('name', 'log10');
|
480 | });
|
481 |
|
482 | it('is not enumerable', function () {
|
483 | expect(Math).ownPropertyDescriptor('log10').to.have.property('enumerable', false);
|
484 | });
|
485 |
|
486 | it('has the right arity', function () {
|
487 | expect(Math.log10).to.have.property('length', 1);
|
488 | });
|
489 |
|
490 | it('should be correct for edge cases', function () {
|
491 | expect(numberIsNaN(Math.log10(NaN))).to.equal(true);
|
492 | expect(numberIsNaN(Math.log10(-1e-50))).to.equal(true);
|
493 | expect(Math.log10(+0)).to.equal(-Infinity);
|
494 | expect(Math.log10(-0)).to.equal(-Infinity);
|
495 | expect(isPositiveZero(Math.log10(1))).to.equal(true);
|
496 | expect(Math.log10(Infinity)).to.equal(Infinity);
|
497 | });
|
498 |
|
499 | it('should have the right precision', function () {
|
500 | expect(Math.log10(5)).to.almostEqual(0.698970004336018);
|
501 | expect(Math.log10(50)).to.almostEqual(1.6989700043360187);
|
502 | });
|
503 | });
|
504 |
|
505 | describe('.log1p', function () {
|
506 | if (!Object.prototype.hasOwnProperty.call(Math, 'log1p')) {
|
507 | return it('exists', function () {
|
508 | expect(Math).to.have.property('log1p');
|
509 | });
|
510 | }
|
511 |
|
512 | ifFunctionsHaveNamesIt('has the right name', function () {
|
513 | expect(Math.log1p).to.have.property('name', 'log1p');
|
514 | });
|
515 |
|
516 | it('is not enumerable', function () {
|
517 | expect(Math).ownPropertyDescriptor('log1p').to.have.property('enumerable', false);
|
518 | });
|
519 |
|
520 | it('has the right arity', function () {
|
521 | expect(Math.log1p).to.have.property('length', 1);
|
522 | });
|
523 |
|
524 | it('should be correct', function () {
|
525 | expect(numberIsNaN(Math.log1p(NaN))).to.equal(true);
|
526 | expect(numberIsNaN(Math.log1p(-1.000000001))).to.equal(true);
|
527 | expect(Math.log1p(-1)).to.equal(-Infinity);
|
528 | expect(isPositiveZero(Math.log1p(+0))).to.equal(true);
|
529 | expect(isNegativeZero(Math.log1p(-0))).to.equal(true);
|
530 | expect(Math.log1p(Infinity)).to.equal(Infinity);
|
531 |
|
532 | expect(Math.log1p(5)).to.almostEqual(1.791759469228055);
|
533 | expect(Math.log1p(50)).to.almostEqual(3.9318256327243257);
|
534 | expect(Math.log1p(-1e-17)).to.equal(-1e-17);
|
535 | expect(Math.log1p(-2e-17)).to.equal(-2e-17);
|
536 | });
|
537 | });
|
538 |
|
539 | describe('.sign()', function () {
|
540 | if (!Object.prototype.hasOwnProperty.call(Math, 'sign')) {
|
541 | return it('exists', function () {
|
542 | expect(Math).to.have.property('sign');
|
543 | });
|
544 | }
|
545 |
|
546 | ifFunctionsHaveNamesIt('has the right name', function () {
|
547 | expect(Math.sign).to.have.property('name', 'sign');
|
548 | });
|
549 |
|
550 | it('is not enumerable', function () {
|
551 | expect(Math).ownPropertyDescriptor('sign').to.have.property('enumerable', false);
|
552 | });
|
553 |
|
554 | it('has the right arity', function () {
|
555 | expect(Math.sign).to.have.property('length', 1);
|
556 | });
|
557 |
|
558 | it('should be correct', function () {
|
559 |
|
560 | [Infinity, 1].forEach(function (value) {
|
561 | expect(Math.sign(value)).to.equal(1);
|
562 | expect(Math.sign(String(value))).to.equal(1);
|
563 | });
|
564 | expect(Math.sign(true)).to.equal(1);
|
565 |
|
566 | [-Infinity, -1].forEach(function (value) {
|
567 | expect(Math.sign(value)).to.equal(-1);
|
568 | expect(Math.sign(String(value))).to.equal(-1);
|
569 | });
|
570 |
|
571 | expect(isPositiveZero(Math.sign(+0))).to.equal(true);
|
572 | expect(isPositiveZero(Math.sign('0'))).to.equal(true);
|
573 | expect(isPositiveZero(Math.sign('+0'))).to.equal(true);
|
574 | expect(isPositiveZero(Math.sign(''))).to.equal(true);
|
575 | expect(isPositiveZero(Math.sign(' '))).to.equal(true);
|
576 | expect(isPositiveZero(Math.sign(null))).to.equal(true);
|
577 | expect(isPositiveZero(Math.sign(false))).to.equal(true);
|
578 | expect(isNegativeZero(Math.sign(-0))).to.equal(true);
|
579 | expect(isNegativeZero(Math.sign('-0'))).to.equal(true);
|
580 | expect(numberIsNaN(Math.sign(NaN))).to.equal(true);
|
581 | expect(numberIsNaN(Math.sign('NaN'))).to.equal(true);
|
582 | expect(numberIsNaN(Math.sign(undefined))).to.equal(true);
|
583 | });
|
584 | });
|
585 |
|
586 | describe('.sinh()', function () {
|
587 | if (!Object.prototype.hasOwnProperty.call(Math, 'sinh')) {
|
588 | return it('exists', function () {
|
589 | expect(Math).to.have.property('sinh');
|
590 | });
|
591 | }
|
592 |
|
593 | ifFunctionsHaveNamesIt('has the right name', function () {
|
594 | expect(Math.sinh).to.have.property('name', 'sinh');
|
595 | });
|
596 |
|
597 | it('is not enumerable', function () {
|
598 | expect(Math).ownPropertyDescriptor('sinh').to.have.property('enumerable', false);
|
599 | });
|
600 |
|
601 | it('has the right arity', function () {
|
602 | expect(Math.sinh).to.have.property('length', 1);
|
603 | });
|
604 |
|
605 | it('should be correct', function () {
|
606 | expect(numberIsNaN(Math.sinh(NaN))).to.equal(true);
|
607 | expect(isPositiveZero(Math.sinh(+0))).to.equal(true);
|
608 | expect(isNegativeZero(Math.sinh(-0))).to.equal(true);
|
609 | expect(Math.sinh(Infinity)).to.equal(Infinity);
|
610 | expect(Math.sinh(-Infinity)).to.equal(-Infinity);
|
611 | expect(Math.sinh(-5)).to.almostEqual(-74.20321057778875);
|
612 | expect(Math.sinh(2)).to.almostEqual(3.6268604078470186);
|
613 | expect(Math.sinh(-2e-17)).to.equal(-2e-17);
|
614 | });
|
615 |
|
616 | it('is correct for extreme non-infinities', function () {
|
617 | expect(Math.sinh(710)).not.to.equal(Infinity);
|
618 | expect(Math.sinh(710) / 1e+308).to.almostEqual(1.1169973830808557);
|
619 | });
|
620 | });
|
621 |
|
622 | describe('.tanh()', function () {
|
623 | if (!Object.prototype.hasOwnProperty.call(Math, 'tanh')) {
|
624 | return it('exists', function () {
|
625 | expect(Math).to.have.property('tanh');
|
626 | });
|
627 | }
|
628 |
|
629 | ifFunctionsHaveNamesIt('has the right name', function () {
|
630 | expect(Math.tanh).to.have.property('name', 'tanh');
|
631 | });
|
632 |
|
633 | it('is not enumerable', function () {
|
634 | expect(Math).ownPropertyDescriptor('tanh').to.have.property('enumerable', false);
|
635 | });
|
636 |
|
637 | it('has the right arity', function () {
|
638 | expect(Math.tanh).to.have.property('length', 1);
|
639 | });
|
640 |
|
641 | it('should be correct', function () {
|
642 | expect(numberIsNaN(Math.tanh(NaN))).to.equal(true);
|
643 | expect(isPositiveZero(Math.tanh(+0))).to.equal(true);
|
644 | expect(isNegativeZero(Math.tanh(-0))).to.equal(true);
|
645 | expect(Math.tanh(Infinity)).to.equal(1);
|
646 | expect(Math.tanh(-Infinity)).to.equal(-1);
|
647 | expect(Math.tanh(19)).to.almostEqual(1);
|
648 | expect(Math.tanh(-19)).to.almostEqual(-1);
|
649 | expect(Math.tanh(20)).to.equal(1);
|
650 | expect(Math.tanh(-20)).to.equal(-1);
|
651 | expect(Math.tanh(10)).to.almostEqual(0.9999999958776927);
|
652 | expect(Math.tanh(-2e-17)).to.equal(-2e-17);
|
653 | });
|
654 | });
|
655 |
|
656 | describe('.trunc()', function () {
|
657 | if (!Object.prototype.hasOwnProperty.call(Math, 'trunc')) {
|
658 | return it('exists', function () {
|
659 | expect(Math).to.have.property('trunc');
|
660 | });
|
661 | }
|
662 |
|
663 | ifFunctionsHaveNamesIt('has the right name', function () {
|
664 | expect(Math.trunc).to.have.property('name', 'trunc');
|
665 | });
|
666 |
|
667 | it('is not enumerable', function () {
|
668 | expect(Math).ownPropertyDescriptor('trunc').to.have.property('enumerable', false);
|
669 | });
|
670 |
|
671 | it('has the right arity', function () {
|
672 | expect(Math.trunc).to.have.property('length', 1);
|
673 | });
|
674 |
|
675 | it('should be correct', function () {
|
676 | expect(numberIsNaN(Math.trunc(NaN))).to.equal(true);
|
677 | expect(isNegativeZero(Math.trunc(-0))).to.equal(true);
|
678 | expect(isPositiveZero(Math.trunc(+0))).to.equal(true);
|
679 | expect(Math.trunc(Infinity)).to.equal(Infinity);
|
680 | expect(Math.trunc(-Infinity)).to.equal(-Infinity);
|
681 | expect(Math.trunc(1.01)).to.equal(1);
|
682 | expect(Math.trunc(1.99)).to.equal(1);
|
683 | expect(Math.trunc(-555.555)).to.equal(-555);
|
684 | expect(Math.trunc(-1.99)).to.equal(-1);
|
685 | });
|
686 |
|
687 | it('should coerce to a number immediately', function () {
|
688 | expect(Math.trunc(valueOfIsInfinity)).to.equal(Infinity);
|
689 | expect(numberIsNaN(Math.trunc(valueOfIsNaN))).to.equal(true);
|
690 | });
|
691 | });
|
692 |
|
693 | describe('.imul()', function () {
|
694 | if (!Object.prototype.hasOwnProperty.call(Math, 'imul')) {
|
695 | return it('exists', function () {
|
696 | expect(Math).to.have.property('imul');
|
697 | });
|
698 | }
|
699 |
|
700 | ifFunctionsHaveNamesIt('has the right name', function () {
|
701 | expect(Math.imul).to.have.property('name', 'imul');
|
702 | });
|
703 |
|
704 | it('is not enumerable', function () {
|
705 | expect(Math).ownPropertyDescriptor('imul').to.have.property('enumerable', false);
|
706 | });
|
707 |
|
708 | it('has the right arity', function () {
|
709 | expect(Math.imul).to.have.property('length', 2);
|
710 | });
|
711 |
|
712 | var str = 'str';
|
713 | var obj = {};
|
714 | var arr = [];
|
715 |
|
716 | it('should be correct for non-numbers', function () {
|
717 | expect(Math.imul(false, 7)).to.equal(0);
|
718 | expect(Math.imul(7, false)).to.equal(0);
|
719 | expect(Math.imul(false, false)).to.equal(0);
|
720 | expect(Math.imul(true, 7)).to.equal(7);
|
721 | expect(Math.imul(7, true)).to.equal(7);
|
722 | expect(Math.imul(true, true)).to.equal(1);
|
723 | expect(Math.imul(undefined, 7)).to.equal(0);
|
724 | expect(Math.imul(7, undefined)).to.equal(0);
|
725 | expect(Math.imul(undefined, undefined)).to.equal(0);
|
726 | expect(Math.imul(str, 7)).to.equal(0);
|
727 | expect(Math.imul(7, str)).to.equal(0);
|
728 | expect(Math.imul(obj, 7)).to.equal(0);
|
729 | expect(Math.imul(7, obj)).to.equal(0);
|
730 | expect(Math.imul(arr, 7)).to.equal(0);
|
731 | expect(Math.imul(7, arr)).to.equal(0);
|
732 | });
|
733 |
|
734 | it('should be correct for hex values', function () {
|
735 | expect(Math.imul(0xffffffff, 5)).to.equal(-5);
|
736 | expect(Math.imul(0xfffffffe, 5)).to.equal(-10);
|
737 | });
|
738 |
|
739 | it('should be correct', function () {
|
740 | expect(Math.imul(2, 4)).to.equal(8);
|
741 | expect(Math.imul(-1, 8)).to.equal(-8);
|
742 | expect(Math.imul(-2, -2)).to.equal(4);
|
743 | expect(Math.imul(-0, 7)).to.equal(0);
|
744 | expect(Math.imul(7, -0)).to.equal(0);
|
745 | expect(Math.imul(0.1, 7)).to.equal(0);
|
746 | expect(Math.imul(7, 0.1)).to.equal(0);
|
747 | expect(Math.imul(0.9, 7)).to.equal(0);
|
748 | expect(Math.imul(7, 0.9)).to.equal(0);
|
749 | expect(Math.imul(1.1, 7)).to.equal(7);
|
750 | expect(Math.imul(7, 1.1)).to.equal(7);
|
751 | expect(Math.imul(1.9, 7)).to.equal(7);
|
752 | expect(Math.imul(7, 1.9)).to.equal(7);
|
753 | });
|
754 |
|
755 | it('should be correct for objects with valueOf', function () {
|
756 | var x = {
|
757 | x: 0,
|
758 | valueOf: function () { this.x += 1; return this.x; }
|
759 | };
|
760 | expect(Math.imul(x, 1)).to.equal(1);
|
761 | expect(Math.imul(1, x)).to.equal(2);
|
762 | expect(Math.imul(x, 1)).to.equal(3);
|
763 | expect(Math.imul(1, x)).to.equal(4);
|
764 | expect(Math.imul(x, 1)).to.equal(5);
|
765 | });
|
766 | });
|
767 |
|
768 | describe('.round()', function () {
|
769 | ifFunctionsHaveNamesIt('has the right name', function () {
|
770 | expect(Math.round).to.have.property('name', 'round');
|
771 | });
|
772 |
|
773 | it('is not enumerable', function () {
|
774 | expect(Math).ownPropertyDescriptor('round').to.have.property('enumerable', false);
|
775 | });
|
776 |
|
777 | it('has the right arity', function () {
|
778 | expect(Math.round).to.have.property('length', 1);
|
779 | });
|
780 |
|
781 | it('works for edge cases', function () {
|
782 | expect(numberIsNaN(Math.round(NaN))).to.equal(true);
|
783 | expect(isPositiveZero(Math.round(0))).to.equal(true);
|
784 | expect(isNegativeZero(Math.round(-0))).to.equal(true);
|
785 | expect(Math.round(Infinity)).to.equal(Infinity);
|
786 | expect(Math.round(-Infinity)).to.equal(-Infinity);
|
787 | });
|
788 |
|
789 | it('returns 0 for (0,0.5)', function () {
|
790 | expect(Math.round(0.5)).not.to.equal(0);
|
791 | expect(Math.round(0.5 - (EPSILON / 4))).to.equal(0);
|
792 | expect(Math.round(0 + (EPSILON / 4))).to.equal(0);
|
793 | });
|
794 |
|
795 | it('returns -0 for (-0.5,0)', function () {
|
796 | expect(Math.round(-0.5)).to.equal(0);
|
797 | expect(Math.round(-0.5 - (EPSILON / 3.99))).not.to.equal(0);
|
798 | expect(isNegativeZero(Math.round(-0.5 + (EPSILON / 3.99)))).to.equal(true);
|
799 | expect(isNegativeZero(Math.round(0 - (EPSILON / 3.99)))).to.equal(true);
|
800 | });
|
801 |
|
802 | it('returns 1 / Number.EPSILON + 1 for 1 / Number.EPSILON + 1', function () {
|
803 | var inverseEpsilonPlus1 = (1 / EPSILON) + 1;
|
804 | expect(Math.round(inverseEpsilonPlus1)).to.equal(inverseEpsilonPlus1);
|
805 | });
|
806 |
|
807 | it('returns 2 / Number.EPSILON - 1 for 2 / Number.EPSILON - 1', function () {
|
808 | var twiceInverseEpsilonMinus1 = (2 / EPSILON) - 1;
|
809 | expect(Math.round(twiceInverseEpsilonMinus1)).to.equal(twiceInverseEpsilonMinus1);
|
810 | });
|
811 | });
|
812 |
|
813 | describe('.fround()', function () {
|
814 | if (!Object.prototype.hasOwnProperty.call(Math, 'fround')) {
|
815 | return it('exists', function () {
|
816 | expect(Math).to.have.property('fround');
|
817 | });
|
818 | }
|
819 |
|
820 | ifFunctionsHaveNamesIt('has the right name', function () {
|
821 | expect(Math.fround).to.have.property('name', 'fround');
|
822 | });
|
823 |
|
824 | it('is not enumerable', function () {
|
825 | expect(Math).ownPropertyDescriptor('fround').to.have.property('enumerable', false);
|
826 | });
|
827 |
|
828 | it('has the right arity', function () {
|
829 | expect(Math.fround).to.have.property('length', 1);
|
830 | });
|
831 |
|
832 |
|
833 | it('returns NaN for undefined', function () {
|
834 | expect(numberIsNaN(Math.fround())).to.equal(true);
|
835 | });
|
836 |
|
837 | it('returns NaN for NaN', function () {
|
838 | expect(numberIsNaN(Math.fround(NaN))).to.equal(true);
|
839 | });
|
840 |
|
841 | it('works for zeroes and infinities', function () {
|
842 | expect(isPositiveZero(Math.fround(0))).to.equal(true);
|
843 | expect(isPositiveZero(Math.fround({ valueOf: function () { return 0; } }))).to.equal(true);
|
844 | expect(isNegativeZero(Math.fround(-0))).to.equal(true);
|
845 | expect(isNegativeZero(Math.fround({ valueOf: function () { return -0; } }))).to.equal(true);
|
846 | expect(Math.fround(Infinity)).to.equal(Infinity);
|
847 | expect(Math.fround({ valueOf: function () { return Infinity; } })).to.equal(Infinity);
|
848 | expect(Math.fround(-Infinity)).to.equal(-Infinity);
|
849 | expect(Math.fround({ valueOf: function () { return -Infinity; } })).to.equal(-Infinity);
|
850 | });
|
851 |
|
852 | it('returns infinity for large numbers', function () {
|
853 | expect(Math.fround(1.7976931348623157e+308)).to.equal(Infinity);
|
854 | expect(Math.fround(-1.7976931348623157e+308)).to.equal(-Infinity);
|
855 | expect(Math.fround(3.4028235677973366e+38)).to.equal(Infinity);
|
856 | });
|
857 |
|
858 | it('returns zero for really small numbers', function () {
|
859 | expect(Number.MIN_VALUE).to.equal(5e-324);
|
860 |
|
861 | expect(Math.fround(Number.MIN_VALUE)).to.equal(0);
|
862 | expect(Math.fround(-Number.MIN_VALUE)).to.equal(0);
|
863 | });
|
864 |
|
865 | it('rounds properly', function () {
|
866 | expect(Math.fround(3)).to.equal(3);
|
867 | expect(Math.fround(-3)).to.equal(-3);
|
868 | });
|
869 |
|
870 | it('rounds properly with the max float 32', function () {
|
871 | var maxFloat32 = 3.4028234663852886e+38;
|
872 | expect(Math.fround(maxFloat32)).to.equal(maxFloat32);
|
873 | expect(Math.fround(-maxFloat32)).to.equal(-maxFloat32);
|
874 |
|
875 |
|
876 | expect(Math.fround(maxFloat32 + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 2))).to.equal(maxFloat32);
|
877 | });
|
878 |
|
879 | it('rounds properly with the min float 32', function () {
|
880 | var minFloat32 = 1.401298464324817e-45;
|
881 | expect(Math.fround(minFloat32)).to.equal(minFloat32);
|
882 | expect(Math.fround(-minFloat32)).to.equal(-minFloat32);
|
883 | expect(Math.fround(minFloat32 / 2)).to.equal(0);
|
884 | expect(Math.fround(-minFloat32 / 2)).to.equal(0);
|
885 | expect(Math.fround((minFloat32 / 2) + Math.pow(2, -202))).to.equal(minFloat32);
|
886 | expect(Math.fround((-minFloat32 / 2) - Math.pow(2, -202))).to.equal(-minFloat32);
|
887 | });
|
888 | });
|
889 | });
|