From cc93a38fcf661b40e1d151b5dbe7ea897e3a4f8b Mon Sep 17 00:00:00 2001 From: Nate Clark Date: Fri, 2 Aug 2019 09:04:45 -0400 Subject: [PATCH 1/3] CronExpressionTest: Use assertEquals when possible Assert equals gives a more useful default error message upon failure so use that when possible instead of assertTrue. --- .../test/java/fc/cron/CronExpressionTest.java | 174 +++++++++--------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/java8/src/test/java/fc/cron/CronExpressionTest.java b/java8/src/test/java/fc/cron/CronExpressionTest.java index aba3946..7841d02 100644 --- a/java8/src/test/java/fc/cron/CronExpressionTest.java +++ b/java8/src/test/java/fc/cron/CronExpressionTest.java @@ -155,15 +155,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 1, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 2, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 2, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 2, 1, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 59, 59, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 14, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test(expected = IllegalArgumentException.class) @@ -177,23 +177,23 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 1, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 1, 3, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 1, 3, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 2, 3, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 59, 3, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 14, 0, 3, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 23, 59, 3, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 0, 0, 3, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 30, 23, 59, 3, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 1, 0, 0, 3, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -202,23 +202,23 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 5, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 5, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 20, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 20, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 35, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 35, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 50, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 50, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 1, 5, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); // if rolling over minute then reset second (cron rules - increment affects only values in own field) after = ZonedDateTime.of(2012, 4, 10, 13, 0, 50, 0, zoneId); @@ -236,15 +236,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 7, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 7, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 19, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 19, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 1, 7, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -253,23 +253,23 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 42, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 42, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 43, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 43, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 44, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 44, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 0, 45, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 0, 45, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 1, 42, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test(expected = IllegalArgumentException.class) @@ -288,11 +288,11 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 1, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 3, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 3, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 14, 3, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -301,19 +301,19 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 15, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 15, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 30, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 30, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 45, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 45, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 14, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -322,11 +322,11 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 13, 7, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 13, 7, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 13, 19, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -335,15 +335,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 1, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 11, 3, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 11, 3, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 3, 1, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 11, 3, 59, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 12, 3, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -352,23 +352,23 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 15, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 15, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 15, 1, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 15, 59, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 11, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 0, 1, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 11, 15, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 15, 1, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -377,15 +377,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 10, 19, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 19, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 10, 19, 1, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 10, 19, 59, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 7, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -400,7 +400,7 @@ public class CronExpressionTest { int count = 0; ZonedDateTime lastTime = tid; - while (tid.isBefore(slutt)){ + while (tid.isBefore(slutt)) { ZonedDateTime nextTime = cron.nextTimeAfter(tid); assertTrue(nextTime.isAfter(lastTime)); lastTime = nextTime; @@ -420,9 +420,9 @@ public class CronExpressionTest { // throws: Unsupported unit: Seconds // assertEquals(23, Duration.between(start.toLocalDate(), slutt.toLocalDate()).toHours()); - int count=0; + int count = 0; ZonedDateTime lastTime = tid; - while(tid.isBefore(slutt)){ + while (tid.isBefore(slutt)) { ZonedDateTime nextTime = cron.nextTimeAfter(tid); assertTrue(nextTime.isAfter(lastTime)); lastTime = nextTime; @@ -438,19 +438,19 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 5, 3, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 5, 3, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 3, 0, 1, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 5, 3, 0, 59, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 3, 1, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 5, 3, 23, 59, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 6, 3, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -459,18 +459,18 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 16, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 16, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 1, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 30, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 5, 1, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 16, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -479,19 +479,19 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 19, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 19, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 7, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 5, 7, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 19, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 5, 30, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 6, 7, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -500,11 +500,11 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 30, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 2, 12, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 2, 29, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -513,11 +513,11 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 10, 13, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 30 - 3, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 2, 12, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 2, 29 - 3, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -527,21 +527,21 @@ public class CronExpressionTest { // 9 - is weekday in may ZonedDateTime after = ZonedDateTime.of(2012, 5, 2, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 5, 9, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); // 9 - is weekday in may after = ZonedDateTime.of(2012, 5, 8, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); // 9 - saturday, friday closest weekday in june after = ZonedDateTime.of(2012, 5, 9, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 6, 8, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); // 9 - sunday, monday closest weekday in september after = ZonedDateTime.of(2012, 9, 1, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 9, 10, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test(expected = IllegalArgumentException.class) @@ -583,15 +583,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 2, 12, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 3, 1, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 3, 1, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 7, 1, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 7, 1, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 12, 1, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -600,15 +600,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 2, 12, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 3, 1, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 3, 1, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 7, 1, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 7, 1, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 12, 1, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test(expected = IllegalArgumentException.class) @@ -622,19 +622,19 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 1, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 4, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 4, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 12, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 18, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 18, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 25, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -643,19 +643,19 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 1, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 4, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 4, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 6, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 6, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 8, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 8, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 11, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -664,15 +664,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 1, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 2, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 2, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 6, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 6, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 8, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -681,15 +681,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 1, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 2, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 2, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 6, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 6, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 4, 8, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test @@ -698,15 +698,15 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 4, 1, 1, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2012, 4, 27, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 4, 27, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 5, 25, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 2, 6, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 2, 24, 0, 0, 0, 0, zoneId); - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); after = ZonedDateTime.of(2012, 2, 6, 0, 0, 0, 0, zoneId); expected = ZonedDateTime.of(2012, 2, 24, 0, 0, 0, 0, zoneId); @@ -794,7 +794,7 @@ public class CronExpressionTest { ZonedDateTime after = ZonedDateTime.of(2012, 3, 1, 0, 0, 0, 0, zoneId); ZonedDateTime expected = ZonedDateTime.of(2016, 2, 29, 0, 0, 0, 0, zoneId); // the default barrier is 4 years - so leap years are considered. - assertTrue(cronExpr.nextTimeAfter(after).equals(expected)); + assertEquals(expected, cronExpr.nextTimeAfter(after)); } @Test(expected = IllegalArgumentException.class) From 69828d01afefa773019513f08f1f9a75551bac38 Mon Sep 17 00:00:00 2001 From: Nate Clark Date: Fri, 2 Aug 2019 09:09:59 -0400 Subject: [PATCH 2/3] CronExpression.FieldPart use int rather than Integer It is more expensive to perform operations on Integer objects rather than primitive int. Since an object is not needed use the primitive instead. --- .../src/main/java/fc/cron/CronExpression.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/java8/src/main/java/fc/cron/CronExpression.java b/java8/src/main/java/fc/cron/CronExpression.java index 74e7698..a4abc3e 100644 --- a/java8/src/main/java/fc/cron/CronExpression.java +++ b/java8/src/main/java/fc/cron/CronExpression.java @@ -20,6 +20,7 @@ package fc.cron; import java.time.*; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; @@ -256,9 +257,14 @@ public class CronExpression { return getClass().getSimpleName() + "<" + expr + ">"; } - static class FieldPart { - private Integer from, to, increment; + static class FieldPart implements Comparable { + private int from = -1, to = -1, increment = -1; private String modifier, incrementModifier; + + @Override + public int compareTo(FieldPart o) { + return Integer.compare(from, o.from); + } } abstract static class BasicField { @@ -322,14 +328,15 @@ public class CronExpression { if (increment != null) { part.incrementModifier = incrementModifier; - part.increment = Integer.valueOf(increment); + part.increment = Integer.parseInt(increment); } validateRange(part); validatePart(part); parts.add(part); - } + + Collections.sort(parts); } protected void validatePart(FieldPart part) { @@ -341,10 +348,10 @@ public class CronExpression { } private void validateRange(FieldPart part) { - if ((part.from != null && part.from < fieldType.from) || (part.to != null && part.to > fieldType.to)) { + if ((part.from != -1 && part.from < fieldType.from) || (part.to != -1 && part.to > fieldType.to)) { throw new IllegalArgumentException(String.format("Invalid interval [%s-%s], must be %s<=_<=%s", part.from, part.to, fieldType.from, fieldType.to)); - } else if (part.from != null && part.to != null && part.from > part.to) { + } else if (part.from != -1 && part.to != -1 && part.from > part.to) { throw new IllegalArgumentException( String.format( "Invalid interval [%s-%s]. Rolling periods are not supported (ex. 5-1, only 1-5) since this won't give a deterministic result. Must be %s<=_<=%s", @@ -352,12 +359,12 @@ public class CronExpression { } } - protected Integer mapValue(String value) { - Integer idx; + protected int mapValue(String value) { + int idx; if (fieldType.names != null && (idx = fieldType.names.indexOf(value.toUpperCase(Locale.getDefault()))) >= 0) { - return idx + 1; + return idx + fieldType.from; } - return Integer.valueOf(value); + return Integer.parseInt(value); } protected boolean matches(int val, FieldPart part) { @@ -410,9 +417,9 @@ public class CronExpression { } @Override - protected Integer mapValue(String value) { + protected int mapValue(String value) { // Use 1-7 for weedays, but 0 will also represent sunday (linux practice) - return "0".equals(value) ? Integer.valueOf(7) : super.mapValue(value); + return "0".equals(value) ? 7 : super.mapValue(value); } @Override @@ -439,7 +446,7 @@ public class CronExpression { for (FieldPart part : parts) { if ("L".equals(part.modifier)) { YearMonth ym = YearMonth.of(dato.getYear(), dato.getMonth().getValue()); - return dato.getDayOfMonth() == (ym.lengthOfMonth() - (part.from == null ? 0 : part.from)); + return dato.getDayOfMonth() == (ym.lengthOfMonth() - (part.from == -1 ? 0 : part.from)); } else if ("W".equals(part.modifier)) { if (dato.getDayOfWeek().getValue() <= 5) { if (dato.getDayOfMonth() == part.from) { From 59d3f1134c3f1c61be3e02887f8453207197ce9e Mon Sep 17 00:00:00 2001 From: Nate Clark Date: Fri, 2 Aug 2019 10:02:56 -0400 Subject: [PATCH 3/3] CronExpression: Search from most to least significant field Searching for next time from least significant to most significant field can be very expensive if the next time stamp is significantly in the future. Instead match from most significant field down to least restarting the search if a match is not found for the current field. --- .../src/main/java/fc/cron/CronExpression.java | 249 +++++++++++++++--- 1 file changed, 206 insertions(+), 43 deletions(-) diff --git a/java8/src/main/java/fc/cron/CronExpression.java b/java8/src/main/java/fc/cron/CronExpression.java index a4abc3e..ad9d7a6 100644 --- a/java8/src/main/java/fc/cron/CronExpression.java +++ b/java8/src/main/java/fc/cron/CronExpression.java @@ -17,7 +17,11 @@ package fc.cron; * * Note: rewritten to standard Java 8 DateTime by zemiak (c) 2016 */ -import java.time.*; +import java.time.DayOfWeek; +import java.time.Duration; +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -129,9 +133,103 @@ import java.util.regex.Pattern; public class CronExpression { enum CronFieldType { - SECOND(0, 59, null), MINUTE(0, 59, null), HOUR(0, 23, null), DAY_OF_MONTH(1, 31, null), MONTH(1, 12, - Arrays.asList("JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC")), DAY_OF_WEEK(1, 7, - Arrays.asList("MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN")); + SECOND(0, 59, null) { + @Override + int getValue(ZonedDateTime dateTime) { + return dateTime.getSecond(); + } + + @Override + ZonedDateTime setValue(ZonedDateTime dateTime, int value) { + return dateTime.withSecond(value).withNano(0); + } + + @Override + ZonedDateTime overflow(ZonedDateTime dateTime) { + return dateTime.plusMinutes(1).withSecond(0).withNano(0); + } + }, + MINUTE(0, 59, null) { + @Override + int getValue(ZonedDateTime dateTime) { + return dateTime.getMinute(); + } + + @Override + ZonedDateTime setValue(ZonedDateTime dateTime, int value) { + return dateTime.withMinute(value).withSecond(0).withNano(0); + } + + @Override + ZonedDateTime overflow(ZonedDateTime dateTime) { + return dateTime.plusHours(1).withMinute(0).withSecond(0).withNano(0); + } + }, + HOUR(0, 23, null) { + @Override + int getValue(ZonedDateTime dateTime) { + return dateTime.getHour(); + } + + @Override + ZonedDateTime setValue(ZonedDateTime dateTime, int value) { + return dateTime.withHour(value).withMinute(0).withSecond(0).withNano(0); + } + + @Override + ZonedDateTime overflow(ZonedDateTime dateTime) { + return dateTime.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + } + }, + DAY_OF_MONTH(1, 31, null) { + @Override + int getValue(ZonedDateTime dateTime) { + return dateTime.getDayOfMonth(); + } + + @Override + ZonedDateTime setValue(ZonedDateTime dateTime, int value) { + return dateTime.withDayOfMonth(value).withMinute(0).withSecond(0).withNano(0); + } + + @Override + ZonedDateTime overflow(ZonedDateTime dateTime) { + return dateTime.plusMonths(1).withDayOfMonth(0).withMinute(0).withSecond(0).withNano(0); + } + }, + MONTH(1, 12, + Arrays.asList("JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC")) { + @Override + int getValue(ZonedDateTime dateTime) { + return dateTime.getMonthValue(); + } + + @Override + ZonedDateTime setValue(ZonedDateTime dateTime, int value) { + return dateTime.withMonth(value).withDayOfMonth(1).withMinute(0).withSecond(0).withNano(0); + } + + @Override + ZonedDateTime overflow(ZonedDateTime dateTime) { + return dateTime.plusYears(1).withMonth(1).withDayOfMonth(1).withMinute(0).withSecond(0).withNano(0); + } + }, + DAY_OF_WEEK(1, 7, Arrays.asList("MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN")) { + @Override + int getValue(ZonedDateTime dateTime) { + return dateTime.getDayOfWeek().getValue(); + } + + @Override + ZonedDateTime setValue(ZonedDateTime dateTime, int value) { + throw new UnsupportedOperationException(); + } + + @Override + ZonedDateTime overflow(ZonedDateTime dateTime) { + throw new UnsupportedOperationException(); + } + }; final int from, to; final List names; @@ -141,6 +239,27 @@ public class CronExpression { this.to = to; this.names = names; } + + /** + * @param dateTime {@link ZonedDateTime} instance + * @return The field time or date value from {@code dateTime} + */ + abstract int getValue(ZonedDateTime dateTime); + + /** + * @param dateTime Initial {@link ZonedDateTime} instance to use + * @param value to set for this field in {@code dateTime} + * @return {@link ZonedDateTime} with {@code value} set for this field and all smaller fields cleared + */ + abstract ZonedDateTime setValue(ZonedDateTime dateTime, int value); + + /** + * Handle when this field overflows and the next higher field should be incremented + * + * @param dateTime Initial {@link ZonedDateTime} instance to use + * @return {@link ZonedDateTime} with the next greater field incremented and all smaller fields cleared + */ + abstract ZonedDateTime overflow(ZonedDateTime dateTime); } private final String expr; @@ -200,50 +319,53 @@ public class CronExpression { } public ZonedDateTime nextTimeAfter(ZonedDateTime afterTime, ZonedDateTime dateTimeBarrier) { - ZonedDateTime nextTime = ZonedDateTime.from(afterTime).withNano(0).plusSeconds(1).withNano(0); - ; + ZonedDateTime[] nextDateTime = { afterTime.plusSeconds(1).withNano(0) }; - while (true) { // day of week - while (true) { // month - while (true) { // day of month - while (true) { // hour - while (true) { // minute - while (true) { // second - if (secondField.matches(nextTime.getSecond())) { - break; - } - nextTime = nextTime.plusSeconds(1).withNano(0); - } - if (minuteField.matches(nextTime.getMinute())) { - break; - } - nextTime = nextTime.plusMinutes(1).withSecond(0).withNano(0); - } - if (hourField.matches(nextTime.getHour())) { - break; - } - nextTime = nextTime.plusHours(1).withMinute(0).withSecond(0).withNano(0); - } - if (dayOfMonthField.matches(nextTime.toLocalDate())) { - break; - } - nextTime = nextTime.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0); - checkIfDateTimeBarrierIsReached(nextTime, dateTimeBarrier); - } - if (monthField.matches(nextTime.getMonth().getValue())) { - break; - } - nextTime = nextTime.plusMonths(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); - checkIfDateTimeBarrierIsReached(nextTime, dateTimeBarrier); + while (true) { + checkIfDateTimeBarrierIsReached(nextDateTime[0], dateTimeBarrier); + if (!monthField.nextMatch(nextDateTime)) { + continue; } - if (dayOfWeekField.matches(nextTime.toLocalDate())) { - break; + if (!findDay(nextDateTime, dateTimeBarrier)) { + continue; } - nextTime = nextTime.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0); - checkIfDateTimeBarrierIsReached(nextTime, dateTimeBarrier); + if (!hourField.nextMatch(nextDateTime)) { + continue; + } + if (!minuteField.nextMatch(nextDateTime)) { + continue; + } + if (!secondField.nextMatch(nextDateTime)) { + continue; + } + + checkIfDateTimeBarrierIsReached(nextDateTime[0], dateTimeBarrier); + return nextDateTime[0]; } + } - return nextTime; + /** + * Find the next match for the day field. + *

+ * This is handled different than all other fields because there are two ways to describe the day and it is easier + * to handle them together in the same method. + * + * @param dateTime Initial {@link ZonedDateTime} instance to start from + * @param dateTimeBarrier At which point stop searching for next execution time + * @return {@code true} if a match was found for this field or {@code false} if the field overflowed + * @see {@link SimpleField#nextMatch(ZonedDateTime[])} + */ + private boolean findDay(ZonedDateTime[] dateTime, ZonedDateTime dateTimeBarrier) { + int month = dateTime[0].getMonthValue(); + + while (!(dayOfMonthField.matches(dateTime[0].toLocalDate()) + && dayOfWeekField.matches(dateTime[0].toLocalDate()))) { + dateTime[0] = dateTime[0].plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + if (dateTime[0].getMonthValue() != month) { + return false; + } + } + return true; } private static void checkIfDateTimeBarrierIsReached(ZonedDateTime nextTime, ZonedDateTime dateTimeBarrier) { @@ -373,6 +495,23 @@ public class CronExpression { } return false; } + + protected int nextMatch(int val, FieldPart part) { + if (val > part.to) { + return -1; + } + int nextPotential = Math.max(val, part.from); + if (part.increment == 1 || nextPotential == part.from) { + return nextPotential; + } + + int remainder = ((nextPotential - part.from) % part.increment); + if (remainder != 0) { + nextPotential += part.increment - remainder; + } + + return nextPotential <= part.to ? nextPotential : -1; + } } static class SimpleField extends BasicField { @@ -390,6 +529,30 @@ public class CronExpression { } return false; } + + /** + * Find the next match for this field. If a match cannot be found force an overflow and increase the next + * greatest field. + * + * @param dateTime {@link ZonedDateTime} array so the reference can be modified + * @return {@code true} if a match was found for this field or {@code false} if the field overflowed + */ + protected boolean nextMatch(ZonedDateTime[] dateTime) { + int value = fieldType.getValue(dateTime[0]); + + for (FieldPart part : parts) { + int nextMatch = nextMatch(value, part); + if (nextMatch > -1) { + if (nextMatch != value) { + dateTime[0] = fieldType.setValue(dateTime[0], nextMatch); + } + return true; + } + } + + dateTime[0] = fieldType.overflow(dateTime[0]); + return false; + } } static class DayOfWeekField extends BasicField {