import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.quartz.CronExpression;
import org.quartz.CronScheduleBuilder;
/**
* Quartz CronExpression 정규식 처리를 이해하기 위한 테스트 코드
*
* @author ihoneymon
* @see http://quartz-scheduler.org/api/2.2.0/org/quartz/CronExpression.html
*/
public class QuartzCronExpressionTest {
/**
* Null은 예외발생
*/
@Test(expected = IllegalArgumentException.class)
public void testNullCronExpressionException() {
assertThat(CronExpression.isValidExpression(null), is(false));
fail();
}
/**
* 빈값이나 cron 정규식 표현이 아니라면 실패
*/
@Test
public void testEmptyCronExpressionException() {
assertThat(CronExpression.isValidExpression(""), is(false));
assertThat(CronExpression.isValidExpression("1 1+2 1*2"), is(false));
assertThat(CronExpression.isValidExpression("testWrongChronExpression"), is(false));
}
/**
* Quartz CronExpression 중에 DayOfMonth와 DayOfWeek에 대한 확인 DayOfMonth와
* DayOfWeek의 표현식에 대해서는 신경을 써야한다.
*
* Second Minute Hour DayOfMonth Month DayOfWeek (optional)Year
*/
@Test
public void testDayOfMonthAndDayOfWeekCronExpression() {
/**
* same DayOfMonth & DayOfMonth is valid fail DayOfMonth & DayOfMonth is
* all: false DayOfMonth & DayOfMonth is none: valid fail
*/
assertThat(CronExpression.isValidExpression("* * * * * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * ? * ?"), is(false));
/**
* DayOfMonth is all and DayOfMonth is none: valid success DayOfMonth is
* all and DayOfMonth is define: valid fail
*/
assertThat(CronExpression.isValidExpression("* * * * * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * * * MON"), is(false));
assertThat(CronExpression.isValidExpression("* * * * * 2"), is(false));
assertThat(CronExpression.isValidExpression("* * * * * 2,5"), is(false));
/**
* DayOfMonth is none and DayOfMonth is all: valid success DayOfMonth
* required none DayOfMonth DayOfMonth가 none(?)인 경우에는 DayOfMonth에 허용되는
* 정규식은 대부분 통과
*/
assertThat(CronExpression.isValidExpression("* * * ? * *"), is(true));
assertThat(CronExpression.isValidExpression("* * * ? * MON"), is(true));
assertThat(CronExpression.isValidExpression("* * * ? * MON-FRI"), is(true));
assertThat(CronExpression.isValidExpression("* * * ? * MON-FRI,SUN"), is(true));
assertThat(CronExpression.isValidExpression("* * * ? * MON#2"), is(true));
assertThat(CronExpression.isValidExpression("* * * ? * 2#2"), is(true));
assertThat(CronExpression.isValidExpression("* * * ? * 2#2,1#2"), is(false));
/**
* DayOfMonth에
*/
assertThat(CronExpression.isValidExpression("* * * 1 * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * 1-3 * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * 1,6,9 * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * 1 * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * 1-3 * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * 1,6,9 * FRI"), is(false));
/**
* DayOfMonth use L(last) special character
*/
assertThat(CronExpression.isValidExpression("* * * L * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * L * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * L * MON"), is(false));
/**
* DayOfMonth에 L은 단독으로 사용되거나 '-nth day'만 허용
*/
assertThat(CronExpression.isValidExpression("* * * 15L * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * L15 * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * 15L * MON"), is(false));
assertThat(CronExpression.isValidExpression("* * * 15L * ?"), is(false));
assertThat(CronExpression.isValidExpression("* * * L-3 * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * L-3 * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * L-3 * MON"), is(false));
/**
* DayOfMonth use W(week: mon-fri) special character
*/
assertThat(CronExpression.isValidExpression("* * * W * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * 15W * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * 15W * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * 15W,16W * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * 15W-17W * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * 15W/2W * ?"), is(true));
/**
* DayOfMonth use LW(last-week: mon-fri) special character
*/
assertThat(CronExpression.isValidExpression("* * * LW * *"), is(false));
assertThat(CronExpression.isValidExpression("* * * LW * ?"), is(true));
assertThat(CronExpression.isValidExpression("* * * 1LW * ?"), is(false));
assertThat(CronExpression.isValidExpression("* * * LW2 * ?"), is(false));
assertThat(CronExpression.isValidExpression("* * * LW * MON"), is(false));
assertThat(CronExpression.isValidExpression("* * * LW * 2"), is(false));
}
@Test(expected = RuntimeException.class)
public void testCronBuilder() {
assertThat(CronExpression.isValidExpression("* * * LW * *"), is(false));
CronScheduleBuilder.cronSchedule("* * * LW * *").build();
}
}
CronExpression.isValidExpression() 에서 false가 발생한 정규식을 CronScheduleBuilder.cronSchedule()
를 사용하여 스케줄을 생성하려하면 RuntimeException
이 발생한다.