/* * Copyright 2015-2016 Cel Skeggs * * This file is part of the CCRE, the Common Chicken Runtime Engine. * * The CCRE is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * The CCRE 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with the CCRE. If not, see <http://www.gnu.org/licenses/>. */ package ccre.util; import java.util.Random; /** * A class that provides useful sets of values and methods for generating them, * which may be used in unit tests. * * Some of these may be random, and some may be pregenerated sequences that hit * all of the major edge cases. * * @author skeggsc */ public class Values { private static final Random random = new Random(); /** * Creates and return a random string of up to length 9. * * Characters are chosen to be weighted towards ASCII characters, especially * control characters. * * @return the generated String. */ public static String getRandomString() { char[] chrs = new char[random.nextInt(10)]; for (int i = 0; i < chrs.length; i++) { chrs[i] = (char) (random.nextBoolean() ? random.nextBoolean() ? random.nextInt(0xAFFF) : random.nextInt(256) : random.nextInt(33)); } return new String(chrs); } /** * Creates and returns an array of <code>n</code> random strings of up to * length 9. * * @param n the number of strings to generate. * @see #getRandomString() for how these strings are generated. * @return the generated strings. */ public static String[] getRandomStrings(int n) { String[] strs = new String[n]; for (int i = 0; i < n; i++) { strs[i] = getRandomString(); } return strs; } /** * Generates a random array of <code>length</code> bytes, mostly evenly * distributed. * * @param length the number of bytes to generate. * @return the generated bytes. */ public static byte[] getRandomBytes(int length) { byte[] bytes = new byte[length]; random.nextBytes(bytes); return bytes; } /** * Generates a random array of bytes, somewhere from length * <code>minlen</code> to length <code>maxlen</code>, inclusive. * * @see #getRandomBytes(int) for details on how random bytes are generated. * @param minlen the minimum number of bytes to generate. * @param maxlen the maximum number of bytes to generate. * @return the generated bytes. */ public static byte[] getRandomBytes(int minlen, int maxlen) { return getRandomBytes(random.nextInt(maxlen - minlen + 1) + minlen); } /** * Generates an array of random random arrays of bytes, somewhere from * length <code>minlen</code> to length <code>maxlen</code>, inclusive. * <code>count</code> is the count of the number of arrays generated. * * @see #getRandomBytes(int, int) for details on how random byte arrays are * generated. * @param count the number of byte arrays to generate. * @param minlen the minimum number of bytes to generate. * @param maxlen the maximum number of bytes to generate. * @return the generated bytes. */ public static byte[][] getRandomByteses(int count, int minlen, int maxlen) { byte[][] byteses = new byte[count][]; for (int i = 0; i < count; i++) { byteses[i] = getRandomBytes(minlen, maxlen); } return byteses; } /** * Generates a random boolean. * * @return the random boolean. */ public static boolean getRandomBoolean() { return random.nextBoolean(); } /** * Generates a random integer, no less than zero and smaller than * <code>bound</code>. * * @param bound the upper bound, exclusive. * @return the random boolean. */ public static int getRandomInt(int bound) { return random.nextInt(bound); } /** * Generates a random float. May include numbers like NaN, infinity, * MAX_VALUE, or 0. * * @return the random float. */ public static float getRandomFloat() { return (float) (interestingFloats[random.nextInt(interestingFloats.length)] * random.nextGaussian() * 1.5f); } /** * A sequence of interesting floats for testing edge cases: things like * negative infinity, NaN, MAX_VALUE, -MAX_VALUE, 0, 1, -1, etc. * * @see Values#shorterInterestingFloats * @see Values#lessInterestingFloats * @see Values#interestingBooleans */ public static final float[] interestingFloats = new float[] { Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, -1024.7f, -32f, -6.3f, -1.1f, -1f, -0.7f, -0.3f, -0.1f, -0.001f, -Float.MIN_VALUE, -0.0f, +0.0f, Float.NaN, Float.MIN_VALUE, 0.001f, 0.1f, 0.3f, 0.7f, 1.0f, 1.1f, 6.3f, 32f, 1024.7f, Float.MAX_VALUE, Float.POSITIVE_INFINITY }; /** * A shorter sequence of interesting floats for testing edge cases: things * like negative infinity, NaN, MAX_VALUE, -MAX_VALUE, 0, 1, -1, etc. * * @see Values#interestingFloats * @see Values#lessInterestingFloats * @see Values#interestingBooleans */ public static final float[] shorterInterestingFloats = new float[] { Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, -32f, -1.1f, -1f, -0.1f, -Float.MIN_VALUE, -0.0f, +0.0f, Float.NaN, Float.MIN_VALUE, 0.1f, 1.0f, 1.1f, 32f, Float.MAX_VALUE, Float.POSITIVE_INFINITY }; /** * A sequence of slightly less interesting floats for testing edge cases: * this is like {@link #interestingFloats}, but with only finite values not * near MAX_VALUE in magnitude. * * @see Values#interestingFloats * @see Values#shorterInterestingFloats */ public static final float[] lessInterestingFloats = new float[] { -1024.7f, -32f, -6.3f, -1.1f, -1f, -0.7f, -0.5f, -0.3f, -0.1f, -0.001f, -Float.MIN_VALUE, 0, Float.NaN, Float.MIN_VALUE, 0.001f, 0.1f, 0.3f, 0.5f, 0.7f, 1.0f, 1.1f, 6.3f, 32f, 1024.7f }; /** * A sequence of booleans in an interesting sequence: mostly, toggling and * longer periods of toggling. * * @see Values#interestingFloats */ public static final boolean[] interestingBooleans = new boolean[] { false, true, true, false, false, true, false, true, false, true, true, true, false, true, false, false, false, true }; }