hiccup 0.5.14 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hiccup.rb +17 -17
- data/lib/hiccup/convenience.rb +9 -9
- data/lib/hiccup/core_ext/date.rb +7 -7
- data/lib/hiccup/core_ext/duration.rb +4 -4
- data/lib/hiccup/core_ext/enumerable.rb +2 -2
- data/lib/hiccup/core_ext/fixnum.rb +2 -2
- data/lib/hiccup/core_ext/hash.rb +2 -2
- data/lib/hiccup/enumerable.rb +43 -29
- data/lib/hiccup/enumerable/annually_enumerator.rb +23 -23
- data/lib/hiccup/enumerable/monthly_date_enumerator.rb +2 -2
- data/lib/hiccup/enumerable/monthly_enumerator.rb +40 -40
- data/lib/hiccup/enumerable/never_enumerator.rb +8 -8
- data/lib/hiccup/enumerable/schedule_enumerator.rb +39 -39
- data/lib/hiccup/enumerable/weekly_enumerator.rb +30 -30
- data/lib/hiccup/errors.rb +4 -0
- data/lib/hiccup/humanizable.rb +19 -19
- data/lib/hiccup/inferable.rb +30 -30
- data/lib/hiccup/inferable/dates_enumerator.rb +6 -6
- data/lib/hiccup/inferable/guesser.rb +21 -21
- data/lib/hiccup/inferable/score.rb +7 -7
- data/lib/hiccup/inferable/scorer.rb +19 -19
- data/lib/hiccup/schedule.rb +10 -10
- data/lib/hiccup/serializable/ical.rb +13 -13
- data/lib/hiccup/serializers/ical.rb +59 -59
- data/lib/hiccup/validatable.rb +23 -23
- data/lib/hiccup/version.rb +1 -1
- data/test/core_ext_date_test.rb +5 -5
- data/test/duration_ext_test.rb +8 -8
- data/test/enumerable_test.rb +103 -103
- data/test/humanizable_test.rb +24 -24
- data/test/ical_serializable_test.rb +29 -29
- data/test/inferrable_test.rb +84 -84
- data/test/leap_year_test.rb +7 -7
- data/test/monthly_enumerator_test.rb +13 -13
- data/test/performance_test.rb +7 -7
- data/test/validatable_test.rb +1 -1
- data/test/weekly_enumerator_test.rb +38 -38
- metadata +4 -3
data/test/humanizable_test.rb
CHANGED
@@ -3,44 +3,44 @@ require "test_helper"
|
|
3
3
|
|
4
4
|
class HumanizableTest < ActiveSupport::TestCase
|
5
5
|
include Hiccup
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
|
8
8
|
def self.test_humanize(*args)
|
9
9
|
expected_string = args.shift
|
10
10
|
attributes = args.shift
|
11
|
-
|
11
|
+
|
12
12
|
test(expected_string) do
|
13
13
|
schedule = Schedule.new(attributes)
|
14
14
|
assert_equal expected_string, schedule.humanize
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
|
18
|
+
|
19
|
+
|
20
20
|
test_humanize(
|
21
21
|
"Every Sunday",
|
22
22
|
{:kind => :weekly, :weekly_pattern => %w[Sunday]})
|
23
|
-
|
23
|
+
|
24
24
|
test_humanize(
|
25
25
|
"Every other Sunday",
|
26
26
|
{:kind => :weekly, :weekly_pattern => %w[Sunday], :skip => 2})
|
27
|
-
|
27
|
+
|
28
28
|
test_humanize(
|
29
29
|
"Every Sunday and Monday",
|
30
30
|
{:kind => :weekly, :weekly_pattern => %w[Sunday Monday]})
|
31
|
-
|
31
|
+
|
32
32
|
test_humanize(
|
33
33
|
"Monday, Wednesday, and Friday of every third week",
|
34
34
|
{:kind => :weekly, :weekly_pattern => %w[Monday Wednesday Friday], :skip => 3})
|
35
|
-
|
35
|
+
|
36
36
|
test_humanize(
|
37
37
|
"The 4th of every month",
|
38
38
|
{:kind => :monthly, :monthly_pattern => [4]})
|
39
|
-
|
39
|
+
|
40
40
|
test_humanize(
|
41
41
|
"The 4th and 5th of every month",
|
42
42
|
{:kind => :monthly, :monthly_pattern => [4,5]})
|
43
|
-
|
43
|
+
|
44
44
|
test_humanize(
|
45
45
|
"The last day of every month",
|
46
46
|
{:kind => :monthly, :monthly_pattern => [-1]})
|
@@ -48,33 +48,33 @@ class HumanizableTest < ActiveSupport::TestCase
|
|
48
48
|
test_humanize(
|
49
49
|
"The first Monday of every month",
|
50
50
|
{:kind => :monthly, :monthly_pattern => [[1, "Monday"]]})
|
51
|
-
|
51
|
+
|
52
52
|
test_humanize(
|
53
53
|
"The last Tuesday of every month",
|
54
54
|
{:kind => :monthly, :monthly_pattern => [[-1, "Tuesday"]]})
|
55
|
-
|
55
|
+
|
56
56
|
test_humanize(
|
57
57
|
"The first Monday and third Monday of every other month",
|
58
58
|
{:kind => :monthly, :monthly_pattern => [[1, "Monday"], [3, "Monday"]], :skip => 2})
|
59
|
-
|
59
|
+
|
60
60
|
test_humanize(
|
61
61
|
"Every year on October 1",
|
62
62
|
{:kind => :annually, start_date: Date.new(2012, 10, 1)})
|
63
|
-
|
63
|
+
|
64
64
|
test_humanize(
|
65
65
|
"Every year on October 10",
|
66
66
|
{:kind => :annually, start_date: Date.new(2012, 10, 10)})
|
67
|
-
|
67
|
+
|
68
68
|
test_humanize(
|
69
69
|
"Every other year on August 12",
|
70
70
|
{:kind => :annually, :skip => 2, start_date: Date.new(2012, 8, 12)})
|
71
|
-
|
71
|
+
|
72
72
|
test_humanize(
|
73
73
|
"Every fourth year on January 31",
|
74
74
|
{:kind => :annually, :skip => 4, start_date: Date.new(1888, 1, 31)})
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
|
76
|
+
|
77
|
+
|
78
78
|
test "should not have spaces in front of day numbers" do
|
79
79
|
independence_day = Schedule.new({
|
80
80
|
:kind => :annually,
|
@@ -86,7 +86,7 @@ class HumanizableTest < ActiveSupport::TestCase
|
|
86
86
|
test "should let you supply a format for strftime" do
|
87
87
|
assert_equal "July 4, 1776", Schedule.new(start_date: Date.new(1776, 7, 4)).humanize(format: "%B %-d, %Y")
|
88
88
|
end
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
|
90
|
+
|
91
|
+
|
92
92
|
end
|
@@ -4,8 +4,8 @@ require "test_helper"
|
|
4
4
|
|
5
5
|
class IcalSerializableTest < ActiveSupport::TestCase
|
6
6
|
include Hiccup
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
|
9
9
|
def self.test_roundtrip(*args)
|
10
10
|
message = args.shift
|
11
11
|
ics = args.shift
|
@@ -15,27 +15,27 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
15
15
|
assert_roundtrip ics, recurrence
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
19
|
-
|
18
|
+
|
19
|
+
|
20
20
|
def test_parsing_empty_recurrence
|
21
21
|
schedule = Schedule.from_ical("")
|
22
22
|
assert_equal :never, schedule.kind
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def test_formatting_an_empty_schedule
|
26
26
|
schedule = Schedule.new(:kind => :yearly, :start_date => "")
|
27
27
|
assert_equal "", schedule.to_ical
|
28
28
|
end
|
29
|
-
|
30
|
-
|
29
|
+
|
30
|
+
|
31
31
|
test_roundtrip(
|
32
32
|
"No recurrence",
|
33
33
|
"DTSTART;VALUE=DATE-TIME:20090101T000000Z\n",
|
34
34
|
{ :kind => :never,
|
35
35
|
:start_date => DateTime.new(2009, 1, 1)
|
36
36
|
})
|
37
|
-
|
38
|
-
|
37
|
+
|
38
|
+
|
39
39
|
test_roundtrip(
|
40
40
|
"Simple weekly recurrence",
|
41
41
|
"DTSTART;VALUE=DATE-TIME:20090101T000000Z\nRRULE:FREQ=WEEKLY;BYDAY=SU\n",
|
@@ -43,8 +43,8 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
43
43
|
:weekly_pattern => %w{Sunday},
|
44
44
|
:start_date => DateTime.new(2009, 1, 1)
|
45
45
|
})
|
46
|
-
|
47
|
-
|
46
|
+
|
47
|
+
|
48
48
|
test_roundtrip(
|
49
49
|
"Simple weekly recurrence (with an end date)",
|
50
50
|
"DTSTART;VALUE=DATE-TIME:20090101T000000Z\nRRULE:FREQ=WEEKLY;UNTIL=20091231T000000Z;BYDAY=SU\n",
|
@@ -54,8 +54,8 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
54
54
|
:end_date => DateTime.new(2009, 12, 31),
|
55
55
|
:ends => true
|
56
56
|
})
|
57
|
-
|
58
|
-
|
57
|
+
|
58
|
+
|
59
59
|
test_roundtrip(
|
60
60
|
"Complex weekly recurrence (with an interval)",
|
61
61
|
"DTSTART;VALUE=DATE-TIME:20090101T000000Z\nRRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,TH\n",
|
@@ -64,16 +64,16 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
64
64
|
:start_date => DateTime.new(2009, 1, 1),
|
65
65
|
:skip => 2
|
66
66
|
})
|
67
|
-
|
68
|
-
|
67
|
+
|
68
|
+
|
69
69
|
test_roundtrip(
|
70
70
|
"Simple annual recurrence",
|
71
71
|
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=YEARLY\n",
|
72
72
|
{ :kind => :annually,
|
73
73
|
:start_date => DateTime.new(2009, 3, 15)
|
74
74
|
})
|
75
|
-
|
76
|
-
|
75
|
+
|
76
|
+
|
77
77
|
test_roundtrip(
|
78
78
|
"Annual recurrence with an end date",
|
79
79
|
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=YEARLY;UNTIL=20120315T000000Z\n",
|
@@ -81,8 +81,8 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
81
81
|
:start_date => DateTime.new(2009, 3, 15),
|
82
82
|
:end_date => DateTime.new(2012, 3, 15), :ends => true
|
83
83
|
})
|
84
|
-
|
85
|
-
|
84
|
+
|
85
|
+
|
86
86
|
test_roundtrip(
|
87
87
|
"Simple monthly recurrence",
|
88
88
|
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=MONTHLY;BYMONTHDAY=4\n",
|
@@ -90,8 +90,8 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
90
90
|
:monthly_pattern => [4],
|
91
91
|
:start_date => DateTime.new(2009, 3, 15)
|
92
92
|
})
|
93
|
-
|
94
|
-
|
93
|
+
|
94
|
+
|
95
95
|
test_roundtrip(
|
96
96
|
"Monthly recurrence on the last Tuesday of the month",
|
97
97
|
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=MONTHLY;BYDAY=-1TU\n",
|
@@ -99,8 +99,8 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
99
99
|
:monthly_pattern => [[-1, "Tuesday"]],
|
100
100
|
:start_date => DateTime.new(2009, 3, 15)
|
101
101
|
})
|
102
|
-
|
103
|
-
|
102
|
+
|
103
|
+
|
104
104
|
test_roundtrip(
|
105
105
|
"Complex monthly recurrence",
|
106
106
|
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=MONTHLY;BYDAY=2SU,4SU\n",
|
@@ -108,15 +108,15 @@ class IcalSerializableTest < ActiveSupport::TestCase
|
|
108
108
|
:monthly_pattern => [[2, "Sunday"], [4, "Sunday"]],
|
109
109
|
:start_date => DateTime.new(2009, 3, 15)
|
110
110
|
})
|
111
|
-
|
112
|
-
|
111
|
+
|
112
|
+
|
113
113
|
protected
|
114
|
-
|
115
|
-
|
114
|
+
|
115
|
+
|
116
116
|
def assert_roundtrip(ics, recurrence)
|
117
117
|
assert_equal ics, recurrence.to_ical, "to_ical did not result in the expected ICS"
|
118
118
|
assert_equal recurrence.to_hash, Schedule.from_ical(ics).to_hash, "from_ical did not result in the expected recurrence"
|
119
119
|
end
|
120
|
-
|
121
|
-
|
120
|
+
|
121
|
+
|
122
122
|
end
|
data/test/inferrable_test.rb
CHANGED
@@ -5,263 +5,263 @@ require "test_helper"
|
|
5
5
|
|
6
6
|
class InferableTest < ActiveSupport::TestCase
|
7
7
|
include Hiccup
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
|
9
|
+
|
10
|
+
|
11
11
|
test "should raise an error if not given an array of dates" do
|
12
12
|
assert_raises ArgumentError do
|
13
13
|
Schedule.infer(["what's this?"])
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
test "extract_array_of_dates! should interpret date-like things as dates" do
|
18
18
|
datelike_things = [Date.today, Time.now, DateTime.new(2012, 8, 17)]
|
19
19
|
dates = Schedule.extract_array_of_dates!(datelike_things)
|
20
20
|
assert_equal datelike_things.length, dates.length
|
21
21
|
assert dates.all? { |date| date.is_a?(Date) }, "Expected these to all be dates, but they were #{dates.map(&:class)}"
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
test "extract_array_of_dates! should put dates in order" do
|
25
25
|
input_dates = %w{2014-01-01 2007-01-01 2009-01-01}
|
26
26
|
expected_dates = %w{2007-01-01 2009-01-01 2014-01-01}
|
27
27
|
dates = Schedule.extract_array_of_dates!(input_dates)
|
28
28
|
assert_equal expected_dates, dates.map(&:to_s)
|
29
29
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
|
31
|
+
|
32
|
+
|
33
33
|
test "should prefer guesses that predict too many results over guesses that predict too few" do
|
34
|
-
|
34
|
+
|
35
35
|
# In this stream of dates, we could guess an annual recurrence on 1/15
|
36
36
|
# or a monthly recurrence on the 15th.
|
37
37
|
#
|
38
|
-
# - The annual recurrence would have zero bricks (no unfulfilled predictions),
|
38
|
+
# - The annual recurrence would have zero bricks (no unfulfilled predictions),
|
39
39
|
# but it would fail to predict 5 of the dates in this list.
|
40
40
|
#
|
41
41
|
# - The monthly recurrence would have zero failures (there's nothing in
|
42
42
|
# in the list it _wouldn't_ predict), but it would have 6 bricks.
|
43
43
|
#
|
44
44
|
dates = %w{2011-1-15 2011-2-15 2011-5-15 2011-7-15 2011-8-15 2011-11-15 2012-1-15}
|
45
|
-
|
45
|
+
|
46
46
|
# If bricks and fails were equal, the annual recurrence would be the
|
47
47
|
# preferred guess, but the monthly one makes more sense.
|
48
48
|
# It is better to brick than to fail.
|
49
49
|
schedule = Schedule.infer(dates).first
|
50
50
|
assert_equal :monthly, schedule.kind
|
51
51
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
57
|
# Infers annual schedules
|
58
|
-
|
58
|
+
|
59
59
|
test "should infer an annual" do
|
60
60
|
dates = %w{2010-3-4 2011-3-4 2012-3-4}
|
61
61
|
schedules = Schedule.infer(dates)
|
62
62
|
assert_equal ["Every year on March 4"], schedules.map(&:humanize)
|
63
63
|
end
|
64
|
-
|
65
|
-
|
64
|
+
|
65
|
+
|
66
66
|
# ... with skips
|
67
|
-
|
67
|
+
|
68
68
|
test "should infer a schedule that occurs every other year" do
|
69
69
|
dates = %w{2010-3-4 2012-3-4 2014-3-4}
|
70
70
|
schedules = Schedule.infer(dates)
|
71
71
|
assert_equal ["Every other year on March 4"], schedules.map(&:humanize)
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
# ... where some of the input is wrong
|
75
|
-
|
75
|
+
|
76
76
|
test "should infer a yearly schedule when one of the dates was rescheduled" do
|
77
77
|
dates = %w{2010-3-4 2011-9-15 2012-3-4 2013-3-4}
|
78
78
|
schedules = Schedule.infer(dates)
|
79
79
|
assert_equal ["Every year on March 4"], schedules.map(&:humanize)
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
test "should infer a yearly schedule when the first date was rescheduled" do
|
83
83
|
dates = %w{2010-3-6 2011-3-4 2012-3-4 2013-3-4}
|
84
84
|
schedules = Schedule.infer(dates)
|
85
85
|
assert_equal ["Every year on March 4"], schedules.map(&:humanize)
|
86
86
|
end
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
92
|
# Infers monthly schedules
|
93
|
-
|
93
|
+
|
94
94
|
test "should infer a monthly schedule that occurs on a date" do
|
95
95
|
dates = %w{2012-2-4 2012-3-4 2012-4-4}
|
96
96
|
schedules = Schedule.infer(dates)
|
97
97
|
assert_equal ["The 4th of every month"], schedules.map(&:humanize)
|
98
|
-
|
98
|
+
|
99
99
|
dates = %w{2012-2-17 2012-3-17 2012-4-17}
|
100
100
|
schedules = Schedule.infer(dates)
|
101
101
|
assert_equal ["The 17th of every month"], schedules.map(&:humanize)
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
test "should infer a monthly schedule that occurs on a weekday" do
|
105
105
|
dates = %w{2012-7-9 2012-8-13 2012-9-10}
|
106
106
|
schedules = Schedule.infer(dates)
|
107
107
|
assert_equal ["The second Monday of every month"], schedules.map(&:humanize)
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
test "should infer a schedule that occurs several times a month" do
|
111
111
|
dates = %w{2012-7-9 2012-7-23 2012-8-13 2012-8-27 2012-9-10 2012-9-24}
|
112
112
|
schedules = Schedule.infer(dates)
|
113
113
|
assert_equal ["The second Monday and fourth Monday of every month"], schedules.map(&:humanize)
|
114
114
|
end
|
115
|
-
|
116
|
-
|
115
|
+
|
116
|
+
|
117
117
|
# ... with skips
|
118
|
-
|
118
|
+
|
119
119
|
test "should infer a schedule that occurs every third month" do
|
120
120
|
dates = %w{2012-2-4 2012-5-4 2012-8-4}
|
121
121
|
schedules = Schedule.infer(dates)
|
122
122
|
assert_equal ["The 4th of every third month"], schedules.map(&:humanize)
|
123
123
|
end
|
124
|
-
|
125
|
-
|
124
|
+
|
125
|
+
|
126
126
|
# ... when some dates are wrong in the input group
|
127
|
-
|
127
|
+
|
128
128
|
test "should infer a monthly (by day) schedule when one day was rescheduled" do
|
129
129
|
dates = %w{2012-10-02 2012-11-02 2012-12-03}
|
130
130
|
schedules = Schedule.infer(dates)
|
131
131
|
assert_equal ["The 2nd of every month"], schedules.map(&:humanize)
|
132
132
|
end
|
133
|
-
|
133
|
+
|
134
134
|
test "should infer a monthly (by day) schedule when the first day was rescheduled" do
|
135
135
|
dates = %w{2012-10-03 2012-11-02 2012-12-02}
|
136
136
|
schedules = Schedule.infer(dates)
|
137
137
|
assert_equal ["The 2nd of every month"], schedules.map(&:humanize)
|
138
138
|
end
|
139
|
-
|
140
|
-
|
139
|
+
|
140
|
+
|
141
141
|
test "should infer a monthly (by weekday) schedule when one day was rescheduled" do
|
142
142
|
dates = %w{2012-10-02 2012-11-06 2012-12-05} # 1st Tuesday, 1st Tuesday, 1st Wednesday
|
143
143
|
schedules = Schedule.infer(dates)
|
144
144
|
assert_equal ["The first Tuesday of every month"], schedules.map(&:humanize)
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
test "should infer a monthly (by weekday) schedule when the first day was rescheduled" do
|
148
148
|
dates = %w{2012-10-03 2012-11-01 2012-12-06} # 1st Wednesday, 1st Thursday, 1st Thursday
|
149
149
|
schedules = Schedule.infer(dates)
|
150
150
|
assert_equal ["The first Thursday of every month"], schedules.map(&:humanize)
|
151
151
|
end
|
152
|
-
|
152
|
+
|
153
153
|
test "should infer a monthly (by weekday) schedule when the first day was rescheduled 2" do
|
154
154
|
dates = %w{2012-10-11 2012-11-01 2012-12-06} # 2nd Thursday, 1st Thursday, 1st Thursday
|
155
155
|
schedules = Schedule.infer(dates)
|
156
156
|
assert_equal ["The first Thursday of every month"], schedules.map(&:humanize)
|
157
157
|
end
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
|
163
163
|
# Infers weekly schedules
|
164
|
-
|
164
|
+
|
165
165
|
test "should infer a weekly schedule" do
|
166
166
|
dates = %w{2012-3-4 2012-3-11 2012-3-18}
|
167
167
|
schedules = Schedule.infer(dates)
|
168
168
|
assert_equal ["Every Sunday"], schedules.map(&:humanize)
|
169
169
|
end
|
170
|
-
|
170
|
+
|
171
171
|
test "should infer a schedule that occurs several times a week" do
|
172
172
|
dates = %w{2012-3-6 2012-3-8 2012-3-13 2012-3-15 2012-3-20 2012-3-22}
|
173
173
|
schedules = Schedule.infer(dates)
|
174
174
|
assert_equal ["Every Tuesday and Thursday"], schedules.map(&:humanize)
|
175
175
|
end
|
176
|
-
|
177
|
-
|
176
|
+
|
177
|
+
|
178
178
|
# ... with skips
|
179
|
-
|
179
|
+
|
180
180
|
test "should infer weekly recurrence for something that occurs every other week" do
|
181
181
|
dates = %w{2012-3-6 2012-3-8 2012-3-20 2012-3-22}
|
182
182
|
schedules = Schedule.infer(dates)
|
183
183
|
assert_equal ["Tuesday and Thursday of every other week"], schedules.map(&:humanize)
|
184
184
|
end
|
185
|
-
|
186
|
-
|
185
|
+
|
186
|
+
|
187
187
|
# ... when some dates are missing from the input array
|
188
|
-
|
188
|
+
|
189
189
|
test "should infer a weekly schedule (missing dates)" do
|
190
190
|
dates = %w{2012-3-4 2012-3-11 2012-3-25}
|
191
191
|
schedules = Schedule.infer(dates)
|
192
192
|
assert_equal ["Every Sunday"], schedules.map(&:humanize)
|
193
193
|
end
|
194
|
-
|
194
|
+
|
195
195
|
test "should infer a schedule that occurs several times a week (missing dates)" do
|
196
196
|
dates = %w{2012-3-6 2012-3-8 2012-3-15 2012-3-20 2012-3-27 2012-3-29}
|
197
197
|
schedules = Schedule.infer(dates)
|
198
198
|
assert_equal ["Every Tuesday and Thursday"], schedules.map(&:humanize)
|
199
199
|
end
|
200
|
-
|
201
|
-
|
200
|
+
|
201
|
+
|
202
202
|
# ... when some dates are wrong in the input group
|
203
|
-
|
203
|
+
|
204
204
|
test "should infer a weekly schedule when one day was rescheduled" do
|
205
205
|
dates = %w{2012-10-02 2012-10-09 2012-10-15} # a Tuesday, a Tuesday, and a Monday
|
206
206
|
schedules = Schedule.infer(dates)
|
207
207
|
assert_equal ["Every Tuesday"], schedules.map(&:humanize)
|
208
208
|
end
|
209
|
-
|
209
|
+
|
210
210
|
test "should infer a weekly schedule when the first day was rescheduled" do
|
211
211
|
dates = %w{2012-10-07 2012-10-10 2012-10-17} # a Sunday, a Wednesday, and a Wednesday
|
212
212
|
schedules = Schedule.infer(dates)
|
213
213
|
assert_equal ["Every Wednesday"], schedules.map(&:humanize)
|
214
214
|
end
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
|
219
219
|
# Correctly identifies scenarios where there is no pattern
|
220
|
-
|
220
|
+
|
221
221
|
test "should not try to guess a pattern for input where there is none" do
|
222
222
|
arbitrary_date_ranges = [
|
223
223
|
%w{2013-01-01 2013-03-30 2014-08-19},
|
224
224
|
%w{2012-10-01 2012-10-09 2012-10-17}, # a Monday, a Tuesday, and a Wednesday
|
225
225
|
]
|
226
|
-
|
226
|
+
|
227
227
|
arbitrary_date_ranges.each do |dates|
|
228
228
|
schedules = Schedule.infer(dates)
|
229
229
|
fail "There should be no pattern to the dates #{dates}, but Hiccup guessed \"#{schedules.map(&:humanize)}\"" if schedules.any?
|
230
230
|
end
|
231
231
|
end
|
232
|
-
|
232
|
+
|
233
233
|
test "should create one non-recurring schedule for each break if asked" do
|
234
234
|
dates = %w{2012-03-05 2012-11-28 2012-12-05 2012-12-12} # a random Monday, then three Wednesdays
|
235
235
|
schedules = Schedule.infer(dates, allow_null_schedules: true)
|
236
|
-
|
236
|
+
|
237
237
|
assert_equal ["2012-03-05", "Every Wednesday"], schedules.map(&:humanize)
|
238
238
|
end
|
239
|
-
|
240
|
-
|
241
|
-
|
239
|
+
|
240
|
+
|
241
|
+
|
242
242
|
test "should infer multiple schedules from mixed input" do
|
243
243
|
dates = %w{2012-11-05 2012-11-12 2012-11-19 2012-11-28 2012-12-05 2012-12-12} # three Mondays then three Wednesdays
|
244
244
|
schedules = Schedule.infer(dates)
|
245
|
-
|
245
|
+
|
246
246
|
assert_equal ["Every Monday", "Every Wednesday"], schedules.map(&:humanize)
|
247
247
|
end
|
248
|
-
|
249
|
-
|
250
|
-
|
248
|
+
|
249
|
+
|
250
|
+
|
251
251
|
test "should reject diabolically complex schedules by default" do
|
252
252
|
dates = %w{2012-11-06 2012-11-08 2012-11-15 2012-11-20 2012-11-27 2012-11-29 2013-02-05 2013-02-14 2013-02-21 2013-02-19 2013-02-26 2013-05-07 2013-05-09 2013-05-16 2013-05-28 2013-05-21 2013-05-30}
|
253
253
|
schedules = Schedule.infer(dates)
|
254
254
|
refute_equal ["The first Tuesday, second Thursday, third Thursday, third Tuesday, fourth Tuesday, and fifth Thursday of every third month"], schedules.map(&:humanize)
|
255
255
|
end
|
256
|
-
|
256
|
+
|
257
257
|
test "should infer diabolically complex schedules on demand" do
|
258
258
|
dates = %w{2012-11-06 2012-11-08 2012-11-15 2012-11-20 2012-11-27 2012-11-29 2013-02-05 2013-02-14 2013-02-21 2013-02-19 2013-02-26 2013-05-07 2013-05-09 2013-05-16 2013-05-28 2013-05-21 2013-05-30}
|
259
259
|
schedules = Schedule.infer(dates, max_complexity: 99)
|
260
260
|
assert_equal ["The first Tuesday, second Thursday, third Thursday, third Tuesday, fourth Tuesday, and fifth Thursday of every third month"], schedules.map(&:humanize)
|
261
261
|
end
|
262
|
-
|
263
|
-
|
264
|
-
|
262
|
+
|
263
|
+
|
264
|
+
|
265
265
|
if ENV['PERFORMANCE_TEST']
|
266
266
|
test "performance test" do
|
267
267
|
Benchmark.bm(20) do |x|
|
@@ -275,8 +275,8 @@ class InferableTest < ActiveSupport::TestCase
|
|
275
275
|
end
|
276
276
|
end
|
277
277
|
end
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
278
|
+
|
279
|
+
|
280
|
+
|
281
|
+
|
282
282
|
end
|