/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.test.unit; import java.math.BigInteger; import java.util.ArrayList; import java.util.Random; import org.h2.test.TestBase; import org.h2.util.New; import org.h2.value.Value; import org.h2.value.ValueString; /** * Tests numeric overflow on various data types. * Other than in Java, overflow is detected and an exception is thrown. */ public class TestOverflow extends TestBase { private ArrayList<Value> values; private int dataType; private BigInteger min, max; private boolean successExpected; /** * Run just this test. * * @param a ignored */ public static void main(String... a) throws Exception { TestBase.createCaller().init().test(); } public void test() { test(Value.BYTE, Byte.MIN_VALUE, Byte.MAX_VALUE); test(Value.INT, Integer.MIN_VALUE, Integer.MAX_VALUE); test(Value.LONG, Long.MIN_VALUE, Long.MAX_VALUE); test(Value.SHORT, Short.MIN_VALUE, Short.MAX_VALUE); } private void test(int type, long minValue, long maxValue) { values = New.arrayList(); this.dataType = type; this.min = new BigInteger("" + minValue); this.max = new BigInteger("" + maxValue); add(0); add(minValue); add(maxValue); add(maxValue - 1); add(minValue + 1); add(1); add(-1); Random random = new Random(1); for (int i = 0; i < 40; i++) { if (maxValue > Integer.MAX_VALUE) { add(random.nextLong()); } else { add((random.nextBoolean() ? 1 : -1) * random.nextInt((int) maxValue)); } } for (Value va : values) { for (Value vb : values) { testValues(va, vb); } } } private void checkIfExpected(String a, String b) { if (successExpected) { assertEquals(a, b); } } private void onSuccess() { if (!successExpected) { fail(); } } private void onError() { if (successExpected) { fail(); } } private void testValues(Value va, Value vb) { BigInteger a = new BigInteger(va.getString()); BigInteger b = new BigInteger(vb.getString()); successExpected = inRange(a.negate()); try { checkIfExpected(va.negate().getString(), a.negate().toString()); onSuccess(); } catch (Exception e) { onError(); } successExpected = inRange(a.add(b)); try { checkIfExpected(va.add(vb).getString(), a.add(b).toString()); onSuccess(); } catch (Exception e) { onError(); } successExpected = inRange(a.subtract(b)); try { checkIfExpected(va.subtract(vb).getString(), a.subtract(b).toString()); onSuccess(); } catch (Exception e) { onError(); } successExpected = inRange(a.multiply(b)); try { checkIfExpected(va.multiply(vb).getString(), a.multiply(b).toString()); onSuccess(); } catch (Exception e) { onError(); } } private boolean inRange(BigInteger v) { return v.compareTo(min) >= 0 && v.compareTo(max) <= 0; } private void add(long l) { values.add(ValueString.get("" + l).convertTo(dataType)); } }