PortableDistance { static PortableDistance fromDistance(Distance distance) { long seconds = (Objects.requireNonNull(distance).millis() + 500) / 1000; return new PortableDistance(String.format("%dh %dm %ds", seconds / 3600, seconds / 60 % 60, seconds % 60)); } private  PortableDistance(String distance); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString();  }
@Test void marshal_to_json() throws IOException { Distance distance = Distance.ofMillis(3_661_987); assertThat(json.write(PortableDistance.fromDistance(distance)).getJson()).isEqualTo("\"1h 1m 2s\""); }
@Test void from_distance() { assertThatNullPointerException().isThrownBy(() -> PortableDistance.fromDistance(null)); }
@Test void equals_hashCode_toString() { long millis = 173_000; Distance distance = Distance.ofMillis(millis); PortableDistance portableDistance = PortableDistance.fromDistance(distance); assertThat(portableDistance) .isEqualTo(portableDistance) .isEqualTo(PortableDistance.fromDistance(distance)) .isNotEqualTo(null) .isNotEqualTo(millis) .isNotEqualTo(PortableDistance.fromDistance(Distance.ofMillis(millis - 501))) .hasSameHashCodeAs(PortableDistance.fromDistance(distance)) .asString().contains("0h 2m 53s"); }