chronic 0.6.3 → 0.10.2

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 (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -3
  3. data/.travis.yml +8 -0
  4. data/HISTORY.md +76 -0
  5. data/README.md +47 -42
  6. data/Rakefile +30 -12
  7. data/chronic.gemspec +10 -4
  8. data/lib/chronic/date.rb +82 -0
  9. data/lib/chronic/grabber.rb +9 -7
  10. data/lib/chronic/handler.rb +47 -40
  11. data/lib/chronic/handlers.rb +240 -28
  12. data/lib/chronic/numerizer.rb +11 -2
  13. data/lib/chronic/ordinal.rb +28 -23
  14. data/lib/chronic/parser.rb +268 -0
  15. data/lib/chronic/pointer.rb +9 -7
  16. data/lib/chronic/repeater.rb +58 -48
  17. data/lib/chronic/repeaters/repeater_day.rb +4 -3
  18. data/lib/chronic/repeaters/repeater_day_name.rb +5 -4
  19. data/lib/chronic/repeaters/repeater_day_portion.rb +33 -18
  20. data/lib/chronic/repeaters/repeater_fortnight.rb +4 -3
  21. data/lib/chronic/repeaters/repeater_hour.rb +4 -3
  22. data/lib/chronic/repeaters/repeater_minute.rb +4 -3
  23. data/lib/chronic/repeaters/repeater_month.rb +5 -4
  24. data/lib/chronic/repeaters/repeater_month_name.rb +4 -3
  25. data/lib/chronic/repeaters/repeater_season.rb +5 -3
  26. data/lib/chronic/repeaters/repeater_second.rb +4 -3
  27. data/lib/chronic/repeaters/repeater_time.rb +35 -25
  28. data/lib/chronic/repeaters/repeater_week.rb +4 -3
  29. data/lib/chronic/repeaters/repeater_weekday.rb +4 -3
  30. data/lib/chronic/repeaters/repeater_weekend.rb +4 -3
  31. data/lib/chronic/repeaters/repeater_year.rb +6 -5
  32. data/lib/chronic/scalar.rb +40 -68
  33. data/lib/chronic/season.rb +1 -12
  34. data/lib/chronic/separator.rb +142 -23
  35. data/lib/chronic/sign.rb +49 -0
  36. data/lib/chronic/span.rb +2 -2
  37. data/lib/chronic/tag.rb +10 -15
  38. data/lib/chronic/time.rb +40 -0
  39. data/lib/chronic/time_zone.rb +9 -7
  40. data/lib/chronic/token.rb +16 -10
  41. data/lib/chronic.rb +109 -70
  42. data/test/helper.rb +8 -2
  43. data/test/{test_Chronic.rb → test_chronic.rb} +69 -34
  44. data/test/{test_DaylightSavings.rb → test_daylight_savings.rb} +1 -1
  45. data/test/{test_Handler.rb → test_handler.rb} +38 -14
  46. data/test/{test_MiniDate.rb → test_mini_date.rb} +9 -9
  47. data/test/{test_Numerizer.rb → test_numerizer.rb} +16 -2
  48. data/test/test_parsing.rb +392 -22
  49. data/test/{test_RepeaterDayName.rb → test_repeater_day_name.rb} +1 -1
  50. data/test/test_repeater_day_portion.rb +254 -0
  51. data/test/{test_RepeaterFortnight.rb → test_repeater_fortnight.rb} +1 -1
  52. data/test/{test_RepeaterHour.rb → test_repeater_hour.rb} +1 -1
  53. data/test/{test_RepeaterMinute.rb → test_repeater_minute.rb} +1 -1
  54. data/test/{test_RepeaterMonth.rb → test_repeater_month.rb} +1 -1
  55. data/test/{test_RepeaterMonthName.rb → test_repeater_month_name.rb} +1 -1
  56. data/test/{test_RepeaterSeason.rb → test_repeater_season.rb} +1 -1
  57. data/test/{test_RepeaterTime.rb → test_repeater_time.rb} +19 -1
  58. data/test/{test_RepeaterWeek.rb → test_repeater_week.rb} +1 -1
  59. data/test/{test_RepeaterWeekday.rb → test_repeater_weekday.rb} +1 -1
  60. data/test/{test_RepeaterWeekend.rb → test_repeater_weekend.rb} +1 -1
  61. data/test/{test_RepeaterYear.rb → test_repeater_year.rb} +1 -1
  62. data/test/{test_Span.rb → test_span.rb} +2 -2
  63. data/test/{test_Token.rb → test_token.rb} +1 -1
  64. metadata +129 -87
  65. data/.gemtest +0 -0
  66. data/.yardopts +0 -3
  67. data/lib/chronic/chronic.rb +0 -323
@@ -1,15 +1,19 @@
1
1
  require 'helper'
2
2
 
3
- class TestChronic < Test::Unit::TestCase
3
+ class TestChronic < TestCase
4
4
 
5
5
  def setup
6
6
  # Wed Aug 16 14:00:00 UTC 2006
7
7
  @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
8
8
  end
9
9
 
10
+ def test_pre_normalize
11
+ assert_equal Chronic::Parser.new.pre_normalize('12:55 pm'), Chronic::Parser.new.pre_normalize('12.55 pm')
12
+ end
13
+
10
14
  def test_pre_normalize_numerized_string
11
15
  string = 'two and a half years'
12
- assert_equal Chronic::Numerizer.numerize(string), Chronic.pre_normalize(string)
16
+ assert_equal Chronic::Numerizer.numerize(string), Chronic::Parser.new.pre_normalize(string)
13
17
  end
14
18
 
15
19
  def test_post_normalize_am_pm_aliases
@@ -42,50 +46,34 @@ class TestChronic < Test::Unit::TestCase
42
46
 
43
47
  def test_guess
44
48
  span = Chronic::Span.new(Time.local(2006, 8, 16, 0), Time.local(2006, 8, 17, 0))
45
- assert_equal Time.local(2006, 8, 16, 12), Chronic.guess(span)
49
+ assert_equal Time.local(2006, 8, 16, 12), Chronic::Parser.new.guess(span)
46
50
 
47
51
  span = Chronic::Span.new(Time.local(2006, 8, 16, 0), Time.local(2006, 8, 17, 0, 0, 1))
48
- assert_equal Time.local(2006, 8, 16, 12), Chronic.guess(span)
52
+ assert_equal Time.local(2006, 8, 16, 12), Chronic::Parser.new.guess(span)
49
53
 
50
54
  span = Chronic::Span.new(Time.local(2006, 11), Time.local(2006, 12))
51
- assert_equal Time.local(2006, 11, 16), Chronic.guess(span)
52
- end
53
-
54
- def test_now
55
- Chronic.parse('now', :now => Time.local(2006, 01))
56
- assert_equal Time.local(2006, 01), Chronic.now
57
-
58
- Chronic.parse('now', :now => Time.local(2007, 01))
59
- assert_equal Time.local(2007, 01), Chronic.now
55
+ assert_equal Time.local(2006, 11, 16), Chronic::Parser.new.guess(span)
60
56
  end
61
57
 
62
58
  def test_endian_definitions
63
59
  # middle, little
64
60
  endians = [
65
- Chronic::Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_day, :separator_slash_or_dash, :scalar_year, :separator_at?, 'time?'], :handle_sm_sd_sy),
66
- Chronic::Handler.new([:scalar_day, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_year, :separator_at?, 'time?'], :handle_sd_sm_sy)
61
+ Chronic::Handler.new([:scalar_month, [:separator_slash, :separator_dash], :scalar_day, [:separator_slash, :separator_dash], :scalar_year, :separator_at?, 'time?'], :handle_sm_sd_sy),
62
+ Chronic::Handler.new([:scalar_month, [:separator_slash, :separator_dash], :scalar_day, :separator_at?, 'time?'], :handle_sm_sd),
63
+ Chronic::Handler.new([:scalar_day, [:separator_slash, :separator_dash], :scalar_month, :separator_at?, 'time?'], :handle_sd_sm),
64
+ Chronic::Handler.new([:scalar_day, [:separator_slash, :separator_dash], :scalar_month, [:separator_slash, :separator_dash], :scalar_year, :separator_at?, 'time?'], :handle_sd_sm_sy)
67
65
  ]
68
66
 
69
- assert_equal endians, Chronic.definitions[:endian]
67
+ assert_equal endians, Chronic::Parser.new.definitions[:endian]
70
68
 
71
- defs = Chronic.definitions(:endian_precedence => :little)
69
+ defs = Chronic::Parser.new.definitions(:endian_precedence => :little)
72
70
  assert_equal endians.reverse, defs[:endian]
73
71
 
74
- defs = Chronic.definitions(:endian_precedence => [:little, :middle])
72
+ defs = Chronic::Parser.new.definitions(:endian_precedence => [:little, :middle])
75
73
  assert_equal endians.reverse, defs[:endian]
76
74
 
77
75
  assert_raises(ArgumentError) do
78
- Chronic.definitions(:endian_precedence => :invalid)
79
- end
80
- end
81
-
82
- def test_passing_options
83
- assert_raises(ArgumentError) do
84
- Chronic.parse('now', :invalid => :option)
85
- end
86
-
87
- assert_raises(ArgumentError) do
88
- Chronic.parse('now', :context => :invalid_context)
76
+ Chronic::Parser.new.definitions(:endian_precedence => :invalid)
89
77
  end
90
78
  end
91
79
 
@@ -131,11 +119,7 @@ class TestChronic < Test::Unit::TestCase
131
119
  assert_equal Time.local(2004, 3, 4), Chronic.construct(2004, 2, 33)
132
120
  assert_equal Time.local(2000, 3, 4), Chronic.construct(2000, 2, 33)
133
121
 
134
- assert_nothing_raised do
135
- Chronic.construct(2006, 1, 56)
136
- end
137
-
138
- assert_raise(RuntimeError) do
122
+ assert_raises(RuntimeError) do
139
123
  Chronic.construct(2006, 1, 57)
140
124
  end
141
125
  end
@@ -145,4 +129,55 @@ class TestChronic < Test::Unit::TestCase
145
129
  assert_equal Time.local(2005, 12), Chronic.construct(2000, 72)
146
130
  end
147
131
 
132
+ def test_time
133
+ org = Chronic.time_class
134
+ begin
135
+ Chronic.time_class = ::Time
136
+ assert_equal ::Time.new(2013, 8, 27, 20, 30, 40, '+05:30'), Chronic.construct(2013, 8, 27, 20, 30, 40, '+05:30')
137
+ assert_equal ::Time.new(2013, 8, 27, 20, 30, 40, '-08:00'), Chronic.construct(2013, 8, 27, 20, 30, 40, -28800)
138
+ ensure
139
+ Chronic.time_class = org
140
+ end
141
+ end
142
+
143
+ def test_date
144
+ org = Chronic.time_class
145
+ begin
146
+ Chronic.time_class = ::Date
147
+ assert_equal Date.new(2013, 8, 27), Chronic.construct(2013, 8, 27)
148
+ ensure
149
+ Chronic.time_class = org
150
+ end
151
+ end
152
+
153
+ def test_datetime
154
+ org = Chronic.time_class
155
+ begin
156
+ Chronic.time_class = ::DateTime
157
+ assert_equal DateTime.new(2013, 8, 27, 20, 30, 40, '+05:30'), Chronic.construct(2013, 8, 27, 20, 30, 40, '+05:30')
158
+ assert_equal DateTime.new(2013, 8, 27, 20, 30, 40, '-08:00'), Chronic.construct(2013, 8, 27, 20, 30, 40, -28800)
159
+ ensure
160
+ Chronic.time_class = org
161
+ end
162
+ end
163
+
164
+ def test_activesupport
165
+ =begin
166
+ # ActiveSupport needs MiniTest '~> 4.2' which conflicts with '~> 5.0'
167
+ require 'active_support/time'
168
+ org = Chronic.time_class
169
+ org_zone = ::Time.zone
170
+ begin
171
+ ::Time.zone = "Tokyo"
172
+ Chronic.time_class = ::Time.zone
173
+ assert_equal Time.new(2013, 8, 27, 20, 30, 40, '+09:00'), Chronic.construct(2013, 8, 27, 20, 30, 40)
174
+ ::Time.zone = "Indiana (East)"
175
+ Chronic.time_class = ::Time.zone
176
+ assert_equal Time.new(2013, 8, 27, 20, 30, 40, -14400), Chronic.construct(2013, 8, 27, 20, 30, 40)
177
+ ensure
178
+ Chronic.time_class = org
179
+ ::Time.zone = org_zone
180
+ end
181
+ =end
182
+ end
148
183
  end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestDaylightSavings < Test::Unit::TestCase
3
+ class TestDaylightSavings < TestCase
4
4
 
5
5
  def setup
6
6
  @begin_daylight_savings = Time.local(2008, 3, 9, 5, 0, 0, 0)
@@ -1,24 +1,28 @@
1
1
  require 'helper'
2
2
 
3
- class TestHandler < Test::Unit::TestCase
3
+ class TestHandler < TestCase
4
4
 
5
5
  def setup
6
6
  # Wed Aug 16 14:00:00 UTC 2006
7
7
  @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
8
8
  end
9
9
 
10
+ def definitions
11
+ @definitions ||= Chronic::Parser.new.definitions
12
+ end
13
+
10
14
  def test_handler_class_1
11
15
  handler = Chronic::Handler.new([:repeater], :handler)
12
16
 
13
17
  tokens = [Chronic::Token.new('friday')]
14
18
  tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
15
19
 
16
- assert handler.match(tokens, Chronic.definitions)
20
+ assert handler.match(tokens, definitions)
17
21
 
18
22
  tokens << Chronic::Token.new('afternoon')
19
23
  tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
20
24
 
21
- assert !handler.match(tokens, Chronic.definitions)
25
+ assert !handler.match(tokens, definitions)
22
26
  end
23
27
 
24
28
  def test_handler_class_2
@@ -27,17 +31,17 @@ class TestHandler < Test::Unit::TestCase
27
31
  tokens = [Chronic::Token.new('friday')]
28
32
  tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
29
33
 
30
- assert handler.match(tokens, Chronic.definitions)
34
+ assert handler.match(tokens, definitions)
31
35
 
32
36
  tokens << Chronic::Token.new('afternoon')
33
37
  tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
34
38
 
35
- assert handler.match(tokens, Chronic.definitions)
39
+ assert handler.match(tokens, definitions)
36
40
 
37
41
  tokens << Chronic::Token.new('afternoon')
38
42
  tokens[2].tag(Chronic::RepeaterDayPortion.new(:afternoon))
39
43
 
40
- assert !handler.match(tokens, Chronic.definitions)
44
+ assert !handler.match(tokens, definitions)
41
45
  end
42
46
 
43
47
  def test_handler_class_3
@@ -46,12 +50,12 @@ class TestHandler < Test::Unit::TestCase
46
50
  tokens = [Chronic::Token.new('friday')]
47
51
  tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
48
52
 
49
- assert handler.match(tokens, Chronic.definitions)
53
+ assert handler.match(tokens, definitions)
50
54
 
51
55
  tokens << Chronic::Token.new('afternoon')
52
56
  tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
53
57
 
54
- assert !handler.match(tokens, Chronic.definitions)
58
+ assert !handler.match(tokens, definitions)
55
59
  end
56
60
 
57
61
  def test_handler_class_4
@@ -60,12 +64,12 @@ class TestHandler < Test::Unit::TestCase
60
64
  tokens = [Chronic::Token.new('may')]
61
65
  tokens[0].tag(Chronic::RepeaterMonthName.new(:may))
62
66
 
63
- assert !handler.match(tokens, Chronic.definitions)
67
+ assert !handler.match(tokens, definitions)
64
68
 
65
69
  tokens << Chronic::Token.new('27')
66
70
  tokens[1].tag(Chronic::ScalarDay.new(27))
67
71
 
68
- assert handler.match(tokens, Chronic.definitions)
72
+ assert handler.match(tokens, definitions)
69
73
  end
70
74
 
71
75
  def test_handler_class_5
@@ -74,17 +78,17 @@ class TestHandler < Test::Unit::TestCase
74
78
  tokens = [Chronic::Token.new('friday')]
75
79
  tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
76
80
 
77
- assert handler.match(tokens, Chronic.definitions)
81
+ assert handler.match(tokens, definitions)
78
82
 
79
83
  tokens << Chronic::Token.new('5:00')
80
84
  tokens[1].tag(Chronic::RepeaterTime.new('5:00'))
81
85
 
82
- assert handler.match(tokens, Chronic.definitions)
86
+ assert handler.match(tokens, definitions)
83
87
 
84
88
  tokens << Chronic::Token.new('pm')
85
89
  tokens[2].tag(Chronic::RepeaterDayPortion.new(:pm))
86
90
 
87
- assert handler.match(tokens, Chronic.definitions)
91
+ assert handler.match(tokens, definitions)
88
92
  end
89
93
 
90
94
  def test_handler_class_6
@@ -98,7 +102,27 @@ class TestHandler < Test::Unit::TestCase
98
102
  tokens[1].tag(Chronic::RepeaterYear.new(:year))
99
103
  tokens[2].tag(Chronic::Pointer.new(:past))
100
104
 
101
- assert handler.match(tokens, Chronic.definitions)
105
+ assert handler.match(tokens, definitions)
106
+ end
107
+
108
+ def test_handler_class_7
109
+ handler = Chronic::Handler.new([[:separator_on, :separator_at], :scalar], :handler)
110
+
111
+ tokens = [Chronic::Token.new('at'),
112
+ Chronic::Token.new('14')]
113
+
114
+ tokens[0].tag(Chronic::SeparatorAt.new('at'))
115
+ tokens[1].tag(Chronic::Scalar.new(14))
116
+
117
+ assert handler.match(tokens, definitions)
118
+
119
+ tokens = [Chronic::Token.new('on'),
120
+ Chronic::Token.new('15')]
121
+
122
+ tokens[0].tag(Chronic::SeparatorOn.new('on'))
123
+ tokens[1].tag(Chronic::Scalar.new(15))
124
+
125
+ assert handler.match(tokens, definitions)
102
126
  end
103
127
 
104
128
  end
@@ -1,32 +1,32 @@
1
1
  require 'helper'
2
2
 
3
- class TestMiniDate < Test::Unit::TestCase
3
+ class TestMiniDate < TestCase
4
4
  def test_valid_month
5
- assert_raise(ArgumentError){ Chronic::MiniDate.new(0,12) }
6
- assert_raise(ArgumentError){ Chronic::MiniDate.new(13,1) }
5
+ assert_raises(ArgumentError){ Chronic::MiniDate.new(0,12) }
6
+ assert_raises(ArgumentError){ Chronic::MiniDate.new(13,1) }
7
7
  end
8
-
8
+
9
9
  def test_is_between
10
10
  m=Chronic::MiniDate.new(3,2)
11
11
  assert m.is_between?(Chronic::MiniDate.new(2,4), Chronic::MiniDate.new(4,7))
12
- assert !m.is_between?(Chronic::MiniDate.new(1,5), Chronic::MiniDate.new(2,7))
13
-
12
+ assert !m.is_between?(Chronic::MiniDate.new(1,5), Chronic::MiniDate.new(2,7))
13
+
14
14
  #There was a hang if date tested is in december and outside the testing range
15
15
  m=Chronic::MiniDate.new(12,24)
16
16
  assert !m.is_between?(Chronic::MiniDate.new(10,1), Chronic::MiniDate.new(12,21))
17
17
  end
18
-
18
+
19
19
  def test_is_between_short_range
20
20
  m=Chronic::MiniDate.new(5,10)
21
21
  assert m.is_between?(Chronic::MiniDate.new(5,3), Chronic::MiniDate.new(5,12))
22
22
  assert !m.is_between?(Chronic::MiniDate.new(5,11), Chronic::MiniDate.new(5,15))
23
23
  end
24
-
24
+
25
25
  def test_is_between_wrapping_range
26
26
  m=Chronic::MiniDate.new(1,1)
27
27
  assert m.is_between?(Chronic::MiniDate.new(11,11), Chronic::MiniDate.new(2,2))
28
28
  m=Chronic::MiniDate.new(12,12)
29
29
  assert m.is_between?(Chronic::MiniDate.new(11,11), Chronic::MiniDate.new(1,5))
30
30
  end
31
-
31
+
32
32
  end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class ParseNumbersTest < Test::Unit::TestCase
3
+ class ParseNumbersTest < TestCase
4
4
 
5
5
  def test_straight_parsing
6
6
  strings = {
@@ -57,12 +57,26 @@ class ParseNumbersTest < Test::Unit::TestCase
57
57
  'second day' => '2nd day',
58
58
  'second of may' => '2nd of may',
59
59
  'fifth' => '5th',
60
+ 'twelfth' => '12th',
61
+ 'twentieth' => '20th',
62
+ 'thirtieth' => '30th',
63
+ 'fourtieth' => '40th',
64
+ 'fiftieth' => '50th',
65
+ 'sixtieth' => '60th',
66
+ 'seventieth' => '70th',
67
+ 'eightieth' => '80th',
68
+ 'ninetieth' => '90th',
69
+ 'hundredth' => '100th',
70
+ 'thousandth' => '1000th',
71
+ 'millionth' => '1000000th',
72
+ 'billionth' => '1000000000th',
73
+ 'trillionth' => '1000000000000th',
60
74
  'twenty third' => '23rd',
61
75
  'first day month two' => '1st day month 2'
62
76
  }.each do |key, val|
63
77
  # Use pre_normalize here instead of Numerizer directly because
64
78
  # pre_normalize deals with parsing 'second' appropriately
65
- assert_equal val, Chronic.pre_normalize(key)
79
+ assert_equal val, Chronic::Parser.new.pre_normalize(key)
66
80
  end
67
81
  end
68
82