spec_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package cron
  2. import (
  3. "testing"
  4. "time"
  5. )
  6. func TestActivation(t *testing.T) {
  7. tests := []struct {
  8. time, spec string
  9. expected bool
  10. }{
  11. // Every fifteen minutes.
  12. {"Mon Jul 9 15:00 2012", "0 0/15 * * *", true},
  13. {"Mon Jul 9 15:45 2012", "0 0/15 * * *", true},
  14. {"Mon Jul 9 15:40 2012", "0 0/15 * * *", false},
  15. // Every fifteen minutes, starting at 5 minutes.
  16. {"Mon Jul 9 15:05 2012", "0 5/15 * * *", true},
  17. {"Mon Jul 9 15:20 2012", "0 5/15 * * *", true},
  18. {"Mon Jul 9 15:50 2012", "0 5/15 * * *", true},
  19. // Named months
  20. {"Sun Jul 15 15:00 2012", "0 0/15 * * Jul", true},
  21. {"Sun Jul 15 15:00 2012", "0 0/15 * * Jun", false},
  22. // Everything set.
  23. {"Sun Jul 15 08:30 2012", "0 30 08 ? Jul Sun", true},
  24. {"Sun Jul 15 08:30 2012", "0 30 08 15 Jul ?", true},
  25. {"Mon Jul 16 08:30 2012", "0 30 08 ? Jul Sun", false},
  26. {"Mon Jul 16 08:30 2012", "0 30 08 15 Jul ?", false},
  27. // Predefined schedules
  28. {"Mon Jul 9 15:00 2012", "@hourly", true},
  29. {"Mon Jul 9 15:04 2012", "@hourly", false},
  30. {"Mon Jul 9 15:00 2012", "@daily", false},
  31. {"Mon Jul 9 00:00 2012", "@daily", true},
  32. {"Mon Jul 9 00:00 2012", "@weekly", false},
  33. {"Sun Jul 8 00:00 2012", "@weekly", true},
  34. {"Sun Jul 8 01:00 2012", "@weekly", false},
  35. {"Sun Jul 8 00:00 2012", "@monthly", false},
  36. {"Sun Jul 1 00:00 2012", "@monthly", true},
  37. // Test interaction of DOW and DOM.
  38. // If both are specified, then only one needs to match.
  39. {"Sun Jul 15 00:00 2012", "0 * * 1,15 * Sun", true},
  40. {"Fri Jun 15 00:00 2012", "0 * * 1,15 * Sun", true},
  41. {"Wed Aug 1 00:00 2012", "0 * * 1,15 * Sun", true},
  42. // However, if one has a star, then both need to match.
  43. {"Sun Jul 15 00:00 2012", "0 * * * * Mon", false},
  44. {"Sun Jul 15 00:00 2012", "0 * * */10 * Sun", false},
  45. {"Mon Jul 9 00:00 2012", "0 * * 1,15 * *", false},
  46. {"Sun Jul 15 00:00 2012", "0 * * 1,15 * *", true},
  47. {"Sun Jul 15 00:00 2012", "0 * * */2 * Sun", true},
  48. }
  49. for _, test := range tests {
  50. actual := Parse(test.spec).Next(getTime(test.time).Add(-1 * time.Second))
  51. expected := getTime(test.time)
  52. if test.expected && expected != actual || !test.expected && expected == actual {
  53. t.Errorf("Fail evaluating %s on %s: (expected) %s != %s (actual)",
  54. test.spec, test.time, expected, actual)
  55. }
  56. }
  57. }
  58. func TestNext(t *testing.T) {
  59. runs := []struct {
  60. time, spec string
  61. expected string
  62. }{
  63. // Simple cases
  64. {"Mon Jul 9 14:45 2012", "0 0/15 * * *", "Mon Jul 9 15:00 2012"},
  65. {"Mon Jul 9 14:59 2012", "0 0/15 * * *", "Mon Jul 9 15:00 2012"},
  66. {"Mon Jul 9 14:59:59 2012", "0 0/15 * * *", "Mon Jul 9 15:00 2012"},
  67. // Wrap around hours
  68. {"Mon Jul 9 15:45 2012", "0 20-35/15 * * *", "Mon Jul 9 16:20 2012"},
  69. // Wrap around days
  70. {"Mon Jul 9 23:46 2012", "0 */15 * * *", "Tue Jul 10 00:00 2012"},
  71. {"Mon Jul 9 23:45 2012", "0 20-35/15 * * *", "Tue Jul 10 00:20 2012"},
  72. {"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 * * *", "Tue Jul 10 00:20:15 2012"},
  73. {"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 1/2 * *", "Tue Jul 10 01:20:15 2012"},
  74. {"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 10-12 * *", "Tue Jul 10 10:20:15 2012"},
  75. {"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 1/2 */2 * *", "Thu Jul 11 01:20:15 2012"},
  76. {"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 * 9-20 * *", "Wed Jul 10 00:20:15 2012"},
  77. {"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 * 9-20 Jul *", "Wed Jul 10 00:20:15 2012"},
  78. // Wrap around months
  79. {"Mon Jul 9 23:35 2012", "0 0 0 9 Apr-Oct ?", "Thu Aug 9 00:00 2012"},
  80. {"Mon Jul 9 23:35 2012", "0 0 0 */5 Apr,Aug,Oct Mon", "Mon Aug 6 00:00 2012"},
  81. {"Mon Jul 9 23:35 2012", "0 0 0 */5 Oct Mon", "Mon Oct 1 00:00 2012"},
  82. // Wrap around years
  83. {"Mon Jul 9 23:35 2012", "0 0 0 * Feb Mon", "Mon Feb 4 00:00 2013"},
  84. {"Mon Jul 9 23:35 2012", "0 0 0 * Feb Mon/2", "Fri Feb 1 00:00 2013"},
  85. // Wrap around minute, hour, day, month, and year
  86. {"Mon Dec 31 23:59:45 2012", "0 * * * * *", "Tue Jan 1 00:00:00 2013"},
  87. // Leap year
  88. {"Mon Jul 9 23:35 2012", "0 0 0 29 Feb ?", "Mon Feb 29 00:00 2016"},
  89. // Daylight savings time
  90. {"Sun Mar 11 00:00 2012 EST", "0 30 2 11 Mar ?", "Mon Mar 11 02:30 2013 EDT"},
  91. // Unsatisfiable
  92. {"Mon Jul 9 23:35 2012", "0 0 0 30 Feb ?", ""},
  93. {"Mon Jul 9 23:35 2012", "0 0 0 31 Apr ?", ""},
  94. }
  95. for _, c := range runs {
  96. actual := Parse(c.spec).Next(getTime(c.time))
  97. expected := getTime(c.expected)
  98. if actual != expected {
  99. t.Errorf("%s, \"%s\": (expected) %v != %v (actual)", c.time, c.spec, expected, actual)
  100. }
  101. }
  102. }
  103. func getTime(value string) time.Time {
  104. if value == "" {
  105. return time.Time{}
  106. }
  107. t, err := time.Parse("Mon Jan 2 15:04 2006", value)
  108. if err != nil {
  109. t, err = time.Parse("Mon Jan 2 15:04:05 2006", value)
  110. if err != nil {
  111. t, err = time.Parse("Mon Jan 2 15:04 2006 MST", value)
  112. if err != nil {
  113. panic(err)
  114. }
  115. }
  116. }
  117. return t
  118. }