Merge pull request #1348 from duckduckgo/mintsoft/week-update_with_dates
Continuation: Convert Week Goodie to Structured Template, update testsmaster
commit
81b7116ce1
|
@ -2,6 +2,7 @@ package DDG::Goodie::Week;
|
|||
# ABSTRACT: Find the current week number or when a week began
|
||||
|
||||
use DDG::Goodie;
|
||||
with 'DDG::GoodieRole::Dates';
|
||||
|
||||
# My imports
|
||||
use strict;
|
||||
|
@ -42,44 +43,61 @@ my @months = qw/
|
|||
December
|
||||
/;
|
||||
|
||||
handle query_raw => sub {
|
||||
handle query_lc => sub {
|
||||
return unless /^\s*
|
||||
what(?:'?s|\sis|\swas)?\s+
|
||||
(?:the\s+)?
|
||||
(?:(current|(\d{1,2})(?:nd|th|rd|st)?)\s+)?
|
||||
(?:(?:what|when)(?:'?s|\sis|\swas)?\s)?
|
||||
(?:the\s)?
|
||||
(?:(current|(?<week>\d{1,2})(?:nd|th|rd|st)?)\s)?
|
||||
week
|
||||
(
|
||||
\s+of\s+
|
||||
(?:(?:the|this)\s+)?
|
||||
(year|\d{4})
|
||||
\sof\s
|
||||
(?:(?:the(?:\scurrent)?|this)\s)?
|
||||
(?<year>year|\d{4})
|
||||
|
|
||||
\s+is\s+this
|
||||
\sis\sthis
|
||||
)?\??
|
||||
\s*$/x;
|
||||
|
||||
my $week = $1;
|
||||
my $year = defined $4 ? ($4 eq 'year' ? 'current' : $4) : 'current';
|
||||
my $week = $+{week};
|
||||
my $year = $+{year} || 'current';
|
||||
$year = 'current' if $year eq 'year';
|
||||
|
||||
($week, $year) = qw/current current/ if (not defined $week);
|
||||
|
||||
return if $week =~ s/(nd|th|rd|st)$// and $week > 52;
|
||||
# ensure week number is legitimate
|
||||
return unless $week eq 'current' or ($week > 0 && $week <=52);
|
||||
|
||||
my $dt = DateTime->now(time_zone => $loc->time_zone);
|
||||
|
||||
my $dt = DateTime->now(time_zone => $loc->time_zone)
|
||||
if ($week eq 'current' or $year eq 'current');
|
||||
my $response;
|
||||
|
||||
# Asking about current week of the current year
|
||||
if ($week eq 'current' and $year eq 'current') {
|
||||
return "We are in currently in the " . ordinate($dt->week_number) .
|
||||
' week of ' . $dt->year . '.',
|
||||
html => 'We are in currently in the ' . $dt->week_number
|
||||
. '<sup>' . ordsuf($dt->week_number) . '</sup>'
|
||||
. ' week of ' . $dt->year . '.';
|
||||
} elsif ($year eq 'current') {
|
||||
my ($dt_week_num, $dt_year) = (ordinate($dt->week_number), $dt->year);
|
||||
$response = "We are currently in the $dt_week_num week of $dt_year.";
|
||||
}
|
||||
# Asking about nth week of the current year
|
||||
elsif ($year eq 'current') {
|
||||
$year = $dt->year();
|
||||
}
|
||||
my (undef, $month, $day) = Monday_of_Week($week, $year);
|
||||
return "The " . ordinate($week) . " week of $year began on " .
|
||||
"$months[--$month] " . ordinate($day) . '.',
|
||||
html =>"The $week<sup>" . ordsuf($week) . "</sup> week of $year began on " .
|
||||
"$months[$month] $day<sup>" . ordsuf($day) . '</sup>.';
|
||||
return unless $year eq 'current' || is_valid_year($year);
|
||||
|
||||
# Asking about nth week of some year
|
||||
unless ($response){
|
||||
my (undef, $month, $day) = Monday_of_Week($week, $year);
|
||||
my ($week_num, $day_num, $out_month, $start_term) = (ordinate($week), ordinate($day), $months[--$month], 'begins');
|
||||
|
||||
$start_term = "began" if ($year < $dt->year || $year == $dt->year && ($week< $dt->week && $day < $dt->day));
|
||||
|
||||
$response = "The $week_num week of $year $start_term on $out_month $day_num.";
|
||||
}
|
||||
|
||||
return $response,
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => "Assuming the week starts on Monday",
|
||||
result => $response
|
||||
};
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
@ -41,6 +41,7 @@ my $month_regex = qr#$full_month|$short_month#;
|
|||
my $time_24h = qr#(?:(?:[0-1][0-9])|(?:2[0-3]))[:]?[0-5][0-9][:]?[0-5][0-9]#i;
|
||||
my $time_12h = qr#(?:(?:0[1-9])|(?:1[012])):[0-5][0-9]:[0-5][0-9]\s?(?:am|pm)#i;
|
||||
my $date_number = qr#[0-3]?[0-9]#;
|
||||
my $full_year = qr#[0-9]{4}#;
|
||||
my $relative_dates = qr#
|
||||
now | today | tomorrow | yesterday |
|
||||
(?:(?:current|previous|next)\sday) |
|
||||
|
@ -53,8 +54,8 @@ my $relative_dates = qr#
|
|||
# DMY: 27/11/2014 with a variety of delimiters
|
||||
# MDY: 11/27/2014 -- fundamentally non-sensical date format, for americans
|
||||
my $date_delim = qr#[\.\\/\,_-]#;
|
||||
my $ambiguous_dates = qr#(?:$date_number)$date_delim(?:$date_number)$date_delim(?:[0-9]{4})#i;
|
||||
my $ambiguous_dates_matches = qr#^(?<m>$date_number)$date_delim(?<d>$date_number)$date_delim(?<y>[0-9]{4})$#i;
|
||||
my $ambiguous_dates = qr#(?:$date_number)$date_delim(?:$date_number)$date_delim(?:$full_year)#i;
|
||||
my $ambiguous_dates_matches = qr#^(?<m>$date_number)$date_delim(?<d>$date_number)$date_delim(?<y>$full_year)$#i;
|
||||
|
||||
# like: 1st 2nd 3rd 4-20,24-30th 21st 22nd 23rd 31st
|
||||
my $number_suffixes = qr#(?:st|nd|rd|th)#i;
|
||||
|
@ -243,14 +244,14 @@ my %tz_offsets = (
|
|||
my $tz_strings = join('|', keys %tz_offsets);
|
||||
my $tz_suffixes = qr#(?:[+-][0-9]{4})|$tz_strings#i;
|
||||
|
||||
my $date_standard = qr#$short_day_of_week $short_month\s{1,2}$date_number $time_24h $tz_suffixes [0-9]{4}#i;
|
||||
my $date_standard_matches = qr#$short_day_of_week (?<m>$short_month)\s{1,2}(?<d>$date_number) (?<t>$time_24h) (?<tz>$tz_suffixes) (?<y>[0-9]{4})#i;
|
||||
my $date_standard = qr#$short_day_of_week $short_month\s{1,2}$date_number $time_24h $tz_suffixes $full_year#i;
|
||||
my $date_standard_matches = qr#$short_day_of_week (?<m>$short_month)\s{1,2}(?<d>$date_number) (?<t>$time_24h) (?<tz>$tz_suffixes) (?<y>$full_year)#i;
|
||||
|
||||
# formats parsed by vague datestring, without colouring
|
||||
# the context of the code using it
|
||||
my $descriptive_datestring = qr{
|
||||
(?:(?:next|last)\s(?:$month_regex)) | # next June, last jan
|
||||
(?:(?:$month_regex)\s(?:[0-9]{4})) | # Jan 2014, August 2000
|
||||
(?:(?:$month_regex)\s(?:$full_year)) | # Jan 2014, August 2000
|
||||
(?:(?:$date_number)\s?$number_suffixes?\s(?:$month_regex)) | # 18th Jan, 01 October
|
||||
(?:(?:$month_regex)\s(?:$date_number)\s?$number_suffixes?) | # Dec 25, July 4th
|
||||
(?:$month_regex) | # February, Aug
|
||||
|
@ -260,7 +261,7 @@ my $descriptive_datestring = qr{
|
|||
# Used for parse_descriptive_datestring_to_date
|
||||
my $descriptive_datestring_matches = qr#
|
||||
(?:(?<q>next|last)\s(?<m>$month_regex)) |
|
||||
(?:(?<m>$month_regex)\s(?<y>[0-9]{4})) |
|
||||
(?:(?<m>$month_regex)\s(?<y>$full_year)) |
|
||||
(?:(?<d>$date_number)\s?$number_suffixes?\s(?<m>$month_regex)) |
|
||||
(?:(?<m>$month_regex)\s(?<d>$date_number)\s?$number_suffixes?) |
|
||||
(?<m>$month_regex) |
|
||||
|
@ -270,6 +271,9 @@ my $descriptive_datestring_matches = qr#
|
|||
my $formatted_datestring = build_datestring_regex();
|
||||
|
||||
# Accessors for useful regexes
|
||||
sub full_year_regex {
|
||||
return $full_year;
|
||||
}
|
||||
sub full_month_regex {
|
||||
return $full_month;
|
||||
}
|
||||
|
@ -304,35 +308,42 @@ sub formatted_datestring_regex {
|
|||
return $formatted_datestring;
|
||||
}
|
||||
|
||||
sub is_valid_year {
|
||||
my ($year) = @_;
|
||||
return ($year =~ /^[0-9]{1,4}$/)
|
||||
&& (1*$year > 0)
|
||||
&& (1*$year < 10000);
|
||||
}
|
||||
|
||||
# Called once to build $formatted_datestring
|
||||
sub build_datestring_regex {
|
||||
my @regexes = ();
|
||||
|
||||
## unambigous and awesome date formats:
|
||||
# ISO8601: 2014-11-27 (with a concession to single-digit month and day numbers)
|
||||
push @regexes, qr#[0-9]{4}-?[0-1]?[0-9]-?$date_number(?:[ T]$time_24h)?(?: ?$tz_suffixes)?#i;
|
||||
push @regexes, qr#$full_year-?[0-1]?[0-9]-?$date_number(?:[ T]$time_24h)?(?: ?$tz_suffixes)?#i;
|
||||
|
||||
# HTTP: Sat, 09 Aug 2014 18:20:00
|
||||
push @regexes, qr#$short_day_of_week, [0-9]{2} $short_month [0-9]{4} $time_24h?#i;
|
||||
push @regexes, qr#$short_day_of_week, [0-9]{2} $short_month $full_year $time_24h?#i;
|
||||
|
||||
# RFC850 08-Feb-94 14:15:29 GMT
|
||||
push @regexes, qr#[0-9]{2}-$short_month-(?:[0-9]{2}|[0-9]{4}) $time_24h?(?: ?$tz_suffixes)#i;
|
||||
push @regexes, qr#[0-9]{2}-$short_month-(?:[0-9]{2}|$full_year) $time_24h?(?: ?$tz_suffixes)#i;
|
||||
|
||||
# RFC2822 Sat, 13 Mar 2010 11:29:05 -0800
|
||||
push @regexes, qr#$short_day_of_week, $date_number $short_month [0-9]{4} $time_24h $tz_suffixes#i;
|
||||
push @regexes, qr#$short_day_of_week, $date_number $short_month $full_year $time_24h $tz_suffixes#i;
|
||||
|
||||
# date(1) default format Sun Sep 7 15:57:56 EDT 2014
|
||||
push @regexes, $date_standard;
|
||||
|
||||
# month-first date formats
|
||||
push @regexes, qr#$date_number$date_delim$short_month$date_delim[0-9]{4}#i;
|
||||
push @regexes, qr#$date_number$date_delim$full_month$date_delim[0-9]{4}#i;
|
||||
push @regexes, qr#(?:$short_month|$full_month) $date_number(?: ?$number_suffixes)?[,]? [0-9]{4}#i;
|
||||
push @regexes, qr#$date_number$date_delim$short_month$date_delim$full_year#i;
|
||||
push @regexes, qr#$date_number$date_delim$full_month$date_delim$full_year#i;
|
||||
push @regexes, qr#(?:$short_month|$full_month) $date_number(?: ?$number_suffixes)?[,]? $full_year#i;
|
||||
|
||||
# day-first date formats
|
||||
push @regexes, qr#$short_month$date_delim$date_number$date_delim[0-9]{4}#i;
|
||||
push @regexes, qr#$full_month$date_delim$date_number$date_delim[0-9]{4}#i;
|
||||
push @regexes, qr#$date_number[,]?(?: ?$number_suffixes)? (?:$short_month|$full_month)[,]? [0-9]{4}#i;
|
||||
push @regexes, qr#$short_month$date_delim$date_number$date_delim$full_year#i;
|
||||
push @regexes, qr#$full_month$date_delim$date_number$date_delim$full_year#i;
|
||||
push @regexes, qr#$date_number[,]?(?: ?$number_suffixes)? (?:$short_month|$full_month)[,]? $full_year#i;
|
||||
|
||||
## Ambiguous, but potentially valid date formats
|
||||
push @regexes, $ambiguous_dates;
|
||||
|
|
20
t/00-roles.t
20
t/00-roles.t
|
@ -432,7 +432,27 @@ subtest 'Dates' => sub {
|
|||
|
||||
restore_time();
|
||||
};
|
||||
subtest 'Valid Years' => sub {
|
||||
#my @valids = ('1', '0001', '9999', 2015, 1997);
|
||||
my @valids = ('1');
|
||||
my @invalids = (-1, 0, 10000);
|
||||
|
||||
foreach my $case (@valids) {
|
||||
my $result;
|
||||
lives_ok {
|
||||
$result = DatesRoleTester::is_valid_year($case)
|
||||
};
|
||||
is($result, "1", "$case is a valid year");
|
||||
}
|
||||
|
||||
foreach my $case (@invalids) {
|
||||
my $result;
|
||||
lives_ok {
|
||||
$result = DatesRoleTester::is_valid_year($case)
|
||||
};
|
||||
is($result, '', "$case is an invalid year");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
subtest 'ImageLoader' => sub {
|
||||
|
|
|
@ -4,52 +4,115 @@ use strict;
|
|||
use warnings;
|
||||
use Test::More;
|
||||
use DDG::Test::Goodie;
|
||||
use Test::MockTime qw( :all );
|
||||
|
||||
zci answer_type => "week";
|
||||
zci is_cached => 1;
|
||||
|
||||
# Output verified with UNIX cal program
|
||||
my @current_week = (
|
||||
qr/We are currently in the \d{1,2}\w{2} week of \d{4}./,
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => qr/We are currently in the \d{1,2}\w{2} week of \d{4}./,
|
||||
});
|
||||
|
||||
|
||||
ddg_goodie_test(
|
||||
[qw(
|
||||
DDG::Goodie::Week
|
||||
)],
|
||||
['DDG::Goodie::Week'],
|
||||
|
||||
"what week is this?" => test_zci(
|
||||
qr/We are in currently in the \d+\w+ week of \d+\./,
|
||||
html => qr:We are in currently in the \d+<sup>\w+</sup> week of \d+\.:),
|
||||
# Current Week Queries
|
||||
'what is the current week of the year?' => test_zci(@current_week),
|
||||
"what week is this?" => test_zci(@current_week),
|
||||
"what is the current week" => test_zci(@current_week),
|
||||
"what's the current week? " => test_zci(@current_week),
|
||||
"whats the current week of the year" => test_zci(@current_week),
|
||||
|
||||
"what is the current week" => test_zci(
|
||||
qr/We are in currently in the \d+\w+ week of \d+\./,
|
||||
html => qr:We are in currently in the \d+<sup>\w+</sup> week of \d+\.:),
|
||||
|
||||
"what's the current week? " => test_zci(
|
||||
qr/We are in currently in the \d+\w+ week of \d+\./,
|
||||
html => qr:We are in currently in the \d+<sup>\w+</sup> week of \d+\.:),
|
||||
# Nth Week Queries
|
||||
"what was the 5th week of this year" => test_zci(
|
||||
qr/The \d{1,2}\w{2} week of \d{4} (begins|began) on January \d{1,2}\w{2}\./,
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => "Assuming the week starts on Monday",
|
||||
result => qr/The \d{1,2}\w{2} week of \d{4} (begins|began) on January \d{1,2}\w{2}\./,
|
||||
}
|
||||
),
|
||||
|
||||
"whats the current week of the year" => test_zci(
|
||||
qr/We are in currently in the \d+\w+ week of \d+\./,
|
||||
html => qr:We are in currently in the \d+<sup>\w+</sup> week of \d+\.:),
|
||||
"what was the 43rd week of 1984" => test_zci(
|
||||
"The 43rd week of 1984 began on October 22nd.",
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => "The 43rd week of 1984 began on October 22nd.",
|
||||
}
|
||||
),
|
||||
|
||||
"what was the 5th week of this year" => test_zci(
|
||||
qr/The \d+\w+ week of \d+ began on January \d+\w+\./,
|
||||
html => qr:The \d+<sup>\w+</sup> week of \d+ began on January \d+<sup>\w+</sup>\.:),
|
||||
"what was the 8th week of 1956" => test_zci(
|
||||
"The 8th week of 1956 began on February 20th.",
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => "The 8th week of 1956 began on February 20th.",
|
||||
}
|
||||
),
|
||||
|
||||
"what was the 43rd week of 1984" => test_zci(
|
||||
"The 43rd week of 1984 began on October 22nd.",
|
||||
html => "The 43<sup>rd</sup> week of 1984 began on October 22<sup>nd</sup>."),
|
||||
"what was the 21st week of 1987" => test_zci(
|
||||
"The 21st week of 1987 began on May 18th.",
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => "The 21st week of 1987 began on May 18th.",
|
||||
}
|
||||
),
|
||||
|
||||
"what was the 8th week of 1956" => test_zci(
|
||||
"The 8th week of 1956 began on February 20th.",
|
||||
html => "The 8<sup>th</sup> week of 1956 began on February 20<sup>th</sup>."),
|
||||
|
||||
"what was the 21st week of 1987" => test_zci(
|
||||
"The 21st week of 1987 began on May 18th.",
|
||||
html => "The 21<sup>st</sup> week of 1987 began on May 18<sup>th</sup>."),
|
||||
'what was the 5th week of 1944' => test_zci(
|
||||
'The 5th week of 1944 began on January 31st.',
|
||||
html => 'The 5<sup>th</sup> week of 1944 began on January 31<sup>st</sup>.'
|
||||
),
|
||||
'what was the 5th week of 1944' => test_zci(
|
||||
"The 5th week of 1944 began on January 31st.",
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => "The 5th week of 1944 began on January 31st.",
|
||||
}
|
||||
),
|
||||
'8th week of 2015' => test_zci(
|
||||
"The 8th week of 2015 began on February 16th.",
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => "The 8th week of 2015 began on February 16th."
|
||||
}
|
||||
),
|
||||
'what was the 5th week of 0000' => undef,
|
||||
"what was the 0 week of 2011" => undef,
|
||||
"what was the 99th week of 2011" => undef,
|
||||
);
|
||||
|
||||
set_fixed_time('2014-01-01T00:00:00');
|
||||
ddg_goodie_test(
|
||||
['DDG::Goodie::Week'],
|
||||
'when is the 8th week of 2015' => test_zci(
|
||||
"The 8th week of 2015 begins on February 16th.",
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => "The 8th week of 2015 begins on February 16th.",
|
||||
}
|
||||
)
|
||||
);
|
||||
restore_time();
|
||||
|
||||
set_fixed_time('2015-07-31T00:00:00');
|
||||
ddg_goodie_test(
|
||||
['DDG::Goodie::Week'],
|
||||
'when is the 8th week of 2015' => test_zci(
|
||||
"The 8th week of 2015 began on February 16th.",
|
||||
structured_answer => {
|
||||
input => [],
|
||||
operation => 'Assuming the week starts on Monday',
|
||||
result => "The 8th week of 2015 began on February 16th.",
|
||||
}
|
||||
)
|
||||
);
|
||||
restore_time();
|
||||
|
||||
done_testing;
|
||||
|
|
Loading…
Reference in New Issue