Skip to content

Commit

Permalink
Fix: Correct contract of equals and hashCode of HODateTime
Browse files Browse the repository at this point in the history
  • Loading branch information
sgcr committed Sep 3, 2024
1 parent 56baf8a commit 7505a3d
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
20 changes: 19 additions & 1 deletion src/main/java/core/util/HODateTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,25 @@ public int compareTo(@NotNull HODateTime o) {
return instant.compareTo(o.instant);
}

public boolean equals(HODateTime t){ return this.instant.equals(t.instant);}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof HODateTime that) {
return that.canEqual(this) && instant.equals(that.instant);
}
return false;
}

@Override
public int hashCode() {
return instant.hashCode();
}

protected boolean canEqual(Object o) {
return o instanceof HODateTime;
}

public HODateTime minus(int i, ChronoUnit unit) {
return new HODateTime(instant.minus(i, unit));
Expand Down
75 changes: 74 additions & 1 deletion src/test/java/core/util/HODateTimeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.math.BigDecimal.ONE;
import static java.math.BigDecimal.ZERO;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.assertj.core.data.Offset.offset;
import static org.junit.jupiter.params.provider.Arguments.of;

class HODateTimeTest {

private static final HODateTime HO_DATE_TIME = HODateTime.fromHT("2024-01-01 00:00:00");

@Test
void test() {
var nextTraining = HODateTime.fromHT("2022-03-31 08:30:00");
Expand Down Expand Up @@ -74,6 +81,72 @@ void test() {

}

static Stream<Arguments> equals() {
return Stream.of(
Arguments.of(HODateTime.fromHT("2024-10-30 20:00:00"), HODateTime.fromHT("2025-10-30 20:00:00"), false),
Arguments.of(HODateTime.fromHT("2024-10-30 20:00:00"), HODateTime.fromHT("2024-11-30 20:00:00"), false),
Arguments.of(HODateTime.fromHT("2024-10-30 20:00:00"), HODateTime.fromHT("2024-10-31 20:00:00"), false),
Arguments.of(HODateTime.fromHT("2024-10-30 20:00:00"), HODateTime.fromHT("2024-10-30 21:00:00"), false),
Arguments.of(HODateTime.fromHT("2024-10-30 20:00:00"), HODateTime.fromHT("2024-10-30 20:01:00"), false),
Arguments.of(HODateTime.fromHT("2024-10-30 20:00:00"), HODateTime.fromHT("2024-10-30 20:00:01"), false),
Arguments.of(HO_DATE_TIME, HO_DATE_TIME, true),
Arguments.of(HODateTime.fromHT("2024-10-30 20:00:00"), HODateTime.fromHT("2024-10-30 20:00:00"), true),
Arguments.of(HO_DATE_TIME, null, false)
);
}

@ParameterizedTest
@MethodSource
void equals(HODateTime lhs, HODateTime rhs, boolean result) {
assertThat(lhs.equals(rhs)).isEqualTo(result);
}


@Test
void testHashCode_consistencyOnTwoCalls() {
// given
final var now = HODateTime.now();

// when
final var hashCode1 = now.hashCode();
final var hashCode2 = now.hashCode();

// then
assertThat(hashCode1).isEqualTo(hashCode2);
}

@Test
void testHashCode_twoEqualObjectsResultsEqualHashCodes() {
// given
final var htTimeString = "2024-12-31 23:59:59";
final var hoDateTime1 = HODateTime.fromHT(htTimeString);
final var hoDateTime2 = HODateTime.fromHT(htTimeString);

// when
final var hashCode1 = hoDateTime1.hashCode();
final var hashCode2 = hoDateTime2.hashCode();

// then
assertThat(hashCode1).isEqualTo(hashCode2);
}

@Test
void testHashCode_givenMultipleObjects_whenTestingHashCodeDistribution_thenEvenDistributionOfHashCodes() {
// given
final var localDateTime = LocalDateTime.now();
final var objects = IntStream.range(0, 1000).mapToObj(i -> generate(i, localDateTime)).toList();

// when
final Set<Integer> hashCodes = objects.stream().map(Objects::hashCode).collect(Collectors.toSet());

// then
assertThat(hashCodes.size()).isCloseTo( objects.size(), offset(10));
}

private static HODateTime generate(int i, LocalDateTime localDateTime) {
return fromLocalDateTime(localDateTime.plusDays(i));
}

@Test
void daysFromNow_future() {
// given
Expand Down

0 comments on commit 7505a3d

Please sign in to comment.