diff --git a/lib/Pod/POM/Web/Indexer.pm b/lib/Pod/POM/Web/Indexer.pm index 7fca9ae..df9d79d 100644 --- a/lib/Pod/POM/Web/Indexer.pm +++ b/lib/Pod/POM/Web/Indexer.pm @@ -28,8 +28,6 @@ my $ignore_headings = qr[ SYNOPSIS | DESCRIPTION | METHODS | FUNCTIONS | BUGS | AUTHOR | SEE\ ALSO | COPYRIGHT | LICENSE ]x; -(my $index_dir = __FILE__) =~ s[Indexer\.pm$][index]; - my $id_regex = qr/(?![0-9]) # don't start with a digit \w\w+ # start with 2 or more word chars .. (?:::\w+)* # .. and possibly ::some::more::components @@ -81,6 +79,16 @@ my @stopwords = ( ); +sub new { + my ($class, $request, $response, $options) = @_; + + my $self = $class->SUPER::new($request, $response, $options); + ($self->{index_dir} = __FILE__) =~ s[Indexer\.pm$][index]; + + return $self; +} + + #---------------------------------------------------------------------- # RETRIEVING #---------------------------------------------------------------------- @@ -90,7 +98,7 @@ sub full_text { my ($self, $search_string) = @_; my $indexer = eval { - new Search::Indexer(dir => $index_dir, + new Search::Indexer(dir => $self->{index_dir}, wregex => $wregex, preMatch => '[[', postMatch => ']]'); @@ -262,6 +270,7 @@ sub index { if grep {!/^-(from_scratch|max_size|positions)$/} keys %options; # make sure index dir exists + my $index_dir = $self->{index_dir}; -d $index_dir or mkdir $index_dir or die "mkdir $index_dir: $!"; # if -from_scratch, throw away old index @@ -404,6 +413,7 @@ sub index_file { sub _tie_docs { my ($self, $mode) = @_; + my $index_dir = $self->{index_dir}; # tie to docs.bdb, storing {$doc_id => "$mtime\t$pathname\t$description"} tie %{$self->{_docs}}, 'BerkeleyDB::Hash', -Filename => "$index_dir/docs.bdb", diff --git a/t/indexer.t b/t/indexer.t index 5d27a3a..95fb2d6 100644 --- a/t/indexer.t +++ b/t/indexer.t @@ -3,15 +3,77 @@ use strict; use warnings; -use Test::More tests => 1; +use Test::More; +use Capture::Tiny qw(capture_stdout capture_stderr); +use File::Temp qw(tempdir); - -SKIP: { - eval {require Search::Indexer}; - skip "Search::Indexer does not seem to be installed", 1 - if $@; - use_ok( 'Pod::POM::Web::Indexer' ); +BEGIN { + eval {require Search::Indexer}; + plan skip_all => 'Search::Indexer does not seem to be installed' + if $@; } +plan tests => 4; + +use_ok( 'Pod::POM::Web::Indexer' ); + +subtest "indexing" => sub { + plan tests => 2; + + my $ppwi = Pod::POM::Web::Indexer->new(); + + $ppwi->{index_dir} = tempdir(CLEANUP => 1); + my $output = capture_stderr { + $ppwi->index(); + }; + like($output, qr/INDEXING/, "Creating index creates individual indices"); + + $output = capture_stderr { + $ppwi->index(); + }; + unlike($output, qr/INDEXING/, "Rerunning index avoids recreation"); +}; + +subtest "modlist" => sub { + plan tests => 4; + my $ppwi = Pod::POM::Web::Indexer->new(); + $ppwi->{index_dir} = tempdir(CLEANUP => 1); + capture_stderr { + $ppwi->index(); # index needs to be created for modlist tests + }; + + eval { $ppwi->modlist(); }; + like($@, qr/module_list: arg too short/, "Error message with undef search string"); + + eval { $ppwi->modlist(); }; + like($@, qr/module_list: arg too short/, "Error message with empty search string"); + + my $output = capture_stdout { + $ppwi->modlist('nonexistent_search_string'); + }; + like($output, qr/\[\]/, "Empty list returned with unknown search string"); + + $output = capture_stdout { + $ppwi->modlist('devel'); + }; + like($output, qr/Devel::/, "Module list returned with known search string"); +}; + +subtest "uri escape" => sub { + plan tests => 3; + is(uri_escape(), undef, "An escaped, undefined URI stays undefined"); + + my $plain_uri = "http://example.com"; + is(uri_escape($plain_uri), $plain_uri, "Plain URI remains unchanged"); + + my $unescaped_uri = "http://example.com/^;/?:\@,Az0-_.!~*'()"; + my $escaped_uri = "http://example.com/%5E;/?:\@,Az0-_.!~*'()"; + is(uri_escape($unescaped_uri), $escaped_uri, "Non-standard characters escaped in URI"); +}; + +sub uri_escape { + my $uri = shift; + return Pod::POM::Web::Indexer::uri_escape($uri); +} # TODO ... more than just a compile test