eventual 0.4.9 → 0.5.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/lib/eventual.rb CHANGED
@@ -1,193 +1,7 @@
1
+ require 'rubygems'
2
+ require 'treetop'
1
3
  require 'date'
2
- require 'iconv'
3
- require 'strscan'
4
4
 
5
- module Eventual
6
- class WdayMatchError < StandardError; end
7
-
8
-
9
- VERSION = '0.4.9'
10
- extend self
11
-
12
- WDAY_LIST = %w(domingo lunes martes miércoles jueves viernes sábado).freeze
13
- MESES = %w(enero febrero marzo abril mayo junio julio agosto septiembre octubre noviembre diciembre).unshift(nil).freeze
14
- DIAS_DE_LA_SEMANA = WDAY_LIST.map{ |d| d.match(/s$/) ? d : "#{d}s?" }
15
-
16
- def rango_de a, b = nil
17
- a = a.join('|') if Array === a
18
- b ||= a
19
- /(?:de |del )?(?:#{ a }) (?:a|al) (?:#{ b })/
20
- end
21
-
22
- def lista_de elementos
23
- elementos = elementos.join('|') if Array === elementos
24
- /(?:#{ elementos }) # Primer elemento -requerido-
25
- (?: # Cualquier número de
26
- (?-x:, | y ) # concatenador
27
- (?:#{ elementos }) # y elemento.
28
- )*/ix
29
- end
30
-
31
- def plural_opcional elementos
32
- elementos.map{ |d| d.match(/s$/) ? d : "#{d}s?" }
33
- end
34
-
35
- year = /(?-x:del |de )?(\d{4})/i
36
- horarios = /a las (#{ lista_de '\d{1,2}:\d{2}' })(?: horas| hrs)?/i
37
-
38
-
39
- DAY_LIST = /
40
- (#{ lista_de %r"(?:(?:#{ DIAS_DE_LA_SEMANA.join('|') }) )?\d{1,2}" })\s
41
- de\s(#{ MESES.compact.join('|') }) # Mes
42
- (?:\s#{ year })? # Año opcional
43
- (\s#{ horarios })? # Hora opcional
44
- /ixo
45
-
46
- DAY_PERIOD = /
47
- (?:
48
- (
49
- (?:#{ rango_de DIAS_DE_LA_SEMANA })\s
50
- |
51
- (?:#{ lista_de DIAS_DE_LA_SEMANA })\s
52
- )
53
- (?-x:de |del )
54
- )?
55
- (?-x:(?:de |del )?(?:(#{ DIAS_DE_LA_SEMANA.join('|') }) )?(\d{1,2})(?: de (#{ MESES.compact.join('|') })(?: #{ year })?)?)
56
- (?-x: (?:a|al) (?:(#{ DIAS_DE_LA_SEMANA.join('|') }) )?(\d{1,2}) de (#{ MESES.compact.join('|') })(?: #{ year })?)
57
- (?:\s#{ horarios })?
58
- /ixo
59
-
60
- WHOLE_MONTH = /
61
- ( # Dias de la semana opcionales
62
- (?-x:los |todos los )?
63
- (?:
64
- (?:#{ rango_de DIAS_DE_LA_SEMANA })
65
- |
66
- (?:#{ lista_de DIAS_DE_LA_SEMANA })
67
- )\s
68
- (?-x:de|durante|durante todo)\s
69
- )?
70
- (?:
71
- (?:#{ rango_de %r"(#{ MESES.compact.join('|') })(?:\s#{ year })?" })
72
- |
73
- (#{ lista_de MESES.compact })(?:\s#{ year })?
74
- )
75
- (?:\s#{ horarios })? # Hora opcional
76
- /ixo
77
-
78
- def event_parse string, opts = {}, &block
79
- parser = opts.delete(:parser) || (self == Eventual ? DateTime : self)
80
- use_trailing = opts.delete(:use_trailing)
81
- string = string.gsub('miercoles', 'miércoles').gsub('sabado', 'sábado').gsub(/'/, '').gsub(/(\s)+/, '\1')
82
- results = []
83
- scanner = StringScanner.new string
84
-
85
- map_months = lambda{ |months| months.scan(/#{ MESES.compact.join('|') }/).map{ |m| MESES.index(m.downcase) } }
86
- make_range = lambda{ |first, last, min, max| first > last ? (first..max).map + (min..last).map : (first..last).map }
87
-
88
- extract_wdays = lambda do |wdays|
89
- wdays_array = wdays ? wdays.scan( /#{ WDAY_LIST.join('|') }/ ).map{ |d| WDAY_LIST.index d.downcase } : []
90
- next wdays_array unless rango_de(DIAS_DE_LA_SEMANA) === wdays
91
- make_range[wdays_array.first, wdays_array.last, 0, 6]
92
- end
93
-
94
- until scanner.eos?
95
- case match = scanner.scan(/.*?(?:#{ DAY_LIST }|#{ DAY_PERIOD }|#{ WHOLE_MONTH })/m)
96
-
97
- when DAY_PERIOD
98
- wdays, first_wday, first_day, first_month, first_year, last_wday, last_day, last_month, last_year, times = $1, $2, $3, $4, $5, $6, $7, $8, $9, $10
99
-
100
- wdays_array = extract_wdays[wdays]
101
- last_year ||= string.match(/\d{4}/) ? $& : Date.today.year
102
- first_year ||= last_year
103
- first_month ||= last_month
104
- last_month = MESES.index last_month.downcase
105
- first_month = MESES.index first_month.downcase
106
-
107
- make_days = lambda do |hour, minute|
108
- first = make_day parser, first_year, first_month, first_day, hour, minute
109
- last = make_day parser, last_year, last_month, last_day, hour, minute
110
-
111
- [first, last].zip([first_wday, last_wday]).each do |day, wday|
112
- raise WdayMatchError.new("El día #{ day } cae en #{ DIAS_DE_LA_SEMANA[day.wday] }, no en #{ wday.downcase }") unless day.wday == WDAY_LIST.index(wday.downcase) if wday
113
- end
114
-
115
- next (first..last).map if wdays_array.empty?
116
- (first..last).select{ |day| wdays_array.include? day.wday }
117
- end
118
-
119
- when DAY_LIST
120
- daynums, month, year, times = $1, MESES.index($2.downcase), $3, $4
121
-
122
- year ||= string.match(/\d{4}/) ? $& : Date.today.year
123
- make_days = lambda do |hour, minute|
124
- daynums.scan(/(?:(#{ DIAS_DE_LA_SEMANA.join('|') }) )?(\d{1,2})/).collect do |wday, daynum|
125
- day = make_day(parser, year, month, daynum, hour, minute)
126
- raise WdayMatchError.new("El día #{ day } cae en #{ DIAS_DE_LA_SEMANA[day.wday] }, no en #{ wday.downcase }") unless day.wday == WDAY_LIST.index(wday.downcase) if wday
127
- day
128
- end
129
- end
130
-
131
- when WHOLE_MONTH
132
- wdays, month_range_start, starting_year, month_range_end, ending_year, months, year, times = $1, $2, $3, $4, $5, $6, $7, $8
133
- wdays_array = extract_wdays[wdays]
134
-
135
- month_array =
136
- if month_range_start
137
- ending_year ||= Date.today.year
138
- first = Date.civil( (starting_year || ending_year).to_i, MESES.index(month_range_start.downcase) )
139
- last = Date.civil ending_year.to_i, MESES.index(month_range_end.downcase)
140
- (first..last)
141
- else
142
- year ||= Date.today.year
143
- months.scan(/#{ MESES.compact.join('|') }/).map do |m|
144
- Date.civil year.to_i, MESES.index(m.downcase)
145
- end
146
- end
147
-
148
- make_days = lambda do |hour, minute|
149
- months = month_array.map do |date|
150
- first = make_day(parser, date.year, date.month, 1, hour, minute)
151
- last = (first >> 1) - 1
152
- next (first..last).map if wdays_array.empty?
153
- (first..last).select{ |day| wdays_array.include? day.wday }
154
- end.flatten
155
- end
156
-
157
- else
158
- break
159
- end
160
-
161
- extra = scanner.scan(/.*?(?=#{ DAY_LIST }|#{ DAY_PERIOD }|\z)/m).to_s.chomp
162
- extra.gsub!(/^(,|\n|\.)/, '')
163
-
164
- days =
165
- if times
166
- times.scan( /(\d{2}):(\d{2})/ ).map{ |hour, minute| make_days.call hour, minute }.flatten
167
- else
168
- make_days.call nil, nil
169
- end
170
-
171
- days.each { |day| day.instance_variable_set('@extra', extra) }
172
- results += days
173
- end
174
-
175
- raise ArgumentError.new( 'El formato de las fechas parece ser incorrecto' ) if results.empty?
176
- results.uniq!
177
- results.sort!
178
-
179
- use_trailing ? results.map!{ |day| yield day, day.instance_variable_get('@extra') } : results.map!{ |day| yield day } if block_given?
180
- results
181
- end
182
-
183
- protected
184
- def make_day *args
185
- maker = args.shift
186
- if maker == Date
187
- maker.civil *args.compact.collect{ |a| a.to_i }[0...4]
188
- else
189
- maker.civil *args.compact.collect{ |a| a.to_i }
190
- end
191
- end
192
- end
5
+ require "#{ File.dirname __FILE__ }/eventual/syntax_nodes"
193
6
 
7
+ autoload :EsDatesParser, 'eventual/es'
@@ -1,222 +1,435 @@
1
- require File.expand_path( File.dirname(__FILE__) + '/spec_helper' )
1
+ require "#{File.dirname __FILE__}/spec_helper"
2
+ require 'eventual'
2
3
 
3
- describe 'event parsing' do
4
+ describe Eventual, 'Es' do
5
+ before do
6
+ @parser = EsDatesParser.new
7
+ Date.stub!(:today).and_return Date.civil(2010)
8
+ end
4
9
 
5
- describe 'lista de número dia' do
6
- it "should event_parse one day" do
7
- Eventual.event_parse( '1 de enero del 2009' ).should map_times( '2009-1-1' )
8
- end
9
-
10
- it "should event_parse several days" do
11
- Eventual.event_parse( '1, 2 y 3 de enero' ).should map_times( "2009-1-1", "2009-1-2", "2009-1-3" )
12
- end
13
-
14
- it "should match several days with year" do
15
- Eventual.event_parse( '1, 2 y 3 de enero del 2010' ).should map_times( "2010-1-1", "2010-1-2", "2010-1-3" )
16
- end
17
-
18
- it "should event_parse one day with one time" do
19
- Eventual.event_parse( '1 de enero del 2009 a las 16:00 horas' ).should map_times( '2009-1-1T16:00' )
20
- end
21
-
22
- it "should parse one day with wday" do
23
- Eventual.event_parse( 'viernes 1 de enero del 2010' ).should map_times( '2010-1-1' )
10
+ shared_examples_for 'correctly parses' do
11
+ it { @result.should_not be_nil }
12
+ it { @result.to_a.size.should == @dates.map.size }
13
+ it { @result.should map_dates *@dates }
14
+ it { @dates.map{ |date| @result.should include(date) } }
15
+ it { @result.should_not include(@dates.first - 1) }
16
+ it { @result.should_not include(@dates.last + 1) }
17
+ it { @dates.select{ |d| @result.include? d }.map{ |d| d.to_s }.should == @dates.map{ |r| r.to_s } }
18
+ end
19
+
20
+ describe 'month' do
21
+ describe "month without year parsing 'marzo'" do
22
+ before do
23
+ @result = @parser.parse 'marzo'
24
+ @dates = (Date.parse('2010-3-1')..Date.parse('2010-3-31')).map
25
+ end
26
+ it_should_behave_like 'correctly parses'
24
27
  end
25
-
26
- it "should parse list with wday" do
27
- Eventual.event_parse( 'viernes 1, sábado 2, domingo 3 y lunes 4 de enero del 2010' ).should map_times( '2010-1-1', '2010-1-2', '2010-1-3', '2010-1-4' )
28
+
29
+ describe 'month with year' do
30
+ describe "parsing 'marzo de 2009'" do
31
+ before do
32
+ @result = @parser.parse "marzo de 2009"
33
+ @dates = (Date.parse('2009-3-1')..Date.parse('2009-3-31')).map
34
+ end
35
+ it_should_behave_like 'correctly parses'
36
+ end
37
+
38
+ describe "parsing 'marzo del 2009'" do
39
+ before do
40
+ @result = @parser.parse "marzo del 2009"
41
+ @dates = (Date.parse('2009-3-1')..Date.parse('2009-3-31')).map
42
+ end
43
+ it_should_behave_like 'correctly parses'
44
+ end
45
+
46
+ describe "parsing 'marzo 2009'" do
47
+ before do
48
+ @result = @parser.parse "marzo 2009"
49
+ @dates = (Date.parse('2009-3-1')..Date.parse('2009-3-31')).map
50
+ end
51
+ it_should_behave_like 'correctly parses'
52
+ end
53
+
54
+ describe "parsing 'marzo, 2009'" do
55
+ before do
56
+ @result = @parser.parse "marzo, 2009"
57
+ @dates = (Date.parse('2009-3-1')..Date.parse('2009-3-31')).map
58
+ end
59
+ it_should_behave_like 'correctly parses'
60
+ end
61
+
62
+ describe "parsing 'marzo '09'" do
63
+ before do
64
+ @result = @parser.parse "marzo '09"
65
+ @dates = (Date.parse('2009-3-1')..Date.parse('2009-3-31')).map
66
+ end
67
+ it_should_behave_like 'correctly parses'
68
+ end
28
69
  end
29
-
30
- it "should blow if wday doesn't correspond" do
31
- lambda{ Eventual.event_parse('sábado 1 de enero del 2010') }.should raise_error(Eventual::WdayMatchError)
70
+
71
+ describe 'month with wdays' do
72
+ before do
73
+ @dates = (Date.parse('2010-3-1')..Date.parse('2010-3-31')).reject{ |day| not [1,2].include?(day.wday) }
74
+ end
75
+
76
+ describe "parsing 'lunes y martes marzo del 2010'" do
77
+ before { @result = @parser.parse "lunes y martes marzo del 2010" }
78
+ it_should_behave_like 'correctly parses'
79
+ end
80
+
81
+ describe "parsing 'lunes y martes de marzo del 2010'" do
82
+ before { @result = @parser.parse "lunes y martes de marzo del 2010" }
83
+ it_should_behave_like 'correctly parses'
84
+ end
85
+
86
+ describe "parsing 'lunes y martes durante marzo del 2010'" do
87
+ before { @result = @parser.parse "lunes y martes durante marzo del 2010" }
88
+ it_should_behave_like 'correctly parses'
89
+ end
90
+
91
+ describe "parsing 'lunes y martes durante todo marzo del 2010'" do
92
+ before { @result = @parser.parse "lunes y martes durante todo marzo del 2010" }
93
+ it_should_behave_like 'correctly parses'
94
+ end
95
+
96
+ describe "parsing 'lunes y martes, marzo del 2010'" do
97
+ before { @result = @parser.parse "lunes y martes, marzo del 2010" }
98
+ it_should_behave_like 'correctly parses'
99
+ end
32
100
  end
101
+
33
102
  end
34
103
 
35
- describe 'lista de rango de número de día' do
36
- it "should event_parse a period" do
37
- Eventual.event_parse( 'del 1 al 3 de enero' ).should map_times( '2009-1-1', '2009-1-2', '2009-1-3' )
38
- end
39
-
40
- it "should event_parse a period with year" do
41
- Eventual.event_parse( 'del 1 al 3 de enero 2010' ).should map_times( '2010-1-1', '2010-1-2', '2010-1-3' )
104
+ describe 'day numbers' do
105
+ describe 'single date' do
106
+ before do
107
+ @dates = [Date.civil 2010, 3, 21]
108
+ end
109
+
110
+ describe "should single day number for '21 de marzo'" do
111
+ before { @result = @parser.parse("21 de marzo") }
112
+ it_should_behave_like 'correctly parses'
113
+ end
114
+
115
+ describe "parsing '21 marzo'" do
116
+ before { @result = @parser.parse("21 marzo") }
117
+ it_should_behave_like 'correctly parses'
118
+ end
119
+
120
+ # describe "parsing 'marzo 21'" do
121
+ # before { @result = @parser.parse("21 marzo") }
122
+ # it_should_behave_like 'correctly parses'
123
+ # end
124
+
125
+ describe 'date with wday' do
126
+ describe "parsing 'domingo 21 de marzo'" do
127
+ before { @result = @parser.parse("domingo 21 de marzo") }
128
+ it_should_behave_like 'correctly parses'
129
+ end
130
+
131
+ it "should raise WdayMatchError if weekday doesn't correspond to date" do
132
+ lambda { @parser.parse("lunes 21 de marzo").map }.should raise_error(Eventual::WdayMatchError)
133
+ end
134
+ end
42
135
  end
43
-
44
- it "should event_parse a period with time" do
45
- Eventual.event_parse( 'miércoles del 1 al 3 de junio' ).should map_times( '2009-6-3' )
136
+
137
+ describe 'day list' do
138
+ before do
139
+ @dates = (1..3).map{ |i| Date.civil( 2010, 3, i) }
140
+ end
141
+
142
+ describe "day list for '1, 2 y 3 de marzo'" do
143
+ before { @result = @parser.parse("1, 2 y 3 marzo") }
144
+ it_should_behave_like 'correctly parses'
145
+ end
146
+
147
+ describe "day list for '1, 2 y 3 marzo'" do
148
+ before { @result = @parser.parse("1, 2 y 3 de marzo") }
149
+ it_should_behave_like 'correctly parses'
150
+ end
151
+
152
+ describe "day list with weekday 'lunes 1, martes 2 y miercoles 3 de marzo'" do
153
+ before { @result = @parser.parse("lunes 1, martes 2 y miercoles 3 de marzo") }
154
+ it_should_behave_like 'correctly parses'
155
+ end
156
+
157
+ it "should raise WdayMatchError if weekday doesn't correspond to date" do
158
+ lambda { @parser.parse("lunes 2, martes 2 y jueves 3 de marzo").map }.should raise_error(Eventual::WdayMatchError)
159
+ end
46
160
  end
47
-
48
- it "should event_parse a period with time" do
49
- Eventual.event_parse( 'miércoles del 1 al 3 de junio a las 16:00 horas' ).should map_times( '2009-6-3T16:00' )
161
+ end
162
+
163
+ describe 'day range' do
164
+ describe 'period in same month' do
165
+ before do
166
+ @dates = (1..3).map{ |i| Date.civil( 2010, 3, i) }
167
+ end
168
+
169
+ describe "day list for '1 al 3 de marzo" do
170
+ before { @result = @parser.parse("1 al 3 de marzo del '10") }
171
+ it_should_behave_like 'correctly parses'
172
+ end
173
+
174
+ describe "day list for '1 al 3, marzo" do
175
+ before { @result = @parser.parse("1 al 3, marzo del '10") }
176
+ it_should_behave_like 'correctly parses'
177
+ end
178
+
179
+ describe "day list for 'del 1 al 3 de marzo" do
180
+ before { @result = @parser.parse("del 1 al 3 de marzo del '10") }
181
+ it_should_behave_like 'correctly parses'
182
+ end
183
+
184
+ describe "day list for 'del 1 al 3, marzo" do
185
+ before { @result = @parser.parse("del 1 al 3, marzo del '10") }
186
+ it_should_behave_like 'correctly parses'
187
+ end
50
188
  end
51
-
52
- it "should event_parse one day with several times" do
53
- Eventual.event_parse( '1 de enero del 2009 a las 16:00 y 17:00' ).should map_times( '2009-1-1T16:00', '2009-1-1T:17:00' )
189
+
190
+ describe "spanning diferent months '24 de febrero al 3 de marzo del 2010" do
191
+ before do
192
+ @result = @parser.parse "24 de febrero al 3 de marzo del 2010"
193
+ @dates = (Date.parse('2010-2-24')..Date.parse('2010-3-3'))
194
+ end
195
+ it_should_behave_like 'correctly parses'
54
196
  end
55
-
56
- it "should event_parse period spanning more than one month" do
57
- Eventual.event_parse( 'del 29 de enero al 3 de febrero' ).should map_times( '2009-1-29', '2009-1-30', '2009-1-31', '2009-2-1', '2009-2-2', '2009-2-3' )
197
+
198
+ describe "spanning diferent years '24 de diciembre del 2009 al 3 de enero del 2010" do
199
+ before do
200
+ @result = @parser.parse("24 de diciembre del 2009 al 3 de enero del 2010")
201
+ @dates = (Date.parse('2009-12-24')..Date.parse('2010-1-3'))
202
+ end
203
+ it_should_behave_like 'correctly parses'
58
204
  end
59
205
 
60
- it "should parse period spanning across year" do
61
- Eventual.event_parse( 'del 28 de diciembre del 2009 al 2 de enero del 2010').should map_times( '2009-12-28', '2009-12-29', '2009-12-30', '2009-12-31', '2010-1-1', '2010-1-2')
62
- end
63
-
64
- it "should parse range with wday" do
65
- Eventual.event_parse( 'viernes 1 al domingo 3 de enero del 2010' ).should map_times( '2010-1-1', '2010-1-2', '2010-1-3' )
66
- end
67
-
68
- it "should blow if wday doesn't correspond" do
69
- lambda{ Eventual.event_parse('viernes 2 a domingo 4 de enero del 2010') }.should raise_error(Eventual::WdayMatchError)
70
- end
206
+ describe 'period spanning two dates' do
207
+ before do
208
+ @dates = (Date.parse('2008-10-1')..DateTime.parse('2008-12-2'))
209
+ end
210
+
211
+ describe "1 de octubre a 2 de diciembre del 2008" do
212
+ before { @result = @parser.parse "1 de octubre a 2 de diciembre del 2008" }
213
+ it_should_behave_like 'correctly parses'
214
+ end
71
215
 
72
- describe 'restringido por dia de la semana' do
73
- it "should parse all tuesdays and thursdays of the year" do
74
- e = Eventual.event_parse( 'martes y jueves del 1 de enero al 31 de diciembre del 2008')
75
- r = ( DateTime.parse('2008-1-1')..DateTime.parse('2008-12-31') ).reject{ |day| not [2,4].include?(day.wday) }
76
- e.should map_times( *r )
216
+ describe "1 de octubre al 2 de diciembre del 2008" do
217
+ before { @result = @parser.parse "1 de octubre al 2 de diciembre del 2008" }
218
+ it_should_behave_like 'correctly parses'
77
219
  end
78
220
 
79
- it "should parse all tuesdays and thursdays of the year with time" do
80
- e = Eventual.event_parse( 'martes y jueves del 1 de enero al 31 de diciembre del 2008 a las 16:00')
81
- r = ( DateTime.parse('2008-1-1T16:00')..DateTime.parse('2008-12-31T16:00') ).reject{ |day| not [2,4].include?(day.wday) }
82
- e.should map_times( *r )
221
+ describe "del miercoles 1 de octubre al martes 2 de diciembre del 2008" do
222
+ before { @result = @parser.parse "del miercoles 1 de octubre al martes 2 de diciembre del 2008" }
223
+ it_should_behave_like 'correctly parses'
83
224
  end
225
+ end
84
226
 
85
- it "should parse all saturdays and sundays of the year with time" do
86
- e = Eventual.event_parse( 'sábado y domingo del 1 de enero al 31 de diciembre del 2008 a las 16:00')
87
- r = ( DateTime.parse('2008-1-1T16:00')..DateTime.parse('2008-12-31T16:00') ).reject{ |day| not [0,6].include?(day.wday) }
88
- e.should map_times( *r )
227
+ describe "lunes y martes del 1 de octubre al 2 de diciembre del 2008" do
228
+ before do
229
+ @result = @parser.parse "lunes y martes del 1 de octubre al 2 de diciembre del 2008"
230
+ @dates = (Date.parse('2008-10-1')..DateTime.parse('2008-12-2')).reject{ |day| not [1,2].include?(day.wday) }
231
+ end
232
+ it_should_behave_like 'correctly parses'
233
+ end
234
+
235
+ describe 'with weekday constrain' do
236
+ describe "wdays for 'lunes y martes del 1 al 22 de marzo del '10" do
237
+ before do
238
+ @result = @parser.parse "lunes y martes del 1 al 22 de marzo del '10"
239
+ @dates = (Date.parse('2010-3-1')..Date.parse('2010-3-22')).reject{ |day| not [1,2].include?(day.wday) }
240
+ end
241
+ it_should_behave_like 'correctly parses'
89
242
  end
90
243
 
91
- it "should parse all pluralized saturdays and sundays of the year with time" do
92
- e = Eventual.event_parse( 'sábados y domingos del 1 de enero al 31 de diciembre del 2008 a las 16:00')
93
- r = ( DateTime.parse('2008-1-1T16:00')..DateTime.parse('2008-12-31T16:00') ).reject{ |day| not [0,6].include?(day.wday) }
94
- e.should map_times( *r )
244
+ describe "wdays for 'fines de semana del 1 al 22 de marzo del '10" do
245
+ before do
246
+ @result = @parser.parse "fines de semana del 1 al 22 de marzo del '10"
247
+ @dates = (Date.parse('2010-3-1')..Date.parse('2010-3-22')).map.reject{ |day| not [6,0].include?(day.wday) }
248
+ end
249
+ it_should_behave_like 'correctly parses'
95
250
  end
96
251
 
97
- it "should parse week day period" do
98
- e = Eventual.event_parse( 'lunes a viernes del 1 de enero al 31 de diciembre del 2008 a las 16:00')
99
- r = ( DateTime.parse('2008-1-1T16:00')..DateTime.parse('2008-12-31T16:00') ).reject{ |day| not (1..5).map.include?(day.wday) }
100
- e.should map_times( *r )
252
+ describe "wdays for 'entre semana del 1 al 22 de marzo del '10" do
253
+ before do
254
+ @result = @parser.parse("entre semana del 1 al 22 de marzo del '10")
255
+ @dates = (Date.parse('2010-3-1')..Date.parse('2010-3-22')).map.reject{ |day| not (1..5).map.include?(day.wday) }
256
+ end
257
+ it_should_behave_like 'correctly parses'
101
258
  end
259
+
260
+ describe 'sugar for wday constrain' do
261
+ before do
262
+ @dates = (Date.parse('2010-3-1')..Date.parse('2010-3-22')).reject{ |day| not [1,2].include?(day.wday) }
263
+ end
264
+
265
+ describe "wdays for 'lunes y martes del 1 al 22 de marzo del '10" do
266
+ before { @result = @parser.parse("lunes y martes del 1 al 22 de marzo del '10") }
267
+ it_should_behave_like 'correctly parses'
268
+ end
102
269
 
103
- it "should parse week day period across week" do
104
- e = Eventual.event_parse( 'viernes a lunes del 1 de enero al 31 de diciembre del 2008 a las 16:00')
105
- r = ( DateTime.parse('2008-1-1T16:00')..DateTime.parse('2008-12-31T16:00') ).reject{ |day| not [5,6,0,1].map.include?(day.wday) }
106
- e.should map_times( *r )
270
+ describe "wdays for 'todos los lunes y martes del 1 al 22 de marzo del '10" do
271
+ before { @result = @parser.parse("todos los lunes y martes del 1 al 22 de marzo del '10") }
272
+ it_should_behave_like 'correctly parses'
273
+ end
274
+
275
+ describe "wdays for 'los lunes y martes del 1 al 22 de marzo del '10" do
276
+ before { @result = @parser.parse("los lunes y martes del 1 al 22 de marzo del '10") }
277
+ it_should_behave_like 'correctly parses'
278
+ end
279
+
280
+ describe "wdays for 'los lunes y los martes del 1 al 22 de marzo del '10" do
281
+ before { @result = @parser.parse("los lunes y los martes del 1 al 22 de marzo del '10") }
282
+ it_should_behave_like 'correctly parses'
283
+ end
107
284
  end
108
285
  end
109
286
  end
110
-
111
- describe 'Meses completos' do
112
- it "should parse a single month" do
113
- ['diciembre del 2008', 'durante diciembre del 2008', 'durante todo diciembre del 2008'].each do |e|
114
- Eventual.event_parse(e).should map_times( *(DateTime.parse('2008-12-1T00:00')..DateTime.parse('2008-12-31T00:00')).map )
287
+
288
+ describe 'month range' do
289
+ describe 'octubre a diciembre del 2008' do
290
+ before do
291
+ @result = @parser.parse('octubre a diciembre del 2008')
292
+ @dates = (Date.parse('2008-10-1')..DateTime.parse('2008-12-31')).map
115
293
  end
294
+ it_should_behave_like 'correctly parses'
116
295
  end
117
-
118
- it "should parse two full months" do
119
- ['noviembre y diciembre del 2008', 'durante noviembre y diciembre del 2008', 'durante todo noviembre y diciembre del 2008'].each do |e|
120
- Eventual.event_parse(e).should map_times( *(DateTime.parse('2008-11-1T00:00')..DateTime.parse('2008-12-31T00:00')).map )
296
+
297
+
298
+ describe 'lunes y martes de octubre del 2007 a diciembre del 2008' do
299
+ before do
300
+ @result = @parser.parse('lunes y martes de octubre del 2007 a diciembre del 2008')
301
+ @dates = (Date.parse('2007-10-1')..DateTime.parse('2008-12-31')).reject{ |day| not [1,2].include?(day.wday) }
121
302
  end
303
+ it_should_behave_like 'correctly parses'
122
304
  end
123
-
124
- it "should parse severals full months" do
125
- ['octubre, noviembre y diciembre del 2008', 'durante octubre, noviembre y diciembre del 2008', 'durante todo octubre, noviembre y diciembre del 2008'].each do |e|
126
- Eventual.event_parse(e).should map_times( *(DateTime.parse('2008-10-1T00:00')..DateTime.parse('2008-12-31T00:00')).map )
127
- end
305
+ end
306
+
307
+ describe 'compound dates giving year at the end' do
308
+ before do
309
+ @result = @parser.parse "1 de enero y lunes y martes del 1 de octubre al 2 de diciembre del 2008"
310
+ @dates = [Date.parse('2008-1-1')] + (Date.parse('2008-10-1')..Date.parse('2008-12-2')).reject{ |day| not [1,2].include?(day.wday) }
128
311
  end
312
+ it_should_behave_like 'correctly parses'
313
+ end
129
314
 
130
- it "should parse a full month with time" do
131
- Eventual.event_parse('diciembre del 2008 a las 16:00 horas').should map_times( *(DateTime.parse('2008-12-1T16:00')..DateTime.parse('2008-12-31T16:00')).map )
315
+ describe 'compound dates in different lines' do
316
+ before do
317
+ @result = @parser.parse "1 de enero\nlunes y martes del 1 de octubre al 2 de diciembre del 2008"
318
+ @dates = [Date.parse('2008-1-1')] + (Date.parse('2008-10-1')..Date.parse('2008-12-2')).reject{ |day| not [1,2].include?(day.wday) }
132
319
  end
320
+ it_should_behave_like 'correctly parses'
321
+ end
133
322
 
134
- it "should parse a full month with time with days" do
135
- Eventual.event_parse('domingos de diciembre del 2008').should map_times( *(DateTime.parse('2008-12-1T00:00')..DateTime.parse('2008-12-31T00:00')).reject{ |day| not [0].include?(day.wday) } )
323
+ describe 'with time constrain' do
324
+ shared_examples_for 'outputs DateTime' do
325
+ it "should all be DateTime" do
326
+ @result.map{ |d| d.should be_a(DateTime) }
327
+ end
136
328
  end
137
329
 
138
- it "should parse a full month with time with days and sugar" do
139
- ['todos los domingos de diciembre del 2008', 'los domingos durante todo diciembre del 2008'].each do |e|
140
- Eventual.event_parse(e).should map_times( *(DateTime.parse('2008-12-1T00:00')..DateTime.parse('2008-12-31T00:00')).reject{ |day| not [0].include?(day.wday) } )
330
+ describe 'single day with time' do
331
+ before do
332
+ @result = @parser.parse('1 de enero del 2010 a las 15:00')
333
+ @dates = [DateTime.civil 2010, 1, 1, 15]
141
334
  end
335
+ it_should_behave_like 'correctly parses'
336
+ it_should_behave_like 'outputs DateTime'
142
337
  end
143
338
 
144
- it "should parse a full month with time with days" do
145
- ['sábados y domingos de diciembre del 2008', 'todos los sábados y domingos de diciembre del 2008', 'sábados y domingos durante todo diciembre del 2008'].each do |e|
146
- Eventual.event_parse(e).should map_times( *(DateTime.parse('2008-12-1T00:00')..DateTime.parse('2008-12-31T00:00')).reject{ |day| not [0, 6].include?(day.wday) } )
339
+ describe 'single time with no sugar for month range' do
340
+ before do
341
+ @result = @parser.parse('lunes y martes de diciembre del 2010 a las 15:00')
342
+ @dates = (DateTime.parse('2010-12-1T15:00')..DateTime.parse('2010-12-31T15:00')).reject{ |day| not [1,2].include?(day.wday) }
147
343
  end
344
+ it_should_behave_like 'correctly parses'
345
+ it_should_behave_like 'outputs DateTime'
148
346
  end
149
347
 
150
- it "should parse a full month with time with days" do
151
- ['todos los sábados a lunes de diciembre del 2008', 'sábado a lunes de diciembre del 2008', 'sábados a lunes durante todo diciembre del 2008'].each do |e|
152
- Eventual.event_parse(e).should map_times( *(DateTime.parse('2008-12-1T00:00')..DateTime.parse('2008-12-31T00:00')).reject{ |day| not [0, 1, 6].include?(day.wday) } )
348
+ describe 'single time with sugar 1 for month range' do
349
+ before do
350
+ @result = @parser.parse('lunes y martes de diciembre a las 15:00 hrs.')
351
+ @dates = (DateTime.parse('2010-12-1T15:00')..DateTime.parse('2010-12-31T15:00')).reject{ |day| not [1,2].include?(day.wday) }
153
352
  end
353
+ it_should_behave_like 'correctly parses'
354
+ it_should_behave_like 'outputs DateTime'
154
355
  end
155
356
 
156
- it "should parse without year" do
157
- Eventual.event_parse('sábados de diciembre').should map_times( *(DateTime.parse("#{ y = Date.today.year }-12-1T00:00")..DateTime.parse("#{ y }-12-31T00:00")).reject{ |day| not [6].include?(day.wday) } )
357
+ describe 'single time with sugar 2 for month range' do
358
+ before do
359
+ @result = @parser.parse('lunes y martes de diciembre a las 15:00hrs')
360
+ @dates = (DateTime.parse('2010-12-1T15:00')..DateTime.parse('2010-12-31T15:00')).reject{ |day| not [1,2].include?(day.wday) }
361
+ end
362
+ it_should_behave_like 'correctly parses'
363
+ it_should_behave_like 'outputs DateTime'
158
364
  end
159
365
 
160
- it "should parse month range" do
161
- Eventual.event_parse('octubre a diciembre del 2008').should map_times( *(DateTime.parse('2008-10-1T00:00')..DateTime.parse('2008-12-31T00:00')).map )
366
+ describe 'single time with sugar 3 for month range' do
367
+ before do
368
+ @result = @parser.parse('lunes y martes de diciembre a las 15 horas')
369
+ @dates = (DateTime.parse('2010-12-1T15:00')..DateTime.parse('2010-12-31T15:00')).reject{ |day| not [1,2].include?(day.wday) }
370
+ end
371
+ it_should_behave_like 'correctly parses'
372
+ it_should_behave_like 'outputs DateTime'
162
373
  end
163
374
 
164
- it "should parse month range" do
165
- Eventual.event_parse('diciembre del 2008 a enero del 2009').should map_times( *(DateTime.parse('2008-12-1T00:00')..DateTime.parse('2009-1-31T00:00')).map )
166
- end
167
- end
168
-
169
- it "should event_parse a period with block" do
170
- Eventual.event_parse( 'del 5 al 7 de junio 2009' ){ |d| Eventual::WDAY_LIST[ d.wday ] }.should == ['viernes', 'sábado', 'domingo']
171
- end
172
-
173
- it "should parse several expressions" do
174
- Eventual.event_parse( '1 de enero y 2 de febrero del 2008' ).should map_times( '2008-1-1', '2008-2-2' )
175
- end
176
-
177
- it "should event_parse period spanning more than one month" do
178
- Eventual.event_parse( '1 de enero, del 29 de enero al 3 de febrero y 2 de febrero del 2008' ).should map_times( '2008-1-1', '2008-1-29', '2008-1-30', '2008-1-31', '2008-2-1', '2008-2-2', '2008-2-3' )
179
- end
180
-
181
- it "should event_parse a several dates separated by \\n" do |d, extra|
182
- Eventual.event_parse( "1 de enero del 2009\n2 de enero del 2009" ) do |d|
183
- d.to_s
184
- end.should == ["2009-01-01T00:00:00+00:00", "2009-01-02T00:00:00+00:00"]
185
- end
186
-
187
- describe 'With extra data' do
188
- it "should event_parse one day with one time" do
189
- Eventual.event_parse( "1 de enero del 2009 a las 16:00 horas\nSede:Áreas verdes\nCupo: limitado", :use_trailing => true ) do |day, extra|
190
- day.to_s.should == "2009-01-01T16:00:00+00:00"
191
- extra.should == "Sede:Áreas verdes\nCupo: limitado"
375
+ describe 'two times for month range' do
376
+ before do
377
+ @result = @parser.parse('lunes y martes de diciembre a las 16:00 y 15:00 horas')
378
+ @dates = ((DateTime.parse('2010-12-1T15:00')..DateTime.parse('2010-12-31T15:00')).map + (DateTime.parse('2010-12-1T16:00')..DateTime.parse('2010-12-31T16:00')).map).reject{ |day| not [1,2].include?(day.wday) }
379
+ end
380
+ it_should_behave_like 'correctly parses'
381
+ it_should_behave_like 'outputs DateTime'
382
+
383
+ it "should not include other time" do
384
+ @result.should_not include(DateTime.parse('2010-12-06T14:00'))
192
385
  end
193
386
  end
194
-
195
- it "should event_parse a period with block" do
196
- Eventual.event_parse( "del 5 al 7 de junio 2009\nSede:El tercer lugar\nCupo: limitado", :use_trailing => true ) do |d, extra|
197
- extra.should == "Sede:El tercer lugar\nCupo: limitado"
198
- Eventual::WDAY_LIST[ d.wday ]
199
- end.should == ['viernes', 'sábado', 'domingo']
387
+
388
+ describe 'range with time as 12 hours am' do
389
+ before do
390
+ @result = @parser.parse('lunes y martes de diciembre a las 3 am')
391
+ @dates = ((DateTime.parse('2010-12-1T03:00')..DateTime.parse('2010-12-31T03:00')).map).reject{ |day| not [1,2].include?(day.wday) }
392
+ end
393
+ it_should_behave_like 'correctly parses'
394
+ it_should_behave_like 'outputs DateTime'
395
+
396
+ it "should not include other time" do
397
+ @result.should_not include(DateTime.parse('2010-12-06T14:00'))
398
+ end
200
399
  end
201
400
 
202
- it "should event_parse a several dates" do
203
- Eventual.event_parse( "1 de enero del 2009\nSede:El tercer lugar\nCupo: limitado\n2 de enero del 2009\nSede:El tercer lugar\nCupo: limitado", :use_trailing => true ) do |d, extra|
204
- extra.should == "Sede:El tercer lugar\nCupo: limitado"
205
- d.to_s
206
- end.should == ["2009-01-01T00:00:00+00:00", "2009-01-02T00:00:00+00:00"]
401
+ describe 'range with time as 12 hours pm' do
402
+ before do
403
+ @result = @parser.parse('lunes y martes de diciembre a las 3:00 pm')
404
+ @dates = ((DateTime.parse('2010-12-1T15:00')..DateTime.parse('2010-12-31T15:00')).map).reject{ |day| not [1,2].include?(day.wday) }
405
+ end
406
+ it_should_behave_like 'correctly parses'
407
+ it_should_behave_like 'outputs DateTime'
408
+
409
+ it "should not include other time" do
410
+ @result.should_not include(DateTime.parse('2010-12-06T14:00'))
411
+ end
207
412
  end
413
+ end
208
414
 
209
- it "should event_parse a several dates" do
210
- Eventual.event_parse( "1 de enero del 2009\nSede 1\n\n2 de enero del 2009\nSede 2", :use_trailing => true ) do |d, extra|
211
- [d.to_s, extra]
212
- end.should == [["2009-01-01T00:00:00+00:00", "Sede 1"], ["2009-01-02T00:00:00+00:00", "Sede 2"]]
415
+ describe 'Marshal dump' do
416
+ describe "month without year parsing 'marzo'" do
417
+ before do
418
+ @result = Marshal.load Marshal.dump(@parser.parse('marzo')).gsub('NaturalDates::', 'NaturalDates::Eventual::Es::')
419
+ @dates = (Date.parse('2010-3-1')..Date.parse('2010-3-31')).map
420
+ end
421
+ it_should_behave_like 'correctly parses'
213
422
  end
214
423
  end
215
424
 
216
- describe 'Case sensitivity' do
217
- it "should ignore case" do
218
- Eventual.event_parse( 'DeL 1 al 3 de ENeRO' ).should map_times( '2009-1-1', '2009-1-2', '2009-1-3' )
425
+ describe 'Default year' do
426
+ describe "month without year parsing 'marzo'" do
427
+ before do
428
+ @result = @parser.parse('marzo')
429
+ @result.year = 2007
430
+ @dates = (Date.parse('2007-3-1')..Date.parse('2007-3-31')).map
431
+ end
432
+ it_should_behave_like 'correctly parses'
219
433
  end
220
434
  end
221
435
  end
222
-