1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
#!/usr/bin/perl
use strict;
use warnings;
use boolean qw(true false);
use DateTime::Format::Natural;
use Test::More tests => 23;
{
# Assert for prefixed dates that an extracted unit which is
# partially invalid is not being passed to a DateTime wrapper.
local $@;
eval {
my $parser = DateTime::Format::Natural->new;
$parser->parse_datetime('+1XXXday');
$parser->parse_datetime('-1dayXXX');
};
ok(!$@, 'prefixed date');
}
{
# Assert that parse_datetime_duration() shrinks the date strings
# and fails.
my $parser = DateTime::Format::Natural->new;
my @dt = $parser->parse_datetime_duration('mon to fri to sun');
ok(!$parser->success, 'duration with substrings exceeding limit failed');
is(@dt, 2, 'count of objects returned for shrinked duration');
}
{
my ($parser, $warnings);
local $SIG{__WARN__} = sub { $warnings = true };
# Assert that a malformed formatted date with mixed separators previously
# wrongly recognized as "m/d" format is rejected without warnings emitted.
$warnings = false;
$parser = DateTime::Format::Natural->new;
$parser->parse_datetime('2011/04-12');
ok(!$parser->success && !$warnings, 'checking of formatted date string end');
$warnings = false;
$parser = DateTime::Format::Natural->new;
$parser->parse_datetime('2011/04-12 15:00');
ok(!$parser->success && !$warnings, 'checking of formatted date word boundary');
# Assert that a formatted date with an invalid month name which
# contains non-letters is rejected without warnings emitted.
$warnings = false;
$parser = DateTime::Format::Natural->new;
$parser->parse_datetime('2011-j6n-04');
ok(!$parser->success && !$warnings, 'formatted date with non-letter in month name');
}
{
# Assert that extract_datetime() returns expressions depending on context.
my $parser = DateTime::Format::Natural->new;
my $string = 'monday until friday';
my $expression = $parser->extract_datetime($string);
is($expression, 'monday', 'extract_datetime scalar');
my @expressions = $parser->extract_datetime($string);
is_deeply(\@expressions, [qw(monday friday)], 'extract_datetime list');
}
{
# Assert that extract_datetime() looping through a grammar entry does not
# match in more than one subentry for all tokens (previously broken for
# this input string with the weekday_time grammar entry, at least).
my $parser = DateTime::Format::Natural->new;
my @expressions = $parser->extract_datetime('8am 4pm');
is_deeply(\@expressions, [qw(8am 4pm)], 'extract with single grammar subentry');
}
{
# Assert that regexes match only at word boundary when extracting relative durations.
my $parser = DateTime::Format::Natural->new;
my @expressions = $parser->extract_datetime('123first to last day of nov');
ok(@expressions == 1 && $expressions[0] eq 'last day of nov', 'first to last duration word boundary begin');
@expressions = $parser->extract_datetime('first to last day of nov456');
ok(@expressions == 1 && $expressions[0] eq 'last day', 'first to last duration word boundary end');
@expressions = $parser->extract_datetime('abc2012-11-01 18:00 to 20:00');
ok(@expressions == 1 && $expressions[0] eq '18:00 to 20:00', 'from count to count duration word boundary begin');
@expressions = $parser->extract_datetime('nov 1 to 2ndxyz');
ok(@expressions == 1 && $expressions[0] eq 'nov 1', 'from count to count duration word boundary end');
}
{
# Assert that date/grammar expressions do not overlap with duration ones.
my $parser = DateTime::Format::Natural->new;
my @expressions = $parser->extract_datetime('2012-12-31 to first to last day of 2013');
is_deeply(\@expressions, ['2012-12-31', 'first to last day of 2013'], 'date overlapping duration');
@expressions = $parser->extract_datetime('last day of 2012 to jan 1st to 31st');
is_deeply(\@expressions, ['last day of 2012', 'jan 1st to 31st'], 'grammar overlapping duration');
}
{
# Assert that rightmost matching token on left side of duration is used to determine the type.
my $parser = DateTime::Format::Natural->new;
my @expressions = $parser->extract_datetime('23:30 some text jan 19th to 20th');
is_deeply(\@expressions, ['23:30', 'jan 19th to 20th'], 'last matching token in left duration substring');
}
{
# Assert that parsing month/day with an explicit ymd-format fails.
my $parser = DateTime::Format::Natural->new(format => 'd/m/y');
$parser->parse_datetime('8/10');
ok(!$parser->success, 'parsing month/day with an explicit ymd-format failed');
}
{
# Assert that error() returns '' on success.
my $parser = DateTime::Format::Natural->new;
$parser->parse_datetime('now'); # success
is($parser->error, '', "error() returns '' on success");
}
{
my $parser;
# Assert that error() returns an appropriate message.
$parser = DateTime::Format::Natural->new;
like($parser->error, qr/neither .+? nor .+? method invoked/, 'error() with no method invoked');
$parser->extract_datetime('fail');
like($parser->error, qr/cannot be extracted from/, 'error() with extract_datetime()');
$parser->parse_datetime('fail');
like($parser->error, qr/does not parse/, 'error() with parse_datetime()');
$parser->parse_datetime_duration('fail to fail');
like($parser->error, qr/does not parse/, 'error() with parse_datetime_duration()');
# Assert that trace() without traces returns cleanly.
$parser = DateTime::Format::Natural->new;
is_deeply([$parser->trace], [], 'trace() without traces returns cleanly');
}
|