slaxor-chronic 0.3.1

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.
Files changed (55) hide show
  1. data/HISTORY.md +76 -0
  2. data/LICENSE +21 -0
  3. data/Manifest.txt +47 -0
  4. data/README.md +165 -0
  5. data/Rakefile +146 -0
  6. data/benchmark/benchmark.rb +13 -0
  7. data/lib/chronic.rb +127 -0
  8. data/lib/chronic/chronic.rb +249 -0
  9. data/lib/chronic/grabber.rb +26 -0
  10. data/lib/chronic/handlers.rb +524 -0
  11. data/lib/chronic/numerizer/numerizer.rb +97 -0
  12. data/lib/chronic/ordinal.rb +40 -0
  13. data/lib/chronic/pointer.rb +27 -0
  14. data/lib/chronic/repeater.rb +129 -0
  15. data/lib/chronic/repeaters/repeater_day.rb +52 -0
  16. data/lib/chronic/repeaters/repeater_day_name.rb +51 -0
  17. data/lib/chronic/repeaters/repeater_day_portion.rb +94 -0
  18. data/lib/chronic/repeaters/repeater_fortnight.rb +70 -0
  19. data/lib/chronic/repeaters/repeater_hour.rb +57 -0
  20. data/lib/chronic/repeaters/repeater_minute.rb +57 -0
  21. data/lib/chronic/repeaters/repeater_month.rb +66 -0
  22. data/lib/chronic/repeaters/repeater_month_name.rb +98 -0
  23. data/lib/chronic/repeaters/repeater_season.rb +150 -0
  24. data/lib/chronic/repeaters/repeater_season_name.rb +45 -0
  25. data/lib/chronic/repeaters/repeater_second.rb +41 -0
  26. data/lib/chronic/repeaters/repeater_time.rb +124 -0
  27. data/lib/chronic/repeaters/repeater_week.rb +73 -0
  28. data/lib/chronic/repeaters/repeater_weekday.rb +77 -0
  29. data/lib/chronic/repeaters/repeater_weekend.rb +65 -0
  30. data/lib/chronic/repeaters/repeater_year.rb +64 -0
  31. data/lib/chronic/scalar.rb +76 -0
  32. data/lib/chronic/separator.rb +91 -0
  33. data/lib/chronic/time_zone.rb +23 -0
  34. data/slaxor-chronic.gemspec +85 -0
  35. data/test/helper.rb +7 -0
  36. data/test/test_Chronic.rb +49 -0
  37. data/test/test_DaylightSavings.rb +118 -0
  38. data/test/test_Handler.rb +109 -0
  39. data/test/test_Numerizer.rb +51 -0
  40. data/test/test_RepeaterDayName.rb +51 -0
  41. data/test/test_RepeaterFortnight.rb +62 -0
  42. data/test/test_RepeaterHour.rb +64 -0
  43. data/test/test_RepeaterMinute.rb +34 -0
  44. data/test/test_RepeaterMonth.rb +46 -0
  45. data/test/test_RepeaterMonthName.rb +56 -0
  46. data/test/test_RepeaterTime.rb +70 -0
  47. data/test/test_RepeaterWeek.rb +62 -0
  48. data/test/test_RepeaterWeekday.rb +55 -0
  49. data/test/test_RepeaterWeekend.rb +74 -0
  50. data/test/test_RepeaterYear.rb +62 -0
  51. data/test/test_Span.rb +23 -0
  52. data/test/test_Time.rb +49 -0
  53. data/test/test_Token.rb +25 -0
  54. data/test/test_parsing.rb +710 -0
  55. metadata +138 -0
@@ -0,0 +1,109 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class TestHandler < Test::Unit::TestCase
4
+
5
+ def setup
6
+ # Wed Aug 16 14:00:00 UTC 2006
7
+ @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
8
+ end
9
+
10
+ def test_handler_class_1
11
+ handler = Chronic::Handler.new([:repeater], :handler)
12
+
13
+ tokens = [Chronic::Token.new('friday')]
14
+ tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
15
+
16
+ assert handler.match(tokens, Chronic.definitions)
17
+
18
+ tokens << Chronic::Token.new('afternoon')
19
+ tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
20
+
21
+ assert !handler.match(tokens, Chronic.definitions)
22
+ end
23
+
24
+ def test_handler_class_2
25
+ handler = Chronic::Handler.new([:repeater, :repeater?], :handler)
26
+
27
+ tokens = [Chronic::Token.new('friday')]
28
+ tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
29
+
30
+ assert handler.match(tokens, Chronic.definitions)
31
+
32
+ tokens << Chronic::Token.new('afternoon')
33
+ tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
34
+
35
+ assert handler.match(tokens, Chronic.definitions)
36
+
37
+ tokens << Chronic::Token.new('afternoon')
38
+ tokens[2].tag(Chronic::RepeaterDayPortion.new(:afternoon))
39
+
40
+ assert !handler.match(tokens, Chronic.definitions)
41
+ end
42
+
43
+ def test_handler_class_3
44
+ handler = Chronic::Handler.new([:repeater, 'time?'], :handler)
45
+
46
+ tokens = [Chronic::Token.new('friday')]
47
+ tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
48
+
49
+ assert handler.match(tokens, Chronic.definitions)
50
+
51
+ tokens << Chronic::Token.new('afternoon')
52
+ tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
53
+
54
+ assert !handler.match(tokens, Chronic.definitions)
55
+ end
56
+
57
+ def test_handler_class_4
58
+ handler = Chronic::Handler.new([:repeater_month_name, :scalar_day, 'time?'], :handler)
59
+
60
+ tokens = [Chronic::Token.new('may')]
61
+ tokens[0].tag(Chronic::RepeaterMonthName.new(:may))
62
+
63
+ assert !handler.match(tokens, Chronic.definitions)
64
+
65
+ tokens << Chronic::Token.new('27')
66
+ tokens[1].tag(Chronic::ScalarDay.new(27))
67
+
68
+ assert handler.match(tokens, Chronic.definitions)
69
+ end
70
+
71
+ def test_handler_class_5
72
+ handler = Chronic::Handler.new([:repeater, 'time?'], :handler)
73
+
74
+ tokens = [Chronic::Token.new('friday')]
75
+ tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
76
+
77
+ assert handler.match(tokens, Chronic.definitions)
78
+
79
+ tokens << Chronic::Token.new('5:00')
80
+ tokens[1].tag(Chronic::RepeaterTime.new('5:00'))
81
+
82
+ assert handler.match(tokens, Chronic.definitions)
83
+
84
+ tokens << Chronic::Token.new('pm')
85
+ tokens[2].tag(Chronic::RepeaterDayPortion.new(:pm))
86
+
87
+ assert handler.match(tokens, Chronic.definitions)
88
+ end
89
+
90
+ def test_handler_class_6
91
+ handler = Chronic::Handler.new([:scalar, :repeater, :pointer], :handler)
92
+
93
+ tokens = [Chronic::Token.new('3'),
94
+ Chronic::Token.new('years'),
95
+ Chronic::Token.new('past')]
96
+
97
+ tokens[0].tag(Chronic::Scalar.new(3))
98
+ tokens[1].tag(Chronic::RepeaterYear.new(:year))
99
+ tokens[2].tag(Chronic::Pointer.new(:past))
100
+
101
+ assert handler.match(tokens, Chronic.definitions)
102
+ end
103
+
104
+ def test_constantize
105
+ handler = Chronic::Handler.new([], :handler)
106
+ assert_equal Chronic::RepeaterTime, handler.constantize(:repeater_time)
107
+ end
108
+
109
+ end
@@ -0,0 +1,51 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class ParseNumbersTest < Test::Unit::TestCase
4
+
5
+ def test_straight_parsing
6
+ strings = { 1 => 'one',
7
+ 5 => 'five',
8
+ 10 => 'ten',
9
+ 11 => 'eleven',
10
+ 12 => 'twelve',
11
+ 13 => 'thirteen',
12
+ 14 => 'fourteen',
13
+ 15 => 'fifteen',
14
+ 16 => 'sixteen',
15
+ 17 => 'seventeen',
16
+ 18 => 'eighteen',
17
+ 19 => 'nineteen',
18
+ 20 => 'twenty',
19
+ 27 => 'twenty seven',
20
+ 31 => 'thirty-one',
21
+ 59 => 'fifty nine',
22
+ 100 => 'a hundred',
23
+ 100 => 'one hundred',
24
+ 150 => 'one hundred and fifty',
25
+ # 150 => 'one fifty',
26
+ 200 => 'two-hundred',
27
+ 500 => '5 hundred',
28
+ 999 => 'nine hundred and ninety nine',
29
+ 1_000 => 'one thousand',
30
+ 1_200 => 'twelve hundred',
31
+ 1_200 => 'one thousand two hundred',
32
+ 17_000 => 'seventeen thousand',
33
+ 21_473 => 'twentyone-thousand-four-hundred-and-seventy-three',
34
+ 74_002 => 'seventy four thousand and two',
35
+ 99_999 => 'ninety nine thousand nine hundred ninety nine',
36
+ 100_000 => '100 thousand',
37
+ 250_000 => 'two hundred fifty thousand',
38
+ 1_000_000 => 'one million',
39
+ 1_250_007 => 'one million two hundred fifty thousand and seven',
40
+ 1_000_000_000 => 'one billion',
41
+ 1_000_000_001 => 'one billion and one' }
42
+
43
+ strings.keys.sort.each do |key|
44
+ assert_equal key, Numerizer.numerize(strings[key]).to_i
45
+ end
46
+ end
47
+
48
+ def test_edges
49
+ assert_equal "27 Oct 2006 7:30am", Numerizer.numerize("27 Oct 2006 7:30am")
50
+ end
51
+ end
@@ -0,0 +1,51 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class TestRepeaterDayName < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
7
+ end
8
+
9
+ def test_match
10
+ token = Chronic::Token.new('saturday')
11
+ repeater = Chronic::Repeater.scan_for_day_names(token)
12
+ assert_equal Chronic::RepeaterDayName, repeater.class
13
+ assert_equal :saturday, repeater.type
14
+
15
+ token = Chronic::Token.new('sunday')
16
+ repeater = Chronic::Repeater.scan_for_day_names(token)
17
+ assert_equal Chronic::RepeaterDayName, repeater.class
18
+ assert_equal :sunday, repeater.type
19
+ end
20
+
21
+ def test_next_future
22
+ mondays = Chronic::RepeaterDayName.new(:monday)
23
+ mondays.start = @now
24
+
25
+ span = mondays.next(:future)
26
+
27
+ assert_equal Time.local(2006, 8, 21), span.begin
28
+ assert_equal Time.local(2006, 8, 22), span.end
29
+
30
+ span = mondays.next(:future)
31
+
32
+ assert_equal Time.local(2006, 8, 28), span.begin
33
+ assert_equal Time.local(2006, 8, 29), span.end
34
+ end
35
+
36
+ def test_next_past
37
+ mondays = Chronic::RepeaterDayName.new(:monday)
38
+ mondays.start = @now
39
+
40
+ span = mondays.next(:past)
41
+
42
+ assert_equal Time.local(2006, 8, 14), span.begin
43
+ assert_equal Time.local(2006, 8, 15), span.end
44
+
45
+ span = mondays.next(:past)
46
+
47
+ assert_equal Time.local(2006, 8, 7), span.begin
48
+ assert_equal Time.local(2006, 8, 8), span.end
49
+ end
50
+
51
+ end
@@ -0,0 +1,62 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class TestRepeaterFortnight < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
7
+ end
8
+
9
+ def test_next_future
10
+ fortnights = Chronic::RepeaterFortnight.new(:fortnight)
11
+ fortnights.start = @now
12
+
13
+ next_fortnight = fortnights.next(:future)
14
+ assert_equal Time.local(2006, 8, 20), next_fortnight.begin
15
+ assert_equal Time.local(2006, 9, 3), next_fortnight.end
16
+
17
+ next_next_fortnight = fortnights.next(:future)
18
+ assert_equal Time.local(2006, 9, 3), next_next_fortnight.begin
19
+ assert_equal Time.local(2006, 9, 17), next_next_fortnight.end
20
+ end
21
+
22
+ def test_next_past
23
+ fortnights = Chronic::RepeaterFortnight.new(:fortnight)
24
+ fortnights.start = @now
25
+
26
+ last_fortnight = fortnights.next(:past)
27
+ assert_equal Time.local(2006, 7, 30), last_fortnight.begin
28
+ assert_equal Time.local(2006, 8, 13), last_fortnight.end
29
+
30
+ last_last_fortnight = fortnights.next(:past)
31
+ assert_equal Time.local(2006, 7, 16), last_last_fortnight.begin
32
+ assert_equal Time.local(2006, 7, 30), last_last_fortnight.end
33
+ end
34
+
35
+ def test_this_future
36
+ fortnights = Chronic::RepeaterFortnight.new(:fortnight)
37
+ fortnights.start = @now
38
+
39
+ this_fortnight = fortnights.this(:future)
40
+ assert_equal Time.local(2006, 8, 16, 15), this_fortnight.begin
41
+ assert_equal Time.local(2006, 8, 27), this_fortnight.end
42
+ end
43
+
44
+ def test_this_past
45
+ fortnights = Chronic::RepeaterFortnight.new(:fortnight)
46
+ fortnights.start = @now
47
+
48
+ this_fortnight = fortnights.this(:past)
49
+ assert_equal Time.local(2006, 8, 13, 0), this_fortnight.begin
50
+ assert_equal Time.local(2006, 8, 16, 14), this_fortnight.end
51
+ end
52
+
53
+ def test_offset
54
+ span = Chronic::Span.new(@now, @now + 1)
55
+
56
+ offset_span = Chronic::RepeaterWeek.new(:week).offset(span, 3, :future)
57
+
58
+ assert_equal Time.local(2006, 9, 6, 14), offset_span.begin
59
+ assert_equal Time.local(2006, 9, 6, 14, 0, 1), offset_span.end
60
+ end
61
+
62
+ end
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class TestRepeaterHour < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
7
+ end
8
+
9
+ def test_next_future
10
+ hours = Chronic::RepeaterHour.new(:hour)
11
+ hours.start = @now
12
+
13
+ next_hour = hours.next(:future)
14
+ assert_equal Time.local(2006, 8, 16, 15), next_hour.begin
15
+ assert_equal Time.local(2006, 8, 16, 16), next_hour.end
16
+
17
+ next_next_hour = hours.next(:future)
18
+ assert_equal Time.local(2006, 8, 16, 16), next_next_hour.begin
19
+ assert_equal Time.local(2006, 8, 16, 17), next_next_hour.end
20
+ end
21
+
22
+ def test_next_past
23
+ hours = Chronic::RepeaterHour.new(:hour)
24
+ hours.start = @now
25
+
26
+ past_hour = hours.next(:past)
27
+ assert_equal Time.local(2006, 8, 16, 13), past_hour.begin
28
+ assert_equal Time.local(2006, 8, 16, 14), past_hour.end
29
+
30
+ past_past_hour = hours.next(:past)
31
+ assert_equal Time.local(2006, 8, 16, 12), past_past_hour.begin
32
+ assert_equal Time.local(2006, 8, 16, 13), past_past_hour.end
33
+ end
34
+
35
+ def test_this
36
+ @now = Time.local(2006, 8, 16, 14, 30)
37
+
38
+ hours = Chronic::RepeaterHour.new(:hour)
39
+ hours.start = @now
40
+
41
+ this_hour = hours.this(:future)
42
+ assert_equal Time.local(2006, 8, 16, 14, 31), this_hour.begin
43
+ assert_equal Time.local(2006, 8, 16, 15), this_hour.end
44
+
45
+ this_hour = hours.this(:past)
46
+ assert_equal Time.local(2006, 8, 16, 14), this_hour.begin
47
+ assert_equal Time.local(2006, 8, 16, 14, 30), this_hour.end
48
+ end
49
+
50
+ def test_offset
51
+ span = Chronic::Span.new(@now, @now + 1)
52
+
53
+ offset_span = Chronic::RepeaterHour.new(:hour).offset(span, 3, :future)
54
+
55
+ assert_equal Time.local(2006, 8, 16, 17), offset_span.begin
56
+ assert_equal Time.local(2006, 8, 16, 17, 0, 1), offset_span.end
57
+
58
+ offset_span = Chronic::RepeaterHour.new(:hour).offset(span, 24, :past)
59
+
60
+ assert_equal Time.local(2006, 8, 15, 14), offset_span.begin
61
+ assert_equal Time.local(2006, 8, 15, 14, 0, 1), offset_span.end
62
+ end
63
+
64
+ end
@@ -0,0 +1,34 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class TestRepeaterMinute < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @now = Time.local(2008, 6, 25, 7, 15, 30, 0)
7
+ end
8
+
9
+ def test_next_future
10
+ minutes = Chronic::RepeaterMinute.new(:minute)
11
+ minutes.start = @now
12
+
13
+ next_minute = minutes.next(:future)
14
+ assert_equal Time.local(2008, 6, 25, 7, 16), next_minute.begin
15
+ assert_equal Time.local(2008, 6, 25, 7, 17), next_minute.end
16
+
17
+ next_next_minute = minutes.next(:future)
18
+ assert_equal Time.local(2008, 6, 25, 7, 17), next_next_minute.begin
19
+ assert_equal Time.local(2008, 6, 25, 7, 18), next_next_minute.end
20
+ end
21
+
22
+ def test_next_past
23
+ minutes = Chronic::RepeaterMinute.new(:minute)
24
+ minutes.start = @now
25
+
26
+ prev_minute = minutes.next(:past)
27
+ assert_equal Time.local(2008, 6, 25, 7, 14), prev_minute.begin
28
+ assert_equal Time.local(2008, 6, 25, 7, 15), prev_minute.end
29
+
30
+ prev_prev_minute = minutes.next(:past)
31
+ assert_equal Time.local(2008, 6, 25, 7, 13), prev_prev_minute.begin
32
+ assert_equal Time.local(2008, 6, 25, 7, 14), prev_prev_minute.end
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class TestRepeaterMonth < Test::Unit::TestCase
4
+
5
+ def setup
6
+ # Wed Aug 16 14:00:00 2006
7
+ @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
8
+ end
9
+
10
+ def test_offset_by
11
+ # future
12
+
13
+ time = Chronic::RepeaterMonth.new(:month).offset_by(@now, 1, :future)
14
+ assert_equal Time.local(2006, 9, 16, 14), time
15
+
16
+ time = Chronic::RepeaterMonth.new(:month).offset_by(@now, 5, :future)
17
+ assert_equal Time.local(2007, 1, 16, 14), time
18
+
19
+ # past
20
+
21
+ time = Chronic::RepeaterMonth.new(:month).offset_by(@now, 1, :past)
22
+ assert_equal Time.local(2006, 7, 16, 14), time
23
+
24
+ time = Chronic::RepeaterMonth.new(:month).offset_by(@now, 10, :past)
25
+ assert_equal Time.local(2005, 10, 16, 14), time
26
+ end
27
+
28
+ def test_offset
29
+ # future
30
+
31
+ span = Chronic::Span.new(@now, @now + 60)
32
+ offset_span = Chronic::RepeaterMonth.new(:month).offset(span, 1, :future)
33
+
34
+ assert_equal Time.local(2006, 9, 16, 14), offset_span.begin
35
+ assert_equal Time.local(2006, 9, 16, 14, 1), offset_span.end
36
+
37
+ # past
38
+
39
+ span = Chronic::Span.new(@now, @now + 60)
40
+ offset_span = Chronic::RepeaterMonth.new(:month).offset(span, 1, :past)
41
+
42
+ assert_equal Time.local(2006, 7, 16, 14), offset_span.begin
43
+ assert_equal Time.local(2006, 7, 16, 14, 1), offset_span.end
44
+ end
45
+
46
+ end
@@ -0,0 +1,56 @@
1
+ require File.join(File.dirname(__FILE__), *%w[helper])
2
+
3
+ class TestRepeaterMonthName < Test::Unit::TestCase
4
+
5
+ def setup
6
+ # Wed Aug 16 14:00:00 2006
7
+ @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
8
+ end
9
+
10
+ def test_next
11
+ # future
12
+
13
+ mays = Chronic::RepeaterMonthName.new(:may)
14
+ mays.start = @now
15
+
16
+ next_may = mays.next(:future)
17
+ assert_equal Time.local(2007, 5), next_may.begin
18
+ assert_equal Time.local(2007, 6), next_may.end
19
+
20
+ next_next_may = mays.next(:future)
21
+ assert_equal Time.local(2008, 5), next_next_may.begin
22
+ assert_equal Time.local(2008, 6), next_next_may.end
23
+
24
+ decembers = Chronic::RepeaterMonthName.new(:december)
25
+ decembers.start = @now
26
+
27
+ next_december = decembers.next(:future)
28
+ assert_equal Time.local(2006, 12), next_december.begin
29
+ assert_equal Time.local(2007, 1), next_december.end
30
+
31
+ # past
32
+
33
+ mays = Chronic::RepeaterMonthName.new(:may)
34
+ mays.start = @now
35
+
36
+ assert_equal Time.local(2006, 5), mays.next(:past).begin
37
+ assert_equal Time.local(2005, 5), mays.next(:past).begin
38
+ end
39
+
40
+ def test_this
41
+ octobers = Chronic::RepeaterMonthName.new(:october)
42
+ octobers.start = @now
43
+
44
+ this_october = octobers.this(:future)
45
+ assert_equal Time.local(2006, 10, 1), this_october.begin
46
+ assert_equal Time.local(2006, 11, 1), this_october.end
47
+
48
+ aprils = Chronic::RepeaterMonthName.new(:april)
49
+ aprils.start = @now
50
+
51
+ this_april = aprils.this(:past)
52
+ assert_equal Time.local(2006, 4, 1), this_april.begin
53
+ assert_equal Time.local(2006, 5, 1), this_april.end
54
+ end
55
+
56
+ end