chronic 0.1.0
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.
- data/README +119 -0
- data/lib/chronic.rb +30 -0
- data/lib/chronic/chronic.rb +242 -0
- data/lib/chronic/grabber.rb +26 -0
- data/lib/chronic/handlers.rb +405 -0
- data/lib/chronic/ordinal.rb +40 -0
- data/lib/chronic/pointer.rb +27 -0
- data/lib/chronic/repeater.rb +114 -0
- data/lib/chronic/repeaters/repeater_day.rb +40 -0
- data/lib/chronic/repeaters/repeater_day_name.rb +41 -0
- data/lib/chronic/repeaters/repeater_day_portion.rb +93 -0
- data/lib/chronic/repeaters/repeater_fortnight.rb +64 -0
- data/lib/chronic/repeaters/repeater_hour.rb +52 -0
- data/lib/chronic/repeaters/repeater_minute.rb +21 -0
- data/lib/chronic/repeaters/repeater_month.rb +54 -0
- data/lib/chronic/repeaters/repeater_month_name.rb +82 -0
- data/lib/chronic/repeaters/repeater_season.rb +23 -0
- data/lib/chronic/repeaters/repeater_season_name.rb +24 -0
- data/lib/chronic/repeaters/repeater_second.rb +34 -0
- data/lib/chronic/repeaters/repeater_time.rb +106 -0
- data/lib/chronic/repeaters/repeater_week.rb +62 -0
- data/lib/chronic/repeaters/repeater_weekend.rb +11 -0
- data/lib/chronic/repeaters/repeater_year.rb +55 -0
- data/lib/chronic/scalar.rb +74 -0
- data/lib/chronic/separator.rb +76 -0
- data/test/parse_numbers.rb +50 -0
- data/test/suite.rb +9 -0
- data/test/test_Chronic.rb +50 -0
- data/test/test_Handler.rb +110 -0
- data/test/test_RepeaterDayName.rb +52 -0
- data/test/test_RepeaterFortnight.rb +63 -0
- data/test/test_RepeaterHour.rb +65 -0
- data/test/test_RepeaterMonth.rb +47 -0
- data/test/test_RepeaterMonthName.rb +57 -0
- data/test/test_RepeaterTime.rb +72 -0
- data/test/test_RepeaterWeek.rb +63 -0
- data/test/test_RepeaterYear.rb +63 -0
- data/test/test_Span.rb +24 -0
- data/test/test_Token.rb +26 -0
- data/test/test_parsing.rb +472 -0
- metadata +87 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
module Chronic
|
2
|
+
|
3
|
+
class Scalar < Tag #:nodoc:
|
4
|
+
def self.scan(tokens)
|
5
|
+
# for each token
|
6
|
+
tokens.each_index do |i|
|
7
|
+
if t = self.scan_for_scalars(tokens[i], tokens[i + 1]) then tokens[i].tag(t) end
|
8
|
+
if t = self.scan_for_days(tokens[i], tokens[i + 1]) then tokens[i].tag(t) end
|
9
|
+
if t = self.scan_for_months(tokens[i], tokens[i + 1]) then tokens[i].tag(t) end
|
10
|
+
if t = self.scan_for_years(tokens[i], tokens[i + 1]) then tokens[i].tag(t) end
|
11
|
+
end
|
12
|
+
tokens
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.scan_for_scalars(token, post_token)
|
16
|
+
if token.word =~ /^\d*$/
|
17
|
+
unless post_token && %w{am pm morning afternoon evening night}.include?(post_token)
|
18
|
+
return Scalar.new(token.word.to_i)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.scan_for_days(token, post_token)
|
25
|
+
if token.word =~ /^\d\d?$/
|
26
|
+
unless token.word.to_i > 31 || (post_token && %w{am pm morning afternoon evening night}.include?(post_token))
|
27
|
+
return ScalarDay.new(token.word.to_i)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.scan_for_months(token, post_token)
|
34
|
+
if token.word =~ /^\d\d?$/
|
35
|
+
unless token.word.to_i > 12 || (post_token && %w{am pm morning afternoon evening night}.include?(post_token))
|
36
|
+
return ScalarMonth.new(token.word.to_i)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.scan_for_years(token, post_token)
|
43
|
+
if token.word =~ /^\d\d(\d\d)?$/
|
44
|
+
unless post_token && %w{am pm morning afternoon evening night}.include?(post_token)
|
45
|
+
return ScalarYear.new(token.word.to_i)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
return nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_s
|
52
|
+
'scalar'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class ScalarDay < Scalar #:nodoc:
|
57
|
+
def to_s
|
58
|
+
super << '-day-' << @type.to_s
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class ScalarMonth < Scalar #:nodoc:
|
63
|
+
def to_s
|
64
|
+
super << '-month-' << @type.to_s
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class ScalarYear < Scalar #:nodoc:
|
69
|
+
def to_s
|
70
|
+
super << '-year-' << @type.to_s
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Chronic
|
2
|
+
|
3
|
+
class Separator < Tag #:nodoc:
|
4
|
+
def self.scan(tokens)
|
5
|
+
tokens.each_index do |i|
|
6
|
+
if t = self.scan_for_commas(tokens[i]) then tokens[i].tag(t); next end
|
7
|
+
if t = self.scan_for_slash_or_dash(tokens[i]) then tokens[i].tag(t); next end
|
8
|
+
if t = self.scan_for_at(tokens[i]) then tokens[i].tag(t); next end
|
9
|
+
if t = self.scan_for_in(tokens[i]) then tokens[i].tag(t); next end
|
10
|
+
end
|
11
|
+
tokens
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.scan_for_commas(token)
|
15
|
+
scanner = {/^,$/ => :comma}
|
16
|
+
scanner.keys.each do |scanner_item|
|
17
|
+
return SeparatorComma.new(scanner[scanner_item]) if scanner_item =~ token.word
|
18
|
+
end
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.scan_for_slash_or_dash(token)
|
23
|
+
scanner = {/^-$/ => :dash,
|
24
|
+
/^\/$/ => :slash}
|
25
|
+
scanner.keys.each do |scanner_item|
|
26
|
+
return SeparatorSlashOrDash.new(scanner[scanner_item]) if scanner_item =~ token.word
|
27
|
+
end
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.scan_for_at(token)
|
32
|
+
scanner = {/^(at|@)$/ => :at}
|
33
|
+
scanner.keys.each do |scanner_item|
|
34
|
+
return SeparatorAt.new(scanner[scanner_item]) if scanner_item =~ token.word
|
35
|
+
end
|
36
|
+
return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.scan_for_in(token)
|
40
|
+
scanner = {/^in$/ => :in}
|
41
|
+
scanner.keys.each do |scanner_item|
|
42
|
+
return SeparatorIn.new(scanner[scanner_item]) if scanner_item =~ token.word
|
43
|
+
end
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
'separator'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class SeparatorComma < Separator #:nodoc:
|
53
|
+
def to_s
|
54
|
+
super << '-comma'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class SeparatorSlashOrDash < Separator #:nodoc:
|
59
|
+
def to_s
|
60
|
+
super << '-slashordash-' << @type.to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class SeparatorAt < Separator #:nodoc:
|
65
|
+
def to_s
|
66
|
+
super << '-at'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class SeparatorIn < Separator #:nodoc:
|
71
|
+
def to_s
|
72
|
+
super << '-in'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
__END__
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class ParseNumbersTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_parse
|
8
|
+
strings = {1 => 'one',
|
9
|
+
5 => 'five',
|
10
|
+
10 => 'ten',
|
11
|
+
11 => 'eleven',
|
12
|
+
12 => 'twelve',
|
13
|
+
13 => 'thirteen',
|
14
|
+
14 => 'fourteen',
|
15
|
+
15 => 'fifteen',
|
16
|
+
16 => 'sixteen',
|
17
|
+
17 => 'seventeen',
|
18
|
+
18 => 'eighteen',
|
19
|
+
19 => 'nineteen',
|
20
|
+
20 => 'twenty',
|
21
|
+
27 => 'twenty seven',
|
22
|
+
31 => 'thirty-one',
|
23
|
+
59 => 'fifty nine',
|
24
|
+
100 => 'a hundred',
|
25
|
+
100 => 'one hundred',
|
26
|
+
150 => 'one hundred and fifty',
|
27
|
+
150 => 'one fifty',
|
28
|
+
200 => 'two-hundred',
|
29
|
+
500 => '5 hundred',
|
30
|
+
999 => 'nine hundred and ninety nine',
|
31
|
+
1_000 => 'one thousand',
|
32
|
+
1_200 => 'twelve hundred',
|
33
|
+
1_200 => 'one thousand two hundred',
|
34
|
+
17_000 => 'seventeen thousand',
|
35
|
+
21_473 => 'twentyone-thousand-four-hundred-and-seventy-three',
|
36
|
+
74_002 => 'seventy four thousand and two',
|
37
|
+
99_999 => 'ninety nine thousand nine hundred ninety nine',
|
38
|
+
100_000 => '100 thousand',
|
39
|
+
250_000 => 'two hundred fifty thousand',
|
40
|
+
1_000_000 => 'one million',
|
41
|
+
1_250_007 => 'one million two hundred fifty thousand and seven',
|
42
|
+
1_000_000_000 => 'one billion',
|
43
|
+
1_000_000_001 => 'one billion and one'}
|
44
|
+
|
45
|
+
strings.keys.sort.each do |key|
|
46
|
+
assert_equal key, JW::NumberMagick.convert(strings[key])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/test/suite.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'chronic'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestChronic < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
# Wed Aug 16 14:00:00 UTC 2006
|
8
|
+
@now = Time.local(2006, 8, 16, 14, 0, 0, 0)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_post_normalize_am_pm_aliases
|
12
|
+
# affect wanted patterns
|
13
|
+
|
14
|
+
tokens = [Chronic::Token.new("5:00"), Chronic::Token.new("morning")]
|
15
|
+
tokens[0].tag(Chronic::RepeaterTime.new("5:00"))
|
16
|
+
tokens[1].tag(Chronic::RepeaterDayPortion.new(:morning))
|
17
|
+
|
18
|
+
assert_equal :morning, tokens[1].tags[0].type
|
19
|
+
|
20
|
+
tokens = Chronic.dealias_and_disambiguate_times(tokens, {})
|
21
|
+
|
22
|
+
assert_equal :am, tokens[1].tags[0].type
|
23
|
+
assert_equal 2, tokens.size
|
24
|
+
|
25
|
+
# don't affect unwanted patterns
|
26
|
+
|
27
|
+
tokens = [Chronic::Token.new("friday"), Chronic::Token.new("morning")]
|
28
|
+
tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
|
29
|
+
tokens[1].tag(Chronic::RepeaterDayPortion.new(:morning))
|
30
|
+
|
31
|
+
assert_equal :morning, tokens[1].tags[0].type
|
32
|
+
|
33
|
+
tokens = Chronic.dealias_and_disambiguate_times(tokens, {})
|
34
|
+
|
35
|
+
assert_equal :morning, tokens[1].tags[0].type
|
36
|
+
assert_equal 2, tokens.size
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_guess
|
40
|
+
span = Chronic::Span.new(Time.local(2006, 8, 16, 0), Time.local(2006, 8, 17, 0))
|
41
|
+
assert_equal Time.local(2006, 8, 16, 12), Chronic.guess(span)
|
42
|
+
|
43
|
+
span = Chronic::Span.new(Time.local(2006, 8, 16, 0), Time.local(2006, 8, 17, 0, 0, 1))
|
44
|
+
assert_equal Time.local(2006, 8, 16, 12), Chronic.guess(span)
|
45
|
+
|
46
|
+
span = Chronic::Span.new(Time.local(2006, 11), Time.local(2006, 12))
|
47
|
+
assert_equal Time.local(2006, 11, 16), Chronic.guess(span)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'chronic'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestHandler < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
# Wed Aug 16 14:00:00 UTC 2006
|
8
|
+
@now = Time.local(2006, 8, 16, 14, 0, 0, 0)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_handler_class_1
|
12
|
+
handler = Chronic::Handler.new([:repeater], :handler)
|
13
|
+
|
14
|
+
tokens = [Chronic::Token.new('friday')]
|
15
|
+
tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
|
16
|
+
|
17
|
+
assert handler.match(tokens, Chronic.definitions)
|
18
|
+
|
19
|
+
tokens << Chronic::Token.new('afternoon')
|
20
|
+
tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
|
21
|
+
|
22
|
+
assert !handler.match(tokens, Chronic.definitions)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_handler_class_2
|
26
|
+
handler = Chronic::Handler.new([:repeater, :repeater?], :handler)
|
27
|
+
|
28
|
+
tokens = [Chronic::Token.new('friday')]
|
29
|
+
tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
|
30
|
+
|
31
|
+
assert handler.match(tokens, Chronic.definitions)
|
32
|
+
|
33
|
+
tokens << Chronic::Token.new('afternoon')
|
34
|
+
tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
|
35
|
+
|
36
|
+
assert handler.match(tokens, Chronic.definitions)
|
37
|
+
|
38
|
+
tokens << Chronic::Token.new('afternoon')
|
39
|
+
tokens[2].tag(Chronic::RepeaterDayPortion.new(:afternoon))
|
40
|
+
|
41
|
+
assert !handler.match(tokens, Chronic.definitions)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_handler_class_3
|
45
|
+
handler = Chronic::Handler.new([:repeater, 'time?'], :handler)
|
46
|
+
|
47
|
+
tokens = [Chronic::Token.new('friday')]
|
48
|
+
tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
|
49
|
+
|
50
|
+
assert handler.match(tokens, Chronic.definitions)
|
51
|
+
|
52
|
+
tokens << Chronic::Token.new('afternoon')
|
53
|
+
tokens[1].tag(Chronic::RepeaterDayPortion.new(:afternoon))
|
54
|
+
|
55
|
+
assert !handler.match(tokens, Chronic.definitions)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_handler_class_4
|
59
|
+
handler = Chronic::Handler.new([:repeater_month_name, :scalar_day, 'time?'], :handler)
|
60
|
+
|
61
|
+
tokens = [Chronic::Token.new('may')]
|
62
|
+
tokens[0].tag(Chronic::RepeaterMonthName.new(:may))
|
63
|
+
|
64
|
+
assert !handler.match(tokens, Chronic.definitions)
|
65
|
+
|
66
|
+
tokens << Chronic::Token.new('27')
|
67
|
+
tokens[1].tag(Chronic::ScalarDay.new(27))
|
68
|
+
|
69
|
+
assert handler.match(tokens, Chronic.definitions)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_handler_class_5
|
73
|
+
handler = Chronic::Handler.new([:repeater, 'time?'], :handler)
|
74
|
+
|
75
|
+
tokens = [Chronic::Token.new('friday')]
|
76
|
+
tokens[0].tag(Chronic::RepeaterDayName.new(:friday))
|
77
|
+
|
78
|
+
assert handler.match(tokens, Chronic.definitions)
|
79
|
+
|
80
|
+
tokens << Chronic::Token.new('5:00')
|
81
|
+
tokens[1].tag(Chronic::RepeaterTime.new('5:00'))
|
82
|
+
|
83
|
+
assert handler.match(tokens, Chronic.definitions)
|
84
|
+
|
85
|
+
tokens << Chronic::Token.new('pm')
|
86
|
+
tokens[2].tag(Chronic::RepeaterDayPortion.new(:pm))
|
87
|
+
|
88
|
+
assert handler.match(tokens, Chronic.definitions)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_handler_class_6
|
92
|
+
handler = Chronic::Handler.new([:scalar, :repeater, :pointer], :handler)
|
93
|
+
|
94
|
+
tokens = [Chronic::Token.new('3'),
|
95
|
+
Chronic::Token.new('years'),
|
96
|
+
Chronic::Token.new('past')]
|
97
|
+
|
98
|
+
tokens[0].tag(Chronic::Scalar.new(3))
|
99
|
+
tokens[1].tag(Chronic::RepeaterYear.new(:year))
|
100
|
+
tokens[2].tag(Chronic::Pointer.new(:past))
|
101
|
+
|
102
|
+
assert handler.match(tokens, Chronic.definitions)
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_constantize
|
106
|
+
handler = Chronic::Handler.new([], :handler)
|
107
|
+
assert_equal Chronic::RepeaterTime, handler.constantize(:repeater_time)
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'chronic'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestRepeaterDayName < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@now = Time.local(2006, 8, 16, 14, 0, 0, 0)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_match
|
11
|
+
token = Chronic::Token.new('saturday')
|
12
|
+
repeater = Chronic::Repeater.scan_for_day_names(token)
|
13
|
+
assert_equal Chronic::RepeaterDayName, repeater.class
|
14
|
+
assert_equal :saturday, repeater.type
|
15
|
+
|
16
|
+
token = Chronic::Token.new('sunday')
|
17
|
+
repeater = Chronic::Repeater.scan_for_day_names(token)
|
18
|
+
assert_equal Chronic::RepeaterDayName, repeater.class
|
19
|
+
assert_equal :sunday, repeater.type
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_next_future
|
23
|
+
mondays = Chronic::RepeaterDayName.new(:monday)
|
24
|
+
mondays.start = @now
|
25
|
+
|
26
|
+
span = mondays.next(:future)
|
27
|
+
|
28
|
+
assert_equal Time.local(2006, 8, 21), span.begin
|
29
|
+
assert_equal Time.local(2006, 8, 22), span.end
|
30
|
+
|
31
|
+
span = mondays.next(:future)
|
32
|
+
|
33
|
+
assert_equal Time.local(2006, 8, 28), span.begin
|
34
|
+
assert_equal Time.local(2006, 8, 29), span.end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_next_past
|
38
|
+
mondays = Chronic::RepeaterDayName.new(:monday)
|
39
|
+
mondays.start = @now
|
40
|
+
|
41
|
+
span = mondays.next(:past)
|
42
|
+
|
43
|
+
assert_equal Time.local(2006, 8, 14), span.begin
|
44
|
+
assert_equal Time.local(2006, 8, 15), span.end
|
45
|
+
|
46
|
+
span = mondays.next(:past)
|
47
|
+
|
48
|
+
assert_equal Time.local(2006, 8, 7), span.begin
|
49
|
+
assert_equal Time.local(2006, 8, 8), span.end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'chronic'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestRepeaterFortnight < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@now = Time.local(2006, 8, 16, 14, 0, 0, 0)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_next_future
|
11
|
+
fortnights = Chronic::RepeaterFortnight.new(:fortnight)
|
12
|
+
fortnights.start = @now
|
13
|
+
|
14
|
+
next_fortnight = fortnights.next(:future)
|
15
|
+
assert_equal Time.local(2006, 8, 20), next_fortnight.begin
|
16
|
+
assert_equal Time.local(2006, 9, 3), next_fortnight.end
|
17
|
+
|
18
|
+
next_next_fortnight = fortnights.next(:future)
|
19
|
+
assert_equal Time.local(2006, 9, 3), next_next_fortnight.begin
|
20
|
+
assert_equal Time.local(2006, 9, 17), next_next_fortnight.end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_next_past
|
24
|
+
fortnights = Chronic::RepeaterFortnight.new(:fortnight)
|
25
|
+
fortnights.start = @now
|
26
|
+
|
27
|
+
last_fortnight = fortnights.next(:past)
|
28
|
+
assert_equal Time.local(2006, 7, 30), last_fortnight.begin
|
29
|
+
assert_equal Time.local(2006, 8, 13), last_fortnight.end
|
30
|
+
|
31
|
+
last_last_fortnight = fortnights.next(:past)
|
32
|
+
assert_equal Time.local(2006, 7, 16), last_last_fortnight.begin
|
33
|
+
assert_equal Time.local(2006, 7, 30), last_last_fortnight.end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_this_future
|
37
|
+
fortnights = Chronic::RepeaterFortnight.new(:fortnight)
|
38
|
+
fortnights.start = @now
|
39
|
+
|
40
|
+
this_fortnight = fortnights.this(:future)
|
41
|
+
assert_equal Time.local(2006, 8, 16, 15), this_fortnight.begin
|
42
|
+
assert_equal Time.local(2006, 8, 27), this_fortnight.end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_this_past
|
46
|
+
fortnights = Chronic::RepeaterFortnight.new(:fortnight)
|
47
|
+
fortnights.start = @now
|
48
|
+
|
49
|
+
this_fortnight = fortnights.this(:past)
|
50
|
+
assert_equal Time.local(2006, 8, 13, 0), this_fortnight.begin
|
51
|
+
assert_equal Time.local(2006, 8, 16, 14), this_fortnight.end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_offset
|
55
|
+
span = Chronic::Span.new(@now, @now + 1)
|
56
|
+
|
57
|
+
offset_span = Chronic::RepeaterWeek.new(:week).offset(span, 3, :future)
|
58
|
+
|
59
|
+
assert_equal Time.local(2006, 9, 6, 14), offset_span.begin
|
60
|
+
assert_equal Time.local(2006, 9, 6, 14, 0, 1), offset_span.end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|