Skip to content

Commit 096d9b3

Browse files
committed
Add tests for every combination of cases
1 parent 2f0b404 commit 096d9b3

File tree

1 file changed

+77
-42
lines changed
  • x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/date

1 file changed

+77
-42
lines changed

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTruncTests.java

Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import org.elasticsearch.common.time.DateUtils;
1414
import org.elasticsearch.core.Nullable;
15+
import org.elasticsearch.core.Tuple;
1516
import org.elasticsearch.xpack.esql.core.expression.Expression;
1617
import org.elasticsearch.xpack.esql.core.tree.Source;
1718
import org.elasticsearch.xpack.esql.core.type.DataType;
@@ -22,11 +23,13 @@
2223

2324
import java.time.Duration;
2425
import java.time.Instant;
26+
import java.time.LocalDateTime;
2527
import java.time.Period;
2628
import java.time.ZoneId;
2729
import java.util.ArrayList;
2830
import java.util.List;
2931
import java.util.function.Supplier;
32+
import java.util.stream.Stream;
3033

3134
import static org.elasticsearch.test.ReadableMatchers.matchesDateMillis;
3235
import static org.elasticsearch.test.ReadableMatchers.matchesDateNanos;
@@ -150,52 +153,84 @@ public static List<DurationTestCaseData> makeTruncDurationTestCases() {
150153
}
151154

152155
public static List<PeriodTestCaseData> makeTruncPeriodTestCases() {
153-
String ts = "2023-02-17T10:25:33.38Z";
154-
return List.of(
155-
///
156-
/// UTC
157-
///
158-
new PeriodTestCaseData(Period.ofDays(1), ts, "UTC", "2023-02-17T00:00:00.00Z"),
159-
new PeriodTestCaseData(Period.ofMonths(1), ts, "UTC", "2023-02-01T00:00:00.00Z"),
160-
new PeriodTestCaseData(Period.ofYears(1), ts, "UTC", "2023-01-01T00:00:00.00Z"),
161-
new PeriodTestCaseData(Period.ofDays(10), ts, "UTC", "2023-02-12T00:00:00.00Z"),
162-
// 7 days period should return weekly rounding
163-
new PeriodTestCaseData(Period.ofDays(7), ts, "UTC", "2023-02-13T00:00:00.00Z"),
164-
// 3 months period should return quarterly
165-
new PeriodTestCaseData(Period.ofMonths(3), ts, "UTC", "2023-01-01T00:00:00.00Z"),
166-
// arbitrary period of months and years
167-
new PeriodTestCaseData(Period.ofMonths(7), ts, "UTC", "2022-11-01T00:00:00.00Z"),
168-
new PeriodTestCaseData(Period.ofYears(5), ts, "UTC", "2021-01-01T00:00:00.00Z"),
169-
170-
///
171-
/// Timezones
172-
///
173-
new PeriodTestCaseData(Period.ofDays(1), "2024-03-01T00:30:00Z", "-03", "2024-02-29T03:00:00Z"),
156+
List<PeriodTestCaseData> cases = new ArrayList<>();
157+
158+
// Add generic cases for either UTC, fixed timezones and timezones with minutes.
159+
// Note that we can't do this with variable timezones, as date formats accept only offsets.
160+
//
161+
// For every unit, we test 2 cases: 1 unit, and multiple units.
162+
// Then, for every case, we check 4 boundaries (↑Bucket1, ↓Bucket2, ↑Bucket2, ↓Bucket3) to ensure the exact size of the buckets.
163+
final List<String> timezones = List.of("Z", "-08:00", "+04:00", "+11:45", "Europe/Madrid", "America/New_York");
164+
Stream.of(
165+
// Days
166+
new PeriodTestCaseData(Period.ofDays(1), "2023-02-16T23:59:59.99", "", "2023-02-16T00:00:00"),
167+
new PeriodTestCaseData(Period.ofDays(1), "2023-02-17T00:00:00", "", "2023-02-17T00:00:00"),
168+
new PeriodTestCaseData(Period.ofDays(1), "2023-02-17T23:59:59.99", "", "2023-02-17T00:00:00"),
169+
new PeriodTestCaseData(Period.ofDays(1), "2023-02-18T00:00:00", "", "2023-02-18T00:00:00"),
170+
new PeriodTestCaseData(Period.ofDays(10), "2023-02-11T23:59:59.99", "", "2023-02-02T00:00:00"),
171+
new PeriodTestCaseData(Period.ofDays(10), "2023-02-12T00:00:00", "", "2023-02-12T00:00:00"),
172+
new PeriodTestCaseData(Period.ofDays(10), "2023-02-21T23:59:59.99", "", "2023-02-12T00:00:00"),
173+
new PeriodTestCaseData(Period.ofDays(10), "2023-02-22T00:00:00", "", "2023-02-22T00:00:00"),
174+
// Weeks
175+
new PeriodTestCaseData(Period.ofDays(7), "2023-02-05T23:59:59.99", "", "2023-01-30T00:00:00"),
176+
new PeriodTestCaseData(Period.ofDays(7), "2023-02-06T00:00:00", "", "2023-02-06T00:00:00"),
177+
new PeriodTestCaseData(Period.ofDays(7), "2023-02-12T23:59:59.99", "", "2023-02-06T00:00:00"),
178+
new PeriodTestCaseData(Period.ofDays(7), "2023-02-13T00:00:00", "", "2023-02-13T00:00:00"),
179+
new PeriodTestCaseData(Period.ofDays(21), "2023-01-25T23:59:59.99", "", "2023-01-05T00:00:00"),
180+
new PeriodTestCaseData(Period.ofDays(21), "2023-01-26T00:00:00", "", "2023-01-26T00:00:00"),
181+
new PeriodTestCaseData(Period.ofDays(21), "2023-02-15T23:59:59.99", "", "2023-01-26T00:00:00"),
182+
new PeriodTestCaseData(Period.ofDays(21), "2023-02-16T00:00:00", "", "2023-02-16T00:00:00"),
183+
// Months
184+
new PeriodTestCaseData(Period.ofMonths(1), "2024-02-29T23:59:59.99", "", "2024-02-01T00:00:00"),
185+
new PeriodTestCaseData(Period.ofMonths(1), "2024-03-01T00:00:00", "", "2024-03-01T00:00:00"),
186+
new PeriodTestCaseData(Period.ofMonths(1), "2024-03-31T23:59:59.99", "", "2024-03-01T00:00:00"),
187+
new PeriodTestCaseData(Period.ofMonths(1), "2024-04-01T00:00:00", "", "2024-04-01T00:00:00"),
188+
new PeriodTestCaseData(Period.ofMonths(7), "2022-10-31T23:59:59.99", "", "2022-04-01T00:00:00"),
189+
new PeriodTestCaseData(Period.ofMonths(7), "2022-11-01T00:00:00", "", "2022-11-01T00:00:00"),
190+
new PeriodTestCaseData(Period.ofMonths(7), "2023-05-31T23:59:59.99", "", "2022-11-01T00:00:00"),
191+
new PeriodTestCaseData(Period.ofMonths(7), "2023-06-01T00:00:00", "", "2023-06-01T00:00:00"),
192+
// Quarters
193+
new PeriodTestCaseData(Period.ofMonths(3), "2023-12-31T23:59:59.99", "", "2023-10-01T00:00:00"),
194+
new PeriodTestCaseData(Period.ofMonths(3), "2024-01-01T00:00:00", "", "2024-01-01T00:00:00"),
195+
new PeriodTestCaseData(Period.ofMonths(3), "2024-03-31T23:59:59.99", "", "2024-01-01T00:00:00"),
196+
new PeriodTestCaseData(Period.ofMonths(3), "2024-04-01T00:00:00", "", "2024-04-01T00:00:00"),
197+
new PeriodTestCaseData(Period.ofMonths(6), "2023-12-31T23:59:59.99", "", "2023-07-01T00:00:00"),
198+
new PeriodTestCaseData(Period.ofMonths(6), "2024-01-01T00:00:00", "", "2024-01-01T00:00:00"),
199+
new PeriodTestCaseData(Period.ofMonths(6), "2024-06-30T23:59:59.99", "", "2024-01-01T00:00:00"),
200+
new PeriodTestCaseData(Period.ofMonths(6), "2024-07-01T00:00:00", "", "2024-07-01T00:00:00"),
201+
// Years
202+
new PeriodTestCaseData(Period.ofYears(1), "2022-12-31T23:59:59.99", "", "2022-01-01T00:00:00"),
203+
new PeriodTestCaseData(Period.ofYears(1), "2023-01-01T00:00:00", "", "2023-01-01T00:00:00"),
204+
new PeriodTestCaseData(Period.ofYears(1), "2023-12-31T23:59:59.99", "", "2023-01-01T00:00:00"),
205+
new PeriodTestCaseData(Period.ofYears(1), "2024-01-01T00:00:00", "", "2024-01-01T00:00:00"),
206+
new PeriodTestCaseData(Period.ofYears(5), "2020-12-31T23:59:59.99", "", "2016-01-01T00:00:00"),
207+
new PeriodTestCaseData(Period.ofYears(5), "2021-01-01T00:00:00", "", "2021-01-01T00:00:00"),
208+
new PeriodTestCaseData(Period.ofYears(5), "2025-12-31T23:59:59.99", "", "2021-01-01T00:00:00"),
209+
new PeriodTestCaseData(Period.ofYears(5), "2026-01-01T00:00:00", "", "2026-01-01T00:00:00")
210+
).forEach(c -> timezones.forEach(timezone -> {
211+
// Convert the timezone to the offset in each local time.
212+
// This is required as date strings can't have a zone name as its zone.
213+
var inputOffset = timezone.startsWith("+") || timezone.startsWith("-")
214+
? timezone
215+
: LocalDateTime.parse(c.inputDate()).atZone(ZoneId.of(timezone)).getOffset().getId();
216+
var expectedOffset = timezone.startsWith("+") || timezone.startsWith("-")
217+
? timezone
218+
: LocalDateTime.parse(c.expectedDate()).atZone(ZoneId.of(timezone)).getOffset().getId();
219+
cases.add(
220+
new PeriodTestCaseData(c.period(), c.inputDate() + inputOffset, timezone, c.expectedDate() + expectedOffset)
221+
);
222+
}));
174223

224+
// Special cases
225+
cases.addAll(List.of(
175226
///
176-
/// Timezone with DST (e.g. New York: -5 to -4 at 2025-03-09T02:00:00-05, and -4 to -5 at 2025-11-02T02:00:00-04)
227+
/// DST boundaries (e.g. New York: -5 to -4 at 2025-03-09T02:00:00-05, and -4 to -5 at 2025-11-02T02:00:00-04)
177228
///
229+
// Days
178230
new PeriodTestCaseData(Period.ofDays(1), "2025-03-09T06:00:00-04:00", "America/New_York", "2025-03-09T00:00:00-05:00"),
179-
new PeriodTestCaseData(Period.ofMonths(1), "2025-03-09T06:00:00-04:00", "America/New_York", "2025-03-01T00:00:00-05:00"),
180-
new PeriodTestCaseData(Period.ofYears(1), "2025-03-09T06:00:00-04:00", "America/New_York", "2025-01-01T00:00:00-05:00"),
181-
new PeriodTestCaseData(Period.ofDays(10), "2025-03-09T06:00:00-04:00", "America/New_York", "2025-03-03T00:00:00-05:00"),
182-
new PeriodTestCaseData(Period.ofDays(1), "2025-11-02T05:00:00-05:00", "America/New_York", "2025-11-02T00:00:00-04:00"),
183-
new PeriodTestCaseData(Period.ofDays(7), "2025-11-02T05:00:00-05:00", "America/New_York", "2025-10-27T00:00:00-04:00"),
184-
new PeriodTestCaseData(Period.ofMonths(3), "2025-11-02T05:00:00-05:00", "America/New_York", "2025-10-01T00:00:00-04:00"),
185-
new PeriodTestCaseData(Period.ofDays(1), "2025-10-26T02:00:00+02:00", "Europe/Rome", "2025-10-26T00:00:00+02:00"),
186-
new PeriodTestCaseData(Period.ofMonths(3), "2025-11-02T05:00:00-05:00", "Europe/Rome", "2025-10-01T00:00:00-04:00"),
187-
188-
///
189-
/// Partial hours timezones
190-
///
191-
new PeriodTestCaseData(Period.ofDays(1), "2025-03-09T07:08:09-05:45", "-05:45", "2025-03-09T00:00:00-05:45"),
192-
new PeriodTestCaseData(Period.ofMonths(1), "2025-03-09T07:08:09-05:45", "-05:45", "2025-03-01T00:00:00-05:45"),
193-
new PeriodTestCaseData(Period.ofYears(1), "2025-03-09T07:08:09-05:45", "-05:45", "2025-01-01T00:00:00-05:45"),
194-
new PeriodTestCaseData(Period.ofDays(10), "2025-03-09T07:08:09-05:45", "-05:45", "2025-03-03T00:00:00-05:45"),
195-
new PeriodTestCaseData(Period.ofDays(1), "2025-03-09T07:08:09-05:45", "-05:45", "2025-03-09T00:00:00-05:45"),
196-
new PeriodTestCaseData(Period.ofDays(7), "2025-03-09T07:08:09-05:45", "-05:45", "2025-03-03T00:00:00-05:45"),
197-
new PeriodTestCaseData(Period.ofMonths(3), "2025-03-09T07:08:09-05:45", "-05:45", "2025-01-01T00:00:00-05:45")
198-
);
231+
new PeriodTestCaseData(Period.ofDays(1), "2025-11-02T05:00:00-05:00", "America/New_York", "2025-11-02T00:00:00-04:00")
232+
));
233+
return cases;
199234
}
200235

201236
private static List<TestCaseSupplier> ofDatePeriod(PeriodTestCaseData data) {

0 commit comments

Comments
 (0)