package BetterOutput; use strict; use HTML::Entities; use URI::Escape; 1; sub new { my $class = shift; my($results) = @_; return bless {'results' => $results, 'output' => undef}, $class; } sub capture { my $self = shift; my($target) = @_; $self->{output} = $target; } sub print { my $self = shift; if (defined $self->{output}) { local $" = ''; ${$self->{output}} .= "@_"; } else { CORE::print(@_); } } sub redirect { my $self = shift; my($command, $args) = @_; my $uri = './?command=' . encode_entities($command); foreach (keys %$args) { $uri .= '&' . encode_entities($_) . '=' . encode_entities($args->{$_}); } $self->print(<print("Status: $status\n") if defined $status; $self->print(< BETTER: $title

$title

eof $self->{close} = sub { CORE::print(" \n\n"); }; } sub subhead { my $self = shift; my($title) = @_; $title = encode_entities($title); $self->print("

$title

\n"); } sub paragraph { my $self = shift; my $attributes = {}; if (ref $_[0] eq 'HASH') { $attributes = shift; } $self->print(' {$attr}); $self->print(" $attr=\"$value\""); } $self->print('>'); foreach (@_) { my $a = ''; my $text = ''; my $z = ''; if (ref $_ eq 'ARRAY') { $a = "<$_->[0]>"; $text = $_->[1]; $z = "[0]>"; } else { $text = $_; } $text = encode_entities($text); $self->print("$a$text$z"); } $self->print("

\n"); } sub explicitLink { my $self = shift; my($text, $uri) = @_; $text = encode_entities($text); $uri = encode_entities($uri); $self->print("

$text $uri

\n"); } sub link { my $self = shift; my($text, $uri) = @_; $text = encode_entities($text); $uri = encode_entities($uri); $self->print("

$text

\n"); } sub openList { my $self = shift; my($title) = @_; $self->print("
    \n"); } sub closeList { my $self = shift; my($title) = @_; $self->print("
\n"); } sub getLinkItem { my $self = shift; my($data, $label, $comment) = @_; my $uri = './?'; foreach (keys %$data) { $uri .= uri_escape($_); $uri .= '='; $uri .= uri_escape($data->{$_}); $uri .= '&'; } chop $uri; # remove trailing '&' (or '?') $uri = encode_entities($uri); $label = encode_entities($label); if (defined $comment) { $comment = encode_entities(" $comment"); } else { $comment = ''; } $self->print("
  • $label$comment
  • \n"); } sub postLinkItem { my $self = shift; my($data, $label, $comment) = @_; $label = encode_entities($label); $comment = '' unless defined $comment; $comment = encode_entities($comment); $self->print(<

    eof foreach (keys %$data) { my $name = encode_entities($_); my $value = encode_entities($data->{$_}); $self->print(" \n"); } $self->print(< eof } sub form { my $self = shift; my($command, $method, $fields, $submit) = @_; $command = encode_entities($command); $method = encode_entities($method); $submit = encode_entities($submit); $self->print(<

    eof my $count = 0; foreach (@$fields) { my $type = encode_entities($_->{type}); my $name = encode_entities($_->{name}); my $label = ''; if (exists $_->{label}) { $label = '' . encode_entities($_->{label}) . ' '; } if ($type ne 'hidden') { $count++; if ($count > 1) { $self->print("

    \n

    \n"); } } if ($_->{type} eq 'textarea') { my $value = encode_entities($_->{value}); $self->print(" \n"); } elsif ($_->{type} eq 'select') { $self->print(" \n"); } else { my $value = encode_entities($_->{value}); $self->print(" \n"); } } if ($count > 1) { $self->print("

    \n

    \n"); } $self->print(<

    eof } sub testFrameset { my $self = shift; my($title, $runID, $suiteID, $testID, $uri, $n, $maxN, $tester, $password) = @_; my $frameURI = './?command=submissionFrame&run=' . uri_escape($runID) . '&suite=' . uri_escape($suiteID) . '&test=' . uri_escape($testID) . '&remaining=' . uri_escape($n) . '&total=' . uri_escape($maxN) . '&tester=' . uri_escape($tester) . '&password=' . uri_escape($password); foreach ($title, $uri, $frameURI) { $_ = encode_entities($_); } $self->print(< BETTER: $title <object src="$uri"><p><a href="$uri">View test</a>.</p></object> eof $self->submissionBlock(@_[1..3], @_[5..8]); # $runID, $suiteID, $testID, $n, $maxN, $tester, $password (but not escaped) $self->print(" \n \n"); } sub testSubmissionFrame { my $self = shift; # my($runID, $suiteID, $testID, $n, $maxN, $tester, $password) = @_; $self->print(< BETTER: Test Result Submission Form eof $self->submissionBlock(@_); # $runID, $suiteID, $testID, $n, $maxN, $tester, $password (not escaped) $self->print(" \n"); } sub submissionBlock { my $self = shift; my($runID, $suiteID, $testID, $n, $maxN, $tester, $password) = @_; foreach ($runID, $suiteID, $testID, $n, $maxN, $tester, $password) { $_ = encode_entities($_); } my $resultCodes = $self->{results}; foreach (@$resultCodes) { my $code = $_->{'code'}; my $label = $_->{'label'}; $self->print(<

    eof } # XXX support skipping tests $n = $maxN - $n + 1; $self->print(<

    Test $n of $maxN.

    eof } sub stylesheet { my $self = shift; $self->print(<getSortLinks([@$columns, @$otherColumns], $currentKeys, $arguments); $self->print(" \n \n \n"); foreach my $col (@$columns) { my $link = shift @$links; $self->print(" \n"); } $self->print(" \n \n"); return $links; } sub getSortLinks { my $self = shift; my($columns, $currentKeys, $arguments) = @_; my @links; my $prefix = './?'; foreach (keys %$arguments) { $prefix .= uri_escape($_) . '=' . uri_escape($arguments->{$_}) . '&'; } my $currentKey = ''; if (@$currentKeys) { $currentKey = $currentKeys->[0]; } foreach my $col (@$columns) { my $key = $col->[0]; if (defined $key) { my $class = ''; my $keyPrefix = ''; if ($currentKey eq $key) { $class = 'class="ascending sort"'; $keyPrefix = '-'; } elsif ($currentKey eq "-$key") { $class = 'class="descending sort"'; } my $link = $prefix . 'key0=' . encode_entities("$keyPrefix$key"); my $keyIndex = 0; foreach (@$currentKeys) { if ($_ !~ /^-?\Q$key\E/s) { ++$keyIndex; $link .= "&key$keyIndex=" . encode_entities($_); } } $link = encode_entities($link); my $title = encode_entities($col->[1]); push(@links, "$title"); } else { push(@links, encode_entities($col->[1])); } } return \@links; } sub printIndexRow { my $self = shift; my($label, $arguments, @values) = @_; my $uri; if (ref $arguments eq 'HASH') { $uri = './?'; foreach (keys %$arguments) { $uri .= uri_escape($_) . '=' . uri_escape($arguments->{$_}) . '&'; } chop $uri; } else { $uri = $arguments; } $uri = encode_entities($uri); $label = encode_entities($label); $self->print(" \n \n"); foreach (@values) { if (ref $_ eq 'ARRAY') { my $data = encode_entities($_->[0]); my $class = encode_entities($_->[1]); $self->print(" \n"); } elsif (ref $_ eq 'HASH') { my $uri = encode_entities($_->{'uri'}); my $label = encode_entities($_->{'label'}); $self->print(" \n"); } else { my $data = encode_entities($_); $self->print(" \n"); } } $self->print(" \n"); } sub closeTable { my $self = shift; my($otherLinks) = @_; $self->print("
    $link
    \n $label\n $data$label$data
    \n"); if (@$otherLinks) { $self->print('

    Sort by:'); my $prefix = ' '; foreach (@$otherLinks) { $self->print("$prefix$_"); $prefix = ', '; } $self->print("

    \n"); } } sub DESTROY { my $self = shift; if (defined $self->{close}) { &{$self->{close}}; } }