blob: c3f31eb3bc74566d1d72dde78006a8b49421abe9 [file] [log] [blame]
// 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(-1, goog.math.sign(-1));
assertEquals(1, goog.math.sign(1));
assertEquals(0, goog.math.sign(0));
assertEquals(0, goog.math.sign(-0));
assertEquals(1, goog.math.sign(0.0001));
assertEquals(-1, goog.math.sign(-0.0001));
assertEquals(-1, goog.math.sign(-Infinity));
assertEquals(1, goog.math.sign(Infinity));
assertEquals(1, goog.math.sign(3141592653589793));
}
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 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));
}