Skip to content

Commit

Permalink
Test conversion to/from hex
Browse files Browse the repository at this point in the history
  • Loading branch information
aherbert committed Jul 27, 2023
1 parent 2a33303 commit aab807f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
18 changes: 14 additions & 4 deletions gdsc-core/src/main/java/uk/ac/sussex/gdsc/core/utils/Seed.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
* Provides a seed of bits. Methods are provided to convert between data representations.
*/
public final class Seed {

/** The bytes. */
private final byte[] bytes;
/** The hash code. */
Expand Down Expand Up @@ -64,11 +63,22 @@ public static Seed from(byte[] bytes) {
/**
* Create a seed from the hex-encoded characters. No reference to the input is stored.
*
* @param cs the characters
* <p>If the sequence is an odd length then the final hex character is assumed to be '0'.
*
* @param chars the hex characters
* @return the seed
* @throws IllegalArgumentException If the sequence does not contain valid hex characters
*/
public static Seed from(CharSequence cs) {
return new Seed(Hex.decode(Objects.requireNonNull(cs, "The characters must not be null")));
public static Seed from(CharSequence chars) {
int length = Objects.requireNonNull(chars, "The characters must not be null").length();
// Avoid IAE when length is zero
if (length == 0) {
return new Seed(new byte[0]);
}
// Here any error decoding will throw an exception
return new Seed(Hex.decode(chars, () -> {
throw new IllegalArgumentException("Invalid hex sequence");
}));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Locale;
import java.util.stream.Stream;
import org.apache.commons.rng.UniformRandomProvider;
import org.junit.jupiter.api.Assertions;
Expand All @@ -44,7 +45,7 @@
@SuppressWarnings({"javadoc"})
class SeedTest {
@Test
void nullArgumentThrows() {
void testNullArgumentThrows() {
Assertions.assertThrows(NullPointerException.class, () -> Seed.from((byte[]) null));
Assertions.assertThrows(NullPointerException.class, () -> Seed.from((String) null));
}
Expand Down Expand Up @@ -94,6 +95,35 @@ void testBytesToLong() {
Assertions.assertNotEquals(Seed.from(b3).toLong(), Seed.from(b4).toLong());
}

@ParameterizedTest
@ValueSource(strings = {"abcg", "helloworld", "0123456789 abcdef"})
void testInvalidHexThrows(String s) {
Assertions.assertThrows(IllegalArgumentException.class, () -> Seed.from(s));
}

@Test
void testEmptyHex() {
final Seed seed = Seed.from("");
Assertions.assertEquals(0, seed.toLong());
Assertions.assertArrayEquals(new byte[0], seed.toBytes());
Assertions.assertEquals("", seed.toString());
Assertions.assertEquals(Arrays.hashCode(new byte[0]), seed.hashCode());
}

@ParameterizedTest
@ValueSource(strings = {"abc", "4567", "0123456789abcdef", "0a7BC81f"})
void testHex(String s) {
// Case insensitive
final Seed seed = Seed.from(s);
final Seed seed1 = Seed.from(s.toLowerCase(Locale.ROOT));
final Seed seed2 = Seed.from(s.toUpperCase(Locale.ROOT));
Assertions.assertArrayEquals(seed.toBytes(), seed1.toBytes());
Assertions.assertArrayEquals(seed.toBytes(), seed2.toBytes());
// The seed zero pads an odd length input
final String expected = (s.length() & 1) == 0 ? s : s + "0";
Assertions.assertEquals(expected.toLowerCase(Locale.ROOT), seed.toString());
}

@SeededTest
void testEqualsAndHashCode(RandomSeed rs) {
final byte[] bytes = rs.get();
Expand Down

0 comments on commit aab807f

Please sign in to comment.