Skip to content

Commit

Permalink
Improves usability of the ByteCount class by implementing equals()/ha…
Browse files Browse the repository at this point in the history
…shCode()/toString(). (opensearch-project#3960)

Signed-off-by: David Venable <[email protected]>
  • Loading branch information
dlvenable authored Jan 19, 2024
1 parent 578d253 commit b8c4933
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -120,4 +121,48 @@ private static BigDecimal scaleToBytes(final BigDecimal value, final Unit unit)
private static boolean isFractional(final BigDecimal value) {
return value.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) != 0;
}

/**
* Returns a hash code consistent with {@link ByteCount#equals(Object)}.
*
* @return The hash code
* @since 2.7
*/
@Override
public int hashCode() {
return Objects.hashCode(bytes);
}

/**
* Returns whether this and another instance are equal {@link ByteCount} values.
* Two objects are equal if the bytes are equal. It does not matter how they
* were originally parsed.
*
* @param otherObject The other object to compare against.
* @return True if and only if the values are equal.
* @since 2.7
*/
@Override
public boolean equals(final Object otherObject) {
if(! (otherObject instanceof ByteCount))
return false;

return ((ByteCount) otherObject).bytes == bytes;
}

/**
* Returns a string representation of this {@link ByteCount}. This
* representation can be parsed by {@link ByteCount#parse(String)}.
* <p>
* The exact string return could change between versions, but this
* API will provide consistency that the value is accurate and can
* be parsed by {@link ByteCount#parse(String)}.
*
* @return The string representation of this byte count.
* @since 2.7
*/
@Override
public String toString() {
return bytes + "b";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Random;

import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
Expand All @@ -18,6 +21,8 @@
import static org.junit.jupiter.api.Assertions.assertThrows;

class ByteCountTest {
private final Random random = new Random();

@ParameterizedTest
@ValueSource(strings = {
".1b",
Expand Down Expand Up @@ -174,4 +179,87 @@ void zeroBytes_returns_same_instance() {
assertThat(ByteCount.zeroBytes(), notNullValue());
assertThat(ByteCount.zeroBytes(), sameInstance(ByteCount.zeroBytes()));
}

@ParameterizedTest
@ValueSource(longs = {0, 1, 2, 500, 512, 1000, 1024, Integer.MAX_VALUE, (long) Integer.MAX_VALUE + 100})
void hashCode_returns_same_value_for_same_bytes(final long bytes) {
assertThat(ByteCount.ofBytes(bytes).hashCode(),
equalTo(ByteCount.ofBytes(bytes).hashCode()));
}

@ParameterizedTest
@ValueSource(longs = {0, 1, 2, 500, 512, 1000, 1024, Integer.MAX_VALUE, (long) Integer.MAX_VALUE + 100})
void hashCode_returns_different_value_for_known_differences(final long bytes) {
assertThat(ByteCount.ofBytes(bytes).hashCode(),
not(equalTo(ByteCount.ofBytes(bytes+1).hashCode())));
}

@ParameterizedTest
@ValueSource(longs = {0, 1, 2, 500, 512, 1000, 1024, Integer.MAX_VALUE, (long) Integer.MAX_VALUE + 100})
void equals_returns_true_for_same_value(final long bytes) {
assertThat(ByteCount.ofBytes(bytes).equals(ByteCount.ofBytes(bytes)),
equalTo(true));
}

@Test
void equals_returns_false_for_null_other_object() {
assertThat(ByteCount.ofBytes(1024).equals(null),
equalTo(false));
}

@Test
void equals_returns_false_for_other_type() {
assertThat(ByteCount.ofBytes(1024).equals("1kb"),
equalTo(false));
}

@ParameterizedTest
@ValueSource(longs = {0, 1, 2, 500, 512, 1000, 1024, Integer.MAX_VALUE, (long) Integer.MAX_VALUE + 100})
void equals_returns_false_for_unequal_values(final long bytes) {
assertThat(ByteCount.ofBytes(bytes).equals(ByteCount.ofBytes(bytes+1)),
equalTo(false));
}

@ParameterizedTest
@CsvSource({
"0b, 0b",
"0kb, 0b",
"0mb, 0b",
"0gb, 0b",
"1b, 1b",
"8b, 8b",
"1024b, 1024b",
"2048b, 2048b",
"0.25kb, 256b",
"0.5kb, 512b",
"1kb, 1024b",
"2kb, 2048b",
"1.25kb, 1280b",
"1.5kb, 1536b",
"1024kb, 1048576b",
"2048kb, 2097152b",
"0.5mb, 524288b",
"1mb, 1048576b",
"2mb, 2097152b",
"5mb, 5242880b",
"1024mb, 1073741824b",
"0.5gb, 536870912b",
"1gb, 1073741824b",
"1.5gb, 1610612736b",
"2gb, 2147483648b",
"200gb, 214748364800b"
})
void toString_returns_expected_byte_string(final String byteString, final String expectedString) {
final ByteCount objectUnderTest = ByteCount.parse(byteString);
assertThat(objectUnderTest.toString(), equalTo(expectedString));
}

@ParameterizedTest
@ValueSource(longs = {0, 1, 2, 500, 512, 1000, 1024, Integer.MAX_VALUE, (long) Integer.MAX_VALUE + 100})
void toString_returns_string_that_parses_to_the_same_value(final long bytes) {
final ByteCount objectUnderTest = ByteCount.ofBytes(bytes);
final ByteCount parsedByteCount = ByteCount.parse(objectUnderTest.toString());
assertThat(parsedByteCount, equalTo(objectUnderTest));
assertThat(parsedByteCount.hashCode(), equalTo(objectUnderTest.hashCode()));
}
}

0 comments on commit b8c4933

Please sign in to comment.