/* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.math.BigInteger; import java.util.ArrayList; import java.util.Iterator; import java.util.Arrays; import java.util.List; import java.util.function.LongFunction; import java.util.function.Function; import static org.testng.Assert.assertEquals; /** * @test * @run testng IntegralPrimitiveToString * @summary test string conversions for primitive integral types. * @author Mike Duigou */ public class IntegralPrimitiveToString { @Test(dataProvider="numbers") public void testToString(String description, Function converter, Function unsignedConverter, N[] values, Object[] formatters) { System.out.printf("%s : conversions: %d values: %d\n", description, formatters.length, values.length); for( N value : values) { BigInteger asBigInt = converter.apply(value); BigInteger asUnsignedBigInt = unsignedConverter.apply(value); for(Object format : formatters) { Object[] formatter = (Object[]) format; boolean signed = (Boolean) formatter[0]; int radix = (Integer) formatter[1]; Function toString = (Function) formatter[2]; String exemplar = signed ? asBigInt.toString(radix) : asUnsignedBigInt.toString(radix); String test = toString.apply(value); assertEquals(exemplar, test, description + " should be the same"); } } } @DataProvider(name="numbers", parallel=true) public Iterator testSetProvider() { return Arrays.asList( new Object[] { "Byte", (Function) (Byte b) -> BigInteger.valueOf((long) b), (Function) (Byte b) -> BigInteger.valueOf(Integer.toUnsignedLong((byte)b)), numberProvider((LongFunction) (l) -> Byte.valueOf((byte) l), Byte.SIZE), new Object[] { new Object[] { true, 10, (Function) (b) -> b.toString() }, new Object[] { true, 10, (Function) (b) -> Byte.toString((byte) b) } } }, new Object[] { "Short", (Function) (s) -> BigInteger.valueOf((long) s), (Function) (s) -> BigInteger.valueOf(Integer.toUnsignedLong((short)s)), numberProvider((LongFunction) (l) -> Short.valueOf((short) l), Short.SIZE), new Object[] { new Object[] { true, 10, (Function) (s) -> s.toString() }, new Object[] { true, 10, (Function) (s) -> Short.toString((short) s) } } }, new Object[] { "Integer", (Function) (i) -> BigInteger.valueOf((long) i), (Function) (i) -> BigInteger.valueOf(Integer.toUnsignedLong(i)), numberProvider((LongFunction) (l) -> Integer.valueOf((int) l), Integer.SIZE), new Object[] { new Object[] { true, 10, (Function) (i) -> i.toString() }, new Object[] { true, 10, (Function) (i) -> Integer.toString((int) i) }, new Object[] { false, 2, (Function) (i) -> Integer.toBinaryString((int) i) }, new Object[] { false, 16, (Function) (i) -> Integer.toHexString((int) i) }, new Object[] { false, 8, (Function) (i) -> Integer.toOctalString((int) i) }, new Object[] { true, 2, (Function) (i) -> Integer.toString((int) i, 2) }, new Object[] { true, 8, (Function) (i) -> Integer.toString((int) i, 8) }, new Object[] { true, 10, (Function) (i) -> Integer.toString((int) i, 10) }, new Object[] { true, 16, (Function) (i) -> Integer.toString((int) i, 16) }, new Object[] { true, Character.MAX_RADIX, (Function) (i) -> Integer.toString((int) i, Character.MAX_RADIX) }, new Object[] { false, 10, (Function) (i) -> Integer.toUnsignedString((int) i) }, new Object[] { false, 2, (Function) (i) -> Integer.toUnsignedString((int) i, 2) }, new Object[] { false, 8, (Function) (i) -> Integer.toUnsignedString((int) i, 8) }, new Object[] { false, 10, (Function) (i) -> Integer.toUnsignedString((int) i, 10) }, new Object[] { false, 16, (Function) (i) -> Integer.toUnsignedString((int) i, 16) }, new Object[] { false, Character.MAX_RADIX, (Function) (i) -> Integer.toUnsignedString((int) i, Character.MAX_RADIX) } } }, new Object[] { "Long", (Function) (l) -> BigInteger.valueOf((long) l), (Function)(l) -> { if (l >= 0) { return BigInteger.valueOf((long)l); } else { int upper = (int)(l >>> 32); int lower = (int) (long) l; // return (upper << 32) + lower return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32). add(BigInteger.valueOf(Integer.toUnsignedLong(lower))); } }, numberProvider((LongFunction) Long::valueOf, Long.SIZE), new Object[] { new Object[] { true, 10, (Function) (l) -> l.toString() }, new Object[] { true, 10, (Function) (l) -> Long.toString((long) l) }, new Object[] { false, 2, (Function) (l) -> Long.toBinaryString((long) l) }, new Object[] { false, 16, (Function) (l) -> Long.toHexString((long) l) }, new Object[] { false, 8, (Function) (l) -> Long.toOctalString((long) l) }, new Object[] { true, 2, (Function) (l) -> Long.toString((long) l, 2) }, new Object[] { true, 8, (Function) (l) -> Long.toString((long) l, 8) }, new Object[] { true, 10, (Function) (l) -> Long.toString((long) l, 10) }, new Object[] { true, 16, (Function) (l) -> Long.toString((long) l, 16) }, new Object[] { true, Character.MAX_RADIX, (Function) (l) -> Long.toString((long) l, Character.MAX_RADIX) }, new Object[] { false, 10, (Function) (l) -> Long.toUnsignedString((long) l) }, new Object[] { false, 2, (Function) (l) -> Long.toUnsignedString((long) l, 2) }, new Object[] { false, 8, (Function) (l) -> Long.toUnsignedString((long) l, 8) }, new Object[] { false, 10, (Function) (l) -> Long.toUnsignedString((long) l, 10) }, new Object[] { false, 16, (Function) (l) -> Long.toUnsignedString((long) l, 16) }, new Object[] { false, Character.MAX_RADIX, (Function) (l) -> Long.toUnsignedString((long) l, Character.MAX_RADIX) } } } ).iterator(); } private static final long[] SOME_PRIMES = { 3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L, 29L, 31L, 37L, 41L, 43L, 47L, 53L, 59L, 61L, 71L, 73L, 79L, Long.MIN_VALUE }; public N[] numberProvider(LongFunction boxer, int bits, N... extras) { List numbers = new ArrayList<>(); for(int bitmag = 0; bitmag < bits; bitmag++) { long value = 1L << bitmag; numbers.add(boxer.apply(value)); numbers.add(boxer.apply(value - 1)); numbers.add(boxer.apply(value + 1)); numbers.add(boxer.apply(-value)); for(int divisor = 0; value < SOME_PRIMES[divisor]; divisor++) { numbers.add(boxer.apply(value - SOME_PRIMES[divisor])); numbers.add(boxer.apply(value + SOME_PRIMES[divisor])); numbers.add(boxer.apply(value * SOME_PRIMES[divisor])); numbers.add(boxer.apply(value / SOME_PRIMES[divisor])); numbers.add(boxer.apply(value | SOME_PRIMES[divisor])); numbers.add(boxer.apply(value & SOME_PRIMES[divisor])); numbers.add(boxer.apply(value ^ SOME_PRIMES[divisor])); } } numbers.addAll(Arrays.asList(extras)); return (N[]) numbers.toArray(new Number[numbers.size()]); } }