Skip to content
This repository was archived by the owner on Aug 13, 2020. It is now read-only.

Commit 5d233a9

Browse files
authored
Merge pull request #200 from sibyg/sibyg
Add local date converter, expose register() on enveloper, add random generators
2 parents 9bfbb19 + f2e9abf commit 5d233a9

File tree

18 files changed

+470
-1
lines changed

18 files changed

+470
-1
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package uk.gov.justice.services.common.converter;
2+
3+
import java.time.LocalDate;
4+
import java.time.format.DateTimeFormatter;
5+
6+
/**
7+
* Utility functions for converting to and from {@link LocalDate} objects
8+
* and ISO date format String such as '2011-12-03'
9+
*/
10+
public final class LocalDates {
11+
12+
private static DateTimeFormatter FORMAT = DateTimeFormatter.ISO_DATE;
13+
14+
/**
15+
* Private constructor to avoid misuse of utility class.
16+
*/
17+
private LocalDates() {
18+
}
19+
20+
/**
21+
* Parses a string in ISO date format such as '2011-12-03' to create a {@link LocalDate} object
22+
*
23+
* @param source the @link LocalDate} as a string in ISO_DATE format
24+
* @return LocalDate object
25+
*/
26+
public static LocalDate from(final String source) {
27+
return LocalDate.parse(source, FORMAT);
28+
}
29+
30+
/**
31+
* Format a {@link LocalDate} object to ISO date format string such as '2011-12-03'
32+
*
33+
* @param source the date time
34+
* @return the date time as a string
35+
*/
36+
public static String to(final LocalDate source) {
37+
return source.format(FORMAT);
38+
}
39+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package uk.gov.justice.services.common.converter;
2+
3+
import org.hamcrest.Description;
4+
import org.hamcrest.Matcher;
5+
import org.hamcrest.TypeSafeDiagnosingMatcher;
6+
import org.junit.Test;
7+
8+
import java.time.LocalDate;
9+
10+
import static java.lang.String.format;
11+
import static net.trajano.commons.testing.UtilityClassTestUtil.assertUtilityClassWellDefined;
12+
import static org.hamcrest.MatcherAssert.assertThat;
13+
14+
/**
15+
* Unit tests for the {@link LocalDates} utility class.
16+
*/
17+
public class LocalDatesTest {
18+
19+
@Test
20+
public void shouldBeWellDefinedUtilityClass() {
21+
assertUtilityClassWellDefined(LocalDates.class);
22+
}
23+
24+
@Test
25+
public void shouldConvertStringToLocalDate() {
26+
// given
27+
int year = 2016;
28+
// and
29+
int month = 11;
30+
// and
31+
int dayOfMonth = 21;
32+
// and
33+
String localDateStr = format("%d-%02d-%d", year, month, dayOfMonth);
34+
35+
// when
36+
final LocalDate localDate = LocalDates.from(localDateStr);
37+
38+
// then
39+
assertThat(localDate, has(year, month, dayOfMonth));
40+
41+
}
42+
43+
private Matcher<LocalDate> has(final int year, final int month, final int dayOfMonth) {
44+
return new TypeSafeDiagnosingMatcher<LocalDate>() {
45+
46+
@Override
47+
public void describeTo(Description description) {
48+
description.appendText("from() should return ").appendValue(format("%d-%d-%d", year, month, dayOfMonth));
49+
}
50+
51+
@Override
52+
protected boolean matchesSafely(LocalDate localDate, Description description) {
53+
boolean status = true;
54+
if (localDate.getYear() != year) {
55+
description.appendText(format("Year Mismatch, Actual:%d, Expected:%s", localDate.getYear(), year));
56+
status = false;
57+
}
58+
if (localDate.getMonth().getValue() != month) {
59+
description.appendText(format(" Month Mismatch, Actual:%d, Expected:%s", localDate.getMonth().getValue(), month));
60+
status = false;
61+
}
62+
if (localDate.getDayOfMonth() != dayOfMonth) {
63+
description.appendText(format(" Day Of Month Mismatch, Actual:%d, Expected:%s", localDate.getDayOfMonth(), dayOfMonth));
64+
status = false;
65+
}
66+
return status;
67+
}
68+
};
69+
}
70+
71+
@Test
72+
public void shouldConvertLocalDateToString() {
73+
// given
74+
LocalDate localDate = LocalDate.now();
75+
76+
// when
77+
String str = LocalDates.to(localDate);
78+
79+
// then
80+
assertThat(str, isFrom(localDate));
81+
}
82+
83+
private Matcher<String> isFrom(final LocalDate localDate) {
84+
return new TypeSafeDiagnosingMatcher<String>() {
85+
86+
@Override
87+
public void describeTo(Description description) {
88+
description.appendText("to() should return LocalDate:").appendValue(localDate);
89+
}
90+
91+
@Override
92+
protected boolean matchesSafely(String str, Description description) {
93+
boolean status = true;
94+
String[] tokens = str.split("-");
95+
96+
if (tokens.length != 3) {
97+
description.appendText("Unformatted string");
98+
return false;
99+
}
100+
101+
102+
if (Integer.valueOf(tokens[0]) != localDate.getYear()) {
103+
description.appendText(format("Year Mismatch, Actual:%s, Expected:%d", tokens[0], localDate.getYear()));
104+
status = false;
105+
}
106+
if (Integer.valueOf(tokens[1]) != localDate.getMonth().getValue()) {
107+
description.appendText(format(" Month Mismatch, Actual:%s, Expected:%02d", tokens[1], localDate.getMonth().getValue()));
108+
status = false;
109+
}
110+
if (Integer.valueOf(tokens[2]) != localDate.getDayOfMonth()) {
111+
description.appendText(format(" Day Of Month Mismatch, Actual:%s, Expected:%d", tokens[2], localDate.getDayOfMonth()));
112+
status = false;
113+
}
114+
return status;
115+
}
116+
};
117+
}
118+
}

core/src/main/java/uk/gov/justice/services/core/enveloper/Enveloper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public Enveloper(final ObjectToJsonValueConverter objectToJsonValueConverter) {
5656
*
5757
* @param event identified by the framework to be registered into the event map.
5858
*/
59-
void register(@Observes final EventFoundEvent event) {
59+
public void register(@Observes final EventFoundEvent event) {
6060
eventMap.putIfAbsent(event.getClazz(), event.getEventName());
6161
}
6262

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package uk.gov.justice.services.test.utils.core.random;
2+
3+
import java.math.BigDecimal;
4+
5+
import static java.lang.Math.pow;
6+
import static java.math.RoundingMode.FLOOR;
7+
8+
public class BigDecimalGenerator extends Generator<BigDecimal> {
9+
10+
private final Integer max;
11+
private final Integer decimalPlaces;
12+
13+
public BigDecimalGenerator(final Integer max, final Integer decimalPlaces) {
14+
this.max = max;
15+
this.decimalPlaces = decimalPlaces;
16+
}
17+
18+
@Override
19+
public BigDecimal next() {
20+
final double pow = pow(10, decimalPlaces);
21+
return new BigDecimal((long) RANDOM.nextInt((int) (max * pow)) / pow).setScale(decimalPlaces, FLOOR);
22+
}
23+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package uk.gov.justice.services.test.utils.core.random;
2+
3+
public class BooleanGenerator extends Generator<Boolean> {
4+
@Override
5+
public Boolean next() {
6+
return RANDOM.nextBoolean();
7+
}
8+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package uk.gov.justice.services.test.utils.core.random;
2+
3+
import static java.lang.Math.pow;
4+
5+
class DoubleGenerator extends Generator<Double> {
6+
7+
private final Integer max;
8+
private final Integer decimalPlaces;
9+
10+
public DoubleGenerator(final Integer max, final Integer decimalPlaces) {
11+
this.max = max;
12+
this.decimalPlaces = decimalPlaces;
13+
}
14+
15+
@Override
16+
public Double next() {
17+
final double pow = pow(10, decimalPlaces);
18+
return (double) RANDOM.nextInt((int) (max * pow)) / pow;
19+
}
20+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package uk.gov.justice.services.test.utils.core.random;
2+
3+
import static java.lang.String.format;
4+
5+
public class EmailAddressGenerator extends Generator<String> {
6+
@Override
7+
public String next() {
8+
return format("%s@%s.%s", RandomGenerator.string(10).next(), RandomGenerator.string(10).next(), RandomGenerator.values("com", "co.uk", "gov.uk", "org", "net").next());
9+
}
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package uk.gov.justice.services.test.utils.core.random;
2+
3+
import java.util.Random;
4+
5+
/**
6+
* Provides template for random value generation
7+
* for a given type T
8+
* @param <T> random value of T will be generated by the implementing class
9+
*/
10+
public abstract class Generator<T> {
11+
final Random RANDOM = new java.util.Random();
12+
abstract T next();
13+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package uk.gov.justice.services.test.utils.core.random;
2+
3+
public class IntegerGenerator extends Generator<Integer> {
4+
5+
private final Integer max;
6+
7+
public IntegerGenerator(final Integer max) {
8+
this.max = max;
9+
}
10+
11+
@Override
12+
public Integer next() {
13+
return RANDOM.nextInt(max);
14+
}
15+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package uk.gov.justice.services.test.utils.core.random;
2+
3+
import java.time.LocalDate;
4+
import java.time.Period;
5+
import java.time.ZoneId;
6+
import java.time.ZonedDateTime;
7+
8+
import static java.time.Instant.ofEpochMilli;
9+
import static java.time.ZoneOffset.UTC;
10+
import static uk.gov.justice.services.test.utils.core.random.LocalDateGenerator.Direction.FORWARD;
11+
12+
public class LocalDateGenerator extends Generator<LocalDate> {
13+
private final LocalDate start;
14+
private final LocalDate end;
15+
private final Direction direction;
16+
17+
public LocalDateGenerator(final Period period, final LocalDate start, final Direction direction) {
18+
this.start = start;
19+
this.direction = direction;
20+
this.end = direction == FORWARD ? start.plus(period) : start.minus(period);
21+
}
22+
23+
@Override
24+
public LocalDate next() {
25+
final ZonedDateTime startZDT = start.atStartOfDay(UTC);
26+
final ZonedDateTime endZDT = end.atStartOfDay(UTC);
27+
final long startMillsecs = startZDT.toInstant().toEpochMilli();
28+
final long endMillisecs = endZDT.toInstant().toEpochMilli();
29+
30+
Long randomMillsecs;
31+
32+
if (direction == FORWARD) {
33+
randomMillsecs = RANDOM.longs(startMillsecs, endMillisecs).findFirst().getAsLong();
34+
} else {
35+
randomMillsecs = RANDOM.longs(endMillisecs, startMillsecs).findFirst().getAsLong();
36+
}
37+
38+
return ofEpochMilli(randomMillsecs).atZone(ZoneId.systemDefault()).toLocalDate();
39+
}
40+
41+
public static enum Direction {FORWARD, BACKWARD}
42+
}

0 commit comments

Comments
 (0)