1 package org.apache.velocity.test; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import junit.framework.Test; 23 import junit.framework.TestCase; 24 import junit.framework.TestSuite; 25 import org.apache.velocity.runtime.parser.node.MathUtils; 26 27 import java.math.BigDecimal; 28 import java.math.BigInteger; 29 30 /** 31 * Test arithmetic operations. Introduced after extending from Integer-only 32 * to Number-handling. 33 * 34 * @author <a href="mailto:pero@antaramusic.de">Peter Romianowski</a> 35 */ 36 public class ArithmeticTestCase extends TestCase 37 { 38 ArithmeticTestCase(String testName)39 public ArithmeticTestCase(String testName) 40 { 41 super(testName); 42 } 43 suite()44 public static Test suite() 45 { 46 return new TestSuite(ArithmeticTestCase.class); 47 } 48 testAdd()49 public void testAdd() 50 { 51 addHelper (10, (short) 20, 30, Integer.class); 52 addHelper ((byte) 10, (short) 20, 30, Short.class); 53 addHelper (10f, (short) 20, 30, Float.class); 54 addHelper ((byte) 10, 20d, 30, Double.class); 55 addHelper (BigInteger.valueOf(10), 20, 30, BigInteger.class); 56 addHelper (20, BigDecimal.valueOf(10), 30, BigDecimal.class); 57 58 // Test overflow 59 addHelper (Integer.MAX_VALUE, (short) 20, (double)Integer.MAX_VALUE+20, Long.class); 60 addHelper (20, Long.MAX_VALUE, (double)Long.MAX_VALUE+20, BigInteger.class); 61 addHelper (-20, Long.MIN_VALUE, (double)Long.MIN_VALUE-20, BigInteger.class); 62 } 63 addHelper(Number n1, Number n2, double expectedResult, Class expectedResultType)64 private void addHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) 65 { 66 Number result = MathUtils.add( n1, n2); 67 assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); 68 assertEquals("ResultType does not match.", expectedResultType, result.getClass()); 69 } 70 testSubtract()71 public void testSubtract() 72 { 73 subtractHelper (100, (short) 20, 80, Integer.class); 74 subtractHelper ((byte) 100, (short) 20, 80, Short.class); 75 subtractHelper (100f, (short) 20, 80, Float.class); 76 subtractHelper ((byte) 100, 20d, 80, Double.class); 77 subtractHelper (BigInteger.valueOf(100), 20, 80, BigInteger.class); 78 subtractHelper (100, BigDecimal.valueOf(20), 80, BigDecimal.class); 79 80 // Test overflow 81 subtractHelper (Integer.MIN_VALUE, (short) 20, (double)Integer.MIN_VALUE-20, Long.class); 82 subtractHelper(-20, Long.MAX_VALUE, -20d - (double) Long.MAX_VALUE, BigInteger.class); 83 subtractHelper(Integer.MAX_VALUE, Long.MIN_VALUE, (double) Long.MAX_VALUE + (double) Integer.MAX_VALUE, BigInteger.class); 84 } 85 subtractHelper(Number n1, Number n2, double expectedResult, Class expectedResultType)86 private void subtractHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) 87 { 88 Number result = MathUtils.subtract( n1, n2); 89 assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); 90 assertEquals("ResultType does not match.", expectedResultType, result.getClass()); 91 } 92 testMultiply()93 public void testMultiply() 94 { 95 multiplyHelper (10, (short) 20, 200, Integer.class); 96 multiplyHelper ((byte) 100, (short) 20, 2000, Short.class); 97 multiplyHelper ((byte) 100, (short) 2000, 200000, Integer.class); 98 multiplyHelper (100f, (short) 20, 2000, Float.class); 99 multiplyHelper ((byte) 100, 20d, 2000, Double.class); 100 multiplyHelper (BigInteger.valueOf(100), 20, 2000, BigInteger.class); 101 multiplyHelper (100, BigDecimal.valueOf(20), 2000, BigDecimal.class); 102 103 // Test overflow 104 multiplyHelper (Integer.MAX_VALUE, (short) 10, (double)Integer.MAX_VALUE*10d, Long.class); 105 multiplyHelper(Integer.MAX_VALUE, (short) -10, (double) Integer.MAX_VALUE * -10d, Long.class); 106 multiplyHelper(20, Long.MAX_VALUE, 20d * (double) Long.MAX_VALUE, BigInteger.class); 107 } 108 multiplyHelper(Number n1, Number n2, double expectedResult, Class expectedResultType)109 private void multiplyHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) 110 { 111 Number result = MathUtils.multiply( n1, n2); 112 assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); 113 assertEquals("ResultType does not match.", expectedResultType, result.getClass()); 114 } 115 testDivide()116 public void testDivide() 117 { 118 divideHelper (10, (short) 2, 5, Integer.class); 119 divideHelper ((byte) 10, (short) 2, 5, Short.class); 120 divideHelper (BigInteger.valueOf(10), (short) 2, 5, BigInteger.class); 121 divideHelper (10, (short) 4, 2, Integer.class); 122 divideHelper (10, 2.5f, 4, Float.class); 123 divideHelper(10, 2.5, 4, Double.class); 124 divideHelper(10, new BigDecimal(2.5), 4, BigDecimal.class); 125 } 126 divideHelper(Number n1, Number n2, double expectedResult, Class expectedResultType)127 private void divideHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) 128 { 129 Number result = MathUtils.divide( n1, n2); 130 assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); 131 assertEquals("ResultType does not match.", expectedResultType, result.getClass()); 132 } 133 testModulo()134 public void testModulo() 135 { 136 moduloHelper (10, (short) 2, 0, Integer.class); 137 moduloHelper ((byte) 10, (short) 3, 1, Short.class); 138 moduloHelper(BigInteger.valueOf(10), (short) 4, 2, BigInteger.class); 139 moduloHelper(10, 5.5f, 4.5, Float.class); 140 141 try 142 { 143 moduloHelper (10, new BigDecimal( 2.5), 4, BigDecimal.class); 144 fail ("Modulo with BigDecimal is not allowed! Should have thrown an ArithmeticException."); 145 } 146 catch( ArithmeticException e) 147 { 148 // do nothing 149 } 150 } 151 moduloHelper(Number n1, Number n2, double expectedResult, Class expectedResultType)152 private void moduloHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) 153 { 154 Number result = MathUtils.modulo( n1, n2); 155 assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); 156 assertEquals("ResultType does not match.", expectedResultType, result.getClass()); 157 } 158 testCompare()159 public void testCompare() 160 { 161 compareHelper (10, (short) 10, 0); 162 compareHelper (10, (short) 11, -1); 163 compareHelper (BigInteger.valueOf(10), (short) 11, -1); 164 compareHelper ((byte) 10, (short) 3, 1); 165 compareHelper(10f, (short) 11, -1); 166 compareHelper(10d, (short) 11, -1); 167 } 168 compareHelper(Number n1, Number n2, int expectedResult)169 private void compareHelper (Number n1, Number n2, int expectedResult) 170 { 171 int result = MathUtils.compare( n1, n2 ); 172 assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result); 173 } 174 testNegate()175 public void testNegate() 176 { 177 negateHelper((byte) 1, -1, Byte.class); 178 negateHelper((short) 1, -1, Short.class); 179 negateHelper(1, -1, Integer.class); 180 negateHelper(1L, -1, Long.class); 181 negateHelper(BigInteger.valueOf(1), -1, BigInteger.class); 182 negateHelper(BigDecimal.valueOf(1), -1, BigDecimal.class); 183 negateHelper(Long.MIN_VALUE, BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.valueOf(1)).doubleValue(), BigInteger.class); 184 } 185 negateHelper(Number n, double expectedResult, Class expectedResultType)186 private void negateHelper(Number n, double expectedResult, Class expectedResultType) 187 { 188 Number result = MathUtils.negate(n); 189 assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); 190 assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); 191 } 192 193 /* 194 * 195 * COMMENT OUT FOR PERFORMANCE-MEASSUREMENTS 196 * 197 * public void testProfile() 198 * { 199 * 200 * long start = System.currentTimeMillis(); 201 * 202 * Number v1 = new Long (1000); 203 * Number v2 = new Double (10.23); 204 * Number result = null; 205 * for (int a = 0; a < 10000; a++) 206 * { 207 * 208 * result = MathUtils.typeConvert ( 209 * new BigDecimal (v1.doubleValue()).add ( 210 * new BigDecimal (v2.doubleValue())), v1, v2, false); 211 * 212 * } 213 * 214 * System.out.println ("took: "+(System.currentTimeMillis()-start)); 215 * 216 * start = System.currentTimeMillis(); 217 * for (int a = 0; a < 10000; a++) 218 * { 219 * 220 * result = MathUtils.divide( v1, v2); 221 * } 222 * 223 * Number result2 = result; 224 * System.out.println ("took: "+(System.currentTimeMillis()-start)); 225 * } 226 * 227 */ 228 229 /** 230 * Test additional functions 231 */ testIsZero()232 public void testIsZero() 233 { 234 assertTrue (MathUtils.isZero (0)); 235 assertTrue (!MathUtils.isZero (1)); 236 assertTrue (!MathUtils.isZero (-1)); 237 238 assertTrue (MathUtils.isZero (0f)); 239 assertTrue (!MathUtils.isZero (0.00001f)); 240 assertTrue (!MathUtils.isZero (-0.00001f)); 241 242 } 243 244 } 245