Whitespace is collapsed, so no need to match multiple in the parser.
Fix exact start times with recurring events, when the start time precedes the interval in the expression, i.e: starting at 2015-01-01 09:00:00 run every other minute for 2 days FossilOrigin-Name: 0fb500373ccb3d17bcc66ee66cc2c513f2abd343d90a516bb8e9ed2c957deda0
This commit is contained in:
parent
f3c9b10b95
commit
9364c9df09
3 changed files with 35 additions and 18 deletions
|
|
@ -9,7 +9,7 @@ module Symphony::Metronome
|
||||||
Configurability
|
Configurability
|
||||||
|
|
||||||
# Library version constant
|
# Library version constant
|
||||||
VERSION = '0.2.0'
|
VERSION = '0.2.1'
|
||||||
|
|
||||||
# Version-control revision constant
|
# Version-control revision constant
|
||||||
REVISION = %q$Revision$
|
REVISION = %q$Revision$
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
( 'milli'? 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' ) 's'?;
|
( 'milli'? 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' ) 's'?;
|
||||||
|
|
||||||
start_identifiers = ( 'start' | 'begin' 'n'? ) 'ing'?;
|
start_identifiers = ( 'start' | 'begin' 'n'? ) 'ing'?;
|
||||||
exec_identifiers = ('run' | 'exec' 'ute'?);
|
exec_identifiers = ('run' | 'exec' 'ute'? | 'do' );
|
||||||
ending_identifiers = ( ('for' | 'until' | 'during') | ('end'|'finish'|'stop'|'complet' 'e'?) 'ing'? );
|
ending_identifiers = ( ('for' | 'until' | 'during') | ('end'|'finish'|'stop'|'complet' 'e'?) 'ing'? );
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
# 2014-05-01 15:00:30
|
# 2014-05-01 15:00:30
|
||||||
#
|
#
|
||||||
fulldate = digit{4} '-' digit{2} '-' digit{2}
|
fulldate = digit{4} '-' digit{2} '-' digit{2}
|
||||||
( space+ digit{2} ':' digit{2} ( ':' digit{2} )? )?;
|
( space digit{2} ':' digit{2} ( ':' digit{2} )? )?;
|
||||||
|
|
||||||
# 10am
|
# 10am
|
||||||
# 2:45pm
|
# 2:45pm
|
||||||
|
|
@ -118,7 +118,7 @@
|
||||||
# other minute
|
# other minute
|
||||||
#
|
#
|
||||||
interval = (
|
interval = (
|
||||||
(( 'a' 'n'? | [1-9][0-9]* ( '.' [0-9]+ )? ) | 'other' | ordinals ) space+
|
(( 'a' 'n'? | [1-9][0-9]* ( '.' [0-9]+ )? ) | 'other' | ordinals ) space
|
||||||
)? interval_times;
|
)? interval_times;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -129,21 +129,21 @@
|
||||||
start_time = date_or_time >set_mark %start_time;
|
start_time = date_or_time >set_mark %start_time;
|
||||||
start_interval = interval >set_mark %start_interval;
|
start_interval = interval >set_mark %start_interval;
|
||||||
|
|
||||||
start_expression = ( (time_preposition space+)? start_time ) |
|
start_expression = ( (time_preposition space)? start_time ) |
|
||||||
( (interval_preposition space+)? start_interval );
|
( (interval_preposition space)? start_interval );
|
||||||
|
|
||||||
execute_time = date_or_time >set_mark %/execute_time;
|
execute_time = date_or_time >set_mark %/execute_time;
|
||||||
execute_interval = interval >set_mark %execute_interval;
|
execute_interval = interval >set_mark %execute_interval;
|
||||||
execute_multiplier = ( digit+ space+ 'times' )
|
execute_multiplier = ( digit+ space 'times' )
|
||||||
>set_mark %execute_multiplier @recurring;
|
>set_mark %execute_multiplier @recurring;
|
||||||
|
|
||||||
execute_expression = (
|
execute_expression = (
|
||||||
# regular dates and intervals
|
# regular dates and intervals
|
||||||
( time_preposition space+ execute_time ) |
|
( time_preposition space execute_time ) |
|
||||||
( ( interval_preposition | recur_preposition ) space+ execute_interval )
|
( ( interval_preposition | recur_preposition ) space execute_interval )
|
||||||
) | (
|
) | (
|
||||||
# count + interval (10 times every minute)
|
# count + interval (10 times every minute)
|
||||||
execute_multiplier space+ ( recur_preposition space+ )? execute_interval
|
execute_multiplier space ( recur_preposition space )? execute_interval
|
||||||
) |
|
) |
|
||||||
# count for 'timeboxed' intervals
|
# count for 'timeboxed' intervals
|
||||||
execute_multiplier;
|
execute_multiplier;
|
||||||
|
|
@ -152,8 +152,8 @@
|
||||||
ending_time = date_or_time >set_mark %ending_time;
|
ending_time = date_or_time >set_mark %ending_time;
|
||||||
ending_interval = interval >set_mark %ending_interval;
|
ending_interval = interval >set_mark %ending_interval;
|
||||||
|
|
||||||
ending_expression = ( (time_preposition space+)? ending_time ) |
|
ending_expression = ( (time_preposition space)? ending_time ) |
|
||||||
( (interval_preposition space+)? ending_interval );
|
( (interval_preposition space)? ending_interval );
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
@ -161,26 +161,26 @@
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
Start = (
|
Start = (
|
||||||
start: start_identifiers space+ -> StartTime,
|
start: start_identifiers space -> StartTime,
|
||||||
StartTime: start_expression -> final
|
StartTime: start_expression -> final
|
||||||
);
|
);
|
||||||
|
|
||||||
Interval = (
|
Interval = (
|
||||||
start:
|
start:
|
||||||
Decorators: ( exec_identifiers space+ )? -> ExecuteTime,
|
Decorators: ( exec_identifiers space )? -> ExecuteTime,
|
||||||
ExecuteTime: execute_expression -> final
|
ExecuteTime: execute_expression -> final
|
||||||
);
|
);
|
||||||
|
|
||||||
Ending = (
|
Ending = (
|
||||||
start: space+ ending_identifiers space+ -> EndingTime,
|
start: space ending_identifiers space -> EndingTime,
|
||||||
EndingTime: ending_expression -> final
|
EndingTime: ending_expression -> final
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
main := (
|
main := (
|
||||||
( (Start space+)? Interval Ending? ) |
|
( Start space Interval Ending? ) |
|
||||||
( Interval ( space+ Start )? Ending? ) |
|
( Interval ( space Start )? Ending? ) |
|
||||||
( Interval Ending space+ Start )
|
( Interval Ending space Start )
|
||||||
) %set_valid @!set_invalid;
|
) %set_valid @!set_invalid;
|
||||||
}%%
|
}%%
|
||||||
|
|
||||||
|
|
@ -205,6 +205,7 @@ using Symphony::Metronome::TimeRefinements
|
||||||
### every other hour
|
### every other hour
|
||||||
### once a day ending in 1 week
|
### once a day ending in 1 week
|
||||||
### run once a minute for an hour starting in 6 days
|
### run once a minute for an hour starting in 6 days
|
||||||
|
### run each hour starting at 2010-01-05 09:00:00
|
||||||
### 10 times a minute for 2 days
|
### 10 times a minute for 2 days
|
||||||
### run 45 times every hour
|
### run 45 times every hour
|
||||||
### 30 times per day
|
### 30 times per day
|
||||||
|
|
@ -384,6 +385,14 @@ class Symphony::Metronome::IntervalExpression
|
||||||
### string and the +type+ of string (interval or exact time)
|
### string and the +type+ of string (interval or exact time)
|
||||||
###
|
###
|
||||||
def set_starting( time_arg, type )
|
def set_starting( time_arg, type )
|
||||||
|
@starting_args ||= []
|
||||||
|
@starting_args << time_arg
|
||||||
|
|
||||||
|
# If we already have seen a start time, it's possible the parser
|
||||||
|
# was non-deterministic and this action has been executed multiple
|
||||||
|
# times. Re-parse the complete date string, overwriting any previous.
|
||||||
|
time_arg = @starting_args.join( ' ' )
|
||||||
|
|
||||||
start = self.get_time( time_arg, type )
|
start = self.get_time( time_arg, type )
|
||||||
@starting = start
|
@starting = start
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,14 @@ describe Symphony::Metronome::IntervalExpression do
|
||||||
expect( parsed.interval ).to be( 60.0 )
|
expect( parsed.interval ).to be( 60.0 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'starting at 2010-01-02 09:00:00 run once a day' do |example|
|
||||||
|
parsed = described_class.parse( example.description )
|
||||||
|
expect( parsed.valid ).to be_truthy
|
||||||
|
expect( parsed.recurring ).to be_truthy
|
||||||
|
expect( parsed.starting ).to eq( past + 75600 )
|
||||||
|
expect( parsed.interval ).to be( 86400.0 )
|
||||||
|
end
|
||||||
|
|
||||||
it 'always sets a start time if one is not specified' do
|
it 'always sets a start time if one is not specified' do
|
||||||
parsed = described_class.parse( 'every 5 seconds' )
|
parsed = described_class.parse( 'every 5 seconds' )
|
||||||
expect( parsed.valid ).to be_truthy
|
expect( parsed.valid ).to be_truthy
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue