/* * Copyright 2015 Cel Skeggs, 2016 Alexander Mackworth * * 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 static org.junit.Assert.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; import org.junit.Test; @SuppressWarnings("javadoc") public class UtilsTest { private void checkBytesToFloatFor(float f) { int ibits = Float.floatToIntBits(f); byte[] d = new byte[] { (byte) (ibits >> 24), (byte) (ibits >> 16), (byte) (ibits >> 8), (byte) ibits }; assertEquals(ibits, Utils.bytesToInt(d, 0)); assertEquals(ibits, Float.floatToIntBits(Utils.bytesToFloat(d, 0))); } @Test public void testSimpleBytesToFloat() { checkBytesToFloatFor(0); } @Test public void testOffsetBytesToFloat() { int ibits = Float.floatToIntBits(17.77f); // junk data at start byte[] d = new byte[] { 3, 3, 3, 8, 1, 2, 5, (byte) (ibits >> 24), (byte) (ibits >> 16), (byte) (ibits >> 8), (byte) ibits }; assertEquals(ibits, Utils.bytesToInt(d, 7)); assertEquals(ibits, Float.floatToIntBits(Utils.bytesToFloat(d, 7))); } @Test public void testInterestingBytesToFloat() { for (float f : Values.interestingFloats) { checkBytesToFloatFor(f); } } @Test public void testGaussianBytesToFloat() { Random r = new Random(); for (int i = 0; i < 10000; i++) { checkBytesToFloatFor((float) (r.nextGaussian() / 10000)); checkBytesToFloatFor((float) r.nextGaussian()); checkBytesToFloatFor((float) (r.nextGaussian() * 10000)); } } private int[][] bytesToIntTests = new int[][] { { 0x00, 0x00, 0x00, 0x00, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF, -1 }, { 0x00, 0x00, 0x00, 0x01, 1 }, { 0x00, 0x00, 0x00, 0x0A, 10 }, { 0x00, 0x00, 0x00, 0x10, 16 }, { 0x00, 0x00, 0x00, 0x42, 66 }, { 0x00, 0x00, 0x01, 0x00, 256 }, { 0x00, 0x00, 0x01, 0x42, 322 }, { 0x00, 0x00, 0xA1, 0x42, 0xA142 }, { 0x00, 0xBC, 0xFF, 0x02, 0xBCFF02 }, { 0x72, 0xEE, 0x99, 0x31, 0x72EE9931 }, { 0xCA, 0xAC, 0xBD, 0xDB, 0xCAACBDDB } }; @Test public void testBytesToIntSimple() { assertEquals(0x1000203, Utils.bytesToInt(new byte[] { 1, 0, 2, 3 }, 0)); } @Test public void testBytesToInt() { for (int[] line : bytesToIntTests) {// MSB, B, B, LSB, EXPECTED byte a = (byte) line[0], b = (byte) line[1], c = (byte) line[2], d = (byte) line[3]; assertEquals(line[4], Utils.bytesToInt(new byte[] { a, b, c, d }, 0)); } } @Test public void testBytesToIntOffset() { for (int[] line : bytesToIntTests) {// MSB, B, B, LSB, EXPECTED byte a = (byte) line[0], b = (byte) line[1], c = (byte) line[2], d = (byte) line[3]; assertEquals(line[4], Utils.bytesToInt(new byte[] { 0, 0, 0, a, b, c, d }, 3)); } } @Test public void testUpdateRamping() { for (float base : new float[] { -1, 0, 1, 0.5f, -0.5f, 0.1f, -0.1f, 0.001f, -0.001f, 0.7f, -0.7f, 56, -56, -1.3f, 1.3f }) { for (float limit : new float[] { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 1f, 2f, 2.5f, 6f, 10f }) { assertEquals(base, Utils.updateRamping(base, base, limit), 0); assertEquals(base, Utils.updateRamping(base, base, -limit), 0); for (float rel : new float[] { 0f, 0.01f, 0.1f, 0.2f, 0.3f, 0.5f, 1f, 2f, 30f }) { if (rel >= limit) { assertEquals((base + limit), Utils.updateRamping(base, base + rel, limit), 0); assertEquals((base + limit), Utils.updateRamping(base, base + rel, -limit), 0); assertEquals((base - limit), Utils.updateRamping(base, base - rel, limit), 0); assertEquals((base - limit), Utils.updateRamping(base, base - rel, -limit), 0); } else { assertEquals((base + rel), Utils.updateRamping(base, base + rel, limit), 0); assertEquals((base + rel), Utils.updateRamping(base, base + rel, -limit), 0); assertEquals((base - rel), Utils.updateRamping(base, base - rel, limit), 0); assertEquals((base - rel), Utils.updateRamping(base, base - rel, -limit), 0); } } } for (float rel : new float[] { 0f, 0.01f, 0.1f, 0.2f, 0.3f, 0.5f, 1f, 2f, 30f }) { assertEquals((base + rel), Utils.updateRamping(base, base + rel, 0), 0); } } } @Test public void testDeadzone() { for (float i = -17.6f; i <= 17.6f; i += 0.1f) { float dz = Utils.deadzone(i, 7.2f); if (i >= -7.2f && i <= 7.2f) { assertEquals(0f, dz, 0); } else { assertEquals(i, dz, 0); } } } @Test public void testMethodCaller() { CallerInfo info = Utils.getMethodCaller(0); assertEquals("ccre.util.UtilsTest", info.getClassName()); assertEquals("UtilsTest.java", info.getFileName()); assertEquals("testMethodCaller", info.getMethodName()); } @Test public void testMethodCallerLineNumber() { CallerInfo info = Utils.getMethodCaller(0); CallerInfo info2 = Utils.getMethodCaller(0); assertEquals(info2.getLineNum() - 1, info.getLineNum()); } @Test public void testMethodCallerInvalid() { for (int i = -10; i < 0; i++) { assertNull("Got caller info for internals!", Utils.getMethodCaller(i)); } assertNull("Got caller info for what should be off the end of the stack trace!", Utils.getMethodCaller(1000)); } @Test public void testToStringThrowable() { CallerInfo info = Utils.getMethodCaller(0); String got = Utils.toStringThrowable(new Throwable("Example")); String[] pts = got.split("\n"); assertNotNull(info.getFileName()); assertNotNull(info.getMethodName()); assertTrue(info.getLineNum() > 0); assertEquals("java.lang.Throwable: Example", pts[0]); int expectedLine = info.getLineNum() + 1; assertEquals("\tat " + info.getClassName() + "." + info.getMethodName() + "(" + info.getFileName() + ":" + expectedLine + ")", pts[1]); } @Test public void testNullToStringThrowable() { assertNull(Utils.toStringThrowable(null)); } @Test public void testJoinStrings() { // TODO: generate lists of different lengths String separator = Values.getRandomString(); List<String> pathComponents = Arrays.asList(Values.getRandomString(), Values.getRandomString(), Values.getRandomString()); String result = Utils.joinStrings(pathComponents, separator); assertEquals(pathComponents.get(0) + separator + pathComponents.get(1) + separator + pathComponents.get(2), result); } @Test(expected = NullPointerException.class) public void testJoinStringsNullStrings() { Utils.joinStrings(null, ","); } @Test(expected = NullPointerException.class) public void testJoinStringsNullSeparator() { List<String> pathComponents = Arrays.asList("beginning", "middle", "end"); Utils.joinStrings(pathComponents, null); } @Test(expected = NullPointerException.class) public void testJoinStringsBothArgumentsNull() { Utils.joinStrings(null, null); } @Test public void testJoinStringsEmptyArguments() { for (int i = 0; i < 10; i++) { String separator = Values.getRandomString(); List<String> pathComponents = Arrays.asList(Values.getRandomString(), Values.getRandomString(), Values.getRandomString()); assertEquals(Utils.joinStrings(new ArrayList<String>(), separator), ""); assertEquals(Utils.joinStrings(pathComponents, ""), pathComponents.get(0) + pathComponents.get(1) + pathComponents.get(2)); } } @Test(expected = NullPointerException.class) public void testJoinStringsAllNullElements() { Utils.joinStrings(Arrays.asList(null, null), ","); } @Test(expected = NullPointerException.class) public void testJoinStringsNullElementBeginning() { Utils.joinStrings(Arrays.asList(null, "middle", "end"), ","); } @Test(expected = NullPointerException.class) public void testJoinStringsNullElementMiddle() { Utils.joinStrings(Arrays.asList("beginning", null, "end"), ","); } @Test(expected = NullPointerException.class) public void testJoinStringsNullElementEnd() { Utils.joinStrings(Arrays.asList("beginning", "middle", null), ","); } }