From 53fcd15fe7667628f4d5c4f2c1b2dc49f174d67c Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Mon, 28 Sep 2015 18:06:25 +0200 Subject: EFA: Handle ambiguous input properly (explicit accessors for candidate lists) --- Changelog | 7 +++++++ bin/efa-m | 10 ++++++++++ lib/Travel/Status/DE/EFA.pm | 47 +++++++++++++++++++++++++++++++++------------ t/21-vrr-ambig.t | 8 +++++--- 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/Changelog b/Changelog index dddafe2..eaedf71 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,10 @@ +git HEAD + + * EFA: Add accessors name_candidates and place_candidates + * EFA: errstr: in cases of ambiguous input, the name/place + candidates list is no longer encoded in the errstr accessor. Use the + new name_candidates / place_candidates accessors instead. + Travel::Status::DE::VRR 1.12 - Tue Aug 04 2015 * EFA: Add static method get_efa_urls diff --git a/bin/efa-m b/bin/efa-m index 5e2c68d..28fd2ad 100755 --- a/bin/efa-m +++ b/bin/efa-m @@ -338,6 +338,16 @@ $efa = new_efa_by_url($efa_url); if ( my $err = $efa->errstr ) { say STDERR "Request error: ${err}"; + + if ( $efa->place_candidates ) { + say 'You might want to try one of the following places:'; + say join( "\n", $efa->place_candidates ); + } + elsif ( $efa->name_candidates ) { + say 'You might want to try one of the following names:'; + say join( "\n", $efa->name_candidates ); + } + exit 2; } diff --git a/lib/Travel/Status/DE/EFA.pm b/lib/Travel/Status/DE/EFA.pm index 5b1e36a..c9123df 100644 --- a/lib/Travel/Status/DE/EFA.pm +++ b/lib/Travel/Status/DE/EFA.pm @@ -167,6 +167,24 @@ sub errstr { return $self->{errstr}; } +sub name_candidates { + my ($self) = @_; + + if ( $self->{name_candidates} ) { + return @{ $self->{name_candidates} }; + } + return; +} + +sub place_candidates { + my ($self) = @_; + + if ( $self->{place_candidates} ) { + return @{ $self->{place_candidates} }; + } + return; +} + sub sprintf_date { my ($e) = @_; @@ -222,21 +240,16 @@ sub check_for_ambiguous { my $s_name = $e_name->getAttribute('state'); if ( $s_place eq 'list' ) { - $self->{errstr} = sprintf( - 'Ambiguous place input: %s', - join( q{ | }, - map { decode( 'UTF-8', $_->textContent ) } - @{ $e_place->findnodes($xp_place_elem) } ) - ); + $self->{place_candidates} = [ map { decode( 'UTF-8', $_->textContent ) } + @{ $e_place->findnodes($xp_place_elem) } ]; + $self->{errstr} = 'ambiguous place parameter'; return; } if ( $s_name eq 'list' ) { - $self->{errstr} = sprintf( - 'Ambiguous name input: %s', - join( q{ | }, - map { decode( 'UTF-8', $_->textContent ) } - @{ $e_name->findnodes($xp_name_elem) } ) - ); + $self->{name_candidates} = [ map { decode( 'UTF-8', $_->textContent ) } + @{ $e_name->findnodes($xp_name_elem) } ]; + + $self->{errstr} = 'ambiguous name parameter'; return; } if ( $s_place eq 'notidentified' ) { @@ -704,6 +717,16 @@ will return ("Essen", "Martinstr."). Returns a list of Travel::Status::DE::EFA::Line(3pm) objects, each one describing one line servicing the selected station. +=item $status->name_candidates + +Returns a list of B candidates if I is ambiguous. Returns +nothing (undef / empty list) otherwise. + +=item $status->place_candidates + +Returns a list of B candidates if I is ambiguous. Returns +nothing (undef / empty list) otherwise. + =item $status->results Returns a list of Travel::Status::DE::EFA::Result(3pm) objects, each one describing diff --git a/t/21-vrr-ambig.t b/t/21-vrr-ambig.t index 7dd96a4..fb03a43 100644 --- a/t/21-vrr-ambig.t +++ b/t/21-vrr-ambig.t @@ -5,7 +5,7 @@ use 5.010; use utf8; use File::Slurp qw(slurp); -use Test::More tests => 7; +use Test::More tests => 9; BEGIN { use_ok('Travel::Status::DE::VRR'); @@ -21,8 +21,10 @@ can_ok($status, qw(errstr results)); $status->check_for_ambiguous(); -is($status->errstr, 'Ambiguous name input: Alfredusbad | Am Alfredusbad', - 'errstr ok'); +is($status->errstr, 'ambiguous name parameter', 'errstr ok'); + +is_deeply([$status->place_candidates], [], 'place candidates ok'); +is_deeply([$status->name_candidates], ['Alfredusbad', 'Am Alfredusbad'], 'name candidates ok'); is_deeply([$status->lines], [], 'no lines'); is_deeply([$status->results], [], 'no results'); -- cgit v1.2.3