--- trunk/lib/Frey/Test/Runner.pm 2008/11/24 21:35:34 500 +++ trunk/lib/Frey/Test/Runner.pm 2008/11/27 21:31:45 565 @@ -8,6 +8,7 @@ use TAP::Harness; use TAP::Formatter::HTML; use Data::Dump qw/dump/; +use File::Slurp; use Frey::SVK; use Frey::PPI; @@ -18,14 +19,66 @@ required => 1, lazy => 1, # FIXME ask users which tests to run default => sub { -# [ glob('t/*.t') ] # all tests [ Frey::SVK->modified ] }, + documentation => 'run tests which are result of modifications or whole full tests', +); + +has test => ( + is => 'rw', + isa => 'Str', + documentation => 'run only this single test', +); + +has test_because => ( + documentation => 'returns classes responsable for each test run', + is => 'rw', +# isa => 'HashRef[Hashref[Int]', + required => 1, + lazy => 1, + default => sub { + my $self = shift; + my $depends; + + # collect real tests + map { + $depends->{$_}->{'test modified'}++ if m{\.t$}; + } @{ $self->tests }; + + # and tests which depend on modified classes supplied + map { + if ( m{(.+)\.pm$} ) { + my $class = $1; + $class =~ s{^lib/}{}; + $class =~ s{/}{::}g; + warn "extract tests from $_ class $class"; + $depends->{$_}->{$class}++ foreach Frey::PPI->new( class => $class )->has_tests; + } + } @{ $self->tests }; + + return $depends; + }, ); sub as_markup { my ($self) = @_; + my $path = 'var/test/'; + my $running_pid = "$path/running.pid"; + + my $pid = read_file $running_pid if -e $running_pid; + if ( $pid ) { + if ( kill 0, $pid ) { + warn "ABORTING: $self started twice"; + return 'abort'; + } else { + warn "got $pid from $running_pid but no process alive, ignoring..."; + } + } + + write_file( $running_pid, $$ ); + warn "# started $self with pid $$ -> $running_pid"; + my $f = TAP::Formatter::HTML->new({ # silent => 1, @@ -37,40 +90,41 @@ formatter => $f, }); - my $tests; + my @tests; - map { - $tests->{$_}++ if m{\.t$}; - } @{ $self->tests }; - - map { - if ( m{(.+)\.pm$} ) { - my $class = $1; - $class =~ s{^lib/}{}; - $class =~ s{/}{::}g; - warn "extract tests from $_ class $class"; - $tests->{$_}->{$class}++ foreach Frey::PPI->new( class => $class )->has_tests; - } - } @{ $self->tests }; + @tests = ( $self->test ) if $self->test; + + if ( my $depends = $self->test_because ) { + @tests = grep { + $_ ne '' && + ! m{$0} # break recursion + } sort keys %{ $depends } unless @tests; + } + + $self->add_status( { test => { depends => $self->test_because } } ); + + if ( ! @tests ) { + warn "can't find any tests ", dump( $self->tests ), " within depends ", dump( $self->test_because ); +# warn "running all tests instead"; +# @tests = glob('t/*.t'); + @tests = glob('t/01*.t'); # XXX default tests + } - my @tests = grep { - ! m{$0} # break recursion - } sort keys %$tests; - die "no tests for files ", dump( $self->tests ),dump( $tests ) unless @tests; + $self->title( join(' ', @tests ) ); warn "testing ",dump( @tests ); $h->runtests( @tests ); $self->store( 'var/test/' . time() . '.yaml', $h ); - push @{ $self->status }, { test => $tests }; - my $html = ${ $f->html }; # warn $html; warn "got ",length($html), " bytes"; while ( $html =~ s{()}{}gs ) { - $self->add_head( $1 ); + my $style = $1; + $style =~ s[((?:body|html)\s+{[^}]+})][/\* $1 \*/]sg; # remove some styles + $self->add_head( $style ); } $self->add_head(qq| @@ -80,29 +134,42 @@ td.results:hover ul.test-out { display: block; } |); + $html =~ s{}{}sg; # remove menu which doesn't work without JavaScript $html =~ s{^.*}{}s; $html =~ s{.*$}{}s; $html =~ s{(t/(.+?)}{$3}sg; - return - $self->editor_links( $html ) + $html = $self->editor_links( $html ); + + if ( my $depends = $self->test_because ) { + $html .= qq|Test dependencies:| . qq|| ; - + } + + $self->add_icon( $1 ) if $html =~ m{class="(passed|failed)"}; + + unlink $running_pid or die "can't remove $running_pid: $!"; + + return $html; } 1;