View Javadoc

1   package com.atlassian.scheduler.core.tests;
2   
3   import org.hamcrest.Matcher;
4   import org.joda.time.DateTime;
5   import org.joda.time.DateTimeZone;
6   
7   import java.util.ArrayList;
8   import java.util.Date;
9   import java.util.List;
10  
11  import static com.atlassian.scheduler.core.tests.CronFactory.CronExpressionAdapter;
12  import static java.util.concurrent.TimeUnit.MILLISECONDS;
13  import static org.hamcrest.Matchers.allOf;
14  import static org.hamcrest.Matchers.contains;
15  import static org.junit.Assert.assertThat;
16  import static org.junit.Assert.fail;
17  
18  /**
19   * @since v1.5
20   */
21  public abstract class AbstractCronExpressionTest {
22      protected final CronFactory cronFactory;
23  
24      protected AbstractCronExpressionTest(final CronFactory cronFactory) {
25          this.cronFactory = cronFactory;
26      }
27  
28      @SuppressWarnings("unchecked")
29      protected void assertCron(final String message, final String cronExpression, final Matcher... matchers) {
30          assertThat(message, cronFactory.parse(cronExpression), allOf(matchers));
31      }
32  
33      protected void assertQuartzBug(final String whyQuartzIsWrong, final String cronExpression, final Matcher<?> matcher) {
34          final CronExpressionAdapter cron = cronFactory.parse(cronExpression);
35          if (matcher.matches(cron)) {
36              fail("Expected a Quartz bug to cause a mismatch between <" + cronExpression + "> and <" + matcher +
37                      "> because " + whyQuartzIsWrong + " -- Maybe this bug has been fixed, now?");
38          } else {
39              System.err.println("Quartz failed to match <" + cronExpression + "> with <" + matcher +
40                      "> due to known bug: " + whyQuartzIsWrong);
41          }
42      }
43  
44      protected void assertRunTimes(final String message, final String cronExpression, final DateTime startingAfter,
45                                    final Matcher... matchers) {
46          final CronExpressionAdapter cron = cronFactory.parse(cronExpression, startingAfter.getZone());
47          assertRunTimes(message, cron, startingAfter, matchers);
48      }
49  
50      protected void assertRunTimes(final String message, final CronExpressionAdapter cron, final DateTime startingAfter,
51                                    final Matcher... matchers) {
52          final List<Date> list = generateNextRunTimes(cron, startingAfter, matchers.length);
53          boolean ok = false;
54          try {
55              assertThat(message, list, contains(matchers));
56              ok = true;
57          } finally {
58              if (!ok) {
59                  final DateTimeZone zone = startingAfter.getZone();
60                  System.err.println("Debug info for run times of '" + cron + "':");
61                  System.err.println("\t" + startingAfter.getMillis() + " = " + startingAfter + " (T = starting point)");
62                  for (Date date : list) {
63                      System.err.println("\t" + date.getTime() + " = " + new DateTime(date, zone) + " (T + " +
64                              MILLISECONDS.toMinutes(date.getTime() - startingAfter.getMillis()) + " min)");
65                  }
66              }
67          }
68      }
69  
70      protected List<Date> generateNextRunTimes(final CronExpressionAdapter adapter,
71                                                final DateTime startingAfter, final int maximumResults) {
72          final List<Date> list = new ArrayList<Date>(maximumResults);
73          Date current = startingAfter.toDate();
74          for (int i = 0; i < maximumResults && current != null; ++i) {
75              current = adapter.nextRunTime(current);
76              list.add(current);
77          }
78          return list;
79      }
80  }