package tests::ReportParserLaTeXWriterTest;
use strict;
use base qw/Lire::Test::TestCase tests::TestStoreFixture
tests::ChartTypesFixture /;
use Lire::ReportParser::LaTeXWriter;
use Lire::ReportParser::ReportBuilder;
use Lire::Utils qw/tempdir create_file file_content/;
use File::Path qw/rmtree/;
use Lire::Config::ConfigSpec;
use Lire::DlfSchema;
use Lire::Field;
use Lire::Report;
use Lire::Report::Section;
use Lire::Report::Subreport;
use Lire::Report::TableInfo;
use Lire::Report::ChartConfig;
use Lire::ChartType;
use Lire::PluginManager;
use Lire::Test::Mock;
use IO::Scalar;
use Time::Local;
sub set_up {
my $self = $_[0];
$self->SUPER::set_up();
$self->{'tmpdir'} = tempdir( $self->name() . "_XXXXXX" );
$self->{'writer'} =
new_proxy Lire::Test::Mock( 'Lire::ReportParser::LaTeXWriter' );
$self->{'writer'}{'_fh'} = new IO::Scalar();
$self->{'keep_tmpdir'} = 0;
return;
}
sub tear_down {
my $self = $_[0];
$self->SUPER::tear_down();
rmtree( $self->{'tmpdir'}, 0 )
unless $self->{'keep_tmpdir'};
return;
}
sub test_write_report {
my $self = $_[0];
my $report = new Lire::Report();
$report->add_section( new Lire::Report::Section( 'Section 1' ) );
$report->add_section( new Lire::Report::Section( 'Section 2' ) );
create_file( "$self->{'tmpdir'}/font.tex", '' );
$self->{'writer'}->set_result( 'write_header', '' );
$self->{'writer'}->set_result( 'write_titlepage', '' );
$self->{'writer'}->set_result( 'write_section', '' );
$self->{'writer'}->set_result( 'write_appendix', '' );
$self->{'writer'}->set_result( 'process_latex', '' );
$self->{'writer'}{'_fh'} = undef;
$self->{'writer'}->write_report( $report,
"$self->{'tmpdir'}/report.pdf", 'pdf',
"$self->{'tmpdir'}/font.tex" );
$self->assert_str_equals( 'pdf', $self->{'writer'}{'_format'} );
$self->assert_str_equals( "$self->{'tmpdir'}/report.pdf",
$self->{'writer'}{'_outputfile'}, );
$self->assert_str_equals( $self->{'tmpdir'},
$self->{'writer'}{'_outputdir'} );
$self->assert_str_equals( "$self->{'tmpdir'}/report",
$self->{'writer'}{'_outputbase'}, );
$self->assert_str_equals( "$self->{'tmpdir'}/font.tex",
$self->{'writer'}{'_preamble'}, );
$self->assert_not_null( $self->{'writer'}{'_fh'},
"missing _fh attribute" );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_header' ) );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_titlepage' ) );
$self->assert_num_equals( 2, $self->{'writer'}->invocation_count( 'write_section' ) );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_appendix' ) );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'process_latex' ) );
}
sub test_write_header {
my $self = $_[0];
$self->{'cfg'}{'unicode.tex'} = '/usr/share/lire/tex/unicode.tex';
$self->{'writer'}{'_preamble'} = 'font.tex';
$self->{'writer'}{'_format'} = 'pdf';
$self->{'writer'}->write_header();
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->assert_str_equals( <<EOF, $$buf );
\\ocp\\MyTexUTF=inutf8
\\InputTranslation currentfile \\MyTexUTF
\\documentclass{report}
\\addtolength{\\textwidth}{2\\oddsidemargin}
\\addtolength{\\textheight}{2\\topmargin}
\\setlength{\\oddsidemargin}{0cm}
\\setlength{\\topmargin}{0cm}
\\input /usr/share/lire/tex/unicode.tex
\\usepackage[dvipdf]{graphics}
\\usepackage{longtable}
\\usepackage[ps2pdf,bookmarks,bookmarksopen,bookmarksnumbered]{hyperref}
\\input font.tex
\\begin{document}
EOF
}
sub test_write_titlepage {
my $self = $_[0];
my $report = new Lire::Report();
$report->title( '{My report}' );
my $start = timelocal( 0, 0, 0, 1, 0, 2004 );
my $time = timelocal( 15, 15, 3, 2, 0, 2004 );
$report->timespan_start( $start );
$report->timespan_end( $start + 86400);
$report->date( $time );
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_titlepage( $report );
$self->assert_str_equals( <<'EOF', $$buf );
\title{\{My report\}}
\author{}
\date{Report for 2004-01-01 00:00 -- 2004-01-02 00:00\\
Report generated 2004-01-02 03:15}
\maketitle
\tableofcontents
EOF
}
sub test_write_section {
my $self = $_[0];
my $section = new Lire::Report::Section( '{Section title}' );
$section->description( '<para>Section description</para>' );
my $sub1 = new Lire::Report::Subreport( 'test', 'test1' );
$sub1->id( 'test-test1' );
$section->add_subreport( $sub1 );
my $sub2 = new_missing Lire::Report::Subreport( 'test', 'test2',
'No good reason' );
$sub2->id( 'test-test2' );
$section->add_subreport( $sub2 );
$self->{'writer'}->set_result( 'write_subreport', '' );
$self->{'writer'}->set_result( 'write_missing_subreport', '' );
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_section( $section );
$self->assert_str_equals( <<'EOF', $$buf );
\chapter{\{Section title\}}
Section description
EOF
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_subreport' ) );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_missing_subreport' ) );
}
sub test_write_missing_subreport {
my $self = $_[0];
my $sub = new_missing Lire::Report::Subreport( 'test', 'test1', '{No good reason}' );
$sub->title( '{My subreport}' );
$sub->description( '<para>Description</para>' );
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_missing_subreport( $sub );
$self->assert_str_equals( <<'EOF', $$buf );
\section{\{My subreport\}}
\emph{This report is missing: \{No good reason\}}
EOF
}
sub set_up_chart_configs {
my $self = $_[0];
$self->{'cfg'}{'_lr_config_spec'} = new Lire::Config::ConfigSpec();
$self->set_up_plugin_mgr();
my $type = new_proxy Lire::Test::Mock( 'Lire::ChartType' );
$type->set_result( 'name' => 'mock_chart',
'write_chart' => sub { return '/tmp/chart.eps' } );
Lire::PluginManager->register_plugin( $type );
$self->{'mock_chart'} = $type;
$self->{'cfg'}{'lr_chart_font'} = '';
$self->{'chart1'} = new Lire::Report::ChartConfig();
$self->{'chart1'}->type( $type );
$self->{'chart2'} = new Lire::Report::ChartConfig();
$self->{'chart2'}->type( $type );
return;
}
sub test_write_subreport {
my $self = $_[0];
$self->set_up_chart_configs();
my $subreport = new Lire::Report::Subreport( 'test', 'test1' );
$subreport->title( "{Subreport's Title}" );
$subreport->description( "<para>Subreport's description</para>" );
$subreport->add_chart_config( $self->{'chart1'} );
$subreport->add_chart_config( $self->{'chart2'} );
$self->{'writer'}->set_result( 'write_chart', '' );
$self->{'writer'}->set_result( 'write_table_header', '' );
$self->{'writer'}->set_result( 'write_table_entries', '' );
$self->{'writer'}->set_result( 'write_table_footer', '' );
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_subreport( $subreport );
$self->assert_str_equals( <<'EOF', $$buf );
\section{\{Subreport's Title\}}
Subreport's description
EOF
$self->assert_num_equals( 2, $self->{'writer'}->invocation_count( 'write_chart' ) );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_table_header' ) );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_table_entries' ) );
$self->assert_num_equals( 1, $self->{'writer'}->invocation_count( 'write_table_footer' ) );
}
sub test_write_chart {
my $self = $_[0];
$self->set_up_chart_configs();
my $subreport = new Lire::Report::Subreport( 'test', 'test1' );
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}{'_outputdir'} = $self->{'tmpdir'};
$self->{'writer'}->write_chart( $subreport, $self->{'chart1'} );
$self->assert_str_equals( <<'EOF', $$buf );
\begin{center}
\includegraphics{chart.eps}
\end{center}
EOF
$self->assert_deep_equals( [ $self->{'mock_chart'},
$self->{'chart1'}, $subreport,
'outputdir', $self->{'tmpdir'},
'format', 'eps',
'font', '/Helvetica',
],
$self->{'mock_chart'}->get_invocation( 'write_chart' ) );
$self->assert_deep_equals( [ '/tmp/chart.eps' ],
$self->{'writer'}{'_chart_files'} );
$self->{'cfg'}{'lr_chart_font'} = '/Times-New-Roman';
$self->{'writer'}->write_chart( $subreport, $self->{'chart1'} );
$self->assert_deep_equals( [ $self->{'mock_chart'},
$self->{'chart1'}, $subreport,
'outputdir', $self->{'tmpdir'},
'format', 'eps',
'font', '/Times-New-Roman',
],
$self->{'mock_chart'}->get_invocation( 'write_chart', 1 ) );
$self->{'mock_chart'}->set_result( 'write_chart',
sub { die "An error occured\n" } );
$$buf = '';
$self->{'writer'}->write_chart( $subreport, $self->{'chart1'} );
$self->assert_str_equals( <<'EOF', $$buf );
\emph{An error occured while generating the chart: An error occured
}
EOF
$self->{'mock_chart'}->set_result( 'write_chart',
sub { return undef } );
$$buf = '';
$self->{'writer'}->write_chart( $subreport, $self->{'chart1'} );
$self->assert_str_equals( '', $$buf );
return;
}
sub set_up_subreport {
my $self = $_[0];
my $subreport = new Lire::Report::Subreport( 'test', 'test1' );
my $table_info = new Lire::Report::TableInfo();
$table_info->create_column_info( 'user', 'categorical', 'string',
'{User}' );
my $group = $table_info->create_group_info( 'group1' );
$group->create_column_info( 'file', 'categorical', 'string', '{File}' );
$group->create_column_info( 'count', 'numerical', 'int', 'Downloads' );
$group->create_column_info( 'size', 'numerical', 'bytes', 'Size' );
$table_info->compute_group_layout();
$subreport->table_info( $table_info );
$subreport->schemas( 'test' );
$self->{'subreport'} = $subreport;
return;
}
sub test_write_table_header {
my $self = $_[0];
$self->init();
$self->set_up_test_schema();
$self->set_up_subreport();
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_table_header( $self->{'subreport'} );
$self->assert_str_equals( <<'EOF', $$buf );
\begin{longtable}{|llrr|}
\hline
\multicolumn{2}{|l}{\bfseries \hyperlink{test:user}{\{User\}}} & \bfseries Downloads & \bfseries Size\\
& \bfseries \hyperlink{test:file}{\{File\}} & & \\
\hline
\endhead
EOF
return;
}
sub test_write_table_footer {
my $self = $_[0];
$self->set_up_subreport();
$self->{'subreport'}->nrecords( 100 );
$self->{'subreport'}->set_summary_value( 'count', 'content' => '356' );
$self->{'subreport'}->set_summary_value( 'size', 'value' => 1024 * 1024,
'content' => '1$' );
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_table_footer( $self->{'subreport'} );
$self->assert_str_equals( <<'EOF', $$buf );
\hline
\multicolumn{4}{r}{\emph{continued on next page}}
\endfoot
\hline
\multicolumn{2}{|l}{\emph{Total for 100 records}} & 356 & 1\$\\
\hline
\endlastfoot
EOF
}
sub set_up_subreport_data {
my $self = $_[0];
my $data = [ [ 'flacoste', undef, 9, 53 ],
[ undef, 'page1.html', 5, 50 ],
[ undef, 'page2.html', 4, 3 ],
[ '{wsourdeau}', undef, 5, 10 ],
[ undef, 'page3.html$', 3, 6 ],
[ undef, 'page2.html', 1, 2 ],
[ undef, 'page4.html', 1, 2 ] ];
my $group;
foreach my $r ( @$data ) {
my ( $user, $page, $count, $size ) = @$r;
if ( $user ) {
my $entry = $self->{'subreport'}->create_entry();
$entry->add_name( $user );
$group = $entry->create_group();
$group->set_summary_value( 'count', 'content' => $count );
$group->set_summary_value( 'size', 'content' => $size );
} else {
my $entry = $group->create_entry();
$entry->add_name( $page );
$entry->add_value( 'content' => $count );
$entry->add_value( 'content' => $size );
}
}
$self->{'subreport'}->finalize();
}
sub test_write_table_entries {
my $self = $_[0];
$self->set_up_subreport();
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_table_entries( $self->{'subreport'} );
$self->assert_str_equals( <<'EOF', $$buf );
\multicolumn{4}{|l|}{\emph{There is no entries in this table.}}\\
\end{longtable}
EOF
$self->set_up_subreport_data();
$$buf = '';
$self->{'writer'}->write_table_entries( $self->{'subreport'} );
$self->assert_str_equals( <<'EOF', $$buf );
\multicolumn{2}{|l}{flacoste} & 9 & 53\\
& page1.html & 5 & 50\\
& page2.html & 4 & 3\\
\multicolumn{2}{|l}{\{wsourdeau\}} & 5 & 10\\
& page3.html\$ & 3 & 6\\
& page2.html & 1 & 2\\
& page4.html & 1 & 2\\
\end{longtable}
EOF
}
sub test_write_appendix {
my $self = $_[0];
my $report = new Lire::Report();
my $sect = new Lire::Report::Section( 'Title' );
$report->add_section( $sect );
my $sub = new Lire::Report::Subreport( 'test', 'top-dirs' );
$sub->id( 'top-dirs.0' );
$sub->schemas( 'test', 'test-extended' );
$sect->add_subreport( $sub );
$self->{'writer'}->set_result( 'write_schema', '' );
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_appendix( $report );
$self->assert_str_equals( "\\appendix\n", $$buf );
$self->assert_num_equals( 2, $self->{'writer'}->invocation_count( 'write_schema' ) );
}
sub test_write_schema {
my $self = $_[0];
my $test_schema = new Lire::DlfSchema( 'superservice' => 'test',
'timestamp' => 'time' );
$test_schema->title( '{A title}' );
$test_schema->description( '<para>A description.</para>' );
$test_schema->add_field( new Lire::Field( 'name' => 'time',
'type' => 'timestamp',
'label' => '{Time}',
'description' => '<para>The time field.</para>' ) );
$test_schema->add_field( new Lire::Field( 'name' => 'field_1',
'type' => 'string',
'label' => 'Field 1',
'description' => '<para>The first field.</para>' ) );
local $Lire::DlfSchema::SCHEMA_CACHE{'test'} = $test_schema;
my $buf = $self->{'writer'}{'_fh'}->sref();
$self->{'writer'}->write_schema( 'test' );
$self->assert_str_equals( <<'EOF', $$buf );
\chapter{\{A title\}}
A description.
\begin{description}
\item[\hypertarget{test:time}{\{Time\}}]
The time field.
\item[\hypertarget{test:field_1}{Field 1}]
The first field.
\end{description}
EOF
}
sub set_up_write_report {
my $self = $_[0];
$self->init();
$self->set_up_test_schema();
$self->set_up_chart_types();
$self->{'keep_tmpdir'} = $ENV{'KEEP_LATEX'};
my $spec = $self->{'cfg'}{'_lr_config_spec'};
$self->{'cfg'}{'unicode.tex'} =
"$self->{'testdir'}/../../../extras/unicode.tex";
$self->{'cfg'}{'lambda_path'} =
$spec->get( 'lambda_path' )->default()->as_value();
$self->{'cfg'}{'odvips_path'} =
$spec->get( 'odvips_path' )->default()->as_value();
$self->{'cfg'}{'ps2pdf_path'} =
$spec->get( 'ps2pdf_path' )->default()->as_value();
my $parser = new Lire::ReportParser::ReportBuilder();
$self->{'report'} = $parser->parsefile( "$self->{'testdir'}/data/TestReport_daily_jan25_2003.xml" );
$self->{'writer'} = new Lire::ReportParser::LaTeXWriter();
}
sub test_write_report_latex {
my $self = $_[0];
$self->set_up_write_report();
$self->{'writer'}->write_report( $self->{'report'},
"$self->{'tmpdir'}/report.tex",
'latex' );
$self->assert( -s "$self->{'tmpdir'}/report.tex",
"missing '$self->{'tmpdir'}/report.tex'" );
print "\nLaTeX report generated in $self->{'tmpdir'}/report.tex\n"
if $self->{'keep_tmpdir'};
}
sub test_write_report_dvi {
my $self = $_[0];
$self->set_up_write_report();
$self->assert( $self->{'cfg'}{'lambda_path'},
"Can't test without lambda" );
$self->{'writer'}->write_report( $self->{'report'},
"$self->{'tmpdir'}/report.dvi",
'dvi' );
$self->assert( -s "$self->{'tmpdir'}/report.dvi",
"missing '$self->{'tmpdir'}/report.dvi'" );
$self->assert( ! -f "$self->{'tmpdir'}/report.tex",
"file $self->{'tmpdir'}/report.tex wasn't removed" );
$self->assert( ! -f "$self->{'tmpdir'}/report.log",
"temporary $self->{'tmpdir'}/report.log wasn't removed" );
$self->assert( ! -f "$self->{'tmpdir'}/report.aux",
"temporary $self->{'tmpdir'}/report.aux wasn't removed" );
print "\nDVI report generated in $self->{'tmpdir'}/report.dvi\n"
if $self->{'keep_tmpdir'};
}
sub test_write_report_ps {
my $self = $_[0];
$self->set_up_write_report();
$self->assert( $self->{'cfg'}{'lambda_path'},
"Can't test without lambda" );
$self->assert( $self->{'cfg'}{'odvips_path'},
"Can't test without odvips" );
$self->{'writer'}->write_report( $self->{'report'},
"$self->{'tmpdir'}/report.ps",
'ps' );
$self->assert( -s "$self->{'tmpdir'}/report.ps",
"missing '$self->{'tmpdir'}/report.ps'" );
$self->assert( ! -f "$self->{'tmpdir'}/report.dvi",
"temporary $self->{'tmpdir'}/report.dvi wasn't removed" );
print "\nPS report generated in $self->{'tmpdir'}/report.ps\n"
if $self->{'keep_tmpdir'};
}
sub test_write_report_pdf {
my $self = $_[0];
$self->set_up_write_report();
$self->assert( $self->{'cfg'}{'lambda_path'},
"Can't test without lambda" );
$self->assert( $self->{'cfg'}{'odvips_path'},
"Can't test without odvips" );
$self->assert( $self->{'cfg'}{'ps2pdf_path'},
"Can't test without ps2pdf" );
$self->{'writer'}->write_report( $self->{'report'},
"$self->{'tmpdir'}/report.pdf",
'pdf' );
$self->assert( -s "$self->{'tmpdir'}/report.pdf",
"missing '$self->{'tmpdir'}/report.pdf'" );
$self->assert( ! -f "$self->{'tmpdir'}/report.ps",
"temporary $self->{'tmpdir'}/report.ps wasn't removed" );
print "\nPDF report generated in $self->{'tmpdir'}/report.pdf\n"
if $self->{'keep_tmpdir'};
}
1;
syntax highlighted by Code2HTML, v. 0.9.1