Skip to content

Commit 5d3b32d

Browse files
committed
Randomized ITs for temporal types
1 parent 740e4a4 commit 5d3b32d

File tree

2 files changed

+195
-3
lines changed

2 files changed

+195
-3
lines changed

driver/src/test/java/org/neo4j/driver/v1/integration/TemporalTypesIT.java

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,26 @@
2929
import java.time.ZoneId;
3030
import java.time.ZoneOffset;
3131
import java.time.ZonedDateTime;
32-
import java.util.function.Function;
32+
import java.util.function.Supplier;
3333

3434
import org.neo4j.driver.v1.Record;
3535
import org.neo4j.driver.v1.Value;
36-
import org.neo4j.driver.v1.Values;
3736
import org.neo4j.driver.v1.types.Duration;
37+
import org.neo4j.driver.v1.util.Function;
38+
import org.neo4j.driver.v1.util.TemporalUtil;
3839
import org.neo4j.driver.v1.util.TestNeo4jSession;
3940

4041
import static java.time.Month.MARCH;
4142
import static java.util.Collections.singletonMap;
4243
import static org.junit.Assert.assertEquals;
4344
import static org.junit.Assume.assumeTrue;
4445
import static org.neo4j.driver.internal.util.ServerVersion.v3_4_0;
46+
import static org.neo4j.driver.v1.Values.duration;
4547

4648
public class TemporalTypesIT
4749
{
50+
private static final int RANDOM_VALUES_TO_TEST = 1_000;
51+
4852
@Rule
4953
public final TestNeo4jSession session = new TestNeo4jSession();
5054

@@ -74,6 +78,12 @@ public void shouldSendAndReceiveDate()
7478
testSendAndReceiveValue( LocalDate.now(), Value::asLocalDate );
7579
}
7680

81+
@Test
82+
public void shouldSendAndReceiveRandomDate()
83+
{
84+
testSendAndReceiveRandomValues( TemporalUtil::randomLocalDate, Value::asLocalDate );
85+
}
86+
7787
@Test
7888
public void shouldSendTime()
7989
{
@@ -94,6 +104,12 @@ public void shouldSendAndReceiveTime()
94104
testSendAndReceiveValue( OffsetTime.now(), Value::asOffsetTime );
95105
}
96106

107+
@Test
108+
public void shouldSendAndReceiveRandomTime()
109+
{
110+
testSendAndReceiveRandomValues( TemporalUtil::randomOffsetTime, Value::asOffsetTime );
111+
}
112+
97113
@Test
98114
public void shouldSendLocalTime()
99115
{
@@ -114,6 +130,12 @@ public void shouldSendAndReceiveLocalTime()
114130
testSendAndReceiveValue( LocalTime.now(), Value::asLocalTime );
115131
}
116132

133+
@Test
134+
public void shouldSendAndReceiveRandomLocalTime()
135+
{
136+
testSendAndReceiveRandomValues( TemporalUtil::randomLocalTime, Value::asLocalTime );
137+
}
138+
117139
@Test
118140
public void shouldSendLocalDateTime()
119141
{
@@ -134,6 +156,12 @@ public void shouldSendAndReceiveLocalDateTime()
134156
testSendAndReceiveValue( LocalDateTime.now(), Value::asLocalDateTime );
135157
}
136158

159+
@Test
160+
public void shouldSendAndReceiveRandomLocalDateTime()
161+
{
162+
testSendAndReceiveRandomValues( TemporalUtil::randomLocalDateTime, Value::asLocalDateTime );
163+
}
164+
137165
@Test
138166
public void shouldSendDateTimeWithZoneOffset()
139167
{
@@ -157,6 +185,12 @@ public void shouldSendAndReceiveDateTimeWithZoneOffset()
157185
testSendAndReceiveValue( ZonedDateTime.of( 2017, 3, 9, 11, 12, 13, 14, offset ), Value::asZonedDateTime );
158186
}
159187

188+
@Test
189+
public void shouldSendAndReceiveRandomDateTimeWithZoneOffset()
190+
{
191+
testSendAndReceiveRandomValues( TemporalUtil::randomZonedDateTimeWithOffset, Value::asZonedDateTime );
192+
}
193+
160194
@Test
161195
public void shouldSendDateTimeWithZoneId()
162196
{
@@ -180,6 +214,12 @@ public void shouldSendAndReceiveDateTimeWithZoneId()
180214
testSendAndReceiveValue( ZonedDateTime.of( 2099, 12, 29, 12, 59, 59, 59, zoneId ), Value::asZonedDateTime );
181215
}
182216

217+
@Test
218+
public void shouldSendAndReceiveRandomDateTimeWithZoneId()
219+
{
220+
testSendAndReceiveRandomValues( TemporalUtil::randomZonedDateTimeWithZoneId, Value::asZonedDateTime );
221+
}
222+
183223
@Test
184224
public void shouldSendDuration()
185225
{
@@ -200,6 +240,20 @@ public void shouldSendAndReceiveDuration()
200240
testSendAndReceiveValue( newDuration( 7, 7, 88, 999_999 ), Value::asDuration );
201241
}
202242

243+
@Test
244+
public void shouldSendAndReceiveRandomDuration()
245+
{
246+
testSendAndReceiveRandomValues( TemporalUtil::randomDuration, Value::asDuration );
247+
}
248+
249+
private <T> void testSendAndReceiveRandomValues( Supplier<T> supplier, Function<Value,T> converter )
250+
{
251+
for ( int i = 0; i < RANDOM_VALUES_TO_TEST; i++ )
252+
{
253+
testSendAndReceiveValue( supplier.get(), converter );
254+
}
255+
}
256+
203257
private <T> void testSendValue( T value, Function<Value,T> converter )
204258
{
205259
Record record1 = session.run( "CREATE (n:Node {value: $value}) RETURN 42", singletonMap( "value", value ) ).single();
@@ -223,6 +277,6 @@ private <T> void testSendAndReceiveValue( T value, Function<Value,T> converter )
223277

224278
private static Duration newDuration( long months, long days, long seconds, long nanoseconds )
225279
{
226-
return Values.duration( months, days, seconds, nanoseconds ).asDuration();
280+
return duration( months, days, seconds, nanoseconds ).asDuration();
227281
}
228282
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (c) 2002-2018 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.v1.util;
20+
21+
import java.time.LocalDate;
22+
import java.time.LocalDateTime;
23+
import java.time.LocalTime;
24+
import java.time.OffsetTime;
25+
import java.time.ZoneId;
26+
import java.time.ZoneOffset;
27+
import java.time.ZonedDateTime;
28+
import java.time.temporal.ChronoField;
29+
import java.time.temporal.ValueRange;
30+
import java.util.Set;
31+
import java.util.concurrent.ThreadLocalRandom;
32+
33+
import org.neo4j.driver.internal.InternalDuration;
34+
import org.neo4j.driver.v1.types.Duration;
35+
36+
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
37+
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
38+
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
39+
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
40+
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
41+
import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
42+
import static java.time.temporal.ChronoField.YEAR;
43+
44+
public final class TemporalUtil
45+
{
46+
private TemporalUtil()
47+
{
48+
}
49+
50+
public static LocalDate randomLocalDate()
51+
{
52+
return LocalDate.of( random( YEAR ), random( MONTH_OF_YEAR ), random( DAY_OF_MONTH ) );
53+
}
54+
55+
public static OffsetTime randomOffsetTime()
56+
{
57+
ZoneOffset offset = randomZoneOffset();
58+
return OffsetTime.of( random( HOUR_OF_DAY ), random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ), offset );
59+
}
60+
61+
public static LocalTime randomLocalTime()
62+
{
63+
return LocalTime.of( random( HOUR_OF_DAY ), random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ) );
64+
}
65+
66+
public static LocalDateTime randomLocalDateTime()
67+
{
68+
return LocalDateTime.of( random( YEAR ), random( MONTH_OF_YEAR ), random( DAY_OF_MONTH ), random( HOUR_OF_DAY ),
69+
random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ) );
70+
}
71+
72+
public static ZonedDateTime randomZonedDateTimeWithOffset()
73+
{
74+
return randomZonedDateTime( randomZoneOffset() );
75+
}
76+
77+
public static ZonedDateTime randomZonedDateTimeWithZoneId()
78+
{
79+
return randomZonedDateTime( randomZoneId() );
80+
}
81+
82+
public static Duration randomDuration()
83+
{
84+
int sign = random().nextBoolean() ? 1 : -1; // duration can be negative
85+
return new InternalDuration( sign * randomInt(), sign * randomInt(), sign * randomInt(), sign * Math.abs( random( NANO_OF_SECOND ) ) );
86+
}
87+
88+
private static ZonedDateTime randomZonedDateTime( ZoneId zoneId )
89+
{
90+
return ZonedDateTime.of( random( YEAR ), random( MONTH_OF_YEAR ), random( DAY_OF_MONTH ), random( HOUR_OF_DAY ),
91+
random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ), zoneId );
92+
}
93+
94+
private static ZoneOffset randomZoneOffset()
95+
{
96+
int min = ZoneOffset.MIN.getTotalSeconds();
97+
int max = ZoneOffset.MAX.getTotalSeconds();
98+
return ZoneOffset.ofTotalSeconds( random().nextInt( min, max ) );
99+
}
100+
101+
private static ZoneId randomZoneId()
102+
{
103+
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
104+
int randomIndex = random().nextInt( availableZoneIds.size() );
105+
int index = 0;
106+
for ( String id : availableZoneIds )
107+
{
108+
if ( index == randomIndex )
109+
{
110+
return ZoneId.of( id );
111+
}
112+
else
113+
{
114+
index++;
115+
}
116+
}
117+
throw new AssertionError( "Unable to pick random ZoneId from the set of available ids: " + availableZoneIds );
118+
}
119+
120+
private static int random( ChronoField field )
121+
{
122+
ValueRange range = field.range();
123+
long min = range.getMinimum();
124+
long max = range.getSmallestMaximum();
125+
long value = random().nextLong( min, max );
126+
return Math.toIntExact( value );
127+
}
128+
129+
private static int randomInt()
130+
{
131+
return random().nextInt( 0, Integer.MAX_VALUE );
132+
}
133+
134+
private static ThreadLocalRandom random()
135+
{
136+
return ThreadLocalRandom.current();
137+
}
138+
}

0 commit comments

Comments
 (0)