TSK-1994: introduce new Generic Interval
Co-authored-by: Alex <arolfes@users.noreply.github.com>
This commit is contained in:
parent
f9e6b26817
commit
ff643fdff6
|
@ -1,56 +1,14 @@
|
|||
package pro.taskana.common.api;
|
||||
|
||||
import java.util.Objects;
|
||||
import pro.taskana.common.internal.Interval;
|
||||
|
||||
/**
|
||||
* IntInterval captures an Integer interval. A fixed interval has defined begin and end. An open
|
||||
* ended interval has either begin == null or end ==null.
|
||||
*/
|
||||
public class IntInterval {
|
||||
|
||||
private final Integer begin;
|
||||
private final Integer end;
|
||||
public class IntInterval extends Interval<Integer> {
|
||||
|
||||
public IntInterval(Integer begin, Integer end) {
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
boolean isValid = begin != null || end != null;
|
||||
if (begin != null && end != null && begin > end) {
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
public Integer getBegin() {
|
||||
return begin;
|
||||
}
|
||||
|
||||
public Integer getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof IntInterval)) {
|
||||
return false;
|
||||
}
|
||||
IntInterval other = (IntInterval) obj;
|
||||
return Objects.equals(begin, other.begin) && Objects.equals(end, other.end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IntInterval [" + "begin=" + this.begin + ", end=" + this.end + "]";
|
||||
super(begin, end);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,66 +1,16 @@
|
|||
package pro.taskana.common.api;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
import pro.taskana.common.internal.Interval;
|
||||
|
||||
/**
|
||||
* Capture a time interval. A fixed interval has defined begin and end Instant. An open ended
|
||||
* interval has either begin == null or end ==null.
|
||||
*/
|
||||
public class TimeInterval {
|
||||
|
||||
private final Instant begin;
|
||||
private final Instant end;
|
||||
public class TimeInterval extends Interval<Instant> {
|
||||
|
||||
public TimeInterval(Instant begin, Instant end) {
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public boolean contains(Instant i) {
|
||||
if (i == null) {
|
||||
return false;
|
||||
}
|
||||
boolean isAfterBegin = begin == null || !i.isBefore(begin);
|
||||
boolean isBeforeEnd = end == null || !i.isAfter(end);
|
||||
return (isAfterBegin && isBeforeEnd);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
boolean isValid = begin != null || end != null;
|
||||
if (begin != null && end != null && begin.isAfter(end)) {
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
public Instant getBegin() {
|
||||
return begin;
|
||||
}
|
||||
|
||||
public Instant getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof TimeInterval)) {
|
||||
return false;
|
||||
}
|
||||
TimeInterval other = (TimeInterval) obj;
|
||||
return Objects.equals(begin, other.begin) && Objects.equals(end, other.end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TimeInterval [" + "begin=" + this.begin + ", end=" + this.end + "]";
|
||||
super(begin, end);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package pro.taskana.common.internal;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An Interval captures an interval of Type <code>T extends Comparable</code>. A fixed interval has
|
||||
* defined begin and end. An open ended interval has either begin == null or end ==null.
|
||||
*
|
||||
* <p>Example: <code>Interval<Integer> interval = new Interval<>(1, 2);</code> or <code>
|
||||
* Interval<Instant> timeInterval = new Interval<>(instant_1, instant_2)</code>
|
||||
*/
|
||||
public class Interval<T extends Comparable<? super T>> {
|
||||
|
||||
private final T begin;
|
||||
|
||||
private final T end;
|
||||
|
||||
public Interval(T begin, T end) {
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public T getBegin() {
|
||||
return begin;
|
||||
}
|
||||
|
||||
public T getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public boolean contains(T i) {
|
||||
if (i == null) {
|
||||
return false;
|
||||
}
|
||||
boolean isAfterBegin = begin == null || i.compareTo(begin) >= 0;
|
||||
boolean isBeforeEnd = end == null || i.compareTo(end) <= 0;
|
||||
return (isAfterBegin && isBeforeEnd);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
boolean isValid = begin != null || end != null;
|
||||
if (begin != null && end != null && begin.compareTo(end) > 0) {
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Interval)) {
|
||||
return false;
|
||||
}
|
||||
Interval<?> other = (Interval<?>) obj;
|
||||
return Objects.equals(begin, other.begin) && Objects.equals(end, other.end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Interval [" + "begin=" + this.begin + ", end=" + this.end + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package pro.taskana.common.api;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class IntIntervalTest {
|
||||
|
||||
@Test
|
||||
void should_BeAValidIntervall_when_BeginIsBeforEnd() {
|
||||
IntInterval interval = new IntInterval(1, 2);
|
||||
assertThat(interval.isValid()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_BeAValidIntervall_when_BeginAndEndAreEqual() {
|
||||
IntInterval interval = new IntInterval(1, 1);
|
||||
assertThat(interval.isValid()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_NotBeAValidIntervall_when_BeginIsAfterEnd() {
|
||||
IntInterval interval = new IntInterval(2, 1);
|
||||
assertThat(interval.isValid()).isFalse();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {1, 2, 3})
|
||||
void should_ContainIntegerInIntervall_when_BeginIsOneAndEndIsThree(int number) {
|
||||
IntInterval interval = new IntInterval(1, 3);
|
||||
assertThat(interval.contains(number)).isTrue();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, 4})
|
||||
void should_NotContainIntegerInIntervall_when_BeginIsOneAndEndIsThree(int number) {
|
||||
IntInterval interval = new IntInterval(1, 3);
|
||||
assertThat(interval.contains(number)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_TwoIntervallsAreEqual_when_BothHaveSameBeginAndEnd() {
|
||||
IntInterval interval1 = new IntInterval(1, 2);
|
||||
IntInterval interval2 = new IntInterval(1, 2);
|
||||
|
||||
assertThat(interval1).isEqualTo(interval2);
|
||||
assertThat(interval2).isEqualTo(interval1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_TwoIntervallsAreNotEqual_when_BeginAndEndAreDifferent() {
|
||||
IntInterval interval1 = new IntInterval(1, 2);
|
||||
IntInterval interval2 = new IntInterval(1, 3);
|
||||
|
||||
assertThat(interval1).isNotEqualTo(interval2);
|
||||
assertThat(interval2).isNotEqualTo(interval1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package pro.taskana.common.api;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class TimeIntervalTest {
|
||||
|
||||
private static final ZoneId UTC = ZoneId.of("UTC");
|
||||
private final Instant date1 = LocalDate.of(2023, 2, 10).atStartOfDay(UTC).toInstant();
|
||||
private final Instant date2 = LocalDate.of(2023, 2, 13).atStartOfDay(UTC).toInstant();
|
||||
|
||||
@Test
|
||||
void should_BeAValidIntervall_when_BeginIsBeforEnd() {
|
||||
TimeInterval timeInterval = new TimeInterval(date1, date2);
|
||||
|
||||
assertThat(timeInterval.isValid()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_BeAValidIntervall_when_BeginAndEndAreEqual() {
|
||||
TimeInterval timeInterval = new TimeInterval(date1, date1);
|
||||
|
||||
assertThat(timeInterval.isValid()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_NotBeAValidIntervall_when_BeginIsAfterEnd() {
|
||||
TimeInterval timeInterval = new TimeInterval(date2, date1);
|
||||
|
||||
assertThat(timeInterval.isValid()).isFalse();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {10, 11, 12, 13})
|
||||
void should_ContainDateInIntervall(int day) {
|
||||
TimeInterval timeInterval = new TimeInterval(date1, date2);
|
||||
|
||||
Instant actualInstant = LocalDate.of(2023, 2, day).atStartOfDay(UTC).toInstant();
|
||||
|
||||
assertThat(timeInterval.contains(actualInstant)).isTrue();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {8, 9, 14, 15})
|
||||
void should_NotContainDateInIntervall_when_InstantIsBeforeOrAfter(int day) {
|
||||
TimeInterval timeInterval = new TimeInterval(date1, date2);
|
||||
|
||||
Instant actualInstant = LocalDate.of(2023, 2, day).atStartOfDay(UTC).toInstant();
|
||||
|
||||
assertThat(timeInterval.contains(actualInstant)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_TwoIntervallsAreEqual_when_BothHaveSameBeginAndEnd() {
|
||||
TimeInterval timeInterval1 = new TimeInterval(date1, date2);
|
||||
TimeInterval timeInterval2 = new TimeInterval(date1, date2);
|
||||
|
||||
assertThat(timeInterval1).isEqualTo(timeInterval2);
|
||||
assertThat(timeInterval2).isEqualTo(timeInterval1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_TwoIntervallsAreNotEqual_when_BeginAndEndAreDifferent() {
|
||||
TimeInterval timeInterval1 = new TimeInterval(date1, date2);
|
||||
TimeInterval timeInterval2 =
|
||||
new TimeInterval(date1, LocalDate.of(2023, 2, 14).atStartOfDay(UTC).toInstant());
|
||||
|
||||
assertThat(timeInterval1).isNotEqualTo(timeInterval2);
|
||||
assertThat(timeInterval2).isNotEqualTo(timeInterval1);
|
||||
}
|
||||
}
|
|
@ -66,6 +66,7 @@ import pro.taskana.common.api.exceptions.ErrorCode;
|
|||
import pro.taskana.common.api.exceptions.TaskanaException;
|
||||
import pro.taskana.common.api.exceptions.TaskanaRuntimeException;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.Interval;
|
||||
import pro.taskana.common.internal.logging.LoggingAspect;
|
||||
import pro.taskana.common.internal.util.MapCreator;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
|
@ -214,6 +215,8 @@ class ArchitectureTest {
|
|||
.resideInAPackage("..api..")
|
||||
.and()
|
||||
.areNotAssignableFrom(TaskanaEngine.class)
|
||||
.and()
|
||||
.areNotAssignableTo(Interval.class)
|
||||
.should()
|
||||
.onlyDependOnClassesThat(
|
||||
resideOutsideOfPackage("..pro.taskana..internal..")
|
||||
|
|
Loading…
Reference in New Issue