123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- // Copyright 2006 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- goog.provide('goog.mathTest');
- goog.setTestOnly('goog.mathTest');
- goog.require('goog.math');
- goog.require('goog.testing.jsunit');
- function testRandomInt() {
- assertEquals(0, goog.math.randomInt(0));
- assertEquals(0, goog.math.randomInt(1));
- var r = goog.math.randomInt(3);
- assertTrue(0 <= r && r < 3);
- }
- function testUniformRandom() {
- assertEquals(5.2, goog.math.uniformRandom(5.2, 5.2));
- assertEquals(-6, goog.math.uniformRandom(-6, -6));
- var r = goog.math.uniformRandom(-0.5, 0.5);
- assertTrue(-0.5 <= r && r < 0.5);
- }
- function testClamp() {
- assertEquals(3, goog.math.clamp(3, -5, 5));
- assertEquals(5, goog.math.clamp(5, -5, 5));
- assertEquals(-5, goog.math.clamp(-5, -5, 5));
- assertEquals(-5, goog.math.clamp(-22, -5, 5));
- assertEquals(5, goog.math.clamp(6, -5, 5));
- }
- function testModulo() {
- assertEquals(0, goog.math.modulo(256, 8));
- assertEquals(7, goog.math.modulo(7, 8));
- assertEquals(7, goog.math.modulo(23, 8));
- assertEquals(7, goog.math.modulo(-1, 8));
- // Safari 5.1.7 has a bug in its JS engine where modulo is computed
- // incorrectly when using variables. We avoid using
- // goog.testing.ExpectedFailure here since it pulls in a bunch of
- // extra dependencies for maintaining a DOM console.
- var a = 1;
- var b = -5;
- if (a % b === 1 % -5) {
- assertEquals(-4, goog.math.modulo(1, -5));
- assertEquals(-4, goog.math.modulo(6, -5));
- }
- assertEquals(-4, goog.math.modulo(-4, -5));
- }
- function testLerp() {
- assertEquals(0, goog.math.lerp(0, 0, 0));
- assertEquals(3, goog.math.lerp(0, 6, 0.5));
- assertEquals(3, goog.math.lerp(-1, 1, 2));
- }
- function testNearlyEquals() {
- assertTrue(
- 'Numbers inside default tolerance should be equal',
- goog.math.nearlyEquals(0.000001, 0.000001001));
- assertFalse(
- 'Numbers outside default tolerance should be unequal',
- goog.math.nearlyEquals(0.000001, 0.000003));
- assertTrue(
- 'Numbers inside custom tolerance should be equal',
- goog.math.nearlyEquals(0.001, 0.002, 0.1));
- assertFalse(
- 'Numbers outside custom tolerance should be unequal',
- goog.math.nearlyEquals(0.001, -0.1, 0.1));
- assertTrue(
- 'Integer tolerance greater than one should succeed',
- goog.math.nearlyEquals(87, 85, 3));
- }
- function testStandardAngleInRadians() {
- assertRoughlyEquals(0, goog.math.standardAngleInRadians(2 * Math.PI), 1e-10);
- assertRoughlyEquals(
- Math.PI, goog.math.standardAngleInRadians(Math.PI), 1e-10);
- assertRoughlyEquals(
- Math.PI, goog.math.standardAngleInRadians(-1 * Math.PI), 1e-10);
- assertRoughlyEquals(
- Math.PI / 2, goog.math.standardAngleInRadians(-1.5 * Math.PI), 1e-10);
- assertRoughlyEquals(
- Math.PI, goog.math.standardAngleInRadians(5 * Math.PI), 1e-10);
- assertEquals(0.01, goog.math.standardAngleInRadians(0.01));
- assertEquals(0, goog.math.standardAngleInRadians(0));
- }
- function testStandardAngle() {
- assertEquals(359.5, goog.math.standardAngle(-360.5));
- assertEquals(0, goog.math.standardAngle(-360));
- assertEquals(359.5, goog.math.standardAngle(-0.5));
- assertEquals(0, goog.math.standardAngle(0));
- assertEquals(0.5, goog.math.standardAngle(0.5));
- assertEquals(0, goog.math.standardAngle(360));
- assertEquals(1, goog.math.standardAngle(721));
- }
- function testToRadians() {
- assertEquals(-Math.PI, goog.math.toRadians(-180));
- assertEquals(0, goog.math.toRadians(0));
- assertEquals(Math.PI, goog.math.toRadians(180));
- }
- function testToDegrees() {
- assertEquals(-180, goog.math.toDegrees(-Math.PI));
- assertEquals(0, goog.math.toDegrees(0));
- assertEquals(180, goog.math.toDegrees(Math.PI));
- }
- function testAngleDx() {
- assertRoughlyEquals(0, goog.math.angleDx(0, 0), 1e-10);
- assertRoughlyEquals(0, goog.math.angleDx(90, 0), 1e-10);
- assertRoughlyEquals(100, goog.math.angleDx(0, 100), 1e-10);
- assertRoughlyEquals(0, goog.math.angleDx(90, 100), 1e-10);
- assertRoughlyEquals(-100, goog.math.angleDx(180, 100), 1e-10);
- assertRoughlyEquals(0, goog.math.angleDx(270, 100), 1e-10);
- }
- function testAngleDy() {
- assertRoughlyEquals(0, goog.math.angleDy(0, 0), 1e-10);
- assertRoughlyEquals(0, goog.math.angleDy(90, 0), 1e-10);
- assertRoughlyEquals(0, goog.math.angleDy(0, 100), 1e-10);
- assertRoughlyEquals(100, goog.math.angleDy(90, 100), 1e-10);
- assertRoughlyEquals(0, goog.math.angleDy(180, 100), 1e-10);
- assertRoughlyEquals(-100, goog.math.angleDy(270, 100), 1e-10);
- }
- function testAngle() {
- assertRoughlyEquals(0, goog.math.angle(10, 10, 20, 10), 1e-10);
- assertRoughlyEquals(90, goog.math.angle(10, 10, 10, 20), 1e-10);
- assertRoughlyEquals(225, goog.math.angle(10, 10, 0, 0), 1e-10);
- assertRoughlyEquals(270, goog.math.angle(10, 10, 10, 0), 1e-10);
- // 0 is the conventional result, but mathematically this is undefined.
- assertEquals(0, goog.math.angle(10, 10, 10, 10));
- }
- function testAngleDifference() {
- assertEquals(10, goog.math.angleDifference(30, 40));
- assertEquals(-10, goog.math.angleDifference(40, 30));
- assertEquals(180, goog.math.angleDifference(10, 190));
- assertEquals(180, goog.math.angleDifference(190, 10));
- assertEquals(20, goog.math.angleDifference(350, 10));
- assertEquals(-20, goog.math.angleDifference(10, 350));
- assertEquals(100, goog.math.angleDifference(350, 90));
- assertEquals(-80, goog.math.angleDifference(350, 270));
- assertEquals(0, goog.math.angleDifference(15, 15));
- }
- function testSign() {
- assertEquals(0, goog.math.sign(0));
- assertEquals(-1, goog.math.sign(-3));
- assertEquals(1, goog.math.sign(3));
- assertEquals(1, goog.math.sign(0.0001));
- assertEquals(-1, goog.math.sign(-0.0001));
- assertEquals(1, goog.math.sign(3141592653589793));
- }
- function testSignOfSpecialFloatValues() {
- assertEquals(-1, goog.math.sign(-Infinity));
- assertEquals(1, goog.math.sign(Infinity));
- assertNaN(goog.math.sign(NaN));
- assertEquals(0, goog.math.sign(0));
- assertFalse(goog.math.isNegativeZero(goog.math.sign(0)));
- assertEquals(0, goog.math.sign(-0));
- assertTrue(goog.math.isNegativeZero(goog.math.sign(-0)));
- }
- function testLongestCommonSubsequence() {
- var func = goog.math.longestCommonSubsequence;
- assertArrayEquals([2], func([1, 2], [2, 1]));
- assertArrayEquals([1, 2], func([1, 2, 5], [2, 1, 2]));
- assertArrayEquals(
- [1, 2, 3, 4, 5],
- func([1, 0, 2, 3, 8, 4, 9, 5], [8, 1, 2, 4, 3, 6, 4, 5]));
- assertArrayEquals([1, 1, 1, 1, 1], func([1, 1, 1, 1, 1], [1, 1, 1, 1, 1]));
- assertArrayEquals([5], func([1, 2, 3, 4, 5], [5, 4, 3, 2, 1]));
- assertArrayEquals(
- [1, 8, 11], func([1, 6, 8, 11, 13], [1, 3, 5, 8, 9, 11, 12]));
- }
- function testLongestCommonSubsequenceWithCustomComparator() {
- var func = goog.math.longestCommonSubsequence;
- var compareFn = function(a, b) { return a.field == b.field; };
- var a1 = {field: 'a1', field2: 'hello'};
- var a2 = {field: 'a2', field2: 33};
- var a3 = {field: 'a3'};
- var a4 = {field: 'a3'};
- assertArrayEquals([a1, a2], func([a1, a2, a3], [a3, a1, a2], compareFn));
- assertArrayEquals([a1, a3], func([a1, a3], [a1, a4], compareFn));
- // testing the same arrays without compare function
- assertArrayEquals([a1], func([a1, a3], [a1, a4]));
- }
- function testLongestCommonSubsequenceWithCustomCollector() {
- var func = goog.math.longestCommonSubsequence;
- var collectorFn = function(a, b) { return b; };
- assertArrayEquals(
- [1, 2, 4, 6, 7], func(
- [1, 0, 2, 3, 8, 4, 9, 5], [8, 1, 2, 4, 3, 6, 4, 5],
- null, collectorFn));
- }
- function testSum() {
- assertEquals(
- 'sum() must return 0 if there are no arguments', 0, goog.math.sum());
- assertEquals(
- 'sum() must return its argument if there is only one', 17,
- goog.math.sum(17));
- assertEquals(
- 'sum() must handle positive integers', 10, goog.math.sum(1, 2, 3, 4));
- assertEquals(
- 'sum() must handle real numbers', -2.5, goog.math.sum(1, -2, 3, -4.5));
- assertTrue(
- 'sum() must return NaN if one of the arguments isn\'t numeric',
- isNaN(goog.math.sum(1, 2, 'foo', 3)));
- }
- function testAverage() {
- assertTrue(
- 'average() must return NaN if there are no arguments',
- isNaN(goog.math.average()));
- assertEquals(
- 'average() must return its argument if there is only one', 17,
- goog.math.average(17));
- assertEquals(
- 'average() must handle positive integers', 3,
- goog.math.average(1, 2, 3, 4, 5));
- assertEquals(
- 'average() must handle real numbers', -0.625,
- goog.math.average(1, -2, 3, -4.5));
- assertTrue(
- 'average() must return NaN if one of the arguments isn\'t ' +
- 'numeric',
- isNaN(goog.math.average(1, 2, 'foo', 3)));
- }
- function testSampleVariance() {
- assertEquals(
- 'sampleVariance() must return 0 if there are no samples', 0,
- goog.math.sampleVariance());
- assertEquals(
- 'sampleVariance() must return 0 if there is only one ' +
- 'sample',
- 0, goog.math.sampleVariance(17));
- assertRoughlyEquals(
- 'sampleVariance() must handle positive integers', 48,
- goog.math.sampleVariance(3, 7, 7, 19), 0.0001);
- assertRoughlyEquals(
- 'sampleVariance() must handle real numbers', 12.0138,
- goog.math.sampleVariance(1.23, -2.34, 3.14, -4.56), 0.0001);
- }
- function testStandardDeviation() {
- assertEquals(
- 'standardDeviation() must return 0 if there are no samples', 0,
- goog.math.standardDeviation());
- assertEquals(
- 'standardDeviation() must return 0 if there is only one ' +
- 'sample',
- 0, goog.math.standardDeviation(17));
- assertRoughlyEquals(
- 'standardDeviation() must handle positive integers', 6.9282,
- goog.math.standardDeviation(3, 7, 7, 19), 0.0001);
- assertRoughlyEquals(
- 'standardDeviation() must handle real numbers', 3.4660,
- goog.math.standardDeviation(1.23, -2.34, 3.14, -4.56), 0.0001);
- }
- function testIsInt() {
- assertFalse(goog.math.isInt(12345.67));
- assertFalse(goog.math.isInt(0.123));
- assertFalse(goog.math.isInt(.1));
- assertFalse(goog.math.isInt(-23.43));
- assertFalse(goog.math.isInt(-.1));
- assertFalse(goog.math.isInt(1e-1));
- assertTrue(goog.math.isInt(1));
- assertTrue(goog.math.isInt(0));
- assertTrue(goog.math.isInt(-2));
- assertTrue(goog.math.isInt(-2.0));
- assertTrue(goog.math.isInt(10324231));
- assertTrue(goog.math.isInt(1.));
- assertTrue(goog.math.isInt(1e3));
- }
- function testIsFiniteNumber() {
- assertFalse(goog.math.isFiniteNumber(NaN));
- assertFalse(goog.math.isFiniteNumber(-Infinity));
- assertFalse(goog.math.isFiniteNumber(+Infinity));
- assertTrue(goog.math.isFiniteNumber(0));
- assertTrue(goog.math.isFiniteNumber(1));
- assertTrue(goog.math.isFiniteNumber(Math.PI));
- }
- function testIsNegativeZero() {
- assertFalse(goog.math.isNegativeZero(0));
- assertTrue(goog.math.isNegativeZero(-0));
- assertFalse(goog.math.isNegativeZero(1));
- assertFalse(goog.math.isNegativeZero(-1));
- assertFalse(goog.math.isNegativeZero(-Number.MIN_VALUE));
- }
- function testLog10Floor() {
- // The greatest floating point number that is less than 1.
- var oneMinusEpsilon = 1 - Math.pow(2, -53);
- for (var i = -30; i <= 30; i++) {
- assertEquals(i, goog.math.log10Floor(parseFloat('1e' + i)));
- assertEquals(
- i - 1, goog.math.log10Floor(parseFloat('1e' + i) * oneMinusEpsilon));
- }
- assertEquals(-Infinity, goog.math.log10Floor(0));
- assertTrue(isNaN(goog.math.log10Floor(-1)));
- }
- function testSafeFloor() {
- assertEquals(0, goog.math.safeFloor(0));
- assertEquals(0, goog.math.safeFloor(1e-15));
- assertEquals(0, goog.math.safeFloor(-1e-15));
- assertEquals(-1, goog.math.safeFloor(-3e-15));
- assertEquals(4, goog.math.safeFloor(5 - 3e-15));
- assertEquals(5, goog.math.safeFloor(5 - 1e-15));
- assertEquals(-5, goog.math.safeFloor(-5 - 1e-15));
- assertEquals(-6, goog.math.safeFloor(-5 - 3e-15));
- assertEquals(3, goog.math.safeFloor(2.91, 0.1));
- assertEquals(2, goog.math.safeFloor(2.89, 0.1));
- // Tests some real life examples with the default epsilon value.
- assertEquals(0, goog.math.safeFloor(Math.log(1000) / Math.LN10 - 3));
- assertEquals(21, goog.math.safeFloor(Math.log(1e+21) / Math.LN10));
- }
- function testSafeCeil() {
- assertEquals(0, goog.math.safeCeil(0));
- assertEquals(0, goog.math.safeCeil(1e-15));
- assertEquals(0, goog.math.safeCeil(-1e-15));
- assertEquals(1, goog.math.safeCeil(3e-15));
- assertEquals(6, goog.math.safeCeil(5 + 3e-15));
- assertEquals(5, goog.math.safeCeil(5 + 1e-15));
- assertEquals(-4, goog.math.safeCeil(-5 + 3e-15));
- assertEquals(-5, goog.math.safeCeil(-5 + 1e-15));
- assertEquals(3, goog.math.safeCeil(3.09, 0.1));
- assertEquals(4, goog.math.safeCeil(3.11, 0.1));
- }
|